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