1 /* 2 * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 19 #include <linux/module.h> 20 #include <linux/firmware.h> 21 #include <linux/platform_device.h> 22 #include <linux/of.h> 23 #include <linux/of_address.h> 24 #include <linux/rpmsg.h> 25 #include <linux/soc/qcom/smem_state.h> 26 #include <linux/soc/qcom/wcnss_ctrl.h> 27 #include <net/ipv6.h> 28 #include "wcn36xx.h" 29 #include "testmode.h" 30 #include "firmware.h" 31 32 unsigned int wcn36xx_dbg_mask; 33 module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644); 34 MODULE_PARM_DESC(debug_mask, "Debugging mask"); 35 36 #define CHAN2G(_freq, _idx) { \ 37 .band = NL80211_BAND_2GHZ, \ 38 .center_freq = (_freq), \ 39 .hw_value = (_idx), \ 40 .max_power = 25, \ 41 } 42 43 #define CHAN5G(_freq, _idx, _phy_val) { \ 44 .band = NL80211_BAND_5GHZ, \ 45 .center_freq = (_freq), \ 46 .hw_value = (_phy_val) << HW_VALUE_PHY_SHIFT | HW_VALUE_CHANNEL(_idx), \ 47 .max_power = 25, \ 48 } 49 50 /* The wcn firmware expects channel values to matching 51 * their mnemonic values. So use these for .hw_value. */ 52 static struct ieee80211_channel wcn_2ghz_channels[] = { 53 CHAN2G(2412, 1), /* Channel 1 */ 54 CHAN2G(2417, 2), /* Channel 2 */ 55 CHAN2G(2422, 3), /* Channel 3 */ 56 CHAN2G(2427, 4), /* Channel 4 */ 57 CHAN2G(2432, 5), /* Channel 5 */ 58 CHAN2G(2437, 6), /* Channel 6 */ 59 CHAN2G(2442, 7), /* Channel 7 */ 60 CHAN2G(2447, 8), /* Channel 8 */ 61 CHAN2G(2452, 9), /* Channel 9 */ 62 CHAN2G(2457, 10), /* Channel 10 */ 63 CHAN2G(2462, 11), /* Channel 11 */ 64 CHAN2G(2467, 12), /* Channel 12 */ 65 CHAN2G(2472, 13), /* Channel 13 */ 66 CHAN2G(2484, 14) /* Channel 14 */ 67 68 }; 69 70 static struct ieee80211_channel wcn_5ghz_channels[] = { 71 CHAN5G(5180, 36, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW), 72 CHAN5G(5200, 40, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW), 73 CHAN5G(5220, 44, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), 74 CHAN5G(5240, 48, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH), 75 CHAN5G(5260, 52, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW), 76 CHAN5G(5280, 56, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW), 77 CHAN5G(5300, 60, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), 78 CHAN5G(5320, 64, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH), 79 CHAN5G(5500, 100, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW), 80 CHAN5G(5520, 104, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW), 81 CHAN5G(5540, 108, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), 82 CHAN5G(5560, 112, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH), 83 CHAN5G(5580, 116, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW), 84 CHAN5G(5600, 120, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW), 85 CHAN5G(5620, 124, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), 86 CHAN5G(5640, 128, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH), 87 CHAN5G(5660, 132, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW), 88 CHAN5G(5680, 136, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW), 89 CHAN5G(5700, 140, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), 90 CHAN5G(5720, 144, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH), 91 CHAN5G(5745, 149, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW), 92 CHAN5G(5765, 153, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW), 93 CHAN5G(5785, 157, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), 94 CHAN5G(5805, 161, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH), 95 CHAN5G(5825, 165, 0) 96 }; 97 98 #define RATE(_bitrate, _hw_rate, _flags) { \ 99 .bitrate = (_bitrate), \ 100 .flags = (_flags), \ 101 .hw_value = (_hw_rate), \ 102 .hw_value_short = (_hw_rate) \ 103 } 104 105 static struct ieee80211_rate wcn_2ghz_rates[] = { 106 RATE(10, HW_RATE_INDEX_1MBPS, 0), 107 RATE(20, HW_RATE_INDEX_2MBPS, IEEE80211_RATE_SHORT_PREAMBLE), 108 RATE(55, HW_RATE_INDEX_5_5MBPS, IEEE80211_RATE_SHORT_PREAMBLE), 109 RATE(110, HW_RATE_INDEX_11MBPS, IEEE80211_RATE_SHORT_PREAMBLE), 110 RATE(60, HW_RATE_INDEX_6MBPS, 0), 111 RATE(90, HW_RATE_INDEX_9MBPS, 0), 112 RATE(120, HW_RATE_INDEX_12MBPS, 0), 113 RATE(180, HW_RATE_INDEX_18MBPS, 0), 114 RATE(240, HW_RATE_INDEX_24MBPS, 0), 115 RATE(360, HW_RATE_INDEX_36MBPS, 0), 116 RATE(480, HW_RATE_INDEX_48MBPS, 0), 117 RATE(540, HW_RATE_INDEX_54MBPS, 0) 118 }; 119 120 static struct ieee80211_rate wcn_5ghz_rates[] = { 121 RATE(60, HW_RATE_INDEX_6MBPS, 0), 122 RATE(90, HW_RATE_INDEX_9MBPS, 0), 123 RATE(120, HW_RATE_INDEX_12MBPS, 0), 124 RATE(180, HW_RATE_INDEX_18MBPS, 0), 125 RATE(240, HW_RATE_INDEX_24MBPS, 0), 126 RATE(360, HW_RATE_INDEX_36MBPS, 0), 127 RATE(480, HW_RATE_INDEX_48MBPS, 0), 128 RATE(540, HW_RATE_INDEX_54MBPS, 0) 129 }; 130 131 static struct ieee80211_supported_band wcn_band_2ghz = { 132 .channels = wcn_2ghz_channels, 133 .n_channels = ARRAY_SIZE(wcn_2ghz_channels), 134 .bitrates = wcn_2ghz_rates, 135 .n_bitrates = ARRAY_SIZE(wcn_2ghz_rates), 136 .ht_cap = { 137 .cap = IEEE80211_HT_CAP_GRN_FLD | 138 IEEE80211_HT_CAP_SGI_20 | 139 IEEE80211_HT_CAP_DSSSCCK40 | 140 IEEE80211_HT_CAP_LSIG_TXOP_PROT | 141 IEEE80211_HT_CAP_SGI_40 | 142 IEEE80211_HT_CAP_SUP_WIDTH_20_40, 143 .ht_supported = true, 144 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, 145 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 146 .mcs = { 147 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 148 .rx_highest = cpu_to_le16(72), 149 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, 150 } 151 } 152 }; 153 154 static struct ieee80211_supported_band wcn_band_5ghz = { 155 .channels = wcn_5ghz_channels, 156 .n_channels = ARRAY_SIZE(wcn_5ghz_channels), 157 .bitrates = wcn_5ghz_rates, 158 .n_bitrates = ARRAY_SIZE(wcn_5ghz_rates), 159 .ht_cap = { 160 .cap = IEEE80211_HT_CAP_GRN_FLD | 161 IEEE80211_HT_CAP_SGI_20 | 162 IEEE80211_HT_CAP_DSSSCCK40 | 163 IEEE80211_HT_CAP_LSIG_TXOP_PROT | 164 IEEE80211_HT_CAP_SGI_40 | 165 IEEE80211_HT_CAP_SUP_WIDTH_20_40, 166 .ht_supported = true, 167 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, 168 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 169 .mcs = { 170 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 171 .rx_highest = cpu_to_le16(150), 172 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, 173 } 174 } 175 }; 176 177 #ifdef CONFIG_PM 178 179 static const struct wiphy_wowlan_support wowlan_support = { 180 .flags = WIPHY_WOWLAN_ANY | 181 WIPHY_WOWLAN_MAGIC_PKT | 182 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY 183 }; 184 185 #endif 186 187 static inline u8 get_sta_index(struct ieee80211_vif *vif, 188 struct wcn36xx_sta *sta_priv) 189 { 190 return NL80211_IFTYPE_STATION == vif->type ? 191 sta_priv->bss_sta_index : 192 sta_priv->sta_index; 193 } 194 195 static void wcn36xx_feat_caps_info(struct wcn36xx *wcn) 196 { 197 int i; 198 199 for (i = 0; i < MAX_FEATURE_SUPPORTED; i++) { 200 if (wcn36xx_firmware_get_feat_caps(wcn->fw_feat_caps, i)) { 201 wcn36xx_dbg(WCN36XX_DBG_MAC, "FW Cap %s\n", 202 wcn36xx_firmware_get_cap_name(i)); 203 } 204 } 205 } 206 207 static int wcn36xx_start(struct ieee80211_hw *hw) 208 { 209 struct wcn36xx *wcn = hw->priv; 210 int ret; 211 212 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac start\n"); 213 214 /* SMD initialization */ 215 ret = wcn36xx_smd_open(wcn); 216 if (ret) { 217 wcn36xx_err("Failed to open smd channel: %d\n", ret); 218 goto out_err; 219 } 220 221 /* Allocate memory pools for Mgmt BD headers and Data BD headers */ 222 ret = wcn36xx_dxe_allocate_mem_pools(wcn); 223 if (ret) { 224 wcn36xx_err("Failed to alloc DXE mempool: %d\n", ret); 225 goto out_smd_close; 226 } 227 228 ret = wcn36xx_dxe_alloc_ctl_blks(wcn); 229 if (ret) { 230 wcn36xx_err("Failed to alloc DXE ctl blocks: %d\n", ret); 231 goto out_free_dxe_pool; 232 } 233 234 ret = wcn36xx_smd_load_nv(wcn); 235 if (ret) { 236 wcn36xx_err("Failed to push NV to chip\n"); 237 goto out_free_dxe_ctl; 238 } 239 240 ret = wcn36xx_smd_start(wcn); 241 if (ret) { 242 wcn36xx_err("Failed to start chip\n"); 243 goto out_free_dxe_ctl; 244 } 245 246 if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { 247 ret = wcn36xx_smd_feature_caps_exchange(wcn); 248 if (ret) 249 wcn36xx_warn("Exchange feature caps failed\n"); 250 else 251 wcn36xx_feat_caps_info(wcn); 252 } 253 254 /* DMA channel initialization */ 255 ret = wcn36xx_dxe_init(wcn); 256 if (ret) { 257 wcn36xx_err("DXE init failed\n"); 258 goto out_smd_stop; 259 } 260 261 wcn36xx_debugfs_init(wcn); 262 263 INIT_LIST_HEAD(&wcn->vif_list); 264 spin_lock_init(&wcn->dxe_lock); 265 spin_lock_init(&wcn->survey_lock); 266 267 return 0; 268 269 out_smd_stop: 270 wcn36xx_smd_stop(wcn); 271 out_free_dxe_ctl: 272 wcn36xx_dxe_free_ctl_blks(wcn); 273 out_free_dxe_pool: 274 wcn36xx_dxe_free_mem_pools(wcn); 275 out_smd_close: 276 wcn36xx_smd_close(wcn); 277 out_err: 278 return ret; 279 } 280 281 static void wcn36xx_stop(struct ieee80211_hw *hw) 282 { 283 struct wcn36xx *wcn = hw->priv; 284 285 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac stop\n"); 286 287 mutex_lock(&wcn->scan_lock); 288 if (wcn->scan_req) { 289 struct cfg80211_scan_info scan_info = { 290 .aborted = true, 291 }; 292 293 ieee80211_scan_completed(wcn->hw, &scan_info); 294 } 295 wcn->scan_req = NULL; 296 mutex_unlock(&wcn->scan_lock); 297 298 wcn36xx_debugfs_exit(wcn); 299 wcn36xx_smd_stop(wcn); 300 wcn36xx_dxe_deinit(wcn); 301 wcn36xx_smd_close(wcn); 302 303 wcn36xx_dxe_free_mem_pools(wcn); 304 wcn36xx_dxe_free_ctl_blks(wcn); 305 } 306 307 static void wcn36xx_change_ps(struct wcn36xx *wcn, bool enable) 308 { 309 struct ieee80211_vif *vif = NULL; 310 struct wcn36xx_vif *tmp; 311 312 list_for_each_entry(tmp, &wcn->vif_list, list) { 313 vif = wcn36xx_priv_to_vif(tmp); 314 if (enable && !wcn->sw_scan) { 315 if (vif->cfg.ps) /* ps allowed ? */ 316 wcn36xx_pmc_enter_bmps_state(wcn, vif); 317 } else { 318 wcn36xx_pmc_exit_bmps_state(wcn, vif); 319 } 320 } 321 } 322 323 static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch) 324 { 325 struct ieee80211_vif *vif = NULL; 326 struct wcn36xx_vif *tmp; 327 struct ieee80211_supported_band *band; 328 struct ieee80211_channel *channel = NULL; 329 unsigned long flags; 330 int i, j; 331 332 for (i = 0; i < ARRAY_SIZE(wcn->hw->wiphy->bands); i++) { 333 band = wcn->hw->wiphy->bands[i]; 334 if (!band) 335 break; 336 for (j = 0; j < band->n_channels; j++) { 337 if (HW_VALUE_CHANNEL(band->channels[j].hw_value) == ch) { 338 channel = &band->channels[j]; 339 break; 340 } 341 } 342 if (channel) 343 break; 344 } 345 346 if (!channel) { 347 wcn36xx_err("Cannot tune to channel %d\n", ch); 348 return; 349 } 350 351 spin_lock_irqsave(&wcn->survey_lock, flags); 352 wcn->band = band; 353 wcn->channel = channel; 354 spin_unlock_irqrestore(&wcn->survey_lock, flags); 355 356 list_for_each_entry(tmp, &wcn->vif_list, list) { 357 vif = wcn36xx_priv_to_vif(tmp); 358 wcn36xx_smd_switch_channel(wcn, vif, ch); 359 } 360 361 return; 362 } 363 364 static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) 365 { 366 struct wcn36xx *wcn = hw->priv; 367 int ret; 368 369 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x\n", changed); 370 371 mutex_lock(&wcn->conf_mutex); 372 373 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 374 int ch = WCN36XX_HW_CHANNEL(wcn); 375 wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n", 376 ch); 377 378 if (wcn->sw_scan_opchannel == ch && wcn->sw_scan_channel) { 379 /* If channel is the initial operating channel, we may 380 * want to receive/transmit regular data packets, then 381 * simply stop the scan session and exit PS mode. 382 */ 383 if (wcn->sw_scan_channel) 384 wcn36xx_smd_end_scan(wcn, wcn->sw_scan_channel); 385 if (wcn->sw_scan_init) { 386 wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN, 387 wcn->sw_scan_vif); 388 } 389 } else if (wcn->sw_scan) { 390 /* A scan is ongoing, do not change the operating 391 * channel, but start a scan session on the channel. 392 */ 393 if (wcn->sw_scan_channel) 394 wcn36xx_smd_end_scan(wcn, wcn->sw_scan_channel); 395 if (!wcn->sw_scan_init) { 396 /* This can fail if we are unable to notify the 397 * operating channel. 398 */ 399 ret = wcn36xx_smd_init_scan(wcn, 400 HAL_SYS_MODE_SCAN, 401 wcn->sw_scan_vif); 402 if (ret) { 403 mutex_unlock(&wcn->conf_mutex); 404 return -EIO; 405 } 406 } 407 wcn36xx_smd_start_scan(wcn, ch); 408 } else { 409 wcn36xx_change_opchannel(wcn, ch); 410 } 411 } 412 413 if (changed & IEEE80211_CONF_CHANGE_PS) 414 wcn36xx_change_ps(wcn, hw->conf.flags & IEEE80211_CONF_PS); 415 416 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 417 if (hw->conf.flags & IEEE80211_CONF_IDLE) 418 wcn36xx_smd_enter_imps(wcn); 419 else 420 wcn36xx_smd_exit_imps(wcn); 421 } 422 423 mutex_unlock(&wcn->conf_mutex); 424 425 return 0; 426 } 427 428 static void wcn36xx_configure_filter(struct ieee80211_hw *hw, 429 unsigned int changed, 430 unsigned int *total, u64 multicast) 431 { 432 struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp; 433 struct wcn36xx *wcn = hw->priv; 434 struct wcn36xx_vif *tmp; 435 struct ieee80211_vif *vif = NULL; 436 437 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n"); 438 439 mutex_lock(&wcn->conf_mutex); 440 441 *total &= FIF_ALLMULTI; 442 443 fp = (void *)(unsigned long)multicast; 444 list_for_each_entry(tmp, &wcn->vif_list, list) { 445 vif = wcn36xx_priv_to_vif(tmp); 446 447 /* FW handles MC filtering only when connected as STA */ 448 if (*total & FIF_ALLMULTI) 449 wcn36xx_smd_set_mc_list(wcn, vif, NULL); 450 else if (NL80211_IFTYPE_STATION == vif->type && tmp->sta_assoc) 451 wcn36xx_smd_set_mc_list(wcn, vif, fp); 452 } 453 454 mutex_unlock(&wcn->conf_mutex); 455 kfree(fp); 456 } 457 458 static u64 wcn36xx_prepare_multicast(struct ieee80211_hw *hw, 459 struct netdev_hw_addr_list *mc_list) 460 { 461 struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp; 462 struct netdev_hw_addr *ha; 463 464 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac prepare multicast list\n"); 465 fp = kzalloc(sizeof(*fp), GFP_ATOMIC); 466 if (!fp) { 467 wcn36xx_err("Out of memory setting filters.\n"); 468 return 0; 469 } 470 471 fp->mc_addr_count = 0; 472 /* update multicast filtering parameters */ 473 if (netdev_hw_addr_list_count(mc_list) <= 474 WCN36XX_HAL_MAX_NUM_MULTICAST_ADDRESS) { 475 netdev_hw_addr_list_for_each(ha, mc_list) { 476 memcpy(fp->mc_addr[fp->mc_addr_count], 477 ha->addr, ETH_ALEN); 478 fp->mc_addr_count++; 479 } 480 } 481 482 return (u64)(unsigned long)fp; 483 } 484 485 static void wcn36xx_tx(struct ieee80211_hw *hw, 486 struct ieee80211_tx_control *control, 487 struct sk_buff *skb) 488 { 489 struct wcn36xx *wcn = hw->priv; 490 struct wcn36xx_sta *sta_priv = NULL; 491 492 if (control->sta) 493 sta_priv = wcn36xx_sta_to_priv(control->sta); 494 495 if (wcn36xx_start_tx(wcn, sta_priv, skb)) 496 ieee80211_free_txskb(wcn->hw, skb); 497 } 498 499 static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 500 struct ieee80211_vif *vif, 501 struct ieee80211_sta *sta, 502 struct ieee80211_key_conf *key_conf) 503 { 504 struct wcn36xx *wcn = hw->priv; 505 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 506 struct wcn36xx_sta *sta_priv = sta ? wcn36xx_sta_to_priv(sta) : NULL; 507 int ret = 0; 508 u8 key[WLAN_MAX_KEY_LEN]; 509 510 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 set key\n"); 511 wcn36xx_dbg(WCN36XX_DBG_MAC, "Key: cmd=0x%x algo:0x%x, id:%d, len:%d flags 0x%x\n", 512 cmd, key_conf->cipher, key_conf->keyidx, 513 key_conf->keylen, key_conf->flags); 514 wcn36xx_dbg_dump(WCN36XX_DBG_MAC, "KEY: ", 515 key_conf->key, 516 key_conf->keylen); 517 518 mutex_lock(&wcn->conf_mutex); 519 520 switch (key_conf->cipher) { 521 case WLAN_CIPHER_SUITE_WEP40: 522 vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP40; 523 break; 524 case WLAN_CIPHER_SUITE_WEP104: 525 vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP104; 526 break; 527 case WLAN_CIPHER_SUITE_CCMP: 528 vif_priv->encrypt_type = WCN36XX_HAL_ED_CCMP; 529 break; 530 case WLAN_CIPHER_SUITE_TKIP: 531 vif_priv->encrypt_type = WCN36XX_HAL_ED_TKIP; 532 break; 533 default: 534 wcn36xx_err("Unsupported key type 0x%x\n", 535 key_conf->cipher); 536 ret = -EOPNOTSUPP; 537 goto out; 538 } 539 540 switch (cmd) { 541 case SET_KEY: 542 if (WCN36XX_HAL_ED_TKIP == vif_priv->encrypt_type) { 543 /* 544 * Supplicant is sending key in the wrong order: 545 * Temporal Key (16 b) - TX MIC (8 b) - RX MIC (8 b) 546 * but HW expects it to be in the order as described in 547 * IEEE 802.11 spec (see chapter 11.7) like this: 548 * Temporal Key (16 b) - RX MIC (8 b) - TX MIC (8 b) 549 */ 550 memcpy(key, key_conf->key, 16); 551 memcpy(key + 16, key_conf->key + 24, 8); 552 memcpy(key + 24, key_conf->key + 16, 8); 553 } else { 554 memcpy(key, key_conf->key, key_conf->keylen); 555 } 556 557 if (IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags) { 558 sta_priv->is_data_encrypted = true; 559 /* Reconfigure bss with encrypt_type */ 560 if (NL80211_IFTYPE_STATION == vif->type) { 561 wcn36xx_smd_config_bss(wcn, 562 vif, 563 sta, 564 sta->addr, 565 true); 566 wcn36xx_smd_config_sta(wcn, vif, sta); 567 } 568 569 wcn36xx_smd_set_stakey(wcn, 570 vif_priv->encrypt_type, 571 key_conf->keyidx, 572 key_conf->keylen, 573 key, 574 get_sta_index(vif, sta_priv)); 575 } else { 576 wcn36xx_smd_set_bsskey(wcn, 577 vif_priv->encrypt_type, 578 vif_priv->bss_index, 579 key_conf->keyidx, 580 key_conf->keylen, 581 key); 582 583 if ((WLAN_CIPHER_SUITE_WEP40 == key_conf->cipher) || 584 (WLAN_CIPHER_SUITE_WEP104 == key_conf->cipher)) { 585 list_for_each_entry(sta_priv, 586 &vif_priv->sta_list, list) { 587 sta_priv->is_data_encrypted = true; 588 wcn36xx_smd_set_stakey(wcn, 589 vif_priv->encrypt_type, 590 key_conf->keyidx, 591 key_conf->keylen, 592 key, 593 get_sta_index(vif, sta_priv)); 594 } 595 } 596 } 597 break; 598 case DISABLE_KEY: 599 if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) { 600 if (vif_priv->bss_index != WCN36XX_HAL_BSS_INVALID_IDX) 601 wcn36xx_smd_remove_bsskey(wcn, 602 vif_priv->encrypt_type, 603 vif_priv->bss_index, 604 key_conf->keyidx); 605 606 vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE; 607 } else { 608 sta_priv->is_data_encrypted = false; 609 /* do not remove key if disassociated */ 610 if (sta_priv->aid) 611 wcn36xx_smd_remove_stakey(wcn, 612 vif_priv->encrypt_type, 613 key_conf->keyidx, 614 get_sta_index(vif, sta_priv)); 615 } 616 break; 617 default: 618 wcn36xx_err("Unsupported key cmd 0x%x\n", cmd); 619 ret = -EOPNOTSUPP; 620 goto out; 621 } 622 623 out: 624 mutex_unlock(&wcn->conf_mutex); 625 626 return ret; 627 } 628 629 static int wcn36xx_hw_scan(struct ieee80211_hw *hw, 630 struct ieee80211_vif *vif, 631 struct ieee80211_scan_request *hw_req) 632 { 633 struct wcn36xx *wcn = hw->priv; 634 635 if (!wcn36xx_firmware_get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) { 636 /* fallback to mac80211 software scan */ 637 return 1; 638 } 639 640 /* Firmware scan offload is limited to 48 channels, fallback to 641 * software driven scanning otherwise. 642 */ 643 if (hw_req->req.n_channels > 48) { 644 wcn36xx_warn("Offload scan aborted, n_channels=%u", 645 hw_req->req.n_channels); 646 return 1; 647 } 648 649 mutex_lock(&wcn->scan_lock); 650 if (wcn->scan_req) { 651 mutex_unlock(&wcn->scan_lock); 652 return -EBUSY; 653 } 654 655 wcn->scan_aborted = false; 656 wcn->scan_req = &hw_req->req; 657 658 mutex_unlock(&wcn->scan_lock); 659 660 wcn36xx_smd_update_channel_list(wcn, &hw_req->req); 661 return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req); 662 } 663 664 static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw, 665 struct ieee80211_vif *vif) 666 { 667 struct wcn36xx *wcn = hw->priv; 668 669 mutex_lock(&wcn->scan_lock); 670 wcn->scan_aborted = true; 671 mutex_unlock(&wcn->scan_lock); 672 673 if (wcn36xx_firmware_get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) { 674 /* ieee80211_scan_completed will be called on FW scan 675 * indication */ 676 wcn36xx_smd_stop_hw_scan(wcn); 677 } 678 } 679 680 static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw, 681 struct ieee80211_vif *vif, 682 const u8 *mac_addr) 683 { 684 struct wcn36xx *wcn = hw->priv; 685 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 686 687 wcn36xx_dbg(WCN36XX_DBG_MAC, "sw_scan_start"); 688 689 wcn->sw_scan = true; 690 wcn->sw_scan_vif = vif; 691 wcn->sw_scan_channel = 0; 692 if (vif_priv->sta_assoc) 693 wcn->sw_scan_opchannel = WCN36XX_HW_CHANNEL(wcn); 694 else 695 wcn->sw_scan_opchannel = 0; 696 } 697 698 static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw, 699 struct ieee80211_vif *vif) 700 { 701 struct wcn36xx *wcn = hw->priv; 702 703 wcn36xx_dbg(WCN36XX_DBG_MAC, "sw_scan_complete"); 704 705 /* ensure that any scan session is finished */ 706 if (wcn->sw_scan_channel) 707 wcn36xx_smd_end_scan(wcn, wcn->sw_scan_channel); 708 if (wcn->sw_scan_init) { 709 wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN, 710 wcn->sw_scan_vif); 711 } 712 wcn->sw_scan = false; 713 wcn->sw_scan_opchannel = 0; 714 } 715 716 static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta, 717 enum nl80211_band band) 718 { 719 int i, size; 720 u16 *rates_table; 721 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); 722 u32 rates = sta->deflink.supp_rates[band]; 723 724 memset(&sta_priv->supported_rates, 0, 725 sizeof(sta_priv->supported_rates)); 726 sta_priv->supported_rates.op_rate_mode = STA_11n; 727 728 size = ARRAY_SIZE(sta_priv->supported_rates.dsss_rates); 729 rates_table = sta_priv->supported_rates.dsss_rates; 730 if (band == NL80211_BAND_2GHZ) { 731 for (i = 0; i < size; i++) { 732 if (rates & 0x01) { 733 rates_table[i] = wcn_2ghz_rates[i].hw_value; 734 rates = rates >> 1; 735 } 736 } 737 } 738 739 size = ARRAY_SIZE(sta_priv->supported_rates.ofdm_rates); 740 rates_table = sta_priv->supported_rates.ofdm_rates; 741 for (i = 0; i < size; i++) { 742 if (rates & 0x01) { 743 rates_table[i] = wcn_5ghz_rates[i].hw_value; 744 rates = rates >> 1; 745 } 746 } 747 748 if (sta->deflink.ht_cap.ht_supported) { 749 BUILD_BUG_ON(sizeof(sta->deflink.ht_cap.mcs.rx_mask) > 750 sizeof(sta_priv->supported_rates.supported_mcs_set)); 751 memcpy(sta_priv->supported_rates.supported_mcs_set, 752 sta->deflink.ht_cap.mcs.rx_mask, 753 sizeof(sta->deflink.ht_cap.mcs.rx_mask)); 754 } 755 756 if (sta->deflink.vht_cap.vht_supported) { 757 sta_priv->supported_rates.op_rate_mode = STA_11ac; 758 sta_priv->supported_rates.vht_rx_mcs_map = 759 sta->deflink.vht_cap.vht_mcs.rx_mcs_map; 760 sta_priv->supported_rates.vht_tx_mcs_map = 761 sta->deflink.vht_cap.vht_mcs.tx_mcs_map; 762 } 763 } 764 765 void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates) 766 { 767 u16 ofdm_rates[WCN36XX_HAL_NUM_OFDM_RATES] = { 768 HW_RATE_INDEX_6MBPS, 769 HW_RATE_INDEX_9MBPS, 770 HW_RATE_INDEX_12MBPS, 771 HW_RATE_INDEX_18MBPS, 772 HW_RATE_INDEX_24MBPS, 773 HW_RATE_INDEX_36MBPS, 774 HW_RATE_INDEX_48MBPS, 775 HW_RATE_INDEX_54MBPS 776 }; 777 u16 dsss_rates[WCN36XX_HAL_NUM_DSSS_RATES] = { 778 HW_RATE_INDEX_1MBPS, 779 HW_RATE_INDEX_2MBPS, 780 HW_RATE_INDEX_5_5MBPS, 781 HW_RATE_INDEX_11MBPS 782 }; 783 784 rates->op_rate_mode = STA_11n; 785 memcpy(rates->dsss_rates, dsss_rates, 786 sizeof(*dsss_rates) * WCN36XX_HAL_NUM_DSSS_RATES); 787 memcpy(rates->ofdm_rates, ofdm_rates, 788 sizeof(*ofdm_rates) * WCN36XX_HAL_NUM_OFDM_RATES); 789 rates->supported_mcs_set[0] = 0xFF; 790 } 791 792 void wcn36xx_set_default_rates_v1(struct wcn36xx_hal_supported_rates_v1 *rates) 793 { 794 rates->op_rate_mode = STA_11ac; 795 rates->vht_rx_mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9; 796 rates->vht_tx_mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9; 797 } 798 799 static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, 800 struct ieee80211_vif *vif, 801 struct ieee80211_bss_conf *bss_conf, 802 u64 changed) 803 { 804 struct wcn36xx *wcn = hw->priv; 805 struct sk_buff *skb = NULL; 806 u16 tim_off, tim_len; 807 enum wcn36xx_hal_link_state link_state; 808 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 809 810 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%llx\n", 811 vif, changed); 812 813 mutex_lock(&wcn->conf_mutex); 814 815 if (changed & BSS_CHANGED_BEACON_INFO) { 816 wcn36xx_dbg(WCN36XX_DBG_MAC, 817 "mac bss changed dtim period %d\n", 818 bss_conf->dtim_period); 819 820 vif_priv->dtim_period = bss_conf->dtim_period; 821 } 822 823 if (changed & BSS_CHANGED_BSSID) { 824 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed_bssid %pM\n", 825 bss_conf->bssid); 826 827 if (!is_zero_ether_addr(bss_conf->bssid)) { 828 vif_priv->is_joining = true; 829 vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX; 830 wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr, 831 WCN36XX_HAL_LINK_PREASSOC_STATE); 832 wcn36xx_smd_join(wcn, bss_conf->bssid, 833 vif->addr, WCN36XX_HW_CHANNEL(wcn)); 834 wcn36xx_smd_config_bss(wcn, vif, NULL, 835 bss_conf->bssid, false); 836 } else { 837 vif_priv->is_joining = false; 838 wcn36xx_smd_delete_bss(wcn, vif); 839 wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr, 840 WCN36XX_HAL_LINK_IDLE_STATE); 841 vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE; 842 } 843 } 844 845 if (changed & BSS_CHANGED_SSID) { 846 wcn36xx_dbg(WCN36XX_DBG_MAC, 847 "mac bss changed ssid\n"); 848 wcn36xx_dbg_dump(WCN36XX_DBG_MAC, "ssid ", 849 vif->cfg.ssid, vif->cfg.ssid_len); 850 851 vif_priv->ssid.length = vif->cfg.ssid_len; 852 memcpy(&vif_priv->ssid.ssid, 853 vif->cfg.ssid, 854 vif->cfg.ssid_len); 855 } 856 857 if (changed & BSS_CHANGED_ASSOC) { 858 vif_priv->is_joining = false; 859 if (vif->cfg.assoc) { 860 struct ieee80211_sta *sta; 861 struct wcn36xx_sta *sta_priv; 862 863 wcn36xx_dbg(WCN36XX_DBG_MAC, 864 "mac assoc bss %pM vif %pM AID=%d\n", 865 bss_conf->bssid, 866 vif->addr, 867 vif->cfg.aid); 868 869 vif_priv->sta_assoc = true; 870 871 /* 872 * Holding conf_mutex ensures mutal exclusion with 873 * wcn36xx_sta_remove() and as such ensures that sta 874 * won't be freed while we're operating on it. As such 875 * we do not need to hold the rcu_read_lock(). 876 */ 877 sta = ieee80211_find_sta(vif, bss_conf->bssid); 878 if (!sta) { 879 wcn36xx_err("sta %pM is not found\n", 880 bss_conf->bssid); 881 goto out; 882 } 883 sta_priv = wcn36xx_sta_to_priv(sta); 884 885 wcn36xx_update_allowed_rates(sta, WCN36XX_BAND(wcn)); 886 887 wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, 888 vif->addr, 889 WCN36XX_HAL_LINK_POSTASSOC_STATE); 890 wcn36xx_smd_config_bss(wcn, vif, sta, 891 bss_conf->bssid, 892 true); 893 sta_priv->aid = vif->cfg.aid; 894 /* 895 * config_sta must be called from because this is the 896 * place where AID is available. 897 */ 898 wcn36xx_smd_config_sta(wcn, vif, sta); 899 if (vif->type == NL80211_IFTYPE_STATION) 900 wcn36xx_smd_add_beacon_filter(wcn, vif); 901 wcn36xx_enable_keep_alive_null_packet(wcn, vif); 902 } else { 903 wcn36xx_dbg(WCN36XX_DBG_MAC, 904 "disassociated bss %pM vif %pM AID=%d\n", 905 bss_conf->bssid, 906 vif->addr, 907 vif->cfg.aid); 908 vif_priv->sta_assoc = false; 909 wcn36xx_smd_set_link_st(wcn, 910 bss_conf->bssid, 911 vif->addr, 912 WCN36XX_HAL_LINK_IDLE_STATE); 913 } 914 } 915 916 if (changed & BSS_CHANGED_AP_PROBE_RESP) { 917 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed ap probe resp\n"); 918 skb = ieee80211_proberesp_get(hw, vif); 919 if (!skb) { 920 wcn36xx_err("failed to alloc probereq skb\n"); 921 goto out; 922 } 923 924 wcn36xx_smd_update_proberesp_tmpl(wcn, vif, skb); 925 dev_kfree_skb(skb); 926 } 927 928 if (changed & BSS_CHANGED_BEACON_ENABLED || 929 changed & BSS_CHANGED_BEACON) { 930 wcn36xx_dbg(WCN36XX_DBG_MAC, 931 "mac bss changed beacon enabled %d\n", 932 bss_conf->enable_beacon); 933 934 if (bss_conf->enable_beacon) { 935 vif_priv->dtim_period = bss_conf->dtim_period; 936 vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX; 937 wcn36xx_smd_config_bss(wcn, vif, NULL, 938 vif->addr, false); 939 skb = ieee80211_beacon_get_tim(hw, vif, &tim_off, 940 &tim_len, 0); 941 if (!skb) { 942 wcn36xx_err("failed to alloc beacon skb\n"); 943 goto out; 944 } 945 wcn36xx_smd_send_beacon(wcn, vif, skb, tim_off, 0); 946 dev_kfree_skb(skb); 947 948 if (vif->type == NL80211_IFTYPE_ADHOC || 949 vif->type == NL80211_IFTYPE_MESH_POINT) 950 link_state = WCN36XX_HAL_LINK_IBSS_STATE; 951 else 952 link_state = WCN36XX_HAL_LINK_AP_STATE; 953 954 wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr, 955 link_state); 956 } else { 957 wcn36xx_smd_delete_bss(wcn, vif); 958 wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr, 959 WCN36XX_HAL_LINK_IDLE_STATE); 960 } 961 } 962 out: 963 964 mutex_unlock(&wcn->conf_mutex); 965 } 966 967 /* this is required when using IEEE80211_HW_HAS_RATE_CONTROL */ 968 static int wcn36xx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 969 { 970 struct wcn36xx *wcn = hw->priv; 971 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac set RTS threshold %d\n", value); 972 973 mutex_lock(&wcn->conf_mutex); 974 wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_RTS_THRESHOLD, value); 975 mutex_unlock(&wcn->conf_mutex); 976 977 return 0; 978 } 979 980 static void wcn36xx_remove_interface(struct ieee80211_hw *hw, 981 struct ieee80211_vif *vif) 982 { 983 struct wcn36xx *wcn = hw->priv; 984 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 985 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif); 986 987 mutex_lock(&wcn->conf_mutex); 988 989 list_del(&vif_priv->list); 990 wcn36xx_smd_delete_sta_self(wcn, vif->addr); 991 992 mutex_unlock(&wcn->conf_mutex); 993 } 994 995 static int wcn36xx_add_interface(struct ieee80211_hw *hw, 996 struct ieee80211_vif *vif) 997 { 998 struct wcn36xx *wcn = hw->priv; 999 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 1000 1001 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac add interface vif %p type %d\n", 1002 vif, vif->type); 1003 1004 if (!(NL80211_IFTYPE_STATION == vif->type || 1005 NL80211_IFTYPE_AP == vif->type || 1006 NL80211_IFTYPE_ADHOC == vif->type || 1007 NL80211_IFTYPE_MESH_POINT == vif->type)) { 1008 wcn36xx_warn("Unsupported interface type requested: %d\n", 1009 vif->type); 1010 return -EOPNOTSUPP; 1011 } 1012 1013 mutex_lock(&wcn->conf_mutex); 1014 1015 vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX; 1016 INIT_LIST_HEAD(&vif_priv->sta_list); 1017 list_add(&vif_priv->list, &wcn->vif_list); 1018 wcn36xx_smd_add_sta_self(wcn, vif); 1019 1020 mutex_unlock(&wcn->conf_mutex); 1021 1022 return 0; 1023 } 1024 1025 static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1026 struct ieee80211_sta *sta) 1027 { 1028 struct wcn36xx *wcn = hw->priv; 1029 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 1030 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); 1031 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n", 1032 vif, sta->addr); 1033 1034 mutex_lock(&wcn->conf_mutex); 1035 1036 spin_lock_init(&sta_priv->ampdu_lock); 1037 sta_priv->vif = vif_priv; 1038 list_add(&sta_priv->list, &vif_priv->sta_list); 1039 1040 /* 1041 * For STA mode HW will be configured on BSS_CHANGED_ASSOC because 1042 * at this stage AID is not available yet. 1043 */ 1044 if (NL80211_IFTYPE_STATION != vif->type) { 1045 wcn36xx_update_allowed_rates(sta, WCN36XX_BAND(wcn)); 1046 sta_priv->aid = sta->aid; 1047 wcn36xx_smd_config_sta(wcn, vif, sta); 1048 } 1049 1050 mutex_unlock(&wcn->conf_mutex); 1051 1052 return 0; 1053 } 1054 1055 static int wcn36xx_sta_remove(struct ieee80211_hw *hw, 1056 struct ieee80211_vif *vif, 1057 struct ieee80211_sta *sta) 1058 { 1059 struct wcn36xx *wcn = hw->priv; 1060 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); 1061 1062 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n", 1063 vif, sta->addr, sta_priv->sta_index); 1064 1065 mutex_lock(&wcn->conf_mutex); 1066 1067 list_del(&sta_priv->list); 1068 wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index); 1069 sta_priv->vif = NULL; 1070 1071 mutex_unlock(&wcn->conf_mutex); 1072 1073 return 0; 1074 } 1075 1076 #ifdef CONFIG_PM 1077 1078 static struct ieee80211_vif *wcn36xx_get_first_assoc_vif(struct wcn36xx *wcn) 1079 { 1080 struct wcn36xx_vif *vif_priv = NULL; 1081 struct ieee80211_vif *vif = NULL; 1082 1083 list_for_each_entry(vif_priv, &wcn->vif_list, list) { 1084 if (vif_priv->sta_assoc) { 1085 vif = wcn36xx_priv_to_vif(vif_priv); 1086 break; 1087 } 1088 } 1089 return vif; 1090 } 1091 1092 static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow) 1093 { 1094 struct wcn36xx *wcn = hw->priv; 1095 struct ieee80211_vif *vif = NULL; 1096 int ret = 0; 1097 1098 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac suspend\n"); 1099 1100 mutex_lock(&wcn->conf_mutex); 1101 1102 vif = wcn36xx_get_first_assoc_vif(wcn); 1103 if (vif) { 1104 ret = wcn36xx_smd_arp_offload(wcn, vif, true); 1105 if (ret) 1106 goto out; 1107 ret = wcn36xx_smd_ipv6_ns_offload(wcn, vif, true); 1108 if (ret) 1109 goto out; 1110 ret = wcn36xx_smd_gtk_offload(wcn, vif, true); 1111 if (ret) 1112 goto out; 1113 ret = wcn36xx_smd_set_power_params(wcn, true); 1114 if (ret) 1115 goto out; 1116 ret = wcn36xx_smd_wlan_host_suspend_ind(wcn); 1117 } 1118 1119 /* Disable IRQ, we don't want to handle any packet before mac80211 is 1120 * resumed and ready to receive packets. 1121 */ 1122 disable_irq(wcn->tx_irq); 1123 disable_irq(wcn->rx_irq); 1124 1125 out: 1126 mutex_unlock(&wcn->conf_mutex); 1127 return ret; 1128 } 1129 1130 static int wcn36xx_resume(struct ieee80211_hw *hw) 1131 { 1132 struct wcn36xx *wcn = hw->priv; 1133 struct ieee80211_vif *vif = NULL; 1134 1135 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac resume\n"); 1136 1137 mutex_lock(&wcn->conf_mutex); 1138 vif = wcn36xx_get_first_assoc_vif(wcn); 1139 if (vif) { 1140 wcn36xx_smd_host_resume(wcn); 1141 wcn36xx_smd_set_power_params(wcn, false); 1142 wcn36xx_smd_gtk_offload_get_info(wcn, vif); 1143 wcn36xx_smd_gtk_offload(wcn, vif, false); 1144 wcn36xx_smd_ipv6_ns_offload(wcn, vif, false); 1145 wcn36xx_smd_arp_offload(wcn, vif, false); 1146 } 1147 1148 enable_irq(wcn->tx_irq); 1149 enable_irq(wcn->rx_irq); 1150 1151 mutex_unlock(&wcn->conf_mutex); 1152 1153 return 0; 1154 } 1155 1156 static void wcn36xx_set_rekey_data(struct ieee80211_hw *hw, 1157 struct ieee80211_vif *vif, 1158 struct cfg80211_gtk_rekey_data *data) 1159 { 1160 struct wcn36xx *wcn = hw->priv; 1161 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 1162 1163 mutex_lock(&wcn->conf_mutex); 1164 1165 memcpy(vif_priv->rekey_data.kek, data->kek, NL80211_KEK_LEN); 1166 memcpy(vif_priv->rekey_data.kck, data->kck, NL80211_KCK_LEN); 1167 vif_priv->rekey_data.replay_ctr = 1168 cpu_to_le64(be64_to_cpup((__be64 *)data->replay_ctr)); 1169 vif_priv->rekey_data.valid = true; 1170 1171 mutex_unlock(&wcn->conf_mutex); 1172 } 1173 1174 #endif 1175 1176 static int wcn36xx_ampdu_action(struct ieee80211_hw *hw, 1177 struct ieee80211_vif *vif, 1178 struct ieee80211_ampdu_params *params) 1179 { 1180 struct wcn36xx *wcn = hw->priv; 1181 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(params->sta); 1182 struct ieee80211_sta *sta = params->sta; 1183 enum ieee80211_ampdu_mlme_action action = params->action; 1184 u16 tid = params->tid; 1185 u16 *ssn = ¶ms->ssn; 1186 int ret = 0; 1187 int session; 1188 1189 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n", 1190 action, tid); 1191 1192 mutex_lock(&wcn->conf_mutex); 1193 1194 switch (action) { 1195 case IEEE80211_AMPDU_RX_START: 1196 sta_priv->tid = tid; 1197 session = wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 0, 1198 get_sta_index(vif, sta_priv)); 1199 if (session < 0) { 1200 ret = session; 1201 goto out; 1202 } 1203 wcn36xx_smd_add_ba(wcn, session); 1204 break; 1205 case IEEE80211_AMPDU_RX_STOP: 1206 wcn36xx_smd_del_ba(wcn, tid, 0, get_sta_index(vif, sta_priv)); 1207 break; 1208 case IEEE80211_AMPDU_TX_START: 1209 spin_lock_bh(&sta_priv->ampdu_lock); 1210 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_START; 1211 spin_unlock_bh(&sta_priv->ampdu_lock); 1212 1213 /* Replace the mac80211 ssn with the firmware one */ 1214 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu ssn = %u\n", *ssn); 1215 wcn36xx_smd_trigger_ba(wcn, get_sta_index(vif, sta_priv), tid, ssn); 1216 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu fw-ssn = %u\n", *ssn); 1217 1218 /* Start BA session */ 1219 session = wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 1, 1220 get_sta_index(vif, sta_priv)); 1221 if (session < 0) { 1222 ret = session; 1223 goto out; 1224 } 1225 ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; 1226 break; 1227 case IEEE80211_AMPDU_TX_OPERATIONAL: 1228 spin_lock_bh(&sta_priv->ampdu_lock); 1229 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_OPERATIONAL; 1230 spin_unlock_bh(&sta_priv->ampdu_lock); 1231 1232 break; 1233 case IEEE80211_AMPDU_TX_STOP_FLUSH: 1234 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 1235 case IEEE80211_AMPDU_TX_STOP_CONT: 1236 spin_lock_bh(&sta_priv->ampdu_lock); 1237 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_NONE; 1238 spin_unlock_bh(&sta_priv->ampdu_lock); 1239 1240 wcn36xx_smd_del_ba(wcn, tid, 1, get_sta_index(vif, sta_priv)); 1241 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1242 break; 1243 default: 1244 wcn36xx_err("Unknown AMPDU action\n"); 1245 } 1246 1247 out: 1248 mutex_unlock(&wcn->conf_mutex); 1249 1250 return ret; 1251 } 1252 1253 #if IS_ENABLED(CONFIG_IPV6) 1254 static void wcn36xx_ipv6_addr_change(struct ieee80211_hw *hw, 1255 struct ieee80211_vif *vif, 1256 struct inet6_dev *idev) 1257 { 1258 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 1259 struct inet6_ifaddr *ifa; 1260 int idx = 0; 1261 1262 memset(vif_priv->tentative_addrs, 0, sizeof(vif_priv->tentative_addrs)); 1263 1264 read_lock_bh(&idev->lock); 1265 list_for_each_entry(ifa, &idev->addr_list, if_list) { 1266 vif_priv->target_ipv6_addrs[idx] = ifa->addr; 1267 if (ifa->flags & IFA_F_TENTATIVE) 1268 __set_bit(idx, vif_priv->tentative_addrs); 1269 idx++; 1270 if (idx >= WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX) 1271 break; 1272 wcn36xx_dbg(WCN36XX_DBG_MAC, "%pI6 %s\n", &ifa->addr, 1273 (ifa->flags & IFA_F_TENTATIVE) ? "tentative" : NULL); 1274 } 1275 read_unlock_bh(&idev->lock); 1276 1277 vif_priv->num_target_ipv6_addrs = idx; 1278 } 1279 #endif 1280 1281 static void wcn36xx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1282 u32 queues, bool drop) 1283 { 1284 struct wcn36xx *wcn = hw->priv; 1285 1286 if (wcn36xx_dxe_tx_flush(wcn)) { 1287 wcn36xx_err("Failed to flush hardware tx queues\n"); 1288 } 1289 } 1290 1291 static int wcn36xx_get_survey(struct ieee80211_hw *hw, int idx, 1292 struct survey_info *survey) 1293 { 1294 struct wcn36xx *wcn = hw->priv; 1295 struct ieee80211_supported_band *sband; 1296 struct wcn36xx_chan_survey *chan_survey; 1297 int band_idx; 1298 unsigned long flags; 1299 1300 sband = wcn->hw->wiphy->bands[NL80211_BAND_2GHZ]; 1301 band_idx = idx; 1302 if (band_idx >= sband->n_channels) { 1303 band_idx -= sband->n_channels; 1304 sband = wcn->hw->wiphy->bands[NL80211_BAND_5GHZ]; 1305 } 1306 1307 if (!sband || band_idx >= sband->n_channels) 1308 return -ENOENT; 1309 1310 spin_lock_irqsave(&wcn->survey_lock, flags); 1311 1312 chan_survey = &wcn->chan_survey[idx]; 1313 survey->channel = &sband->channels[band_idx]; 1314 survey->noise = chan_survey->rssi - chan_survey->snr; 1315 survey->filled = 0; 1316 1317 if (chan_survey->rssi > -100 && chan_survey->rssi < 0) 1318 survey->filled |= SURVEY_INFO_NOISE_DBM; 1319 1320 if (survey->channel == wcn->channel) 1321 survey->filled |= SURVEY_INFO_IN_USE; 1322 1323 spin_unlock_irqrestore(&wcn->survey_lock, flags); 1324 1325 wcn36xx_dbg(WCN36XX_DBG_MAC, 1326 "ch %d rssi %d snr %d noise %d filled %x freq %d\n", 1327 HW_VALUE_CHANNEL(survey->channel->hw_value), 1328 chan_survey->rssi, chan_survey->snr, survey->noise, 1329 survey->filled, survey->channel->center_freq); 1330 1331 return 0; 1332 } 1333 1334 static void wcn36xx_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1335 struct ieee80211_sta *sta, struct station_info *sinfo) 1336 { 1337 struct wcn36xx *wcn; 1338 u8 sta_index; 1339 int status; 1340 1341 wcn = hw->priv; 1342 sta_index = get_sta_index(vif, wcn36xx_sta_to_priv(sta)); 1343 status = wcn36xx_smd_get_stats(wcn, sta_index, HAL_GLOBAL_CLASS_A_STATS_INFO, sinfo); 1344 1345 if (status) 1346 wcn36xx_err("wcn36xx_smd_get_stats failed\n"); 1347 } 1348 1349 static const struct ieee80211_ops wcn36xx_ops = { 1350 .start = wcn36xx_start, 1351 .stop = wcn36xx_stop, 1352 .add_interface = wcn36xx_add_interface, 1353 .remove_interface = wcn36xx_remove_interface, 1354 #ifdef CONFIG_PM 1355 .suspend = wcn36xx_suspend, 1356 .resume = wcn36xx_resume, 1357 .set_rekey_data = wcn36xx_set_rekey_data, 1358 #endif 1359 .config = wcn36xx_config, 1360 .prepare_multicast = wcn36xx_prepare_multicast, 1361 .configure_filter = wcn36xx_configure_filter, 1362 .tx = wcn36xx_tx, 1363 .wake_tx_queue = ieee80211_handle_wake_tx_queue, 1364 .set_key = wcn36xx_set_key, 1365 .hw_scan = wcn36xx_hw_scan, 1366 .cancel_hw_scan = wcn36xx_cancel_hw_scan, 1367 .sw_scan_start = wcn36xx_sw_scan_start, 1368 .sw_scan_complete = wcn36xx_sw_scan_complete, 1369 .bss_info_changed = wcn36xx_bss_info_changed, 1370 .set_rts_threshold = wcn36xx_set_rts_threshold, 1371 .sta_add = wcn36xx_sta_add, 1372 .sta_remove = wcn36xx_sta_remove, 1373 .sta_statistics = wcn36xx_sta_statistics, 1374 .ampdu_action = wcn36xx_ampdu_action, 1375 #if IS_ENABLED(CONFIG_IPV6) 1376 .ipv6_addr_change = wcn36xx_ipv6_addr_change, 1377 #endif 1378 .flush = wcn36xx_flush, 1379 .get_survey = wcn36xx_get_survey, 1380 1381 CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd) 1382 }; 1383 1384 static void 1385 wcn36xx_set_ieee80211_vht_caps(struct ieee80211_sta_vht_cap *vht_cap) 1386 { 1387 vht_cap->vht_supported = true; 1388 1389 vht_cap->cap = (IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 | 1390 IEEE80211_VHT_CAP_SHORT_GI_80 | 1391 IEEE80211_VHT_CAP_RXSTBC_1 | 1392 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | 1393 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | 1394 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT | 1395 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT); 1396 1397 vht_cap->vht_mcs.rx_mcs_map = 1398 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 | 1399 IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 | 1400 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | 1401 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | 1402 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | 1403 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | 1404 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | 1405 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14); 1406 1407 vht_cap->vht_mcs.rx_highest = cpu_to_le16(433); 1408 vht_cap->vht_mcs.tx_highest = vht_cap->vht_mcs.rx_highest; 1409 1410 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map; 1411 } 1412 1413 static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) 1414 { 1415 static const u32 cipher_suites[] = { 1416 WLAN_CIPHER_SUITE_WEP40, 1417 WLAN_CIPHER_SUITE_WEP104, 1418 WLAN_CIPHER_SUITE_TKIP, 1419 WLAN_CIPHER_SUITE_CCMP, 1420 }; 1421 1422 ieee80211_hw_set(wcn->hw, TIMING_BEACON_ONLY); 1423 ieee80211_hw_set(wcn->hw, AMPDU_AGGREGATION); 1424 ieee80211_hw_set(wcn->hw, SUPPORTS_PS); 1425 ieee80211_hw_set(wcn->hw, SIGNAL_DBM); 1426 ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL); 1427 ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS); 1428 ieee80211_hw_set(wcn->hw, REPORTS_TX_ACK_STATUS); 1429 1430 wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1431 BIT(NL80211_IFTYPE_AP) | 1432 BIT(NL80211_IFTYPE_ADHOC) | 1433 BIT(NL80211_IFTYPE_MESH_POINT); 1434 1435 wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = &wcn_band_2ghz; 1436 if (wcn->rf_id != RF_IRIS_WCN3620) 1437 wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = &wcn_band_5ghz; 1438 1439 if (wcn->rf_id == RF_IRIS_WCN3680) 1440 wcn36xx_set_ieee80211_vht_caps(&wcn_band_5ghz.vht_cap); 1441 1442 wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS; 1443 wcn->hw->wiphy->max_scan_ie_len = WCN36XX_MAX_SCAN_IE_LEN; 1444 1445 wcn->hw->wiphy->cipher_suites = cipher_suites; 1446 wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 1447 1448 #ifdef CONFIG_PM 1449 wcn->hw->wiphy->wowlan = &wowlan_support; 1450 #endif 1451 1452 wcn->hw->max_listen_interval = 200; 1453 1454 wcn->hw->queues = 4; 1455 1456 SET_IEEE80211_DEV(wcn->hw, wcn->dev); 1457 1458 wcn->hw->sta_data_size = sizeof(struct wcn36xx_sta); 1459 wcn->hw->vif_data_size = sizeof(struct wcn36xx_vif); 1460 1461 wiphy_ext_feature_set(wcn->hw->wiphy, 1462 NL80211_EXT_FEATURE_CQM_RSSI_LIST); 1463 1464 return 0; 1465 } 1466 1467 static int wcn36xx_platform_get_resources(struct wcn36xx *wcn, 1468 struct platform_device *pdev) 1469 { 1470 struct device_node *mmio_node; 1471 struct device_node *iris_node; 1472 int index; 1473 int ret; 1474 1475 /* Set TX IRQ */ 1476 ret = platform_get_irq_byname(pdev, "tx"); 1477 if (ret < 0) 1478 return ret; 1479 wcn->tx_irq = ret; 1480 1481 /* Set RX IRQ */ 1482 ret = platform_get_irq_byname(pdev, "rx"); 1483 if (ret < 0) 1484 return ret; 1485 wcn->rx_irq = ret; 1486 1487 /* Acquire SMSM tx enable handle */ 1488 wcn->tx_enable_state = qcom_smem_state_get(&pdev->dev, 1489 "tx-enable", &wcn->tx_enable_state_bit); 1490 if (IS_ERR(wcn->tx_enable_state)) { 1491 wcn36xx_err("failed to get tx-enable state\n"); 1492 return PTR_ERR(wcn->tx_enable_state); 1493 } 1494 1495 /* Acquire SMSM tx rings empty handle */ 1496 wcn->tx_rings_empty_state = qcom_smem_state_get(&pdev->dev, 1497 "tx-rings-empty", &wcn->tx_rings_empty_state_bit); 1498 if (IS_ERR(wcn->tx_rings_empty_state)) { 1499 wcn36xx_err("failed to get tx-rings-empty state\n"); 1500 return PTR_ERR(wcn->tx_rings_empty_state); 1501 } 1502 1503 mmio_node = of_parse_phandle(pdev->dev.parent->of_node, "qcom,mmio", 0); 1504 if (!mmio_node) { 1505 wcn36xx_err("failed to acquire qcom,mmio reference\n"); 1506 return -EINVAL; 1507 } 1508 1509 wcn->is_pronto = !!of_device_is_compatible(mmio_node, "qcom,pronto"); 1510 wcn->is_pronto_v3 = !!of_device_is_compatible(mmio_node, "qcom,pronto-v3-pil"); 1511 1512 /* Map the CCU memory */ 1513 index = of_property_match_string(mmio_node, "reg-names", "ccu"); 1514 wcn->ccu_base = of_iomap(mmio_node, index); 1515 if (!wcn->ccu_base) { 1516 wcn36xx_err("failed to map ccu memory\n"); 1517 ret = -ENOMEM; 1518 goto put_mmio_node; 1519 } 1520 1521 /* Map the DXE memory */ 1522 index = of_property_match_string(mmio_node, "reg-names", "dxe"); 1523 wcn->dxe_base = of_iomap(mmio_node, index); 1524 if (!wcn->dxe_base) { 1525 wcn36xx_err("failed to map dxe memory\n"); 1526 ret = -ENOMEM; 1527 goto unmap_ccu; 1528 } 1529 1530 /* External RF module */ 1531 iris_node = of_get_child_by_name(mmio_node, "iris"); 1532 if (iris_node) { 1533 if (of_device_is_compatible(iris_node, "qcom,wcn3620")) 1534 wcn->rf_id = RF_IRIS_WCN3620; 1535 if (of_device_is_compatible(iris_node, "qcom,wcn3660") || 1536 of_device_is_compatible(iris_node, "qcom,wcn3660b")) 1537 wcn->rf_id = RF_IRIS_WCN3660; 1538 if (of_device_is_compatible(iris_node, "qcom,wcn3680")) 1539 wcn->rf_id = RF_IRIS_WCN3680; 1540 of_node_put(iris_node); 1541 } 1542 1543 of_node_put(mmio_node); 1544 return 0; 1545 1546 unmap_ccu: 1547 iounmap(wcn->ccu_base); 1548 put_mmio_node: 1549 of_node_put(mmio_node); 1550 return ret; 1551 } 1552 1553 static int wcn36xx_probe(struct platform_device *pdev) 1554 { 1555 struct ieee80211_hw *hw; 1556 struct wcn36xx *wcn; 1557 void *wcnss; 1558 int ret; 1559 const u8 *addr; 1560 int n_channels; 1561 1562 wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n"); 1563 1564 wcnss = dev_get_drvdata(pdev->dev.parent); 1565 1566 hw = ieee80211_alloc_hw(sizeof(struct wcn36xx), &wcn36xx_ops); 1567 if (!hw) { 1568 wcn36xx_err("failed to alloc hw\n"); 1569 ret = -ENOMEM; 1570 goto out_err; 1571 } 1572 platform_set_drvdata(pdev, hw); 1573 wcn = hw->priv; 1574 wcn->hw = hw; 1575 wcn->dev = &pdev->dev; 1576 wcn->first_boot = true; 1577 mutex_init(&wcn->conf_mutex); 1578 mutex_init(&wcn->hal_mutex); 1579 mutex_init(&wcn->scan_lock); 1580 __skb_queue_head_init(&wcn->amsdu); 1581 1582 wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); 1583 if (!wcn->hal_buf) { 1584 ret = -ENOMEM; 1585 goto out_wq; 1586 } 1587 1588 n_channels = wcn_band_2ghz.n_channels + wcn_band_5ghz.n_channels; 1589 wcn->chan_survey = devm_kmalloc(wcn->dev, n_channels, GFP_KERNEL); 1590 if (!wcn->chan_survey) { 1591 ret = -ENOMEM; 1592 goto out_wq; 1593 } 1594 1595 ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32)); 1596 if (ret < 0) { 1597 wcn36xx_err("failed to set DMA mask: %d\n", ret); 1598 goto out_wq; 1599 } 1600 1601 wcn->nv_file = WLAN_NV_FILE; 1602 ret = of_property_read_string(wcn->dev->parent->of_node, "firmware-name", &wcn->nv_file); 1603 if (ret < 0 && ret != -EINVAL) { 1604 wcn36xx_err("failed to read \"firmware-name\" property: %d\n", ret); 1605 goto out_wq; 1606 } 1607 1608 wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process, hw); 1609 if (IS_ERR(wcn->smd_channel)) { 1610 wcn36xx_err("failed to open WLAN_CTRL channel\n"); 1611 ret = PTR_ERR(wcn->smd_channel); 1612 goto out_wq; 1613 } 1614 1615 addr = of_get_property(pdev->dev.of_node, "local-mac-address", &ret); 1616 if (addr && ret != ETH_ALEN) { 1617 wcn36xx_err("invalid local-mac-address\n"); 1618 ret = -EINVAL; 1619 goto out_destroy_ept; 1620 } else if (addr) { 1621 wcn36xx_info("mac address: %pM\n", addr); 1622 SET_IEEE80211_PERM_ADDR(wcn->hw, addr); 1623 } 1624 1625 ret = wcn36xx_platform_get_resources(wcn, pdev); 1626 if (ret) 1627 goto out_destroy_ept; 1628 1629 wcn36xx_init_ieee80211(wcn); 1630 ret = ieee80211_register_hw(wcn->hw); 1631 if (ret) 1632 goto out_unmap; 1633 1634 return 0; 1635 1636 out_unmap: 1637 iounmap(wcn->ccu_base); 1638 iounmap(wcn->dxe_base); 1639 out_destroy_ept: 1640 rpmsg_destroy_ept(wcn->smd_channel); 1641 out_wq: 1642 ieee80211_free_hw(hw); 1643 out_err: 1644 return ret; 1645 } 1646 1647 static int wcn36xx_remove(struct platform_device *pdev) 1648 { 1649 struct ieee80211_hw *hw = platform_get_drvdata(pdev); 1650 struct wcn36xx *wcn = hw->priv; 1651 wcn36xx_dbg(WCN36XX_DBG_MAC, "platform remove\n"); 1652 1653 release_firmware(wcn->nv); 1654 1655 ieee80211_unregister_hw(hw); 1656 1657 qcom_smem_state_put(wcn->tx_enable_state); 1658 qcom_smem_state_put(wcn->tx_rings_empty_state); 1659 1660 rpmsg_destroy_ept(wcn->smd_channel); 1661 1662 iounmap(wcn->dxe_base); 1663 iounmap(wcn->ccu_base); 1664 1665 __skb_queue_purge(&wcn->amsdu); 1666 1667 mutex_destroy(&wcn->hal_mutex); 1668 ieee80211_free_hw(hw); 1669 1670 return 0; 1671 } 1672 1673 static const struct of_device_id wcn36xx_of_match[] = { 1674 { .compatible = "qcom,wcnss-wlan" }, 1675 {} 1676 }; 1677 MODULE_DEVICE_TABLE(of, wcn36xx_of_match); 1678 1679 static struct platform_driver wcn36xx_driver = { 1680 .probe = wcn36xx_probe, 1681 .remove = wcn36xx_remove, 1682 .driver = { 1683 .name = "wcn36xx", 1684 .of_match_table = wcn36xx_of_match, 1685 }, 1686 }; 1687 1688 module_platform_driver(wcn36xx_driver); 1689 1690 MODULE_LICENSE("Dual BSD/GPL"); 1691 MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com"); 1692 MODULE_FIRMWARE(WLAN_NV_FILE); 1693