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