RE: [PATCH 2/3] ath9k: make rxfilter per HW
> -Original Message- > From: Johannes Berg [mailto:johan...@sipsolutions.net] > Sent: Monday, June 22, 2015 15:00 > To: Janusz Dziedzic > Cc: linux-wireless@vger.kernel.org; ath9k-de...@venema.h4ckr.net; > n...@openwrt.org; suj...@msujith.org; Otcheretianski, Andrei > Subject: Re: [PATCH 2/3] ath9k: make rxfilter per HW > > On Mon, 2015-06-22 at 13:58 +0200, Johannes Berg wrote: > > On Mon, 2015-06-22 at 13:43 +0200, Janusz Dziedzic wrote: > > > mac80211 configure rxfilter per HW, > > > so we don't need this per channel. > > > > As I said before, I think there's value in mac80211 doing it per > > chanctx or even per vif, and it should be more efficient to do so. > > > > It's tempting to do it per vif and leave the chanctx work up to the > > driver, but perhaps with CSA and all that it gets complicated enough > > that doing it per chanctx in mac80211 would make sense? I don't think that it makes sense to do it per chanctx in mac80211. The cfg80211 API to configure filter isn't aware about chanctx's and also vifs that share same chanctx may have different filters etc.. Andrei > > On the other hand, I think our device requires it per vif, so we'd probably > have to do both. > > +Andrei, who was looking into this. > > johannes N�r��yb�X��ǧv�^�){.n�+{��*ޕ�,�
Re: [PATCH v2 8/8] ath10k: configure frag desc memory to target for qca99X0
On 06/23/2015 05:11 AM, Peter Oh wrote: Hi Raja, On 06/22/2015 07:52 AM, Raja Mani wrote: Pre qca99X0 chipsets follows the model where dynamically allocate memory for frag desc on getting new skb for TX. But, this is not going to be the case in qca99X0. It expects frag desc memory to be allocated at boot time and let the driver to reuse allocated memory after every TX completion. So there won't be any dynamic frag memory memory allocation in qca99X0 during data transmission. qca99X0 hardware doesn't need fragment desc address to be programmed in msdu descriptor for every data transaction. It needs to know only starting address of fragment descriptor at the time of the boot. During data transmission, qca99X0 hardware can retrieve corresponding frag addr by adding programmed frag desc base addr + msdu id. Allocate continuous fragment descriptor memory (same size as number of descriptor) at the time of target initialization and configure allocated dma address to the target via HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG. How this is allocated continuous memory is going to be used is not covered in this patch. It just allocates memory and hand over to firmware. If we don't do it at init time, qca99X0 will stall when firmware tries to do TX. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/core.c | 1 + drivers/net/wireless/ath/ath10k/core.h | 6 +++ drivers/net/wireless/ath/ath10k/htt.c| 4 ++ drivers/net/wireless/ath/ath10k/htt.h| 11 + drivers/net/wireless/ath/ath10k/htt_tx.c | 76 +++- 5 files changed, 96 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 3c8d5c5..be5f01c 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -111,6 +111,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, .uart_pin = 7, .otp_exe_param = 0x0700, +.continuous_frag_desc = true, .fw = { .dir = QCA99X0_HW_2_0_FW_DIR, .fw = QCA99X0_HW_2_0_FW_FILE, diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index f0811d0..2e5c935 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -582,6 +582,12 @@ struct ath10k { */ bool has_shifted_cc_wraparound; +/* Some of chip expects fragment descriptor to be continuous + * memory for any TX operation. Set continuous_frag_desc flag + * for the hardware which have such requirement. + */ +bool continuous_frag_desc; + struct ath10k_hw_params_fw { const char *dir; const char *fw; diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c index 6f71f94..4474c3e 100644 --- a/drivers/net/wireless/ath/ath10k/htt.c +++ b/drivers/net/wireless/ath/ath10k/htt.c @@ -249,5 +249,9 @@ int ath10k_htt_setup(struct ath10k_htt *htt) if (status) return status; +status = ath10k_htt_send_frag_desc_bank_cfg(htt); +if (status) +return status; + return ath10k_htt_send_rx_ring_cfg_ll(htt); } diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 8e64ace..8bdf1e7 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -87,6 +87,11 @@ struct htt_data_tx_desc_frag { __le32 len; } __packed; +struct htt_msdu_ext_desc { +__le32 tso_flag[4]; +struct htt_data_tx_desc_frag frags[6]; +}; + enum htt_data_tx_desc_flags0 { HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT = 1 << 0, HTT_DATA_TX_DESC_FLAGS0_NO_AGGR = 1 << 1, @@ -1466,6 +1471,11 @@ struct ath10k_htt { /* rx_status template */ struct ieee80211_rx_status rx_status; + +struct { +dma_addr_t paddr; +struct htt_msdu_ext_desc *vaddr; Defining structure htt_msdu_ext_desc for vaddr instead of void * which will be used as base address to get offset address of msdu data could lead unexpected address assignment when we manipulate msdu address pointer based on vaddr variable. For example vaddr variable will be used at ath10k_htt_tx like below to have msdu external link descriptor. struct htt_msdu_ext_desc *frags_ext; frags_ext = htt->frag_desc.vaddr + (sizeof(struct htt_msdu_ext_desc) * msdu_id); If we assume vaddr is 0xde81 and msdu_id is 1, we expect frags_ext has 0xde810040, but linux memory management system could assign 0xde811000 to frags_ext to use continuous memory block for structure htt_msdu_ext_desc and it will cause data traffic failure. To avoid this scenario, we have to use void * for vaddr. Here we know the type of memory what for we are allocating, thats why i kept it as struct htt_msdu_ext_desc *. We can type cast base addr to u8 * i
[PATCH 1/4] staging: wilc1000: wilc_wfi_netdevice.c: remove commented codes
Remove commented codes. Signed-off-by: Chaehyun Lim --- drivers/staging/wilc1000/wilc_wfi_netdevice.c | 21 - 1 file changed, 21 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.c b/drivers/staging/wilc1000/wilc_wfi_netdevice.c index 170ca65..478cd2b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.c +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.c @@ -325,7 +325,6 @@ void WILC_WFI_Rx(struct net_device *dev, struct WILC_WFI_packet *pkt) PRINT_INFO(RX_DBG, "In monitor device name %s\n", dev->name); priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); PRINT_D(RX_DBG, "VALUE PASSED IN OF HRWD %p\n", priv->hWILCWFIDrv); - /* host_int_get_rssi(priv->hWILCWFIDrv, &(rssi)); */ if (INFO) { for (i = 14; i < skb->len; i++) PRINT_INFO(RX_DBG, "RXdata[%d] %02x\n", i, skb->data[i]); @@ -600,12 +599,6 @@ int WILC_WFI_Tx(struct sk_buff *skb, struct net_device *dev) char *data, shortpkt[ETH_ZLEN]; struct WILC_WFI_priv *priv = netdev_priv(dev); - /* priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); */ - - /* if(priv->monitor_flag) */ - /* mac80211_hwsim_monitor_rx(skb); */ - - data = skb->data; len = skb->len; @@ -836,12 +829,6 @@ void WILC_WFI_Cleanup(void) int i; struct WILC_WFI_priv *priv[2]; - /*if(hwsim_mon!=NULL) -* { -* PRINT_D(RX_DBG, "Freeing monitor interface\n"); -* unregister_netdev(hwsim_mon); -* free_netdev(hwsim_mon); -* }*/ for (i = 0; i < 2; i++) { priv[i] = netdev_priv(WILC_WFI_devs[i]); @@ -897,7 +884,6 @@ int WILC_WFI_InitModule(void) WILC_WFI_Init); if (WILC_WFI_devs[i] == NULL) goto out; - /* priv[i] = netdev_priv(WILC_WFI_devs[i]); */ wdev = WILC_WFI_WiphyRegister(WILC_WFI_devs[i]); WILC_WFI_devs[i]->ieee80211_ptr = wdev; @@ -921,9 +907,6 @@ int WILC_WFI_InitModule(void) priv[1] = netdev_priv(WILC_WFI_devs[1]); if (priv[1]->dev->ieee80211_ptr->wiphy->interface_modes && BIT(NL80211_IFTYPE_MONITOR)) { - /* snprintf(buf, IFNAMSIZ, "mon.%s", priv[1]->dev->name); */ - /* WILC_WFI_init_mon_interface(); */ - /* priv[1]->monitor_flag = 1; */ } priv[0]->bCfgScanning = false; @@ -931,10 +914,6 @@ int WILC_WFI_InitModule(void) WILC_memset(priv[0]->au8AssociatedBss, 0xFF, ETH_ALEN); - - /* ret = host_int_init(&priv[0]->hWILCWFIDrv); */ - /*copy handle to the other driver*/ - /* priv[1]->hWILCWFIDrv = priv[0]->hWILCWFIDrv; */ if (ret) PRINT_ER("Error Init Driver\n"); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 2/4] staging: wilc1000: wilc_wfi_netdevice.c: remove unused codes
Remove if statement that has no any codes. Signed-off-by: Chaehyun Lim --- drivers/staging/wilc1000/wilc_wfi_netdevice.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.c b/drivers/staging/wilc1000/wilc_wfi_netdevice.c index 478cd2b..d5facb4 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.c +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.c @@ -906,9 +906,6 @@ int WILC_WFI_InitModule(void) priv[0] = netdev_priv(WILC_WFI_devs[0]); priv[1] = netdev_priv(WILC_WFI_devs[1]); - if (priv[1]->dev->ieee80211_ptr->wiphy->interface_modes && BIT(NL80211_IFTYPE_MONITOR)) { - - } priv[0]->bCfgScanning = false; priv[0]->u32RcvdChCount = 0; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 4/4] staging: wilc1000: wilc_wfi_netdevice.c: remove blank lines
Remove multiple blank lines. Signed-off-by: Chaehyun Lim --- drivers/staging/wilc1000/wilc_wfi_netdevice.c | 19 --- 1 file changed, 19 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.c b/drivers/staging/wilc1000/wilc_wfi_netdevice.c index c2e92c0..af9b858 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.c +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.c @@ -12,11 +12,9 @@ #include "wilc_wfi_cfgoperations.h" #include "host_interface.h" - MODULE_AUTHOR("Mai Daftedar"); MODULE_LICENSE("Dual BSD/GPL"); - struct net_device *WILC_WFI_devs[2]; /* @@ -34,7 +32,6 @@ module_param(timeout, int, 0); static int use_napi; module_param(use_napi, int, 0); - /* * A structure representing an in-flight packet. */ @@ -45,12 +42,9 @@ struct WILC_WFI_packet { u8 data[ETH_DATA_LEN]; }; - - int pool_size = 8; module_param(pool_size, int, 0); - static void WILC_WFI_TxTimeout(struct net_device *dev); static void (*WILC_WFI_Interrupt)(int, void *, struct pt_regs *); @@ -252,7 +246,6 @@ int WILC_WFI_Open(struct net_device *dev) int WILC_WFI_Release(struct net_device *dev) { /* release ports, irq and such -- like fops->close */ - netif_stop_queue(dev); /* can't transmit any more */ return 0; @@ -512,7 +505,6 @@ void WILC_WFI_HwTx(char *buf, int len, struct net_device *dev) u32 *saddr, *daddr; struct WILC_WFI_packet *tx_buffer; - /* I am paranoid. Ain't I? */ if (len < sizeof(struct ethhdr) + sizeof(struct iphdr)) { PRINT_D(RX_DBG, "WILC_WFI: Hmm... packet too short (%i octets)\n", @@ -580,7 +572,6 @@ void WILC_WFI_HwTx(char *buf, int len, struct net_device *dev) (unsigned long) priv->stats.tx_packets); } else WILC_WFI_Interrupt(0, dev, NULL); - } /** @@ -785,7 +776,6 @@ void WILC_WFI_Init(struct net_device *dev) { struct WILC_WFI_priv *priv; - /* * Then, assign other fields in dev, using ether_setup() and some * hand assignments @@ -851,12 +841,6 @@ void WILC_WFI_Cleanup(void) void StartConfigSim(void); - - - - - - /** * @brief WILC_WFI_Stat * @detailsReturn statistics to the caller @@ -877,7 +861,6 @@ int WILC_WFI_InitModule(void) WILC_WFI_Interrupt = use_napi ? WILC_WFI_NapiInterrupt : WILC_WFI_RegularInterrupt; for (i = 0; i < 2; i++) { - /* Allocate the net devices */ WILC_WFI_devs[i] = alloc_netdev(sizeof(struct WILC_WFI_priv), "wlan%d", WILC_WFI_Init); @@ -900,7 +883,6 @@ int WILC_WFI_InitModule(void) ret = 0; } - /*init atmel driver */ priv[0] = netdev_priv(WILC_WFI_devs[0]); priv[1] = netdev_priv(WILC_WFI_devs[1]); @@ -921,7 +903,6 @@ out: } - module_init(WILC_WFI_InitModule); module_exit(WILC_WFI_Cleanup); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 3/4] staging: wilc1000: wilc_wfi_netdevice.c: remove unused variable
Remove variable that is defined but never used. Signed-off-by: Chaehyun Lim --- drivers/staging/wilc1000/wilc_wfi_netdevice.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.c b/drivers/staging/wilc1000/wilc_wfi_netdevice.c index d5facb4..c2e92c0 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.c +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.c @@ -873,7 +873,6 @@ int WILC_WFI_InitModule(void) int result, i, ret = -ENOMEM; struct WILC_WFI_priv *priv[2], *netpriv; struct wireless_dev *wdev; - char buf[IFNAMSIZ]; WILC_WFI_Interrupt = use_napi ? WILC_WFI_NapiInterrupt : WILC_WFI_RegularInterrupt; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: [PATCH v2 8/8] ath10k: configure frag desc memory to target for qca99X0
Hi Raja, On 06/22/2015 07:52 AM, Raja Mani wrote: Pre qca99X0 chipsets follows the model where dynamically allocate memory for frag desc on getting new skb for TX. But, this is not going to be the case in qca99X0. It expects frag desc memory to be allocated at boot time and let the driver to reuse allocated memory after every TX completion. So there won't be any dynamic frag memory memory allocation in qca99X0 during data transmission. qca99X0 hardware doesn't need fragment desc address to be programmed in msdu descriptor for every data transaction. It needs to know only starting address of fragment descriptor at the time of the boot. During data transmission, qca99X0 hardware can retrieve corresponding frag addr by adding programmed frag desc base addr + msdu id. Allocate continuous fragment descriptor memory (same size as number of descriptor) at the time of target initialization and configure allocated dma address to the target via HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG. How this is allocated continuous memory is going to be used is not covered in this patch. It just allocates memory and hand over to firmware. If we don't do it at init time, qca99X0 will stall when firmware tries to do TX. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/core.c | 1 + drivers/net/wireless/ath/ath10k/core.h | 6 +++ drivers/net/wireless/ath/ath10k/htt.c| 4 ++ drivers/net/wireless/ath/ath10k/htt.h| 11 + drivers/net/wireless/ath/ath10k/htt_tx.c | 76 +++- 5 files changed, 96 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 3c8d5c5..be5f01c 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -111,6 +111,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, .uart_pin = 7, .otp_exe_param = 0x0700, + .continuous_frag_desc = true, .fw = { .dir = QCA99X0_HW_2_0_FW_DIR, .fw = QCA99X0_HW_2_0_FW_FILE, diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index f0811d0..2e5c935 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -582,6 +582,12 @@ struct ath10k { */ bool has_shifted_cc_wraparound; + /* Some of chip expects fragment descriptor to be continuous +* memory for any TX operation. Set continuous_frag_desc flag +* for the hardware which have such requirement. +*/ + bool continuous_frag_desc; + struct ath10k_hw_params_fw { const char *dir; const char *fw; diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c index 6f71f94..4474c3e 100644 --- a/drivers/net/wireless/ath/ath10k/htt.c +++ b/drivers/net/wireless/ath/ath10k/htt.c @@ -249,5 +249,9 @@ int ath10k_htt_setup(struct ath10k_htt *htt) if (status) return status; + status = ath10k_htt_send_frag_desc_bank_cfg(htt); + if (status) + return status; + return ath10k_htt_send_rx_ring_cfg_ll(htt); } diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 8e64ace..8bdf1e7 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -87,6 +87,11 @@ struct htt_data_tx_desc_frag { __le32 len; } __packed; +struct htt_msdu_ext_desc { + __le32 tso_flag[4]; + struct htt_data_tx_desc_frag frags[6]; +}; + enum htt_data_tx_desc_flags0 { HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT = 1 << 0, HTT_DATA_TX_DESC_FLAGS0_NO_AGGR = 1 << 1, @@ -1466,6 +1471,11 @@ struct ath10k_htt { /* rx_status template */ struct ieee80211_rx_status rx_status; + + struct { + dma_addr_t paddr; + struct htt_msdu_ext_desc *vaddr; Defining structure htt_msdu_ext_desc for vaddr instead of void * which will be used as base address to get offset address of msdu data could lead unexpected address assignment when we manipulate msdu address pointer based on vaddr variable. For example vaddr variable will be used at ath10k_htt_tx like below to have msdu external link descriptor. struct htt_msdu_ext_desc *frags_ext; frags_ext = htt->frag_desc.vaddr + (sizeof(struct htt_msdu_ext_desc) * msdu_id); If we assume vaddr is 0xde81 and msdu_id is 1, we expect frags_ext has 0xde810040, but linux memory management system could assign 0xde811000 to frags_ext to use continuous memory block for structure htt_msdu_ext_desc and it will cause data traffic failure. To avoid this scenario, we have to use void * for vaddr. + }
Best Dual Band Linux Drivers
What linux driver has the ability to set the preference for the 5 GHz over the 2.4 GHz range? The current one I have does not allow it. I posted this question online and since the SSID's are the same for the 2.4GHz and 5GHz, it has been difficult to setup the 5 GHz wireless connectivity. How do I set a preference for 5GHz over 2.4GHz Wifi in Lubuntu 12.04 http://askubuntu.com/questions/635358/how-do-i-set-a-preference-for-5ghz-over-2-4ghz-wifi-in-lubuntu-12-04 Any solutions or suggestions would be greatly appreciated. Thank you, Curtis Redkey Information Services | Systems Administrator | Loma Linda University Medical Center Telephone : 909.558.5068 |Email : cred...@llu.edu |Pager: cred...@my2way.com But the fruit of the Spirit is love, joy, peace, forbearance, kindness, goodness, faithfulness, gentleness and self-control. Against such things there is no law. Galatians 5:22-23 (NIV) CONFIDENTIALITY NOTICE: This e-mail communication and any attachments may contain confidential and privileged information for the use of the designated recipients named above. If you are not the intended recipient, you are hereby notified that you have received this communication in error and that any review, disclosure, dissemination, distribution or copying of it or its contents is prohibited. If you have received this communication in error, please notify me immediately by replying to this message and destroy all copies of this communication and any attachments. Thank you. -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: [PATCH] staging:rtl8723au:odm.c:Removing trailing whitespaces
"Joglekar, Tejas (T.)" writes: > From: Joglekar Tejas > > This patch removes the trailing whitespace error given > by checkpatch.pl > > Signed-off-by: Joglekar Tejas > --- > drivers/staging/rtl8723au/hal/odm.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) Looks straight forward. Acked-by: Jes Sorensen Jes > diff --git a/drivers/staging/rtl8723au/hal/odm.c > b/drivers/staging/rtl8723au/hal/odm.c > index f354f5e..6b9dbef 100644 > --- a/drivers/staging/rtl8723au/hal/odm.c > +++ b/drivers/staging/rtl8723au/hal/odm.c > @@ -985,7 +985,7 @@ void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 > bForceInNormal) > val32 = rtl8723au_read32(adapter, 0x874); > val32 |= pDM_PSTable->Reg874; > rtl8723au_write32(adapter, 0x874, val32); > - > + > val32 = rtl8723au_read32(adapter, 0xc70); > val32 |= pDM_PSTable->RegC70; > rtl8723au_write32(adapter, 0xc70, val32); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: [PATCH 2/3] ath9k: make rxfilter per HW
On 2015-06-22 13:59, Johannes Berg wrote: > On Mon, 2015-06-22 at 13:58 +0200, Johannes Berg wrote: >> On Mon, 2015-06-22 at 13:43 +0200, Janusz Dziedzic wrote: >> > mac80211 configure rxfilter per HW, >> > so we don't need this per channel. >> >> As I said before, I think there's value in mac80211 doing it per chanctx >> or even per vif, and it should be more efficient to do so. >> >> It's tempting to do it per vif and leave the chanctx work up to the >> driver, but perhaps with CSA and all that it gets complicated enough >> that doing it per chanctx in mac80211 would make sense? > > On the other hand, I think our device requires it per vif, so we'd > probably have to do both. > > +Andrei, who was looking into this. There's value in it, but I think it makes more sense to fix this bug now, and rework the code again later when mac80211 has support for per-vif or per-chanctx rxfilter. - Felix -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH v2 1/8] ath10k: enhance swba event handler to adapt different size tim bitmap
Due to 512 client support in 10.4 firmware, size of tim ie is going to be slightly higher than non 10.4 firmware. So, size of tim_bitmap what is carried in swba event from 10.4 firmware is bit higher. The only bottle neck to reuse existing swba handler ath10k_wmi_event_host_swba() for 10.4 is that code designed to deal with fixed size tim bitmap(ie, tim_info[].tim_bitmap in wmi_swba_ev_arg). This patch removes such size limitation and makes it more suitable to handle swba event which has different size tim bitmap. All existing swba event parsing functions are changed to adapt this change. Actual support to handle 10.4 swba event is added in next patch. Only preparation is made in this patch. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 18 +++- drivers/net/wireless/ath/ath10k/wmi.c | 49 +++ drivers/net/wireless/ath/ath10k/wmi.h | 10 ++- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 620b37b..ced35a1 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -709,6 +709,8 @@ static int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len, const void *ptr, void *data) { struct wmi_tlv_swba_parse *swba = data; + struct wmi_tim_info_arg *tim_info_arg; + const struct wmi_tim_info *tim_info_ev = ptr; if (tag != WMI_TLV_TAG_STRUCT_TIM_INFO) return -EPROTO; @@ -716,7 +718,21 @@ static int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len, if (swba->n_tim >= ARRAY_SIZE(swba->arg->tim_info)) return -ENOBUFS; - swba->arg->tim_info[swba->n_tim++] = ptr; + if (__le32_to_cpu(tim_info_ev->tim_len) > +sizeof(tim_info_ev->tim_bitmap)) { + ath10k_warn(ar, "refusing to parse invalid swba structure\n"); + return -EPROTO; + } + + tim_info_arg = &swba->arg->tim_info[swba->n_tim]; + tim_info_arg->tim_len = tim_info_ev->tim_len; + tim_info_arg->tim_mcast = tim_info_ev->tim_mcast; + tim_info_arg->tim_bitmap = tim_info_ev->tim_bitmap; + tim_info_arg->tim_changed = tim_info_ev->tim_changed; + tim_info_arg->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; + + swba->n_tim++; + return 0; } diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 271ad2f..d6a3ff2 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2874,33 +2874,38 @@ exit: static void ath10k_wmi_update_tim(struct ath10k *ar, struct ath10k_vif *arvif, struct sk_buff *bcn, - const struct wmi_tim_info *tim_info) + const struct wmi_tim_info_arg *tim_info) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)bcn->data; struct ieee80211_tim_ie *tim; u8 *ies, *ie; u8 ie_len, pvm_len; __le32 t; - u32 v; + u32 v, tim_len; + + /* When FW reports 0 in tim_len, ensure atleast first byte +* in tim_bitmap is considered for pvm calculation. +*/ + tim_len = tim_info->tim_len ? __le32_to_cpu(tim_info->tim_len) : 1; /* if next SWBA has no tim_changed the tim_bitmap is garbage. * we must copy the bitmap upon change and reuse it later */ if (__le32_to_cpu(tim_info->tim_changed)) { int i; - BUILD_BUG_ON(sizeof(arvif->u.ap.tim_bitmap) != -sizeof(tim_info->tim_bitmap)); + WARN_ON(sizeof(arvif->u.ap.tim_bitmap) < tim_len); - for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) { + for (i = 0; i < tim_len; i++) { t = tim_info->tim_bitmap[i / 4]; v = __le32_to_cpu(t); arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF; } - /* FW reports either length 0 or 16 -* so we calculate this on our own */ + /* FW reports either length 0 or length based on max supported +* station. so we calculate this on our own +*/ arvif->u.ap.tim_len = 0; - for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) + for (i = 0; i < tim_len; i++) if (arvif->u.ap.tim_bitmap[i]) arvif->u.ap.tim_len = i; @@ -2924,7 +2929,7 @@ static void ath10k_wmi_update_tim(struct ath10k *ar, pvm_len = ie_len - 3; /* exclude dtim count, dtim period, bmap ctl */ if (pvm_len < arvif->u.ap.tim_len) { - int expand_size = sizeof(ar
[PATCH v2 8/8] ath10k: configure frag desc memory to target for qca99X0
Pre qca99X0 chipsets follows the model where dynamically allocate memory for frag desc on getting new skb for TX. But, this is not going to be the case in qca99X0. It expects frag desc memory to be allocated at boot time and let the driver to reuse allocated memory after every TX completion. So there won't be any dynamic frag memory memory allocation in qca99X0 during data transmission. qca99X0 hardware doesn't need fragment desc address to be programmed in msdu descriptor for every data transaction. It needs to know only starting address of fragment descriptor at the time of the boot. During data transmission, qca99X0 hardware can retrieve corresponding frag addr by adding programmed frag desc base addr + msdu id. Allocate continuous fragment descriptor memory (same size as number of descriptor) at the time of target initialization and configure allocated dma address to the target via HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG. How this is allocated continuous memory is going to be used is not covered in this patch. It just allocates memory and hand over to firmware. If we don't do it at init time, qca99X0 will stall when firmware tries to do TX. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/core.c | 1 + drivers/net/wireless/ath/ath10k/core.h | 6 +++ drivers/net/wireless/ath/ath10k/htt.c| 4 ++ drivers/net/wireless/ath/ath10k/htt.h| 11 + drivers/net/wireless/ath/ath10k/htt_tx.c | 76 +++- 5 files changed, 96 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 3c8d5c5..be5f01c 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -111,6 +111,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, .uart_pin = 7, .otp_exe_param = 0x0700, + .continuous_frag_desc = true, .fw = { .dir = QCA99X0_HW_2_0_FW_DIR, .fw = QCA99X0_HW_2_0_FW_FILE, diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index f0811d0..2e5c935 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -582,6 +582,12 @@ struct ath10k { */ bool has_shifted_cc_wraparound; + /* Some of chip expects fragment descriptor to be continuous +* memory for any TX operation. Set continuous_frag_desc flag +* for the hardware which have such requirement. +*/ + bool continuous_frag_desc; + struct ath10k_hw_params_fw { const char *dir; const char *fw; diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c index 6f71f94..4474c3e 100644 --- a/drivers/net/wireless/ath/ath10k/htt.c +++ b/drivers/net/wireless/ath/ath10k/htt.c @@ -249,5 +249,9 @@ int ath10k_htt_setup(struct ath10k_htt *htt) if (status) return status; + status = ath10k_htt_send_frag_desc_bank_cfg(htt); + if (status) + return status; + return ath10k_htt_send_rx_ring_cfg_ll(htt); } diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 8e64ace..8bdf1e7 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -87,6 +87,11 @@ struct htt_data_tx_desc_frag { __le32 len; } __packed; +struct htt_msdu_ext_desc { + __le32 tso_flag[4]; + struct htt_data_tx_desc_frag frags[6]; +}; + enum htt_data_tx_desc_flags0 { HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT = 1 << 0, HTT_DATA_TX_DESC_FLAGS0_NO_AGGR = 1 << 1, @@ -1466,6 +1471,11 @@ struct ath10k_htt { /* rx_status template */ struct ieee80211_rx_status rx_status; + + struct { + dma_addr_t paddr; + struct htt_msdu_ext_desc *vaddr; + } frag_desc; }; #define RX_HTT_HDR_STATUS_LEN 64 @@ -1533,6 +1543,7 @@ void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb); void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb); int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt); int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie); +int ath10k_htt_send_frag_desc_bank_cfg(struct ath10k_htt *htt); int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt); int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt, u8 max_subfrms_ampdu, diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index a60ef7d..148d5b6 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -84,6 +84,7 @@ void
[PATCH v2 7/8] ath10k: set max spatial stream to 4 for 10.4 fw
10.4 fw supports upto 4 spatial stream. Limit max spatial stream to 4 for 10.4 firmware and to 3 for non 10.4 firmware. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/core.c | 4 drivers/net/wireless/ath/ath10k/core.h | 1 + drivers/net/wireless/ath/ath10k/wmi.c | 6 +++--- drivers/net/wireless/ath/ath10k/wmi.h | 3 ++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index b43565d..3c8d5c5 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -1095,6 +1095,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC; ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV | WMI_STAT_PEER; + ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM; break; case ATH10K_FW_WMI_OP_VERSION_10_1: case ATH10K_FW_WMI_OP_VERSION_10_2: @@ -1104,6 +1105,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) ar->max_num_vdevs = TARGET_10X_NUM_VDEVS; ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC; ar->fw_stats_req_mask = WMI_STAT_PEER; + ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM; break; case ATH10K_FW_WMI_OP_VERSION_TLV: ar->max_num_peers = TARGET_TLV_NUM_PEERS; @@ -1114,6 +1116,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS; ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV | WMI_STAT_PEER; + ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM; break; case ATH10K_FW_WMI_OP_VERSION_10_4: ar->max_num_peers = TARGET_10_4_NUM_PEERS; @@ -1123,6 +1126,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) ar->num_tids = TARGET_10_4_TGT_NUM_TIDS; ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC; ar->fw_stats_req_mask = WMI_STAT_PEER; + ar->max_spatial_stream = WMI_10_4_MAX_SPATIAL_STREAM; break; case ATH10K_FW_WMI_OP_VERSION_UNSET: case ATH10K_FW_WMI_OP_VERSION_MAX: diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 86c4015..f0811d0 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -546,6 +546,7 @@ struct ath10k { u32 ht_cap_info; u32 vht_cap_info; u32 num_rf_chains; + u32 max_spatial_stream; /* protected by conf_mutex */ bool ani_enabled; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index fffdae1..a00e3ca 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3911,10 +3911,10 @@ void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb) if (ar->fw_api == 1 && ar->fw_version_build > 636) set_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features); - if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { + if (ar->num_rf_chains > ar->max_spatial_stream) { ath10k_warn(ar, "hardware advertises support for more spatial streams than it should (%d > %d)\n", - ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); - ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; + ar->num_rf_chains, ar->max_spatial_stream); + ar->num_rf_chains = ar->max_spatial_stream; } ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1; diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 6e806cb..0d4efc9 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -1747,7 +1747,8 @@ enum wmi_channel_change_cause { /* Indicate reason for channel switch */ #define WMI_CHANNEL_CHANGE_CAUSE_CSA (1 << 13) -#define WMI_MAX_SPATIAL_STREAM 3 +#define WMI_MAX_SPATIAL_STREAM3 /* default max ss */ +#define WMI_10_4_MAX_SPATIAL_STREAM 4 /* HT Capabilities*/ #define WMI_HT_CAP_ENABLED0x0001 /* HT Enabled/ disabled */ -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH v2 6/8] ath10k: advertise 10.4 fw ap and sta iface combination to mac80211
10.4 fw supports upto 16 interface in ap mode and 1 interface in station mode, overall total interfaces supported are 16 interfaces. Populate this limit in wiphy->iface_combinations. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/mac.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index f9989d1..bbdf7a9 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -6620,6 +6620,33 @@ static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = { }, }; +static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max= 16, + .types = BIT(NL80211_IFTYPE_AP) + }, +}; + +static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = { + { + .limits = ath10k_10_4_if_limits, + .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits), + .max_interfaces = 16, + .num_different_channels = 1, + .beacon_int_infra_match = true, +#ifdef CONFIG_ATH10K_DFS_CERTIFIED + .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | + BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80), +#endif + }, +}; + static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar) { struct ieee80211_sta_vht_cap vht_cap = {0}; @@ -6944,6 +6971,9 @@ int ath10k_mac_register(struct ath10k *ar) ARRAY_SIZE(ath10k_10x_if_comb); break; case ATH10K_FW_WMI_OP_VERSION_10_4: + ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb; + ar->hw->wiphy->n_iface_combinations = + ARRAY_SIZE(ath10k_10_4_if_comb); break; case ATH10K_FW_WMI_OP_VERSION_UNSET: case ATH10K_FW_WMI_OP_VERSION_MAX: -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH v2 4/8] ath10k: add scan support for 10.4 fw
Existing non 10.4 firmware scan related events and commands are matching with 10.4 firmware (except chan info event). Link general start scan,stop scan, scan channel list configuration functions to 10.4 wmi function table and add a new handler to parse 10.4 specific chan info event. 10.4 firmware has extra scan completion reason WMI_SCAN_REASON_INTERNAL_FAILURE and new scan event WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT compared to previous firmware versions. These things are added in respective enum. Signed-off-by: Raja Mani --- v2 changes: - WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT is added newly. - BIT() macro is used to define the values of "enum wmi_scan_event_type" - New member rx_frame_count is added in struct wmi_10_4_chan_info_event drivers/net/wireless/ath/ath10k/wmi.c | 42 +++ drivers/net/wireless/ath/ath10k/wmi.h | 36 ++ 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index c4d777d..fffdae1 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1923,6 +1923,8 @@ ath10k_wmi_event_scan_type_str(enum wmi_scan_event_type type, return "completed [preempted]"; case WMI_SCAN_REASON_TIMEDOUT: return "completed [timedout]"; + case WMI_SCAN_REASON_INTERNAL_FAILURE: + return "completed [internal err]"; case WMI_SCAN_REASON_MAX: break; } @@ -1937,6 +1939,10 @@ ath10k_wmi_event_scan_type_str(enum wmi_scan_event_type type, return "preempted"; case WMI_SCAN_EVENT_START_FAILED: return "start failed"; + case WMI_SCAN_EVENT_RESTARTED: + return "restarted"; + case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: + return "foreign channel exit"; default: return "unknown"; } @@ -2012,6 +2018,8 @@ int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) break; case WMI_SCAN_EVENT_DEQUEUED: case WMI_SCAN_EVENT_PREEMPTED: + case WMI_SCAN_EVENT_RESTARTED: + case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: default: break; } @@ -2318,6 +2326,29 @@ static int ath10k_wmi_op_pull_ch_info_ev(struct ath10k *ar, struct sk_buff *skb, return 0; } +static int ath10k_wmi_10_4_op_pull_ch_info_ev(struct ath10k *ar, + struct sk_buff *skb, + struct wmi_ch_info_ev_arg *arg) +{ + struct wmi_10_4_chan_info_event *ev = (void *)skb->data; + + if (skb->len < sizeof(*ev)) + return -EPROTO; + + skb_pull(skb, sizeof(*ev)); + arg->err_code = ev->err_code; + arg->freq = ev->freq; + arg->cmd_flags = ev->cmd_flags; + arg->noise_floor = ev->noise_floor; + arg->rx_clear_count = ev->rx_clear_count; + arg->cycle_count = ev->cycle_count; + arg->chan_tx_pwr_range = ev->chan_tx_pwr_range; + arg->chan_tx_pwr_tp = ev->chan_tx_pwr_tp; + arg->rx_frame_count = ev->rx_frame_count; + + return 0; +} + void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb) { struct wmi_ch_info_ev_arg arg = {}; @@ -4427,6 +4458,12 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) case WMI_10_4_SERVICE_READY_EVENTID: ath10k_wmi_event_service_ready(ar, skb); break; + case WMI_10_4_SCAN_EVENTID: + ath10k_wmi_event_scan(ar, skb); + break; + case WMI_10_4_CHAN_INFO_EVENTID: + ath10k_wmi_event_chan_info(ar, skb); + break; case WMI_10_4_READY_EVENTID: ath10k_wmi_event_ready(ar, skb); break; @@ -6382,7 +6419,10 @@ static const struct wmi_ops wmi_10_2_4_ops = { static const struct wmi_ops wmi_10_4_ops = { .rx = ath10k_wmi_10_4_op_rx, .map_svc = wmi_10_4_svc_map, + + .pull_scan = ath10k_wmi_op_pull_scan_ev, .pull_mgmt_rx = ath10k_wmi_10_4_op_pull_mgmt_rx_ev, + .pull_ch_info = ath10k_wmi_10_4_op_pull_ch_info_ev, .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, .pull_swba = ath10k_wmi_10_4_op_pull_swba_ev, @@ -6394,6 +6434,8 @@ static const struct wmi_ops wmi_10_4_ops = { .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, .gen_init = ath10k_wmi_10_4_op_gen_init, + .gen_start_scan = ath10k_wmi_op_gen_start_scan, + .gen_stop_scan = ath10k_wmi_op_gen_stop_scan, .gen_vdev_create = ath10k_wmi_op_gen_vdev_create, .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
[PATCH v2 5/8] ath10k: add 10.4 fw specific htt msg definitions
New htt event table is added for 10.4 firmware. Following new htt events are available only 10.4. adding this to generic htt event table, HTT_T2H_MSG_TYPE_EN_STATS, HTT_T2H_MSG_TYPE_TX_FETCH_IND, HTT_T2H_MSG_TYPE_TX_FETCH_CONF, HTT_T2H_MSG_TYPE_TX_LOW_LATENCY_IND Signed-off-by: Raja Mani --- v2 changes: - updated htt msg ids based on stable 10.4 firmware. drivers/net/wireless/ath/ath10k/core.c | 3 +++ drivers/net/wireless/ath/ath10k/htt.c| 41 drivers/net/wireless/ath/ath10k/htt.h| 36 drivers/net/wireless/ath/ath10k/htt_rx.c | 4 drivers/net/wireless/ath/ath10k/hw.h | 2 ++ 5 files changed, 86 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 020ac9f..b43565d 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -1121,6 +1121,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS; ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS; ar->num_tids = TARGET_10_4_TGT_NUM_TIDS; + ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC; ar->fw_stats_req_mask = WMI_STAT_PEER; break; case ATH10K_FW_WMI_OP_VERSION_UNSET: @@ -1146,6 +1147,8 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_TLV; break; case ATH10K_FW_WMI_OP_VERSION_10_4: + ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_10_4; + break; case ATH10K_FW_WMI_OP_VERSION_UNSET: case ATH10K_FW_WMI_OP_VERSION_MAX: WARN_ON(1); diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c index 6da6ef2..6f71f94 100644 --- a/drivers/net/wireless/ath/ath10k/htt.c +++ b/drivers/net/wireless/ath/ath10k/htt.c @@ -102,6 +102,43 @@ static const enum htt_t2h_msg_type htt_tlv_t2h_msg_types[] = { [HTT_TLV_T2H_MSG_TYPE_TEST] = HTT_T2H_MSG_TYPE_TEST, }; +static const enum htt_t2h_msg_type htt_10_4_t2h_msg_types[] = { + [HTT_10_4_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF, + [HTT_10_4_T2H_MSG_TYPE_RX_IND] = HTT_T2H_MSG_TYPE_RX_IND, + [HTT_10_4_T2H_MSG_TYPE_RX_FLUSH] = HTT_T2H_MSG_TYPE_RX_FLUSH, + [HTT_10_4_T2H_MSG_TYPE_PEER_MAP] = HTT_T2H_MSG_TYPE_PEER_MAP, + [HTT_10_4_T2H_MSG_TYPE_PEER_UNMAP] = HTT_T2H_MSG_TYPE_PEER_UNMAP, + [HTT_10_4_T2H_MSG_TYPE_RX_ADDBA] = HTT_T2H_MSG_TYPE_RX_ADDBA, + [HTT_10_4_T2H_MSG_TYPE_RX_DELBA] = HTT_T2H_MSG_TYPE_RX_DELBA, + [HTT_10_4_T2H_MSG_TYPE_TX_COMPL_IND] = HTT_T2H_MSG_TYPE_TX_COMPL_IND, + [HTT_10_4_T2H_MSG_TYPE_PKTLOG] = HTT_T2H_MSG_TYPE_PKTLOG, + [HTT_10_4_T2H_MSG_TYPE_STATS_CONF] = HTT_T2H_MSG_TYPE_STATS_CONF, + [HTT_10_4_T2H_MSG_TYPE_RX_FRAG_IND] = HTT_T2H_MSG_TYPE_RX_FRAG_IND, + [HTT_10_4_T2H_MSG_TYPE_SEC_IND] = HTT_T2H_MSG_TYPE_SEC_IND, + [HTT_10_4_T2H_MSG_TYPE_RC_UPDATE_IND] = HTT_T2H_MSG_TYPE_RC_UPDATE_IND, + [HTT_10_4_T2H_MSG_TYPE_TX_INSPECT_IND] = + HTT_T2H_MSG_TYPE_TX_INSPECT_IND, + [HTT_10_4_T2H_MSG_TYPE_MGMT_TX_COMPL_IND] = + HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION, + [HTT_10_4_T2H_MSG_TYPE_CHAN_CHANGE] = HTT_T2H_MSG_TYPE_CHAN_CHANGE, + [HTT_10_4_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND] = + HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND, + [HTT_10_4_T2H_MSG_TYPE_RX_PN_IND] = HTT_T2H_MSG_TYPE_RX_PN_IND, + [HTT_10_4_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND] = + HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND, + [HTT_10_4_T2H_MSG_TYPE_TEST] = HTT_T2H_MSG_TYPE_TEST, + [HTT_10_4_T2H_MSG_TYPE_EN_STATS] = HTT_T2H_MSG_TYPE_EN_STATS, + [HTT_10_4_T2H_MSG_TYPE_AGGR_CONF] = HTT_T2H_MSG_TYPE_AGGR_CONF, + [HTT_10_4_T2H_MSG_TYPE_TX_FETCH_IND] = + HTT_T2H_MSG_TYPE_TX_FETCH_IND, + [HTT_10_4_T2H_MSG_TYPE_TX_FETCH_CONF] = + HTT_T2H_MSG_TYPE_TX_FETCH_CONF, + [HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD] = + HTT_T2H_MSG_TYPE_STATS_NOUPLOAD, + [HTT_10_4_T2H_MSG_TYPE_TX_LOW_LATENCY_IND] = + HTT_T2H_MSG_TYPE_TX_LOW_LATENCY_IND, +}; + int ath10k_htt_connect(struct ath10k_htt *htt) { struct ath10k_htc_svc_conn_req conn_req; @@ -147,6 +184,10 @@ int ath10k_htt_init(struct ath10k *ar) 2; /* ip4 dscp or ip6 priority */ switch (ar->htt.op_version) { + case ATH10K_FW_HTT_OP_VERSION_10_4: + ar->htt.t2h_msg_types = htt_10_4_t2h_msg_types; + ar->htt.t2h_msg_types_max = HTT_10_4_T2H_
[PATCH v2 0/8] add beacon and htt msg support for 10.4 firmware
This is the continuation of earlier patch set posted for adding 10.4 wmi support. This patch series covers following items w.r.t 10.4 firmware, - Enhance existing swba event handler to handle variable size tim bitmap and add support to handle 10.4 swba event. - Enable pdev, vdev, peer related wmi operations like create, delete, etc. - Includes scan support. - Add 10.4 specific htt msg. - Advertise 10.4 iface combination to mac80211. - Adjust max ss and initialize continuous frag descriptor memory v2 changes: - rebased on top of "introduce wmi support for qca99x0" patch series. - updated htt msg definitions as per stable 10.4 firmware. - synced scan related info as per stable 10.4 firmware. Raja Mani (8): ath10k: enhance swba event handler to adapt different size tim bitmap ath10k: handle 10.4 firmware wmi swba event ath10k: enable vdev and peer related operations for 10.4 fw ath10k: add scan support for 10.4 fw ath10k: add 10.4 fw specific htt msg definitions ath10k: advertise 10.4 fw ap and sta iface combination to mac80211 ath10k: set max spatial stream to 4 for 10.4 fw ath10k: configure frag desc memory to target for qca99X0 drivers/net/wireless/ath/ath10k/core.c| 8 ++ drivers/net/wireless/ath/ath10k/core.h| 11 +- drivers/net/wireless/ath/ath10k/htt.c | 45 ++ drivers/net/wireless/ath/ath10k/htt.h | 47 +++ drivers/net/wireless/ath/ath10k/htt_rx.c | 4 + drivers/net/wireless/ath/ath10k/htt_tx.c | 76 ++- drivers/net/wireless/ath/ath10k/hw.h | 2 + drivers/net/wireless/ath/ath10k/mac.c | 30 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 18 ++- drivers/net/wireless/ath/ath10k/wmi.c | 220 +++--- drivers/net/wireless/ath/ath10k/wmi.h | 90 ++-- 11 files changed, 519 insertions(+), 32 deletions(-) -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH v2 2/8] ath10k: handle 10.4 firmware wmi swba event
10.4 firmware swba event payload has space to accommodate upto 512 client traffic indication info & one p2p noa descriptor. It's is not matching with exiting swba event format defined for non 10.4 firmware. Non 10.4 firmware swba event format is designed to support only upto only 128 client and four p2p notice of absence descriptor. following changes are done in this patch to enable ath10k to handle 10.4 firmware swba event, - link generic ath10k_wmi_event_host_swba() to handle 10.4 swba event in 10.4 wmi rx handler. - add 10.4 specific swba event structure wmi_10_4_host_swba_event. - new function ath10k_wmi_10_4_op_pull_swba_ev() to parse 10.4 swba event. - increase tim_bitmap[] size in ath10k_vif to 64 to hold 512 station power save state. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/core.h | 4 +-- drivers/net/wireless/ath/ath10k/wmi.c | 61 ++ drivers/net/wireless/ath/ath10k/wmi.h | 41 +++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 58b02ae..86c4015 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -328,8 +328,8 @@ struct ath10k_vif { u32 uapsd; } sta; struct { - /* 127 stations; wmi limit */ - u8 tim_bitmap[16]; + /* 512 stations */ + u8 tim_bitmap[64]; u8 tim_len; u32 ssid_len; u8 ssid[IEEE80211_MAX_SSID_LEN]; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index d6a3ff2..48ea442 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3030,6 +3030,63 @@ static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb, return 0; } +static int ath10k_wmi_10_4_op_pull_swba_ev(struct ath10k *ar, + struct sk_buff *skb, + struct wmi_swba_ev_arg *arg) +{ + struct wmi_10_4_host_swba_event *ev = (void *)skb->data; + u32 map, tim_len; + size_t i; + + if (skb->len < sizeof(*ev)) + return -EPROTO; + + skb_pull(skb, sizeof(*ev)); + arg->vdev_map = ev->vdev_map; + + for (i = 0, map = __le32_to_cpu(ev->vdev_map); map; map >>= 1) { + if (!(map & BIT(0))) + continue; + + /* If this happens there were some changes in firmware and +* ath10k should update the max size of tim_info array. +*/ + if (WARN_ON_ONCE(i == ARRAY_SIZE(arg->tim_info))) + break; + + if (__le32_to_cpu(ev->bcn_info[i].tim_info.tim_len) > + sizeof(ev->bcn_info[i].tim_info.tim_bitmap)) { + ath10k_warn(ar, "refusing to parse invalid swba structure\n"); + return -EPROTO; + } + + tim_len = __le32_to_cpu(ev->bcn_info[i].tim_info.tim_len); + if (tim_len) { + /* Exclude 4 byte guard length */ + tim_len -= 4; + arg->tim_info[i].tim_len = __cpu_to_le32(tim_len); + } else { + arg->tim_info[i].tim_len = 0; + } + + arg->tim_info[i].tim_mcast = ev->bcn_info[i].tim_info.tim_mcast; + arg->tim_info[i].tim_bitmap = + ev->bcn_info[i].tim_info.tim_bitmap; + arg->tim_info[i].tim_changed = + ev->bcn_info[i].tim_info.tim_changed; + arg->tim_info[i].tim_num_ps_pending = + ev->bcn_info[i].tim_info.tim_num_ps_pending; + + /* 10.4 firmware doesn't have p2p support. notice of absence +* info can be ignored for now. +*/ + + i++; + } + + return 0; +} + void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) { struct wmi_swba_ev_arg arg = {}; @@ -4364,6 +4421,9 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) case WMI_10_4_READY_EVENTID: ath10k_wmi_event_ready(ar, skb); break; + case WMI_10_4_HOST_SWBA_EVENTID: + ath10k_wmi_event_host_swba(ar, skb); + break; default: ath10k_warn(ar, "Unknown eventid: %d\n", id); break; @@ -6295,6 +6355,7 @@ static const struct wmi_ops wmi_10_4_ops = { .rx = ath10k_wmi_10_4_op_rx, .map_svc = wmi_10_4_svc_map, .pull_mgmt_rx = ath10k_wmi_10_4_op_pull_mgmt_rx_ev, + .pull_swba = ath10k_wmi_10_
[PATCH v2 3/8] ath10k: enable vdev and peer related operations for 10.4 fw
Most of existing vdev and peer related functions (vdev create, vdev delete, vdev start, peer create, peer delete, peer flush, etc) are reusable for 10.4 firmware. Link those general vdev and peer functions to 10.4 wmi function table. Existing general pktlog enable/disable, dbglog configuration functions are reusable for 10.4 and add them also in wmi function table. Also handle few wmi events (sevice rdy, echo, dbg msg, tbtt offset update, dbg print) in ath10k_wmi_10_4_op_rx(). wow event is not applicable in 10.4 firmware, have it under not implemented print. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/wmi.c | 62 +++ 1 file changed, 62 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 48ea442..c4d777d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -4418,12 +4418,40 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) ath10k_wmi_event_mgmt_rx(ar, skb); /* mgmt_rx() owns the skb now! */ return; + case WMI_10_4_ECHO_EVENTID: + ath10k_wmi_event_echo(ar, skb); + break; + case WMI_10_4_DEBUG_MESG_EVENTID: + ath10k_wmi_event_debug_mesg(ar, skb); + break; + case WMI_10_4_SERVICE_READY_EVENTID: + ath10k_wmi_event_service_ready(ar, skb); + break; case WMI_10_4_READY_EVENTID: ath10k_wmi_event_ready(ar, skb); break; + case WMI_10_4_PEER_STA_KICKOUT_EVENTID: + ath10k_wmi_event_peer_sta_kickout(ar, skb); + break; case WMI_10_4_HOST_SWBA_EVENTID: ath10k_wmi_event_host_swba(ar, skb); break; + case WMI_10_4_TBTTOFFSET_UPDATE_EVENTID: + ath10k_wmi_event_tbttoffset_update(ar, skb); + break; + case WMI_10_4_DEBUG_PRINT_EVENTID: + ath10k_wmi_event_debug_print(ar, skb); + break; + case WMI_10_4_VDEV_START_RESP_EVENTID: + ath10k_wmi_event_vdev_start_resp(ar, skb); + break; + case WMI_10_4_VDEV_STOPPED_EVENTID: + ath10k_wmi_event_vdev_stopped(ar, skb); + break; + case WMI_10_4_WOW_WAKEUP_HOST_EVENTID: + ath10k_dbg(ar, ATH10K_DBG_WMI, + "received event id %d not implemented\n", id); + break; default: ath10k_warn(ar, "Unknown eventid: %d\n", id); break; @@ -6355,10 +6383,44 @@ static const struct wmi_ops wmi_10_4_ops = { .rx = ath10k_wmi_10_4_op_rx, .map_svc = wmi_10_4_svc_map, .pull_mgmt_rx = ath10k_wmi_10_4_op_pull_mgmt_rx_ev, + .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, + .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, .pull_swba = ath10k_wmi_10_4_op_pull_swba_ev, .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev, .pull_rdy = ath10k_wmi_op_pull_rdy_ev, + + .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, + .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, + .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, + .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, .gen_init = ath10k_wmi_10_4_op_gen_init, + .gen_vdev_create = ath10k_wmi_op_gen_vdev_create, + .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete, + .gen_vdev_start = ath10k_wmi_op_gen_vdev_start, + .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop, + .gen_vdev_up = ath10k_wmi_op_gen_vdev_up, + .gen_vdev_down = ath10k_wmi_op_gen_vdev_down, + .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param, + .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key, + .gen_peer_create = ath10k_wmi_op_gen_peer_create, + .gen_peer_delete = ath10k_wmi_op_gen_peer_delete, + .gen_peer_flush = ath10k_wmi_op_gen_peer_flush, + .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param, + .gen_set_psmode = ath10k_wmi_op_gen_set_psmode, + .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps, + .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps, + .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list, + .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma, + .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm, + .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang, + .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx, + .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg, + .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable, + .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable, + .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode, + + /* shared with 10.2 */ + .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc, }; int ath10k_wmi_attach(struct ath10k *ar) -- 1.8.1.2
[PATCH v2 10/10] ath10k: handle 10.4 fw wmi ready event
Reuse existing function ath10k_wmi_op_pull_rdy_ev() to parse WMI_10_4_READY_EVENTID and handle the same event in ath10k_wmi_10_4_op_rx(). Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/wmi.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 62ea0bc..271ad2f 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -4338,6 +4338,9 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) ath10k_wmi_event_mgmt_rx(ar, skb); /* mgmt_rx() owns the skb now! */ return; + case WMI_10_4_READY_EVENTID: + ath10k_wmi_event_ready(ar, skb); + break; default: ath10k_warn(ar, "Unknown eventid: %d\n", id); break; @@ -6270,6 +6273,7 @@ static const struct wmi_ops wmi_10_4_ops = { .map_svc = wmi_10_4_svc_map, .pull_mgmt_rx = ath10k_wmi_10_4_op_pull_mgmt_rx_ev, .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev, + .pull_rdy = ath10k_wmi_op_pull_rdy_ev, .gen_init = ath10k_wmi_10_4_op_gen_init, }; -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH v2 09/10] ath10k: adjust default peer limits if qcache enabled in 10.4 fw
10.4 firmware supports upto 512 clients when qcache feature is enabled. Make adjustment on default max peer count, active peers, number of tid in such case to meet qcache requirement. 10.4 fw has extra unit info flag NUM_UNITS_IS_NUM_ACTIVE_PEERS which is also handled in this patch. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/hw.h | 6 ++ drivers/net/wireless/ath/ath10k/wmi.c | 27 +++ drivers/net/wireless/ath/ath10k/wmi.h | 5 +++-- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 52fc024..568c5ea5 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -360,6 +360,12 @@ enum ath10k_hw_rate_cck { #define TARGET_10_4_NUM_PEERS ((TARGET_10_4_NUM_STATIONS) + \ (TARGET_10_4_NUM_VDEVS)) #define TARGET_10_4_ACTIVE_PEERS 0 + +/* TODO: increase qcache max client limit to 512 after + * testing with 512 client. + */ +#define TARGET_10_4_NUM_QCACHE_PEERS_MAX 256 +#define TARGET_10_4_QCACHE_ACTIVE_PEERS50 #define TARGET_10_4_NUM_OFFLOAD_PEERS 0 #define TARGET_10_4_NUM_OFFLOAD_REORDER_BUFFS 0 #define TARGET_10_4_NUM_PEER_KEYS 2 diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 9502032..62ea0bc 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3826,20 +3826,39 @@ void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb) return; } + if (test_bit(WMI_SERVICE_PEER_CACHING, ar->wmi.svc_map)) { + ar->max_num_peers = TARGET_10_4_NUM_QCACHE_PEERS_MAX + + TARGET_10_4_NUM_VDEVS; + ar->num_active_peers = TARGET_10_4_QCACHE_ACTIVE_PEERS + + TARGET_10_4_NUM_VDEVS; + ar->num_tids = ar->num_active_peers * 2; + ar->max_num_stations = TARGET_10_4_NUM_QCACHE_PEERS_MAX; + } + + /* TODO: Adjust max peer count for cases like WMI_SERVICE_RATECTRL_CACHE +* and WMI_SERVICE_IRAM_TIDS, etc. +*/ + for (i = 0; i < num_mem_reqs; ++i) { req_id = __le32_to_cpu(arg.mem_reqs[i]->req_id); num_units = __le32_to_cpu(arg.mem_reqs[i]->num_units); unit_size = __le32_to_cpu(arg.mem_reqs[i]->unit_size); num_unit_info = __le32_to_cpu(arg.mem_reqs[i]->num_unit_info); - if (num_unit_info & NUM_UNITS_IS_NUM_PEERS) + if (num_unit_info & NUM_UNITS_IS_NUM_ACTIVE_PEERS) { + if (ar->num_active_peers) + num_units = ar->num_active_peers + 1; + else + num_units = ar->max_num_peers + 1; + } else if (num_unit_info & NUM_UNITS_IS_NUM_PEERS) { /* number of units to allocate is number of * peers, 1 extra for self peer on target */ /* this needs to be tied, host and target * can get out of sync */ - num_units = TARGET_10X_NUM_PEERS + 1; - else if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS) - num_units = TARGET_10X_NUM_VDEVS + 1; + num_units = ar->max_num_peers + 1; + } else if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS) { + num_units = ar->max_num_vdevs + 1; + } ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n", diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index b1bec03..b1e4932 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -2377,8 +2377,9 @@ struct wmi_resource_config_10_2 { __le32 feature_mask; } __packed; -#define NUM_UNITS_IS_NUM_VDEVS 0x1 -#define NUM_UNITS_IS_NUM_PEERS 0x2 +#define NUM_UNITS_IS_NUM_VDEVS BIT(0) +#define NUM_UNITS_IS_NUM_PEERS BIT(1) +#define NUM_UNITS_IS_NUM_ACTIVE_PEERS BIT(2) struct wmi_resource_config_10_4 { /* Number of virtual devices (VAPs) to support */ -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH v2 07/10] ath10k: fill 10.4 fw wmi init cmd default values
Define 10.4 wmi init command structure and introduce new function ath10k_wmi_10_4_op_gen_init() to fill default values for each field which goes as part of wmi init cmd to 10.4 firmware. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/core.c | 7 ++ drivers/net/wireless/ath/ath10k/core.h | 2 + drivers/net/wireless/ath/ath10k/hw.h | 54 drivers/net/wireless/ath/ath10k/wmi.c | 83 + drivers/net/wireless/ath/ath10k/wmi.h | 220 + 5 files changed, 366 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 5e8d8af..020ac9f 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -1116,6 +1116,13 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) WMI_STAT_PEER; break; case ATH10K_FW_WMI_OP_VERSION_10_4: + ar->max_num_peers = TARGET_10_4_NUM_PEERS; + ar->max_num_stations = TARGET_10_4_NUM_STATIONS; + ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS; + ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS; + ar->num_tids = TARGET_10_4_TGT_NUM_TIDS; + ar->fw_stats_req_mask = WMI_STAT_PEER; + break; case ATH10K_FW_WMI_OP_VERSION_UNSET: case ATH10K_FW_WMI_OP_VERSION_MAX: WARN_ON(1); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index afd21d5..58b02ae 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -684,6 +684,8 @@ struct ath10k { int max_num_stations; int max_num_vdevs; int max_num_tdls_vdevs; + int num_active_peers; + int num_tids; struct work_struct offchan_tx_work; struct sk_buff_head offchan_tx_queue; diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index b0c89b4..52fc024 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -354,6 +354,60 @@ enum ath10k_hw_rate_cck { #define NUM_TARGET_CE_CONFIG_WLAN ar->hw_values->num_target_ce_config_wlan +/* Target specific defines for 10.4 firmware */ +#define TARGET_10_4_NUM_VDEVS 16 +#define TARGET_10_4_NUM_STATIONS 32 +#define TARGET_10_4_NUM_PEERS ((TARGET_10_4_NUM_STATIONS) + \ +(TARGET_10_4_NUM_VDEVS)) +#define TARGET_10_4_ACTIVE_PEERS 0 +#define TARGET_10_4_NUM_OFFLOAD_PEERS 0 +#define TARGET_10_4_NUM_OFFLOAD_REORDER_BUFFS 0 +#define TARGET_10_4_NUM_PEER_KEYS 2 +#define TARGET_10_4_TGT_NUM_TIDS ((TARGET_10_4_NUM_PEERS) * 2) +#define TARGET_10_4_AST_SKID_LIMIT 32 +#define TARGET_10_4_TX_CHAIN_MASK (BIT(0) | BIT(1) | \ +BIT(2) | BIT(3)) +#define TARGET_10_4_RX_CHAIN_MASK (BIT(0) | BIT(1) | \ +BIT(2) | BIT(3)) + +/* 100 ms for video, best-effort, and background */ +#define TARGET_10_4_RX_TIMEOUT_LO_PRI 100 + +/* 40 ms for voice */ +#define TARGET_10_4_RX_TIMEOUT_HI_PRI 40 + +#define TARGET_10_4_RX_DECAP_MODE ATH10K_HW_TXRX_NATIVE_WIFI +#define TARGET_10_4_SCAN_MAX_REQS 4 +#define TARGET_10_4_BMISS_OFFLOAD_MAX_VDEV 3 +#define TARGET_10_4_ROAM_OFFLOAD_MAX_VDEV 3 +#define TARGET_10_4_ROAM_OFFLOAD_MAX_PROFILES 8 + +/* Note: mcast to ucast is disabled by default */ +#define TARGET_10_4_NUM_MCAST_GROUPS 0 +#define TARGET_10_4_NUM_MCAST_TABLE_ELEMS 0 +#define TARGET_10_4_MCAST2UCAST_MODE 0 + +#define TARGET_10_4_TX_DBG_LOG_SIZE1024 +#define TARGET_10_4_NUM_WDS_ENTRIES32 +#define TARGET_10_4_DMA_BURST_SIZE 1 +#define TARGET_10_4_MAC_AGGR_DELIM 0 +#define TARGET_10_4_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1 +#define TARGET_10_4_VOW_CONFIG 0 +#define TARGET_10_4_GTK_OFFLOAD_MAX_VDEV 3 +#define TARGET_10_4_NUM_MSDU_DESC (1024 + 400) +#define TARGET_10_4_11AC_TX_MAX_FRAGS 2 +#define TARGET_10_4_MAX_PEER_EXT_STATS 16 +#define TARGET_10_4_SMART_ANT_CAP 0 +#define TARGET_10_4_BK_MIN_FREE0 +#define TARGET_10_4_BE_MIN_FREE0 +#define TARGET_10_4_VI_MIN_FREE0 +#define TARGET_10_4_VO_MIN_FREE0 +#define TARGET_10_4_RX_BATCH_MODE 1 +#define TARGET_10_4_THERMAL_THROTTLING_CONFIG 0 +#define TARGET_10_4_ATF_CONFIG 0 +#define TARGET_10_4_IPHDR_PAD_CONFIG 1 +#define TARGET_10_4_QWRAP_CONFIG 0 + /* Number of Copy Engines supported */ #define CE_COUNT ar->hw_values->ce_count diff --g
[PATCH v2 08/10] ath10k: handle 10.4 fw wmi mgmt rx event
10.4 firmware wmi mgmt rx event format differs from non 10.4 firmware and changing existing wmi mgmt rx event parsing function ath10k_wmi_op_pull_mgmt_rx_ev() for 10.4 would add more complex. This patch adds new function to receive any wmi rx event from 10.4 firmware and also introduce new function to parse wmi mgmt rx event. In addition, fw main branch service rdy event parsing function is linked in wmi ops table. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/wmi.c | 64 +++ drivers/net/wireless/ath/ath10k/wmi.h | 15 2 files changed, 79 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 6c51b20..9502032 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2124,6 +2124,40 @@ static int ath10k_wmi_op_pull_mgmt_rx_ev(struct ath10k *ar, struct sk_buff *skb, return 0; } +static int ath10k_wmi_10_4_op_pull_mgmt_rx_ev(struct ath10k *ar, + struct sk_buff *skb, + struct wmi_mgmt_rx_ev_arg *arg) +{ + struct wmi_10_4_mgmt_rx_event *ev; + struct wmi_10_4_mgmt_rx_hdr *ev_hdr; + size_t pull_len; + u32 msdu_len; + + ev = (struct wmi_10_4_mgmt_rx_event *)skb->data; + ev_hdr = &ev->hdr; + pull_len = sizeof(*ev); + + if (skb->len < pull_len) + return -EPROTO; + + skb_pull(skb, pull_len); + arg->channel = ev_hdr->channel; + arg->buf_len = ev_hdr->buf_len; + arg->status = ev_hdr->status; + arg->snr = ev_hdr->snr; + arg->phy_mode = ev_hdr->phy_mode; + arg->rate = ev_hdr->rate; + + msdu_len = __le32_to_cpu(arg->buf_len); + if (skb->len < msdu_len) + return -EPROTO; + + /* Make sure bytes added for padding are removed. */ + skb_trim(skb, msdu_len); + + return 0; +} + int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) { struct wmi_mgmt_rx_ev_arg arg = {}; @@ -4267,6 +4301,33 @@ out: dev_kfree_skb(skb); } +static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) +{ + struct wmi_cmd_hdr *cmd_hdr; + enum wmi_10_4_event_id id; + + cmd_hdr = (struct wmi_cmd_hdr *)skb->data; + id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); + + if (!skb_pull(skb, sizeof(struct wmi_cmd_hdr))) + goto out; + + trace_ath10k_wmi_event(ar, id, skb->data, skb->len); + + switch (id) { + case WMI_10_4_MGMT_RX_EVENTID: + ath10k_wmi_event_mgmt_rx(ar, skb); + /* mgmt_rx() owns the skb now! */ + return; + default: + ath10k_warn(ar, "Unknown eventid: %d\n", id); + break; + } + +out: + dev_kfree_skb(skb); +} + static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) { int ret; @@ -6186,7 +6247,10 @@ static const struct wmi_ops wmi_10_2_4_ops = { }; static const struct wmi_ops wmi_10_4_ops = { + .rx = ath10k_wmi_10_4_op_rx, .map_svc = wmi_10_4_svc_map, + .pull_mgmt_rx = ath10k_wmi_10_4_op_pull_mgmt_rx_ev, + .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev, .gen_init = ath10k_wmi_10_4_op_gen_init, }; diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index dbb9f1c..b1bec03 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -2947,6 +2947,21 @@ struct wmi_mgmt_rx_event_v2 { u8 buf[0]; } __packed; +struct wmi_10_4_mgmt_rx_hdr { + __le32 channel; + __le32 snr; + u8 rssi_ctl[4]; + __le32 rate; + __le32 phy_mode; + __le32 buf_len; + __le32 status; +} __packed; + +struct wmi_10_4_mgmt_rx_event { + struct wmi_10_4_mgmt_rx_hdr hdr; + u8 buf[0]; +} __packed; + #define WMI_RX_STATUS_OK 0x00 #define WMI_RX_STATUS_ERR_CRC 0x01 #define WMI_RX_STATUS_ERR_DECRYPT 0x08 -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH v2 06/10] ath10k: add 10.4 fw wmi pdev cmd ids
Include 10.4 firmware wmi pdev cmd id and prepare wmi vdev map table wmi_10_4_pdev_param_map and update non 10.4 firmware pdev cmd map table with newly added vdev cmd id specifically for 10.4 firmware as unsupported. Signed-off-by: Raja Mani --- v2 changes: - udpated pdev cmd id table based on stable 10.4 firmware. drivers/net/wireless/ath/ath10k/wmi-tlv.c | 42 ++ drivers/net/wireless/ath/ath10k/wmi.c | 228 ++ drivers/net/wireless/ath/ath10k/wmi.h | 136 ++ 3 files changed, 406 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index b2a8e32..620b37b 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -3236,6 +3236,48 @@ static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = { .burst_dur = WMI_TLV_PDEV_PARAM_BURST_DUR, .burst_enable = WMI_TLV_PDEV_PARAM_BURST_ENABLE, .cal_period = WMI_PDEV_PARAM_UNSUPPORTED, + .aggr_burst = WMI_PDEV_PARAM_UNSUPPORTED, + .rx_decap_mode = WMI_PDEV_PARAM_UNSUPPORTED, + .smart_antenna_default_antenna = WMI_PDEV_PARAM_UNSUPPORTED, + .igmpmld_override = WMI_PDEV_PARAM_UNSUPPORTED, + .igmpmld_tid = WMI_PDEV_PARAM_UNSUPPORTED, + .antenna_gain = WMI_PDEV_PARAM_UNSUPPORTED, + .rx_filter = WMI_PDEV_PARAM_UNSUPPORTED, + .set_mcast_to_ucast_tid = WMI_PDEV_PARAM_UNSUPPORTED, + .proxy_sta_mode = WMI_PDEV_PARAM_UNSUPPORTED, + .set_mcast2ucast_mode = WMI_PDEV_PARAM_UNSUPPORTED, + .set_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED, + .remove_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED, + .peer_sta_ps_statechg_enable = WMI_PDEV_PARAM_UNSUPPORTED, + .igmpmld_ac_override = WMI_PDEV_PARAM_UNSUPPORTED, + .block_interbss = WMI_PDEV_PARAM_UNSUPPORTED, + .set_disable_reset_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, + .set_msdu_ttl_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, + .set_ppdu_duration_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, + .txbf_sound_period_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, + .set_promisc_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, + .set_burst_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, + .en_stats = WMI_PDEV_PARAM_UNSUPPORTED, + .mu_group_policy = WMI_PDEV_PARAM_UNSUPPORTED, + .noise_detection = WMI_PDEV_PARAM_UNSUPPORTED, + .noise_threshold = WMI_PDEV_PARAM_UNSUPPORTED, + .dpd_enable = WMI_PDEV_PARAM_UNSUPPORTED, + .set_mcast_bcast_echo = WMI_PDEV_PARAM_UNSUPPORTED, + .atf_strict_sch = WMI_PDEV_PARAM_UNSUPPORTED, + .atf_sched_duration = WMI_PDEV_PARAM_UNSUPPORTED, + .ant_plzn = WMI_PDEV_PARAM_UNSUPPORTED, + .mgmt_retry_limit = WMI_PDEV_PARAM_UNSUPPORTED, + .sensitivity_level = WMI_PDEV_PARAM_UNSUPPORTED, + .signed_txpower_2g = WMI_PDEV_PARAM_UNSUPPORTED, + .signed_txpower_5g = WMI_PDEV_PARAM_UNSUPPORTED, + .enable_per_tid_amsdu = WMI_PDEV_PARAM_UNSUPPORTED, + .enable_per_tid_ampdu = WMI_PDEV_PARAM_UNSUPPORTED, + .cca_threshold = WMI_PDEV_PARAM_UNSUPPORTED, + .rts_fixed_rate = WMI_PDEV_PARAM_UNSUPPORTED, + .pdev_reset = WMI_PDEV_PARAM_UNSUPPORTED, + .wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED, + .arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED, + .arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED, }; static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = { diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 087dea8..3f29886 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1053,6 +1053,48 @@ static struct wmi_pdev_param_map wmi_pdev_param_map = { .burst_dur = WMI_PDEV_PARAM_UNSUPPORTED, .burst_enable = WMI_PDEV_PARAM_UNSUPPORTED, .cal_period = WMI_PDEV_PARAM_UNSUPPORTED, + .aggr_burst = WMI_PDEV_PARAM_UNSUPPORTED, + .rx_decap_mode = WMI_PDEV_PARAM_UNSUPPORTED, + .smart_antenna_default_antenna = WMI_PDEV_PARAM_UNSUPPORTED, + .igmpmld_override = WMI_PDEV_PARAM_UNSUPPORTED, + .igmpmld_tid = WMI_PDEV_PARAM_UNSUPPORTED, + .antenna_gain = WMI_PDEV_PARAM_UNSUPPORTED, + .rx_filter = WMI_PDEV_PARAM_UNSUPPORTED, + .set_mcast_to_ucast_tid = WMI_PDEV_PARAM_UNSUPPORTED, + .proxy_sta_mode = WMI_PDEV_PARAM_UNSUPPORTED, + .set_mcast2ucast_mode = WMI_PDEV_PARAM_UNSUPPORTED, + .set_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED, + .remove_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED, + .peer_sta_ps_statechg_enable = WMI_PDEV_PARAM_UNSUPPORTED, + .igmpmld_ac_override = WMI_PDEV_PARAM_UNSUPPORTED, + .block_interbss = WMI_PDEV_PARAM_UNSUPPORTED, + .set_disable_reset_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, + .set_msdu_ttl_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, + .set_ppdu_duration_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, + .txbf_sound_period_cmdid = W
[PATCH v2 03/10] ath10k: include 10.4 fw specific wmi cmd and event ids
10.4 firmware wmi cmd and event id values are not exactly aligned with previous firmware versions (main, 10.x, 10.2, etc). Add new enum to define wmi cmd & event definitions for 10.4 firmware and prepare wmi_10_4_cmd_map based on 10.4 firmware wmi cmd definitions. wmi_cmd_map is extended to accommodate new wmi commands which are exclusively available in 10.4 firmware. Signed-off-by: Raja Mani --- v2 changes: - updated wmi cmd/event ids based on stable 10.4 firmware. drivers/net/wireless/ath/ath10k/wmi.c | 184 + drivers/net/wireless/ath/ath10k/wmi.h | 252 ++ 2 files changed, 436 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 52493d1..8dc937d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -395,6 +395,189 @@ static struct wmi_cmd_map wmi_10_2_4_cmd_map = { .pdev_get_temperature_cmdid = WMI_10_2_PDEV_GET_TEMPERATURE_CMDID, }; +/* 10.4 WMI cmd track */ +static struct wmi_cmd_map wmi_10_4_cmd_map = { + .init_cmdid = WMI_10_4_INIT_CMDID, + .start_scan_cmdid = WMI_10_4_START_SCAN_CMDID, + .stop_scan_cmdid = WMI_10_4_STOP_SCAN_CMDID, + .scan_chan_list_cmdid = WMI_10_4_SCAN_CHAN_LIST_CMDID, + .scan_sch_prio_tbl_cmdid = WMI_10_4_SCAN_SCH_PRIO_TBL_CMDID, + .pdev_set_regdomain_cmdid = WMI_10_4_PDEV_SET_REGDOMAIN_CMDID, + .pdev_set_channel_cmdid = WMI_10_4_PDEV_SET_CHANNEL_CMDID, + .pdev_set_param_cmdid = WMI_10_4_PDEV_SET_PARAM_CMDID, + .pdev_pktlog_enable_cmdid = WMI_10_4_PDEV_PKTLOG_ENABLE_CMDID, + .pdev_pktlog_disable_cmdid = WMI_10_4_PDEV_PKTLOG_DISABLE_CMDID, + .pdev_set_wmm_params_cmdid = WMI_10_4_PDEV_SET_WMM_PARAMS_CMDID, + .pdev_set_ht_cap_ie_cmdid = WMI_10_4_PDEV_SET_HT_CAP_IE_CMDID, + .pdev_set_vht_cap_ie_cmdid = WMI_10_4_PDEV_SET_VHT_CAP_IE_CMDID, + .pdev_set_dscp_tid_map_cmdid = WMI_10_4_PDEV_SET_DSCP_TID_MAP_CMDID, + .pdev_set_quiet_mode_cmdid = WMI_10_4_PDEV_SET_QUIET_MODE_CMDID, + .pdev_green_ap_ps_enable_cmdid = WMI_10_4_PDEV_GREEN_AP_PS_ENABLE_CMDID, + .pdev_get_tpc_config_cmdid = WMI_10_4_PDEV_GET_TPC_CONFIG_CMDID, + .pdev_set_base_macaddr_cmdid = WMI_10_4_PDEV_SET_BASE_MACADDR_CMDID, + .vdev_create_cmdid = WMI_10_4_VDEV_CREATE_CMDID, + .vdev_delete_cmdid = WMI_10_4_VDEV_DELETE_CMDID, + .vdev_start_request_cmdid = WMI_10_4_VDEV_START_REQUEST_CMDID, + .vdev_restart_request_cmdid = WMI_10_4_VDEV_RESTART_REQUEST_CMDID, + .vdev_up_cmdid = WMI_10_4_VDEV_UP_CMDID, + .vdev_stop_cmdid = WMI_10_4_VDEV_STOP_CMDID, + .vdev_down_cmdid = WMI_10_4_VDEV_DOWN_CMDID, + .vdev_set_param_cmdid = WMI_10_4_VDEV_SET_PARAM_CMDID, + .vdev_install_key_cmdid = WMI_10_4_VDEV_INSTALL_KEY_CMDID, + .peer_create_cmdid = WMI_10_4_PEER_CREATE_CMDID, + .peer_delete_cmdid = WMI_10_4_PEER_DELETE_CMDID, + .peer_flush_tids_cmdid = WMI_10_4_PEER_FLUSH_TIDS_CMDID, + .peer_set_param_cmdid = WMI_10_4_PEER_SET_PARAM_CMDID, + .peer_assoc_cmdid = WMI_10_4_PEER_ASSOC_CMDID, + .peer_add_wds_entry_cmdid = WMI_10_4_PEER_ADD_WDS_ENTRY_CMDID, + .peer_remove_wds_entry_cmdid = WMI_10_4_PEER_REMOVE_WDS_ENTRY_CMDID, + .peer_mcast_group_cmdid = WMI_10_4_PEER_MCAST_GROUP_CMDID, + .bcn_tx_cmdid = WMI_10_4_BCN_TX_CMDID, + .pdev_send_bcn_cmdid = WMI_10_4_PDEV_SEND_BCN_CMDID, + .bcn_tmpl_cmdid = WMI_10_4_BCN_PRB_TMPL_CMDID, + .bcn_filter_rx_cmdid = WMI_10_4_BCN_FILTER_RX_CMDID, + .prb_req_filter_rx_cmdid = WMI_10_4_PRB_REQ_FILTER_RX_CMDID, + .mgmt_tx_cmdid = WMI_10_4_MGMT_TX_CMDID, + .prb_tmpl_cmdid = WMI_10_4_PRB_TMPL_CMDID, + .addba_clear_resp_cmdid = WMI_10_4_ADDBA_CLEAR_RESP_CMDID, + .addba_send_cmdid = WMI_10_4_ADDBA_SEND_CMDID, + .addba_status_cmdid = WMI_10_4_ADDBA_STATUS_CMDID, + .delba_send_cmdid = WMI_10_4_DELBA_SEND_CMDID, + .addba_set_resp_cmdid = WMI_10_4_ADDBA_SET_RESP_CMDID, + .send_singleamsdu_cmdid = WMI_10_4_SEND_SINGLEAMSDU_CMDID, + .sta_powersave_mode_cmdid = WMI_10_4_STA_POWERSAVE_MODE_CMDID, + .sta_powersave_param_cmdid = WMI_10_4_STA_POWERSAVE_PARAM_CMDID, + .sta_mimo_ps_mode_cmdid = WMI_10_4_STA_MIMO_PS_MODE_CMDID, + .pdev_dfs_enable_cmdid = WMI_10_4_PDEV_DFS_ENABLE_CMDID, + .pdev_dfs_disable_cmdid = WMI_10_4_PDEV_DFS_DISABLE_CMDID, + .roam_scan_mode = WMI_10_4_ROAM_SCAN_MODE, + .roam_scan_rssi_threshold = WMI_10_4_ROAM_SCAN_RSSI_THRESHOLD, + .roam_scan_period = WMI_10_4_ROAM_SCAN_PERIOD, + .roam_scan_rssi_change_threshold = + WMI_10_4_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, + .roam_ap_profile = WMI_10_4_ROAM_AP_PROFILE, + .ofl_scan_add_ap_profile = WMI_10_4_OFL_SCAN_ADD_AP_PROFILE, + .ofl_scan_remove_ap_profile = WMI_10_4_OFL_SCAN_REMOVE_AP_PROFILE, + .ofl_scan_perio
[PATCH v2 04/10] ath10k: set 10.4 fw exclusive wmi cmd as unsupported for other fw versions
In fact, explicit assigned to ZERO for unsupported wmi commands are not really needed. Global static variable will have ZERO by default. However, just for better readability setting all wmi cmds in non 10.4 firmware wmi mapping table as unsupported for wmi cmd which are exclusively available only in 10.4 firmware. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 32 ++ drivers/net/wireless/ath/ath10k/wmi.c | 158 ++ 2 files changed, 190 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 8fdba38..7e75dec 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -3151,6 +3151,38 @@ static struct wmi_cmd_map wmi_tlv_cmd_map = { .tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID, .tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID, .adaptive_qcs_cmdid = WMI_TLV_RESMGR_ADAPTIVE_OCS_CMDID, + .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED, + .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED, + .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED, + .wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED, + .wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED, + .wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED, + .wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED, + .peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED, + .peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED, + .rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED, + .oem_req_cmdid = WMI_CMD_UNSUPPORTED, + .nan_cmdid = WMI_CMD_UNSUPPORTED, + .vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED, + .qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED, + .peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED, + .peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED, + .peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_fips_cmdid = WMI_CMD_UNSUPPORTED, + .tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED, + .fwtest_cmdid = WMI_CMD_UNSUPPORTED, + .vdev_atf_request_cmdid = WMI_CMD_UNSUPPORTED, + .peer_atf_request_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED, }; static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = { diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 8dc937d..a58ddb7 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -148,6 +148,48 @@ static struct wmi_cmd_map wmi_cmd_map = { .gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID, .gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID, .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED, + .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED, + .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED, + .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED, + .wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED, + .wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED, + .wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED, + .wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED, + .peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED, + .peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED, + .rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED, + .oem_req_cmdid = WMI_CMD_UNSUPPORTED, + .nan_cmdid = WMI_CMD_UNSUPPORTED, + .vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED, + .qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED, + .peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED, + .peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED, + .peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_fips_cmdid = WMI_CMD_UNSUPPORTED, + .tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED, + .fwtest_cmd
[PATCH v2 05/10] ath10k: add 10.4 fw wmi vdev cmd ids
Include 10.4 firmware wmi vdev cmd id and make up wmi vdev map table wmi_10_4_vdev_param_map and also update non 10.4 firmware vdev cmd map table with newly added vdev cmd id specifically for 10.4 firmware as unsupported. Signed-off-by: Raja Mani --- v2 changes: - udpated vdev cmd id table based on stable 10.4 firmware. drivers/net/wireless/ath/ath10k/wmi-tlv.c | 16 drivers/net/wireless/ath/ath10k/wmi.c | 124 ++ drivers/net/wireless/ath/ath10k/wmi.h | 85 3 files changed, 225 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 7e75dec..b2a8e32 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -3294,6 +3294,22 @@ static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = { .tx_encap_type = WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE, .ap_detect_out_of_sync_sleeping_sta_time_secs = WMI_TLV_VDEV_PARAM_UNSUPPORTED, + .rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED, + .cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED, + .mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED, + .rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED, + .vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED, + .vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED, + .proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED, + .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, + .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, + .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, }; static const struct wmi_ops wmi_tlv_ops = { diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index a58ddb7..087dea8 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -761,6 +761,22 @@ static struct wmi_vdev_param_map wmi_vdev_param_map = { .tx_encap_type = WMI_VDEV_PARAM_TX_ENCAP_TYPE, .ap_detect_out_of_sync_sleeping_sta_time_secs = WMI_VDEV_PARAM_UNSUPPORTED, + .rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED, + .cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED, + .mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED, + .rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED, + .vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED, + .vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED, + .proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED, + .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, + .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, + .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, }; /* 10.X WMI VDEV param map */ @@ -820,6 +836,22 @@ static struct wmi_vdev_param_map wmi_10x_vdev_param_map = { .tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED, .ap_detect_out_of_sync_sleeping_sta_time_secs = WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, + .rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED, + .cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED, + .mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED, + .rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED, + .vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED, + .vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED, + .early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED, + .proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED, + .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, + .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, + .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, }; static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = { @@ -878,6 +910,97 @@ static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = { .tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED, .ap_detect_out_of_sync_sleeping_sta_time_secs = WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, + .rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED, + .cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED,
[PATCH v2 01/10] ath10k: include new wmi op version for 10.4 fw
qca99X0 chip uses firmware version 10.4. Define a new macro ATH10K_FW_WMI_OP_VERSION_10_4 for 10.4 firmware and include in switch cases where ATH10K_FW_WMI_OP_VERSION_* is used to avoid compilation error. Signed-off-by: Raja Mani --- drivers/net/wireless/ath/ath10k/core.c | 2 ++ drivers/net/wireless/ath/ath10k/hw.h | 1 + drivers/net/wireless/ath/ath10k/mac.c | 2 ++ drivers/net/wireless/ath/ath10k/wmi.c | 2 ++ 4 files changed, 7 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 80f38b5..5e8d8af 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -1115,6 +1115,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV | WMI_STAT_PEER; break; + case ATH10K_FW_WMI_OP_VERSION_10_4: case ATH10K_FW_WMI_OP_VERSION_UNSET: case ATH10K_FW_WMI_OP_VERSION_MAX: WARN_ON(1); @@ -1137,6 +1138,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) case ATH10K_FW_WMI_OP_VERSION_TLV: ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_TLV; break; + case ATH10K_FW_WMI_OP_VERSION_10_4: case ATH10K_FW_WMI_OP_VERSION_UNSET: case ATH10K_FW_WMI_OP_VERSION_MAX: WARN_ON(1); diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 3e27781..b0c89b4 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -137,6 +137,7 @@ enum ath10k_fw_wmi_op_version { ATH10K_FW_WMI_OP_VERSION_10_2 = 3, ATH10K_FW_WMI_OP_VERSION_TLV = 4, ATH10K_FW_WMI_OP_VERSION_10_2_4 = 5, + ATH10K_FW_WMI_OP_VERSION_10_4 = 6, /* keep last */ ATH10K_FW_WMI_OP_VERSION_MAX, diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 2ec2b0b..f9989d1 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -6943,6 +6943,8 @@ int ath10k_mac_register(struct ath10k *ar) ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ath10k_10x_if_comb); break; + case ATH10K_FW_WMI_OP_VERSION_10_4: + break; case ATH10K_FW_WMI_OP_VERSION_UNSET: case ATH10K_FW_WMI_OP_VERSION_MAX: WARN_ON(1); diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 6c046c2..b32bb68 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -5415,6 +5415,8 @@ static const struct wmi_ops wmi_10_2_4_ops = { int ath10k_wmi_attach(struct ath10k *ar) { switch (ar->wmi.op_version) { + case ATH10K_FW_WMI_OP_VERSION_10_4: + break; case ATH10K_FW_WMI_OP_VERSION_10_2_4: ar->wmi.cmd = &wmi_10_2_4_cmd_map; ar->wmi.ops = &wmi_10_2_4_ops; -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH v2 02/10] ath10k: add 10.4 fw wmi service bitmap definition
Include new enum to define wmi service bitmap definitions for 10.4 firmware and a function wmi_10_4_svc_map() to remap 10.4 firmware wmi service bitmap definitions to ath10k generic wmi services. Signed-off-by: Raja Mani --- v2 changes: - updated wmi service ids based on stable 10.4 firmware. drivers/net/wireless/ath/ath10k/wmi.c | 5 ++ drivers/net/wireless/ath/ath10k/wmi.h | 146 ++ 2 files changed, 151 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index b32bb68..52493d1 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -5412,10 +5412,15 @@ static const struct wmi_ops wmi_10_2_4_ops = { /* .gen_adaptive_qcs not implemented */ }; +static const struct wmi_ops wmi_10_4_ops = { + .map_svc = wmi_10_4_svc_map, +}; + int ath10k_wmi_attach(struct ath10k *ar) { switch (ar->wmi.op_version) { case ATH10K_FW_WMI_OP_VERSION_10_4: + ar->wmi.ops = &wmi_10_4_ops; break; case ATH10K_FW_WMI_OP_VERSION_10_2_4: ar->wmi.cmd = &wmi_10_2_4_cmd_map; diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index cf44a3d..b54d14b 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -150,6 +150,12 @@ enum wmi_service { WMI_SERVICE_SAP_AUTH_OFFLOAD, WMI_SERVICE_ATF, WMI_SERVICE_COEX_GPIO, + WMI_SERVICE_ENHANCED_PROXY_STA, + WMI_SERVICE_TT, + WMI_SERVICE_PEER_CACHING, + WMI_SERVICE_AUX_SPECTRAL_INTF, + WMI_SERVICE_AUX_CHAN_LOAD_INTF, + WMI_SERVICE_BSS_CHANNEL_INFO_64, /* keep last */ WMI_SERVICE_MAX, @@ -218,6 +224,51 @@ enum wmi_main_service { WMI_MAIN_SERVICE_TX_ENCAP, }; +enum wmi_10_4_service { + WMI_10_4_SERVICE_BEACON_OFFLOAD = 0, + WMI_10_4_SERVICE_SCAN_OFFLOAD, + WMI_10_4_SERVICE_ROAM_OFFLOAD, + WMI_10_4_SERVICE_BCN_MISS_OFFLOAD, + WMI_10_4_SERVICE_STA_PWRSAVE, + WMI_10_4_SERVICE_STA_ADVANCED_PWRSAVE, + WMI_10_4_SERVICE_AP_UAPSD, + WMI_10_4_SERVICE_AP_DFS, + WMI_10_4_SERVICE_11AC, + WMI_10_4_SERVICE_BLOCKACK, + WMI_10_4_SERVICE_PHYERR, + WMI_10_4_SERVICE_BCN_FILTER, + WMI_10_4_SERVICE_RTT, + WMI_10_4_SERVICE_RATECTRL, + WMI_10_4_SERVICE_WOW, + WMI_10_4_SERVICE_RATECTRL_CACHE, + WMI_10_4_SERVICE_IRAM_TIDS, + WMI_10_4_SERVICE_BURST, + WMI_10_4_SERVICE_SMART_ANTENNA_SW_SUPPORT, + WMI_10_4_SERVICE_GTK_OFFLOAD, + WMI_10_4_SERVICE_SCAN_SCH, + WMI_10_4_SERVICE_CSA_OFFLOAD, + WMI_10_4_SERVICE_CHATTER, + WMI_10_4_SERVICE_COEX_FREQAVOID, + WMI_10_4_SERVICE_PACKET_POWER_SAVE, + WMI_10_4_SERVICE_FORCE_FW_HANG, + WMI_10_4_SERVICE_SMART_ANTENNA_HW_SUPPORT, + WMI_10_4_SERVICE_GPIO, + WMI_10_4_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, + WMI_10_4_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, + WMI_10_4_SERVICE_STA_KEEP_ALIVE, + WMI_10_4_SERVICE_TX_ENCAP, + WMI_10_4_SERVICE_AP_PS_DETECT_OUT_OF_SYNC, + WMI_10_4_SERVICE_EARLY_RX, + WMI_10_4_SERVICE_ENHANCED_PROXY_STA, + WMI_10_4_SERVICE_TT, + WMI_10_4_SERVICE_ATF, + WMI_10_4_SERVICE_PEER_CACHING, + WMI_10_4_SERVICE_COEX_GPIO, + WMI_10_4_SERVICE_AUX_SPECTRAL_INTF, + WMI_10_4_SERVICE_AUX_CHAN_LOAD_INTF, + WMI_10_4_SERVICE_BSS_CHANNEL_INFO_64, +}; + static inline char *wmi_service_name(int service_id) { #define SVCSTR(x) case x: return #x @@ -299,6 +350,12 @@ static inline char *wmi_service_name(int service_id) SVCSTR(WMI_SERVICE_SAP_AUTH_OFFLOAD); SVCSTR(WMI_SERVICE_ATF); SVCSTR(WMI_SERVICE_COEX_GPIO); + SVCSTR(WMI_SERVICE_ENHANCED_PROXY_STA); + SVCSTR(WMI_SERVICE_TT); + SVCSTR(WMI_SERVICE_PEER_CACHING); + SVCSTR(WMI_SERVICE_AUX_SPECTRAL_INTF); + SVCSTR(WMI_SERVICE_AUX_CHAN_LOAD_INTF); + SVCSTR(WMI_SERVICE_BSS_CHANNEL_INFO_64); default: return NULL; } @@ -437,6 +494,95 @@ static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out, WMI_SERVICE_TX_ENCAP, len); } +static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out, + size_t len) +{ + SVCMAP(WMI_10_4_SERVICE_BEACON_OFFLOAD, + WMI_SERVICE_BEACON_OFFLOAD, len); + SVCMAP(WMI_10_4_SERVICE_SCAN_OFFLOAD, + WMI_SERVICE_SCAN_OFFLOAD, len); + SVCMAP(WMI_10_4_SERVICE_ROAM_OFFLOAD, + WMI_SERVICE_ROAM_OFFLOAD, len); + SVCMAP(WMI_10_4_SERVICE_BCN_MISS_OFFLOAD, + WMI_SERVICE_BCN_MISS_OFFLOAD, len); + SVCMAP(WMI_10_4_SERVICE_STA_PWRSAVE, + WMI_SERVICE_STA_PWRSAVE, len); + SVCMAP(WMI_10_4_SERVICE_STA_ADVANCED_PWRSAVE, + WMI_SERVICE_STA_ADVANCED_PWR
[PATCH v2 00/10] introduce wmi support for qca99X0
qca99X0 uses 10.4 firmware. This patch series adds 10.4 firmware specific WMI cmds/events/parsing logic. All these patches tested on top of qca99X0 initial bring up patches. v2 changes: - Synced wmi service/cmd/event/pdev/vdev ids to most stable 10.4 firmware. Raja Mani (10): ath10k: include new wmi op version for 10.4 fw ath10k: add 10.4 fw wmi service bitmap definition ath10k: include 10.4 fw specific wmi cmd and event ids ath10k: set 10.4 fw exclusive wmi cmd as unsupported for other fw versions ath10k: add 10.4 fw wmi vdev cmd ids ath10k: add 10.4 fw wmi pdev cmd ids ath10k: fill 10.4 fw wmi init cmd default values ath10k: handle 10.4 fw wmi mgmt rx event ath10k: adjust default peer limits if qcache enabled in 10.4 fw ath10k: handle 10.4 fw wmi ready event drivers/net/wireless/ath/ath10k/core.c| 9 + drivers/net/wireless/ath/ath10k/core.h| 2 + drivers/net/wireless/ath/ath10k/hw.h | 61 +++ drivers/net/wireless/ath/ath10k/mac.c | 2 + drivers/net/wireless/ath/ath10k/wmi-tlv.c | 90 +++ drivers/net/wireless/ath/ath10k/wmi.c | 879 +- drivers/net/wireless/ath/ath10k/wmi.h | 859 - 7 files changed, 1896 insertions(+), 6 deletions(-) -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: [PATCH 1/3] ath9k: handle RoC abort correctly
On Mon, Jun 22, 2015 at 6:32 PM, Michal Kazior wrote: > On 22 June 2015 at 13:56, Krishna Chaitanya wrote: >> On Mon, Jun 22, 2015 at 5:13 PM, Janusz Dziedzic >> wrote: >>> In case we will get ROC abort we should not call >>> ieee80211_remain_on_channel_expired(). >>> >>> In other case I hit such warning on MIPS and >>> p2p negotiation failed (tested with use_chanctx=1). >>> >>> ath: phy0: Starting RoC period >>> ath: phy0: Channel definition created: 2412 MHz >>> ath: phy0: Assigned next_chan to 2412 MHz >>> ath: phy0: Offchannel duration for chan 2412 MHz : 506632 >>> ath: phy0: ath_chanctx_set_next: current: 2412 MHz, next: 2412 MHz >>> ath: phy0: Stopping current chanctx: 2412 >>> ath: phy0: Flush timeout: 200 >>> ath: phy0: ath_chanctx_set_next: Set channel 2412 MHz >>> ath: phy0: Set channel: 2412 MHz width: 0 >>> ath: phy0: Reset to 2412 MHz, HT40: 0 fastcc: 0 >>> ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_TSF_TIMER, state: >>> ATH_CHANCTX_STATE_IDLE >>> ath: phy0: ath_offchannel_channel_change: offchannel state: >>> ATH_OFFCHANNEL_ROC_START >>> ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_SWITCH, state: >>> ATH_CHANCTX_STATE_IDLE >>> ath: phy0: Cancel RoC >>> ath: phy0: RoC aborted >>> ath: phy0: RoC request on vif: 00:03:7f:4e:a0:cd, type: 1 duration: 500 >>> ath: phy0: Starting RoC period >>> ath: phy0: Channel definition created: 2412 MHz >>> ath: phy0: Assigned next_chan to 2412 MHz >>> ath: phy0: Offchannel duration for chan 2412 MHz : 506705 >>> ath: phy0: ath_chanctx_set_next: current: 2412 MHz, next: 2412 MHz >>> ath: phy0: ath_offchannel_channel_change: offchannel state: >>> ATH_OFFCHANNEL_ROC_START >>> ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_SWITCH, state: >>> ATH_CHANCTX_STATE_IDLE >>> [ cut here ] >>> WARNING: CPU: 0 PID: 3312 at drivers/net/wireless/ath/ath9k/main.c:2319 >>> Modules linked in: ath9k ath9k_common ath9k_hw ath mac80211 cfg80211 >>> >>> Signed-off-by: Janusz Dziedzic >>> --- >>> drivers/net/wireless/ath/ath9k/channel.c | 3 ++- >>> 1 file changed, 2 insertions(+), 1 deletion(-) >>> >>> diff --git a/drivers/net/wireless/ath/ath9k/channel.c >>> b/drivers/net/wireless/ath/ath9k/channel.c >>> index 2066650..e211325 100644 >>> --- a/drivers/net/wireless/ath/ath9k/channel.c >>> +++ b/drivers/net/wireless/ath/ath9k/channel.c >>> @@ -926,7 +926,8 @@ void ath_roc_complete(struct ath_softc *sc, bool abort) >>> >>> sc->offchannel.roc_vif = NULL; >>> sc->offchannel.roc_chan = NULL; >>> - ieee80211_remain_on_channel_expired(sc->hw); >>> + if (!abort) >>> + ieee80211_remain_on_channel_expired(sc->hw); >>> ath_offchannel_next(sc); >>> ath9k_ps_restore(sc); >>> } >> If HW aborts RoC in middle, should not we inform mac80211 >> that RoC is expired? > > Good point. The ath_roc_complete() can be called with abort=true from > ath9k_cancel_pending_offchannel() as well. I guess ath_roc_complete() > needs a "reason" argument (instead of "abort") with: expired, aborted, > cancelled values. ieee80211_remain_on_channel_expired() should be > called whenever reason != cancelled. Agree, make sense. > By the way - is ath_roc_complete() lock protected properly? It looks > like it isn't from a quick glance. Neither sdata lock nor local->mtx > can be implied in all contexts and sc->mutex isn't always held while > it's called, hmm.. or am I missing something? > >> Also the we are clearing roc_vif independent of abort, so the warning >> indicates that roc_complete has not come from FW, may be we should >> understand that first? > > There's no FW in ath9k. > > The problem is the following sequence: > 1. mac80211 requests roc A > 2. mac80211 cancels roc A >a. ath9k calls expired() and hw_roc_done work is scheduled > 3. mac80211 requests roc B > 4. mac80211 starts to process the scheduled hw_roc_done > 5. mac80211 thinks roc B has expired > 6. mac80211 requests roc C > 7. ath9k WARN_ON is hit > > There's a race between (3) and (4). Depending on circumstances (3) and > (4) may be reordered so the current code doesn't fail all the time. Ok i understand, but if we get roc_complete for B before 6, then it works fine at least at ath9k level, C will be unblocked. Anyways, handling the cancel case should resolve it along with proper locking. -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH] staging: wilc1000: host_interface: add spaces around '='
Fix coding style error by placing spaces around '=' as suggested by checkpatch.pl script. Signed-off-by: Sunil Shahu --- drivers/staging/wilc1000/host_interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 6b10bbb..d1fe73d 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -7945,8 +7945,8 @@ s32 host_int_get_ipaddress(WILC_WFIDrvHandle hWFIDrv, u8 *u16ipadd, u8 idx) strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_IPADDRESS; strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr = u16ipadd; - strHostIFmsg.drvHandler=hWFIDrv; - strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx= idx; + strHostIFmsg.drvHandler = hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx = idx; s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NULL); if (s32Error) { -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: [PATCH 1/3] ath9k: handle RoC abort correctly
On 22 June 2015 at 13:56, Krishna Chaitanya wrote: > On Mon, Jun 22, 2015 at 5:13 PM, Janusz Dziedzic > wrote: >> In case we will get ROC abort we should not call >> ieee80211_remain_on_channel_expired(). >> >> In other case I hit such warning on MIPS and >> p2p negotiation failed (tested with use_chanctx=1). >> >> ath: phy0: Starting RoC period >> ath: phy0: Channel definition created: 2412 MHz >> ath: phy0: Assigned next_chan to 2412 MHz >> ath: phy0: Offchannel duration for chan 2412 MHz : 506632 >> ath: phy0: ath_chanctx_set_next: current: 2412 MHz, next: 2412 MHz >> ath: phy0: Stopping current chanctx: 2412 >> ath: phy0: Flush timeout: 200 >> ath: phy0: ath_chanctx_set_next: Set channel 2412 MHz >> ath: phy0: Set channel: 2412 MHz width: 0 >> ath: phy0: Reset to 2412 MHz, HT40: 0 fastcc: 0 >> ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_TSF_TIMER, state: >> ATH_CHANCTX_STATE_IDLE >> ath: phy0: ath_offchannel_channel_change: offchannel state: >> ATH_OFFCHANNEL_ROC_START >> ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_SWITCH, state: >> ATH_CHANCTX_STATE_IDLE >> ath: phy0: Cancel RoC >> ath: phy0: RoC aborted >> ath: phy0: RoC request on vif: 00:03:7f:4e:a0:cd, type: 1 duration: 500 >> ath: phy0: Starting RoC period >> ath: phy0: Channel definition created: 2412 MHz >> ath: phy0: Assigned next_chan to 2412 MHz >> ath: phy0: Offchannel duration for chan 2412 MHz : 506705 >> ath: phy0: ath_chanctx_set_next: current: 2412 MHz, next: 2412 MHz >> ath: phy0: ath_offchannel_channel_change: offchannel state: >> ATH_OFFCHANNEL_ROC_START >> ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_SWITCH, state: >> ATH_CHANCTX_STATE_IDLE >> [ cut here ] >> WARNING: CPU: 0 PID: 3312 at drivers/net/wireless/ath/ath9k/main.c:2319 >> Modules linked in: ath9k ath9k_common ath9k_hw ath mac80211 cfg80211 >> >> Signed-off-by: Janusz Dziedzic >> --- >> drivers/net/wireless/ath/ath9k/channel.c | 3 ++- >> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/net/wireless/ath/ath9k/channel.c >> b/drivers/net/wireless/ath/ath9k/channel.c >> index 2066650..e211325 100644 >> --- a/drivers/net/wireless/ath/ath9k/channel.c >> +++ b/drivers/net/wireless/ath/ath9k/channel.c >> @@ -926,7 +926,8 @@ void ath_roc_complete(struct ath_softc *sc, bool abort) >> >> sc->offchannel.roc_vif = NULL; >> sc->offchannel.roc_chan = NULL; >> - ieee80211_remain_on_channel_expired(sc->hw); >> + if (!abort) >> + ieee80211_remain_on_channel_expired(sc->hw); >> ath_offchannel_next(sc); >> ath9k_ps_restore(sc); >> } > If HW aborts RoC in middle, should not we inform mac80211 > that RoC is expired? Good point. The ath_roc_complete() can be called with abort=true from ath9k_cancel_pending_offchannel() as well. I guess ath_roc_complete() needs a "reason" argument (instead of "abort") with: expired, aborted, cancelled values. ieee80211_remain_on_channel_expired() should be called whenever reason != cancelled. By the way - is ath_roc_complete() lock protected properly? It looks like it isn't from a quick glance. Neither sdata lock nor local->mtx can be implied in all contexts and sc->mutex isn't always held while it's called, hmm.. or am I missing something? > Also the we are clearing roc_vif independent of abort, so the warning > indicates that roc_complete has not come from FW, may be we should > understand that first? There's no FW in ath9k. The problem is the following sequence: 1. mac80211 requests roc A 2. mac80211 cancels roc A a. ath9k calls expired() and hw_roc_done work is scheduled 3. mac80211 requests roc B 4. mac80211 starts to process the scheduled hw_roc_done 5. mac80211 thinks roc B has expired 6. mac80211 requests roc C 7. ath9k WARN_ON is hit There's a race between (3) and (4). Depending on circumstances (3) and (4) may be reordered so the current code doesn't fail all the time. Michał -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: [PATCH 2/3] ath9k: make rxfilter per HW
On Mon, 2015-06-22 at 13:58 +0200, Johannes Berg wrote: > On Mon, 2015-06-22 at 13:43 +0200, Janusz Dziedzic wrote: > > mac80211 configure rxfilter per HW, > > so we don't need this per channel. > > As I said before, I think there's value in mac80211 doing it per chanctx > or even per vif, and it should be more efficient to do so. > > It's tempting to do it per vif and leave the chanctx work up to the > driver, but perhaps with CSA and all that it gets complicated enough > that doing it per chanctx in mac80211 would make sense? On the other hand, I think our device requires it per vif, so we'd probably have to do both. +Andrei, who was looking into this. johannes -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: [PATCH 2/3] ath9k: make rxfilter per HW
On Mon, 2015-06-22 at 13:43 +0200, Janusz Dziedzic wrote: > mac80211 configure rxfilter per HW, > so we don't need this per channel. As I said before, I think there's value in mac80211 doing it per chanctx or even per vif, and it should be more efficient to do so. It's tempting to do it per vif and leave the chanctx work up to the driver, but perhaps with CSA and all that it gets complicated enough that doing it per chanctx in mac80211 would make sense? johannes -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: [PATCH 1/3] ath9k: handle RoC abort correctly
On Mon, Jun 22, 2015 at 5:13 PM, Janusz Dziedzic wrote: > In case we will get ROC abort we should not call > ieee80211_remain_on_channel_expired(). > > In other case I hit such warning on MIPS and > p2p negotiation failed (tested with use_chanctx=1). > > ath: phy0: Starting RoC period > ath: phy0: Channel definition created: 2412 MHz > ath: phy0: Assigned next_chan to 2412 MHz > ath: phy0: Offchannel duration for chan 2412 MHz : 506632 > ath: phy0: ath_chanctx_set_next: current: 2412 MHz, next: 2412 MHz > ath: phy0: Stopping current chanctx: 2412 > ath: phy0: Flush timeout: 200 > ath: phy0: ath_chanctx_set_next: Set channel 2412 MHz > ath: phy0: Set channel: 2412 MHz width: 0 > ath: phy0: Reset to 2412 MHz, HT40: 0 fastcc: 0 > ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_TSF_TIMER, state: > ATH_CHANCTX_STATE_IDLE > ath: phy0: ath_offchannel_channel_change: offchannel state: > ATH_OFFCHANNEL_ROC_START > ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_SWITCH, state: > ATH_CHANCTX_STATE_IDLE > ath: phy0: Cancel RoC > ath: phy0: RoC aborted > ath: phy0: RoC request on vif: 00:03:7f:4e:a0:cd, type: 1 duration: 500 > ath: phy0: Starting RoC period > ath: phy0: Channel definition created: 2412 MHz > ath: phy0: Assigned next_chan to 2412 MHz > ath: phy0: Offchannel duration for chan 2412 MHz : 506705 > ath: phy0: ath_chanctx_set_next: current: 2412 MHz, next: 2412 MHz > ath: phy0: ath_offchannel_channel_change: offchannel state: > ATH_OFFCHANNEL_ROC_START > ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_SWITCH, state: > ATH_CHANCTX_STATE_IDLE > [ cut here ] > WARNING: CPU: 0 PID: 3312 at drivers/net/wireless/ath/ath9k/main.c:2319 > Modules linked in: ath9k ath9k_common ath9k_hw ath mac80211 cfg80211 > > Signed-off-by: Janusz Dziedzic > --- > drivers/net/wireless/ath/ath9k/channel.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/wireless/ath/ath9k/channel.c > b/drivers/net/wireless/ath/ath9k/channel.c > index 2066650..e211325 100644 > --- a/drivers/net/wireless/ath/ath9k/channel.c > +++ b/drivers/net/wireless/ath/ath9k/channel.c > @@ -926,7 +926,8 @@ void ath_roc_complete(struct ath_softc *sc, bool abort) > > sc->offchannel.roc_vif = NULL; > sc->offchannel.roc_chan = NULL; > - ieee80211_remain_on_channel_expired(sc->hw); > + if (!abort) > + ieee80211_remain_on_channel_expired(sc->hw); > ath_offchannel_next(sc); > ath9k_ps_restore(sc); > } If HW aborts RoC in middle, should not we inform mac80211 that RoC is expired? Also the we are clearing roc_vif independent of abort, so the warning indicates that roc_complete has not come from FW, may be we should understand that first? -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 3/3] ath9k: advertise p2p dev support when chanctx
Advertise p2p device support when ath9k loaded with use_chanctx=1. This will fix problem, when first interface is an AP and next we would like to run p2p_find. Before p2p find (scan phase) failed with EOPNOTSUPP. Signed-off-by: Janusz Dziedzic --- drivers/net/wireless/ath/ath9k/init.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index f8d11ef..7da1a17 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -736,13 +736,14 @@ static const struct ieee80211_iface_limit if_limits_multi[] = { BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) }, { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, + { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }, }; static const struct ieee80211_iface_combination if_comb_multi[] = { { .limits = if_limits_multi, .n_limits = ARRAY_SIZE(if_limits_multi), - .max_interfaces = 2, + .max_interfaces = 3, .num_different_channels = 2, .beacon_int_infra_match = true, }, @@ -855,6 +856,9 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_WDS); + if (ath9k_is_chanctx_enabled()) + hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_DEVICE); + hw->wiphy->iface_combinations = if_comb; hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 2/3] ath9k: make rxfilter per HW
mac80211 configure rxfilter per HW, so we don't need this per channel. This fix problem when chanctx used and ath9k allocate new internal ath_chanctx (eg. when offchannel) and we loose rxfilter configuration. Eg. when p2p_find (with use_chanctx=1), during remain on channel, driver create new ath_chanctx with incorrect rxfilter. Then we didn't receive probe requests and fail p2p_find. Signed-off-by: Janusz Dziedzic --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 ++- drivers/net/wireless/ath/ath9k/main.c | 2 +- drivers/net/wireless/ath/ath9k/recv.c | 12 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a7a81b3..030fd0f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -356,7 +356,6 @@ struct ath_chanctx { short nvifs; short nvifs_assigned; - unsigned int rxfilter; }; enum ath_chanctx_event { @@ -1001,8 +1000,10 @@ struct ath_softc { struct cfg80211_chan_def cur_chandef; struct ath_chanctx chanctx[ATH9K_NUM_CHANCTX]; struct ath_chanctx *cur_chan; + unsigned int rxfilter; spinlock_t chan_lock; + #ifdef CONFIG_MAC80211_LEDS bool led_registered; char led_name[32]; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d285e3a..945f002 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1463,7 +1463,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, *total_flags &= SUPPORTED_FILTERS; spin_lock_bh(&sc->chan_lock); - sc->cur_chan->rxfilter = *total_flags; + sc->rxfilter = *total_flags; spin_unlock_bh(&sc->chan_lock); ath9k_ps_wakeup(sc); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 6c75fb1..5f72c65 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -389,31 +389,31 @@ u32 ath_calcrxfilter(struct ath_softc *sc) spin_lock_bh(&sc->chan_lock); - if (sc->cur_chan->rxfilter & FIF_PROBE_REQ) + if (sc->rxfilter & FIF_PROBE_REQ) rfilt |= ATH9K_RX_FILTER_PROBEREQ; if (sc->sc_ah->is_monitoring) rfilt |= ATH9K_RX_FILTER_PROM; - if ((sc->cur_chan->rxfilter & FIF_CONTROL) || + if ((sc->rxfilter & FIF_CONTROL) || sc->sc_ah->dynack.enabled) rfilt |= ATH9K_RX_FILTER_CONTROL; if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && (sc->cur_chan->nvifs <= 1) && - !(sc->cur_chan->rxfilter & FIF_BCN_PRBRESP_PROMISC)) + !(sc->rxfilter & FIF_BCN_PRBRESP_PROMISC)) rfilt |= ATH9K_RX_FILTER_MYBEACON; else rfilt |= ATH9K_RX_FILTER_BEACON; if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || - (sc->cur_chan->rxfilter & FIF_PSPOLL)) + (sc->rxfilter & FIF_PSPOLL)) rfilt |= ATH9K_RX_FILTER_PSPOLL; if (sc->cur_chandef.width != NL80211_CHAN_WIDTH_20_NOHT) rfilt |= ATH9K_RX_FILTER_COMP_BAR; - if (sc->cur_chan->nvifs > 1 || (sc->cur_chan->rxfilter & FIF_OTHER_BSS)) { + if (sc->cur_chan->nvifs > 1 || (sc->rxfilter & FIF_OTHER_BSS)) { /* This is needed for older chips */ if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160) rfilt |= ATH9K_RX_FILTER_PROM; @@ -878,7 +878,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, */ spin_lock_bh(&sc->chan_lock); if (!ath9k_cmn_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error, -sc->cur_chan->rxfilter)) { +sc->rxfilter)) { spin_unlock_bh(&sc->chan_lock); return -EINVAL; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 1/3] ath9k: handle RoC abort correctly
In case we will get ROC abort we should not call ieee80211_remain_on_channel_expired(). In other case I hit such warning on MIPS and p2p negotiation failed (tested with use_chanctx=1). ath: phy0: Starting RoC period ath: phy0: Channel definition created: 2412 MHz ath: phy0: Assigned next_chan to 2412 MHz ath: phy0: Offchannel duration for chan 2412 MHz : 506632 ath: phy0: ath_chanctx_set_next: current: 2412 MHz, next: 2412 MHz ath: phy0: Stopping current chanctx: 2412 ath: phy0: Flush timeout: 200 ath: phy0: ath_chanctx_set_next: Set channel 2412 MHz ath: phy0: Set channel: 2412 MHz width: 0 ath: phy0: Reset to 2412 MHz, HT40: 0 fastcc: 0 ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_TSF_TIMER, state: ATH_CHANCTX_STATE_IDLE ath: phy0: ath_offchannel_channel_change: offchannel state: ATH_OFFCHANNEL_ROC_START ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_SWITCH, state: ATH_CHANCTX_STATE_IDLE ath: phy0: Cancel RoC ath: phy0: RoC aborted ath: phy0: RoC request on vif: 00:03:7f:4e:a0:cd, type: 1 duration: 500 ath: phy0: Starting RoC period ath: phy0: Channel definition created: 2412 MHz ath: phy0: Assigned next_chan to 2412 MHz ath: phy0: Offchannel duration for chan 2412 MHz : 506705 ath: phy0: ath_chanctx_set_next: current: 2412 MHz, next: 2412 MHz ath: phy0: ath_offchannel_channel_change: offchannel state: ATH_OFFCHANNEL_ROC_START ath: phy0: cur_chan: 2412 MHz, event: ATH_CHANCTX_EVENT_SWITCH, state: ATH_CHANCTX_STATE_IDLE [ cut here ] WARNING: CPU: 0 PID: 3312 at drivers/net/wireless/ath/ath9k/main.c:2319 Modules linked in: ath9k ath9k_common ath9k_hw ath mac80211 cfg80211 Signed-off-by: Janusz Dziedzic --- drivers/net/wireless/ath/ath9k/channel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 2066650..e211325 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -926,7 +926,8 @@ void ath_roc_complete(struct ath_softc *sc, bool abort) sc->offchannel.roc_vif = NULL; sc->offchannel.roc_chan = NULL; - ieee80211_remain_on_channel_expired(sc->hw); + if (!abort) + ieee80211_remain_on_channel_expired(sc->hw); ath_offchannel_next(sc); ath9k_ps_restore(sc); } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 0/3] ath9k: P2P patches when chanctx used
Patches for problems I hit during P2P tests when multichannel used (driver loaded with use_chanctx=1). Janusz Dziedzic (3): ath9k: handle RoC abort correctly ath9k: make rxfilter per HW ath9k: advertise p2p dev support when chanctx drivers/net/wireless/ath/ath9k/ath9k.h | 3 ++- drivers/net/wireless/ath/ath9k/channel.c | 3 ++- drivers/net/wireless/ath/ath9k/init.c| 6 +- drivers/net/wireless/ath/ath9k/main.c| 2 +- drivers/net/wireless/ath/ath9k/recv.c| 12 ++-- 5 files changed, 16 insertions(+), 10 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
IEEE1609.4 support for Linux
Hello, We are developing IEEE1609.4 [1] protocol as a part of Wireless Access in Vehicular Environment (WAVE) stack for the Linux Kernel. The responsibilities of the protocol are as follows : -- Channel Co-ordination and synchronization -- Channel Routing The protocol generally holds two kinds of channels: Service Channel (SCH) and Control Channel (CCH). SCH is mainly used to send the data packets, while the CCH is used to send control as well as data packets. The radio switches between these two channels as configured. Channel Co-ordination and synchronization == The switching between SCH and CCH can be achieved in many modes (Continuous CCH, SCH, Alternating, Immediate SCH). Each of the channel slot is given 50 ms of time slice, where in which, the first 4 ms is generally used as a guard band for changing the channel. The end objective is such that, two or more communicating devices should be synchronized at the same channel for the exchange of data. This is where the concept of channel synchronization and coordination comes. Problem : As mentioned earlier, a guard band of 4ms is introduced to switch the channels. But, few of the devices might complete it in 2.5ms (say) and few in 3.5ms (say), depending on the load of the system. Now, to achieve the synchronization, we need to make sure that no device is transmitting the data during this 4ms, even though it has switched the channel before 4ms. Thus, we need to switch off the transmitter some how for these 4ms. The other side of the story is, we need to keep the Tx packet queuing, and also the Rx ON during these period. So, the queries are as follows : How this can be achieved? How to disable the transmitter? Will it be driver specific? Any help is appreciated. Thanks and Regards, Raghavendra [1] : http://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=5712767 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: [PATCH 1/2] staging: wilc1000: modify type casting warning
On Tue, Jun 16, 2015 at 06:06:43AM -0700, Greg KH wrote: > This shows you are doing something really wrong here, why not just fix > the function type to be a real pointer to a real structure? You are right, of course. > Or even better, just remove the parameter as I don't think they are > even used. I don't know how far you traced the code, you may be right. It eventually becomes driver_handler[] in wilc_wlan_cfg_commit() and we do this: drivers/staging/wilc1000/wilc_wlan.c 1883 cfg->wid_header[1] = seq_no;/* sequence number */ 1884 cfg->wid_header[2] = (uint8_t)total_len; 1885 cfg->wid_header[3] = (uint8_t)(total_len >> 8); 1886 cfg->wid_header[4] = (uint8_t)driver_handler; 1887 cfg->wid_header[5] = (uint8_t)(driver_handler >> 8); 1888 cfg->wid_header[6] = (uint8_t)(driver_handler >> 16); 1889 cfg->wid_header[7] = (uint8_t)(driver_handler >> 24); We put it in the header. 1890 p->cfg_seq_no = seq_no; 1891 1892 /** 1893 * Add to TX queue 1894 **/ 1895 1896 /*Edited by Amr - BugID_4720*/ 1897 if (!wilc_wlan_txq_add_cfg_pkt(&cfg->wid_header[0], total_len)) And I don't know what we do with it after this. 1898 return -1; 1899 1900 return 0; 1901 } regards, dan carpenter -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: [PATCH] staging: wilc1000: modify type casting warning
This silences the warning but really the warnings indicate real bugs which need to be fixed. Silencing these warnings makes the bugs harder to find so it is a step in the wrong direction. Change SendConfigPkt() so that drvHandler is a pointer. regards, dan carpenter -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: brcmfmac: one faulty "iw interface add" command breaks in-firmware BSS state
On Mon, 2015-06-22 at 10:20 +0200, Arend van Spriel wrote: > >>> # iw phy phy0 interface add wlan0 type __ap > Indeed there is an issue with error handling here, but as this was a > user fault I was looking for early detection. If as you say that will > not be easy from cfg80211 we will need to rework brcmfmac code. > Currently, we create interface in firmware and upon receiving 'ifc > created' event we do the register_netdev. I think we do that to avoid > getting start_xmit calls as we do not use netif carrier calls. We could possibly check for duplicate names, but surely there are other failure modes that we can't easily pre-check, so it seems better to fix the driver (and, in fact, use the duplicate name issue as a convenient way of testing the error path) johannes -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: brcmfmac: one faulty "iw interface add" command breaks in-firmware BSS state
On 06/22/15 10:03, Johannes Berg wrote: On Mon, 2015-06-22 at 09:47 +0200, Arend van Spriel wrote: # iw phy phy0 interface add wlan0 type __ap Now this is a pretty silly scenario as there already is a wlan0 interface. Admittedly, this should be rejected as such. This clearly is a user mistake (not sure why you quoted that :-p ) and it might be good to catch this in cfg80211 as it probably applies to other drivers as well. This probably explains why register_netdev fails. I don't think that's easy to catch - but the driver really should just see that register_netdev fails and do nothing (except for reporting the error back), no? Indeed there is an issue with error handling here, but as this was a user fault I was looking for early detection. If as you say that will not be easy from cfg80211 we will need to rework brcmfmac code. Currently, we create interface in firmware and upon receiving 'ifc created' event we do the register_netdev. I think we do that to avoid getting start_xmit calls as we do not use netif carrier calls. Regards, Arend -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 16/17] mwifiex: separate interface combination for multichannel and DFS
Multichannel and DFS cannot be supported at same time. So when multichannel operation is enabled by module parameter, we enable number of channel as 2 while registering wiphy. For all other cases we advertise DFS support to cfg80211. Patch also adds support for radar detect widths parameter. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 25 ++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index bc863e9..93e40d0 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -35,16 +35,33 @@ static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = { }, }; -static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = { +static const struct ieee80211_iface_combination +mwifiex_iface_comb_ap_sta = { .limits = mwifiex_ap_sta_limits, .num_different_channels = 1, .n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits), .max_interfaces = MWIFIEX_MAX_BSS_NUM, .beacon_int_infra_match = true, + .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | + BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40), +}; + +static const struct ieee80211_iface_combination +mwifiex_iface_comb_ap_sta_vht = { + .limits = mwifiex_ap_sta_limits, + .num_different_channels = 1, + .n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits), + .max_interfaces = MWIFIEX_MAX_BSS_NUM, + .beacon_int_infra_match = true, + .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | + BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80), }; static const struct -ieee80211_iface_combination mwifiex_drcs_iface_comb_ap_sta = { +ieee80211_iface_combination mwifiex_iface_comb_ap_sta_drcs = { .limits = mwifiex_ap_sta_limits, .num_different_channels = 2, .n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits), @@ -3755,7 +3772,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; if (adapter->drcs_enabled && ISSUPP_DRCS_ENABLED(adapter->fw_cap_info)) - wiphy->iface_combinations = &mwifiex_drcs_iface_comb_ap_sta; + wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta_drcs; + else if (adapter->is_hw_11ac_capable) + wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta_vht; else wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta; wiphy->n_iface_combinations = 1; -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 17/17] mwifiex: handle multichannel event
This patch adds support to handle multichannel event from FW. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/fw.h| 8 drivers/net/wireless/mwifiex/main.h | 2 ++ drivers/net/wireless/mwifiex/sta_event.c | 30 ++ drivers/net/wireless/mwifiex/uap_event.c | 6 ++ 4 files changed, 46 insertions(+) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 976b585..98269bf 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -172,6 +172,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_TX_PAUSE (PROPRIETARY_TLV_BASE_ID + 148) #define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154) #define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156) +#define TLV_TYPE_MULTI_CHAN_INFO(PROPRIETARY_TLV_BASE_ID + 183) #define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194) #define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197) #define TLV_TYPE_API_REV(PROPRIETARY_TLV_BASE_ID + 199) @@ -516,6 +517,7 @@ enum P2P_MODES { #define EVENT_TX_DATA_PAUSE 0x0055 #define EVENT_EXT_SCAN_REPORT 0x0058 #define EVENT_REMAIN_ON_CHAN_EXPIRED0x005f +#define EVENT_MULTI_CHAN_INFO 0x006a #define EVENT_TX_STATUS_REPORT 0x0074 #define EVENT_BT_COEX_WLAN_PARA_CHANGE 0X0076 @@ -1970,6 +1972,12 @@ struct mwifiex_radar_det_event { __le32 passed; } __packed; +struct mwifiex_ie_types_multi_chan_info { + struct mwifiex_ie_types_header header; + __le16 status; + u8 tlv_buffer[0]; +} __packed; + struct meas_rpt_map { u8 rssi:3; u8 unmeasured:1; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index f3264f2..face747 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1557,6 +1557,8 @@ void mwifiex_11n_delba(struct mwifiex_private *priv, int tid); int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy); void mwifiex_process_tx_pause_event(struct mwifiex_private *priv, struct sk_buff *event); +void mwifiex_process_multi_chan_event(struct mwifiex_private *priv, + struct sk_buff *event_skb); #ifdef CONFIG_DEBUG_FS void mwifiex_debugfs_init(void); diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index a2777d1..3d18c58 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -309,6 +309,31 @@ static void mwifiex_process_sta_tx_pause(struct mwifiex_private *priv, } } +void mwifiex_process_multi_chan_event(struct mwifiex_private *priv, + struct sk_buff *event_skb) +{ + struct mwifiex_ie_types_multi_chan_info *chan_info; + u16 status; + + chan_info = (void *)event_skb->data + sizeof(u32); + + if (le16_to_cpu(chan_info->header.type) != TLV_TYPE_MULTI_CHAN_INFO) { + mwifiex_dbg(priv->adapter, ERROR, + "unknown TLV in chan_info event\n"); + return; + } + + status = le16_to_cpu(chan_info->status); + + if (status) { + mwifiex_dbg(priv->adapter, EVENT, + "multi-channel operation started\n"); + } else { + mwifiex_dbg(priv->adapter, EVENT, + "multi-channel operation over\n"); + } +} + void mwifiex_process_tx_pause_event(struct mwifiex_private *priv, struct sk_buff *event_skb) { @@ -748,6 +773,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) mwifiex_process_tx_pause_event(priv, adapter->event_skb); break; + case EVENT_MULTI_CHAN_INFO: + mwifiex_dbg(adapter, EVENT, "event: multi-chan info\n"); + mwifiex_process_multi_chan_event(priv, adapter->event_skb); + break; + case EVENT_TX_STATUS_REPORT: mwifiex_dbg(adapter, EVENT, "event: TX_STATUS Report\n"); mwifiex_parse_tx_status_event(priv, adapter->event_body); diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c index a9d34c6..492a8b3 100644 --- a/drivers/net/wireless/mwifiex/uap_event.c +++ b/drivers/net/wireless/mwifiex/uap_event.c @@ -304,6 +304,12 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) mwifiex_dbg(adapter, EVENT, "event: TX DATA PAUSE\n"); mwifiex_process_tx_pause_event(priv, adapter->event_skb); break; + + case EVENT_MULTI_CHAN_INFO: + mwifiex_dbg(adapter, EVENT, "event: multi-chan info\n"); + mwifiex_process_multi_chan_event(priv, adapter->event_skb); + break
[PATCH 12/17] mwifiex: enable traffic only when port is open
This patch adds support to enable data traffic only when port is open. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/init.c| 2 +- drivers/net/wireless/mwifiex/join.c| 2 ++ drivers/net/wireless/mwifiex/main.h| 1 + drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 ++ drivers/net/wireless/mwifiex/sta_event.c | 4 +++- drivers/net/wireless/mwifiex/uap_event.c | 3 +++ drivers/net/wireless/mwifiex/wmm.c | 5 - 7 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index e1b62bf..8fa363a 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -77,7 +77,7 @@ int mwifiex_init_priv(struct mwifiex_private *priv) priv->media_connected = false; eth_broadcast_addr(priv->curr_addr); - + priv->port_open = false; priv->pkt_tx_ctrl = 0; priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; priv->data_rate = 0;/* Initially indicate the rate as auto */ diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 56b024a..3cda1f9 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -783,6 +783,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) priv->scan_block = true; + else + priv->port_open = true; done: /* Need to indicate IOCTL complete */ diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index c59430e..6f98d7e 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -519,6 +519,7 @@ struct mwifiex_private { u8 frame_type; u8 curr_addr[ETH_ALEN]; u8 media_connected; + u8 port_open; u32 num_tx_timeout; /* track consecutive timeout */ u8 tx_timeout_cnt; diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 6a85c77..18f269e 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -599,6 +599,7 @@ static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv, "info: key: GTK is set\n"); priv->wpa_is_gtk_set = true; priv->scan_block = false; + priv->port_open = true; } } @@ -629,6 +630,7 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv, mwifiex_dbg(priv->adapter, INFO, "info: key: GTK is set\n"); priv->wpa_is_gtk_set = true; priv->scan_block = false; + priv->port_open = true; } } diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index f1045d4..72be16e 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -54,6 +54,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code) priv->media_connected = false; priv->scan_block = false; + priv->port_open = false; if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) { @@ -474,7 +475,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_PS_AWAKE: mwifiex_dbg(adapter, EVENT, "info: EVENT: AWAKE\n"); - if (!adapter->pps_uapsd_mode && + if (!adapter->pps_uapsd_mode && priv->port_open && priv->media_connected && adapter->sleep_period.period) { adapter->pps_uapsd_mode = true; mwifiex_dbg(adapter, EVENT, @@ -553,6 +554,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_PORT_RELEASE: mwifiex_dbg(adapter, EVENT, "event: PORT RELEASE\n"); + priv->port_open = true; break; case EVENT_EXT_SCAN_REPORT: diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c index 7bc1f85..a412c3d 100644 --- a/drivers/net/wireless/mwifiex/uap_event.c +++ b/drivers/net/wireless/mwifiex/uap_event.c @@ -176,6 +176,7 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) break; case EVENT_UAP_BSS_IDLE: priv->media_connected = false; + priv->port_open = false; if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); mwifiex_stop_net_dev_queue(priv->netdev, adapter); @@ -185,6 +186,7 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
[PATCH 14/17] mwifiex: support to set multichannel policy to FW
This patch adds support for setting multichannel policy as module parameter to FW. Value of 1 indicates Multichannel support is enabled and value of 0 disables it. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/fw.h | 8 drivers/net/wireless/mwifiex/sta_cmd.c | 31 ++ drivers/net/wireless/mwifiex/sta_cmdresp.c | 1 + 3 files changed, 40 insertions(+) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 427e363..976b585 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -201,6 +201,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) #define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14)) +#define ISSUPP_DRCS_ENABLED(FwCapInfo) (FwCapInfo & BIT(15)) #define ISSUPP_SDIO_SPA_ENABLED(FwCapInfo) (FwCapInfo & BIT(16)) #define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \ @@ -361,6 +362,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_REMAIN_ON_CHAN0x010d #define HostCmd_CMD_11AC_CFG 0x0112 #define HostCmd_CMD_TDLS_CONFIG 0x0100 +#define HostCmd_CMD_MC_POLICY 0x0121 #define HostCmd_CMD_TDLS_OPER 0x0122 #define HostCmd_CMD_SDIO_SP_RX_AGGR_CFG 0x0223 @@ -2039,6 +2041,11 @@ struct host_cmd_ds_coalesce_cfg { struct coalesce_receive_filt_rule rule[0]; } __packed; +struct host_cmd_ds_multi_chan_policy { + __le16 action; + __le16 policy; +} __packed; + struct host_cmd_ds_command { __le16 command; __le16 size; @@ -2107,6 +2114,7 @@ struct host_cmd_ds_command { struct host_cmd_ds_tdls_oper tdls_oper; struct host_cmd_ds_chan_rpt_req chan_rpt_req; struct host_cmd_sdio_sp_rx_aggr_cfg sdio_rx_aggr_cfg; + struct host_cmd_ds_multi_chan_policy mc_policy; } params; } __packed; diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 82e6c6e..f250b61 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -26,6 +26,10 @@ #include "11n.h" #include "11ac.h" +static bool drcs; +module_param(drcs, bool, 0644); +MODULE_PARM_DESC(drcs, "multi-channel operation:1, single-channel operation:0"); + static bool disable_auto_ds; module_param(disable_auto_ds, bool, 0); MODULE_PARM_DESC(disable_auto_ds, @@ -1512,6 +1516,22 @@ static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv, } static int +mwifiex_cmd_set_mc_policy(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct host_cmd_ds_multi_chan_policy *mc_pol = &cmd->params.mc_policy; + const u16 *drcs_info = data_buf; + + mc_pol->action = cpu_to_le16(cmd_action); + mc_pol->policy = cpu_to_le16(*drcs_info); + cmd->command = cpu_to_le16(HostCmd_CMD_MC_POLICY); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_multi_chan_policy) + + S_DS_GEN); + return 0; +} + +static int mwifiex_cmd_coalesce_cfg(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) @@ -2014,6 +2034,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, ret = mwifiex_cmd_sdio_rx_aggr_cfg(cmd_ptr, cmd_action, data_buf); break; + case HostCmd_CMD_MC_POLICY: + ret = mwifiex_cmd_set_mc_policy(priv, cmd_ptr, cmd_action, + data_buf); + break; default: mwifiex_dbg(priv->adapter, ERROR, "PREP_CMD: unknown cmd- %#x\n", cmd_no); @@ -2130,6 +2154,13 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init) if (ret) return -1; } + + if (ISSUPP_DRCS_ENABLED(adapter->fw_cap_info)) + ret = mwifiex_send_cmd(priv, HostCmd_CMD_MC_POLICY, + HostCmd_ACT_GEN_SET, 0, &drcs, + true); + if (ret) + return -1; } /* get tx rate */ diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 18f269e..89e8daf 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -1193,6 +1193,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; case
[PATCH 10/17] mwifiex: update domain_info upon band change in start_ap
It was observed that AP beacons would not reflect correct regulatory information upon starting AP in A band. This was because of missing AP config band update in set_channel of start_ap. Also we configure 11D settings info FW only for specific band. So we need to download domain info to FW even if domain remains unchanged but band is changed. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 2 +- drivers/net/wireless/mwifiex/main.h | 2 ++ drivers/net/wireless/mwifiex/uap_cmd.c | 7 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index ecc8278..1d445cb 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -442,7 +442,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, * - Country codes * - Sub bands (first channel, number of channels, maximum Tx power) */ -static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) +int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) { u8 no_of_triplet = 0; struct ieee80211_country_ie_triplet *t; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 0e6ebc9..d74ef2d 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1550,6 +1550,8 @@ void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags); void mwifiex_queue_main_work(struct mwifiex_adapter *adapter); void mwifiex_coex_ampdu_rxwinsize(struct mwifiex_adapter *adapter); void mwifiex_11n_delba(struct mwifiex_private *priv, int tid); +int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy); + #ifdef CONFIG_DEBUG_FS void mwifiex_debugfs_init(void); void mwifiex_debugfs_remove(void); diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index b749300..4d5a6e3 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -808,7 +808,7 @@ void mwifiex_uap_set_channel(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_cfg, struct cfg80211_chan_def chandef) { - u8 config_bands = 0; + u8 config_bands = 0, old_bands = priv->adapter->config_bands; priv->bss_chandef = chandef; @@ -834,6 +834,11 @@ void mwifiex_uap_set_channel(struct mwifiex_private *priv, } priv->adapter->config_bands = config_bands; + + if (old_bands != config_bands) { + mwifiex_send_domain_info_cmd_fw(priv->adapter->wiphy); + mwifiex_dnld_txpwr_table(priv); + } } int mwifiex_config_start_uap(struct mwifiex_private *priv, -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 09/17] mwifiex: add cfg80211 tdls channel switch handler
From: Xinming Hu This patch add cfg80211 tdls_chan_switch and tdls_cancel_chan_switch handler. With this handlers, mwifiex would support TDLS channel switch feature. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 72 + 1 file changed, 72 insertions(+) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index b15e4c7..ecc8278 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -19,6 +19,7 @@ #include "cfg80211.h" #include "main.h" +#include "11n.h" static char *reg_alpha2; module_param(reg_alpha2, charp, 0); @@ -3360,6 +3361,72 @@ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, } static int +mwifiex_cfg80211_tdls_chan_switch(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr, u8 oper_class, + struct cfg80211_chan_def *chandef) +{ + struct mwifiex_sta_node *sta_ptr; + unsigned long flags; + u16 chan; + u8 second_chan_offset, band; + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + + spin_lock_irqsave(&priv->sta_list_spinlock, flags); + sta_ptr = mwifiex_get_sta_entry(priv, addr); + spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); + + if (!sta_ptr) { + wiphy_err(wiphy, "%s: Invalid TDLS peer %pM\n", + __func__, addr); + return -ENOENT; + } + + if (!(sta_ptr->tdls_cap.extcap.ext_capab[3] & + WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH)) { + wiphy_err(wiphy, "%pM do not support tdls cs\n", addr); + return -ENOENT; + } + + if (sta_ptr->tdls_status == TDLS_CHAN_SWITCHING || + sta_ptr->tdls_status == TDLS_IN_OFF_CHAN) { + wiphy_err(wiphy, "channel switch is running, abort request\n"); + return -EALREADY; + } + + chan = chandef->chan->hw_value; + second_chan_offset = mwifiex_get_sec_chan_offset(chan); + band = chandef->chan->band; + mwifiex_start_tdls_cs(priv, addr, chan, second_chan_offset, band); + + return 0; +} + +static void +mwifiex_cfg80211_tdls_cancel_chan_switch(struct wiphy *wiphy, +struct net_device *dev, +const u8 *addr) +{ + struct mwifiex_sta_node *sta_ptr; + unsigned long flags; + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + + spin_lock_irqsave(&priv->sta_list_spinlock, flags); + sta_ptr = mwifiex_get_sta_entry(priv, addr); + spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); + + if (!sta_ptr) { + wiphy_err(wiphy, "%s: Invalid TDLS peer %pM\n", + __func__, addr); + } else if (!(sta_ptr->tdls_status == TDLS_CHAN_SWITCHING || +sta_ptr->tdls_status == TDLS_IN_BASE_CHAN || +sta_ptr->tdls_status == TDLS_IN_OFF_CHAN)) { + wiphy_err(wiphy, "tdls chan switch not initialize by %pM\n", + addr); + } else + mwifiex_stop_tdls_cs(priv, addr); +} + +static int mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_parameters *params) { @@ -3575,6 +3642,8 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { .set_coalesce = mwifiex_cfg80211_set_coalesce, .tdls_mgmt = mwifiex_cfg80211_tdls_mgmt, .tdls_oper = mwifiex_cfg80211_tdls_oper, + .tdls_channel_switch = mwifiex_cfg80211_tdls_chan_switch, + .tdls_cancel_channel_switch = mwifiex_cfg80211_tdls_cancel_chan_switch, .add_station = mwifiex_cfg80211_add_station, .change_station = mwifiex_cfg80211_change_station, .get_channel = mwifiex_cfg80211_get_channel, @@ -3709,6 +3778,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) NL80211_FEATURE_INACTIVITY_TIMER | NL80211_FEATURE_NEED_OBSS_SCAN; + if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info)) + wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH; + if (adapter->fw_api_ver == MWIFIEX_FW_V15) wiphy->features |= NL80211_FEATURE_SK_TX_STATUS; -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 11/17] mwifiex: support for bypass tx queue
This patch adds support for another TX queue in driver- bypass TX queue. This queue is used for sending data/mgmt packets while in disconnected state i.e. when port is yet not unblocked. TDLS setup packets would also be queued in this queue. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 4 +++ drivers/net/wireless/mwifiex/init.c | 1 + drivers/net/wireless/mwifiex/main.c | 49 -- drivers/net/wireless/mwifiex/main.h | 2 ++ drivers/net/wireless/mwifiex/wmm.c | 53 + drivers/net/wireless/mwifiex/wmm.h | 4 +++ 6 files changed, 111 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 1d445cb..46f9dc2 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2789,6 +2789,7 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); struct mwifiex_adapter *adapter = priv->adapter; + struct sk_buff *skb, *tmp; #ifdef CONFIG_DEBUG_FS mwifiex_dev_debugfs_remove(priv); @@ -2796,6 +2797,9 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) mwifiex_stop_net_dev_queue(priv->netdev, adapter); + skb_queue_walk_safe(&priv->bypass_txq, skb, tmp) + mwifiex_write_data_complete(priv->adapter, skb, 0, -1); + if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index df7fdc0..e1b62bf 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -499,6 +499,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) INIT_LIST_HEAD(&priv->sta_list); INIT_LIST_HEAD(&priv->auto_tdls_list); skb_queue_head_init(&priv->tdls_txq); + skb_queue_head_init(&priv->bypass_txq); spin_lock_init(&priv->tx_ba_stream_tbl_lock); spin_lock_init(&priv->rx_reorder_tbl_lock); diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 2a2e5db..278dc94 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -276,6 +276,7 @@ process_start: !adapter->pm_wakeup_fw_try) && (is_command_pending(adapter) || !skb_queue_empty(&adapter->tx_data_q) || +!mwifiex_bypass_txlist_empty(adapter) || !mwifiex_wmm_lists_empty(adapter))) { adapter->pm_wakeup_fw_try = true; mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3)); @@ -303,6 +304,7 @@ process_start: (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA)) || (mwifiex_wmm_lists_empty(adapter) && +mwifiex_bypass_txlist_empty(adapter) && skb_queue_empty(&adapter->tx_data_q))) { if (adapter->cmd_sent || adapter->curr_cmd || !mwifiex_is_send_cmd_allowed @@ -373,6 +375,22 @@ process_start: if ((adapter->scan_chan_gap_enabled || !adapter->scan_processing) && + !adapter->data_sent && + !mwifiex_bypass_txlist_empty(adapter) && + !mwifiex_is_tdls_chan_switching + (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA))) { + mwifiex_process_bypass_tx(adapter); + if (adapter->hs_activated) { + adapter->is_hs_configured = false; + mwifiex_hs_activated_event + (mwifiex_get_priv +(adapter, MWIFIEX_BSS_ROLE_ANY), +false); + } + } + + if ((adapter->scan_chan_gap_enabled || +!adapter->scan_processing) && !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter) && !mwifiex_is_tdls_chan_switching (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA))) { @@ -389,6 +407,7 @@ process_start: if (adapter->delay_null_pkt && !adapter->cmd_sent && !adapter->curr_cmd && !is_command_pending(adapter) && (mwifiex_wmm_lists_empty(adapter) && +mwifiex_bypass_txlist_empty(adapter) && skb_queue_empty(&adapter->tx_data_q))) { if (!mwifiex_send_null_packet
[PATCH 15/17] mwifiex: advertise multichannel support to cfg80211
This patch adds support to advetise mwifiex multichannel support to cfg80211. If module parameter drcs is enabled and FW supports multichannel operation we advertise this support to cfg80211. As of now 2 simultaneous channels are supported. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 14 +- drivers/net/wireless/mwifiex/main.h | 1 + drivers/net/wireless/mwifiex/sta_cmd.c | 13 + 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 46f9dc2..bc863e9 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -43,6 +43,15 @@ static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = { .beacon_int_infra_match = true, }; +static const struct +ieee80211_iface_combination mwifiex_drcs_iface_comb_ap_sta = { + .limits = mwifiex_ap_sta_limits, + .num_different_channels = 2, + .n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits), + .max_interfaces = MWIFIEX_MAX_BSS_NUM, + .beacon_int_infra_match = true, +}; + /* * This function maps the nl802.11 channel type into driver channel type. * @@ -3745,7 +3754,10 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) else wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; - wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta; + if (adapter->drcs_enabled && ISSUPP_DRCS_ENABLED(adapter->fw_cap_info)) + wiphy->iface_combinations = &mwifiex_drcs_iface_comb_ap_sta; + else + wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta; wiphy->n_iface_combinations = 1; /* Initialize cipher suits */ diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 6e82058..f3264f2 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -985,6 +985,7 @@ struct mwifiex_adapter { u8 coex_win_size; u8 coex_tx_win_size; u8 coex_rx_win_size; + bool drcs_enabled; }; void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter); diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index f250b61..36cb6bd 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -2155,12 +2155,17 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init) return -1; } - if (ISSUPP_DRCS_ENABLED(adapter->fw_cap_info)) - ret = mwifiex_send_cmd(priv, HostCmd_CMD_MC_POLICY, - HostCmd_ACT_GEN_SET, 0, &drcs, - true); + if (drcs) { + adapter->drcs_enabled = true; + if (ISSUPP_DRCS_ENABLED(adapter->fw_cap_info)) + ret = mwifiex_send_cmd(priv, + HostCmd_CMD_MC_POLICY, + HostCmd_ACT_GEN_SET, 0, + &adapter->drcs_enabled, + true); if (ret) return -1; + } } /* get tx rate */ -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 13/17] mwifiex: extend tx_data pause to AP interface as well
This patch adds support to extend TX Data pause for AP intefaces. Also for station role, support for pausing/unpausing all traffic when mac address parameter is BSSID is added. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/main.h | 2 + drivers/net/wireless/mwifiex/sta_event.c | 121 ++- drivers/net/wireless/mwifiex/uap_event.c | 4 + 3 files changed, 93 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 6f98d7e..6e82058 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1554,6 +1554,8 @@ void mwifiex_queue_main_work(struct mwifiex_adapter *adapter); void mwifiex_coex_ampdu_rxwinsize(struct mwifiex_adapter *adapter); void mwifiex_11n_delba(struct mwifiex_private *priv, int tid); int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy); +void mwifiex_process_tx_pause_event(struct mwifiex_private *priv, + struct sk_buff *event); #ifdef CONFIG_DEBUG_FS void mwifiex_debugfs_init(void); diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 72be16e..a2777d1 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -237,58 +237,110 @@ static int mwifiex_parse_tdls_event(struct mwifiex_private *priv, return ret; } -static void -mwifiex_process_sta_tx_pause_event(struct mwifiex_private *priv, - struct sk_buff *event_skb) +static void mwifiex_process_uap_tx_pause(struct mwifiex_private *priv, +struct mwifiex_ie_types_header *tlv) { - struct mwifiex_ie_types_header *tlv; - struct mwifiex_tx_pause_tlv *tp_tlv; + struct mwifiex_tx_pause_tlv *tp; struct mwifiex_sta_node *sta_ptr; unsigned long flags; - u16 tlv_type, tlv_len; - int tlv_buf_left, status; - if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) - return; + tp = (void *)tlv; + mwifiex_dbg(priv->adapter, EVENT, + "uap tx_pause: %pM pause=%d, pkts=%d\n", + tp->peermac, tp->tx_pause, + tp->pkt_cnt); + + if (ether_addr_equal(tp->peermac, priv->netdev->dev_addr)) { + if (tp->tx_pause) + priv->port_open = false; + else + priv->port_open = true; + } else if (is_multicast_ether_addr(tp->peermac)) { + mwifiex_update_ralist_tx_pause(priv, tp->peermac, tp->tx_pause); + } else { + spin_lock_irqsave(&priv->sta_list_spinlock, flags); + sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac); + spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); + + if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { + sta_ptr->tx_pause = tp->tx_pause; + mwifiex_update_ralist_tx_pause(priv, tp->peermac, + tp->tx_pause); + } + } +} + +static void mwifiex_process_sta_tx_pause(struct mwifiex_private *priv, +struct mwifiex_ie_types_header *tlv) +{ + struct mwifiex_tx_pause_tlv *tp; + struct mwifiex_sta_node *sta_ptr; + int status; + unsigned long flags; + + tp = (void *)tlv; + mwifiex_dbg(priv->adapter, EVENT, + "sta tx_pause: %pM pause=%d, pkts=%d\n", + tp->peermac, tp->tx_pause, + tp->pkt_cnt); + + if (ether_addr_equal(tp->peermac, priv->cfg_bssid)) { + if (tp->tx_pause) + priv->port_open = false; + else + priv->port_open = true; + } else { + if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) + return; + + status = mwifiex_get_tdls_link_status(priv, tp->peermac); + if (mwifiex_is_tdls_link_setup(status)) { + spin_lock_irqsave(&priv->sta_list_spinlock, flags); + sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac); + spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); + + if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { + sta_ptr->tx_pause = tp->tx_pause; + mwifiex_update_ralist_tx_pause(priv, + tp->peermac, + tp->tx_pause); + } + } + } +} + +void mwifiex_process_tx_pause_event(struct mwifiex_private *priv, + struct sk_buff *event_skb) +{ + struct mwifiex_ie_types_header
[PATCH 01/17] mwifiex: add tx data pause support
This patch adds support to enable TX data pause feature for mwifiex. Whenever FW TX buffers reach threshold, FW would send TX pause event to driver. Driver in turn would block data traffic to that particular receiver address. Signed-off-by: Avinash Patil Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/fw.h| 9 + drivers/net/wireless/mwifiex/main.h | 3 ++ drivers/net/wireless/mwifiex/sta_event.c | 66 drivers/net/wireless/mwifiex/wmm.c | 38 ++ drivers/net/wireless/mwifiex/wmm.h | 2 + 5 files changed, 118 insertions(+) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index cd09051..8ab0d81 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -169,6 +169,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_UAP_PS_AO_TIMER(PROPRIETARY_TLV_BASE_ID + 123) #define TLV_TYPE_PWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 145) #define TLV_TYPE_GWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 146) +#define TLV_TYPE_TX_PAUSE (PROPRIETARY_TLV_BASE_ID + 148) #define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154) #define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156) #define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194) @@ -509,6 +510,7 @@ enum P2P_MODES { #define EVENT_TDLS_GENERIC_EVENT0x0052 #define EVENT_RADAR_DETECTED 0x0053 #define EVENT_CHANNEL_REPORT_RDY0x0054 +#define EVENT_TX_DATA_PAUSE 0x0055 #define EVENT_EXT_SCAN_REPORT 0x0058 #define EVENT_REMAIN_ON_CHAN_EXPIRED0x005f #define EVENT_TX_STATUS_REPORT 0x0074 @@ -1131,6 +1133,13 @@ struct host_cmd_ds_tx_rate_query { u8 ht_info; } __packed; +struct mwifiex_tx_pause_tlv { + struct mwifiex_ie_types_header header; + u8 peermac[ETH_ALEN]; + u8 tx_pause; + u8 pkt_cnt; +} __packed; + enum Host_Sleep_Action { HS_CONFIGURE = 0x0001, HS_ACTIVATE = 0x0002, diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index ae98b5b..2106a5c 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -281,6 +281,7 @@ struct mwifiex_ra_list_tbl { u8 amsdu_in_ampdu; u16 total_pkt_count; bool tdls_link; + bool tx_paused; }; struct mwifiex_tid_tbl { @@ -294,6 +295,7 @@ struct mwifiex_tid_tbl { struct mwifiex_wmm_desc { struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID]; u32 packets_out[MAX_NUM_TID]; + u32 pkts_paused[MAX_NUM_TID]; /* spin lock to protect ra_list */ spinlock_t ra_list_spinlock; struct mwifiex_wmm_ac_status ac_status[IEEE80211_NUM_ACS]; @@ -768,6 +770,7 @@ struct mwifiex_sta_node { u8 tdls_status; struct mwifiex_tdls_capab tdls_cap; struct mwifiex_station_stats stats; + u8 tx_pause; }; struct mwifiex_auto_tdls_peer { diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 848de26..0a80814 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -182,6 +182,67 @@ static int mwifiex_parse_tdls_event(struct mwifiex_private *priv, return ret; } +static void +mwifiex_process_sta_tx_pause_event(struct mwifiex_private *priv, + struct sk_buff *event_skb) +{ + struct mwifiex_ie_types_header *tlv; + struct mwifiex_tx_pause_tlv *tp_tlv; + struct mwifiex_sta_node *sta_ptr; + unsigned long flags; + u16 tlv_type, tlv_len; + int tlv_buf_left, status; + + if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) + return; + + if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected)) + return; + + tlv_buf_left = event_skb->len - sizeof(u32); + tlv = (void *)event_skb->data + sizeof(u32); + while (tlv_buf_left >= (int)sizeof(struct mwifiex_ie_types_header)) { + tlv_type = le16_to_cpu(tlv->type); + tlv_len = le16_to_cpu(tlv->len); + if ((sizeof(struct mwifiex_ie_types_header) + tlv_len) > + tlv_buf_left) { + mwifiex_dbg(priv->adapter, ERROR, + "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n", + tlv_len, tlv_buf_left); + break; + } + if (tlv_type == TLV_TYPE_TX_PAUSE) { + tp_tlv = (void *)tlv; + mwifiex_dbg(priv->adapter, ERROR, + "TxPause: %pM pause=%d, pkts=%d\n", + tp_tlv->peermac, tp_tlv->tx_pause, + tp_tlv->pkt_cnt); +
[PATCH 08/17] mwifiex: enhance tdls link setup condition
From: Xinming Hu TDLS link status - channel switching, off channel or base channel itself indicates that TDLS link is setup. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/main.h | 15 +++ drivers/net/wireless/mwifiex/sta_event.c | 2 +- drivers/net/wireless/mwifiex/tdls.c | 8 drivers/net/wireless/mwifiex/wmm.c | 7 +-- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index da227522..0e6ebc9 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1333,6 +1333,21 @@ static inline u8 mwifiex_is_any_intf_active(struct mwifiex_private *priv) return 0; } +static inline u8 mwifiex_is_tdls_link_setup(u8 status) +{ + switch (status) { + case TDLS_SETUP_COMPLETE: + case TDLS_CHAN_SWITCHING: + case TDLS_IN_BASE_CHAN: + case TDLS_IN_OFF_CHAN: + return true; + default: + break; + } + + return false; +} + int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, u32 func_init_shutdown); int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8); diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 0529b9a..f1045d4 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -273,7 +273,7 @@ mwifiex_process_sta_tx_pause_event(struct mwifiex_private *priv, tp_tlv->pkt_cnt); status = mwifiex_get_tdls_link_status (priv, tp_tlv->peermac); - if (status == TDLS_SETUP_COMPLETE) { + if (mwifiex_is_tdls_link_setup(status)) { spin_lock_irqsave(&priv->sta_list_spinlock, flags); sta_ptr = mwifiex_get_sta_entry diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c index f862ca6..aa3d3c5 100644 --- a/drivers/net/wireless/mwifiex/tdls.c +++ b/drivers/net/wireless/mwifiex/tdls.c @@ -49,7 +49,7 @@ static void mwifiex_restore_tdls_packets(struct mwifiex_private *priv, tid = skb->priority; tid_down = mwifiex_wmm_downgrade_tid(priv, tid); - if (status == TDLS_SETUP_COMPLETE) { + if (mwifiex_is_tdls_link_setup(status)) { ra_list = mwifiex_wmm_get_queue_raptr(priv, tid, mac); ra_list->tdls_link = true; tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT; @@ -1147,7 +1147,7 @@ int mwifiex_get_tdls_list(struct mwifiex_private *priv, spin_lock_irqsave(&priv->sta_list_spinlock, flags); list_for_each_entry(sta_ptr, &priv->sta_list, list) { - if (sta_ptr->tdls_status == TDLS_SETUP_COMPLETE) { + if (mwifiex_is_tdls_link_setup(sta_ptr->tdls_status)) { ether_addr_copy(peer->peer_addr, sta_ptr->mac_addr); peer++; count++; @@ -1301,7 +1301,7 @@ void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv, if ((link_status == TDLS_NOT_SETUP) && (peer->tdls_status == TDLS_SETUP_INPROGRESS)) peer->failure_count++; - else if (link_status == TDLS_SETUP_COMPLETE) + else if (mwifiex_is_tdls_link_setup(link_status)) peer->failure_count = 0; peer->tdls_status = link_status; @@ -1373,7 +1373,7 @@ void mwifiex_check_auto_tdls(unsigned long context) if (((tdls_peer->rssi >= MWIFIEX_TDLS_RSSI_LOW) || !tdls_peer->rssi) && - tdls_peer->tdls_status == TDLS_SETUP_COMPLETE) { + mwifiex_is_tdls_link_setup(tdls_peer->tdls_status)) { tdls_peer->tdls_status = TDLS_LINK_TEARDOWN; mwifiex_dbg(priv->adapter, MSG, "teardown TDLS link,peer=%pM rssi=%d\n", diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 21712cd..6196daa 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -162,8 +162,8 @@ void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra) ra_list->amsdu_in_ampdu = false; ra_list->tx_paused = false; if (!mwifiex_queuing_ra_based(priv)) { - if (mwifiex_get_tdls_link_status(priv, ra) == - TDLS_SETUP_COMPLETE) { + if (mw
[PATCH 05/17] mwifiex: process tdls channel switch event
From: Xinming Hu This patch add support for tdls channel switch event process. We block TX queues for particular RA list depending upon channel switch state. If channel switch state is moving to base channel, we unblock RA lists for AP. If channel switch state is moving to off channel, we unblock TDLS peer RA lists. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/fw.h| 17 +- drivers/net/wireless/mwifiex/sta_event.c | 54 drivers/net/wireless/mwifiex/wmm.c | 45 ++ drivers/net/wireless/mwifiex/wmm.h | 2 ++ 4 files changed, 117 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 8ab0d81..0785e64 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -547,7 +547,14 @@ enum P2P_MODES { #define ACT_TDLS_DELETE0x00 #define ACT_TDLS_CREATE0x01 #define ACT_TDLS_CONFIG0x02 -#define TDLS_EVENT_LINK_TEAR_DOWN 3 + +#define TDLS_EVENT_LINK_TEAR_DOWN 3 +#define TDLS_EVENT_CHAN_SWITCH_RESULT 7 +#define TDLS_EVENT_START_CHAN_SWITCH 8 +#define TDLS_EVENT_CHAN_SWITCH_STOPPED 9 + +#define TDLS_BASE_CHANNEL 0 +#define TDLS_OFF_CHANNEL 1 #define MWIFIEX_FW_V1515 @@ -1936,10 +1943,18 @@ struct host_cmd_ds_802_11_subsc_evt { __le16 events; } __packed; +struct chan_switch_result { + u8 cur_chan; + u8 status; + u8 reason; +} __packed; + struct mwifiex_tdls_generic_event { __le16 type; u8 peer_mac[ETH_ALEN]; union { + struct chan_switch_result switch_result; + u8 cs_stop_reason; __le16 reason_code; __le16 reserved; } u; diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 0a80814..0529b9a 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -153,6 +153,7 @@ static int mwifiex_parse_tdls_event(struct mwifiex_private *priv, struct mwifiex_sta_node *sta_ptr; struct mwifiex_tdls_generic_event *tdls_evt = (void *)event_skb->data + sizeof(adapter->event_cause); + u8 *mac = tdls_evt->peer_mac; /* reserved 2 bytes are not mandatory in tdls event */ if (event_skb->len < (sizeof(struct mwifiex_tdls_generic_event) - @@ -175,6 +176,59 @@ static int mwifiex_parse_tdls_event(struct mwifiex_private *priv, le16_to_cpu(tdls_evt->u.reason_code), GFP_KERNEL); break; + case TDLS_EVENT_CHAN_SWITCH_RESULT: + mwifiex_dbg(adapter, EVENT, "tdls channel switch result :\n"); + mwifiex_dbg(adapter, EVENT, + "status=0x%x, reason=0x%x cur_chan=%d\n", + tdls_evt->u.switch_result.status, + tdls_evt->u.switch_result.reason, + tdls_evt->u.switch_result.cur_chan); + + /* tdls channel switch failed */ + if (tdls_evt->u.switch_result.status != 0) { + switch (tdls_evt->u.switch_result.cur_chan) { + case TDLS_BASE_CHANNEL: + sta_ptr->tdls_status = TDLS_IN_BASE_CHAN; + break; + case TDLS_OFF_CHANNEL: + sta_ptr->tdls_status = TDLS_IN_OFF_CHAN; + break; + default: + break; + } + return ret; + } + + /* tdls channel switch success */ + switch (tdls_evt->u.switch_result.cur_chan) { + case TDLS_BASE_CHANNEL: + if (sta_ptr->tdls_status == TDLS_IN_BASE_CHAN) + break; + mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac, + false); + sta_ptr->tdls_status = TDLS_IN_BASE_CHAN; + break; + case TDLS_OFF_CHANNEL: + if (sta_ptr->tdls_status == TDLS_IN_OFF_CHAN) + break; + mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac, + true); + sta_ptr->tdls_status = TDLS_IN_OFF_CHAN; + break; + default: + break; + } + + break; + case TDLS_EVENT_START_CHAN_SWITCH: + mwifiex_dbg(adapter, EVENT, "tdls start channel swit
[PATCH 04/17] mwifiex: add tdls channel switch status
From: Xinming Hu This patch add new tdls status used for tdls channel switch. Driver in turn would block cmd path and data path if tdls channel switching. Data path to non tdls peer should be blocked if tdls channel switch to off-channel. Signed-off-by: Xinming Hu Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/decl.h | 3 ++ drivers/net/wireless/mwifiex/main.c | 14 +++-- drivers/net/wireless/mwifiex/main.h | 3 ++ drivers/net/wireless/mwifiex/util.c | 59 + 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 51e3447..098e1f1 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -141,6 +141,9 @@ enum mwifiex_tdls_status { TDLS_SETUP_COMPLETE, TDLS_SETUP_FAILURE, TDLS_LINK_TEARDOWN, + TDLS_CHAN_SWITCHING, + TDLS_IN_BASE_CHAN, + TDLS_IN_OFF_CHAN, }; enum mwifiex_tdls_error_code { diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 3ba4e0e..2a2e5db 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -299,9 +299,15 @@ process_start: if ((!adapter->scan_chan_gap_enabled && adapter->scan_processing) || adapter->data_sent || +mwifiex_is_tdls_chan_switching +(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_STA)) || (mwifiex_wmm_lists_empty(adapter) && skb_queue_empty(&adapter->tx_data_q))) { if (adapter->cmd_sent || adapter->curr_cmd || + !mwifiex_is_send_cmd_allowed + (mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_STA)) || (!is_command_pending(adapter))) break; } @@ -342,7 +348,9 @@ process_start: continue; } - if (!adapter->cmd_sent && !adapter->curr_cmd) { + if (!adapter->cmd_sent && !adapter->curr_cmd && + mwifiex_is_send_cmd_allowed + (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA))) { if (mwifiex_exec_next_cmd(adapter) == -1) { ret = -1; break; @@ -365,7 +373,9 @@ process_start: if ((adapter->scan_chan_gap_enabled || !adapter->scan_processing) && - !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) { + !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter) && + !mwifiex_is_tdls_chan_switching + (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA))) { mwifiex_wmm_process_tx(adapter); if (adapter->hs_activated) { adapter->is_hs_configured = false; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 2106a5c..d27e6aa 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1461,6 +1461,9 @@ struct mwifiex_sta_node * mwifiex_add_sta_entry(struct mwifiex_private *priv, const u8 *mac); struct mwifiex_sta_node * mwifiex_get_sta_entry(struct mwifiex_private *priv, const u8 *mac); +u8 mwifiex_is_tdls_chan_switching(struct mwifiex_private *priv); +u8 mwifiex_is_tdls_off_chan(struct mwifiex_private *priv); +u8 mwifiex_is_send_cmd_allowed(struct mwifiex_private *priv); int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer, u8 action_code, u8 dialog_token, u16 status_code, const u8 *extra_ies, diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 790e619..2504e42 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -531,6 +531,65 @@ mwifiex_get_sta_entry(struct mwifiex_private *priv, const u8 *mac) return NULL; } +static struct mwifiex_sta_node * +mwifiex_get_tdls_sta_entry(struct mwifiex_private *priv, u8 status) +{ + struct mwifiex_sta_node *node; + + list_for_each_entry(node, &priv->sta_list, list) { + if (node->tdls_status == status) + return node; + } + + return NULL; +} + +/* If tdls channel switching is on-going, tx data traffic should be + * blocked until the switching stage completed. + */ +u8 mwifiex_is_tdls_chan_switching(struct mwifiex_private *priv) +{ + struct mwifiex_sta_node *sta_ptr;
[PATCH 00/17] mwifiex: multichannel & TDLS channel switch support
This patchset adds multichannel and TDLS channel switch support to mwifiex. Important feature this patchset brings in is TX DATA Pause support wherein FW indicates driver about inablity to handle additional data packets(because of channel switch) and driver would pause traffic for these RA list or interfaces. This in turn enables us to support multichannel operation and TDLS channel switch feature. Avinash Patil (9): mwifiex: add tx data pause support mwifiex: update domain_info upon band change in start_ap mwifiex: support for bypass tx queue mwifiex: enable traffic only when port is open mwifiex: extend tx_data pause to AP interface as well mwifiex: support to set multichannel policy to FW mwifiex: advertise multichannel support to cfg80211 mwifiex: separate interface combination for multichannel and DFS mwifiex: handle multichannel event Xinming Hu (8): mwifiex: block data traffic to tx paused receive address mwifiex: do not increase tx_pkts_queued if receive address tx paused mwifiex: add tdls channel switch status mwifiex: process tdls channel switch event mwifiex: add tdls config command mwifiex: enable tdls channel switch ext_cap mwifiex: enhance tdls link setup condition mwifiex: add cfg80211 tdls channel switch handler drivers/net/wireless/mwifiex/cfg80211.c| 113 +++- drivers/net/wireless/mwifiex/decl.h| 3 + drivers/net/wireless/mwifiex/fw.h | 87 +++- drivers/net/wireless/mwifiex/init.c| 3 +- drivers/net/wireless/mwifiex/join.c| 2 + drivers/net/wireless/mwifiex/main.c| 63 - drivers/net/wireless/mwifiex/main.h| 38 ++ drivers/net/wireless/mwifiex/sta_cmd.c | 84 drivers/net/wireless/mwifiex/sta_cmdresp.c | 5 + drivers/net/wireless/mwifiex/sta_event.c | 207 - drivers/net/wireless/mwifiex/tdls.c| 78 ++- drivers/net/wireless/mwifiex/uap_cmd.c | 7 +- drivers/net/wireless/mwifiex/uap_event.c | 13 ++ drivers/net/wireless/mwifiex/util.c| 59 drivers/net/wireless/mwifiex/wmm.c | 156 +- drivers/net/wireless/mwifiex/wmm.h | 8 ++ 16 files changed, 906 insertions(+), 20 deletions(-) -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 02/17] mwifiex: block data traffic to tx paused receive address
From: Xinming Hu Data traffic to tx paused receive address should be blocked. Signed-off-by: Xinming Hu Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/wmm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index bc920a5..8a4dd24 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -1025,7 +1025,8 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, list_for_each_entry(ptr, &tid_ptr->ra_list, list) { - if (!skb_queue_empty(&ptr->skb_head)) + if (!ptr->tx_paused && + !skb_queue_empty(&ptr->skb_head)) /* holds both locks */ goto found; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 07/17] mwifiex: enable tdls channel switch ext_cap
From: Xinming Hu This patch enable tdls channel switch ext capability in tdls action frame, and also configure basic tdls channel switch parameters while tdls setup completed and tdls link is enabled.. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/tdls.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c index 03eabd7..f862ca6 100644 --- a/drivers/net/wireless/mwifiex/tdls.c +++ b/drivers/net/wireless/mwifiex/tdls.c @@ -355,6 +355,7 @@ static void mwifiex_tdls_add_ext_capab(struct mwifiex_private *priv, extcap->ieee_hdr.len = 8; memset(extcap->ext_capab, 0, 8); extcap->ext_capab[4] |= WLAN_EXT_CAPA5_TDLS_ENABLED; + extcap->ext_capab[3] |= WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH; if (priv->adapter->is_hw_11ac_capable) extcap->ext_capab[7] |= WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED; @@ -1071,6 +1072,11 @@ mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer) for (i = 0; i < MAX_NUM_TID; i++) sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED; } + if (sta_ptr->tdls_cap.extcap.ext_capab[3] & + WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) { + mwifiex_config_tdls_enable(priv); + mwifiex_config_tdls_cs_params(priv); + } memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq)); mwifiex_restore_tdls_packets(priv, peer, TDLS_SETUP_COMPLETE); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 03/17] mwifiex: do not increase tx_pkts_queued if receive address tx paused
From: Xinming Hu If tx_pkts_queued is increased for tx paused receive address, tx process will be triggered for this packet. But since RA list was tx paused, there will be an infinite loop in mwifiex_wmm_process_tx waiting for the event(tx pause, tdls cs) to cancel tx pause. This will be an dead loop, since main_process was locked at this time, there will be no opportunity to process event. So do not increase tx_pkts_queued if receive address tx paused, this will be restored RA list is unpaused. Signed-off-by: Xinming Hu Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/wmm.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 8a4dd24..8e343b3 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -803,7 +803,10 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, atomic_set(&priv->wmm.highest_queued_prio, priv->tos_to_tid_inv[tid_down]); - atomic_inc(&priv->wmm.tx_pkts_queued); + if (ra_list->tx_paused) + priv->wmm.pkts_paused[tid_down]++; + else + atomic_inc(&priv->wmm.tx_pkts_queued); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
[PATCH 06/17] mwifiex: add tdls config command
From: Xinming Hu This patch add support for a new tdls configuration command which is used for configuration of tdls channel switch parameters. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/fw.h | 45 + drivers/net/wireless/mwifiex/main.h| 7 drivers/net/wireless/mwifiex/sta_cmd.c | 48 ++ drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 + drivers/net/wireless/mwifiex/tdls.c| 64 ++ 5 files changed, 166 insertions(+) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 0785e64..427e363 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -360,6 +360,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_MGMT_FRAME_REG0x010c #define HostCmd_CMD_REMAIN_ON_CHAN0x010d #define HostCmd_CMD_11AC_CFG 0x0112 +#define HostCmd_CMD_TDLS_CONFIG 0x0100 #define HostCmd_CMD_TDLS_OPER 0x0122 #define HostCmd_CMD_SDIO_SP_RX_AGGR_CFG 0x0223 @@ -556,6 +557,19 @@ enum P2P_MODES { #define TDLS_BASE_CHANNEL 0 #define TDLS_OFF_CHANNEL 1 +#define ACT_TDLS_CS_ENABLE_CONFIG 0x00 +#define ACT_TDLS_CS_INIT 0x06 +#define ACT_TDLS_CS_STOP 0x07 +#define ACT_TDLS_CS_PARAMS 0x08 + +#define MWIFIEX_DEF_CS_UNIT_TIME 2 +#define MWIFIEX_DEF_CS_THR_OTHERLINK 10 +#define MWIFIEX_DEF_THR_DIRECTLINK 0 +#define MWIFIEX_DEF_CS_TIME10 +#define MWIFIEX_DEF_CS_TIMEOUT 16 +#define MWIFIEX_DEF_CS_REG_CLASS 12 +#define MWIFIEX_DEF_CS_PERIODICITY 1 + #define MWIFIEX_FW_V1515 #define MWIFIEX_MASTER_RADAR_DET_MASK BIT(1) @@ -1265,6 +1279,36 @@ struct host_cmd_ds_tdls_oper { u8 peer_mac[ETH_ALEN]; } __packed; +struct mwifiex_tdls_config { + __le16 enable; +}; + +struct mwifiex_tdls_config_cs_params { + u8 unit_time; + u8 thr_otherlink; + u8 thr_directlink; +}; + +struct mwifiex_tdls_init_cs_params { + u8 peer_mac[ETH_ALEN]; + u8 primary_chan; + u8 second_chan_offset; + u8 band; + __le16 switch_time; + __le16 switch_timeout; + u8 reg_class; + u8 periodicity; +} __packed; + +struct mwifiex_tdls_stop_cs_params { + u8 peer_mac[ETH_ALEN]; +}; + +struct host_cmd_ds_tdls_config { + __le16 tdls_action; + u8 tdls_data[1]; +} __packed; + struct mwifiex_chan_desc { __le16 start_freq; u8 chan_width; @@ -2059,6 +2103,7 @@ struct host_cmd_ds_command { struct host_cmd_ds_sta_list sta_list; struct host_cmd_11ac_vht_cfg vht_cfg; struct host_cmd_ds_coalesce_cfg coalesce_cfg; + struct host_cmd_ds_tdls_config tdls_config; struct host_cmd_ds_tdls_oper tdls_oper; struct host_cmd_ds_chan_rpt_req chan_rpt_req; struct host_cmd_sdio_sp_rx_aggr_cfg sdio_rx_aggr_cfg; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index d27e6aa..da227522 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1494,6 +1494,13 @@ void mwifiex_check_auto_tdls(unsigned long context); void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac); void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv); void mwifiex_clean_auto_tdls(struct mwifiex_private *priv); +int mwifiex_config_tdls_enable(struct mwifiex_private *priv); +int mwifiex_config_tdls_disable(struct mwifiex_private *priv); +int mwifiex_config_tdls_cs_params(struct mwifiex_private *priv); +int mwifiex_stop_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac); +int mwifiex_start_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac, + u8 primary_chan, u8 second_chan_offset, u8 band); + int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 037adcd..82e6c6e 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -1576,6 +1576,50 @@ mwifiex_cmd_coalesce_cfg(struct mwifiex_private *priv, } static int +mwifiex_cmd_tdls_config(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct host_cmd_ds_tdls_config *tdls_config = &cmd->params.tdls_config; + struct mwifiex_tdls_init_cs_params *config; + struct mwifiex_tdls_config *init_config; + u16 len; + + cmd->command = cpu_to_le16(HostCmd_CM
Re: brcmfmac: one faulty "iw interface add" command breaks in-firmware BSS state
On 22 June 2015 at 09:47, Arend van Spriel wrote: > On 06/21/15 21:59, Rafał Miłecki wrote: >> I've discovered some bug in brcmfmac& its BSS management. It was >> >> exposed by OpenWrt user space change ("fix") I introduced in: >> >> http://git.openwrt.org/?p=openwrt.git;a=commit;h=1cbb5e8de50457c1d9724ca75cc6815df5721289 >> and it's related to the "interface add" command. >> >> I've router with BCM43602 and I'm using a very recent brcmfmac. >> >> brcmfmac :01:00.0: enabling device (0140 -> 0142) >> brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Mar 3 2015 >> 04:46:51 version 7.35.177.33 (r538052) FWID 01-c8317c80 >> brcmfmac: brcmf_cfg80211_reg_notifier: not a ISO3166 code >> >> wlan0 Link encap:Ethernet HWaddr 00:23:6A:A3:7D:95 >>BROADCAST MULTICAST MTU:1500 Metric:1 >>RX packets:8 errors:0 dropped:4 overruns:0 frame:0 >>TX packets:19 errors:0 dropped:0 overruns:0 carrier:0 >>collisions:0 txqueuelen:1000 >>RX bytes:505 (505.0 B) TX bytes:1730 (1.6 KiB) >> >> I'll just describe two scenarios that should make things clear. Both >> after a cold boot. >> >> >> 1) Standard (working) scenario >> # hostapd /etc/hostapd.conf >> Configuration file: /etc/hostapd.conf >> Failed to create interface mon.wlan0: -95 (Operation not supported) >> [ 105.483797] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists >> [ 105.490308] brcmfmac: brcmf_add_if: ignore IF event >> [ 105.499067] device wlan0 entered promiscuous mode >> [ 105.503939] br-lan: port 2(wlan0) entered forwarding state >> [ 105.509437] br-lan: port 2(wlan0) entered forwarding state >> wlan0: Could not connect to kernel driver >> Using interface wlan0 with hwaddr 00:23:6a:a3:7d:95 and ssid "OpenWrtA" >> [ 105.640966] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists >> [ 105.647478] brcmfmac: brcmf_add_if: ignore IF event >> wlan0: interface state UNINITIALIZED->ENABLED >> wlan0: AP-ENABLED >> [ 107.510613] br-lan: port 2(wlan0) entered forwarding state >> >> This results in a working AP, my devices are able to connect >> >> >> 2) Scenario with iw command "mistake": >> # iw phy phy0 interface add wlan0 type __ap > > > Now this is a pretty silly scenario as there already is a wlan0 interface. > Admittedly, this should be rejected as such. This clearly is a user mistake > (not sure why you quoted that :-p ) and it might be good to catch this in > cfg80211 as it probably applies to other drivers as well. This probably > explains why register_netdev fails. To tell the truth, it's part of bigger OpenWrt script. To make things clean, on every configuration change, OpenWrt removes all interfaces and (re)creates needed ones. Unfortunately brcmfmac doesn't allow removing wlan0 and it results in OpenWrt trying to create wlan0 that wasn't previously removed. >> [ 65.036358] brcmfmac: brcmf_net_attach: couldn't register the net >> device >> [ 65.043080] brcmfmac: brcmf_ap_add_vif: Registering netdevice failed >> command failed: Invalid exchange (-52) >> # hostapd /etc/hostapd.conf >> Configuration file: /etc/hostapd.conf >> Failed to create interface mon.wlan0: -95 (Operation not supported) >> [ 83.393594] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists >> [ 83.400122] brcmfmac: brcmf_add_if: ignore IF event >> [ 83.409448] device wlan0 entered promiscuous mode >> [ 83.414259] br-lan: port 2(wlan0) entered forwarding state >> [ 83.419802] br-lan: port 2(wlan0) entered forwarding state >> wlan0: Could not connect to kernel driver >> Using interface wlan0 with hwaddr 00:23:6a:a3:7d:95 and ssid "OpenWrtA" >> [ 83.550307] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists >> [ 83.556814] brcmfmac: brcmf_add_if: ignore IF event >> wlan0: interface state UNINITIALIZED->ENABLED >> wlan0: AP-ENABLED >> [ 85.418417] br-lan: port 2(wlan0) entered forwarding state >> >> In this case in-firmware BSS state seems to be broken and BSS seems to >> be using *different* address. Following wpa_supplicant log should make >> it clear. > > > Well, you now have a STA and AP interface in firmware, but only STA netdev > so the AP interface is pretty useless. I am not sure about the mac address, > but I think it is expected. Otherwise you would have two interfaces with the > same mac address. wlan0 is still visible as it was before calling faulty iw command. If brcmfmac assigned different in-firmware BSS to the wlan0 we end up with inconsistent state. We now have STA (wlan0) vs. AP (in-firmware) and 00:23:6a:a3:7d:95 (wlan0) vs. 02:23:6a:a3:7d:96 (in-firmware). So it's clearly not something brcmfmac should do. -- Rafał -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: brcmfmac: one faulty "iw interface add" command breaks in-firmware BSS state
On Mon, 2015-06-22 at 09:47 +0200, Arend van Spriel wrote: > > # iw phy phy0 interface add wlan0 type __ap > > Now this is a pretty silly scenario as there already is a wlan0 > interface. Admittedly, this should be rejected as such. This clearly is > a user mistake (not sure why you quoted that :-p ) and it might be good > to catch this in cfg80211 as it probably applies to other drivers as > well. This probably explains why register_netdev fails. I don't think that's easy to catch - but the driver really should just see that register_netdev fails and do nothing (except for reporting the error back), no? johannes -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
Re: brcmfmac: one faulty "iw interface add" command breaks in-firmware BSS state
On 06/21/15 21:59, Rafał Miłecki wrote: Hi, I've discovered some bug in brcmfmac& its BSS management. It was exposed by OpenWrt user space change ("fix") I introduced in: http://git.openwrt.org/?p=openwrt.git;a=commit;h=1cbb5e8de50457c1d9724ca75cc6815df5721289 and it's related to the "interface add" command. I've router with BCM43602 and I'm using a very recent brcmfmac. brcmfmac :01:00.0: enabling device (0140 -> 0142) brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Mar 3 2015 04:46:51 version 7.35.177.33 (r538052) FWID 01-c8317c80 brcmfmac: brcmf_cfg80211_reg_notifier: not a ISO3166 code wlan0 Link encap:Ethernet HWaddr 00:23:6A:A3:7D:95 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:8 errors:0 dropped:4 overruns:0 frame:0 TX packets:19 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:505 (505.0 B) TX bytes:1730 (1.6 KiB) I'll just describe two scenarios that should make things clear. Both after a cold boot. 1) Standard (working) scenario # hostapd /etc/hostapd.conf Configuration file: /etc/hostapd.conf Failed to create interface mon.wlan0: -95 (Operation not supported) [ 105.483797] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists [ 105.490308] brcmfmac: brcmf_add_if: ignore IF event [ 105.499067] device wlan0 entered promiscuous mode [ 105.503939] br-lan: port 2(wlan0) entered forwarding state [ 105.509437] br-lan: port 2(wlan0) entered forwarding state wlan0: Could not connect to kernel driver Using interface wlan0 with hwaddr 00:23:6a:a3:7d:95 and ssid "OpenWrtA" [ 105.640966] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists [ 105.647478] brcmfmac: brcmf_add_if: ignore IF event wlan0: interface state UNINITIALIZED->ENABLED wlan0: AP-ENABLED [ 107.510613] br-lan: port 2(wlan0) entered forwarding state This results in a working AP, my devices are able to connect 2) Scenario with iw command "mistake": # iw phy phy0 interface add wlan0 type __ap Now this is a pretty silly scenario as there already is a wlan0 interface. Admittedly, this should be rejected as such. This clearly is a user mistake (not sure why you quoted that :-p ) and it might be good to catch this in cfg80211 as it probably applies to other drivers as well. This probably explains why register_netdev fails. Regards, Arend [ 65.036358] brcmfmac: brcmf_net_attach: couldn't register the net device [ 65.043080] brcmfmac: brcmf_ap_add_vif: Registering netdevice failed command failed: Invalid exchange (-52) # hostapd /etc/hostapd.conf Configuration file: /etc/hostapd.conf Failed to create interface mon.wlan0: -95 (Operation not supported) [ 83.393594] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists [ 83.400122] brcmfmac: brcmf_add_if: ignore IF event [ 83.409448] device wlan0 entered promiscuous mode [ 83.414259] br-lan: port 2(wlan0) entered forwarding state [ 83.419802] br-lan: port 2(wlan0) entered forwarding state wlan0: Could not connect to kernel driver Using interface wlan0 with hwaddr 00:23:6a:a3:7d:95 and ssid "OpenWrtA" [ 83.550307] brcmfmac: brcmf_add_if: ERROR: netdev:wlan0 already exists [ 83.556814] brcmfmac: brcmf_add_if: ignore IF event wlan0: interface state UNINITIALIZED->ENABLED wlan0: AP-ENABLED [ 85.418417] br-lan: port 2(wlan0) entered forwarding state In this case in-firmware BSS state seems to be broken and BSS seems to be using *different* address. Following wpa_supplicant log should make it clear. Well, you now have a STA and AP interface in firmware, but only STA netdev so the AP interface is pretty useless. I am not sure about the mac address, but I think it is expected. Otherwise you would have two interfaces with the same mac address. Regards, Arend wlp2s0b1: State: SCANNING -> AUTHENTICATING EAPOL: External notification - EAP success=0 EAPOL: Supplicant port status: Unauthorized EAPOL: External notification - EAP fail=0 EAPOL: Supplicant port status: Unauthorized EAPOL: External notification - portControl=Auto EAPOL: Supplicant port status: Unauthorized nl80211: Authenticate (ifindex=3) * bssid=00:23:6a:a3:7d:95 * freq=2462 * SSID - hexdump_ascii(len=8): 4f 70 65 6e 57 72 74 41 OpenWrtA * IEs - hexdump(len=0): [NULL] * Auth Type 0 nl80211: Authentication request send successfully RSN: Ignored PMKID candidate without preauth flag nl80211: Event message available nl80211: New station 00:23:6a:a3:7d:95 nl80211: Event message available nl80211: MLME event 37 nl80211: Authenticate event wlp2s0b1: Event AUTH (11) received wlp2s0b1: SME: Ignore authentication with unexpected peer 02:23:6a:a3:7d:96 wlp2s0b1: SME: Authentication timeout wpa_driver_nl80211_deauthenticate(addr=00:23:6a:a3:7d:95 reason_code=3) -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in