1/* 2 * Marvell Wireless LAN device driver: CFG80211 3 * 4 * Copyright (C) 2011, Marvell International Ltd. 5 * 6 * This software file (the "File") is distributed by Marvell International 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 8 * (the "License"). You may use, redistribute and/or modify this File in 9 * accordance with the terms and conditions of the License, a copy of which 10 * is available by writing to the Free Software Foundation, Inc., 11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the 12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 13 * 14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about 17 * this warranty disclaimer. 18 */ 19 20#include "cfg80211.h" 21#include "main.h" 22 23/* 24 * This function maps the nl802.11 channel type into driver channel type. 25 * 26 * The mapping is as follows - 27 * NL80211_CHAN_NO_HT -> IEEE80211_HT_PARAM_CHA_SEC_NONE 28 * NL80211_CHAN_HT20 -> IEEE80211_HT_PARAM_CHA_SEC_NONE 29 * NL80211_CHAN_HT40PLUS -> IEEE80211_HT_PARAM_CHA_SEC_ABOVE 30 * NL80211_CHAN_HT40MINUS -> IEEE80211_HT_PARAM_CHA_SEC_BELOW 31 * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE 32 */ 33static u8 34mwifiex_cfg80211_channel_type_to_sec_chan_offset(enum nl80211_channel_type 35 channel_type) 36{ 37 switch (channel_type) { 38 case NL80211_CHAN_NO_HT: 39 case NL80211_CHAN_HT20: 40 return IEEE80211_HT_PARAM_CHA_SEC_NONE; 41 case NL80211_CHAN_HT40PLUS: 42 return IEEE80211_HT_PARAM_CHA_SEC_ABOVE; 43 case NL80211_CHAN_HT40MINUS: 44 return IEEE80211_HT_PARAM_CHA_SEC_BELOW; 45 default: 46 return IEEE80211_HT_PARAM_CHA_SEC_NONE; 47 } 48} 49 50/* 51 * This function checks whether WEP is set. 52 */ 53static int 54mwifiex_is_alg_wep(u32 cipher) 55{ 56 switch (cipher) { 57 case WLAN_CIPHER_SUITE_WEP40: 58 case WLAN_CIPHER_SUITE_WEP104: 59 return 1; 60 default: 61 break; 62 } 63 64 return 0; 65} 66 67/* 68 * This function retrieves the private structure from kernel wiphy structure. 69 */ 70static void *mwifiex_cfg80211_get_priv(struct wiphy *wiphy) 71{ 72 return (void *) (*(unsigned long *) wiphy_priv(wiphy)); 73} 74 75/* 76 * CFG802.11 operation handler to delete a network key. 77 */ 78static int 79mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, 80 u8 key_index, bool pairwise, const u8 *mac_addr) 81{ 82 struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); 83 84 if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) { 85 wiphy_err(wiphy, "deleting the crypto keys\n"); 86 return -EFAULT; 87 } 88 89 wiphy_dbg(wiphy, "info: crypto keys deleted\n"); 90 return 0; 91} 92 93/* 94 * CFG802.11 operation handler to set Tx power. 95 */ 96static int 97mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, 98 enum nl80211_tx_power_setting type, 99 int mbm) 100{ 101 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 102 struct mwifiex_power_cfg power_cfg; 103 int dbm = MBM_TO_DBM(mbm); 104 105 if (type == NL80211_TX_POWER_FIXED) { 106 power_cfg.is_power_auto = 0; 107 power_cfg.power_level = dbm; 108 } else { 109 power_cfg.is_power_auto = 1; 110 } 111 112 return mwifiex_set_tx_power(priv, &power_cfg); 113} 114 115/* 116 * CFG802.11 operation handler to set Power Save option. 117 * 118 * The timeout value, if provided, is currently ignored. 119 */ 120static int 121mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, 122 struct net_device *dev, 123 bool enabled, int timeout) 124{ 125 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 126 u32 ps_mode; 127 128 if (timeout) 129 wiphy_dbg(wiphy, 130 "info: ignore timeout value for IEEE Power Save\n"); 131 132 ps_mode = enabled; 133 134 return mwifiex_drv_set_power(priv, &ps_mode); 135} 136 137/* 138 * CFG802.11 operation handler to set the default network key. 139 */ 140static int 141mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, 142 u8 key_index, bool unicast, 143 bool multicast) 144{ 145 struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); 146 147 /* Return if WEP key not configured */ 148 if (!priv->sec_info.wep_enabled) 149 return 0; 150 151 if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) { 152 wiphy_err(wiphy, "set default Tx key index\n"); 153 return -EFAULT; 154 } 155 156 return 0; 157} 158 159/* 160 * CFG802.11 operation handler to add a network key. 161 */ 162static int 163mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, 164 u8 key_index, bool pairwise, const u8 *mac_addr, 165 struct key_params *params) 166{ 167 struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); 168 169 if (mwifiex_set_encode(priv, params->key, params->key_len, 170 key_index, 0)) { 171 wiphy_err(wiphy, "crypto keys added\n"); 172 return -EFAULT; 173 } 174 175 return 0; 176} 177 178/* 179 * This function sends domain information to the firmware. 180 * 181 * The following information are passed to the firmware - 182 * - Country codes 183 * - Sub bands (first channel, number of channels, maximum Tx power) 184 */ 185static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) 186{ 187 u8 no_of_triplet = 0; 188 struct ieee80211_country_ie_triplet *t; 189 u8 no_of_parsed_chan = 0; 190 u8 first_chan = 0, next_chan = 0, max_pwr = 0; 191 u8 i, flag = 0; 192 enum ieee80211_band band; 193 struct ieee80211_supported_band *sband; 194 struct ieee80211_channel *ch; 195 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 196 struct mwifiex_adapter *adapter = priv->adapter; 197 struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg; 198 199 /* Set country code */ 200 domain_info->country_code[0] = priv->country_code[0]; 201 domain_info->country_code[1] = priv->country_code[1]; 202 domain_info->country_code[2] = ' '; 203 204 band = mwifiex_band_to_radio_type(adapter->config_bands); 205 if (!wiphy->bands[band]) { 206 wiphy_err(wiphy, "11D: setting domain info in FW\n"); 207 return -1; 208 } 209 210 sband = wiphy->bands[band]; 211 212 for (i = 0; i < sband->n_channels ; i++) { 213 ch = &sband->channels[i]; 214 if (ch->flags & IEEE80211_CHAN_DISABLED) 215 continue; 216 217 if (!flag) { 218 flag = 1; 219 first_chan = (u32) ch->hw_value; 220 next_chan = first_chan; 221 max_pwr = ch->max_power; 222 no_of_parsed_chan = 1; 223 continue; 224 } 225 226 if (ch->hw_value == next_chan + 1 && 227 ch->max_power == max_pwr) { 228 next_chan++; 229 no_of_parsed_chan++; 230 } else { 231 t = &domain_info->triplet[no_of_triplet]; 232 t->chans.first_channel = first_chan; 233 t->chans.num_channels = no_of_parsed_chan; 234 t->chans.max_power = max_pwr; 235 no_of_triplet++; 236 first_chan = (u32) ch->hw_value; 237 next_chan = first_chan; 238 max_pwr = ch->max_power; 239 no_of_parsed_chan = 1; 240 } 241 } 242 243 if (flag) { 244 t = &domain_info->triplet[no_of_triplet]; 245 t->chans.first_channel = first_chan; 246 t->chans.num_channels = no_of_parsed_chan; 247 t->chans.max_power = max_pwr; 248 no_of_triplet++; 249 } 250 251 domain_info->no_of_triplet = no_of_triplet; 252 253 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, 254 HostCmd_ACT_GEN_SET, 0, NULL)) { 255 wiphy_err(wiphy, "11D: setting domain info in FW\n"); 256 return -1; 257 } 258 259 return 0; 260} 261 262/* 263 * CFG802.11 regulatory domain callback function. 264 * 265 * This function is called when the regulatory domain is changed due to the 266 * following reasons - 267 * - Set by driver 268 * - Set by system core 269 * - Set by user 270 * - Set bt Country IE 271 */ 272static int mwifiex_reg_notifier(struct wiphy *wiphy, 273 struct regulatory_request *request) 274{ 275 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 276 277 wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for domain" 278 " %c%c\n", request->alpha2[0], request->alpha2[1]); 279 280 memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2)); 281 282 switch (request->initiator) { 283 case NL80211_REGDOM_SET_BY_DRIVER: 284 case NL80211_REGDOM_SET_BY_CORE: 285 case NL80211_REGDOM_SET_BY_USER: 286 break; 287 /* Todo: apply driver specific changes in channel flags based 288 on the request initiator if necessary. */ 289 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 290 break; 291 } 292 mwifiex_send_domain_info_cmd_fw(wiphy); 293 294 return 0; 295} 296 297/* 298 * This function sets the RF channel. 299 * 300 * This function creates multiple IOCTL requests, populates them accordingly 301 * and issues them to set the band/channel and frequency. 302 */ 303static int 304mwifiex_set_rf_channel(struct mwifiex_private *priv, 305 struct ieee80211_channel *chan, 306 enum nl80211_channel_type channel_type) 307{ 308 struct mwifiex_chan_freq_power cfp; 309 u32 config_bands = 0; 310 struct wiphy *wiphy = priv->wdev->wiphy; 311 struct mwifiex_adapter *adapter = priv->adapter; 312 313 if (chan) { 314 /* Set appropriate bands */ 315 if (chan->band == IEEE80211_BAND_2GHZ) { 316 if (channel_type == NL80211_CHAN_NO_HT) 317 if (priv->adapter->config_bands == BAND_B || 318 priv->adapter->config_bands == BAND_G) 319 config_bands = 320 priv->adapter->config_bands; 321 else 322 config_bands = BAND_B | BAND_G; 323 else 324 config_bands = BAND_B | BAND_G | BAND_GN; 325 } else { 326 if (channel_type == NL80211_CHAN_NO_HT) 327 config_bands = BAND_A; 328 else 329 config_bands = BAND_AN | BAND_A; 330 } 331 332 if (!((config_bands | adapter->fw_bands) & 333 ~adapter->fw_bands)) { 334 adapter->config_bands = config_bands; 335 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { 336 adapter->adhoc_start_band = config_bands; 337 if ((config_bands & BAND_GN) || 338 (config_bands & BAND_AN)) 339 adapter->adhoc_11n_enabled = true; 340 else 341 adapter->adhoc_11n_enabled = false; 342 } 343 } 344 adapter->sec_chan_offset = 345 mwifiex_cfg80211_channel_type_to_sec_chan_offset 346 (channel_type); 347 adapter->channel_type = channel_type; 348 349 mwifiex_send_domain_info_cmd_fw(wiphy); 350 } 351 352 wiphy_dbg(wiphy, "info: setting band %d, chan offset %d, mode %d\n", 353 config_bands, adapter->sec_chan_offset, priv->bss_mode); 354 if (!chan) 355 return 0; 356 357 memset(&cfp, 0, sizeof(cfp)); 358 cfp.freq = chan->center_freq; 359 cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); 360 361 if (mwifiex_bss_set_channel(priv, &cfp)) 362 return -EFAULT; 363 364 return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); 365} 366 367/* 368 * CFG802.11 operation handler to set channel. 369 * 370 * This function can only be used when station is not connected. 371 */ 372static int 373mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, 374 struct ieee80211_channel *chan, 375 enum nl80211_channel_type channel_type) 376{ 377 struct mwifiex_private *priv; 378 379 if (dev) 380 priv = mwifiex_netdev_get_priv(dev); 381 else 382 priv = mwifiex_cfg80211_get_priv(wiphy); 383 384 if (priv->media_connected) { 385 wiphy_err(wiphy, "This setting is valid only when station " 386 "is not connected\n"); 387 return -EINVAL; 388 } 389 390 return mwifiex_set_rf_channel(priv, chan, channel_type); 391} 392 393/* 394 * This function sets the fragmentation threshold. 395 * 396 * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE 397 * and MWIFIEX_FRAG_MAX_VALUE. 398 */ 399static int 400mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) 401{ 402 int ret; 403 404 if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || 405 frag_thr > MWIFIEX_FRAG_MAX_VALUE) 406 return -EINVAL; 407 408 /* Send request to firmware */ 409 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 410 HostCmd_ACT_GEN_SET, FRAG_THRESH_I, 411 &frag_thr); 412 413 return ret; 414} 415 416/* 417 * This function sets the RTS threshold. 418 419 * The rts value must lie between MWIFIEX_RTS_MIN_VALUE 420 * and MWIFIEX_RTS_MAX_VALUE. 421 */ 422static int 423mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) 424{ 425 if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) 426 rts_thr = MWIFIEX_RTS_MAX_VALUE; 427 428 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 429 HostCmd_ACT_GEN_SET, RTS_THRESH_I, 430 &rts_thr); 431} 432 433/* 434 * CFG802.11 operation handler to set wiphy parameters. 435 * 436 * This function can be used to set the RTS threshold and the 437 * Fragmentation threshold of the driver. 438 */ 439static int 440mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 441{ 442 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 443 int ret = 0; 444 445 if (changed & WIPHY_PARAM_RTS_THRESHOLD) { 446 ret = mwifiex_set_rts(priv, wiphy->rts_threshold); 447 if (ret) 448 return ret; 449 } 450 451 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) 452 ret = mwifiex_set_frag(priv, wiphy->frag_threshold); 453 454 return ret; 455} 456 457/* 458 * CFG802.11 operation handler to change interface type. 459 */ 460static int 461mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, 462 struct net_device *dev, 463 enum nl80211_iftype type, u32 *flags, 464 struct vif_params *params) 465{ 466 int ret; 467 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 468 469 if (priv->bss_mode == type) { 470 wiphy_warn(wiphy, "already set to required type\n"); 471 return 0; 472 } 473 474 priv->bss_mode = type; 475 476 switch (type) { 477 case NL80211_IFTYPE_ADHOC: 478 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC; 479 wiphy_dbg(wiphy, "info: setting interface type to adhoc\n"); 480 break; 481 case NL80211_IFTYPE_STATION: 482 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; 483 wiphy_dbg(wiphy, "info: setting interface type to managed\n"); 484 break; 485 case NL80211_IFTYPE_UNSPECIFIED: 486 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; 487 wiphy_dbg(wiphy, "info: setting interface type to auto\n"); 488 return 0; 489 default: 490 wiphy_err(wiphy, "unknown interface type: %d\n", type); 491 return -EINVAL; 492 } 493 494 mwifiex_deauthenticate(priv, NULL); 495 496 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; 497 498 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE, 499 HostCmd_ACT_GEN_SET, 0, NULL); 500 501 return ret; 502} 503 504/* 505 * This function dumps the station information on a buffer. 506 * 507 * The following information are shown - 508 * - Total bytes transmitted 509 * - Total bytes received 510 * - Total packets transmitted 511 * - Total packets received 512 * - Signal quality level 513 * - Transmission rate 514 */ 515static int 516mwifiex_dump_station_info(struct mwifiex_private *priv, 517 struct station_info *sinfo) 518{ 519 struct mwifiex_ds_get_signal signal; 520 struct mwifiex_rate_cfg rate; 521 int ret = 0; 522 523 sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES | 524 STATION_INFO_RX_PACKETS | 525 STATION_INFO_TX_PACKETS 526 | STATION_INFO_SIGNAL | STATION_INFO_TX_BITRATE; 527 528 /* Get signal information from the firmware */ 529 memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal)); 530 if (mwifiex_get_signal_info(priv, &signal)) { 531 dev_err(priv->adapter->dev, "getting signal information\n"); 532 ret = -EFAULT; 533 } 534 535 if (mwifiex_drv_get_data_rate(priv, &rate)) { 536 dev_err(priv->adapter->dev, "getting data rate\n"); 537 ret = -EFAULT; 538 } 539 540 /* Get DTIM period information from firmware */ 541 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, 542 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I, 543 &priv->dtim_period); 544 545 /* 546 * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid 547 * MCS index values for us are 0 to 7. 548 */ 549 if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 8)) { 550 sinfo->txrate.mcs = priv->tx_rate; 551 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; 552 /* 40MHz rate */ 553 if (priv->tx_htinfo & BIT(1)) 554 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 555 /* SGI enabled */ 556 if (priv->tx_htinfo & BIT(2)) 557 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; 558 } 559 560 sinfo->rx_bytes = priv->stats.rx_bytes; 561 sinfo->tx_bytes = priv->stats.tx_bytes; 562 sinfo->rx_packets = priv->stats.rx_packets; 563 sinfo->tx_packets = priv->stats.tx_packets; 564 sinfo->signal = priv->qual_level; 565 /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */ 566 sinfo->txrate.legacy = rate.rate * 5; 567 568 if (priv->bss_mode == NL80211_IFTYPE_STATION) { 569 sinfo->filled |= STATION_INFO_BSS_PARAM; 570 sinfo->bss_param.flags = 0; 571 if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & 572 WLAN_CAPABILITY_SHORT_PREAMBLE) 573 sinfo->bss_param.flags |= 574 BSS_PARAM_FLAGS_SHORT_PREAMBLE; 575 if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & 576 WLAN_CAPABILITY_SHORT_SLOT_TIME) 577 sinfo->bss_param.flags |= 578 BSS_PARAM_FLAGS_SHORT_SLOT_TIME; 579 sinfo->bss_param.dtim_period = priv->dtim_period; 580 sinfo->bss_param.beacon_interval = 581 priv->curr_bss_params.bss_descriptor.beacon_period; 582 } 583 584 return ret; 585} 586 587/* 588 * CFG802.11 operation handler to get station information. 589 * 590 * This function only works in connected mode, and dumps the 591 * requested station information, if available. 592 */ 593static int 594mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, 595 u8 *mac, struct station_info *sinfo) 596{ 597 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 598 599 if (!priv->media_connected) 600 return -ENOENT; 601 if (memcmp(mac, priv->cfg_bssid, ETH_ALEN)) 602 return -ENOENT; 603 604 return mwifiex_dump_station_info(priv, sinfo); 605} 606 607/* Supported rates to be advertised to the cfg80211 */ 608 609static struct ieee80211_rate mwifiex_rates[] = { 610 {.bitrate = 10, .hw_value = 2, }, 611 {.bitrate = 20, .hw_value = 4, }, 612 {.bitrate = 55, .hw_value = 11, }, 613 {.bitrate = 110, .hw_value = 22, }, 614 {.bitrate = 60, .hw_value = 12, }, 615 {.bitrate = 90, .hw_value = 18, }, 616 {.bitrate = 120, .hw_value = 24, }, 617 {.bitrate = 180, .hw_value = 36, }, 618 {.bitrate = 240, .hw_value = 48, }, 619 {.bitrate = 360, .hw_value = 72, }, 620 {.bitrate = 480, .hw_value = 96, }, 621 {.bitrate = 540, .hw_value = 108, }, 622}; 623 624/* Channel definitions to be advertised to cfg80211 */ 625 626static struct ieee80211_channel mwifiex_channels_2ghz[] = { 627 {.center_freq = 2412, .hw_value = 1, }, 628 {.center_freq = 2417, .hw_value = 2, }, 629 {.center_freq = 2422, .hw_value = 3, }, 630 {.center_freq = 2427, .hw_value = 4, }, 631 {.center_freq = 2432, .hw_value = 5, }, 632 {.center_freq = 2437, .hw_value = 6, }, 633 {.center_freq = 2442, .hw_value = 7, }, 634 {.center_freq = 2447, .hw_value = 8, }, 635 {.center_freq = 2452, .hw_value = 9, }, 636 {.center_freq = 2457, .hw_value = 10, }, 637 {.center_freq = 2462, .hw_value = 11, }, 638 {.center_freq = 2467, .hw_value = 12, }, 639 {.center_freq = 2472, .hw_value = 13, }, 640 {.center_freq = 2484, .hw_value = 14, }, 641}; 642 643static struct ieee80211_supported_band mwifiex_band_2ghz = { 644 .channels = mwifiex_channels_2ghz, 645 .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz), 646 .bitrates = mwifiex_rates, 647 .n_bitrates = ARRAY_SIZE(mwifiex_rates), 648}; 649 650static struct ieee80211_channel mwifiex_channels_5ghz[] = { 651 {.center_freq = 5040, .hw_value = 8, }, 652 {.center_freq = 5060, .hw_value = 12, }, 653 {.center_freq = 5080, .hw_value = 16, }, 654 {.center_freq = 5170, .hw_value = 34, }, 655 {.center_freq = 5190, .hw_value = 38, }, 656 {.center_freq = 5210, .hw_value = 42, }, 657 {.center_freq = 5230, .hw_value = 46, }, 658 {.center_freq = 5180, .hw_value = 36, }, 659 {.center_freq = 5200, .hw_value = 40, }, 660 {.center_freq = 5220, .hw_value = 44, }, 661 {.center_freq = 5240, .hw_value = 48, }, 662 {.center_freq = 5260, .hw_value = 52, }, 663 {.center_freq = 5280, .hw_value = 56, }, 664 {.center_freq = 5300, .hw_value = 60, }, 665 {.center_freq = 5320, .hw_value = 64, }, 666 {.center_freq = 5500, .hw_value = 100, }, 667 {.center_freq = 5520, .hw_value = 104, }, 668 {.center_freq = 5540, .hw_value = 108, }, 669 {.center_freq = 5560, .hw_value = 112, }, 670 {.center_freq = 5580, .hw_value = 116, }, 671 {.center_freq = 5600, .hw_value = 120, }, 672 {.center_freq = 5620, .hw_value = 124, }, 673 {.center_freq = 5640, .hw_value = 128, }, 674 {.center_freq = 5660, .hw_value = 132, }, 675 {.center_freq = 5680, .hw_value = 136, }, 676 {.center_freq = 5700, .hw_value = 140, }, 677 {.center_freq = 5745, .hw_value = 149, }, 678 {.center_freq = 5765, .hw_value = 153, }, 679 {.center_freq = 5785, .hw_value = 157, }, 680 {.center_freq = 5805, .hw_value = 161, }, 681 {.center_freq = 5825, .hw_value = 165, }, 682}; 683 684static struct ieee80211_supported_band mwifiex_band_5ghz = { 685 .channels = mwifiex_channels_5ghz, 686 .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz), 687 .bitrates = mwifiex_rates + 4, 688 .n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4, 689}; 690 691 692/* Supported crypto cipher suits to be advertised to cfg80211 */ 693 694static const u32 mwifiex_cipher_suites[] = { 695 WLAN_CIPHER_SUITE_WEP40, 696 WLAN_CIPHER_SUITE_WEP104, 697 WLAN_CIPHER_SUITE_TKIP, 698 WLAN_CIPHER_SUITE_CCMP, 699}; 700 701/* 702 * CFG802.11 operation handler for setting bit rates. 703 * 704 * Function selects legacy bang B/G/BG from corresponding bitrates selection. 705 * Currently only 2.4GHz band is supported. 706 */ 707static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, 708 struct net_device *dev, 709 const u8 *peer, 710 const struct cfg80211_bitrate_mask *mask) 711{ 712 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 713 int index = 0, mode = 0, i; 714 struct mwifiex_adapter *adapter = priv->adapter; 715 716 /* Currently only 2.4GHz is supported */ 717 for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) { 718 /* 719 * Rates below 6 Mbps in the table are CCK rates; 802.11b 720 * and from 6 they are OFDM; 802.11G 721 */ 722 if (mwifiex_rates[i].bitrate == 60) { 723 index = 1 << i; 724 break; 725 } 726 } 727 728 if (mask->control[IEEE80211_BAND_2GHZ].legacy < index) { 729 mode = BAND_B; 730 } else { 731 mode = BAND_G; 732 if (mask->control[IEEE80211_BAND_2GHZ].legacy % index) 733 mode |= BAND_B; 734 } 735 736 if (!((mode | adapter->fw_bands) & ~adapter->fw_bands)) { 737 adapter->config_bands = mode; 738 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { 739 adapter->adhoc_start_band = mode; 740 adapter->adhoc_11n_enabled = false; 741 } 742 } 743 adapter->sec_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; 744 adapter->channel_type = NL80211_CHAN_NO_HT; 745 746 wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", 747 (mode & BAND_B) ? "b" : "", (mode & BAND_G) ? "g" : ""); 748 749 return 0; 750} 751 752/* 753 * CFG802.11 operation handler for disconnection request. 754 * 755 * This function does not work when there is already a disconnection 756 * procedure going on. 757 */ 758static int 759mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, 760 u16 reason_code) 761{ 762 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 763 764 if (mwifiex_deauthenticate(priv, NULL)) 765 return -EFAULT; 766 767 wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" 768 " reason code %d\n", priv->cfg_bssid, reason_code); 769 770 memset(priv->cfg_bssid, 0, ETH_ALEN); 771 772 return 0; 773} 774 775/* 776 * This function informs the CFG802.11 subsystem of a new IBSS. 777 * 778 * The following information are sent to the CFG802.11 subsystem 779 * to register the new IBSS. If we do not register the new IBSS, 780 * a kernel panic will result. 781 * - SSID 782 * - SSID length 783 * - BSSID 784 * - Channel 785 */ 786static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) 787{ 788 struct ieee80211_channel *chan; 789 struct mwifiex_bss_info bss_info; 790 struct cfg80211_bss *bss; 791 int ie_len; 792 u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; 793 enum ieee80211_band band; 794 795 if (mwifiex_get_bss_info(priv, &bss_info)) 796 return -1; 797 798 ie_buf[0] = WLAN_EID_SSID; 799 ie_buf[1] = bss_info.ssid.ssid_len; 800 801 memcpy(&ie_buf[sizeof(struct ieee_types_header)], 802 &bss_info.ssid.ssid, bss_info.ssid.ssid_len); 803 ie_len = ie_buf[1] + sizeof(struct ieee_types_header); 804 805 band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 806 chan = __ieee80211_get_channel(priv->wdev->wiphy, 807 ieee80211_channel_to_frequency(bss_info.bss_chan, 808 band)); 809 810 bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, 811 bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, 812 0, ie_buf, ie_len, 0, GFP_KERNEL); 813 cfg80211_put_bss(bss); 814 memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); 815 816 return 0; 817} 818 819/* 820 * This function connects with a BSS. 821 * 822 * This function handles both Infra and Ad-Hoc modes. It also performs 823 * validity checking on the provided parameters, disconnects from the 824 * current BSS (if any), sets up the association/scan parameters, 825 * including security settings, and performs specific SSID scan before 826 * trying to connect. 827 * 828 * For Infra mode, the function returns failure if the specified SSID 829 * is not found in scan table. However, for Ad-Hoc mode, it can create 830 * the IBSS if it does not exist. On successful completion in either case, 831 * the function notifies the CFG802.11 subsystem of the new BSS connection. 832 */ 833static int 834mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, 835 u8 *bssid, int mode, struct ieee80211_channel *channel, 836 struct cfg80211_connect_params *sme, bool privacy) 837{ 838 struct cfg80211_ssid req_ssid; 839 int ret, auth_type = 0; 840 struct cfg80211_bss *bss = NULL; 841 u8 is_scanning_required = 0; 842 843 memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); 844 845 req_ssid.ssid_len = ssid_len; 846 if (ssid_len > IEEE80211_MAX_SSID_LEN) { 847 dev_err(priv->adapter->dev, "invalid SSID - aborting\n"); 848 return -EINVAL; 849 } 850 851 memcpy(req_ssid.ssid, ssid, ssid_len); 852 if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) { 853 dev_err(priv->adapter->dev, "invalid SSID - aborting\n"); 854 return -EINVAL; 855 } 856 857 /* disconnect before try to associate */ 858 mwifiex_deauthenticate(priv, NULL); 859 860 if (channel) 861 ret = mwifiex_set_rf_channel(priv, channel, 862 priv->adapter->channel_type); 863 864 /* As this is new association, clear locally stored 865 * keys and security related flags */ 866 priv->sec_info.wpa_enabled = false; 867 priv->sec_info.wpa2_enabled = false; 868 priv->wep_key_curr_index = 0; 869 priv->sec_info.encryption_mode = 0; 870 priv->sec_info.is_authtype_auto = 0; 871 ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); 872 873 if (mode == NL80211_IFTYPE_ADHOC) { 874 /* "privacy" is set only for ad-hoc mode */ 875 if (privacy) { 876 /* 877 * Keep WLAN_CIPHER_SUITE_WEP104 for now so that 878 * the firmware can find a matching network from the 879 * scan. The cfg80211 does not give us the encryption 880 * mode at this stage so just setting it to WEP here. 881 */ 882 priv->sec_info.encryption_mode = 883 WLAN_CIPHER_SUITE_WEP104; 884 priv->sec_info.authentication_mode = 885 NL80211_AUTHTYPE_OPEN_SYSTEM; 886 } 887 888 goto done; 889 } 890 891 /* Now handle infra mode. "sme" is valid for infra mode only */ 892 if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) { 893 auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; 894 priv->sec_info.is_authtype_auto = 1; 895 } else { 896 auth_type = sme->auth_type; 897 } 898 899 if (sme->crypto.n_ciphers_pairwise) { 900 priv->sec_info.encryption_mode = 901 sme->crypto.ciphers_pairwise[0]; 902 priv->sec_info.authentication_mode = auth_type; 903 } 904 905 if (sme->crypto.cipher_group) { 906 priv->sec_info.encryption_mode = sme->crypto.cipher_group; 907 priv->sec_info.authentication_mode = auth_type; 908 } 909 if (sme->ie) 910 ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len); 911 912 if (sme->key) { 913 if (mwifiex_is_alg_wep(priv->sec_info.encryption_mode)) { 914 dev_dbg(priv->adapter->dev, 915 "info: setting wep encryption" 916 " with key len %d\n", sme->key_len); 917 priv->wep_key_curr_index = sme->key_idx; 918 ret = mwifiex_set_encode(priv, sme->key, sme->key_len, 919 sme->key_idx, 0); 920 } 921 } 922done: 923 /* 924 * Scan entries are valid for some time (15 sec). So we can save one 925 * active scan time if we just try cfg80211_get_bss first. If it fails 926 * then request scan and cfg80211_get_bss() again for final output. 927 */ 928 while (1) { 929 if (is_scanning_required) { 930 /* Do specific SSID scanning */ 931 if (mwifiex_request_scan(priv, &req_ssid)) { 932 dev_err(priv->adapter->dev, "scan error\n"); 933 return -EFAULT; 934 } 935 } 936 937 /* Find the BSS we want using available scan results */ 938 if (mode == NL80211_IFTYPE_ADHOC) 939 bss = cfg80211_get_bss(priv->wdev->wiphy, channel, 940 bssid, ssid, ssid_len, 941 WLAN_CAPABILITY_IBSS, 942 WLAN_CAPABILITY_IBSS); 943 else 944 bss = cfg80211_get_bss(priv->wdev->wiphy, channel, 945 bssid, ssid, ssid_len, 946 WLAN_CAPABILITY_ESS, 947 WLAN_CAPABILITY_ESS); 948 949 if (!bss) { 950 if (is_scanning_required) { 951 dev_warn(priv->adapter->dev, 952 "assoc: requested bss not found in scan results\n"); 953 break; 954 } 955 is_scanning_required = 1; 956 } else { 957 dev_dbg(priv->adapter->dev, 958 "info: trying to associate to '%s' bssid %pM\n", 959 (char *) req_ssid.ssid, bss->bssid); 960 memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN); 961 break; 962 } 963 } 964 965 if (mwifiex_bss_start(priv, bss, &req_ssid)) 966 return -EFAULT; 967 968 if (mode == NL80211_IFTYPE_ADHOC) { 969 /* Inform the BSS information to kernel, otherwise 970 * kernel will give a panic after successful assoc */ 971 if (mwifiex_cfg80211_inform_ibss_bss(priv)) 972 return -EFAULT; 973 } 974 975 return ret; 976} 977 978/* 979 * CFG802.11 operation handler for association request. 980 * 981 * This function does not work when the current mode is set to Ad-Hoc, or 982 * when there is already an association procedure going on. The given BSS 983 * information is used to associate. 984 */ 985static int 986mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, 987 struct cfg80211_connect_params *sme) 988{ 989 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 990 int ret = 0; 991 992 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { 993 wiphy_err(wiphy, "received infra assoc request " 994 "when station is in ibss mode\n"); 995 goto done; 996 } 997 998 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", 999 (char *) sme->ssid, sme->bssid); 1000 1001 ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, 1002 priv->bss_mode, sme->channel, sme, 0); 1003done: 1004 if (!ret) { 1005 cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0, 1006 NULL, 0, WLAN_STATUS_SUCCESS, 1007 GFP_KERNEL); 1008 dev_dbg(priv->adapter->dev, 1009 "info: associated to bssid %pM successfully\n", 1010 priv->cfg_bssid); 1011 } else { 1012 dev_dbg(priv->adapter->dev, 1013 "info: association to bssid %pM failed\n", 1014 priv->cfg_bssid); 1015 memset(priv->cfg_bssid, 0, ETH_ALEN); 1016 } 1017 1018 return ret; 1019} 1020 1021/* 1022 * CFG802.11 operation handler to join an IBSS. 1023 * 1024 * This function does not work in any mode other than Ad-Hoc, or if 1025 * a join operation is already in progress. 1026 */ 1027static int 1028mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, 1029 struct cfg80211_ibss_params *params) 1030{ 1031 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1032 int ret = 0; 1033 1034 if (priv->bss_mode != NL80211_IFTYPE_ADHOC) { 1035 wiphy_err(wiphy, "request to join ibss received " 1036 "when station is not in ibss mode\n"); 1037 goto done; 1038 } 1039 1040 wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", 1041 (char *) params->ssid, params->bssid); 1042 1043 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, 1044 params->bssid, priv->bss_mode, 1045 params->channel, NULL, params->privacy); 1046done: 1047 if (!ret) { 1048 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); 1049 dev_dbg(priv->adapter->dev, 1050 "info: joined/created adhoc network with bssid" 1051 " %pM successfully\n", priv->cfg_bssid); 1052 } else { 1053 dev_dbg(priv->adapter->dev, 1054 "info: failed creating/joining adhoc network\n"); 1055 } 1056 1057 return ret; 1058} 1059 1060/* 1061 * CFG802.11 operation handler to leave an IBSS. 1062 * 1063 * This function does not work if a leave operation is 1064 * already in progress. 1065 */ 1066static int 1067mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) 1068{ 1069 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1070 1071 wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", 1072 priv->cfg_bssid); 1073 if (mwifiex_deauthenticate(priv, NULL)) 1074 return -EFAULT; 1075 1076 memset(priv->cfg_bssid, 0, ETH_ALEN); 1077 1078 return 0; 1079} 1080 1081/* 1082 * CFG802.11 operation handler for scan request. 1083 * 1084 * This function issues a scan request to the firmware based upon 1085 * the user specified scan configuration. On successfull completion, 1086 * it also informs the results. 1087 */ 1088static int 1089mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, 1090 struct cfg80211_scan_request *request) 1091{ 1092 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1093 int i; 1094 struct ieee80211_channel *chan; 1095 1096 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); 1097 1098 priv->scan_request = request; 1099 1100 priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), 1101 GFP_KERNEL); 1102 if (!priv->user_scan_cfg) { 1103 dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); 1104 return -ENOMEM; 1105 } 1106 1107 priv->user_scan_cfg->num_ssids = request->n_ssids; 1108 priv->user_scan_cfg->ssid_list = request->ssids; 1109 1110 for (i = 0; i < request->n_channels; i++) { 1111 chan = request->channels[i]; 1112 priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; 1113 priv->user_scan_cfg->chan_list[i].radio_type = chan->band; 1114 1115 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) 1116 priv->user_scan_cfg->chan_list[i].scan_type = 1117 MWIFIEX_SCAN_TYPE_PASSIVE; 1118 else 1119 priv->user_scan_cfg->chan_list[i].scan_type = 1120 MWIFIEX_SCAN_TYPE_ACTIVE; 1121 1122 priv->user_scan_cfg->chan_list[i].scan_time = 0; 1123 } 1124 if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg)) 1125 return -EFAULT; 1126 1127 return 0; 1128} 1129 1130/* 1131 * This function sets up the CFG802.11 specific HT capability fields 1132 * with default values. 1133 * 1134 * The following default values are set - 1135 * - HT Supported = True 1136 * - Maximum AMPDU length factor = IEEE80211_HT_MAX_AMPDU_64K 1137 * - Minimum AMPDU spacing = IEEE80211_HT_MPDU_DENSITY_NONE 1138 * - HT Capabilities supported by firmware 1139 * - MCS information, Rx mask = 0xff 1140 * - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01) 1141 */ 1142static void 1143mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, 1144 struct mwifiex_private *priv) 1145{ 1146 int rx_mcs_supp; 1147 struct ieee80211_mcs_info mcs_set; 1148 u8 *mcs = (u8 *)&mcs_set; 1149 struct mwifiex_adapter *adapter = priv->adapter; 1150 1151 ht_info->ht_supported = true; 1152 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 1153 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; 1154 1155 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); 1156 1157 /* Fill HT capability information */ 1158 if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) 1159 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 1160 else 1161 ht_info->cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 1162 1163 if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap)) 1164 ht_info->cap |= IEEE80211_HT_CAP_SGI_20; 1165 else 1166 ht_info->cap &= ~IEEE80211_HT_CAP_SGI_20; 1167 1168 if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap)) 1169 ht_info->cap |= IEEE80211_HT_CAP_SGI_40; 1170 else 1171 ht_info->cap &= ~IEEE80211_HT_CAP_SGI_40; 1172 1173 if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap)) 1174 ht_info->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; 1175 else 1176 ht_info->cap &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT); 1177 1178 if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap)) 1179 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; 1180 else 1181 ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC; 1182 1183 ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; 1184 ht_info->cap |= IEEE80211_HT_CAP_SM_PS; 1185 1186 rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support); 1187 /* Set MCS for 1x1 */ 1188 memset(mcs, 0xff, rx_mcs_supp); 1189 /* Clear all the other values */ 1190 memset(&mcs[rx_mcs_supp], 0, 1191 sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); 1192 if (priv->bss_mode == NL80211_IFTYPE_STATION || 1193 ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) 1194 /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ 1195 SETHT_MCS32(mcs_set.rx_mask); 1196 1197 memcpy((u8 *) &ht_info->mcs, mcs, sizeof(struct ieee80211_mcs_info)); 1198 1199 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 1200} 1201 1202/* 1203 * create a new virtual interface with the given name 1204 */ 1205struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, 1206 char *name, 1207 enum nl80211_iftype type, 1208 u32 *flags, 1209 struct vif_params *params) 1210{ 1211 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 1212 struct mwifiex_adapter *adapter; 1213 struct net_device *dev; 1214 void *mdev_priv; 1215 1216 if (!priv) 1217 return ERR_PTR(-EFAULT); 1218 1219 adapter = priv->adapter; 1220 if (!adapter) 1221 return ERR_PTR(-EFAULT); 1222 1223 switch (type) { 1224 case NL80211_IFTYPE_UNSPECIFIED: 1225 case NL80211_IFTYPE_STATION: 1226 case NL80211_IFTYPE_ADHOC: 1227 if (priv->bss_mode) { 1228 wiphy_err(wiphy, "cannot create multiple" 1229 " station/adhoc interfaces\n"); 1230 return ERR_PTR(-EINVAL); 1231 } 1232 1233 if (type == NL80211_IFTYPE_UNSPECIFIED) 1234 priv->bss_mode = NL80211_IFTYPE_STATION; 1235 else 1236 priv->bss_mode = type; 1237 1238 priv->bss_type = MWIFIEX_BSS_TYPE_STA; 1239 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; 1240 priv->bss_priority = 0; 1241 priv->bss_role = MWIFIEX_BSS_ROLE_STA; 1242 priv->bss_num = 0; 1243 1244 break; 1245 default: 1246 wiphy_err(wiphy, "type not supported\n"); 1247 return ERR_PTR(-EINVAL); 1248 } 1249 1250 dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, 1251 ether_setup, 1); 1252 if (!dev) { 1253 wiphy_err(wiphy, "no memory available for netdevice\n"); 1254 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 1255 return ERR_PTR(-ENOMEM); 1256 } 1257 1258 dev_net_set(dev, wiphy_net(wiphy)); 1259 dev->ieee80211_ptr = priv->wdev; 1260 dev->ieee80211_ptr->iftype = priv->bss_mode; 1261 memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN); 1262 memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN); 1263 SET_NETDEV_DEV(dev, wiphy_dev(wiphy)); 1264 1265 dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 1266 dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT; 1267 dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN; 1268 1269 mdev_priv = netdev_priv(dev); 1270 *((unsigned long *) mdev_priv) = (unsigned long) priv; 1271 1272 priv->netdev = dev; 1273 mwifiex_init_priv_params(priv, dev); 1274 1275 SET_NETDEV_DEV(dev, adapter->dev); 1276 1277 /* Register network device */ 1278 if (register_netdevice(dev)) { 1279 wiphy_err(wiphy, "cannot register virtual network device\n"); 1280 free_netdev(dev); 1281 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 1282 return ERR_PTR(-EFAULT); 1283 } 1284 1285 sema_init(&priv->async_sem, 1); 1286 priv->scan_pending_on_block = false; 1287 1288 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); 1289 1290#ifdef CONFIG_DEBUG_FS 1291 mwifiex_dev_debugfs_init(priv); 1292#endif 1293 return dev; 1294} 1295EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); 1296 1297/* 1298 * del_virtual_intf: remove the virtual interface determined by dev 1299 */ 1300int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) 1301{ 1302 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1303 1304#ifdef CONFIG_DEBUG_FS 1305 mwifiex_dev_debugfs_remove(priv); 1306#endif 1307 1308 if (!netif_queue_stopped(priv->netdev)) 1309 netif_stop_queue(priv->netdev); 1310 1311 if (netif_carrier_ok(priv->netdev)) 1312 netif_carrier_off(priv->netdev); 1313 1314 if (dev->reg_state == NETREG_REGISTERED) 1315 unregister_netdevice(dev); 1316 1317 if (dev->reg_state == NETREG_UNREGISTERED) 1318 free_netdev(dev); 1319 1320 /* Clear the priv in adapter */ 1321 priv->netdev = NULL; 1322 1323 priv->media_connected = false; 1324 1325 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 1326 1327 return 0; 1328} 1329EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf); 1330 1331/* station cfg80211 operations */ 1332static struct cfg80211_ops mwifiex_cfg80211_ops = { 1333 .add_virtual_intf = mwifiex_add_virtual_intf, 1334 .del_virtual_intf = mwifiex_del_virtual_intf, 1335 .change_virtual_intf = mwifiex_cfg80211_change_virtual_intf, 1336 .scan = mwifiex_cfg80211_scan, 1337 .connect = mwifiex_cfg80211_connect, 1338 .disconnect = mwifiex_cfg80211_disconnect, 1339 .get_station = mwifiex_cfg80211_get_station, 1340 .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params, 1341 .set_channel = mwifiex_cfg80211_set_channel, 1342 .join_ibss = mwifiex_cfg80211_join_ibss, 1343 .leave_ibss = mwifiex_cfg80211_leave_ibss, 1344 .add_key = mwifiex_cfg80211_add_key, 1345 .del_key = mwifiex_cfg80211_del_key, 1346 .set_default_key = mwifiex_cfg80211_set_default_key, 1347 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, 1348 .set_tx_power = mwifiex_cfg80211_set_tx_power, 1349 .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask, 1350}; 1351 1352/* 1353 * This function registers the device with CFG802.11 subsystem. 1354 * 1355 * The function creates the wireless device/wiphy, populates it with 1356 * default parameters and handler function pointers, and finally 1357 * registers the device. 1358 */ 1359int mwifiex_register_cfg80211(struct mwifiex_private *priv) 1360{ 1361 int ret; 1362 void *wdev_priv; 1363 struct wireless_dev *wdev; 1364 struct ieee80211_sta_ht_cap *ht_info; 1365 1366 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 1367 if (!wdev) { 1368 dev_err(priv->adapter->dev, "%s: allocating wireless device\n", 1369 __func__); 1370 return -ENOMEM; 1371 } 1372 wdev->wiphy = 1373 wiphy_new(&mwifiex_cfg80211_ops, 1374 sizeof(struct mwifiex_private *)); 1375 if (!wdev->wiphy) { 1376 kfree(wdev); 1377 return -ENOMEM; 1378 } 1379 wdev->iftype = NL80211_IFTYPE_STATION; 1380 wdev->wiphy->max_scan_ssids = 10; 1381 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1382 BIT(NL80211_IFTYPE_ADHOC); 1383 1384 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; 1385 ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap; 1386 mwifiex_setup_ht_caps(ht_info, priv); 1387 1388 if (priv->adapter->config_bands & BAND_A) { 1389 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; 1390 ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap; 1391 mwifiex_setup_ht_caps(ht_info, priv); 1392 } else { 1393 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; 1394 } 1395 1396 /* Initialize cipher suits */ 1397 wdev->wiphy->cipher_suites = mwifiex_cipher_suites; 1398 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); 1399 1400 memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN); 1401 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 1402 1403 /* Reserve space for bss band information */ 1404 wdev->wiphy->bss_priv_size = sizeof(u8); 1405 1406 wdev->wiphy->reg_notifier = mwifiex_reg_notifier; 1407 1408 /* Set struct mwifiex_private pointer in wiphy_priv */ 1409 wdev_priv = wiphy_priv(wdev->wiphy); 1410 1411 *(unsigned long *) wdev_priv = (unsigned long) priv; 1412 1413 set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev); 1414 1415 ret = wiphy_register(wdev->wiphy); 1416 if (ret < 0) { 1417 dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", 1418 __func__); 1419 wiphy_free(wdev->wiphy); 1420 kfree(wdev); 1421 return ret; 1422 } else { 1423 dev_dbg(priv->adapter->dev, 1424 "info: successfully registered wiphy device\n"); 1425 } 1426 1427 priv->wdev = wdev; 1428 1429 return ret; 1430} 1431