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