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