root/drivers/staging/wlan-ng/cfg80211.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. prism2_result2err
  2. prism2_domibset_uint32
  3. prism2_domibset_pstr32
  4. prism2_change_virtual_intf
  5. prism2_add_key
  6. prism2_get_key
  7. prism2_del_key
  8. prism2_set_default_key
  9. prism2_get_station
  10. prism2_scan
  11. prism2_set_wiphy_params
  12. prism2_connect
  13. prism2_disconnect
  14. prism2_join_ibss
  15. prism2_leave_ibss
  16. prism2_set_tx_power
  17. prism2_get_tx_power
  18. prism2_connect_result
  19. prism2_disconnected
  20. prism2_roamed
  21. wlan_create_wiphy
  22. wlan_free_wiphy

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* cfg80211 Interface for prism2_usb module */
   3 #include "hfa384x.h"
   4 #include "prism2mgmt.h"
   5 
   6 /* Prism2 channel/frequency/bitrate declarations */
   7 static const struct ieee80211_channel prism2_channels[] = {
   8         { .center_freq = 2412 },
   9         { .center_freq = 2417 },
  10         { .center_freq = 2422 },
  11         { .center_freq = 2427 },
  12         { .center_freq = 2432 },
  13         { .center_freq = 2437 },
  14         { .center_freq = 2442 },
  15         { .center_freq = 2447 },
  16         { .center_freq = 2452 },
  17         { .center_freq = 2457 },
  18         { .center_freq = 2462 },
  19         { .center_freq = 2467 },
  20         { .center_freq = 2472 },
  21         { .center_freq = 2484 },
  22 };
  23 
  24 static const struct ieee80211_rate prism2_rates[] = {
  25         { .bitrate = 10 },
  26         { .bitrate = 20 },
  27         { .bitrate = 55 },
  28         { .bitrate = 110 }
  29 };
  30 
  31 #define PRISM2_NUM_CIPHER_SUITES 2
  32 static const u32 prism2_cipher_suites[PRISM2_NUM_CIPHER_SUITES] = {
  33         WLAN_CIPHER_SUITE_WEP40,
  34         WLAN_CIPHER_SUITE_WEP104
  35 };
  36 
  37 /* prism2 device private data */
  38 struct prism2_wiphy_private {
  39         struct wlandevice *wlandev;
  40 
  41         struct ieee80211_supported_band band;
  42         struct ieee80211_channel channels[ARRAY_SIZE(prism2_channels)];
  43         struct ieee80211_rate rates[ARRAY_SIZE(prism2_rates)];
  44 
  45         struct cfg80211_scan_request *scan_request;
  46 };
  47 
  48 static const void * const prism2_wiphy_privid = &prism2_wiphy_privid;
  49 
  50 /* Helper Functions */
  51 static int prism2_result2err(int prism2_result)
  52 {
  53         int err = 0;
  54 
  55         switch (prism2_result) {
  56         case P80211ENUM_resultcode_invalid_parameters:
  57                 err = -EINVAL;
  58                 break;
  59         case P80211ENUM_resultcode_implementation_failure:
  60                 err = -EIO;
  61                 break;
  62         case P80211ENUM_resultcode_not_supported:
  63                 err = -EOPNOTSUPP;
  64                 break;
  65         default:
  66                 err = 0;
  67                 break;
  68         }
  69 
  70         return err;
  71 }
  72 
  73 static int prism2_domibset_uint32(struct wlandevice *wlandev,
  74                                   u32 did, u32 data)
  75 {
  76         struct p80211msg_dot11req_mibset msg;
  77         struct p80211item_uint32 *mibitem =
  78                         (struct p80211item_uint32 *)&msg.mibattribute.data;
  79 
  80         msg.msgcode = DIDMSG_DOT11REQ_MIBSET;
  81         mibitem->did = did;
  82         mibitem->data = data;
  83 
  84         return p80211req_dorequest(wlandev, (u8 *)&msg);
  85 }
  86 
  87 static int prism2_domibset_pstr32(struct wlandevice *wlandev,
  88                                   u32 did, u8 len, const u8 *data)
  89 {
  90         struct p80211msg_dot11req_mibset msg;
  91         struct p80211item_pstr32 *mibitem =
  92                         (struct p80211item_pstr32 *)&msg.mibattribute.data;
  93 
  94         msg.msgcode = DIDMSG_DOT11REQ_MIBSET;
  95         mibitem->did = did;
  96         mibitem->data.len = len;
  97         memcpy(mibitem->data.data, data, len);
  98 
  99         return p80211req_dorequest(wlandev, (u8 *)&msg);
 100 }
 101 
 102 /* The interface functions, called by the cfg80211 layer */
 103 static int prism2_change_virtual_intf(struct wiphy *wiphy,
 104                                       struct net_device *dev,
 105                                       enum nl80211_iftype type,
 106                                       struct vif_params *params)
 107 {
 108         struct wlandevice *wlandev = dev->ml_priv;
 109         u32 data;
 110         int result;
 111         int err = 0;
 112 
 113         switch (type) {
 114         case NL80211_IFTYPE_ADHOC:
 115                 if (wlandev->macmode == WLAN_MACMODE_IBSS_STA)
 116                         goto exit;
 117                 wlandev->macmode = WLAN_MACMODE_IBSS_STA;
 118                 data = 0;
 119                 break;
 120         case NL80211_IFTYPE_STATION:
 121                 if (wlandev->macmode == WLAN_MACMODE_ESS_STA)
 122                         goto exit;
 123                 wlandev->macmode = WLAN_MACMODE_ESS_STA;
 124                 data = 1;
 125                 break;
 126         default:
 127                 netdev_warn(dev, "Operation mode: %d not support\n", type);
 128                 return -EOPNOTSUPP;
 129         }
 130 
 131         /* Set Operation mode to the PORT TYPE RID */
 132         result = prism2_domibset_uint32(wlandev,
 133                                         DIDMIB_P2_STATIC_CNFPORTTYPE,
 134                                         data);
 135 
 136         if (result)
 137                 err = -EFAULT;
 138 
 139         dev->ieee80211_ptr->iftype = type;
 140 
 141 exit:
 142         return err;
 143 }
 144 
 145 static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
 146                           u8 key_index, bool pairwise, const u8 *mac_addr,
 147                           struct key_params *params)
 148 {
 149         struct wlandevice *wlandev = dev->ml_priv;
 150         u32 did;
 151 
 152         if (key_index >= NUM_WEPKEYS)
 153                 return -EINVAL;
 154 
 155         if (params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
 156             params->cipher != WLAN_CIPHER_SUITE_WEP104) {
 157                 pr_debug("Unsupported cipher suite\n");
 158                 return -EFAULT;
 159         }
 160 
 161         if (prism2_domibset_uint32(wlandev,
 162                                    DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
 163                                    key_index))
 164                 return -EFAULT;
 165 
 166         /* send key to driver */
 167         did = didmib_dot11smt_wepdefaultkeystable_key(key_index + 1);
 168 
 169         if (prism2_domibset_pstr32(wlandev, did, params->key_len, params->key))
 170                 return -EFAULT;
 171         return 0;
 172 }
 173 
 174 static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
 175                           u8 key_index, bool pairwise,
 176                           const u8 *mac_addr, void *cookie,
 177                           void (*callback)(void *cookie, struct key_params*))
 178 {
 179         struct wlandevice *wlandev = dev->ml_priv;
 180         struct key_params params;
 181         int len;
 182 
 183         if (key_index >= NUM_WEPKEYS)
 184                 return -EINVAL;
 185 
 186         len = wlandev->wep_keylens[key_index];
 187         memset(&params, 0, sizeof(params));
 188 
 189         if (len == 13)
 190                 params.cipher = WLAN_CIPHER_SUITE_WEP104;
 191         else if (len == 5)
 192                 params.cipher = WLAN_CIPHER_SUITE_WEP104;
 193         else
 194                 return -ENOENT;
 195         params.key_len = len;
 196         params.key = wlandev->wep_keys[key_index];
 197         params.seq_len = 0;
 198 
 199         callback(cookie, &params);
 200 
 201         return 0;
 202 }
 203 
 204 static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
 205                           u8 key_index, bool pairwise, const u8 *mac_addr)
 206 {
 207         struct wlandevice *wlandev = dev->ml_priv;
 208         u32 did;
 209         int err = 0;
 210         int result = 0;
 211 
 212         /* There is no direct way in the hardware (AFAIK) of removing
 213          * a key, so we will cheat by setting the key to a bogus value
 214          */
 215 
 216         if (key_index >= NUM_WEPKEYS)
 217                 return -EINVAL;
 218 
 219         /* send key to driver */
 220         did = didmib_dot11smt_wepdefaultkeystable_key(key_index + 1);
 221         result = prism2_domibset_pstr32(wlandev, did, 13, "0000000000000");
 222 
 223         if (result)
 224                 err = -EFAULT;
 225 
 226         return err;
 227 }
 228 
 229 static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
 230                                   u8 key_index, bool unicast, bool multicast)
 231 {
 232         struct wlandevice *wlandev = dev->ml_priv;
 233 
 234         return  prism2_domibset_uint32(wlandev,
 235                                        DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
 236                                        key_index);
 237 }
 238 
 239 static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
 240                               const u8 *mac, struct station_info *sinfo)
 241 {
 242         struct wlandevice *wlandev = dev->ml_priv;
 243         struct p80211msg_lnxreq_commsquality quality;
 244         int result;
 245 
 246         memset(sinfo, 0, sizeof(*sinfo));
 247 
 248         if (!wlandev || (wlandev->msdstate != WLAN_MSD_RUNNING))
 249                 return -EOPNOTSUPP;
 250 
 251         /* build request message */
 252         quality.msgcode = DIDMSG_LNXREQ_COMMSQUALITY;
 253         quality.dbm.data = P80211ENUM_truth_true;
 254         quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
 255 
 256         /* send message to nsd */
 257         if (!wlandev->mlmerequest)
 258                 return -EOPNOTSUPP;
 259 
 260         result = wlandev->mlmerequest(wlandev, (struct p80211msg *)&quality);
 261 
 262         if (result == 0) {
 263                 sinfo->txrate.legacy = quality.txrate.data;
 264                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
 265                 sinfo->signal = quality.level.data;
 266                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
 267         }
 268 
 269         return result;
 270 }
 271 
 272 static int prism2_scan(struct wiphy *wiphy,
 273                        struct cfg80211_scan_request *request)
 274 {
 275         struct net_device *dev;
 276         struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
 277         struct wlandevice *wlandev;
 278         struct p80211msg_dot11req_scan msg1;
 279         struct p80211msg_dot11req_scan_results msg2;
 280         struct cfg80211_bss *bss;
 281         struct cfg80211_scan_info info = {};
 282 
 283         int result;
 284         int err = 0;
 285         int numbss = 0;
 286         int i = 0;
 287         u8 ie_buf[46];
 288         int ie_len;
 289 
 290         if (!request)
 291                 return -EINVAL;
 292 
 293         dev = request->wdev->netdev;
 294         wlandev = dev->ml_priv;
 295 
 296         if (priv->scan_request && priv->scan_request != request)
 297                 return -EBUSY;
 298 
 299         if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
 300                 netdev_err(dev, "Can't scan in AP mode\n");
 301                 return -EOPNOTSUPP;
 302         }
 303 
 304         priv->scan_request = request;
 305 
 306         memset(&msg1, 0x00, sizeof(msg1));
 307         msg1.msgcode = DIDMSG_DOT11REQ_SCAN;
 308         msg1.bsstype.data = P80211ENUM_bsstype_any;
 309 
 310         memset(&msg1.bssid.data.data, 0xFF, sizeof(msg1.bssid.data.data));
 311         msg1.bssid.data.len = 6;
 312 
 313         if (request->n_ssids > 0) {
 314                 msg1.scantype.data = P80211ENUM_scantype_active;
 315                 msg1.ssid.data.len = request->ssids->ssid_len;
 316                 memcpy(msg1.ssid.data.data,
 317                        request->ssids->ssid, request->ssids->ssid_len);
 318         } else {
 319                 msg1.scantype.data = 0;
 320         }
 321         msg1.probedelay.data = 0;
 322 
 323         for (i = 0;
 324                 (i < request->n_channels) && i < ARRAY_SIZE(prism2_channels);
 325                 i++)
 326                 msg1.channellist.data.data[i] =
 327                         ieee80211_frequency_to_channel(
 328                                 request->channels[i]->center_freq);
 329         msg1.channellist.data.len = request->n_channels;
 330 
 331         msg1.maxchanneltime.data = 250;
 332         msg1.minchanneltime.data = 200;
 333 
 334         result = p80211req_dorequest(wlandev, (u8 *)&msg1);
 335         if (result) {
 336                 err = prism2_result2err(msg1.resultcode.data);
 337                 goto exit;
 338         }
 339         /* Now retrieve scan results */
 340         numbss = msg1.numbss.data;
 341 
 342         for (i = 0; i < numbss; i++) {
 343                 int freq;
 344 
 345                 memset(&msg2, 0, sizeof(msg2));
 346                 msg2.msgcode = DIDMSG_DOT11REQ_SCAN_RESULTS;
 347                 msg2.bssindex.data = i;
 348 
 349                 result = p80211req_dorequest(wlandev, (u8 *)&msg2);
 350                 if ((result != 0) ||
 351                     (msg2.resultcode.data != P80211ENUM_resultcode_success)) {
 352                         break;
 353                 }
 354 
 355                 ie_buf[0] = WLAN_EID_SSID;
 356                 ie_buf[1] = msg2.ssid.data.len;
 357                 ie_len = ie_buf[1] + 2;
 358                 memcpy(&ie_buf[2], &msg2.ssid.data.data, msg2.ssid.data.len);
 359                 freq = ieee80211_channel_to_frequency(msg2.dschannel.data,
 360                                                       NL80211_BAND_2GHZ);
 361                 bss = cfg80211_inform_bss(wiphy,
 362                         ieee80211_get_channel(wiphy, freq),
 363                         CFG80211_BSS_FTYPE_UNKNOWN,
 364                         (const u8 *)&msg2.bssid.data.data,
 365                         msg2.timestamp.data, msg2.capinfo.data,
 366                         msg2.beaconperiod.data,
 367                         ie_buf,
 368                         ie_len,
 369                         (msg2.signal.data - 65536) * 100, /* Conversion to signed type */
 370                         GFP_KERNEL
 371                 );
 372 
 373                 if (!bss) {
 374                         err = -ENOMEM;
 375                         goto exit;
 376                 }
 377 
 378                 cfg80211_put_bss(wiphy, bss);
 379         }
 380 
 381         if (result)
 382                 err = prism2_result2err(msg2.resultcode.data);
 383 
 384 exit:
 385         info.aborted = !!(err);
 386         cfg80211_scan_done(request, &info);
 387         priv->scan_request = NULL;
 388         return err;
 389 }
 390 
 391 static int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
 392 {
 393         struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
 394         struct wlandevice *wlandev = priv->wlandev;
 395         u32 data;
 396         int result;
 397         int err = 0;
 398 
 399         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
 400                 if (wiphy->rts_threshold == -1)
 401                         data = 2347;
 402                 else
 403                         data = wiphy->rts_threshold;
 404 
 405                 result = prism2_domibset_uint32(wlandev,
 406                                                 DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD,
 407                                                 data);
 408                 if (result) {
 409                         err = -EFAULT;
 410                         goto exit;
 411                 }
 412         }
 413 
 414         if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
 415                 if (wiphy->frag_threshold == -1)
 416                         data = 2346;
 417                 else
 418                         data = wiphy->frag_threshold;
 419 
 420                 result = prism2_domibset_uint32(wlandev,
 421                                                 DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD,
 422                                                 data);
 423                 if (result) {
 424                         err = -EFAULT;
 425                         goto exit;
 426                 }
 427         }
 428 
 429 exit:
 430         return err;
 431 }
 432 
 433 static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
 434                           struct cfg80211_connect_params *sme)
 435 {
 436         struct wlandevice *wlandev = dev->ml_priv;
 437         struct ieee80211_channel *channel = sme->channel;
 438         struct p80211msg_lnxreq_autojoin msg_join;
 439         u32 did;
 440         int length = sme->ssid_len;
 441         int chan = -1;
 442         int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) ||
 443             (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104);
 444         int result;
 445         int err = 0;
 446 
 447         /* Set the channel */
 448         if (channel) {
 449                 chan = ieee80211_frequency_to_channel(channel->center_freq);
 450                 result = prism2_domibset_uint32(wlandev,
 451                                                 DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL,
 452                                                 chan);
 453                 if (result)
 454                         goto exit;
 455         }
 456 
 457         /* Set the authorization */
 458         if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
 459             ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
 460                 msg_join.authtype.data = P80211ENUM_authalg_opensystem;
 461         else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
 462                  ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
 463                 msg_join.authtype.data = P80211ENUM_authalg_sharedkey;
 464         else
 465                 netdev_warn(dev,
 466                             "Unhandled authorisation type for connect (%d)\n",
 467                             sme->auth_type);
 468 
 469         /* Set the encryption - we only support wep */
 470         if (is_wep) {
 471                 if (sme->key) {
 472                         if (sme->key_idx >= NUM_WEPKEYS)
 473                                 return -EINVAL;
 474 
 475                         result = prism2_domibset_uint32(wlandev,
 476                                 DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
 477                                 sme->key_idx);
 478                         if (result)
 479                                 goto exit;
 480 
 481                         /* send key to driver */
 482                         did = didmib_dot11smt_wepdefaultkeystable_key(
 483                                         sme->key_idx + 1);
 484                         result = prism2_domibset_pstr32(wlandev,
 485                                                         did, sme->key_len,
 486                                                         (u8 *)sme->key);
 487                         if (result)
 488                                 goto exit;
 489                 }
 490 
 491                 /* Assume we should set privacy invoked and exclude unencrypted
 492                  * We could possible use sme->privacy here, but the assumption
 493                  * seems reasonable anyways
 494                  */
 495                 result = prism2_domibset_uint32(wlandev,
 496                                                 DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED,
 497                                                 P80211ENUM_truth_true);
 498                 if (result)
 499                         goto exit;
 500 
 501                 result = prism2_domibset_uint32(wlandev,
 502                                                 DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED,
 503                                                 P80211ENUM_truth_true);
 504                 if (result)
 505                         goto exit;
 506 
 507         } else {
 508                 /* Assume we should unset privacy invoked
 509                  * and exclude unencrypted
 510                  */
 511                 result = prism2_domibset_uint32(wlandev,
 512                                                 DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED,
 513                                                 P80211ENUM_truth_false);
 514                 if (result)
 515                         goto exit;
 516 
 517                 result = prism2_domibset_uint32(wlandev,
 518                                                 DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED,
 519                                                 P80211ENUM_truth_false);
 520                 if (result)
 521                         goto exit;
 522         }
 523 
 524         /* Now do the actual join. Note there is no way that I can
 525          * see to request a specific bssid
 526          */
 527         msg_join.msgcode = DIDMSG_LNXREQ_AUTOJOIN;
 528 
 529         memcpy(msg_join.ssid.data.data, sme->ssid, length);
 530         msg_join.ssid.data.len = length;
 531 
 532         result = p80211req_dorequest(wlandev, (u8 *)&msg_join);
 533 
 534 exit:
 535         if (result)
 536                 err = -EFAULT;
 537 
 538         return err;
 539 }
 540 
 541 static int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
 542                              u16 reason_code)
 543 {
 544         struct wlandevice *wlandev = dev->ml_priv;
 545         struct p80211msg_lnxreq_autojoin msg_join;
 546         int result;
 547         int err = 0;
 548 
 549         /* Do a join, with a bogus ssid. Thats the only way I can think of */
 550         msg_join.msgcode = DIDMSG_LNXREQ_AUTOJOIN;
 551 
 552         memcpy(msg_join.ssid.data.data, "---", 3);
 553         msg_join.ssid.data.len = 3;
 554 
 555         result = p80211req_dorequest(wlandev, (u8 *)&msg_join);
 556 
 557         if (result)
 558                 err = -EFAULT;
 559 
 560         return err;
 561 }
 562 
 563 static int prism2_join_ibss(struct wiphy *wiphy, struct net_device *dev,
 564                             struct cfg80211_ibss_params *params)
 565 {
 566         return -EOPNOTSUPP;
 567 }
 568 
 569 static int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 570 {
 571         return -EOPNOTSUPP;
 572 }
 573 
 574 static int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
 575                                enum nl80211_tx_power_setting type, int mbm)
 576 {
 577         struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
 578         struct wlandevice *wlandev = priv->wlandev;
 579         u32 data;
 580         int result;
 581         int err = 0;
 582 
 583         if (type == NL80211_TX_POWER_AUTOMATIC)
 584                 data = 30;
 585         else
 586                 data = MBM_TO_DBM(mbm);
 587 
 588         result = prism2_domibset_uint32(wlandev,
 589                 DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL,
 590                 data);
 591 
 592         if (result) {
 593                 err = -EFAULT;
 594                 goto exit;
 595         }
 596 
 597 exit:
 598         return err;
 599 }
 600 
 601 static int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
 602                                int *dbm)
 603 {
 604         struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
 605         struct wlandevice *wlandev = priv->wlandev;
 606         struct p80211msg_dot11req_mibget msg;
 607         struct p80211item_uint32 *mibitem;
 608         int result;
 609         int err = 0;
 610 
 611         mibitem = (struct p80211item_uint32 *)&msg.mibattribute.data;
 612         msg.msgcode = DIDMSG_DOT11REQ_MIBGET;
 613         mibitem->did = DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL;
 614 
 615         result = p80211req_dorequest(wlandev, (u8 *)&msg);
 616 
 617         if (result) {
 618                 err = -EFAULT;
 619                 goto exit;
 620         }
 621 
 622         *dbm = mibitem->data;
 623 
 624 exit:
 625         return err;
 626 }
 627 
 628 /* Interface callback functions, passing data back up to the cfg80211 layer */
 629 void prism2_connect_result(struct wlandevice *wlandev, u8 failed)
 630 {
 631         u16 status = failed ?
 632                      WLAN_STATUS_UNSPECIFIED_FAILURE : WLAN_STATUS_SUCCESS;
 633 
 634         cfg80211_connect_result(wlandev->netdev, wlandev->bssid,
 635                                 NULL, 0, NULL, 0, status, GFP_KERNEL);
 636 }
 637 
 638 void prism2_disconnected(struct wlandevice *wlandev)
 639 {
 640         cfg80211_disconnected(wlandev->netdev, 0, NULL,
 641                               0, false, GFP_KERNEL);
 642 }
 643 
 644 void prism2_roamed(struct wlandevice *wlandev)
 645 {
 646         struct cfg80211_roam_info roam_info = {
 647                 .bssid = wlandev->bssid,
 648         };
 649 
 650         cfg80211_roamed(wlandev->netdev, &roam_info, GFP_KERNEL);
 651 }
 652 
 653 /* Structures for declaring wiphy interface */
 654 static const struct cfg80211_ops prism2_usb_cfg_ops = {
 655         .change_virtual_intf = prism2_change_virtual_intf,
 656         .add_key = prism2_add_key,
 657         .get_key = prism2_get_key,
 658         .del_key = prism2_del_key,
 659         .set_default_key = prism2_set_default_key,
 660         .get_station = prism2_get_station,
 661         .scan = prism2_scan,
 662         .set_wiphy_params = prism2_set_wiphy_params,
 663         .connect = prism2_connect,
 664         .disconnect = prism2_disconnect,
 665         .join_ibss = prism2_join_ibss,
 666         .leave_ibss = prism2_leave_ibss,
 667         .set_tx_power = prism2_set_tx_power,
 668         .get_tx_power = prism2_get_tx_power,
 669 };
 670 
 671 /* Functions to create/free wiphy interface */
 672 static struct wiphy *wlan_create_wiphy(struct device *dev,
 673                                        struct wlandevice *wlandev)
 674 {
 675         struct wiphy *wiphy;
 676         struct prism2_wiphy_private *priv;
 677 
 678         wiphy = wiphy_new(&prism2_usb_cfg_ops, sizeof(*priv));
 679         if (!wiphy)
 680                 return NULL;
 681 
 682         priv = wiphy_priv(wiphy);
 683         priv->wlandev = wlandev;
 684         memcpy(priv->channels, prism2_channels, sizeof(prism2_channels));
 685         memcpy(priv->rates, prism2_rates, sizeof(prism2_rates));
 686         priv->band.channels = priv->channels;
 687         priv->band.n_channels = ARRAY_SIZE(prism2_channels);
 688         priv->band.bitrates = priv->rates;
 689         priv->band.n_bitrates = ARRAY_SIZE(prism2_rates);
 690         priv->band.band = NL80211_BAND_2GHZ;
 691         priv->band.ht_cap.ht_supported = false;
 692         wiphy->bands[NL80211_BAND_2GHZ] = &priv->band;
 693 
 694         set_wiphy_dev(wiphy, dev);
 695         wiphy->privid = prism2_wiphy_privid;
 696         wiphy->max_scan_ssids = 1;
 697         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
 698                                  | BIT(NL80211_IFTYPE_ADHOC);
 699         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 700         wiphy->n_cipher_suites = PRISM2_NUM_CIPHER_SUITES;
 701         wiphy->cipher_suites = prism2_cipher_suites;
 702 
 703         if (wiphy_register(wiphy) < 0) {
 704                 wiphy_free(wiphy);
 705                 return NULL;
 706         }
 707 
 708         return wiphy;
 709 }
 710 
 711 static void wlan_free_wiphy(struct wiphy *wiphy)
 712 {
 713         wiphy_unregister(wiphy);
 714         wiphy_free(wiphy);
 715 }

/* [<][>][^][v][top][bottom][index][help] */