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) { 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 } else if (wcn->sw_scan) { 419 /* A scan is ongoing, do not change the operating 420 * channel, but start a scan session on the channel. 421 */ 422 wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN, 423 wcn->sw_scan_vif); 424 wcn36xx_smd_start_scan(wcn, ch); 425 } else { 426 wcn36xx_change_opchannel(wcn, ch); 427 } 428 } 429 430 if (changed & IEEE80211_CONF_CHANGE_PS) 431 wcn36xx_change_ps(wcn, hw->conf.flags & IEEE80211_CONF_PS); 432 433 mutex_unlock(&wcn->conf_mutex); 434 435 return 0; 436 } 437 438 static void wcn36xx_configure_filter(struct ieee80211_hw *hw, 439 unsigned int changed, 440 unsigned int *total, u64 multicast) 441 { 442 struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp; 443 struct wcn36xx *wcn = hw->priv; 444 struct wcn36xx_vif *tmp; 445 struct ieee80211_vif *vif = NULL; 446 447 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n"); 448 449 mutex_lock(&wcn->conf_mutex); 450 451 *total &= FIF_ALLMULTI; 452 453 fp = (void *)(unsigned long)multicast; 454 list_for_each_entry(tmp, &wcn->vif_list, list) { 455 vif = wcn36xx_priv_to_vif(tmp); 456 457 /* FW handles MC filtering only when connected as STA */ 458 if (*total & FIF_ALLMULTI) 459 wcn36xx_smd_set_mc_list(wcn, vif, NULL); 460 else if (NL80211_IFTYPE_STATION == vif->type && tmp->sta_assoc) 461 wcn36xx_smd_set_mc_list(wcn, vif, fp); 462 } 463 464 mutex_unlock(&wcn->conf_mutex); 465 kfree(fp); 466 } 467 468 static u64 wcn36xx_prepare_multicast(struct ieee80211_hw *hw, 469 struct netdev_hw_addr_list *mc_list) 470 { 471 struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp; 472 struct netdev_hw_addr *ha; 473 474 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac prepare multicast list\n"); 475 fp = kzalloc(sizeof(*fp), GFP_ATOMIC); 476 if (!fp) { 477 wcn36xx_err("Out of memory setting filters.\n"); 478 return 0; 479 } 480 481 fp->mc_addr_count = 0; 482 /* update multicast filtering parameters */ 483 if (netdev_hw_addr_list_count(mc_list) <= 484 WCN36XX_HAL_MAX_NUM_MULTICAST_ADDRESS) { 485 netdev_hw_addr_list_for_each(ha, mc_list) { 486 memcpy(fp->mc_addr[fp->mc_addr_count], 487 ha->addr, ETH_ALEN); 488 fp->mc_addr_count++; 489 } 490 } 491 492 return (u64)(unsigned long)fp; 493 } 494 495 static void wcn36xx_tx(struct ieee80211_hw *hw, 496 struct ieee80211_tx_control *control, 497 struct sk_buff *skb) 498 { 499 struct wcn36xx *wcn = hw->priv; 500 struct wcn36xx_sta *sta_priv = NULL; 501 502 if (control->sta) 503 sta_priv = wcn36xx_sta_to_priv(control->sta); 504 505 if (wcn36xx_start_tx(wcn, sta_priv, skb)) 506 ieee80211_free_txskb(wcn->hw, skb); 507 } 508 509 static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 510 struct ieee80211_vif *vif, 511 struct ieee80211_sta *sta, 512 struct ieee80211_key_conf *key_conf) 513 { 514 struct wcn36xx *wcn = hw->priv; 515 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 516 struct wcn36xx_sta *sta_priv = sta ? wcn36xx_sta_to_priv(sta) : NULL; 517 int ret = 0; 518 u8 key[WLAN_MAX_KEY_LEN]; 519 520 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 set key\n"); 521 wcn36xx_dbg(WCN36XX_DBG_MAC, "Key: cmd=0x%x algo:0x%x, id:%d, len:%d flags 0x%x\n", 522 cmd, key_conf->cipher, key_conf->keyidx, 523 key_conf->keylen, key_conf->flags); 524 wcn36xx_dbg_dump(WCN36XX_DBG_MAC, "KEY: ", 525 key_conf->key, 526 key_conf->keylen); 527 528 mutex_lock(&wcn->conf_mutex); 529 530 switch (key_conf->cipher) { 531 case WLAN_CIPHER_SUITE_WEP40: 532 vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP40; 533 break; 534 case WLAN_CIPHER_SUITE_WEP104: 535 vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP104; 536 break; 537 case WLAN_CIPHER_SUITE_CCMP: 538 vif_priv->encrypt_type = WCN36XX_HAL_ED_CCMP; 539 break; 540 case WLAN_CIPHER_SUITE_TKIP: 541 vif_priv->encrypt_type = WCN36XX_HAL_ED_TKIP; 542 break; 543 default: 544 wcn36xx_err("Unsupported key type 0x%x\n", 545 key_conf->cipher); 546 ret = -EOPNOTSUPP; 547 goto out; 548 } 549 550 switch (cmd) { 551 case SET_KEY: 552 if (WCN36XX_HAL_ED_TKIP == vif_priv->encrypt_type) { 553 /* 554 * Supplicant is sending key in the wrong order: 555 * Temporal Key (16 b) - TX MIC (8 b) - RX MIC (8 b) 556 * but HW expects it to be in the order as described in 557 * IEEE 802.11 spec (see chapter 11.7) like this: 558 * Temporal Key (16 b) - RX MIC (8 b) - TX MIC (8 b) 559 */ 560 memcpy(key, key_conf->key, 16); 561 memcpy(key + 16, key_conf->key + 24, 8); 562 memcpy(key + 24, key_conf->key + 16, 8); 563 } else { 564 memcpy(key, key_conf->key, key_conf->keylen); 565 } 566 567 if (IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags) { 568 sta_priv->is_data_encrypted = true; 569 /* Reconfigure bss with encrypt_type */ 570 if (NL80211_IFTYPE_STATION == vif->type) 571 wcn36xx_smd_config_bss(wcn, 572 vif, 573 sta, 574 sta->addr, 575 true); 576 577 wcn36xx_smd_set_stakey(wcn, 578 vif_priv->encrypt_type, 579 key_conf->keyidx, 580 key_conf->keylen, 581 key, 582 get_sta_index(vif, sta_priv)); 583 } else { 584 wcn36xx_smd_set_bsskey(wcn, 585 vif_priv->encrypt_type, 586 vif_priv->bss_index, 587 key_conf->keyidx, 588 key_conf->keylen, 589 key); 590 591 if ((WLAN_CIPHER_SUITE_WEP40 == key_conf->cipher) || 592 (WLAN_CIPHER_SUITE_WEP104 == key_conf->cipher)) { 593 list_for_each_entry(sta_priv, 594 &vif_priv->sta_list, list) { 595 sta_priv->is_data_encrypted = true; 596 wcn36xx_smd_set_stakey(wcn, 597 vif_priv->encrypt_type, 598 key_conf->keyidx, 599 key_conf->keylen, 600 key, 601 get_sta_index(vif, sta_priv)); 602 } 603 } 604 } 605 /* FIXME: Only enable bmps support when encryption is enabled. 606 * For any reasons, when connected to open/no-security BSS, 607 * the wcn36xx controller in bmps mode does not forward 608 * 'wake-up' beacons despite AP sends DTIM with station AID. 609 * It could be due to a firmware issue or to the way driver 610 * configure the station. 611 */ 612 if (vif->type == NL80211_IFTYPE_STATION) 613 vif_priv->allow_bmps = true; 614 break; 615 case DISABLE_KEY: 616 if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) { 617 if (vif_priv->bss_index != WCN36XX_HAL_BSS_INVALID_IDX) 618 wcn36xx_smd_remove_bsskey(wcn, 619 vif_priv->encrypt_type, 620 vif_priv->bss_index, 621 key_conf->keyidx); 622 623 vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE; 624 } else { 625 sta_priv->is_data_encrypted = false; 626 /* do not remove key if disassociated */ 627 if (sta_priv->aid) 628 wcn36xx_smd_remove_stakey(wcn, 629 vif_priv->encrypt_type, 630 key_conf->keyidx, 631 get_sta_index(vif, sta_priv)); 632 } 633 break; 634 default: 635 wcn36xx_err("Unsupported key cmd 0x%x\n", cmd); 636 ret = -EOPNOTSUPP; 637 goto out; 638 } 639 640 out: 641 mutex_unlock(&wcn->conf_mutex); 642 643 return ret; 644 } 645 646 static int wcn36xx_hw_scan(struct ieee80211_hw *hw, 647 struct ieee80211_vif *vif, 648 struct ieee80211_scan_request *hw_req) 649 { 650 struct wcn36xx *wcn = hw->priv; 651 int i; 652 653 if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) { 654 /* fallback to mac80211 software scan */ 655 return 1; 656 } 657 658 /* For unknown reason, the hardware offloaded scan only works with 659 * 2.4Ghz channels, fallback to software scan in other cases. 660 */ 661 for (i = 0; i < hw_req->req.n_channels; i++) { 662 if (hw_req->req.channels[i]->band != NL80211_BAND_2GHZ) 663 return 1; 664 } 665 666 mutex_lock(&wcn->scan_lock); 667 if (wcn->scan_req) { 668 mutex_unlock(&wcn->scan_lock); 669 return -EBUSY; 670 } 671 672 wcn->scan_aborted = false; 673 wcn->scan_req = &hw_req->req; 674 675 mutex_unlock(&wcn->scan_lock); 676 677 return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req); 678 } 679 680 static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw, 681 struct ieee80211_vif *vif) 682 { 683 struct wcn36xx *wcn = hw->priv; 684 685 mutex_lock(&wcn->scan_lock); 686 wcn->scan_aborted = true; 687 mutex_unlock(&wcn->scan_lock); 688 689 if (get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) { 690 /* ieee80211_scan_completed will be called on FW scan 691 * indication */ 692 wcn36xx_smd_stop_hw_scan(wcn); 693 } 694 } 695 696 static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw, 697 struct ieee80211_vif *vif, 698 const u8 *mac_addr) 699 { 700 struct wcn36xx *wcn = hw->priv; 701 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 702 703 wcn->sw_scan = true; 704 wcn->sw_scan_vif = vif; 705 if (vif_priv->sta_assoc) 706 wcn->sw_scan_opchannel = WCN36XX_HW_CHANNEL(wcn); 707 else 708 wcn->sw_scan_opchannel = 0; 709 } 710 711 static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw, 712 struct ieee80211_vif *vif) 713 { 714 struct wcn36xx *wcn = hw->priv; 715 716 /* ensure that any scan session is finished */ 717 wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN, wcn->sw_scan_vif); 718 wcn->sw_scan = false; 719 wcn->sw_scan_opchannel = 0; 720 } 721 722 static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta, 723 enum nl80211_band band) 724 { 725 int i, size; 726 u16 *rates_table; 727 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); 728 u32 rates = sta->supp_rates[band]; 729 730 memset(&sta_priv->supported_rates, 0, 731 sizeof(sta_priv->supported_rates)); 732 sta_priv->supported_rates.op_rate_mode = STA_11n; 733 734 size = ARRAY_SIZE(sta_priv->supported_rates.dsss_rates); 735 rates_table = sta_priv->supported_rates.dsss_rates; 736 if (band == NL80211_BAND_2GHZ) { 737 for (i = 0; i < size; i++) { 738 if (rates & 0x01) { 739 rates_table[i] = wcn_2ghz_rates[i].hw_value; 740 rates = rates >> 1; 741 } 742 } 743 } 744 745 size = ARRAY_SIZE(sta_priv->supported_rates.ofdm_rates); 746 rates_table = sta_priv->supported_rates.ofdm_rates; 747 for (i = 0; i < size; i++) { 748 if (rates & 0x01) { 749 rates_table[i] = wcn_5ghz_rates[i].hw_value; 750 rates = rates >> 1; 751 } 752 } 753 754 if (sta->ht_cap.ht_supported) { 755 BUILD_BUG_ON(sizeof(sta->ht_cap.mcs.rx_mask) > 756 sizeof(sta_priv->supported_rates.supported_mcs_set)); 757 memcpy(sta_priv->supported_rates.supported_mcs_set, 758 sta->ht_cap.mcs.rx_mask, 759 sizeof(sta->ht_cap.mcs.rx_mask)); 760 } 761 762 if (sta->vht_cap.vht_supported) { 763 sta_priv->supported_rates.op_rate_mode = STA_11ac; 764 sta_priv->supported_rates.vht_rx_mcs_map = 765 sta->vht_cap.vht_mcs.rx_mcs_map; 766 sta_priv->supported_rates.vht_tx_mcs_map = 767 sta->vht_cap.vht_mcs.tx_mcs_map; 768 } 769 } 770 771 void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates) 772 { 773 u16 ofdm_rates[WCN36XX_HAL_NUM_OFDM_RATES] = { 774 HW_RATE_INDEX_6MBPS, 775 HW_RATE_INDEX_9MBPS, 776 HW_RATE_INDEX_12MBPS, 777 HW_RATE_INDEX_18MBPS, 778 HW_RATE_INDEX_24MBPS, 779 HW_RATE_INDEX_36MBPS, 780 HW_RATE_INDEX_48MBPS, 781 HW_RATE_INDEX_54MBPS 782 }; 783 u16 dsss_rates[WCN36XX_HAL_NUM_DSSS_RATES] = { 784 HW_RATE_INDEX_1MBPS, 785 HW_RATE_INDEX_2MBPS, 786 HW_RATE_INDEX_5_5MBPS, 787 HW_RATE_INDEX_11MBPS 788 }; 789 790 rates->op_rate_mode = STA_11n; 791 memcpy(rates->dsss_rates, dsss_rates, 792 sizeof(*dsss_rates) * WCN36XX_HAL_NUM_DSSS_RATES); 793 memcpy(rates->ofdm_rates, ofdm_rates, 794 sizeof(*ofdm_rates) * WCN36XX_HAL_NUM_OFDM_RATES); 795 rates->supported_mcs_set[0] = 0xFF; 796 } 797 798 void wcn36xx_set_default_rates_v1(struct wcn36xx_hal_supported_rates_v1 *rates) 799 { 800 rates->op_rate_mode = STA_11ac; 801 rates->vht_rx_mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9; 802 rates->vht_tx_mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9; 803 } 804 805 static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, 806 struct ieee80211_vif *vif, 807 struct ieee80211_bss_conf *bss_conf, 808 u32 changed) 809 { 810 struct wcn36xx *wcn = hw->priv; 811 struct sk_buff *skb = NULL; 812 u16 tim_off, tim_len; 813 enum wcn36xx_hal_link_state link_state; 814 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 815 816 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x\n", 817 vif, changed); 818 819 mutex_lock(&wcn->conf_mutex); 820 821 if (changed & BSS_CHANGED_BEACON_INFO) { 822 wcn36xx_dbg(WCN36XX_DBG_MAC, 823 "mac bss changed dtim period %d\n", 824 bss_conf->dtim_period); 825 826 vif_priv->dtim_period = bss_conf->dtim_period; 827 } 828 829 if (changed & BSS_CHANGED_BSSID) { 830 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed_bssid %pM\n", 831 bss_conf->bssid); 832 833 if (!is_zero_ether_addr(bss_conf->bssid)) { 834 vif_priv->is_joining = true; 835 vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX; 836 wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr, 837 WCN36XX_HAL_LINK_PREASSOC_STATE); 838 wcn36xx_smd_join(wcn, bss_conf->bssid, 839 vif->addr, WCN36XX_HW_CHANNEL(wcn)); 840 wcn36xx_smd_config_bss(wcn, vif, NULL, 841 bss_conf->bssid, false); 842 } else { 843 vif_priv->is_joining = false; 844 wcn36xx_smd_delete_bss(wcn, vif); 845 wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr, 846 WCN36XX_HAL_LINK_IDLE_STATE); 847 vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE; 848 } 849 } 850 851 if (changed & BSS_CHANGED_SSID) { 852 wcn36xx_dbg(WCN36XX_DBG_MAC, 853 "mac bss changed ssid\n"); 854 wcn36xx_dbg_dump(WCN36XX_DBG_MAC, "ssid ", 855 bss_conf->ssid, bss_conf->ssid_len); 856 857 vif_priv->ssid.length = bss_conf->ssid_len; 858 memcpy(&vif_priv->ssid.ssid, 859 bss_conf->ssid, 860 bss_conf->ssid_len); 861 } 862 863 if (changed & BSS_CHANGED_ASSOC) { 864 vif_priv->is_joining = false; 865 if (bss_conf->assoc) { 866 struct ieee80211_sta *sta; 867 struct wcn36xx_sta *sta_priv; 868 869 wcn36xx_dbg(WCN36XX_DBG_MAC, 870 "mac assoc bss %pM vif %pM AID=%d\n", 871 bss_conf->bssid, 872 vif->addr, 873 bss_conf->aid); 874 875 vif_priv->sta_assoc = true; 876 877 /* 878 * Holding conf_mutex ensures mutal exclusion with 879 * wcn36xx_sta_remove() and as such ensures that sta 880 * won't be freed while we're operating on it. As such 881 * we do not need to hold the rcu_read_lock(). 882 */ 883 sta = ieee80211_find_sta(vif, bss_conf->bssid); 884 if (!sta) { 885 wcn36xx_err("sta %pM is not found\n", 886 bss_conf->bssid); 887 goto out; 888 } 889 sta_priv = wcn36xx_sta_to_priv(sta); 890 891 wcn36xx_update_allowed_rates(sta, WCN36XX_BAND(wcn)); 892 893 wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, 894 vif->addr, 895 WCN36XX_HAL_LINK_POSTASSOC_STATE); 896 wcn36xx_smd_config_bss(wcn, vif, sta, 897 bss_conf->bssid, 898 true); 899 sta_priv->aid = bss_conf->aid; 900 /* 901 * config_sta must be called from because this is the 902 * place where AID is available. 903 */ 904 wcn36xx_smd_config_sta(wcn, vif, sta); 905 wcn36xx_enable_keep_alive_null_packet(wcn, vif); 906 } else { 907 wcn36xx_dbg(WCN36XX_DBG_MAC, 908 "disassociated bss %pM vif %pM AID=%d\n", 909 bss_conf->bssid, 910 vif->addr, 911 bss_conf->aid); 912 vif_priv->sta_assoc = false; 913 vif_priv->allow_bmps = false; 914 wcn36xx_smd_set_link_st(wcn, 915 bss_conf->bssid, 916 vif->addr, 917 WCN36XX_HAL_LINK_IDLE_STATE); 918 } 919 } 920 921 if (changed & BSS_CHANGED_AP_PROBE_RESP) { 922 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed ap probe resp\n"); 923 skb = ieee80211_proberesp_get(hw, vif); 924 if (!skb) { 925 wcn36xx_err("failed to alloc probereq skb\n"); 926 goto out; 927 } 928 929 wcn36xx_smd_update_proberesp_tmpl(wcn, vif, skb); 930 dev_kfree_skb(skb); 931 } 932 933 if (changed & BSS_CHANGED_BEACON_ENABLED || 934 changed & BSS_CHANGED_BEACON) { 935 wcn36xx_dbg(WCN36XX_DBG_MAC, 936 "mac bss changed beacon enabled %d\n", 937 bss_conf->enable_beacon); 938 939 if (bss_conf->enable_beacon) { 940 vif_priv->dtim_period = bss_conf->dtim_period; 941 vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX; 942 wcn36xx_smd_config_bss(wcn, vif, NULL, 943 vif->addr, false); 944 skb = ieee80211_beacon_get_tim(hw, vif, &tim_off, 945 &tim_len); 946 if (!skb) { 947 wcn36xx_err("failed to alloc beacon skb\n"); 948 goto out; 949 } 950 wcn36xx_smd_send_beacon(wcn, vif, skb, tim_off, 0); 951 dev_kfree_skb(skb); 952 953 if (vif->type == NL80211_IFTYPE_ADHOC || 954 vif->type == NL80211_IFTYPE_MESH_POINT) 955 link_state = WCN36XX_HAL_LINK_IBSS_STATE; 956 else 957 link_state = WCN36XX_HAL_LINK_AP_STATE; 958 959 wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr, 960 link_state); 961 } else { 962 wcn36xx_smd_delete_bss(wcn, vif); 963 wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr, 964 WCN36XX_HAL_LINK_IDLE_STATE); 965 } 966 } 967 out: 968 969 mutex_unlock(&wcn->conf_mutex); 970 } 971 972 /* this is required when using IEEE80211_HW_HAS_RATE_CONTROL */ 973 static int wcn36xx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 974 { 975 struct wcn36xx *wcn = hw->priv; 976 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac set RTS threshold %d\n", value); 977 978 mutex_lock(&wcn->conf_mutex); 979 wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_RTS_THRESHOLD, value); 980 mutex_unlock(&wcn->conf_mutex); 981 982 return 0; 983 } 984 985 static void wcn36xx_remove_interface(struct ieee80211_hw *hw, 986 struct ieee80211_vif *vif) 987 { 988 struct wcn36xx *wcn = hw->priv; 989 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 990 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif); 991 992 mutex_lock(&wcn->conf_mutex); 993 994 list_del(&vif_priv->list); 995 wcn36xx_smd_delete_sta_self(wcn, vif->addr); 996 997 mutex_unlock(&wcn->conf_mutex); 998 } 999 1000 static int wcn36xx_add_interface(struct ieee80211_hw *hw, 1001 struct ieee80211_vif *vif) 1002 { 1003 struct wcn36xx *wcn = hw->priv; 1004 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 1005 1006 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac add interface vif %p type %d\n", 1007 vif, vif->type); 1008 1009 if (!(NL80211_IFTYPE_STATION == vif->type || 1010 NL80211_IFTYPE_AP == vif->type || 1011 NL80211_IFTYPE_ADHOC == vif->type || 1012 NL80211_IFTYPE_MESH_POINT == vif->type)) { 1013 wcn36xx_warn("Unsupported interface type requested: %d\n", 1014 vif->type); 1015 return -EOPNOTSUPP; 1016 } 1017 1018 mutex_lock(&wcn->conf_mutex); 1019 1020 vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX; 1021 INIT_LIST_HEAD(&vif_priv->sta_list); 1022 list_add(&vif_priv->list, &wcn->vif_list); 1023 wcn36xx_smd_add_sta_self(wcn, vif); 1024 1025 mutex_unlock(&wcn->conf_mutex); 1026 1027 return 0; 1028 } 1029 1030 static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1031 struct ieee80211_sta *sta) 1032 { 1033 struct wcn36xx *wcn = hw->priv; 1034 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 1035 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); 1036 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n", 1037 vif, sta->addr); 1038 1039 mutex_lock(&wcn->conf_mutex); 1040 1041 spin_lock_init(&sta_priv->ampdu_lock); 1042 sta_priv->vif = vif_priv; 1043 list_add(&sta_priv->list, &vif_priv->sta_list); 1044 1045 /* 1046 * For STA mode HW will be configured on BSS_CHANGED_ASSOC because 1047 * at this stage AID is not available yet. 1048 */ 1049 if (NL80211_IFTYPE_STATION != vif->type) { 1050 wcn36xx_update_allowed_rates(sta, WCN36XX_BAND(wcn)); 1051 sta_priv->aid = sta->aid; 1052 wcn36xx_smd_config_sta(wcn, vif, sta); 1053 } 1054 1055 mutex_unlock(&wcn->conf_mutex); 1056 1057 return 0; 1058 } 1059 1060 static int wcn36xx_sta_remove(struct ieee80211_hw *hw, 1061 struct ieee80211_vif *vif, 1062 struct ieee80211_sta *sta) 1063 { 1064 struct wcn36xx *wcn = hw->priv; 1065 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); 1066 1067 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n", 1068 vif, sta->addr, sta_priv->sta_index); 1069 1070 mutex_lock(&wcn->conf_mutex); 1071 1072 list_del(&sta_priv->list); 1073 wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index); 1074 sta_priv->vif = NULL; 1075 1076 mutex_unlock(&wcn->conf_mutex); 1077 1078 return 0; 1079 } 1080 1081 #ifdef CONFIG_PM 1082 1083 static struct ieee80211_vif *wcn36xx_get_first_assoc_vif(struct wcn36xx *wcn) 1084 { 1085 struct wcn36xx_vif *vif_priv = NULL; 1086 struct ieee80211_vif *vif = NULL; 1087 1088 list_for_each_entry(vif_priv, &wcn->vif_list, list) { 1089 if (vif_priv->sta_assoc) { 1090 vif = wcn36xx_priv_to_vif(vif_priv); 1091 break; 1092 } 1093 } 1094 return vif; 1095 } 1096 1097 static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow) 1098 { 1099 struct wcn36xx *wcn = hw->priv; 1100 struct ieee80211_vif *vif = NULL; 1101 int ret = 0; 1102 1103 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac suspend\n"); 1104 1105 mutex_lock(&wcn->conf_mutex); 1106 1107 vif = wcn36xx_get_first_assoc_vif(wcn); 1108 if (vif) { 1109 ret = wcn36xx_smd_arp_offload(wcn, vif, true); 1110 if (ret) 1111 goto out; 1112 ret = wcn36xx_smd_ipv6_ns_offload(wcn, vif, true); 1113 if (ret) 1114 goto out; 1115 ret = wcn36xx_smd_gtk_offload(wcn, vif, true); 1116 if (ret) 1117 goto out; 1118 ret = wcn36xx_smd_set_power_params(wcn, true); 1119 if (ret) 1120 goto out; 1121 ret = wcn36xx_smd_wlan_host_suspend_ind(wcn); 1122 } 1123 out: 1124 mutex_unlock(&wcn->conf_mutex); 1125 return ret; 1126 } 1127 1128 static int wcn36xx_resume(struct ieee80211_hw *hw) 1129 { 1130 struct wcn36xx *wcn = hw->priv; 1131 struct ieee80211_vif *vif = NULL; 1132 1133 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac resume\n"); 1134 1135 mutex_lock(&wcn->conf_mutex); 1136 vif = wcn36xx_get_first_assoc_vif(wcn); 1137 if (vif) { 1138 wcn36xx_smd_host_resume(wcn); 1139 wcn36xx_smd_set_power_params(wcn, false); 1140 wcn36xx_smd_gtk_offload_get_info(wcn, vif); 1141 wcn36xx_smd_gtk_offload(wcn, vif, false); 1142 wcn36xx_smd_ipv6_ns_offload(wcn, vif, false); 1143 wcn36xx_smd_arp_offload(wcn, vif, false); 1144 } 1145 mutex_unlock(&wcn->conf_mutex); 1146 1147 return 0; 1148 } 1149 1150 static void wcn36xx_set_rekey_data(struct ieee80211_hw *hw, 1151 struct ieee80211_vif *vif, 1152 struct cfg80211_gtk_rekey_data *data) 1153 { 1154 struct wcn36xx *wcn = hw->priv; 1155 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 1156 1157 mutex_lock(&wcn->conf_mutex); 1158 1159 memcpy(vif_priv->rekey_data.kek, data->kek, NL80211_KEK_LEN); 1160 memcpy(vif_priv->rekey_data.kck, data->kck, NL80211_KCK_LEN); 1161 vif_priv->rekey_data.replay_ctr = 1162 cpu_to_le64(be64_to_cpup((__be64 *)data->replay_ctr)); 1163 vif_priv->rekey_data.valid = true; 1164 1165 mutex_unlock(&wcn->conf_mutex); 1166 } 1167 1168 #endif 1169 1170 static int wcn36xx_ampdu_action(struct ieee80211_hw *hw, 1171 struct ieee80211_vif *vif, 1172 struct ieee80211_ampdu_params *params) 1173 { 1174 struct wcn36xx *wcn = hw->priv; 1175 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(params->sta); 1176 struct ieee80211_sta *sta = params->sta; 1177 enum ieee80211_ampdu_mlme_action action = params->action; 1178 u16 tid = params->tid; 1179 u16 *ssn = ¶ms->ssn; 1180 int ret = 0; 1181 u8 session; 1182 1183 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n", 1184 action, tid); 1185 1186 mutex_lock(&wcn->conf_mutex); 1187 1188 switch (action) { 1189 case IEEE80211_AMPDU_RX_START: 1190 sta_priv->tid = tid; 1191 session = wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 0, 1192 get_sta_index(vif, sta_priv)); 1193 wcn36xx_smd_add_ba(wcn, session); 1194 wcn36xx_smd_trigger_ba(wcn, get_sta_index(vif, sta_priv), tid, 1195 session); 1196 break; 1197 case IEEE80211_AMPDU_RX_STOP: 1198 wcn36xx_smd_del_ba(wcn, tid, 0, get_sta_index(vif, sta_priv)); 1199 break; 1200 case IEEE80211_AMPDU_TX_START: 1201 spin_lock_bh(&sta_priv->ampdu_lock); 1202 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_START; 1203 spin_unlock_bh(&sta_priv->ampdu_lock); 1204 1205 ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; 1206 break; 1207 case IEEE80211_AMPDU_TX_OPERATIONAL: 1208 spin_lock_bh(&sta_priv->ampdu_lock); 1209 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_OPERATIONAL; 1210 spin_unlock_bh(&sta_priv->ampdu_lock); 1211 1212 wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 1, 1213 get_sta_index(vif, sta_priv)); 1214 break; 1215 case IEEE80211_AMPDU_TX_STOP_FLUSH: 1216 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 1217 case IEEE80211_AMPDU_TX_STOP_CONT: 1218 spin_lock_bh(&sta_priv->ampdu_lock); 1219 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_NONE; 1220 spin_unlock_bh(&sta_priv->ampdu_lock); 1221 1222 wcn36xx_smd_del_ba(wcn, tid, 1, get_sta_index(vif, sta_priv)); 1223 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1224 break; 1225 default: 1226 wcn36xx_err("Unknown AMPDU action\n"); 1227 } 1228 1229 mutex_unlock(&wcn->conf_mutex); 1230 1231 return ret; 1232 } 1233 1234 #if IS_ENABLED(CONFIG_IPV6) 1235 static void wcn36xx_ipv6_addr_change(struct ieee80211_hw *hw, 1236 struct ieee80211_vif *vif, 1237 struct inet6_dev *idev) 1238 { 1239 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 1240 struct inet6_ifaddr *ifa; 1241 int idx = 0; 1242 1243 memset(vif_priv->tentative_addrs, 0, sizeof(vif_priv->tentative_addrs)); 1244 1245 read_lock_bh(&idev->lock); 1246 list_for_each_entry(ifa, &idev->addr_list, if_list) { 1247 vif_priv->target_ipv6_addrs[idx] = ifa->addr; 1248 if (ifa->flags & IFA_F_TENTATIVE) 1249 __set_bit(idx, vif_priv->tentative_addrs); 1250 idx++; 1251 if (idx >= WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX) 1252 break; 1253 wcn36xx_dbg(WCN36XX_DBG_MAC, "%pI6 %s\n", &ifa->addr, 1254 (ifa->flags & IFA_F_TENTATIVE) ? "tentative" : NULL); 1255 } 1256 read_unlock_bh(&idev->lock); 1257 1258 vif_priv->num_target_ipv6_addrs = idx; 1259 } 1260 #endif 1261 1262 static const struct ieee80211_ops wcn36xx_ops = { 1263 .start = wcn36xx_start, 1264 .stop = wcn36xx_stop, 1265 .add_interface = wcn36xx_add_interface, 1266 .remove_interface = wcn36xx_remove_interface, 1267 #ifdef CONFIG_PM 1268 .suspend = wcn36xx_suspend, 1269 .resume = wcn36xx_resume, 1270 .set_rekey_data = wcn36xx_set_rekey_data, 1271 #endif 1272 .config = wcn36xx_config, 1273 .prepare_multicast = wcn36xx_prepare_multicast, 1274 .configure_filter = wcn36xx_configure_filter, 1275 .tx = wcn36xx_tx, 1276 .set_key = wcn36xx_set_key, 1277 .hw_scan = wcn36xx_hw_scan, 1278 .cancel_hw_scan = wcn36xx_cancel_hw_scan, 1279 .sw_scan_start = wcn36xx_sw_scan_start, 1280 .sw_scan_complete = wcn36xx_sw_scan_complete, 1281 .bss_info_changed = wcn36xx_bss_info_changed, 1282 .set_rts_threshold = wcn36xx_set_rts_threshold, 1283 .sta_add = wcn36xx_sta_add, 1284 .sta_remove = wcn36xx_sta_remove, 1285 .ampdu_action = wcn36xx_ampdu_action, 1286 #if IS_ENABLED(CONFIG_IPV6) 1287 .ipv6_addr_change = wcn36xx_ipv6_addr_change, 1288 #endif 1289 1290 CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd) 1291 }; 1292 1293 static void 1294 wcn36xx_set_ieee80211_vht_caps(struct ieee80211_sta_vht_cap *vht_cap) 1295 { 1296 vht_cap->vht_supported = true; 1297 1298 vht_cap->cap = (IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 | 1299 IEEE80211_VHT_CAP_SHORT_GI_80 | 1300 IEEE80211_VHT_CAP_RXSTBC_1 | 1301 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | 1302 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | 1303 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT | 1304 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT); 1305 1306 vht_cap->vht_mcs.rx_mcs_map = 1307 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 | 1308 IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 | 1309 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | 1310 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | 1311 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | 1312 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | 1313 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | 1314 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14); 1315 1316 vht_cap->vht_mcs.rx_highest = cpu_to_le16(433); 1317 vht_cap->vht_mcs.tx_highest = vht_cap->vht_mcs.rx_highest; 1318 1319 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map; 1320 } 1321 1322 static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) 1323 { 1324 static const u32 cipher_suites[] = { 1325 WLAN_CIPHER_SUITE_WEP40, 1326 WLAN_CIPHER_SUITE_WEP104, 1327 WLAN_CIPHER_SUITE_TKIP, 1328 WLAN_CIPHER_SUITE_CCMP, 1329 }; 1330 1331 ieee80211_hw_set(wcn->hw, TIMING_BEACON_ONLY); 1332 ieee80211_hw_set(wcn->hw, AMPDU_AGGREGATION); 1333 ieee80211_hw_set(wcn->hw, SUPPORTS_PS); 1334 ieee80211_hw_set(wcn->hw, SIGNAL_DBM); 1335 ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL); 1336 ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS); 1337 ieee80211_hw_set(wcn->hw, REPORTS_TX_ACK_STATUS); 1338 ieee80211_hw_set(wcn->hw, CONNECTION_MONITOR); 1339 1340 wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1341 BIT(NL80211_IFTYPE_AP) | 1342 BIT(NL80211_IFTYPE_ADHOC) | 1343 BIT(NL80211_IFTYPE_MESH_POINT); 1344 1345 wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = &wcn_band_2ghz; 1346 if (wcn->rf_id != RF_IRIS_WCN3620) 1347 wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = &wcn_band_5ghz; 1348 1349 if (wcn->rf_id == RF_IRIS_WCN3680) 1350 wcn36xx_set_ieee80211_vht_caps(&wcn_band_5ghz.vht_cap); 1351 1352 wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS; 1353 wcn->hw->wiphy->max_scan_ie_len = WCN36XX_MAX_SCAN_IE_LEN; 1354 1355 wcn->hw->wiphy->cipher_suites = cipher_suites; 1356 wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 1357 1358 #ifdef CONFIG_PM 1359 wcn->hw->wiphy->wowlan = &wowlan_support; 1360 #endif 1361 1362 wcn->hw->max_listen_interval = 200; 1363 1364 wcn->hw->queues = 4; 1365 1366 SET_IEEE80211_DEV(wcn->hw, wcn->dev); 1367 1368 wcn->hw->sta_data_size = sizeof(struct wcn36xx_sta); 1369 wcn->hw->vif_data_size = sizeof(struct wcn36xx_vif); 1370 1371 wiphy_ext_feature_set(wcn->hw->wiphy, 1372 NL80211_EXT_FEATURE_CQM_RSSI_LIST); 1373 1374 return 0; 1375 } 1376 1377 static int wcn36xx_platform_get_resources(struct wcn36xx *wcn, 1378 struct platform_device *pdev) 1379 { 1380 struct device_node *mmio_node; 1381 struct device_node *iris_node; 1382 struct resource *res; 1383 int index; 1384 int ret; 1385 1386 /* Set TX IRQ */ 1387 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tx"); 1388 if (!res) { 1389 wcn36xx_err("failed to get tx_irq\n"); 1390 return -ENOENT; 1391 } 1392 wcn->tx_irq = res->start; 1393 1394 /* Set RX IRQ */ 1395 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "rx"); 1396 if (!res) { 1397 wcn36xx_err("failed to get rx_irq\n"); 1398 return -ENOENT; 1399 } 1400 wcn->rx_irq = res->start; 1401 1402 /* Acquire SMSM tx enable handle */ 1403 wcn->tx_enable_state = qcom_smem_state_get(&pdev->dev, 1404 "tx-enable", &wcn->tx_enable_state_bit); 1405 if (IS_ERR(wcn->tx_enable_state)) { 1406 wcn36xx_err("failed to get tx-enable state\n"); 1407 return PTR_ERR(wcn->tx_enable_state); 1408 } 1409 1410 /* Acquire SMSM tx rings empty handle */ 1411 wcn->tx_rings_empty_state = qcom_smem_state_get(&pdev->dev, 1412 "tx-rings-empty", &wcn->tx_rings_empty_state_bit); 1413 if (IS_ERR(wcn->tx_rings_empty_state)) { 1414 wcn36xx_err("failed to get tx-rings-empty state\n"); 1415 return PTR_ERR(wcn->tx_rings_empty_state); 1416 } 1417 1418 mmio_node = of_parse_phandle(pdev->dev.parent->of_node, "qcom,mmio", 0); 1419 if (!mmio_node) { 1420 wcn36xx_err("failed to acquire qcom,mmio reference\n"); 1421 return -EINVAL; 1422 } 1423 1424 wcn->is_pronto = !!of_device_is_compatible(mmio_node, "qcom,pronto"); 1425 1426 /* Map the CCU memory */ 1427 index = of_property_match_string(mmio_node, "reg-names", "ccu"); 1428 wcn->ccu_base = of_iomap(mmio_node, index); 1429 if (!wcn->ccu_base) { 1430 wcn36xx_err("failed to map ccu memory\n"); 1431 ret = -ENOMEM; 1432 goto put_mmio_node; 1433 } 1434 1435 /* Map the DXE memory */ 1436 index = of_property_match_string(mmio_node, "reg-names", "dxe"); 1437 wcn->dxe_base = of_iomap(mmio_node, index); 1438 if (!wcn->dxe_base) { 1439 wcn36xx_err("failed to map dxe memory\n"); 1440 ret = -ENOMEM; 1441 goto unmap_ccu; 1442 } 1443 1444 /* External RF module */ 1445 iris_node = of_get_child_by_name(mmio_node, "iris"); 1446 if (iris_node) { 1447 if (of_device_is_compatible(iris_node, "qcom,wcn3620")) 1448 wcn->rf_id = RF_IRIS_WCN3620; 1449 if (of_device_is_compatible(iris_node, "qcom,wcn3680")) 1450 wcn->rf_id = RF_IRIS_WCN3680; 1451 of_node_put(iris_node); 1452 } 1453 1454 of_node_put(mmio_node); 1455 return 0; 1456 1457 unmap_ccu: 1458 iounmap(wcn->ccu_base); 1459 put_mmio_node: 1460 of_node_put(mmio_node); 1461 return ret; 1462 } 1463 1464 static int wcn36xx_probe(struct platform_device *pdev) 1465 { 1466 struct ieee80211_hw *hw; 1467 struct wcn36xx *wcn; 1468 void *wcnss; 1469 int ret; 1470 const u8 *addr; 1471 1472 wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n"); 1473 1474 wcnss = dev_get_drvdata(pdev->dev.parent); 1475 1476 hw = ieee80211_alloc_hw(sizeof(struct wcn36xx), &wcn36xx_ops); 1477 if (!hw) { 1478 wcn36xx_err("failed to alloc hw\n"); 1479 ret = -ENOMEM; 1480 goto out_err; 1481 } 1482 platform_set_drvdata(pdev, hw); 1483 wcn = hw->priv; 1484 wcn->hw = hw; 1485 wcn->dev = &pdev->dev; 1486 wcn->first_boot = true; 1487 mutex_init(&wcn->conf_mutex); 1488 mutex_init(&wcn->hal_mutex); 1489 mutex_init(&wcn->scan_lock); 1490 1491 wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); 1492 if (!wcn->hal_buf) { 1493 ret = -ENOMEM; 1494 goto out_wq; 1495 } 1496 1497 ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32)); 1498 if (ret < 0) { 1499 wcn36xx_err("failed to set DMA mask: %d\n", ret); 1500 goto out_wq; 1501 } 1502 1503 wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process, hw); 1504 if (IS_ERR(wcn->smd_channel)) { 1505 wcn36xx_err("failed to open WLAN_CTRL channel\n"); 1506 ret = PTR_ERR(wcn->smd_channel); 1507 goto out_wq; 1508 } 1509 1510 addr = of_get_property(pdev->dev.of_node, "local-mac-address", &ret); 1511 if (addr && ret != ETH_ALEN) { 1512 wcn36xx_err("invalid local-mac-address\n"); 1513 ret = -EINVAL; 1514 goto out_destroy_ept; 1515 } else if (addr) { 1516 wcn36xx_info("mac address: %pM\n", addr); 1517 SET_IEEE80211_PERM_ADDR(wcn->hw, addr); 1518 } 1519 1520 ret = wcn36xx_platform_get_resources(wcn, pdev); 1521 if (ret) 1522 goto out_destroy_ept; 1523 1524 wcn36xx_init_ieee80211(wcn); 1525 ret = ieee80211_register_hw(wcn->hw); 1526 if (ret) 1527 goto out_unmap; 1528 1529 return 0; 1530 1531 out_unmap: 1532 iounmap(wcn->ccu_base); 1533 iounmap(wcn->dxe_base); 1534 out_destroy_ept: 1535 rpmsg_destroy_ept(wcn->smd_channel); 1536 out_wq: 1537 ieee80211_free_hw(hw); 1538 out_err: 1539 return ret; 1540 } 1541 1542 static int wcn36xx_remove(struct platform_device *pdev) 1543 { 1544 struct ieee80211_hw *hw = platform_get_drvdata(pdev); 1545 struct wcn36xx *wcn = hw->priv; 1546 wcn36xx_dbg(WCN36XX_DBG_MAC, "platform remove\n"); 1547 1548 release_firmware(wcn->nv); 1549 1550 ieee80211_unregister_hw(hw); 1551 1552 qcom_smem_state_put(wcn->tx_enable_state); 1553 qcom_smem_state_put(wcn->tx_rings_empty_state); 1554 1555 rpmsg_destroy_ept(wcn->smd_channel); 1556 1557 iounmap(wcn->dxe_base); 1558 iounmap(wcn->ccu_base); 1559 1560 mutex_destroy(&wcn->hal_mutex); 1561 ieee80211_free_hw(hw); 1562 1563 return 0; 1564 } 1565 1566 static const struct of_device_id wcn36xx_of_match[] = { 1567 { .compatible = "qcom,wcnss-wlan" }, 1568 {} 1569 }; 1570 MODULE_DEVICE_TABLE(of, wcn36xx_of_match); 1571 1572 static struct platform_driver wcn36xx_driver = { 1573 .probe = wcn36xx_probe, 1574 .remove = wcn36xx_remove, 1575 .driver = { 1576 .name = "wcn36xx", 1577 .of_match_table = wcn36xx_of_match, 1578 }, 1579 }; 1580 1581 module_platform_driver(wcn36xx_driver); 1582 1583 MODULE_LICENSE("Dual BSD/GPL"); 1584 MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com"); 1585 MODULE_FIRMWARE(WLAN_NV_FILE); 1586