diff mbox

[4/7] brcmfmac: obtain feature info using 'cap' firmware command

Message ID 1450100394-17414-5-git-send-email-arend@broadcom.com (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show

Commit Message

Arend van Spriel Dec. 14, 2015, 1:39 p.m. UTC
Several features in the driver directly map to a firmware feature
listed in response of the 'cap' firmware command. For those features
this response will be examined instead of attempting individual
firmware commands.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 51 +++++++++++++---------
 1 file changed, 30 insertions(+), 21 deletions(-)

Comments

Mathy Vanhoef Dec. 29, 2015, 8:58 p.m. UTC | #1
On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <arend@broadcom.com> wrote:
> Several features in the driver directly map to a firmware feature
> listed in response of the 'cap' firmware command. For those features
> this response will be examined instead of attempting individual
> firmware commands.
>
> Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
> Signed-off-by: Arend van Spriel <arend@broadcom.com>
> ---
>  .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 51 +++++++++++++---------
>  1 file changed, 30 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
> index d9d1ca4..08b7200 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
> @@ -40,6 +40,17 @@ static const char *brcmf_feat_names[] = {
>  };
>  #undef BRCMF_FEAT_DEF
>
> +struct brcmf_feat_fwcap {
> +       enum brcmf_feat_id feature;
> +       const char * const fwcap_id;
> +};
> +
> +static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
> +       { BRCMF_FEAT_MBSS, "mbss" },
> +       { BRCMF_FEAT_MCHAN, "mchan" },
> +       { BRCMF_FEAT_P2P, "p2p" },
> +};
> +
>  #ifdef DEBUG
>  /*
>   * expand quirk list to array of quirk strings.
> @@ -104,25 +115,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
>         }
>  }
>
> -/**
> - * brcmf_feat_iovar_int_set() - determine feature through iovar set.
> - *
> - * @ifp: interface to query.
> - * @id: feature id.
> - * @name: iovar name.
> - */
> -static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
> -                                    enum brcmf_feat_id id, char *name, u32 val)
> +static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
>  {
> -       int err;
> -
> -       err = brcmf_fil_iovar_int_set(ifp, name, val);
> -       if (err == 0) {
> -               brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
> -               ifp->drvr->feat_flags |= BIT(id);
> -       } else {
> -               brcmf_dbg(TRACE, "%s feature check failed: %d\n",
> -                         brcmf_feat_names[id], err);
> +       char caps[256];
> +       enum brcmf_feat_id id;
> +       int i;
> +
> +       brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
> +       brcmf_dbg(INFO, "[ %s]\n", caps);
> +
> +       for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
> +               if (strnstr(caps, brcmf_fwcap_map[i].fwcap_id, sizeof(caps))) {
> +                       id = brcmf_fwcap_map[i].feature;
> +                       brcmf_dbg(INFO, "enabling feature: %s\n",
> +                                 brcmf_feat_names[id]);
> +                       ifp->drvr->feat_flags |= BIT(id);
> +               }
>         }
>  }
>
> @@ -130,13 +138,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
>  {
>         struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
>
> -       brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
> +       brcmf_feat_firmware_capabilities(ifp);
> +
>         brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
>         if (drvr->bus_if->wowl_supported)
>                 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
> +       /* MBSS does not work for 43362 */
>         if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
> -               brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
> -       brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
> +               ifp->drvr->feat_flags &= BIT(BRCMF_FEAT_MBSS);

Missing ~ before the BIT() declaration? If the if-test fails, all bits are
cleared except BRCMF_FEAT_MBSS. I think the if-test also needs to be updated
to an equals `==` instead of the old inequality. So one would get:

/* clear MBSS feature for the 43362 (does not work) */
if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
    ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);

Also, happy holidays!
Mathy

>         brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
>         brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
>
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arend Van Spriel Dec. 31, 2015, 9:55 p.m. UTC | #2
On 29-12-15 21:58, Mathy Vanhoef wrote:
> On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <arend@broadcom.com> wrote:
>> Several features in the driver directly map to a firmware feature
>> listed in response of the 'cap' firmware command. For those features
>> this response will be examined instead of attempting individual
>> firmware commands.
>>
>> Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
>> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
>> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
>> Signed-off-by: Arend van Spriel <arend@broadcom.com>
>> ---
>>  .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 51 +++++++++++++---------
>>  1 file changed, 30 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> index d9d1ca4..08b7200 100644
>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> @@ -40,6 +40,17 @@ static const char *brcmf_feat_names[] = {
>>  };
>>  #undef BRCMF_FEAT_DEF
>>
>> +struct brcmf_feat_fwcap {
>> +       enum brcmf_feat_id feature;
>> +       const char * const fwcap_id;
>> +};
>> +
>> +static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
>> +       { BRCMF_FEAT_MBSS, "mbss" },
>> +       { BRCMF_FEAT_MCHAN, "mchan" },
>> +       { BRCMF_FEAT_P2P, "p2p" },
>> +};
>> +
>>  #ifdef DEBUG
>>  /*
>>   * expand quirk list to array of quirk strings.
>> @@ -104,25 +115,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
>>         }
>>  }
>>
>> -/**
>> - * brcmf_feat_iovar_int_set() - determine feature through iovar set.
>> - *
>> - * @ifp: interface to query.
>> - * @id: feature id.
>> - * @name: iovar name.
>> - */
>> -static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
>> -                                    enum brcmf_feat_id id, char *name, u32 val)
>> +static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
>>  {
>> -       int err;
>> -
>> -       err = brcmf_fil_iovar_int_set(ifp, name, val);
>> -       if (err == 0) {
>> -               brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
>> -               ifp->drvr->feat_flags |= BIT(id);
>> -       } else {
>> -               brcmf_dbg(TRACE, "%s feature check failed: %d\n",
>> -                         brcmf_feat_names[id], err);
>> +       char caps[256];
>> +       enum brcmf_feat_id id;
>> +       int i;
>> +
>> +       brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
>> +       brcmf_dbg(INFO, "[ %s]\n", caps);
>> +
>> +       for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
>> +               if (strnstr(caps, brcmf_fwcap_map[i].fwcap_id, sizeof(caps))) {
>> +                       id = brcmf_fwcap_map[i].feature;
>> +                       brcmf_dbg(INFO, "enabling feature: %s\n",
>> +                                 brcmf_feat_names[id]);
>> +                       ifp->drvr->feat_flags |= BIT(id);
>> +               }
>>         }
>>  }
>>
>> @@ -130,13 +138,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
>>  {
>>         struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
>>
>> -       brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
>> +       brcmf_feat_firmware_capabilities(ifp);
>> +
>>         brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
>>         if (drvr->bus_if->wowl_supported)
>>                 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
>> +       /* MBSS does not work for 43362 */
>>         if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
>> -               brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
>> -       brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
>> +               ifp->drvr->feat_flags &= BIT(BRCMF_FEAT_MBSS);
> 
> Missing ~ before the BIT() declaration? If the if-test fails, all bits are
> cleared except BRCMF_FEAT_MBSS. I think the if-test also needs to be updated
> to an equals `==` instead of the old inequality. So one would get:
> 
> /* clear MBSS feature for the 43362 (does not work) */
> if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
>     ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);

Geez. You are absolutely right. Apparently my head was already in
christmas mode writing that code.

Thanks,
Arend

> Also, happy holidays!
> Mathy
> 
>>         brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
>>         brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
>>
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arend van Spriel Jan. 1, 2016, 7:05 a.m. UTC | #3
On 12/29/2015 09:58 PM, Mathy Vanhoef wrote:
> On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <arend@broadcom.com> wrote:
>> Several features in the driver directly map to a firmware feature
>> listed in response of the 'cap' firmware command. For those features
>> this response will be examined instead of attempting individual
>> firmware commands.
>>
>> Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
>> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
>> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>

Hi Mathy,

Do you want credits, ie. have "Reviewed-by:" tag added?

Regards,
Arend

>> Signed-off-by: Arend van Spriel <arend@broadcom.com>
>> ---
>>   .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 51 +++++++++++++---------
>>   1 file changed, 30 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> index d9d1ca4..08b7200 100644
>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> @@ -40,6 +40,17 @@ static const char *brcmf_feat_names[] = {
>>   };
>>   #undef BRCMF_FEAT_DEF
>>
>> +struct brcmf_feat_fwcap {
>> +       enum brcmf_feat_id feature;
>> +       const char * const fwcap_id;
>> +};
>> +
>> +static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
>> +       { BRCMF_FEAT_MBSS, "mbss" },
>> +       { BRCMF_FEAT_MCHAN, "mchan" },
>> +       { BRCMF_FEAT_P2P, "p2p" },
>> +};
>> +
>>   #ifdef DEBUG
>>   /*
>>    * expand quirk list to array of quirk strings.
>> @@ -104,25 +115,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
>>          }
>>   }
>>
>> -/**
>> - * brcmf_feat_iovar_int_set() - determine feature through iovar set.
>> - *
>> - * @ifp: interface to query.
>> - * @id: feature id.
>> - * @name: iovar name.
>> - */
>> -static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
>> -                                    enum brcmf_feat_id id, char *name, u32 val)
>> +static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
>>   {
>> -       int err;
>> -
>> -       err = brcmf_fil_iovar_int_set(ifp, name, val);
>> -       if (err == 0) {
>> -               brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
>> -               ifp->drvr->feat_flags |= BIT(id);
>> -       } else {
>> -               brcmf_dbg(TRACE, "%s feature check failed: %d\n",
>> -                         brcmf_feat_names[id], err);
>> +       char caps[256];
>> +       enum brcmf_feat_id id;
>> +       int i;
>> +
>> +       brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
>> +       brcmf_dbg(INFO, "[ %s]\n", caps);
>> +
>> +       for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
>> +               if (strnstr(caps, brcmf_fwcap_map[i].fwcap_id, sizeof(caps))) {
>> +                       id = brcmf_fwcap_map[i].feature;
>> +                       brcmf_dbg(INFO, "enabling feature: %s\n",
>> +                                 brcmf_feat_names[id]);
>> +                       ifp->drvr->feat_flags |= BIT(id);
>> +               }
>>          }
>>   }
>>
>> @@ -130,13 +138,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
>>   {
>>          struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
>>
>> -       brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
>> +       brcmf_feat_firmware_capabilities(ifp);
>> +
>>          brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
>>          if (drvr->bus_if->wowl_supported)
>>                  brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
>> +       /* MBSS does not work for 43362 */
>>          if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
>> -               brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
>> -       brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
>> +               ifp->drvr->feat_flags &= BIT(BRCMF_FEAT_MBSS);
>
> Missing ~ before the BIT() declaration? If the if-test fails, all bits are
> cleared except BRCMF_FEAT_MBSS. I think the if-test also needs to be updated
> to an equals `==` instead of the old inequality. So one would get:
>
> /* clear MBSS feature for the 43362 (does not work) */
> if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
>      ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
>
> Also, happy holidays!
> Mathy
>
>>          brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
>>          brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
>>
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mathy Vanhoef Jan. 2, 2016, 8:21 p.m. UTC | #4
On Fri, Jan 1, 2016 at 8:05 AM, Arend van Spriel <arend@broadcom.com> wrote:
> On 12/29/2015 09:58 PM, Mathy Vanhoef wrote:
>>
>> On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <arend@broadcom.com>
>> wrote:
>>>
>>> Several features in the driver directly map to a firmware feature
>>> listed in response of the 'cap' firmware command. For those features
>>> this response will be examined instead of attempting individual
>>> firmware commands.
>>>
>>> Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
>>> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
>>> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
>
>
> Hi Mathy,
>
> Do you want credits, ie. have "Reviewed-by:" tag added?

Sure, glad I could help.

Kr,
Mathy

>
> Regards,
> Arend
>
>
>>> Signed-off-by: Arend van Spriel <arend@broadcom.com>
>>> ---
>>>   .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 51
>>> +++++++++++++---------
>>>   1 file changed, 30 insertions(+), 21 deletions(-)
>>>
>>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>>> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>>> index d9d1ca4..08b7200 100644
>>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>>> @@ -40,6 +40,17 @@ static const char *brcmf_feat_names[] = {
>>>   };
>>>   #undef BRCMF_FEAT_DEF
>>>
>>> +struct brcmf_feat_fwcap {
>>> +       enum brcmf_feat_id feature;
>>> +       const char * const fwcap_id;
>>> +};
>>> +
>>> +static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
>>> +       { BRCMF_FEAT_MBSS, "mbss" },
>>> +       { BRCMF_FEAT_MCHAN, "mchan" },
>>> +       { BRCMF_FEAT_P2P, "p2p" },
>>> +};
>>> +
>>>   #ifdef DEBUG
>>>   /*
>>>    * expand quirk list to array of quirk strings.
>>> @@ -104,25 +115,22 @@ static void brcmf_feat_iovar_int_get(struct
>>> brcmf_if *ifp,
>>>          }
>>>   }
>>>
>>> -/**
>>> - * brcmf_feat_iovar_int_set() - determine feature through iovar set.
>>> - *
>>> - * @ifp: interface to query.
>>> - * @id: feature id.
>>> - * @name: iovar name.
>>> - */
>>> -static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
>>> -                                    enum brcmf_feat_id id, char *name,
>>> u32 val)
>>> +static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
>>>   {
>>> -       int err;
>>> -
>>> -       err = brcmf_fil_iovar_int_set(ifp, name, val);
>>> -       if (err == 0) {
>>> -               brcmf_dbg(INFO, "enabling feature: %s\n",
>>> brcmf_feat_names[id]);
>>> -               ifp->drvr->feat_flags |= BIT(id);
>>> -       } else {
>>> -               brcmf_dbg(TRACE, "%s feature check failed: %d\n",
>>> -                         brcmf_feat_names[id], err);
>>> +       char caps[256];
>>> +       enum brcmf_feat_id id;
>>> +       int i;
>>> +
>>> +       brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
>>> +       brcmf_dbg(INFO, "[ %s]\n", caps);
>>> +
>>> +       for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
>>> +               if (strnstr(caps, brcmf_fwcap_map[i].fwcap_id,
>>> sizeof(caps))) {
>>> +                       id = brcmf_fwcap_map[i].feature;
>>> +                       brcmf_dbg(INFO, "enabling feature: %s\n",
>>> +                                 brcmf_feat_names[id]);
>>> +                       ifp->drvr->feat_flags |= BIT(id);
>>> +               }
>>>          }
>>>   }
>>>
>>> @@ -130,13 +138,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
>>>   {
>>>          struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
>>>
>>> -       brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
>>> +       brcmf_feat_firmware_capabilities(ifp);
>>> +
>>>          brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
>>>          if (drvr->bus_if->wowl_supported)
>>>                  brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
>>> +       /* MBSS does not work for 43362 */
>>>          if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
>>> -               brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss",
>>> 0);
>>> -       brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
>>> +               ifp->drvr->feat_flags &= BIT(BRCMF_FEAT_MBSS);
>>
>>
>> Missing ~ before the BIT() declaration? If the if-test fails, all bits are
>> cleared except BRCMF_FEAT_MBSS. I think the if-test also needs to be
>> updated
>> to an equals `==` instead of the old inequality. So one would get:
>>
>> /* clear MBSS feature for the 43362 (does not work) */
>> if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
>>      ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
>>
>> Also, happy holidays!
>> Mathy
>>
>>>          brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
>>>          brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
>>>
>>> --
>>> 1.9.1
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-wireless"
>>> in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-wireless"
>> in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index d9d1ca4..08b7200 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -40,6 +40,17 @@  static const char *brcmf_feat_names[] = {
 };
 #undef BRCMF_FEAT_DEF
 
+struct brcmf_feat_fwcap {
+	enum brcmf_feat_id feature;
+	const char * const fwcap_id;
+};
+
+static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
+	{ BRCMF_FEAT_MBSS, "mbss" },
+	{ BRCMF_FEAT_MCHAN, "mchan" },
+	{ BRCMF_FEAT_P2P, "p2p" },
+};
+
 #ifdef DEBUG
 /*
  * expand quirk list to array of quirk strings.
@@ -104,25 +115,22 @@  static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
 	}
 }
 
-/**
- * brcmf_feat_iovar_int_set() - determine feature through iovar set.
- *
- * @ifp: interface to query.
- * @id: feature id.
- * @name: iovar name.
- */
-static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
-				     enum brcmf_feat_id id, char *name, u32 val)
+static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
 {
-	int err;
-
-	err = brcmf_fil_iovar_int_set(ifp, name, val);
-	if (err == 0) {
-		brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
-		ifp->drvr->feat_flags |= BIT(id);
-	} else {
-		brcmf_dbg(TRACE, "%s feature check failed: %d\n",
-			  brcmf_feat_names[id], err);
+	char caps[256];
+	enum brcmf_feat_id id;
+	int i;
+
+	brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
+	brcmf_dbg(INFO, "[ %s]\n", caps);
+
+	for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
+		if (strnstr(caps, brcmf_fwcap_map[i].fwcap_id, sizeof(caps))) {
+			id = brcmf_fwcap_map[i].feature;
+			brcmf_dbg(INFO, "enabling feature: %s\n",
+				  brcmf_feat_names[id]);
+			ifp->drvr->feat_flags |= BIT(id);
+		}
 	}
 }
 
@@ -130,13 +138,14 @@  void brcmf_feat_attach(struct brcmf_pub *drvr)
 {
 	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
 
-	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
+	brcmf_feat_firmware_capabilities(ifp);
+
 	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
 	if (drvr->bus_if->wowl_supported)
 		brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
+	/* MBSS does not work for 43362 */
 	if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
-		brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
-	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
+		ifp->drvr->feat_flags &= BIT(BRCMF_FEAT_MBSS);
 	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
 	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");