diff options
author | Kalle Valo <kvalo@codeaurora.org> | 2016-04-26 07:13:59 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2016-04-26 07:13:59 -0400 |
commit | efd7cef3100b2683ba4ff48943215b9537e9a37c (patch) | |
tree | 73a617e1b1cd7212b4c13d36f64e03ed4a9057fc /drivers/net/wireless/ath/wcn36xx | |
parent | f0d8f38cd909e072833a06b79939256c4aebe3a0 (diff) | |
parent | ffc03c331a1e7cafac3beb4f89c40fa7d6213d6e (diff) |
Merge ath-next from ath.git
ath.git patches for 4.7. Major changes:
ath10k
* implement set_tsf() for 10.2.4 branch
* remove rare MSI range support
* remove deprecated firmware API 1 support
ath9k
* add module parameter to invert LED polarity
wcn36xx
* fixes to get the driver properly working on Dragonboard 410c
Diffstat (limited to 'drivers/net/wireless/ath/wcn36xx')
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/debug.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/hal.h | 55 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/main.c | 133 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/pmc.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/smd.c | 224 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/smd.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/txrx.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 20 |
8 files changed, 336 insertions, 132 deletions
diff --git a/drivers/net/wireless/ath/wcn36xx/debug.c b/drivers/net/wireless/ath/wcn36xx/debug.c index ef44a2da644d..2a6bb62e785c 100644 --- a/drivers/net/wireless/ath/wcn36xx/debug.c +++ b/drivers/net/wireless/ath/wcn36xx/debug.c | |||
@@ -33,9 +33,7 @@ static ssize_t read_file_bool_bmps(struct file *file, char __user *user_buf, | |||
33 | char buf[3]; | 33 | char buf[3]; |
34 | 34 | ||
35 | list_for_each_entry(vif_priv, &wcn->vif_list, list) { | 35 | list_for_each_entry(vif_priv, &wcn->vif_list, list) { |
36 | vif = container_of((void *)vif_priv, | 36 | vif = wcn36xx_priv_to_vif(vif_priv); |
37 | struct ieee80211_vif, | ||
38 | drv_priv); | ||
39 | if (NL80211_IFTYPE_STATION == vif->type) { | 37 | if (NL80211_IFTYPE_STATION == vif->type) { |
40 | if (vif_priv->pw_state == WCN36XX_BMPS) | 38 | if (vif_priv->pw_state == WCN36XX_BMPS) |
41 | buf[0] = '1'; | 39 | buf[0] = '1'; |
@@ -70,9 +68,7 @@ static ssize_t write_file_bool_bmps(struct file *file, | |||
70 | case 'Y': | 68 | case 'Y': |
71 | case '1': | 69 | case '1': |
72 | list_for_each_entry(vif_priv, &wcn->vif_list, list) { | 70 | list_for_each_entry(vif_priv, &wcn->vif_list, list) { |
73 | vif = container_of((void *)vif_priv, | 71 | vif = wcn36xx_priv_to_vif(vif_priv); |
74 | struct ieee80211_vif, | ||
75 | drv_priv); | ||
76 | if (NL80211_IFTYPE_STATION == vif->type) { | 72 | if (NL80211_IFTYPE_STATION == vif->type) { |
77 | wcn36xx_enable_keep_alive_null_packet(wcn, vif); | 73 | wcn36xx_enable_keep_alive_null_packet(wcn, vif); |
78 | wcn36xx_pmc_enter_bmps_state(wcn, vif); | 74 | wcn36xx_pmc_enter_bmps_state(wcn, vif); |
@@ -83,9 +79,7 @@ static ssize_t write_file_bool_bmps(struct file *file, | |||
83 | case 'N': | 79 | case 'N': |
84 | case '0': | 80 | case '0': |
85 | list_for_each_entry(vif_priv, &wcn->vif_list, list) { | 81 | list_for_each_entry(vif_priv, &wcn->vif_list, list) { |
86 | vif = container_of((void *)vif_priv, | 82 | vif = wcn36xx_priv_to_vif(vif_priv); |
87 | struct ieee80211_vif, | ||
88 | drv_priv); | ||
89 | if (NL80211_IFTYPE_STATION == vif->type) | 83 | if (NL80211_IFTYPE_STATION == vif->type) |
90 | wcn36xx_pmc_exit_bmps_state(wcn, vif); | 84 | wcn36xx_pmc_exit_bmps_state(wcn, vif); |
91 | } | 85 | } |
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index b947de0fb2e5..658bfb8baabe 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h | |||
@@ -48,12 +48,15 @@ | |||
48 | 48 | ||
49 | #define WCN36XX_HAL_IPV4_ADDR_LEN 4 | 49 | #define WCN36XX_HAL_IPV4_ADDR_LEN 4 |
50 | 50 | ||
51 | #define WALN_HAL_STA_INVALID_IDX 0xFF | 51 | #define WCN36XX_HAL_STA_INVALID_IDX 0xFF |
52 | #define WCN36XX_HAL_BSS_INVALID_IDX 0xFF | 52 | #define WCN36XX_HAL_BSS_INVALID_IDX 0xFF |
53 | 53 | ||
54 | /* Default Beacon template size */ | 54 | /* Default Beacon template size */ |
55 | #define BEACON_TEMPLATE_SIZE 0x180 | 55 | #define BEACON_TEMPLATE_SIZE 0x180 |
56 | 56 | ||
57 | /* Minimum PVM size that the FW expects. See comment in smd.c for details. */ | ||
58 | #define TIM_MIN_PVM_SIZE 6 | ||
59 | |||
57 | /* Param Change Bitmap sent to HAL */ | 60 | /* Param Change Bitmap sent to HAL */ |
58 | #define PARAM_BCN_INTERVAL_CHANGED (1 << 0) | 61 | #define PARAM_BCN_INTERVAL_CHANGED (1 << 0) |
59 | #define PARAM_SHORT_PREAMBLE_CHANGED (1 << 1) | 62 | #define PARAM_SHORT_PREAMBLE_CHANGED (1 << 1) |
@@ -2884,11 +2887,14 @@ struct update_beacon_rsp_msg { | |||
2884 | struct wcn36xx_hal_send_beacon_req_msg { | 2887 | struct wcn36xx_hal_send_beacon_req_msg { |
2885 | struct wcn36xx_hal_msg_header header; | 2888 | struct wcn36xx_hal_msg_header header; |
2886 | 2889 | ||
2890 | /* length of the template + 6. Only qcom knows why */ | ||
2891 | u32 beacon_length6; | ||
2892 | |||
2887 | /* length of the template. */ | 2893 | /* length of the template. */ |
2888 | u32 beacon_length; | 2894 | u32 beacon_length; |
2889 | 2895 | ||
2890 | /* Beacon data. */ | 2896 | /* Beacon data. */ |
2891 | u8 beacon[BEACON_TEMPLATE_SIZE]; | 2897 | u8 beacon[BEACON_TEMPLATE_SIZE - sizeof(u32)]; |
2892 | 2898 | ||
2893 | u8 bssid[ETH_ALEN]; | 2899 | u8 bssid[ETH_ALEN]; |
2894 | 2900 | ||
@@ -4261,9 +4267,9 @@ struct wcn36xx_hal_rcv_flt_mc_addr_list_type { | |||
4261 | u8 data_offset; | 4267 | u8 data_offset; |
4262 | 4268 | ||
4263 | u32 mc_addr_count; | 4269 | u32 mc_addr_count; |
4264 | u8 mc_addr[ETH_ALEN][WCN36XX_HAL_MAX_NUM_MULTICAST_ADDRESS]; | 4270 | u8 mc_addr[WCN36XX_HAL_MAX_NUM_MULTICAST_ADDRESS][ETH_ALEN]; |
4265 | u8 bss_index; | 4271 | u8 bss_index; |
4266 | }; | 4272 | } __packed; |
4267 | 4273 | ||
4268 | struct wcn36xx_hal_set_pkt_filter_rsp_msg { | 4274 | struct wcn36xx_hal_set_pkt_filter_rsp_msg { |
4269 | struct wcn36xx_hal_msg_header header; | 4275 | struct wcn36xx_hal_msg_header header; |
@@ -4317,7 +4323,7 @@ struct wcn36xx_hal_rcv_flt_pkt_clear_rsp_msg { | |||
4317 | struct wcn36xx_hal_rcv_flt_pkt_set_mc_list_req_msg { | 4323 | struct wcn36xx_hal_rcv_flt_pkt_set_mc_list_req_msg { |
4318 | struct wcn36xx_hal_msg_header header; | 4324 | struct wcn36xx_hal_msg_header header; |
4319 | struct wcn36xx_hal_rcv_flt_mc_addr_list_type mc_addr_list; | 4325 | struct wcn36xx_hal_rcv_flt_mc_addr_list_type mc_addr_list; |
4320 | }; | 4326 | } __packed; |
4321 | 4327 | ||
4322 | struct wcn36xx_hal_rcv_flt_pkt_set_mc_list_rsp_msg { | 4328 | struct wcn36xx_hal_rcv_flt_pkt_set_mc_list_rsp_msg { |
4323 | struct wcn36xx_hal_msg_header header; | 4329 | struct wcn36xx_hal_msg_header header; |
@@ -4383,6 +4389,45 @@ enum place_holder_in_cap_bitmap { | |||
4383 | RTT = 20, | 4389 | RTT = 20, |
4384 | RATECTRL = 21, | 4390 | RATECTRL = 21, |
4385 | WOW = 22, | 4391 | WOW = 22, |
4392 | WLAN_ROAM_SCAN_OFFLOAD = 23, | ||
4393 | SPECULATIVE_PS_POLL = 24, | ||
4394 | SCAN_SCH = 25, | ||
4395 | IBSS_HEARTBEAT_OFFLOAD = 26, | ||
4396 | WLAN_SCAN_OFFLOAD = 27, | ||
4397 | WLAN_PERIODIC_TX_PTRN = 28, | ||
4398 | ADVANCE_TDLS = 29, | ||
4399 | BATCH_SCAN = 30, | ||
4400 | FW_IN_TX_PATH = 31, | ||
4401 | EXTENDED_NSOFFLOAD_SLOT = 32, | ||
4402 | CH_SWITCH_V1 = 33, | ||
4403 | HT40_OBSS_SCAN = 34, | ||
4404 | UPDATE_CHANNEL_LIST = 35, | ||
4405 | WLAN_MCADDR_FLT = 36, | ||
4406 | WLAN_CH144 = 37, | ||
4407 | NAN = 38, | ||
4408 | TDLS_SCAN_COEXISTENCE = 39, | ||
4409 | LINK_LAYER_STATS_MEAS = 40, | ||
4410 | MU_MIMO = 41, | ||
4411 | EXTENDED_SCAN = 42, | ||
4412 | DYNAMIC_WMM_PS = 43, | ||
4413 | MAC_SPOOFED_SCAN = 44, | ||
4414 | BMU_ERROR_GENERIC_RECOVERY = 45, | ||
4415 | DISA = 46, | ||
4416 | FW_STATS = 47, | ||
4417 | WPS_PRBRSP_TMPL = 48, | ||
4418 | BCN_IE_FLT_DELTA = 49, | ||
4419 | TDLS_OFF_CHANNEL = 51, | ||
4420 | RTT3 = 52, | ||
4421 | MGMT_FRAME_LOGGING = 53, | ||
4422 | ENHANCED_TXBD_COMPLETION = 54, | ||
4423 | LOGGING_ENHANCEMENT = 55, | ||
4424 | EXT_SCAN_ENHANCED = 56, | ||
4425 | MEMORY_DUMP_SUPPORTED = 57, | ||
4426 | PER_PKT_STATS_SUPPORTED = 58, | ||
4427 | EXT_LL_STAT = 60, | ||
4428 | WIFI_CONFIG = 61, | ||
4429 | ANTENNA_DIVERSITY_SELECTION = 62, | ||
4430 | |||
4386 | MAX_FEATURE_SUPPORTED = 128, | 4431 | MAX_FEATURE_SUPPORTED = 128, |
4387 | }; | 4432 | }; |
4388 | 4433 | ||
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 9a1db3bbec4e..a920d7020148 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c | |||
@@ -201,7 +201,45 @@ static const char * const wcn36xx_caps_names[] = { | |||
201 | "BCN_FILTER", /* 19 */ | 201 | "BCN_FILTER", /* 19 */ |
202 | "RTT", /* 20 */ | 202 | "RTT", /* 20 */ |
203 | "RATECTRL", /* 21 */ | 203 | "RATECTRL", /* 21 */ |
204 | "WOW" /* 22 */ | 204 | "WOW", /* 22 */ |
205 | "WLAN_ROAM_SCAN_OFFLOAD", /* 23 */ | ||
206 | "SPECULATIVE_PS_POLL", /* 24 */ | ||
207 | "SCAN_SCH", /* 25 */ | ||
208 | "IBSS_HEARTBEAT_OFFLOAD", /* 26 */ | ||
209 | "WLAN_SCAN_OFFLOAD", /* 27 */ | ||
210 | "WLAN_PERIODIC_TX_PTRN", /* 28 */ | ||
211 | "ADVANCE_TDLS", /* 29 */ | ||
212 | "BATCH_SCAN", /* 30 */ | ||
213 | "FW_IN_TX_PATH", /* 31 */ | ||
214 | "EXTENDED_NSOFFLOAD_SLOT", /* 32 */ | ||
215 | "CH_SWITCH_V1", /* 33 */ | ||
216 | "HT40_OBSS_SCAN", /* 34 */ | ||
217 | "UPDATE_CHANNEL_LIST", /* 35 */ | ||
218 | "WLAN_MCADDR_FLT", /* 36 */ | ||
219 | "WLAN_CH144", /* 37 */ | ||
220 | "NAN", /* 38 */ | ||
221 | "TDLS_SCAN_COEXISTENCE", /* 39 */ | ||
222 | "LINK_LAYER_STATS_MEAS", /* 40 */ | ||
223 | "MU_MIMO", /* 41 */ | ||
224 | "EXTENDED_SCAN", /* 42 */ | ||
225 | "DYNAMIC_WMM_PS", /* 43 */ | ||
226 | "MAC_SPOOFED_SCAN", /* 44 */ | ||
227 | "BMU_ERROR_GENERIC_RECOVERY", /* 45 */ | ||
228 | "DISA", /* 46 */ | ||
229 | "FW_STATS", /* 47 */ | ||
230 | "WPS_PRBRSP_TMPL", /* 48 */ | ||
231 | "BCN_IE_FLT_DELTA", /* 49 */ | ||
232 | "TDLS_OFF_CHANNEL", /* 51 */ | ||
233 | "RTT3", /* 52 */ | ||
234 | "MGMT_FRAME_LOGGING", /* 53 */ | ||
235 | "ENHANCED_TXBD_COMPLETION", /* 54 */ | ||
236 | "LOGGING_ENHANCEMENT", /* 55 */ | ||
237 | "EXT_SCAN_ENHANCED", /* 56 */ | ||
238 | "MEMORY_DUMP_SUPPORTED", /* 57 */ | ||
239 | "PER_PKT_STATS_SUPPORTED", /* 58 */ | ||
240 | "EXT_LL_STAT", /* 60 */ | ||
241 | "WIFI_CONFIG", /* 61 */ | ||
242 | "ANTENNA_DIVERSITY_SELECTION", /* 62 */ | ||
205 | }; | 243 | }; |
206 | 244 | ||
207 | static const char *wcn36xx_get_cap_name(enum place_holder_in_cap_bitmap x) | 245 | static const char *wcn36xx_get_cap_name(enum place_holder_in_cap_bitmap x) |
@@ -287,6 +325,7 @@ static int wcn36xx_start(struct ieee80211_hw *hw) | |||
287 | } | 325 | } |
288 | 326 | ||
289 | wcn36xx_detect_chip_version(wcn); | 327 | wcn36xx_detect_chip_version(wcn); |
328 | wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_ENABLE_MC_ADDR_LIST, 1); | ||
290 | 329 | ||
291 | /* DMA channel initialization */ | 330 | /* DMA channel initialization */ |
292 | ret = wcn36xx_dxe_init(wcn); | 331 | ret = wcn36xx_dxe_init(wcn); |
@@ -346,9 +385,7 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) | |||
346 | wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n", | 385 | wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n", |
347 | ch); | 386 | ch); |
348 | list_for_each_entry(tmp, &wcn->vif_list, list) { | 387 | list_for_each_entry(tmp, &wcn->vif_list, list) { |
349 | vif = container_of((void *)tmp, | 388 | vif = wcn36xx_priv_to_vif(tmp); |
350 | struct ieee80211_vif, | ||
351 | drv_priv); | ||
352 | wcn36xx_smd_switch_channel(wcn, vif, ch); | 389 | wcn36xx_smd_switch_channel(wcn, vif, ch); |
353 | } | 390 | } |
354 | } | 391 | } |
@@ -356,15 +393,57 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) | |||
356 | return 0; | 393 | return 0; |
357 | } | 394 | } |
358 | 395 | ||
359 | #define WCN36XX_SUPPORTED_FILTERS (0) | ||
360 | |||
361 | static void wcn36xx_configure_filter(struct ieee80211_hw *hw, | 396 | static void wcn36xx_configure_filter(struct ieee80211_hw *hw, |
362 | unsigned int changed, | 397 | unsigned int changed, |
363 | unsigned int *total, u64 multicast) | 398 | unsigned int *total, u64 multicast) |
364 | { | 399 | { |
400 | struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp; | ||
401 | struct wcn36xx *wcn = hw->priv; | ||
402 | struct wcn36xx_vif *tmp; | ||
403 | struct ieee80211_vif *vif = NULL; | ||
404 | |||
365 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n"); | 405 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n"); |
366 | 406 | ||
367 | *total &= WCN36XX_SUPPORTED_FILTERS; | 407 | *total &= FIF_ALLMULTI; |
408 | |||
409 | fp = (void *)(unsigned long)multicast; | ||
410 | list_for_each_entry(tmp, &wcn->vif_list, list) { | ||
411 | vif = wcn36xx_priv_to_vif(tmp); | ||
412 | |||
413 | /* FW handles MC filtering only when connected as STA */ | ||
414 | if (*total & FIF_ALLMULTI) | ||
415 | wcn36xx_smd_set_mc_list(wcn, vif, NULL); | ||
416 | else if (NL80211_IFTYPE_STATION == vif->type && tmp->sta_assoc) | ||
417 | wcn36xx_smd_set_mc_list(wcn, vif, fp); | ||
418 | } | ||
419 | kfree(fp); | ||
420 | } | ||
421 | |||
422 | static u64 wcn36xx_prepare_multicast(struct ieee80211_hw *hw, | ||
423 | struct netdev_hw_addr_list *mc_list) | ||
424 | { | ||
425 | struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp; | ||
426 | struct netdev_hw_addr *ha; | ||
427 | |||
428 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac prepare multicast list\n"); | ||
429 | fp = kzalloc(sizeof(*fp), GFP_ATOMIC); | ||
430 | if (!fp) { | ||
431 | wcn36xx_err("Out of memory setting filters.\n"); | ||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | fp->mc_addr_count = 0; | ||
436 | /* update multicast filtering parameters */ | ||
437 | if (netdev_hw_addr_list_count(mc_list) <= | ||
438 | WCN36XX_HAL_MAX_NUM_MULTICAST_ADDRESS) { | ||
439 | netdev_hw_addr_list_for_each(ha, mc_list) { | ||
440 | memcpy(fp->mc_addr[fp->mc_addr_count], | ||
441 | ha->addr, ETH_ALEN); | ||
442 | fp->mc_addr_count++; | ||
443 | } | ||
444 | } | ||
445 | |||
446 | return (u64)(unsigned long)fp; | ||
368 | } | 447 | } |
369 | 448 | ||
370 | static void wcn36xx_tx(struct ieee80211_hw *hw, | 449 | static void wcn36xx_tx(struct ieee80211_hw *hw, |
@@ -375,7 +454,7 @@ static void wcn36xx_tx(struct ieee80211_hw *hw, | |||
375 | struct wcn36xx_sta *sta_priv = NULL; | 454 | struct wcn36xx_sta *sta_priv = NULL; |
376 | 455 | ||
377 | if (control->sta) | 456 | if (control->sta) |
378 | sta_priv = (struct wcn36xx_sta *)control->sta->drv_priv; | 457 | sta_priv = wcn36xx_sta_to_priv(control->sta); |
379 | 458 | ||
380 | if (wcn36xx_start_tx(wcn, sta_priv, skb)) | 459 | if (wcn36xx_start_tx(wcn, sta_priv, skb)) |
381 | ieee80211_free_txskb(wcn->hw, skb); | 460 | ieee80211_free_txskb(wcn->hw, skb); |
@@ -387,8 +466,8 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
387 | struct ieee80211_key_conf *key_conf) | 466 | struct ieee80211_key_conf *key_conf) |
388 | { | 467 | { |
389 | struct wcn36xx *wcn = hw->priv; | 468 | struct wcn36xx *wcn = hw->priv; |
390 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 469 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
391 | struct wcn36xx_sta *sta_priv = vif_priv->sta; | 470 | struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); |
392 | int ret = 0; | 471 | int ret = 0; |
393 | u8 key[WLAN_MAX_KEY_LEN]; | 472 | u8 key[WLAN_MAX_KEY_LEN]; |
394 | 473 | ||
@@ -473,6 +552,7 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
473 | break; | 552 | break; |
474 | case DISABLE_KEY: | 553 | case DISABLE_KEY: |
475 | if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) { | 554 | if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) { |
555 | vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE; | ||
476 | wcn36xx_smd_remove_bsskey(wcn, | 556 | wcn36xx_smd_remove_bsskey(wcn, |
477 | vif_priv->encrypt_type, | 557 | vif_priv->encrypt_type, |
478 | key_conf->keyidx); | 558 | key_conf->keyidx); |
@@ -520,7 +600,7 @@ static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta, | |||
520 | { | 600 | { |
521 | int i, size; | 601 | int i, size; |
522 | u16 *rates_table; | 602 | u16 *rates_table; |
523 | struct wcn36xx_sta *sta_priv = (struct wcn36xx_sta *)sta->drv_priv; | 603 | struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); |
524 | u32 rates = sta->supp_rates[band]; | 604 | u32 rates = sta->supp_rates[band]; |
525 | 605 | ||
526 | memset(&sta_priv->supported_rates, 0, | 606 | memset(&sta_priv->supported_rates, 0, |
@@ -590,7 +670,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, | |||
590 | struct sk_buff *skb = NULL; | 670 | struct sk_buff *skb = NULL; |
591 | u16 tim_off, tim_len; | 671 | u16 tim_off, tim_len; |
592 | enum wcn36xx_hal_link_state link_state; | 672 | enum wcn36xx_hal_link_state link_state; |
593 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 673 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
594 | 674 | ||
595 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x\n", | 675 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x\n", |
596 | vif, changed); | 676 | vif, changed); |
@@ -620,7 +700,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, | |||
620 | 700 | ||
621 | if (!is_zero_ether_addr(bss_conf->bssid)) { | 701 | if (!is_zero_ether_addr(bss_conf->bssid)) { |
622 | vif_priv->is_joining = true; | 702 | vif_priv->is_joining = true; |
623 | vif_priv->bss_index = 0xff; | 703 | vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX; |
624 | wcn36xx_smd_join(wcn, bss_conf->bssid, | 704 | wcn36xx_smd_join(wcn, bss_conf->bssid, |
625 | vif->addr, WCN36XX_HW_CHANNEL(wcn)); | 705 | vif->addr, WCN36XX_HW_CHANNEL(wcn)); |
626 | wcn36xx_smd_config_bss(wcn, vif, NULL, | 706 | wcn36xx_smd_config_bss(wcn, vif, NULL, |
@@ -628,6 +708,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, | |||
628 | } else { | 708 | } else { |
629 | vif_priv->is_joining = false; | 709 | vif_priv->is_joining = false; |
630 | wcn36xx_smd_delete_bss(wcn, vif); | 710 | wcn36xx_smd_delete_bss(wcn, vif); |
711 | vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE; | ||
631 | } | 712 | } |
632 | } | 713 | } |
633 | 714 | ||
@@ -655,6 +736,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, | |||
655 | vif->addr, | 736 | vif->addr, |
656 | bss_conf->aid); | 737 | bss_conf->aid); |
657 | 738 | ||
739 | vif_priv->sta_assoc = true; | ||
658 | rcu_read_lock(); | 740 | rcu_read_lock(); |
659 | sta = ieee80211_find_sta(vif, bss_conf->bssid); | 741 | sta = ieee80211_find_sta(vif, bss_conf->bssid); |
660 | if (!sta) { | 742 | if (!sta) { |
@@ -663,7 +745,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, | |||
663 | rcu_read_unlock(); | 745 | rcu_read_unlock(); |
664 | goto out; | 746 | goto out; |
665 | } | 747 | } |
666 | sta_priv = (struct wcn36xx_sta *)sta->drv_priv; | 748 | sta_priv = wcn36xx_sta_to_priv(sta); |
667 | 749 | ||
668 | wcn36xx_update_allowed_rates(sta, WCN36XX_BAND(wcn)); | 750 | wcn36xx_update_allowed_rates(sta, WCN36XX_BAND(wcn)); |
669 | 751 | ||
@@ -686,6 +768,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, | |||
686 | bss_conf->bssid, | 768 | bss_conf->bssid, |
687 | vif->addr, | 769 | vif->addr, |
688 | bss_conf->aid); | 770 | bss_conf->aid); |
771 | vif_priv->sta_assoc = false; | ||
689 | wcn36xx_smd_set_link_st(wcn, | 772 | wcn36xx_smd_set_link_st(wcn, |
690 | bss_conf->bssid, | 773 | bss_conf->bssid, |
691 | vif->addr, | 774 | vif->addr, |
@@ -713,7 +796,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, | |||
713 | 796 | ||
714 | if (bss_conf->enable_beacon) { | 797 | if (bss_conf->enable_beacon) { |
715 | vif_priv->dtim_period = bss_conf->dtim_period; | 798 | vif_priv->dtim_period = bss_conf->dtim_period; |
716 | vif_priv->bss_index = 0xff; | 799 | vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX; |
717 | wcn36xx_smd_config_bss(wcn, vif, NULL, | 800 | wcn36xx_smd_config_bss(wcn, vif, NULL, |
718 | vif->addr, false); | 801 | vif->addr, false); |
719 | skb = ieee80211_beacon_get_tim(hw, vif, &tim_off, | 802 | skb = ieee80211_beacon_get_tim(hw, vif, &tim_off, |
@@ -734,9 +817,9 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, | |||
734 | wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr, | 817 | wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr, |
735 | link_state); | 818 | link_state); |
736 | } else { | 819 | } else { |
820 | wcn36xx_smd_delete_bss(wcn, vif); | ||
737 | wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr, | 821 | wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr, |
738 | WCN36XX_HAL_LINK_IDLE_STATE); | 822 | WCN36XX_HAL_LINK_IDLE_STATE); |
739 | wcn36xx_smd_delete_bss(wcn, vif); | ||
740 | } | 823 | } |
741 | } | 824 | } |
742 | out: | 825 | out: |
@@ -757,7 +840,7 @@ static void wcn36xx_remove_interface(struct ieee80211_hw *hw, | |||
757 | struct ieee80211_vif *vif) | 840 | struct ieee80211_vif *vif) |
758 | { | 841 | { |
759 | struct wcn36xx *wcn = hw->priv; | 842 | struct wcn36xx *wcn = hw->priv; |
760 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 843 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
761 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif); | 844 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif); |
762 | 845 | ||
763 | list_del(&vif_priv->list); | 846 | list_del(&vif_priv->list); |
@@ -768,7 +851,7 @@ static int wcn36xx_add_interface(struct ieee80211_hw *hw, | |||
768 | struct ieee80211_vif *vif) | 851 | struct ieee80211_vif *vif) |
769 | { | 852 | { |
770 | struct wcn36xx *wcn = hw->priv; | 853 | struct wcn36xx *wcn = hw->priv; |
771 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 854 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
772 | 855 | ||
773 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac add interface vif %p type %d\n", | 856 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac add interface vif %p type %d\n", |
774 | vif, vif->type); | 857 | vif, vif->type); |
@@ -792,13 +875,12 @@ static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
792 | struct ieee80211_sta *sta) | 875 | struct ieee80211_sta *sta) |
793 | { | 876 | { |
794 | struct wcn36xx *wcn = hw->priv; | 877 | struct wcn36xx *wcn = hw->priv; |
795 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 878 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
796 | struct wcn36xx_sta *sta_priv = (struct wcn36xx_sta *)sta->drv_priv; | 879 | struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); |
797 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n", | 880 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n", |
798 | vif, sta->addr); | 881 | vif, sta->addr); |
799 | 882 | ||
800 | spin_lock_init(&sta_priv->ampdu_lock); | 883 | spin_lock_init(&sta_priv->ampdu_lock); |
801 | vif_priv->sta = sta_priv; | ||
802 | sta_priv->vif = vif_priv; | 884 | sta_priv->vif = vif_priv; |
803 | /* | 885 | /* |
804 | * For STA mode HW will be configured on BSS_CHANGED_ASSOC because | 886 | * For STA mode HW will be configured on BSS_CHANGED_ASSOC because |
@@ -817,14 +899,12 @@ static int wcn36xx_sta_remove(struct ieee80211_hw *hw, | |||
817 | struct ieee80211_sta *sta) | 899 | struct ieee80211_sta *sta) |
818 | { | 900 | { |
819 | struct wcn36xx *wcn = hw->priv; | 901 | struct wcn36xx *wcn = hw->priv; |
820 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 902 | struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); |
821 | struct wcn36xx_sta *sta_priv = (struct wcn36xx_sta *)sta->drv_priv; | ||
822 | 903 | ||
823 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n", | 904 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n", |
824 | vif, sta->addr, sta_priv->sta_index); | 905 | vif, sta->addr, sta_priv->sta_index); |
825 | 906 | ||
826 | wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index); | 907 | wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index); |
827 | vif_priv->sta = NULL; | ||
828 | sta_priv->vif = NULL; | 908 | sta_priv->vif = NULL; |
829 | return 0; | 909 | return 0; |
830 | } | 910 | } |
@@ -860,7 +940,7 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw, | |||
860 | struct ieee80211_ampdu_params *params) | 940 | struct ieee80211_ampdu_params *params) |
861 | { | 941 | { |
862 | struct wcn36xx *wcn = hw->priv; | 942 | struct wcn36xx *wcn = hw->priv; |
863 | struct wcn36xx_sta *sta_priv = NULL; | 943 | struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(params->sta); |
864 | struct ieee80211_sta *sta = params->sta; | 944 | struct ieee80211_sta *sta = params->sta; |
865 | enum ieee80211_ampdu_mlme_action action = params->action; | 945 | enum ieee80211_ampdu_mlme_action action = params->action; |
866 | u16 tid = params->tid; | 946 | u16 tid = params->tid; |
@@ -869,8 +949,6 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw, | |||
869 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n", | 949 | wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n", |
870 | action, tid); | 950 | action, tid); |
871 | 951 | ||
872 | sta_priv = (struct wcn36xx_sta *)sta->drv_priv; | ||
873 | |||
874 | switch (action) { | 952 | switch (action) { |
875 | case IEEE80211_AMPDU_RX_START: | 953 | case IEEE80211_AMPDU_RX_START: |
876 | sta_priv->tid = tid; | 954 | sta_priv->tid = tid; |
@@ -923,6 +1001,7 @@ static const struct ieee80211_ops wcn36xx_ops = { | |||
923 | .resume = wcn36xx_resume, | 1001 | .resume = wcn36xx_resume, |
924 | #endif | 1002 | #endif |
925 | .config = wcn36xx_config, | 1003 | .config = wcn36xx_config, |
1004 | .prepare_multicast = wcn36xx_prepare_multicast, | ||
926 | .configure_filter = wcn36xx_configure_filter, | 1005 | .configure_filter = wcn36xx_configure_filter, |
927 | .tx = wcn36xx_tx, | 1006 | .tx = wcn36xx_tx, |
928 | .set_key = wcn36xx_set_key, | 1007 | .set_key = wcn36xx_set_key, |
diff --git a/drivers/net/wireless/ath/wcn36xx/pmc.c b/drivers/net/wireless/ath/wcn36xx/pmc.c index 28b515c81b0e..589fe5f70971 100644 --- a/drivers/net/wireless/ath/wcn36xx/pmc.c +++ b/drivers/net/wireless/ath/wcn36xx/pmc.c | |||
@@ -22,7 +22,7 @@ int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, | |||
22 | struct ieee80211_vif *vif) | 22 | struct ieee80211_vif *vif) |
23 | { | 23 | { |
24 | int ret = 0; | 24 | int ret = 0; |
25 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 25 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
26 | /* TODO: Make sure the TX chain clean */ | 26 | /* TODO: Make sure the TX chain clean */ |
27 | ret = wcn36xx_smd_enter_bmps(wcn, vif); | 27 | ret = wcn36xx_smd_enter_bmps(wcn, vif); |
28 | if (!ret) { | 28 | if (!ret) { |
@@ -42,7 +42,7 @@ int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, | |||
42 | int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn, | 42 | int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn, |
43 | struct ieee80211_vif *vif) | 43 | struct ieee80211_vif *vif) |
44 | { | 44 | { |
45 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 45 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
46 | 46 | ||
47 | if (WCN36XX_BMPS != vif_priv->pw_state) { | 47 | if (WCN36XX_BMPS != vif_priv->pw_state) { |
48 | wcn36xx_err("Not in BMPS mode, no need to exit from BMPS mode!\n"); | 48 | wcn36xx_err("Not in BMPS mode, no need to exit from BMPS mode!\n"); |
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 96992a2c4b42..e8b630c4f11e 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c | |||
@@ -191,16 +191,16 @@ static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn, | |||
191 | struct ieee80211_sta *sta, | 191 | struct ieee80211_sta *sta, |
192 | struct wcn36xx_hal_config_sta_params *sta_params) | 192 | struct wcn36xx_hal_config_sta_params *sta_params) |
193 | { | 193 | { |
194 | struct wcn36xx_vif *priv_vif = (struct wcn36xx_vif *)vif->drv_priv; | 194 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
195 | struct wcn36xx_sta *priv_sta = NULL; | 195 | struct wcn36xx_sta *sta_priv = NULL; |
196 | if (vif->type == NL80211_IFTYPE_ADHOC || | 196 | if (vif->type == NL80211_IFTYPE_ADHOC || |
197 | vif->type == NL80211_IFTYPE_AP || | 197 | vif->type == NL80211_IFTYPE_AP || |
198 | vif->type == NL80211_IFTYPE_MESH_POINT) { | 198 | vif->type == NL80211_IFTYPE_MESH_POINT) { |
199 | sta_params->type = 1; | 199 | sta_params->type = 1; |
200 | sta_params->sta_index = 0xFF; | 200 | sta_params->sta_index = WCN36XX_HAL_STA_INVALID_IDX; |
201 | } else { | 201 | } else { |
202 | sta_params->type = 0; | 202 | sta_params->type = 0; |
203 | sta_params->sta_index = 1; | 203 | sta_params->sta_index = vif_priv->self_sta_index; |
204 | } | 204 | } |
205 | 205 | ||
206 | sta_params->listen_interval = WCN36XX_LISTEN_INTERVAL(wcn); | 206 | sta_params->listen_interval = WCN36XX_LISTEN_INTERVAL(wcn); |
@@ -215,7 +215,7 @@ static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn, | |||
215 | else | 215 | else |
216 | memcpy(&sta_params->bssid, vif->addr, ETH_ALEN); | 216 | memcpy(&sta_params->bssid, vif->addr, ETH_ALEN); |
217 | 217 | ||
218 | sta_params->encrypt_type = priv_vif->encrypt_type; | 218 | sta_params->encrypt_type = vif_priv->encrypt_type; |
219 | sta_params->short_preamble_supported = true; | 219 | sta_params->short_preamble_supported = true; |
220 | 220 | ||
221 | sta_params->rifs_mode = 0; | 221 | sta_params->rifs_mode = 0; |
@@ -224,21 +224,21 @@ static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn, | |||
224 | sta_params->uapsd = 0; | 224 | sta_params->uapsd = 0; |
225 | sta_params->mimo_ps = WCN36XX_HAL_HT_MIMO_PS_STATIC; | 225 | sta_params->mimo_ps = WCN36XX_HAL_HT_MIMO_PS_STATIC; |
226 | sta_params->max_ampdu_duration = 0; | 226 | sta_params->max_ampdu_duration = 0; |
227 | sta_params->bssid_index = priv_vif->bss_index; | 227 | sta_params->bssid_index = vif_priv->bss_index; |
228 | sta_params->p2p = 0; | 228 | sta_params->p2p = 0; |
229 | 229 | ||
230 | if (sta) { | 230 | if (sta) { |
231 | priv_sta = (struct wcn36xx_sta *)sta->drv_priv; | 231 | sta_priv = wcn36xx_sta_to_priv(sta); |
232 | if (NL80211_IFTYPE_STATION == vif->type) | 232 | if (NL80211_IFTYPE_STATION == vif->type) |
233 | memcpy(&sta_params->bssid, sta->addr, ETH_ALEN); | 233 | memcpy(&sta_params->bssid, sta->addr, ETH_ALEN); |
234 | else | 234 | else |
235 | memcpy(&sta_params->mac, sta->addr, ETH_ALEN); | 235 | memcpy(&sta_params->mac, sta->addr, ETH_ALEN); |
236 | sta_params->wmm_enabled = sta->wme; | 236 | sta_params->wmm_enabled = sta->wme; |
237 | sta_params->max_sp_len = sta->max_sp; | 237 | sta_params->max_sp_len = sta->max_sp; |
238 | sta_params->aid = priv_sta->aid; | 238 | sta_params->aid = sta_priv->aid; |
239 | wcn36xx_smd_set_sta_ht_params(sta, sta_params); | 239 | wcn36xx_smd_set_sta_ht_params(sta, sta_params); |
240 | memcpy(&sta_params->supported_rates, &priv_sta->supported_rates, | 240 | memcpy(&sta_params->supported_rates, &sta_priv->supported_rates, |
241 | sizeof(priv_sta->supported_rates)); | 241 | sizeof(sta_priv->supported_rates)); |
242 | } else { | 242 | } else { |
243 | wcn36xx_set_default_rates(&sta_params->supported_rates); | 243 | wcn36xx_set_default_rates(&sta_params->supported_rates); |
244 | wcn36xx_smd_set_sta_default_ht_params(sta_params); | 244 | wcn36xx_smd_set_sta_default_ht_params(sta_params); |
@@ -271,6 +271,16 @@ out: | |||
271 | return ret; | 271 | return ret; |
272 | } | 272 | } |
273 | 273 | ||
274 | static void init_hal_msg(struct wcn36xx_hal_msg_header *hdr, | ||
275 | enum wcn36xx_hal_host_msg_type msg_type, | ||
276 | size_t msg_size) | ||
277 | { | ||
278 | memset(hdr, 0, msg_size + sizeof(*hdr)); | ||
279 | hdr->msg_type = msg_type; | ||
280 | hdr->msg_version = WCN36XX_HAL_MSG_VERSION0; | ||
281 | hdr->len = msg_size + sizeof(*hdr); | ||
282 | } | ||
283 | |||
274 | #define INIT_HAL_MSG(msg_body, type) \ | 284 | #define INIT_HAL_MSG(msg_body, type) \ |
275 | do { \ | 285 | do { \ |
276 | memset(&msg_body, 0, sizeof(msg_body)); \ | 286 | memset(&msg_body, 0, sizeof(msg_body)); \ |
@@ -302,22 +312,6 @@ static int wcn36xx_smd_rsp_status_check(void *buf, size_t len) | |||
302 | return 0; | 312 | return 0; |
303 | } | 313 | } |
304 | 314 | ||
305 | static int wcn36xx_smd_rsp_status_check_v2(struct wcn36xx *wcn, void *buf, | ||
306 | size_t len) | ||
307 | { | ||
308 | struct wcn36xx_fw_msg_status_rsp_v2 *rsp; | ||
309 | |||
310 | if (len < sizeof(struct wcn36xx_hal_msg_header) + sizeof(*rsp)) | ||
311 | return wcn36xx_smd_rsp_status_check(buf, len); | ||
312 | |||
313 | rsp = buf + sizeof(struct wcn36xx_hal_msg_header); | ||
314 | |||
315 | if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->status) | ||
316 | return rsp->status; | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | int wcn36xx_smd_load_nv(struct wcn36xx *wcn) | 315 | int wcn36xx_smd_load_nv(struct wcn36xx *wcn) |
322 | { | 316 | { |
323 | struct nv_data *nv_d; | 317 | struct nv_data *nv_d; |
@@ -726,7 +720,7 @@ static int wcn36xx_smd_add_sta_self_rsp(struct wcn36xx *wcn, | |||
726 | size_t len) | 720 | size_t len) |
727 | { | 721 | { |
728 | struct wcn36xx_hal_add_sta_self_rsp_msg *rsp; | 722 | struct wcn36xx_hal_add_sta_self_rsp_msg *rsp; |
729 | struct wcn36xx_vif *priv_vif = (struct wcn36xx_vif *)vif->drv_priv; | 723 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
730 | 724 | ||
731 | if (len < sizeof(*rsp)) | 725 | if (len < sizeof(*rsp)) |
732 | return -EINVAL; | 726 | return -EINVAL; |
@@ -743,8 +737,8 @@ static int wcn36xx_smd_add_sta_self_rsp(struct wcn36xx *wcn, | |||
743 | "hal add sta self status %d self_sta_index %d dpu_index %d\n", | 737 | "hal add sta self status %d self_sta_index %d dpu_index %d\n", |
744 | rsp->status, rsp->self_sta_index, rsp->dpu_index); | 738 | rsp->status, rsp->self_sta_index, rsp->dpu_index); |
745 | 739 | ||
746 | priv_vif->self_sta_index = rsp->self_sta_index; | 740 | vif_priv->self_sta_index = rsp->self_sta_index; |
747 | priv_vif->self_dpu_desc_index = rsp->dpu_index; | 741 | vif_priv->self_dpu_desc_index = rsp->dpu_index; |
748 | 742 | ||
749 | return 0; | 743 | return 0; |
750 | } | 744 | } |
@@ -949,17 +943,32 @@ static void wcn36xx_smd_convert_sta_to_v1(struct wcn36xx *wcn, | |||
949 | memcpy(&v1->mac, orig->mac, ETH_ALEN); | 943 | memcpy(&v1->mac, orig->mac, ETH_ALEN); |
950 | v1->aid = orig->aid; | 944 | v1->aid = orig->aid; |
951 | v1->type = orig->type; | 945 | v1->type = orig->type; |
946 | v1->short_preamble_supported = orig->short_preamble_supported; | ||
952 | v1->listen_interval = orig->listen_interval; | 947 | v1->listen_interval = orig->listen_interval; |
948 | v1->wmm_enabled = orig->wmm_enabled; | ||
953 | v1->ht_capable = orig->ht_capable; | 949 | v1->ht_capable = orig->ht_capable; |
954 | 950 | v1->tx_channel_width_set = orig->tx_channel_width_set; | |
951 | v1->rifs_mode = orig->rifs_mode; | ||
952 | v1->lsig_txop_protection = orig->lsig_txop_protection; | ||
955 | v1->max_ampdu_size = orig->max_ampdu_size; | 953 | v1->max_ampdu_size = orig->max_ampdu_size; |
956 | v1->max_ampdu_density = orig->max_ampdu_density; | 954 | v1->max_ampdu_density = orig->max_ampdu_density; |
957 | v1->sgi_40mhz = orig->sgi_40mhz; | 955 | v1->sgi_40mhz = orig->sgi_40mhz; |
958 | v1->sgi_20Mhz = orig->sgi_20Mhz; | 956 | v1->sgi_20Mhz = orig->sgi_20Mhz; |
959 | 957 | v1->rmf = orig->rmf; | |
958 | v1->encrypt_type = orig->encrypt_type; | ||
959 | v1->action = orig->action; | ||
960 | v1->uapsd = orig->uapsd; | ||
961 | v1->max_sp_len = orig->max_sp_len; | ||
962 | v1->green_field_capable = orig->green_field_capable; | ||
963 | v1->mimo_ps = orig->mimo_ps; | ||
964 | v1->delayed_ba_support = orig->delayed_ba_support; | ||
965 | v1->max_ampdu_duration = orig->max_ampdu_duration; | ||
966 | v1->dsss_cck_mode_40mhz = orig->dsss_cck_mode_40mhz; | ||
960 | memcpy(&v1->supported_rates, &orig->supported_rates, | 967 | memcpy(&v1->supported_rates, &orig->supported_rates, |
961 | sizeof(orig->supported_rates)); | 968 | sizeof(orig->supported_rates)); |
962 | v1->sta_index = orig->sta_index; | 969 | v1->sta_index = orig->sta_index; |
970 | v1->bssid_index = orig->bssid_index; | ||
971 | v1->p2p = orig->p2p; | ||
963 | } | 972 | } |
964 | 973 | ||
965 | static int wcn36xx_smd_config_sta_rsp(struct wcn36xx *wcn, | 974 | static int wcn36xx_smd_config_sta_rsp(struct wcn36xx *wcn, |
@@ -969,7 +978,7 @@ static int wcn36xx_smd_config_sta_rsp(struct wcn36xx *wcn, | |||
969 | { | 978 | { |
970 | struct wcn36xx_hal_config_sta_rsp_msg *rsp; | 979 | struct wcn36xx_hal_config_sta_rsp_msg *rsp; |
971 | struct config_sta_rsp_params *params; | 980 | struct config_sta_rsp_params *params; |
972 | struct wcn36xx_sta *sta_priv = (struct wcn36xx_sta *)sta->drv_priv; | 981 | struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); |
973 | 982 | ||
974 | if (len < sizeof(*rsp)) | 983 | if (len < sizeof(*rsp)) |
975 | return -EINVAL; | 984 | return -EINVAL; |
@@ -1170,12 +1179,13 @@ static int wcn36xx_smd_config_bss_v1(struct wcn36xx *wcn, | |||
1170 | 1179 | ||
1171 | static int wcn36xx_smd_config_bss_rsp(struct wcn36xx *wcn, | 1180 | static int wcn36xx_smd_config_bss_rsp(struct wcn36xx *wcn, |
1172 | struct ieee80211_vif *vif, | 1181 | struct ieee80211_vif *vif, |
1182 | struct ieee80211_sta *sta, | ||
1173 | void *buf, | 1183 | void *buf, |
1174 | size_t len) | 1184 | size_t len) |
1175 | { | 1185 | { |
1176 | struct wcn36xx_hal_config_bss_rsp_msg *rsp; | 1186 | struct wcn36xx_hal_config_bss_rsp_msg *rsp; |
1177 | struct wcn36xx_hal_config_bss_rsp_params *params; | 1187 | struct wcn36xx_hal_config_bss_rsp_params *params; |
1178 | struct wcn36xx_vif *priv_vif = (struct wcn36xx_vif *)vif->drv_priv; | 1188 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
1179 | 1189 | ||
1180 | if (len < sizeof(*rsp)) | 1190 | if (len < sizeof(*rsp)) |
1181 | return -EINVAL; | 1191 | return -EINVAL; |
@@ -1198,14 +1208,15 @@ static int wcn36xx_smd_config_bss_rsp(struct wcn36xx *wcn, | |||
1198 | params->bss_bcast_sta_idx, params->mac, | 1208 | params->bss_bcast_sta_idx, params->mac, |
1199 | params->tx_mgmt_power, params->ucast_dpu_signature); | 1209 | params->tx_mgmt_power, params->ucast_dpu_signature); |
1200 | 1210 | ||
1201 | priv_vif->bss_index = params->bss_index; | 1211 | vif_priv->bss_index = params->bss_index; |
1202 | 1212 | ||
1203 | if (priv_vif->sta) { | 1213 | if (sta) { |
1204 | priv_vif->sta->bss_sta_index = params->bss_sta_index; | 1214 | struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta); |
1205 | priv_vif->sta->bss_dpu_desc_index = params->dpu_desc_index; | 1215 | sta_priv->bss_sta_index = params->bss_sta_index; |
1216 | sta_priv->bss_dpu_desc_index = params->dpu_desc_index; | ||
1206 | } | 1217 | } |
1207 | 1218 | ||
1208 | priv_vif->self_ucast_dpu_sign = params->ucast_dpu_signature; | 1219 | vif_priv->self_ucast_dpu_sign = params->ucast_dpu_signature; |
1209 | 1220 | ||
1210 | return 0; | 1221 | return 0; |
1211 | } | 1222 | } |
@@ -1217,7 +1228,7 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif, | |||
1217 | struct wcn36xx_hal_config_bss_req_msg msg; | 1228 | struct wcn36xx_hal_config_bss_req_msg msg; |
1218 | struct wcn36xx_hal_config_bss_params *bss; | 1229 | struct wcn36xx_hal_config_bss_params *bss; |
1219 | struct wcn36xx_hal_config_sta_params *sta_params; | 1230 | struct wcn36xx_hal_config_sta_params *sta_params; |
1220 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 1231 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
1221 | int ret = 0; | 1232 | int ret = 0; |
1222 | 1233 | ||
1223 | mutex_lock(&wcn->hal_mutex); | 1234 | mutex_lock(&wcn->hal_mutex); |
@@ -1329,6 +1340,7 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif, | |||
1329 | } | 1340 | } |
1330 | ret = wcn36xx_smd_config_bss_rsp(wcn, | 1341 | ret = wcn36xx_smd_config_bss_rsp(wcn, |
1331 | vif, | 1342 | vif, |
1343 | sta, | ||
1332 | wcn->hal_buf, | 1344 | wcn->hal_buf, |
1333 | wcn->hal_rsp_len); | 1345 | wcn->hal_rsp_len); |
1334 | if (ret) { | 1346 | if (ret) { |
@@ -1343,13 +1355,13 @@ out: | |||
1343 | int wcn36xx_smd_delete_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif) | 1355 | int wcn36xx_smd_delete_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif) |
1344 | { | 1356 | { |
1345 | struct wcn36xx_hal_delete_bss_req_msg msg_body; | 1357 | struct wcn36xx_hal_delete_bss_req_msg msg_body; |
1346 | struct wcn36xx_vif *priv_vif = (struct wcn36xx_vif *)vif->drv_priv; | 1358 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
1347 | int ret = 0; | 1359 | int ret = 0; |
1348 | 1360 | ||
1349 | mutex_lock(&wcn->hal_mutex); | 1361 | mutex_lock(&wcn->hal_mutex); |
1350 | INIT_HAL_MSG(msg_body, WCN36XX_HAL_DELETE_BSS_REQ); | 1362 | INIT_HAL_MSG(msg_body, WCN36XX_HAL_DELETE_BSS_REQ); |
1351 | 1363 | ||
1352 | msg_body.bss_index = priv_vif->bss_index; | 1364 | msg_body.bss_index = vif_priv->bss_index; |
1353 | 1365 | ||
1354 | PREPARE_HAL_BUF(wcn->hal_buf, msg_body); | 1366 | PREPARE_HAL_BUF(wcn->hal_buf, msg_body); |
1355 | 1367 | ||
@@ -1375,26 +1387,47 @@ int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct ieee80211_vif *vif, | |||
1375 | u16 p2p_off) | 1387 | u16 p2p_off) |
1376 | { | 1388 | { |
1377 | struct wcn36xx_hal_send_beacon_req_msg msg_body; | 1389 | struct wcn36xx_hal_send_beacon_req_msg msg_body; |
1378 | int ret = 0; | 1390 | int ret = 0, pad, pvm_len; |
1379 | 1391 | ||
1380 | mutex_lock(&wcn->hal_mutex); | 1392 | mutex_lock(&wcn->hal_mutex); |
1381 | INIT_HAL_MSG(msg_body, WCN36XX_HAL_SEND_BEACON_REQ); | 1393 | INIT_HAL_MSG(msg_body, WCN36XX_HAL_SEND_BEACON_REQ); |
1382 | 1394 | ||
1383 | /* TODO need to find out why this is needed? */ | 1395 | pvm_len = skb_beacon->data[tim_off + 1] - 3; |
1384 | msg_body.beacon_length = skb_beacon->len + 6; | 1396 | pad = TIM_MIN_PVM_SIZE - pvm_len; |
1385 | 1397 | ||
1386 | if (BEACON_TEMPLATE_SIZE > msg_body.beacon_length) { | 1398 | /* Padding is irrelevant to mesh mode since tim_off is always 0. */ |
1387 | memcpy(&msg_body.beacon, &skb_beacon->len, sizeof(u32)); | 1399 | if (vif->type == NL80211_IFTYPE_MESH_POINT) |
1388 | memcpy(&(msg_body.beacon[4]), skb_beacon->data, | 1400 | pad = 0; |
1389 | skb_beacon->len); | 1401 | |
1390 | } else { | 1402 | msg_body.beacon_length = skb_beacon->len + pad; |
1403 | /* TODO need to find out why + 6 is needed */ | ||
1404 | msg_body.beacon_length6 = msg_body.beacon_length + 6; | ||
1405 | |||
1406 | if (msg_body.beacon_length > BEACON_TEMPLATE_SIZE) { | ||
1391 | wcn36xx_err("Beacon is to big: beacon size=%d\n", | 1407 | wcn36xx_err("Beacon is to big: beacon size=%d\n", |
1392 | msg_body.beacon_length); | 1408 | msg_body.beacon_length); |
1393 | ret = -ENOMEM; | 1409 | ret = -ENOMEM; |
1394 | goto out; | 1410 | goto out; |
1395 | } | 1411 | } |
1412 | memcpy(msg_body.beacon, skb_beacon->data, skb_beacon->len); | ||
1396 | memcpy(msg_body.bssid, vif->addr, ETH_ALEN); | 1413 | memcpy(msg_body.bssid, vif->addr, ETH_ALEN); |
1397 | 1414 | ||
1415 | if (pad > 0) { | ||
1416 | /* | ||
1417 | * The wcn36xx FW has a fixed size for the PVM in the TIM. If | ||
1418 | * given the beacon template from mac80211 with a PVM shorter | ||
1419 | * than the FW expectes it will overwrite the data after the | ||
1420 | * TIM. | ||
1421 | */ | ||
1422 | wcn36xx_dbg(WCN36XX_DBG_HAL, "Pad TIM PVM. %d bytes at %d\n", | ||
1423 | pad, pvm_len); | ||
1424 | memmove(&msg_body.beacon[tim_off + 5 + pvm_len + pad], | ||
1425 | &msg_body.beacon[tim_off + 5 + pvm_len], | ||
1426 | skb_beacon->len - (tim_off + 5 + pvm_len)); | ||
1427 | memset(&msg_body.beacon[tim_off + 5 + pvm_len], 0, pad); | ||
1428 | msg_body.beacon[tim_off + 1] += pad; | ||
1429 | } | ||
1430 | |||
1398 | /* TODO need to find out why this is needed? */ | 1431 | /* TODO need to find out why this is needed? */ |
1399 | if (vif->type == NL80211_IFTYPE_MESH_POINT) | 1432 | if (vif->type == NL80211_IFTYPE_MESH_POINT) |
1400 | /* mesh beacon don't need this, so push further down */ | 1433 | /* mesh beacon don't need this, so push further down */ |
@@ -1598,8 +1631,7 @@ int wcn36xx_smd_remove_bsskey(struct wcn36xx *wcn, | |||
1598 | wcn36xx_err("Sending hal_remove_bsskey failed\n"); | 1631 | wcn36xx_err("Sending hal_remove_bsskey failed\n"); |
1599 | goto out; | 1632 | goto out; |
1600 | } | 1633 | } |
1601 | ret = wcn36xx_smd_rsp_status_check_v2(wcn, wcn->hal_buf, | 1634 | ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); |
1602 | wcn->hal_rsp_len); | ||
1603 | if (ret) { | 1635 | if (ret) { |
1604 | wcn36xx_err("hal_remove_bsskey response failed err=%d\n", ret); | 1636 | wcn36xx_err("hal_remove_bsskey response failed err=%d\n", ret); |
1605 | goto out; | 1637 | goto out; |
@@ -1612,7 +1644,7 @@ out: | |||
1612 | int wcn36xx_smd_enter_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif) | 1644 | int wcn36xx_smd_enter_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif) |
1613 | { | 1645 | { |
1614 | struct wcn36xx_hal_enter_bmps_req_msg msg_body; | 1646 | struct wcn36xx_hal_enter_bmps_req_msg msg_body; |
1615 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 1647 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
1616 | int ret = 0; | 1648 | int ret = 0; |
1617 | 1649 | ||
1618 | mutex_lock(&wcn->hal_mutex); | 1650 | mutex_lock(&wcn->hal_mutex); |
@@ -1641,8 +1673,8 @@ out: | |||
1641 | 1673 | ||
1642 | int wcn36xx_smd_exit_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif) | 1674 | int wcn36xx_smd_exit_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif) |
1643 | { | 1675 | { |
1644 | struct wcn36xx_hal_enter_bmps_req_msg msg_body; | 1676 | struct wcn36xx_hal_exit_bmps_req_msg msg_body; |
1645 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 1677 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
1646 | int ret = 0; | 1678 | int ret = 0; |
1647 | 1679 | ||
1648 | mutex_lock(&wcn->hal_mutex); | 1680 | mutex_lock(&wcn->hal_mutex); |
@@ -1703,7 +1735,7 @@ int wcn36xx_smd_keep_alive_req(struct wcn36xx *wcn, | |||
1703 | int packet_type) | 1735 | int packet_type) |
1704 | { | 1736 | { |
1705 | struct wcn36xx_hal_keep_alive_req_msg msg_body; | 1737 | struct wcn36xx_hal_keep_alive_req_msg msg_body; |
1706 | struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; | 1738 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); |
1707 | int ret = 0; | 1739 | int ret = 0; |
1708 | 1740 | ||
1709 | mutex_lock(&wcn->hal_mutex); | 1741 | mutex_lock(&wcn->hal_mutex); |
@@ -1944,6 +1976,17 @@ out: | |||
1944 | return ret; | 1976 | return ret; |
1945 | } | 1977 | } |
1946 | 1978 | ||
1979 | static int wcn36xx_smd_trigger_ba_rsp(void *buf, int len) | ||
1980 | { | ||
1981 | struct wcn36xx_hal_trigger_ba_rsp_msg *rsp; | ||
1982 | |||
1983 | if (len < sizeof(*rsp)) | ||
1984 | return -EINVAL; | ||
1985 | |||
1986 | rsp = (struct wcn36xx_hal_trigger_ba_rsp_msg *) buf; | ||
1987 | return rsp->status; | ||
1988 | } | ||
1989 | |||
1947 | int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index) | 1990 | int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index) |
1948 | { | 1991 | { |
1949 | struct wcn36xx_hal_trigger_ba_req_msg msg_body; | 1992 | struct wcn36xx_hal_trigger_ba_req_msg msg_body; |
@@ -1968,8 +2011,7 @@ int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index) | |||
1968 | wcn36xx_err("Sending hal_trigger_ba failed\n"); | 2011 | wcn36xx_err("Sending hal_trigger_ba failed\n"); |
1969 | goto out; | 2012 | goto out; |
1970 | } | 2013 | } |
1971 | ret = wcn36xx_smd_rsp_status_check_v2(wcn, wcn->hal_buf, | 2014 | ret = wcn36xx_smd_trigger_ba_rsp(wcn->hal_buf, wcn->hal_rsp_len); |
1972 | wcn->hal_rsp_len); | ||
1973 | if (ret) { | 2015 | if (ret) { |
1974 | wcn36xx_err("hal_trigger_ba response failed err=%d\n", ret); | 2016 | wcn36xx_err("hal_trigger_ba response failed err=%d\n", ret); |
1975 | goto out; | 2017 | goto out; |
@@ -2006,9 +2048,7 @@ static int wcn36xx_smd_missed_beacon_ind(struct wcn36xx *wcn, | |||
2006 | list_for_each_entry(tmp, &wcn->vif_list, list) { | 2048 | list_for_each_entry(tmp, &wcn->vif_list, list) { |
2007 | wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n", | 2049 | wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n", |
2008 | tmp->bss_index); | 2050 | tmp->bss_index); |
2009 | vif = container_of((void *)tmp, | 2051 | vif = wcn36xx_priv_to_vif(tmp); |
2010 | struct ieee80211_vif, | ||
2011 | drv_priv); | ||
2012 | ieee80211_connection_loss(vif); | 2052 | ieee80211_connection_loss(vif); |
2013 | } | 2053 | } |
2014 | return 0; | 2054 | return 0; |
@@ -2023,9 +2063,7 @@ static int wcn36xx_smd_missed_beacon_ind(struct wcn36xx *wcn, | |||
2023 | if (tmp->bss_index == rsp->bss_index) { | 2063 | if (tmp->bss_index == rsp->bss_index) { |
2024 | wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n", | 2064 | wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n", |
2025 | rsp->bss_index); | 2065 | rsp->bss_index); |
2026 | vif = container_of((void *)tmp, | 2066 | vif = wcn36xx_priv_to_vif(tmp); |
2027 | struct ieee80211_vif, | ||
2028 | drv_priv); | ||
2029 | ieee80211_connection_loss(vif); | 2067 | ieee80211_connection_loss(vif); |
2030 | return 0; | 2068 | return 0; |
2031 | } | 2069 | } |
@@ -2041,25 +2079,24 @@ static int wcn36xx_smd_delete_sta_context_ind(struct wcn36xx *wcn, | |||
2041 | { | 2079 | { |
2042 | struct wcn36xx_hal_delete_sta_context_ind_msg *rsp = buf; | 2080 | struct wcn36xx_hal_delete_sta_context_ind_msg *rsp = buf; |
2043 | struct wcn36xx_vif *tmp; | 2081 | struct wcn36xx_vif *tmp; |
2044 | struct ieee80211_sta *sta = NULL; | 2082 | struct ieee80211_sta *sta; |
2045 | 2083 | ||
2046 | if (len != sizeof(*rsp)) { | 2084 | if (len != sizeof(*rsp)) { |
2047 | wcn36xx_warn("Corrupted delete sta indication\n"); | 2085 | wcn36xx_warn("Corrupted delete sta indication\n"); |
2048 | return -EIO; | 2086 | return -EIO; |
2049 | } | 2087 | } |
2050 | 2088 | ||
2089 | wcn36xx_dbg(WCN36XX_DBG_HAL, "delete station indication %pM index %d\n", | ||
2090 | rsp->addr2, rsp->sta_id); | ||
2091 | |||
2051 | list_for_each_entry(tmp, &wcn->vif_list, list) { | 2092 | list_for_each_entry(tmp, &wcn->vif_list, list) { |
2052 | if (sta && (tmp->sta->sta_index == rsp->sta_id)) { | 2093 | rcu_read_lock(); |
2053 | sta = container_of((void *)tmp->sta, | 2094 | sta = ieee80211_find_sta(wcn36xx_priv_to_vif(tmp), rsp->addr2); |
2054 | struct ieee80211_sta, | 2095 | if (sta) |
2055 | drv_priv); | ||
2056 | wcn36xx_dbg(WCN36XX_DBG_HAL, | ||
2057 | "delete station indication %pM index %d\n", | ||
2058 | rsp->addr2, | ||
2059 | rsp->sta_id); | ||
2060 | ieee80211_report_low_ack(sta, 0); | 2096 | ieee80211_report_low_ack(sta, 0); |
2097 | rcu_read_unlock(); | ||
2098 | if (sta) | ||
2061 | return 0; | 2099 | return 0; |
2062 | } | ||
2063 | } | 2100 | } |
2064 | 2101 | ||
2065 | wcn36xx_warn("STA with addr %pM and index %d not found\n", | 2102 | wcn36xx_warn("STA with addr %pM and index %d not found\n", |
@@ -2100,6 +2137,46 @@ out: | |||
2100 | mutex_unlock(&wcn->hal_mutex); | 2137 | mutex_unlock(&wcn->hal_mutex); |
2101 | return ret; | 2138 | return ret; |
2102 | } | 2139 | } |
2140 | |||
2141 | int wcn36xx_smd_set_mc_list(struct wcn36xx *wcn, | ||
2142 | struct ieee80211_vif *vif, | ||
2143 | struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp) | ||
2144 | { | ||
2145 | struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); | ||
2146 | struct wcn36xx_hal_rcv_flt_pkt_set_mc_list_req_msg *msg_body = NULL; | ||
2147 | int ret = 0; | ||
2148 | |||
2149 | mutex_lock(&wcn->hal_mutex); | ||
2150 | |||
2151 | msg_body = (struct wcn36xx_hal_rcv_flt_pkt_set_mc_list_req_msg *) | ||
2152 | wcn->hal_buf; | ||
2153 | init_hal_msg(&msg_body->header, WCN36XX_HAL_8023_MULTICAST_LIST_REQ, | ||
2154 | sizeof(msg_body->mc_addr_list)); | ||
2155 | |||
2156 | /* An empty list means all mc traffic will be received */ | ||
2157 | if (fp) | ||
2158 | memcpy(&msg_body->mc_addr_list, fp, | ||
2159 | sizeof(msg_body->mc_addr_list)); | ||
2160 | else | ||
2161 | msg_body->mc_addr_list.mc_addr_count = 0; | ||
2162 | |||
2163 | msg_body->mc_addr_list.bss_index = vif_priv->bss_index; | ||
2164 | |||
2165 | ret = wcn36xx_smd_send_and_wait(wcn, msg_body->header.len); | ||
2166 | if (ret) { | ||
2167 | wcn36xx_err("Sending HAL_8023_MULTICAST_LIST failed\n"); | ||
2168 | goto out; | ||
2169 | } | ||
2170 | ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); | ||
2171 | if (ret) { | ||
2172 | wcn36xx_err("HAL_8023_MULTICAST_LIST rsp failed err=%d\n", ret); | ||
2173 | goto out; | ||
2174 | } | ||
2175 | out: | ||
2176 | mutex_unlock(&wcn->hal_mutex); | ||
2177 | return ret; | ||
2178 | } | ||
2179 | |||
2103 | static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len) | 2180 | static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len) |
2104 | { | 2181 | { |
2105 | struct wcn36xx_hal_msg_header *msg_header = buf; | 2182 | struct wcn36xx_hal_msg_header *msg_header = buf; |
@@ -2141,6 +2218,7 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len) | |||
2141 | case WCN36XX_HAL_UPDATE_SCAN_PARAM_RSP: | 2218 | case WCN36XX_HAL_UPDATE_SCAN_PARAM_RSP: |
2142 | case WCN36XX_HAL_CH_SWITCH_RSP: | 2219 | case WCN36XX_HAL_CH_SWITCH_RSP: |
2143 | case WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_RSP: | 2220 | case WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_RSP: |
2221 | case WCN36XX_HAL_8023_MULTICAST_LIST_RSP: | ||
2144 | memcpy(wcn->hal_buf, buf, len); | 2222 | memcpy(wcn->hal_buf, buf, len); |
2145 | wcn->hal_rsp_len = len; | 2223 | wcn->hal_rsp_len = len; |
2146 | complete(&wcn->hal_rsp_compl); | 2224 | complete(&wcn->hal_rsp_compl); |
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h index 8361f9e3995b..d74d781f4c8d 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ b/drivers/net/wireless/ath/wcn36xx/smd.h | |||
@@ -44,15 +44,6 @@ struct wcn36xx_fw_msg_status_rsp { | |||
44 | u32 status; | 44 | u32 status; |
45 | } __packed; | 45 | } __packed; |
46 | 46 | ||
47 | /* wcn3620 returns this for tigger_ba */ | ||
48 | |||
49 | struct wcn36xx_fw_msg_status_rsp_v2 { | ||
50 | u8 bss_id[6]; | ||
51 | u32 status __packed; | ||
52 | u16 count_following_candidates __packed; | ||
53 | /* candidate list follows */ | ||
54 | }; | ||
55 | |||
56 | struct wcn36xx_hal_ind_msg { | 47 | struct wcn36xx_hal_ind_msg { |
57 | struct list_head list; | 48 | struct list_head list; |
58 | u8 *msg; | 49 | u8 *msg; |
@@ -136,4 +127,7 @@ int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 sta_index); | |||
136 | int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index); | 127 | int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index); |
137 | 128 | ||
138 | int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value); | 129 | int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value); |
130 | int wcn36xx_smd_set_mc_list(struct wcn36xx *wcn, | ||
131 | struct ieee80211_vif *vif, | ||
132 | struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp); | ||
139 | #endif /* _SMD_H_ */ | 133 | #endif /* _SMD_H_ */ |
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index 6c47a7336c38..1f34c2e912d7 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c | |||
@@ -102,9 +102,7 @@ static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn, | |||
102 | struct wcn36xx_vif *vif_priv = NULL; | 102 | struct wcn36xx_vif *vif_priv = NULL; |
103 | struct ieee80211_vif *vif = NULL; | 103 | struct ieee80211_vif *vif = NULL; |
104 | list_for_each_entry(vif_priv, &wcn->vif_list, list) { | 104 | list_for_each_entry(vif_priv, &wcn->vif_list, list) { |
105 | vif = container_of((void *)vif_priv, | 105 | vif = wcn36xx_priv_to_vif(vif_priv); |
106 | struct ieee80211_vif, | ||
107 | drv_priv); | ||
108 | if (memcmp(vif->addr, addr, ETH_ALEN) == 0) | 106 | if (memcmp(vif->addr, addr, ETH_ALEN) == 0) |
109 | return vif_priv; | 107 | return vif_priv; |
110 | } | 108 | } |
@@ -167,9 +165,7 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd, | |||
167 | */ | 165 | */ |
168 | if (sta_priv) { | 166 | if (sta_priv) { |
169 | __vif_priv = sta_priv->vif; | 167 | __vif_priv = sta_priv->vif; |
170 | vif = container_of((void *)__vif_priv, | 168 | vif = wcn36xx_priv_to_vif(__vif_priv); |
171 | struct ieee80211_vif, | ||
172 | drv_priv); | ||
173 | 169 | ||
174 | bd->dpu_sign = sta_priv->ucast_dpu_sign; | 170 | bd->dpu_sign = sta_priv->ucast_dpu_sign; |
175 | if (vif->type == NL80211_IFTYPE_STATION) { | 171 | if (vif->type == NL80211_IFTYPE_STATION) { |
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h index 7b41e833e18c..7433d67a5929 100644 --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h | |||
@@ -125,10 +125,10 @@ struct wcn36xx_platform_ctrl_ops { | |||
125 | */ | 125 | */ |
126 | struct wcn36xx_vif { | 126 | struct wcn36xx_vif { |
127 | struct list_head list; | 127 | struct list_head list; |
128 | struct wcn36xx_sta *sta; | ||
129 | u8 dtim_period; | 128 | u8 dtim_period; |
130 | enum ani_ed_type encrypt_type; | 129 | enum ani_ed_type encrypt_type; |
131 | bool is_joining; | 130 | bool is_joining; |
131 | bool sta_assoc; | ||
132 | struct wcn36xx_hal_mac_ssid ssid; | 132 | struct wcn36xx_hal_mac_ssid ssid; |
133 | 133 | ||
134 | /* Power management */ | 134 | /* Power management */ |
@@ -263,4 +263,22 @@ struct ieee80211_sta *wcn36xx_priv_to_sta(struct wcn36xx_sta *sta_priv) | |||
263 | return container_of((void *)sta_priv, struct ieee80211_sta, drv_priv); | 263 | return container_of((void *)sta_priv, struct ieee80211_sta, drv_priv); |
264 | } | 264 | } |
265 | 265 | ||
266 | static inline | ||
267 | struct wcn36xx_vif *wcn36xx_vif_to_priv(struct ieee80211_vif *vif) | ||
268 | { | ||
269 | return (struct wcn36xx_vif *) vif->drv_priv; | ||
270 | } | ||
271 | |||
272 | static inline | ||
273 | struct ieee80211_vif *wcn36xx_priv_to_vif(struct wcn36xx_vif *vif_priv) | ||
274 | { | ||
275 | return container_of((void *) vif_priv, struct ieee80211_vif, drv_priv); | ||
276 | } | ||
277 | |||
278 | static inline | ||
279 | struct wcn36xx_sta *wcn36xx_sta_to_priv(struct ieee80211_sta *sta) | ||
280 | { | ||
281 | return (struct wcn36xx_sta *)sta->drv_priv; | ||
282 | } | ||
283 | |||
266 | #endif /* _WCN36XX_H_ */ | 284 | #endif /* _WCN36XX_H_ */ |