diff mbox

ath6kl: use WMI to set RSN capabilities

Message ID 20180412154159.13934-1-alfonso.sanchez-beato@canonical.com (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show

Commit Message

Alfonso Sánchez-Beato April 12, 2018, 3:41 p.m. UTC
This fixes AP mode when the ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE flag
is not present in the FW. The id of some WMI commands is also fixed
(there was an error in the enum order), and a function to set RSN caps
is added.

Signed-off-by: Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c | 21 ++++++---------------
 drivers/net/wireless/ath/ath6kl/main.c     | 10 +++-------
 drivers/net/wireless/ath/ath6kl/wmi.c      | 23 +++++++++++++++++++++++
 drivers/net/wireless/ath/ath6kl/wmi.h      | 15 +++++++++++----
 4 files changed, 43 insertions(+), 26 deletions(-)

Comments

Kalle Valo April 13, 2018, 10:48 a.m. UTC | #1
Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com> writes:

> This fixes AP mode when the ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE flag

> is not present in the FW. The id of some WMI commands is also fixed

> (there was an error in the enum order), and a function to set RSN caps

> is added.

>

> Signed-off-by: Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>


What hardware and firmware version? Do note that ids can change between
ath6kl firmware branches so even if it works for you it might break some
other branch. That's why it's good to document the setup in the commit
log.

-- 
Kalle Valo
Alfonso Sánchez-Beato April 13, 2018, 11:19 a.m. UTC | #2
On Fri, Apr 13, 2018 at 12:48 PM, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
>
> Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com> writes:
>
> > This fixes AP mode when the ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE flag
> > is not present in the FW. The id of some WMI commands is also fixed
> > (there was an error in the enum order), and a function to set RSN caps
> > is added.
> >
> > Signed-off-by: Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>
>
> What hardware and firmware version? Do note that ids can change between
> ath6kl firmware branches so even if it works for you it might break some
> other branch. That's why it's good to document the setup in the commit
> log.

I have tested this in an Atheros QCA6234. kmsg shows this about the fw:

ath6kl: ar6004 hw 3.0 sdio fw 3.5.0.604 api 1
ath6kl: firmware supports: 64bit-rates,ap-inactivity-mins

The fw file is AR6004/hw3.0/fw.ram.bin

>
> --
> Kalle Valo
Kalle Valo April 13, 2018, 11:22 a.m. UTC | #3
Alfonso Sanchez-Beato <alfonso.sanchez-beato@canonical.com> writes:

> On Fri, Apr 13, 2018 at 12:48 PM, Kalle Valo <kvalo@qca.qualcomm.com> wrote:

>>

>> Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com> writes:

>>

>> > This fixes AP mode when the ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE flag

>> > is not present in the FW. The id of some WMI commands is also fixed

>> > (there was an error in the enum order), and a function to set RSN caps

>> > is added.

>> >

>> > Signed-off-by: Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>

>>

>> What hardware and firmware version? Do note that ids can change between

>> ath6kl firmware branches so even if it works for you it might break some

>> other branch. That's why it's good to document the setup in the commit

>> log.

>

> I have tested this in an Atheros QCA6234. kmsg shows this about the fw:

>

> ath6kl: ar6004 hw 3.0 sdio fw 3.5.0.604 api 1


Ok, I'll add this to the commit log.

-- 
Kalle Valo
Kalle Valo April 27, 2018, 11:23 a.m. UTC | #4
Alfonso Sánchez-Beato wrote:

> This fixes AP mode when the ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE flag
> is not present in the FW. The id of some WMI commands is also fixed
> (there was an error in the enum order), and a function to set RSN caps
> is added.
> 
> Signed-off-by: Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Steve, what do you think of this?
Steve deRosier April 27, 2018, 3:47 p.m. UTC | #5
Hi Alfonso,

On Thu, Apr 12, 2018 at 8:42 AM Alfonso Sánchez-Beato <
alfonso.sanchez-beato@canonical.com> wrote:

> This fixes AP mode when the ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE flag
> is not present in the FW. The id of some WMI commands is also fixed
> (there was an error in the enum order), and a function to set RSN caps
> is added.

> Signed-off-by: Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>
> ---
>   drivers/net/wireless/ath/ath6kl/cfg80211.c | 21 ++++++---------------
>   drivers/net/wireless/ath/ath6kl/main.c     | 10 +++-------
>   drivers/net/wireless/ath/ath6kl/wmi.c      | 23 +++++++++++++++++++++++
>   drivers/net/wireless/ath/ath6kl/wmi.h      | 15 +++++++++++----
>   4 files changed, 43 insertions(+), 26 deletions(-)

> diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c
b/drivers/net/wireless/ath/ath6kl/cfg80211.c
> index 2ba8cf3f38af..1b89c53d47e7 100644
> --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
> +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
> @@ -2933,13 +2933,11 @@ static int ath6kl_start_ap(struct wiphy *wiphy,
struct net_device *dev,
>           * advertise the same in beacon/probe response. Send
>           * the complete RSN IE capability field to firmware
>           */
> -       if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
> -           test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
> -                    ar->fw_capabilities)) {
> -               res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
> -                                           WLAN_EID_RSN, WMI_RSN_IE_CAPB,
> -                                           (const u8 *) &rsn_capab,
> -                                           sizeof(rsn_capab));
> +       if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *)&rsn_capab)) {
> +               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "RSN caps %d\n",
rsn_capab);
> +
> +               res = ath6kl_wmi_set_rsn_cap(ar->wmi, vif->fw_vif_idx,
> +                                            rsn_capab);
>                  vif->rsn_capab = rsn_capab;
>                  if (res < 0)
>                          return res;

So, let me see if I understand this correctly.  Original flow was:

1. get RSN capable from the beacon if one
2. if the firmware is capable of the override, set the IE  else don't do
anything

New flow:
1. get RSN capable from the beacon if one
2. unconditionally send the rsn_cap WMI down

So, what happens on a firmware that _does_ have the rsn-cap-override flag
set? I'm guessing nothing good.  Admittedly I haven't tried your patch on
my platform.

I think that simply ignoring the flag and using a WMI instead of setting
the IE on all devices AR6002..AR6004 is likely going to cause problems for
everyone else.


> @@ -3918,14 +3916,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
>                  return -EINVAL;
>          }

> -       /*
> -        * Even if the fw has HT support, advertise HT cap only when
> -        * the firmware has support to override RSN capability, otherwise
> -        * 4-way handshake would fail.
> -        */
> -       if (!(ht &&
> -             test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
> -                      ar->fw_capabilities))) {
> +       if (!ht) {

Perhaps the comment isn't relevant if we're using the RSN WMI command on a
device with the flag, but I'm willing to bet you neither tested it nor that
the assumption is true.  I'm guessing this change just broke the 4-way
handshake for the majority of devices.

>                  ath6kl_band_2ghz.ht_cap.cap = 0;
>                  ath6kl_band_2ghz.ht_cap.ht_supported = false;
>                  ath6kl_band_5ghz.ht_cap.cap = 0;
> diff --git a/drivers/net/wireless/ath/ath6kl/main.c
b/drivers/net/wireless/ath/ath6kl/main.c
> index db95f85751e3..4e186f8b3950 100644
> --- a/drivers/net/wireless/ath/ath6kl/main.c
> +++ b/drivers/net/wireless/ath/ath6kl/main.c
> @@ -579,13 +579,9 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif
*vif, u16 channel)
>                   * reconfigure any saved RSN IE capabilites in the beacon
/
>                   * probe response to stay in sync with the supplicant.
>                   */
> -               if (vif->rsn_capab &&
> -                   test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
> -                            ar->fw_capabilities))
> -                       ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
> -                                             WLAN_EID_RSN,
WMI_RSN_IE_CAPB,
> -                                             (const u8 *)
&vif->rsn_capab,
> -                                             sizeof(vif->rsn_capab));
> +               if (vif->rsn_capab)
> +                       ath6kl_wmi_set_rsn_cap(ar->wmi, vif->fw_vif_idx,
> +                                              vif->rsn_capab);


So, basically same comment as the first one.

>                  return ath6kl_wmi_ap_profile_commit(ar->wmi,
vif->fw_vif_idx,
>                                                      &vif->profile);
> diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c
b/drivers/net/wireless/ath/ath6kl/wmi.c
> index 777acc564ac9..d7de9224d755 100644
> --- a/drivers/net/wireless/ath/ath6kl/wmi.c
> +++ b/drivers/net/wireless/ath/ath6kl/wmi.c
> @@ -4168,3 +4168,26 @@ void ath6kl_wmi_shutdown(struct wmi *wmi)
>          kfree(wmi->last_mgmt_tx_frame);
>          kfree(wmi);
>   }
> +
> +int ath6kl_wmi_set_rsn_cap(struct wmi *wmi, u8 if_idx, u16 rsn_cap)
> +{
> +       struct sk_buff *skb;
> +       struct wmi_rsn_cap_cmd *cmd;
> +
> +       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
> +       if (!skb)
> +               return -ENOMEM;
> +
> +       ath6kl_dbg(ATH6KL_DBG_WMI, "set_rsn_cap: 0x%04x\n", rsn_cap);
> +
> +       cmd = (struct wmi_rsn_cap_cmd *)skb->data;
> +       cmd->rsn_cap = cpu_to_le16(rsn_cap);
> +
> +       return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
WMI_SET_RSN_CAP_CMDID,
> +                                  NO_SYNC_WMIFLAG);
> +}
> +
> +int ath6kl_wmi_get_rsn_cap(struct wmi *wmi, u8 if_idx)
> +{
> +       return ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_GET_RSN_CAP_CMDID);
> +}
> diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h
b/drivers/net/wireless/ath/ath6kl/wmi.h
> index a60bb49fe920..011d4b6fb5ab 100644
> --- a/drivers/net/wireless/ath/ath6kl/wmi.h
> +++ b/drivers/net/wireless/ath/ath6kl/wmi.h
> @@ -597,10 +597,6 @@ enum wmi_cmd_id {

>          WMI_GREENTX_PARAMS_CMDID,

> -       WMI_RTT_MEASREQ_CMDID,
> -       WMI_RTT_CAPREQ_CMDID,
> -       WMI_RTT_STATUSREQ_CMDID,
> -
>          /* WPS Commands */
>          WMI_WPS_START_CMDID,
>          WMI_GET_WPS_STATUS_CMDID,
> @@ -621,6 +617,10 @@ enum wmi_cmd_id {
>          WMI_RX_FILTER_COALESCE_FILTER_OP_CMDID,
>          WMI_RX_FILTER_SET_FRAME_TEST_LIST_CMDID,

> +       WMI_RTT_MEASREQ_CMDID,
> +       WMI_RTT_CAPREQ_CMDID,
> +       WMI_RTT_STATUSREQ_CMDID,
> +
>          WMI_SEND_MGMT_CMDID,
>          WMI_BEGIN_SCAN_CMDID,

> @@ -2533,6 +2533,10 @@ enum wmi_sync_flag {
>          END_WMIFLAG
>   };


I can factually state that the above reordering of the commands is wrong
for a 6003. The order in the WMI file is consistent for a 6003. Your
reordering is consistent for a 6004. Now, the only commands affected by the
reordering aren't utilized by the driver, other than your added get/set
RSN_CAP_CMDIDs.  But on a 6003, your now used WMI_SET_RSN_CAP_CMDID will
trigger a WMI_GET_OPPPS_CMDID, which isn't what you want.

I've encountered this issue a before - wmi code mismatch between the
different firmwares and the driver. This is a limitation of the driver that
probably should be resolved in some meaningful way. To date, it's been
mitigated by the driver just not using the higher-numbered commands.  But
by "meaningful way" I don't include redefining command IDs in favor of one
particular person's firmware and causing problems on the other 99% of
devices out there.

> +struct wmi_rsn_cap_cmd {
> +       __le16 rsn_cap;
> +} __packed;
> +
>   enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
>   void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id
ep_id);
>   int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
> @@ -2728,4 +2732,7 @@ void *ath6kl_wmi_init(struct ath6kl *devt);
>   void ath6kl_wmi_shutdown(struct wmi *wmi);
>   void ath6kl_wmi_reset(struct wmi *wmi);

> +int ath6kl_wmi_set_rsn_cap(struct wmi *wmi, u8 if_idx, u16 rsn_cap);
> +int ath6kl_wmi_get_rsn_cap(struct wmi *wmi, u8 if_idx);
> +
>   #endif /* WMI_H */
> --
> 2.14.1


 From your answer to Kalle re: what hardware

> I have tested this in an Atheros QCA6234. kmsg shows this about the fw:

> ath6kl: ar6004 hw 3.0 sdio fw 3.5.0.604 api 1
> ath6kl: firmware supports: 64bit-rates,ap-inactivity-mins

The firmware you're using is old. Mine for the QCA6234 is more advanced
than that and has the rsn-cap-override flag, but even the stock one in
linux-firmware is more up-to-date: 3.5.0.2356 api 3. I haven't run it
recently to see if it also has the rsn-cap-override flag, but it might.
Maybe you can try the current firmware to see if it solves your issue?

Thanks,
- Steve

--
Steve deRosier
Cal-Sierra Consulting
https://www.cal-sierra.com/
Alfonso Sánchez-Beato April 27, 2018, 4:57 p.m. UTC | #6
Hi Steve,

On Fri, Apr 27, 2018 at 5:47 PM, Steve deRosier <derosier@gmail.com> wrote:
> Hi Alfonso,
>
> On Thu, Apr 12, 2018 at 8:42 AM Alfonso Sánchez-Beato <
> alfonso.sanchez-beato@canonical.com> wrote:
>
>> This fixes AP mode when the ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE flag
>> is not present in the FW. The id of some WMI commands is also fixed
>> (there was an error in the enum order), and a function to set RSN caps
>> is added.
>
>> Signed-off-by: Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>
>> ---
>>   drivers/net/wireless/ath/ath6kl/cfg80211.c | 21 ++++++---------------
>>   drivers/net/wireless/ath/ath6kl/main.c     | 10 +++-------
>>   drivers/net/wireless/ath/ath6kl/wmi.c      | 23 +++++++++++++++++++++++
>>   drivers/net/wireless/ath/ath6kl/wmi.h      | 15 +++++++++++----
>>   4 files changed, 43 insertions(+), 26 deletions(-)
>
>> diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c
> b/drivers/net/wireless/ath/ath6kl/cfg80211.c
>> index 2ba8cf3f38af..1b89c53d47e7 100644
>> --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
>> +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
>> @@ -2933,13 +2933,11 @@ static int ath6kl_start_ap(struct wiphy *wiphy,
> struct net_device *dev,
>>           * advertise the same in beacon/probe response. Send
>>           * the complete RSN IE capability field to firmware
>>           */
>> -       if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
>> -           test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
>> -                    ar->fw_capabilities)) {
>> -               res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
>> -                                           WLAN_EID_RSN, WMI_RSN_IE_CAPB,
>> -                                           (const u8 *) &rsn_capab,
>> -                                           sizeof(rsn_capab));
>> +       if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *)&rsn_capab)) {
>> +               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "RSN caps %d\n",
> rsn_capab);
>> +
>> +               res = ath6kl_wmi_set_rsn_cap(ar->wmi, vif->fw_vif_idx,
>> +                                            rsn_capab);
>>                  vif->rsn_capab = rsn_capab;
>>                  if (res < 0)
>>                          return res;
>
> So, let me see if I understand this correctly.  Original flow was:
>
> 1. get RSN capable from the beacon if one
> 2. if the firmware is capable of the override, set the IE  else don't do
> anything
>
> New flow:
> 1. get RSN capable from the beacon if one
> 2. unconditionally send the rsn_cap WMI down
>
> So, what happens on a firmware that _does_ have the rsn-cap-override flag
> set? I'm guessing nothing good.  Admittedly I haven't tried your patch on
> my platform.
>
> I think that simply ignoring the flag and using a WMI instead of setting
> the IE on all devices AR6002..AR6004 is likely going to cause problems for
> everyone else.

Admittedly, I have not a wide range of devices to test. This patch was
mostly an RFC to see if the issue is only for a particular fw revision
and to expose it for people that might find it useful. Note that I am
not the first person to hit this, see for instance

http://www.spinics.net/lists/linux-wireless/msg115085.html

>
>
>> @@ -3918,14 +3916,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
>>                  return -EINVAL;
>>          }
>
>> -       /*
>> -        * Even if the fw has HT support, advertise HT cap only when
>> -        * the firmware has support to override RSN capability, otherwise
>> -        * 4-way handshake would fail.
>> -        */
>> -       if (!(ht &&
>> -             test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
>> -                      ar->fw_capabilities))) {
>> +       if (!ht) {
>
> Perhaps the comment isn't relevant if we're using the RSN WMI command on a
> device with the flag, but I'm willing to bet you neither tested it nor that
> the assumption is true.  I'm guessing this change just broke the 4-way
> handshake for the majority of devices.
>
>>                  ath6kl_band_2ghz.ht_cap.cap = 0;
>>                  ath6kl_band_2ghz.ht_cap.ht_supported = false;
>>                  ath6kl_band_5ghz.ht_cap.cap = 0;
>> diff --git a/drivers/net/wireless/ath/ath6kl/main.c
> b/drivers/net/wireless/ath/ath6kl/main.c
>> index db95f85751e3..4e186f8b3950 100644
>> --- a/drivers/net/wireless/ath/ath6kl/main.c
>> +++ b/drivers/net/wireless/ath/ath6kl/main.c
>> @@ -579,13 +579,9 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif
> *vif, u16 channel)
>>                   * reconfigure any saved RSN IE capabilites in the beacon
> /
>>                   * probe response to stay in sync with the supplicant.
>>                   */
>> -               if (vif->rsn_capab &&
>> -                   test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
>> -                            ar->fw_capabilities))
>> -                       ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
>> -                                             WLAN_EID_RSN,
> WMI_RSN_IE_CAPB,
>> -                                             (const u8 *)
> &vif->rsn_capab,
>> -                                             sizeof(vif->rsn_capab));
>> +               if (vif->rsn_capab)
>> +                       ath6kl_wmi_set_rsn_cap(ar->wmi, vif->fw_vif_idx,
>> +                                              vif->rsn_capab);
>
>
> So, basically same comment as the first one.
>
>>                  return ath6kl_wmi_ap_profile_commit(ar->wmi,
> vif->fw_vif_idx,
>>                                                      &vif->profile);
>> diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c
> b/drivers/net/wireless/ath/ath6kl/wmi.c
>> index 777acc564ac9..d7de9224d755 100644
>> --- a/drivers/net/wireless/ath/ath6kl/wmi.c
>> +++ b/drivers/net/wireless/ath/ath6kl/wmi.c
>> @@ -4168,3 +4168,26 @@ void ath6kl_wmi_shutdown(struct wmi *wmi)
>>          kfree(wmi->last_mgmt_tx_frame);
>>          kfree(wmi);
>>   }
>> +
>> +int ath6kl_wmi_set_rsn_cap(struct wmi *wmi, u8 if_idx, u16 rsn_cap)
>> +{
>> +       struct sk_buff *skb;
>> +       struct wmi_rsn_cap_cmd *cmd;
>> +
>> +       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
>> +       if (!skb)
>> +               return -ENOMEM;
>> +
>> +       ath6kl_dbg(ATH6KL_DBG_WMI, "set_rsn_cap: 0x%04x\n", rsn_cap);
>> +
>> +       cmd = (struct wmi_rsn_cap_cmd *)skb->data;
>> +       cmd->rsn_cap = cpu_to_le16(rsn_cap);
>> +
>> +       return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
> WMI_SET_RSN_CAP_CMDID,
>> +                                  NO_SYNC_WMIFLAG);
>> +}
>> +
>> +int ath6kl_wmi_get_rsn_cap(struct wmi *wmi, u8 if_idx)
>> +{
>> +       return ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_GET_RSN_CAP_CMDID);
>> +}
>> diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h
> b/drivers/net/wireless/ath/ath6kl/wmi.h
>> index a60bb49fe920..011d4b6fb5ab 100644
>> --- a/drivers/net/wireless/ath/ath6kl/wmi.h
>> +++ b/drivers/net/wireless/ath/ath6kl/wmi.h
>> @@ -597,10 +597,6 @@ enum wmi_cmd_id {
>
>>          WMI_GREENTX_PARAMS_CMDID,
>
>> -       WMI_RTT_MEASREQ_CMDID,
>> -       WMI_RTT_CAPREQ_CMDID,
>> -       WMI_RTT_STATUSREQ_CMDID,
>> -
>>          /* WPS Commands */
>>          WMI_WPS_START_CMDID,
>>          WMI_GET_WPS_STATUS_CMDID,
>> @@ -621,6 +617,10 @@ enum wmi_cmd_id {
>>          WMI_RX_FILTER_COALESCE_FILTER_OP_CMDID,
>>          WMI_RX_FILTER_SET_FRAME_TEST_LIST_CMDID,
>
>> +       WMI_RTT_MEASREQ_CMDID,
>> +       WMI_RTT_CAPREQ_CMDID,
>> +       WMI_RTT_STATUSREQ_CMDID,
>> +
>>          WMI_SEND_MGMT_CMDID,
>>          WMI_BEGIN_SCAN_CMDID,
>
>> @@ -2533,6 +2533,10 @@ enum wmi_sync_flag {
>>          END_WMIFLAG
>>   };
>
>
> I can factually state that the above reordering of the commands is wrong
> for a 6003. The order in the WMI file is consistent for a 6003. Your
> reordering is consistent for a 6004. Now, the only commands affected by the
> reordering aren't utilized by the driver, other than your added get/set
> RSN_CAP_CMDIDs.  But on a 6003, your now used WMI_SET_RSN_CAP_CMDID will
> trigger a WMI_GET_OPPPS_CMDID, which isn't what you want.
>
> I've encountered this issue a before - wmi code mismatch between the
> different firmwares and the driver. This is a limitation of the driver that
> probably should be resolved in some meaningful way. To date, it's been
> mitigated by the driver just not using the higher-numbered commands.  But
> by "meaningful way" I don't include redefining command IDs in favor of one
> particular person's firmware and causing problems on the other 99% of
> devices out there.

Agreed. I do not have access to much information for the ath6k, so
this was more like a shot in the dark.

>
>> +struct wmi_rsn_cap_cmd {
>> +       __le16 rsn_cap;
>> +} __packed;
>> +
>>   enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
>>   void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id
> ep_id);
>>   int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
>> @@ -2728,4 +2732,7 @@ void *ath6kl_wmi_init(struct ath6kl *devt);
>>   void ath6kl_wmi_shutdown(struct wmi *wmi);
>>   void ath6kl_wmi_reset(struct wmi *wmi);
>
>> +int ath6kl_wmi_set_rsn_cap(struct wmi *wmi, u8 if_idx, u16 rsn_cap);
>> +int ath6kl_wmi_get_rsn_cap(struct wmi *wmi, u8 if_idx);
>> +
>>   #endif /* WMI_H */
>> --
>> 2.14.1
>
>
>  From your answer to Kalle re: what hardware
>
>> I have tested this in an Atheros QCA6234. kmsg shows this about the fw:
>
>> ath6kl: ar6004 hw 3.0 sdio fw 3.5.0.604 api 1
>> ath6kl: firmware supports: 64bit-rates,ap-inactivity-mins
>
> The firmware you're using is old. Mine for the QCA6234 is more advanced
> than that and has the rsn-cap-override flag, but even the stock one in
> linux-firmware is more up-to-date: 3.5.0.2356 api 3. I haven't run it
> recently to see if it also has the rsn-cap-override flag, but it might.
> Maybe you can try the current firmware to see if it solves your issue?

This is hw 3.0, there is actually no ath6k/AR6004/hw3.0 folder in
linux-firmware. I would appreciate pointers for more modern fw for
this hardware version if you have them.

>
> Thanks,
> - Steve

Thanks,
Alfonso

>
> --
> Steve deRosier
> Cal-Sierra Consulting
> https://www.cal-sierra.com/
Steve deRosier April 27, 2018, 5:34 p.m. UTC | #7
On Fri, Apr 27, 2018 at 9:57 AM Alfonso Sanchez-Beato <
alfonso.sanchez-beato@canonical.com> wrote:

> Hi Steve,

> On Fri, Apr 27, 2018 at 5:47 PM, Steve deRosier <derosier@gmail.com>
wrote:
> > Hi Alfonso,
> >
> > On Thu, Apr 12, 2018 at 8:42 AM Alfonso Sánchez-Beato <
> > alfonso.sanchez-beato@canonical.com> wrote:
> >
> >> This fixes AP mode when the ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE flag
> >> is not present in the FW. The id of some WMI commands is also fixed
> >> (there was an error in the enum order), and a function to set RSN caps
> >> is added.
> >
> >> Signed-off-by: Alfonso Sánchez-Beato <
alfonso.sanchez-beato@canonical.com>
> >> ---
> >>   drivers/net/wireless/ath/ath6kl/cfg80211.c | 21 ++++++---------------
> >>   drivers/net/wireless/ath/ath6kl/main.c     | 10 +++-------
> >>   drivers/net/wireless/ath/ath6kl/wmi.c      | 23
+++++++++++++++++++++++
> >>   drivers/net/wireless/ath/ath6kl/wmi.h      | 15 +++++++++++----
> >>   4 files changed, 43 insertions(+), 26 deletions(-)
> >
> >> diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c
> > b/drivers/net/wireless/ath/ath6kl/cfg80211.c
> >> index 2ba8cf3f38af..1b89c53d47e7 100644
> >> --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
> >> +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
> >> @@ -2933,13 +2933,11 @@ static int ath6kl_start_ap(struct wiphy *wiphy,
> > struct net_device *dev,
> >>           * advertise the same in beacon/probe response. Send
> >>           * the complete RSN IE capability field to firmware
> >>           */
> >> -       if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
> >> -           test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
> >> -                    ar->fw_capabilities)) {
> >> -               res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
> >> -                                           WLAN_EID_RSN,
WMI_RSN_IE_CAPB,
> >> -                                           (const u8 *) &rsn_capab,
> >> -                                           sizeof(rsn_capab));
> >> +       if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *)&rsn_capab)) {
> >> +               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "RSN caps %d\n",
> > rsn_capab);
> >> +
> >> +               res = ath6kl_wmi_set_rsn_cap(ar->wmi, vif->fw_vif_idx,
> >> +                                            rsn_capab);
> >>                  vif->rsn_capab = rsn_capab;
> >>                  if (res < 0)
> >>                          return res;
> >
> > So, let me see if I understand this correctly.  Original flow was:
> >
> > 1. get RSN capable from the beacon if one
> > 2. if the firmware is capable of the override, set the IE  else don't do
> > anything
> >
> > New flow:
> > 1. get RSN capable from the beacon if one
> > 2. unconditionally send the rsn_cap WMI down
> >
> > So, what happens on a firmware that _does_ have the rsn-cap-override
flag
> > set? I'm guessing nothing good.  Admittedly I haven't tried your patch
on
> > my platform.
> >
> > I think that simply ignoring the flag and using a WMI instead of setting
> > the IE on all devices AR6002..AR6004 is likely going to cause problems
for
> > everyone else.

> Admittedly, I have not a wide range of devices to test. This patch was
> mostly an RFC to see if the issue is only for a particular fw revision
> and to expose it for people that might find it useful. Note that I am
> not the first person to hit this, see for instance

> http://www.spinics.net/lists/linux-wireless/msg115085.html


Fair enough. However, breaking it for the rest of the devices out there
isn't good. I welcome the fixing of it, but it has to be done across the
spectrum of the supported chips.



> >
> >
> >> @@ -3918,14 +3916,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
> >>                  return -EINVAL;
> >>          }
> >
> >> -       /*
> >> -        * Even if the fw has HT support, advertise HT cap only when
> >> -        * the firmware has support to override RSN capability,
otherwise
> >> -        * 4-way handshake would fail.
> >> -        */
> >> -       if (!(ht &&
> >> -             test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
> >> -                      ar->fw_capabilities))) {
> >> +       if (!ht) {
> >
> > Perhaps the comment isn't relevant if we're using the RSN WMI command
on a
> > device with the flag, but I'm willing to bet you neither tested it nor
that
> > the assumption is true.  I'm guessing this change just broke the 4-way
> > handshake for the majority of devices.
> >
> >>                  ath6kl_band_2ghz.ht_cap.cap = 0;
> >>                  ath6kl_band_2ghz.ht_cap.ht_supported = false;
> >>                  ath6kl_band_5ghz.ht_cap.cap = 0;
> >> diff --git a/drivers/net/wireless/ath/ath6kl/main.c
> > b/drivers/net/wireless/ath/ath6kl/main.c
> >> index db95f85751e3..4e186f8b3950 100644
> >> --- a/drivers/net/wireless/ath/ath6kl/main.c
> >> +++ b/drivers/net/wireless/ath/ath6kl/main.c
> >> @@ -579,13 +579,9 @@ static int ath6kl_commit_ch_switch(struct
ath6kl_vif
> > *vif, u16 channel)
> >>                   * reconfigure any saved RSN IE capabilites in the
beacon
> > /
> >>                   * probe response to stay in sync with the supplicant.
> >>                   */
> >> -               if (vif->rsn_capab &&
> >> -                   test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
> >> -                            ar->fw_capabilities))
> >> -                       ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
> >> -                                             WLAN_EID_RSN,
> > WMI_RSN_IE_CAPB,
> >> -                                             (const u8 *)
> > &vif->rsn_capab,
> >> -                                             sizeof(vif->rsn_capab));
> >> +               if (vif->rsn_capab)
> >> +                       ath6kl_wmi_set_rsn_cap(ar->wmi,
vif->fw_vif_idx,
> >> +                                              vif->rsn_capab);
> >
> >
> > So, basically same comment as the first one.
> >
> >>                  return ath6kl_wmi_ap_profile_commit(ar->wmi,
> > vif->fw_vif_idx,
> >>                                                      &vif->profile);
> >> diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c
> > b/drivers/net/wireless/ath/ath6kl/wmi.c
> >> index 777acc564ac9..d7de9224d755 100644
> >> --- a/drivers/net/wireless/ath/ath6kl/wmi.c
> >> +++ b/drivers/net/wireless/ath/ath6kl/wmi.c
> >> @@ -4168,3 +4168,26 @@ void ath6kl_wmi_shutdown(struct wmi *wmi)
> >>          kfree(wmi->last_mgmt_tx_frame);
> >>          kfree(wmi);
> >>   }
> >> +
> >> +int ath6kl_wmi_set_rsn_cap(struct wmi *wmi, u8 if_idx, u16 rsn_cap)
> >> +{
> >> +       struct sk_buff *skb;
> >> +       struct wmi_rsn_cap_cmd *cmd;
> >> +
> >> +       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
> >> +       if (!skb)
> >> +               return -ENOMEM;
> >> +
> >> +       ath6kl_dbg(ATH6KL_DBG_WMI, "set_rsn_cap: 0x%04x\n", rsn_cap);
> >> +
> >> +       cmd = (struct wmi_rsn_cap_cmd *)skb->data;
> >> +       cmd->rsn_cap = cpu_to_le16(rsn_cap);
> >> +
> >> +       return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
> > WMI_SET_RSN_CAP_CMDID,
> >> +                                  NO_SYNC_WMIFLAG);
> >> +}
> >> +
> >> +int ath6kl_wmi_get_rsn_cap(struct wmi *wmi, u8 if_idx)
> >> +{
> >> +       return ath6kl_wmi_simple_cmd(wmi, if_idx,
WMI_GET_RSN_CAP_CMDID);
> >> +}
> >> diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h
> > b/drivers/net/wireless/ath/ath6kl/wmi.h
> >> index a60bb49fe920..011d4b6fb5ab 100644
> >> --- a/drivers/net/wireless/ath/ath6kl/wmi.h
> >> +++ b/drivers/net/wireless/ath/ath6kl/wmi.h
> >> @@ -597,10 +597,6 @@ enum wmi_cmd_id {
> >
> >>          WMI_GREENTX_PARAMS_CMDID,
> >
> >> -       WMI_RTT_MEASREQ_CMDID,
> >> -       WMI_RTT_CAPREQ_CMDID,
> >> -       WMI_RTT_STATUSREQ_CMDID,
> >> -
> >>          /* WPS Commands */
> >>          WMI_WPS_START_CMDID,
> >>          WMI_GET_WPS_STATUS_CMDID,
> >> @@ -621,6 +617,10 @@ enum wmi_cmd_id {
> >>          WMI_RX_FILTER_COALESCE_FILTER_OP_CMDID,
> >>          WMI_RX_FILTER_SET_FRAME_TEST_LIST_CMDID,
> >
> >> +       WMI_RTT_MEASREQ_CMDID,
> >> +       WMI_RTT_CAPREQ_CMDID,
> >> +       WMI_RTT_STATUSREQ_CMDID,
> >> +
> >>          WMI_SEND_MGMT_CMDID,
> >>          WMI_BEGIN_SCAN_CMDID,
> >
> >> @@ -2533,6 +2533,10 @@ enum wmi_sync_flag {
> >>          END_WMIFLAG
> >>   };
> >
> >
> > I can factually state that the above reordering of the commands is wrong
> > for a 6003. The order in the WMI file is consistent for a 6003. Your
> > reordering is consistent for a 6004. Now, the only commands affected by
the
> > reordering aren't utilized by the driver, other than your added get/set
> > RSN_CAP_CMDIDs.  But on a 6003, your now used WMI_SET_RSN_CAP_CMDID will
> > trigger a WMI_GET_OPPPS_CMDID, which isn't what you want.
> >
> > I've encountered this issue a before - wmi code mismatch between the
> > different firmwares and the driver. This is a limitation of the driver
that
> > probably should be resolved in some meaningful way. To date, it's been
> > mitigated by the driver just not using the higher-numbered commands.
But
> > by "meaningful way" I don't include redefining command IDs in favor of
one
> > particular person's firmware and causing problems on the other 99% of
> > devices out there.

> Agreed. I do not have access to much information for the ath6k, so
> this was more like a shot in the dark.

> >
> >> +struct wmi_rsn_cap_cmd {
> >> +       __le16 rsn_cap;
> >> +} __packed;
> >> +
> >>   enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
> >>   void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id
> > ep_id);
> >>   int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
> >> @@ -2728,4 +2732,7 @@ void *ath6kl_wmi_init(struct ath6kl *devt);
> >>   void ath6kl_wmi_shutdown(struct wmi *wmi);
> >>   void ath6kl_wmi_reset(struct wmi *wmi);
> >
> >> +int ath6kl_wmi_set_rsn_cap(struct wmi *wmi, u8 if_idx, u16 rsn_cap);
> >> +int ath6kl_wmi_get_rsn_cap(struct wmi *wmi, u8 if_idx);
> >> +
> >>   #endif /* WMI_H */
> >> --
> >> 2.14.1
> >
> >
> >  From your answer to Kalle re: what hardware
> >
> >> I have tested this in an Atheros QCA6234. kmsg shows this about the fw:
> >
> >> ath6kl: ar6004 hw 3.0 sdio fw 3.5.0.604 api 1
> >> ath6kl: firmware supports: 64bit-rates,ap-inactivity-mins
> >
> > The firmware you're using is old. Mine for the QCA6234 is more advanced
> > than that and has the rsn-cap-override flag, but even the stock one in
> > linux-firmware is more up-to-date: 3.5.0.2356 api 3. I haven't run it
> > recently to see if it also has the rsn-cap-override flag, but it might.
> > Maybe you can try the current firmware to see if it solves your issue?

> This is hw 3.0, there is actually no ath6k/AR6004/hw3.0 folder in
> linux-firmware. I would appreciate pointers for more modern fw for
> this hardware version if you have them.

Ah.  Silly me, I just looked at the highest number in linux-firmware.
You're right, there's no HW 3.0 in there. I know there's a publically
available firmware for HW 3.0 out there, because I have a note on it, but I
don't recall where I saw it as it's been years.

@Kalle - do you have a more recent official QCA drop for this chip? And if
so, can we get it into linux-firmware?

You never said who's module you're using. If it's a Laird SD/MSD/WB50NBT,
the firmware I use has the rsn-cap-override and is easy to get from them.
It should look like:
     ar6004 hw 3.0 sdio fw 3.5.0.10011 api 5
     firmware supports:
sched-scan,rsn-cap-override,sscan-match-list,rssi-scan-thold,tx-err-notify,sched-scan-v2,hb-poll,64bit-rates,no-ip-checksu

There possibly is a more current version than I have on-hand.

- Steve

--
Steve deRosier
Cal-Sierra Consulting
https://www.cal-sierra.com/
diff mbox

Patch

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 2ba8cf3f38af..1b89c53d47e7 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2933,13 +2933,11 @@  static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
 	 * advertise the same in beacon/probe response. Send
 	 * the complete RSN IE capability field to firmware
 	 */
-	if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
-	    test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
-		     ar->fw_capabilities)) {
-		res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
-					    WLAN_EID_RSN, WMI_RSN_IE_CAPB,
-					    (const u8 *) &rsn_capab,
-					    sizeof(rsn_capab));
+	if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *)&rsn_capab)) {
+		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "RSN caps %d\n", rsn_capab);
+
+		res = ath6kl_wmi_set_rsn_cap(ar->wmi, vif->fw_vif_idx,
+					     rsn_capab);
 		vif->rsn_capab = rsn_capab;
 		if (res < 0)
 			return res;
@@ -3918,14 +3916,7 @@  int ath6kl_cfg80211_init(struct ath6kl *ar)
 		return -EINVAL;
 	}
 
-	/*
-	 * Even if the fw has HT support, advertise HT cap only when
-	 * the firmware has support to override RSN capability, otherwise
-	 * 4-way handshake would fail.
-	 */
-	if (!(ht &&
-	      test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
-		       ar->fw_capabilities))) {
+	if (!ht) {
 		ath6kl_band_2ghz.ht_cap.cap = 0;
 		ath6kl_band_2ghz.ht_cap.ht_supported = false;
 		ath6kl_band_5ghz.ht_cap.cap = 0;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index db95f85751e3..4e186f8b3950 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -579,13 +579,9 @@  static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)
 		 * reconfigure any saved RSN IE capabilites in the beacon /
 		 * probe response to stay in sync with the supplicant.
 		 */
-		if (vif->rsn_capab &&
-		    test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
-			     ar->fw_capabilities))
-			ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
-					      WLAN_EID_RSN, WMI_RSN_IE_CAPB,
-					      (const u8 *) &vif->rsn_capab,
-					      sizeof(vif->rsn_capab));
+		if (vif->rsn_capab)
+			ath6kl_wmi_set_rsn_cap(ar->wmi, vif->fw_vif_idx,
+					       vif->rsn_capab);
 
 		return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx,
 						    &vif->profile);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 777acc564ac9..d7de9224d755 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -4168,3 +4168,26 @@  void ath6kl_wmi_shutdown(struct wmi *wmi)
 	kfree(wmi->last_mgmt_tx_frame);
 	kfree(wmi);
 }
+
+int ath6kl_wmi_set_rsn_cap(struct wmi *wmi, u8 if_idx, u16 rsn_cap)
+{
+	struct sk_buff *skb;
+	struct wmi_rsn_cap_cmd *cmd;
+
+	skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	ath6kl_dbg(ATH6KL_DBG_WMI, "set_rsn_cap: 0x%04x\n", rsn_cap);
+
+	cmd = (struct wmi_rsn_cap_cmd *)skb->data;
+	cmd->rsn_cap = cpu_to_le16(rsn_cap);
+
+	return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_RSN_CAP_CMDID,
+				   NO_SYNC_WMIFLAG);
+}
+
+int ath6kl_wmi_get_rsn_cap(struct wmi *wmi, u8 if_idx)
+{
+	return ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_GET_RSN_CAP_CMDID);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index a60bb49fe920..011d4b6fb5ab 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -597,10 +597,6 @@  enum wmi_cmd_id {
 
 	WMI_GREENTX_PARAMS_CMDID,
 
-	WMI_RTT_MEASREQ_CMDID,
-	WMI_RTT_CAPREQ_CMDID,
-	WMI_RTT_STATUSREQ_CMDID,
-
 	/* WPS Commands */
 	WMI_WPS_START_CMDID,
 	WMI_GET_WPS_STATUS_CMDID,
@@ -621,6 +617,10 @@  enum wmi_cmd_id {
 	WMI_RX_FILTER_COALESCE_FILTER_OP_CMDID,
 	WMI_RX_FILTER_SET_FRAME_TEST_LIST_CMDID,
 
+	WMI_RTT_MEASREQ_CMDID,
+	WMI_RTT_CAPREQ_CMDID,
+	WMI_RTT_STATUSREQ_CMDID,
+
 	WMI_SEND_MGMT_CMDID,
 	WMI_BEGIN_SCAN_CMDID,
 
@@ -2533,6 +2533,10 @@  enum wmi_sync_flag {
 	END_WMIFLAG
 };
 
+struct wmi_rsn_cap_cmd {
+	__le16 rsn_cap;
+} __packed;
+
 enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
 void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id);
 int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
@@ -2728,4 +2732,7 @@  void *ath6kl_wmi_init(struct ath6kl *devt);
 void ath6kl_wmi_shutdown(struct wmi *wmi);
 void ath6kl_wmi_reset(struct wmi *wmi);
 
+int ath6kl_wmi_set_rsn_cap(struct wmi *wmi, u8 if_idx, u16 rsn_cap);
+int ath6kl_wmi_get_rsn_cap(struct wmi *wmi, u8 if_idx);
+
 #endif /* WMI_H */