Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [REGRESSION] 3.10.{6,7} crashes on network activity
From: Arend van Spriel @ 2013-08-20  8:15 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: Greg Kroah-Hartman, Tom Gundersen, stable, Linux Wireless List,
	LKML, Johannes Berg
In-Reply-To: <5212F6E8.3090107@openwrt.org>

On 08/20/2013 06:56 AM, Felix Fietkau wrote:
> On 2013-08-20 2:28 AM, Greg Kroah-Hartman wrote:
>> On Tue, Aug 20, 2013 at 08:26:11AM +0800, Tom Gundersen wrote:
>>> On Tue, Aug 20, 2013 at 8:03 AM, Greg Kroah-Hartman
>>> <gregkh@linuxfoundation.org> wrote:
>>>> On Tue, Aug 20, 2013 at 07:59:47AM +0800, Tom Gundersen wrote:
>>>>> Hi guys,
>>>>>
>>>>> Starting with 3.10.6 (and still present in .7) I get an oops on
>>>>> connecting to the network.
>>>>>
>>>>> The attached picture shows the oops. In case it does not reach the ML,
>>>>> the top of the call trace reads:
>>>>>
>>>>> brcms_c_compute_rtscts_dur
>>>>> brcms_c_ampdu_finalize
>>>>> ampdu_finalize
>>>>> dma_txfast
>>>>> brcms_c_txfifo
>>>>> brcms_c_sendpkt_mac80211
>>>>> brcms_ops_tx
>>>>> __ieee80211_tx
>>>>>
>>>>> I bisected the problem and the first bad commit is
>>>>>
>>>>> commit ef47a5e4f1aaf1d0e2e6875e34b2c9595897bef6
>>>>> Author: Felix Fietkau <nbd@openwrt.org>
>>>>> Date:   Fri Jun 28 21:04:35 2013 +0200
>>>>>
>>>>>      mac80211/minstrel_ht: fix cck rate sampling
>>>>>
>>>>>      commit 1cd158573951f737fbc878a35cb5eb47bf9af3d5 upstream.
>>>>>
>>>>> Reverting it on top of .7 fixes the problem.
>>>>>
>>>>> I had the same (I suppose) problem on mainline some time ago, but I
>>>>> have not bisected it, verified that the problem still occurs there, or
>>>>> checked if reverting the upstream patch fixes it. I'd be happy to do
>>>>> that if it would help though.
>>>>>
>>>>> Let me know if you need any more information.
>>>>
>>>> Do you have this same problem with 3.11-rc6 as well?
>>>
>>> Yes, I just confirmed. I also confirmed that reverting the mainline
>>> commit on top of -rc6 fixes the problem.
>>
>> Great, thanks.
>>
>> Felix and Johannes, any chance we can get this reverted in Linus tree
>> soon, and push that revert back to the 3.10 stable tree as well?
> I'd like to avoid a revert, since that will simply replace one set of
> issues with another. Let's limit the use of the feature that brcmsmac
> can't handle to drivers that are known to work with it. Tom, Please
> test this patch to see if it fixes your issue.

Hi Felix,

I have been diving into root causing why brcmsmac can not handle cck 
fallback rates, because it should. Maybe it is better to flag no cck 
support and only change brcmsmac.

Regards,
Arend

> - Felix
> ---
> --- a/include/net/mac80211.h
> +++ b/include/net/mac80211.h
> @@ -1501,6 +1501,7 @@ enum ieee80211_hw_flags {
>   	IEEE80211_HW_SUPPORTS_RC_TABLE			= 1<<24,
>   	IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF		= 1<<25,
>   	IEEE80211_HW_TIMING_BEACON_ONLY			= 1<<26,
> +	IEEE80211_HW_SUPPORTS_HT_CCK_RATES		= 1<<27,
>   };
>
>   /**
> --- a/net/mac80211/rc80211_minstrel_ht.c
> +++ b/net/mac80211/rc80211_minstrel_ht.c
> @@ -828,6 +828,9 @@ minstrel_ht_update_cck(struct minstrel_p
>   	if (sband->band != IEEE80211_BAND_2GHZ)
>   		return;
>
> +	if (!(mp->hw->flags & IEEE80211_HW_SUPPORTS_HT_CCK_RATES))
> +		return;
> +
>   	mi->cck_supported = 0;
>   	mi->cck_supported_short = 0;
>   	for (i = 0; i < 4; i++) {
> --- a/drivers/net/wireless/ath/ath9k/init.c
> +++ b/drivers/net/wireless/ath/ath9k/init.c
> @@ -807,7 +807,8 @@ void ath9k_set_hw_capab(struct ath_softc
>   		IEEE80211_HW_PS_NULLFUNC_STACK |
>   		IEEE80211_HW_SPECTRUM_MGMT |
>   		IEEE80211_HW_REPORTS_TX_ACK_STATUS |
> -		IEEE80211_HW_SUPPORTS_RC_TABLE;
> +		IEEE80211_HW_SUPPORTS_RC_TABLE |
> +		IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
>
>   	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
>   		hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
> --- a/drivers/net/wireless/ath/carl9170/main.c
> +++ b/drivers/net/wireless/ath/carl9170/main.c
> @@ -1878,7 +1878,8 @@ void *carl9170_alloc(size_t priv_size)
>   		     IEEE80211_HW_PS_NULLFUNC_STACK |
>   		     IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC |
>   		     IEEE80211_HW_SUPPORTS_RC_TABLE |
> -		     IEEE80211_HW_SIGNAL_DBM;
> +		     IEEE80211_HW_SIGNAL_DBM |
> +		     IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
>
>   	if (!modparam_noht) {
>   		/*
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -6327,7 +6327,8 @@ static int rt2800_probe_hw_mode(struct r
>   	    IEEE80211_HW_SUPPORTS_PS |
>   	    IEEE80211_HW_PS_NULLFUNC_STACK |
>   	    IEEE80211_HW_AMPDU_AGGREGATION |
> -	    IEEE80211_HW_REPORTS_TX_ACK_STATUS;
> +	    IEEE80211_HW_REPORTS_TX_ACK_STATUS |
> +	    IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
>
>   	/*
>   	 * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>



^ permalink raw reply

* Re: [REGRESSION] 3.10.{6,7} crashes on network activity
From: Tom Gundersen @ 2013-08-20  8:34 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: Greg Kroah-Hartman, stable, Linux Wireless List, LKML,
	Johannes Berg
In-Reply-To: <5212F6E8.3090107@openwrt.org>

On Tue, Aug 20, 2013 at 12:56 PM, Felix Fietkau <nbd@openwrt.org> wrote:
> On 2013-08-20 2:28 AM, Greg Kroah-Hartman wrote:
>> On Tue, Aug 20, 2013 at 08:26:11AM +0800, Tom Gundersen wrote:
>>> On Tue, Aug 20, 2013 at 8:03 AM, Greg Kroah-Hartman
>>> <gregkh@linuxfoundation.org> wrote:
>>> > On Tue, Aug 20, 2013 at 07:59:47AM +0800, Tom Gundersen wrote:
>>> >> Hi guys,
>>> >>
>>> >> Starting with 3.10.6 (and still present in .7) I get an oops on
>>> >> connecting to the network.
>>> >>
>>> >> The attached picture shows the oops. In case it does not reach the ML,
>>> >> the top of the call trace reads:
>>> >>
>>> >> brcms_c_compute_rtscts_dur
>>> >> brcms_c_ampdu_finalize
>>> >> ampdu_finalize
>>> >> dma_txfast
>>> >> brcms_c_txfifo
>>> >> brcms_c_sendpkt_mac80211
>>> >> brcms_ops_tx
>>> >> __ieee80211_tx
>>> >>
>>> >> I bisected the problem and the first bad commit is
>>> >>
>>> >> commit ef47a5e4f1aaf1d0e2e6875e34b2c9595897bef6
>>> >> Author: Felix Fietkau <nbd@openwrt.org>
>>> >> Date:   Fri Jun 28 21:04:35 2013 +0200
>>> >>
>>> >>     mac80211/minstrel_ht: fix cck rate sampling
>>> >>
>>> >>     commit 1cd158573951f737fbc878a35cb5eb47bf9af3d5 upstream.
>>> >>
>>> >> Reverting it on top of .7 fixes the problem.
>>> >>
>>> >> I had the same (I suppose) problem on mainline some time ago, but I
>>> >> have not bisected it, verified that the problem still occurs there, or
>>> >> checked if reverting the upstream patch fixes it. I'd be happy to do
>>> >> that if it would help though.
>>> >>
>>> >> Let me know if you need any more information.
>>> >
>>> > Do you have this same problem with 3.11-rc6 as well?
>>>
>>> Yes, I just confirmed. I also confirmed that reverting the mainline
>>> commit on top of -rc6 fixes the problem.
>>
>> Great, thanks.
>>
>> Felix and Johannes, any chance we can get this reverted in Linus tree
>> soon, and push that revert back to the 3.10 stable tree as well?
> I'd like to avoid a revert, since that will simply replace one set of
> issues with another. Let's limit the use of the feature that brcmsmac
> can't handle to drivers that are known to work with it. Tom, Please
> test this patch to see if it fixes your issue.

The patch (on top of -rc6) fixes it for me. Thanks.

-t

> ---
> --- a/include/net/mac80211.h
> +++ b/include/net/mac80211.h
> @@ -1501,6 +1501,7 @@ enum ieee80211_hw_flags {
>         IEEE80211_HW_SUPPORTS_RC_TABLE                  = 1<<24,
>         IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF              = 1<<25,
>         IEEE80211_HW_TIMING_BEACON_ONLY                 = 1<<26,
> +       IEEE80211_HW_SUPPORTS_HT_CCK_RATES              = 1<<27,
>  };
>
>  /**
> --- a/net/mac80211/rc80211_minstrel_ht.c
> +++ b/net/mac80211/rc80211_minstrel_ht.c
> @@ -828,6 +828,9 @@ minstrel_ht_update_cck(struct minstrel_p
>         if (sband->band != IEEE80211_BAND_2GHZ)
>                 return;
>
> +       if (!(mp->hw->flags & IEEE80211_HW_SUPPORTS_HT_CCK_RATES))
> +               return;
> +
>         mi->cck_supported = 0;
>         mi->cck_supported_short = 0;
>         for (i = 0; i < 4; i++) {
> --- a/drivers/net/wireless/ath/ath9k/init.c
> +++ b/drivers/net/wireless/ath/ath9k/init.c
> @@ -807,7 +807,8 @@ void ath9k_set_hw_capab(struct ath_softc
>                 IEEE80211_HW_PS_NULLFUNC_STACK |
>                 IEEE80211_HW_SPECTRUM_MGMT |
>                 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
> -               IEEE80211_HW_SUPPORTS_RC_TABLE;
> +               IEEE80211_HW_SUPPORTS_RC_TABLE |
> +               IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
>
>         if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
>                 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
> --- a/drivers/net/wireless/ath/carl9170/main.c
> +++ b/drivers/net/wireless/ath/carl9170/main.c
> @@ -1878,7 +1878,8 @@ void *carl9170_alloc(size_t priv_size)
>                      IEEE80211_HW_PS_NULLFUNC_STACK |
>                      IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC |
>                      IEEE80211_HW_SUPPORTS_RC_TABLE |
> -                    IEEE80211_HW_SIGNAL_DBM;
> +                    IEEE80211_HW_SIGNAL_DBM |
> +                    IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
>
>         if (!modparam_noht) {
>                 /*
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -6327,7 +6327,8 @@ static int rt2800_probe_hw_mode(struct r
>             IEEE80211_HW_SUPPORTS_PS |
>             IEEE80211_HW_PS_NULLFUNC_STACK |
>             IEEE80211_HW_AMPDU_AGGREGATION |
> -           IEEE80211_HW_REPORTS_TX_ACK_STATUS;
> +           IEEE80211_HW_REPORTS_TX_ACK_STATUS |
> +           IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
>
>         /*
>          * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
>

^ permalink raw reply

* Re: [REGRESSION] 3.10.{6,7} crashes on network activity
From: Tom Gundersen @ 2013-08-20  8:36 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Felix Fietkau, Greg Kroah-Hartman, stable, Linux Wireless List,
	LKML, Johannes Berg
In-Reply-To: <52132589.5000306@broadcom.com>

On Tue, Aug 20, 2013 at 4:15 PM, Arend van Spriel <arend@broadcom.com> wrote:
> On 08/20/2013 06:56 AM, Felix Fietkau wrote:
>>
>> On 2013-08-20 2:28 AM, Greg Kroah-Hartman wrote:
>>>
>>> On Tue, Aug 20, 2013 at 08:26:11AM +0800, Tom Gundersen wrote:
>>>>
>>>> On Tue, Aug 20, 2013 at 8:03 AM, Greg Kroah-Hartman
>>>> <gregkh@linuxfoundation.org> wrote:
>>>>>
>>>>> On Tue, Aug 20, 2013 at 07:59:47AM +0800, Tom Gundersen wrote:
>>>>>>
>>>>>> Hi guys,
>>>>>>
>>>>>> Starting with 3.10.6 (and still present in .7) I get an oops on
>>>>>> connecting to the network.
>>>>>>
>>>>>> The attached picture shows the oops. In case it does not reach the ML,
>>>>>> the top of the call trace reads:
>>>>>>
>>>>>> brcms_c_compute_rtscts_dur
>>>>>> brcms_c_ampdu_finalize
>>>>>> ampdu_finalize
>>>>>> dma_txfast
>>>>>> brcms_c_txfifo
>>>>>> brcms_c_sendpkt_mac80211
>>>>>> brcms_ops_tx
>>>>>> __ieee80211_tx
>>>>>>
>>>>>> I bisected the problem and the first bad commit is
>>>>>>
>>>>>> commit ef47a5e4f1aaf1d0e2e6875e34b2c9595897bef6
>>>>>> Author: Felix Fietkau <nbd@openwrt.org>
>>>>>> Date:   Fri Jun 28 21:04:35 2013 +0200
>>>>>>
>>>>>>      mac80211/minstrel_ht: fix cck rate sampling
>>>>>>
>>>>>>      commit 1cd158573951f737fbc878a35cb5eb47bf9af3d5 upstream.
>>>>>>
>>>>>> Reverting it on top of .7 fixes the problem.
>>>>>>
>>>>>> I had the same (I suppose) problem on mainline some time ago, but I
>>>>>> have not bisected it, verified that the problem still occurs there, or
>>>>>> checked if reverting the upstream patch fixes it. I'd be happy to do
>>>>>> that if it would help though.
>>>>>>
>>>>>> Let me know if you need any more information.
>>>>>
>>>>>
>>>>> Do you have this same problem with 3.11-rc6 as well?
>>>>
>>>>
>>>> Yes, I just confirmed. I also confirmed that reverting the mainline
>>>> commit on top of -rc6 fixes the problem.
>>>
>>>
>>> Great, thanks.
>>>
>>> Felix and Johannes, any chance we can get this reverted in Linus tree
>>> soon, and push that revert back to the 3.10 stable tree as well?
>>
>> I'd like to avoid a revert, since that will simply replace one set of
>> issues with another. Let's limit the use of the feature that brcmsmac
>> can't handle to drivers that are known to work with it. Tom, Please
>> test this patch to see if it fixes your issue.
>
>
> Hi Felix,
>
> I have been diving into root causing why brcmsmac can not handle cck
> fallback rates, because it should. Maybe it is better to flag no cck support
> and only change brcmsmac.

Hi Arend,

In case you cannot reproduce, let me know if I can help with testing patches.

Cheers,

Tom

^ permalink raw reply

* Re: [PATCH v2] ath9k_htc: Restore skb headroom when returning skb to mac80211
From: Marc Kleine-Budde @ 2013-08-20  9:01 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-wireless, linux, ath9k-devel, Helmut Schaa
In-Reply-To: <1376681980-27831-1-git-send-email-mkl@pengutronix.de>

[-- Attachment #1: Type: text/plain, Size: 1325 bytes --]

On 08/16/2013 09:39 PM, Marc Kleine-Budde wrote:
> From: Helmut Schaa <helmut.schaa@googlemail.com>
> 
> ath9k_htc adds padding between the 802.11 header and the payload during
> TX by moving the header. When handing the frame back to mac80211 for TX
> status handling the header is not moved back into its original position.
> This can result in a too small skb headroom when entering ath9k_htc
> again (due to a soft retransmission for example) causing an
> skb_under_panic oops.
> 
> Fix this by moving the 802.11 header back into its original position
> before returning the frame to mac80211 as other drivers like rt2x00
> or ath5k do.
> 
> Reported-by: Marc Kleine-Budde <mkl@blackshift.org>
> Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
> Tested-by: Marc Kleine-Budde <mkl@blackshift.org>
> Signed-off-by: Marc Kleine-Budde <mkl@blackshift.org>
> ---
> Hello Helmut,
> 
> I've change the patch a bit, I've used ieee80211_get_hdrlen_from_skb() instead
> of open coding it.
> 
> Tested in ARMv5 with USB device
>   "ID 0cf3:7015 Atheros Communications, Inc. TP-Link TL-WN821N v3 802.11n [Atheros AR7010+AR9287]"
> for four weeks. Without that patch the kernel oopes after about one week.
> 
> I think this is a candidate for stable, can you add stable to Cc?

ping

Marc


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 897 bytes --]

^ permalink raw reply

* Re: [REGRESSION] 3.10.{6,7} crashes on network activity
From: Arend van Spriel @ 2013-08-20  9:58 UTC (permalink / raw)
  To: Tom Gundersen
  Cc: Felix Fietkau, Greg Kroah-Hartman, stable, Linux Wireless List,
	LKML, Johannes Berg
In-Reply-To: <CAG-2HqVo+Jn4QsmErCVcqgS6LcxvXESVWHHCp5BGapcv0A_+Ww@mail.gmail.com>

On 08/20/2013 10:36 AM, Tom Gundersen wrote:
> On Tue, Aug 20, 2013 at 4:15 PM, Arend van Spriel <arend@broadcom.com> wrote:
>> On 08/20/2013 06:56 AM, Felix Fietkau wrote:
>>>
>>> On 2013-08-20 2:28 AM, Greg Kroah-Hartman wrote:
>>>>
>>>> On Tue, Aug 20, 2013 at 08:26:11AM +0800, Tom Gundersen wrote:
>>>>>
>>>>> On Tue, Aug 20, 2013 at 8:03 AM, Greg Kroah-Hartman
>>>>> <gregkh@linuxfoundation.org> wrote:
>>>>>>
>>>>>> On Tue, Aug 20, 2013 at 07:59:47AM +0800, Tom Gundersen wrote:
>>>>>>>
>>>>>>> Hi guys,
>>>>>>>
>>>>>>> Starting with 3.10.6 (and still present in .7) I get an oops on
>>>>>>> connecting to the network.
>>>>>>>
>>>>>>> The attached picture shows the oops. In case it does not reach the ML,
>>>>>>> the top of the call trace reads:
>>>>>>>
>>>>>>> brcms_c_compute_rtscts_dur
>>>>>>> brcms_c_ampdu_finalize
>>>>>>> ampdu_finalize
>>>>>>> dma_txfast
>>>>>>> brcms_c_txfifo
>>>>>>> brcms_c_sendpkt_mac80211
>>>>>>> brcms_ops_tx
>>>>>>> __ieee80211_tx
>>>>>>>
>>>>>>> I bisected the problem and the first bad commit is
>>>>>>>
>>>>>>> commit ef47a5e4f1aaf1d0e2e6875e34b2c9595897bef6
>>>>>>> Author: Felix Fietkau <nbd@openwrt.org>
>>>>>>> Date:   Fri Jun 28 21:04:35 2013 +0200
>>>>>>>
>>>>>>>       mac80211/minstrel_ht: fix cck rate sampling
>>>>>>>
>>>>>>>       commit 1cd158573951f737fbc878a35cb5eb47bf9af3d5 upstream.
>>>>>>>
>>>>>>> Reverting it on top of .7 fixes the problem.
>>>>>>>
>>>>>>> I had the same (I suppose) problem on mainline some time ago, but I
>>>>>>> have not bisected it, verified that the problem still occurs there, or
>>>>>>> checked if reverting the upstream patch fixes it. I'd be happy to do
>>>>>>> that if it would help though.
>>>>>>>
>>>>>>> Let me know if you need any more information.
>>>>>>
>>>>>>
>>>>>> Do you have this same problem with 3.11-rc6 as well?
>>>>>
>>>>>
>>>>> Yes, I just confirmed. I also confirmed that reverting the mainline
>>>>> commit on top of -rc6 fixes the problem.
>>>>
>>>>
>>>> Great, thanks.
>>>>
>>>> Felix and Johannes, any chance we can get this reverted in Linus tree
>>>> soon, and push that revert back to the 3.10 stable tree as well?
>>>
>>> I'd like to avoid a revert, since that will simply replace one set of
>>> issues with another. Let's limit the use of the feature that brcmsmac
>>> can't handle to drivers that are known to work with it. Tom, Please
>>> test this patch to see if it fixes your issue.
>>
>>
>> Hi Felix,
>>
>> I have been diving into root causing why brcmsmac can not handle cck
>> fallback rates, because it should. Maybe it is better to flag no cck support
>> and only change brcmsmac.
>
> Hi Arend,
>
> In case you cannot reproduce, let me know if I can help with testing patches.

So far I have not been able to reproduce it. I have a patch to avoid the 
oops, but the transmit of the related frames will fail in the device so 
it is not a real fix. I will let you you know.

Regards,
Arend

> Cheers,
>
> Tom
>



^ permalink raw reply

* Re: changing dev->needed_headroom/needed_tailroom?
From: Florian Fainelli @ 2013-08-20 10:00 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Eric Dumazet, Ben Hutchings, netdev, linux-wireless
In-Reply-To: <1375711240.8120.11.camel@jlt4.sipsolutions.net>

2013/8/5 Johannes Berg <johannes@sipsolutions.net>:
> On Fri, 2013-08-02 at 06:11 -0700, Eric Dumazet wrote:
>> On Fri, 2013-08-02 at 10:55 +0200, Ben Hutchings wrote:
>>
>> > I don't think this is safe when the interface is running (even if
>> > carrier is off).  Some functions may read dev->needed_headroom twice and
>> > rely on getting the same value each time.
>>
>> It should be no problem. Remaining unsafe places should be fixed.
>
> Most interesting would be stack devs, which I hadn't even considered. In
> any case, since I can't completely _rely_ on it, it's an optimisation,
> the only bugs would be around the double-access and then running
> over/under the SKB or so?

As far as I could test this with an Ethernet driver which adjusted its
needed_headroom by 64 bytes whenever some hardware feature was
enabled/disabled, this expectedly broke bridge and vlans at least.
Bridge code does not use the slave ports needed_headroom values, and
VLAN devices get the parent device needed_headroom only when creating
the vlan device. The good thing is since the needed_headroom space you
need is most likely fixed for a given configuration type, you should
see a pretty "stable" corruption of your SKB head.

>
>> We already had this discussion in the past, and some patches were
>> issued. Check commit ae641949df01b85117845bec45328eab6d6fada1
>> ("net: Remove all uses of LL_ALLOCATED_SPACE")
>
> That would have addressed some of that, I guess.
>
>
> I'm asking because some of the crypto stuff we do has fairly large
> head/tailroom requirements and it seems I may need to add more. But if
> you don't have crypto, it would be much smaller, so I figured we could
> switch it.

We could probably do it via a pair of new NETDEV_* notify event to
signal new needed_headroom/tailroom values to stacked devices. Would
that be acceptable?
-- 
Florian

^ permalink raw reply

* Re: [REGRESSION] 3.10.{6,7} crashes on network activity
From: Georgios Magklaras @ 2013-08-20 10:10 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Tom Gundersen, Felix Fietkau, Greg Kroah-Hartman, stable,
	Linux Wireless List, LKML, Johannes Berg
In-Reply-To: <52133DD9.8010902@broadcom.com>

I verify the same issue on a Latitude E6520 running both the
vanilla/clean and the Fedora 19 specific kernels. I thought it was the
NVIDIA/nouveau driver and I reproduce by switching to non graphical mode
and performing scp transfers.

GM


On Tue, 2013-08-20 at 11:58 +0200, Arend van Spriel wrote:
> On 08/20/2013 10:36 AM, Tom Gundersen wrote:
> > On Tue, Aug 20, 2013 at 4:15 PM, Arend van Spriel <arend@broadcom.com> wrote:
> >> On 08/20/2013 06:56 AM, Felix Fietkau wrote:
> >>>
> >>> On 2013-08-20 2:28 AM, Greg Kroah-Hartman wrote:
> >>>>
> >>>> On Tue, Aug 20, 2013 at 08:26:11AM +0800, Tom Gundersen wrote:
> >>>>>
> >>>>> On Tue, Aug 20, 2013 at 8:03 AM, Greg Kroah-Hartman
> >>>>> <gregkh@linuxfoundation.org> wrote:
> >>>>>>
> >>>>>> On Tue, Aug 20, 2013 at 07:59:47AM +0800, Tom Gundersen wrote:
> >>>>>>>
> >>>>>>> Hi guys,
> >>>>>>>
> >>>>>>> Starting with 3.10.6 (and still present in .7) I get an oops on
> >>>>>>> connecting to the network.
> >>>>>>>
> >>>>>>> The attached picture shows the oops. In case it does not reach the ML,
> >>>>>>> the top of the call trace reads:
> >>>>>>>
> >>>>>>> brcms_c_compute_rtscts_dur
> >>>>>>> brcms_c_ampdu_finalize
> >>>>>>> ampdu_finalize
> >>>>>>> dma_txfast
> >>>>>>> brcms_c_txfifo
> >>>>>>> brcms_c_sendpkt_mac80211
> >>>>>>> brcms_ops_tx
> >>>>>>> __ieee80211_tx
> >>>>>>>
> >>>>>>> I bisected the problem and the first bad commit is
> >>>>>>>
> >>>>>>> commit ef47a5e4f1aaf1d0e2e6875e34b2c9595897bef6
> >>>>>>> Author: Felix Fietkau <nbd@openwrt.org>
> >>>>>>> Date:   Fri Jun 28 21:04:35 2013 +0200
> >>>>>>>
> >>>>>>>       mac80211/minstrel_ht: fix cck rate sampling
> >>>>>>>
> >>>>>>>       commit 1cd158573951f737fbc878a35cb5eb47bf9af3d5 upstream.
> >>>>>>>
> >>>>>>> Reverting it on top of .7 fixes the problem.
> >>>>>>>
> >>>>>>> I had the same (I suppose) problem on mainline some time ago, but I
> >>>>>>> have not bisected it, verified that the problem still occurs there, or
> >>>>>>> checked if reverting the upstream patch fixes it. I'd be happy to do
> >>>>>>> that if it would help though.
> >>>>>>>
> >>>>>>> Let me know if you need any more information.
> >>>>>>
> >>>>>>
> >>>>>> Do you have this same problem with 3.11-rc6 as well?
> >>>>>
> >>>>>
> >>>>> Yes, I just confirmed. I also confirmed that reverting the mainline
> >>>>> commit on top of -rc6 fixes the problem.
> >>>>
> >>>>
> >>>> Great, thanks.
> >>>>
> >>>> Felix and Johannes, any chance we can get this reverted in Linus tree
> >>>> soon, and push that revert back to the 3.10 stable tree as well?
> >>>
> >>> I'd like to avoid a revert, since that will simply replace one set of
> >>> issues with another. Let's limit the use of the feature that brcmsmac
> >>> can't handle to drivers that are known to work with it. Tom, Please
> >>> test this patch to see if it fixes your issue.
> >>
> >>
> >> Hi Felix,
> >>
> >> I have been diving into root causing why brcmsmac can not handle cck
> >> fallback rates, because it should. Maybe it is better to flag no cck support
> >> and only change brcmsmac.
> >
> > Hi Arend,
> >
> > In case you cannot reproduce, let me know if I can help with testing patches.
> 
> So far I have not been able to reproduce it. I have a patch to avoid the 
> oops, but the transmit of the related frames will fail in the device so 
> it is not a real fix. I will let you you know.
> 
> Regards,
> Arend
> 
> > Cheers,
> >
> > Tom
> >
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



^ permalink raw reply

* [RFC 1/2] mac80211: allow APs to send SMPS frames
From: Emmanuel Grumbach @ 2013-08-20 11:12 UTC (permalink / raw)
  To: linux-wireless; +Cc: Emmanuel Grumbach

SMPS code checks all over the place that the vif is
BSS. Remove that constraint and allow SMPS for AP too.

Provide dummy implementation that will be used for
further patches.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 net/mac80211/cfg.c            |   15 ++++++++++++---
 net/mac80211/debugfs_netdev.c |   24 +++++++++++++++---------
 net/mac80211/ht.c             |   38 ++++++++++++++++++++++++++++----------
 net/mac80211/ieee80211_i.h    |   13 ++++++++++---
 net/mac80211/iface.c          |    2 ++
 net/mac80211/mlme.c           |    2 +-
 6 files changed, 68 insertions(+), 26 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 4cc81c3..bd6b38c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2337,8 +2337,14 @@ static int ieee80211_testmode_dump(struct wiphy *wiphy,
 }
 #endif
 
-int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
-			     enum ieee80211_smps_mode smps_mode)
+int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
+				enum ieee80211_smps_mode smps_mode)
+{
+	return 0;
+}
+
+int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
+				 enum ieee80211_smps_mode smps_mode)
 {
 	const u8 *ap;
 	enum ieee80211_smps_mode old_req;
@@ -2346,6 +2352,9 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
 
 	lockdep_assert_held(&sdata->wdev.mtx);
 
+	if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
 	old_req = sdata->u.mgd.req_smps;
 	sdata->u.mgd.req_smps = smps_mode;
 
@@ -2402,7 +2411,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
 
 	/* no change, but if automatic follow powersave */
 	sdata_lock(sdata);
-	__ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
+	__ieee80211_request_smps_mgd(sdata, sdata->u.mgd.req_smps);
 	sdata_unlock(sdata);
 
 	if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index e601c9f..7609e47 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -224,12 +224,15 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
 	     smps_mode == IEEE80211_SMPS_AUTOMATIC))
 		return -EINVAL;
 
-	/* supported only on managed interfaces for now */
-	if (sdata->vif.type != NL80211_IFTYPE_STATION)
+	if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+	    sdata->vif.type != NL80211_IFTYPE_AP)
 		return -EOPNOTSUPP;
 
 	sdata_lock(sdata);
-	err = __ieee80211_request_smps(sdata, smps_mode);
+	if (sdata->vif.type == NL80211_IFTYPE_STATION)
+		err = __ieee80211_request_smps_mgd(sdata, smps_mode);
+	else
+		err = __ieee80211_request_smps_ap(sdata, smps_mode);
 	sdata_unlock(sdata);
 
 	return err;
@@ -245,12 +248,15 @@ static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
 static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata,
 				     char *buf, int buflen)
 {
-	if (sdata->vif.type != NL80211_IFTYPE_STATION)
-		return -EOPNOTSUPP;
-
-	return snprintf(buf, buflen, "request: %s\nused: %s\n",
-			smps_modes[sdata->u.mgd.req_smps],
-			smps_modes[sdata->smps_mode]);
+	if (sdata->vif.type == NL80211_IFTYPE_STATION)
+		return snprintf(buf, buflen, "request: %s\nused: %s\n",
+				smps_modes[sdata->u.mgd.req_smps],
+				smps_modes[sdata->smps_mode]);
+	if (sdata->vif.type == NL80211_IFTYPE_AP)
+		return snprintf(buf, buflen, "request: %s\nused: %s\n",
+				smps_modes[sdata->u.ap.req_smps],
+				smps_modes[sdata->smps_mode]);
+	return -EINVAL;
 }
 
 static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 529bf58..2c85b96 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -448,14 +448,25 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
 	return 0;
 }
 
-void ieee80211_request_smps_work(struct work_struct *work)
+void ieee80211_request_smps_mgd_work(struct work_struct *work)
 {
 	struct ieee80211_sub_if_data *sdata =
 		container_of(work, struct ieee80211_sub_if_data,
 			     u.mgd.request_smps_work);
 
 	sdata_lock(sdata);
-	__ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode);
+	__ieee80211_request_smps_mgd(sdata, sdata->u.mgd.driver_smps_mode);
+	sdata_unlock(sdata);
+}
+
+void ieee80211_request_smps_ap_work(struct work_struct *work)
+{
+	struct ieee80211_sub_if_data *sdata =
+		container_of(work, struct ieee80211_sub_if_data,
+			     u.ap.request_smps_work);
+
+	sdata_lock(sdata);
+	__ieee80211_request_smps_ap(sdata, sdata->u.ap.driver_smps_mode);
 	sdata_unlock(sdata);
 }
 
@@ -464,19 +475,26 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
 {
 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
 
-	if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
+	if (WARN_ON_ONCE(vif->type != NL80211_IFTYPE_STATION &&
+			 vif->type != NL80211_IFTYPE_AP))
 		return;
 
 	if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
 		smps_mode = IEEE80211_SMPS_AUTOMATIC;
 
-	if (sdata->u.mgd.driver_smps_mode == smps_mode)
-		return;
-
-	sdata->u.mgd.driver_smps_mode = smps_mode;
-
-	ieee80211_queue_work(&sdata->local->hw,
-			     &sdata->u.mgd.request_smps_work);
+	if (vif->type == NL80211_IFTYPE_STATION) {
+		if (sdata->u.mgd.driver_smps_mode == smps_mode)
+			return;
+		sdata->u.mgd.driver_smps_mode = smps_mode;
+		ieee80211_queue_work(&sdata->local->hw,
+				     &sdata->u.mgd.request_smps_work);
+	} else {
+		if (sdata->u.ap.driver_smps_mode == smps_mode)
+			return;
+		sdata->u.ap.driver_smps_mode = smps_mode;
+		ieee80211_queue_work(&sdata->local->hw,
+				     &sdata->u.ap.request_smps_work);
+	}
 }
 /* this might change ... don't want non-open drivers using it */
 EXPORT_SYMBOL_GPL(ieee80211_request_smps);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 47cf62e..7c68eac 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -265,6 +265,10 @@ struct ieee80211_if_ap {
 
 	struct ps_data ps;
 	atomic_t num_mcast_sta; /* number of stations receiving multicast */
+	enum ieee80211_smps_mode req_smps, /* requested smps mode */
+			 driver_smps_mode; /* smps mode request */
+
+	struct work_struct request_smps_work;
 };
 
 struct ieee80211_if_wds {
@@ -1439,7 +1443,8 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
 int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
 			       enum ieee80211_smps_mode smps, const u8 *da,
 			       const u8 *bssid);
-void ieee80211_request_smps_work(struct work_struct *work);
+void ieee80211_request_smps_ap_work(struct work_struct *work);
+void ieee80211_request_smps_mgd_work(struct work_struct *work);
 
 void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
 				     u16 initiator, u16 reason, bool stop);
@@ -1634,8 +1639,10 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
 u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
 			    struct ieee802_11_elems *elems,
 			    enum ieee80211_band band, u32 *basic_rates);
-int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
-			     enum ieee80211_smps_mode smps_mode);
+int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
+				 enum ieee80211_smps_mode smps_mode);
+int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
+				enum ieee80211_smps_mode smps_mode);
 void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata);
 
 size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index cc0c4be..913ef15 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1301,6 +1301,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
 	case NL80211_IFTYPE_AP:
 		skb_queue_head_init(&sdata->u.ap.ps.bc_buf);
 		INIT_LIST_HEAD(&sdata->u.ap.vlans);
+		INIT_WORK(&sdata->u.ap.request_smps_work,
+			  ieee80211_request_smps_ap_work);
 		sdata->vif.bss_conf.bssid = sdata->vif.addr;
 		break;
 	case NL80211_IFTYPE_P2P_CLIENT:
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 21bccd8..89e6f28 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3693,7 +3693,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
 		  ieee80211_beacon_connection_loss_work);
 	INIT_WORK(&ifmgd->csa_connection_drop_work,
 		  ieee80211_csa_connection_drop_work);
-	INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_work);
+	INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_mgd_work);
 	setup_timer(&ifmgd->timer, ieee80211_sta_timer,
 		    (unsigned long) sdata);
 	setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 2/2] mac80211: implement SMPS for AP
From: Emmanuel Grumbach @ 2013-08-20 11:12 UTC (permalink / raw)
  To: linux-wireless; +Cc: Emmanuel Grumbach
In-Reply-To: <1376997139-6228-1-git-send-email-emmanuel.grumbach@intel.com>

When the driver requests to move to STATIC or DYNAMIC SMPS,
we send an action frame to each associated station and
reconfigure the channel context / driver.
Of course, non-MIMO stations are ignored.

The beacon isn't updated. The association response will
include the original capabilities. Stations that associate
while in non-OFF SMPS mode will get an action frame right
after association to inform them about our current state.
Note that we wait until the end of the EAPOL. Sending an
action frame before the EAPOL is finished can be an issue
for a few clients. Clients aren't likely to send EAPOL
frames in MIMO anyway.

When the SMPS configuration gets more permissive (e.g.
STATIC -> OFF), we don't wake up stations that are asleep
We remember that they don't know about the change and send
the action frame when they wake up.

When the SMPS configuration gets more restrictive (e.g.
OFF -> STATIC), we set the TIM bit for every sleeping STA.
uAPSD stations might send MIMO until they poll the action
frame, but this is for a short period of time.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 net/mac80211/cfg.c            |   91 +++++++++++++++++++++++++++++++++++++++++
 net/mac80211/debugfs_netdev.c |    1 +
 net/mac80211/ht.c             |    3 ++
 net/mac80211/ieee80211_i.h    |    3 ++
 net/mac80211/sta_info.c       |   56 +++++++++++++++++++++++++
 net/mac80211/sta_info.h       |    5 +++
 net/mac80211/status.c         |   15 ++++---
 net/mac80211/util.c           |   25 +++++++++++
 8 files changed, 194 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index bd6b38c..0e00c83 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1553,6 +1553,19 @@ static int ieee80211_change_station(struct wiphy *wiphy,
 
 	mutex_unlock(&local->sta_mtx);
 
+	if (sdata->vif.type == NL80211_IFTYPE_AP &&
+	    sta->known_smps_mode != sta->sdata->smps_mode &&
+	    test_sta_flag(sta, WLAN_STA_AUTHORIZED) &&
+	    sta_info_tx_chains(sta) != 1) {
+		ht_dbg(sta->sdata,
+		       "%pM just authorized and MIMO capable - update SMPS\n",
+		       sta->sta.addr);
+		ieee80211_send_smps_action(sta->sdata,
+			sta->sdata->u.ap.req_smps,
+			sta->sta.addr,
+			sta->sdata->vif.bss_conf.bssid);
+	}
+
 	if (sdata->vif.type == NL80211_IFTYPE_STATION &&
 	    params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
 		ieee80211_recalc_ps(local, -1);
@@ -2340,6 +2353,84 @@ static int ieee80211_testmode_dump(struct wiphy *wiphy,
 int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
 				enum ieee80211_smps_mode smps_mode)
 {
+	struct sta_info *sta;
+	enum ieee80211_smps_mode old_req;
+	int i;
+
+	if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP))
+		return -EINVAL;
+
+	if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
+		return 0;
+
+	old_req = sdata->u.ap.req_smps;
+	sdata->u.ap.req_smps = smps_mode;
+
+	/* AUTOMATIC doesn't mean much for AP - don't allow it */
+	if (old_req == smps_mode ||
+	    smps_mode == IEEE80211_SMPS_AUTOMATIC)
+		return 0;
+
+	 /* If no associated stations, there's no need to do anything */
+	if (!atomic_read(&sdata->u.ap.num_mcast_sta)) {
+		sdata->smps_mode = smps_mode;
+		ieee80211_queue_work(&sdata->local->hw, &sdata->recalc_smps);
+		return 0;
+	}
+
+	ht_dbg(sdata,
+	       "SMSP %d requested in AP mode, sending Action frame to %d stations\n",
+	       smps_mode, atomic_read(&sdata->u.ap.num_mcast_sta));
+
+	mutex_lock(&sdata->local->sta_mtx);
+	for (i = 0; i < STA_HASH_SIZE; i++) {
+		for (sta = rcu_dereference_protected(sdata->local->sta_hash[i],
+				lockdep_is_held(&sdata->local->sta_mtx));
+		     sta;
+		     sta = rcu_dereference_protected(sta->hnext,
+				lockdep_is_held(&sdata->local->sta_mtx))) {
+			if (sta->sdata != sdata)
+				continue;
+
+			/* This station doesn't support MIMO - skip it */
+			if (sta_info_tx_chains(sta) == 1) {
+				ht_dbg(sdata,
+				       "Won't send SMPS to non-MIMO capable STA %pM\n",
+				       sta->sta.addr);
+				continue;
+			}
+
+			/*
+			 * Don't wake up a STA just to send the action frame
+			 * unless we are getting more restrictive.
+			 */
+			if (test_sta_flag(sta, WLAN_STA_PS_STA) &&
+			    !ieee80211_smps_is_restrictive(sta->known_smps_mode,
+							   smps_mode)) {
+				ht_dbg(sdata,
+				       "Won't send SMPS to sleeping STA %pM\n",
+				       sta->sta.addr);
+				continue;
+			}
+
+			/*
+			 * If the STA is not authorized, wait until it gets
+			 * authorized and the action frame will be sent then.
+			 */
+			if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED))
+				continue;
+
+			ht_dbg(sdata, "Sending SMPS to %pM\n", sta->sta.addr);
+			ieee80211_send_smps_action(sdata, smps_mode,
+						   sta->sta.addr,
+						   sdata->vif.bss_conf.bssid);
+		}
+	}
+	mutex_unlock(&sdata->local->sta_mtx);
+
+	sdata->smps_mode = smps_mode;
+	ieee80211_queue_work(&sdata->local->hw, &sdata->recalc_smps);
+
 	return 0;
 }
 
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 7609e47..4e9ec9e 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -569,6 +569,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
 static void add_ap_files(struct ieee80211_sub_if_data *sdata)
 {
 	DEBUGFS_ADD(num_mcast_sta);
+	DEBUGFS_ADD_MODE(smps, 0600);
 	DEBUGFS_ADD(num_sta_ps);
 	DEBUGFS_ADD(dtim_count);
 	DEBUGFS_ADD(num_buffered_multicast);
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 2c85b96..9a8be8f 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -489,6 +489,9 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
 		ieee80211_queue_work(&sdata->local->hw,
 				     &sdata->u.mgd.request_smps_work);
 	} else {
+		/* AUTOMATIC is meaningless in AP mode */
+		if (WARN_ON_ONCE(smps_mode == IEEE80211_SMPS_AUTOMATIC))
+			return;
 		if (sdata->u.ap.driver_smps_mode == smps_mode)
 			return;
 		sdata->u.ap.driver_smps_mode = smps_mode;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 7c68eac..85387cb 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1445,6 +1445,9 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
 			       const u8 *bssid);
 void ieee80211_request_smps_ap_work(struct work_struct *work);
 void ieee80211_request_smps_mgd_work(struct work_struct *work);
+bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old,
+				   enum ieee80211_smps_mode smps_mode_new);
+
 
 void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
 				     u16 initiator, u16 reason, bool stop);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 9c97237..74c88ba 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -385,6 +385,25 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
 		sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX);
 
 	sta->sta.smps_mode = IEEE80211_SMPS_OFF;
+	if (sdata->vif.type == NL80211_IFTYPE_AP) {
+		struct ieee80211_supported_band *sband =
+			local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
+		u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
+				IEEE80211_HT_CAP_SM_PS_SHIFT;
+		switch (smps) {
+		case WLAN_HT_SMPS_CONTROL_DISABLED:
+			sta->known_smps_mode = IEEE80211_SMPS_OFF;
+			break;
+		case WLAN_HT_SMPS_CONTROL_STATIC:
+			sta->known_smps_mode = IEEE80211_SMPS_STATIC;
+			break;
+		case WLAN_HT_SMPS_CONTROL_DYNAMIC:
+			sta->known_smps_mode = IEEE80211_SMPS_DYNAMIC;
+			break;
+		default:
+			WARN_ON(1);
+		}
+	}
 
 	sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
 
@@ -1069,6 +1088,19 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
 
 	ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
 
+	/* This station just woke up and isn't aware of our SMPS state */
+	if (!ieee80211_smps_is_restrictive(sta->known_smps_mode,
+					   sdata->smps_mode) &&
+	    sta->known_smps_mode != sdata->smps_mode &&
+	    sta_info_tx_chains(sta) != 1) {
+		ht_dbg(sdata,
+		       "%pM just woke up and MIMO capable - update SMPS\n",
+		       sta->sta.addr);
+		ieee80211_send_smps_action(sdata, sdata->smps_mode,
+					   sta->sta.addr,
+					   sdata->vif.bss_conf.bssid);
+	}
+
 	local->total_ps_buffered -= buffered;
 
 	sta_info_recalc_tim(sta);
@@ -1520,3 +1552,27 @@ int sta_info_move_state(struct sta_info *sta,
 
 	return 0;
 }
+
+u8 sta_info_tx_chains(struct sta_info *sta)
+{
+	struct ieee80211_sta_ht_cap *ht_cap = &sta->sta.ht_cap;
+	u8 rx_chains;
+
+	if (!sta->sta.ht_cap.ht_supported)
+		return 1;
+
+	if (ht_cap->mcs.rx_mask[3])
+		rx_chains = 4;
+	else if (ht_cap->mcs.rx_mask[2])
+		rx_chains = 3;
+	else if (ht_cap->mcs.rx_mask[1])
+		rx_chains = 2;
+	else
+		rx_chains = 1;
+
+	if (!(ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_RX_DIFF))
+		return rx_chains;
+
+	return ((ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
+			>> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1;
+}
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 9013969..240aef2 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -301,6 +301,8 @@ struct sta_ampdu_mlme {
  * @chains: chains ever used for RX from this station
  * @chain_signal_last: last signal (per chain)
  * @chain_signal_avg: signal average (per chain)
+ * @known_smps_mode: the smps_mode the client thinks we are in. Relevant for
+ *	AP only.
  */
 struct sta_info {
 	/* General information, mostly static */
@@ -411,6 +413,8 @@ struct sta_info {
 	unsigned int lost_packets;
 	unsigned int beacon_loss_count;
 
+	enum ieee80211_smps_mode known_smps_mode;
+
 	/* keep last! */
 	struct ieee80211_sta sta;
 };
@@ -613,6 +617,7 @@ void sta_set_rate_info_rx(struct sta_info *sta,
 			  struct rate_info *rinfo);
 void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
 			  unsigned long exp_time);
+u8 sta_info_tx_chains(struct sta_info *sta);
 
 void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta);
 void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 368837f..7746cd0 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -191,8 +191,8 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
 	if (ieee80211_is_action(mgmt->frame_control) &&
 	    mgmt->u.action.category == WLAN_CATEGORY_HT &&
 	    mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS &&
-	    sdata->vif.type == NL80211_IFTYPE_STATION &&
 	    ieee80211_sdata_running(sdata)) {
+		enum ieee80211_smps_mode smps_mode;
 		/*
 		 * This update looks racy, but isn't -- if we come
 		 * here we've definitely got a station that we're
@@ -202,18 +202,23 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
 		 */
 		switch (mgmt->u.action.u.ht_smps.smps_control) {
 		case WLAN_HT_SMPS_CONTROL_DYNAMIC:
-			sdata->smps_mode = IEEE80211_SMPS_DYNAMIC;
+			smps_mode = IEEE80211_SMPS_DYNAMIC;
 			break;
 		case WLAN_HT_SMPS_CONTROL_STATIC:
-			sdata->smps_mode = IEEE80211_SMPS_STATIC;
+			smps_mode = IEEE80211_SMPS_STATIC;
 			break;
 		case WLAN_HT_SMPS_CONTROL_DISABLED:
 		default: /* shouldn't happen since we don't send that */
-			sdata->smps_mode = IEEE80211_SMPS_OFF;
+			smps_mode = IEEE80211_SMPS_OFF;
 			break;
 		}
 
-		ieee80211_queue_work(&local->hw, &sdata->recalc_smps);
+		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+			sdata->smps_mode = smps_mode;
+			ieee80211_queue_work(&local->hw, &sdata->recalc_smps);
+		} else if (sdata->vif.type == NL80211_IFTYPE_AP) {
+			sta->known_smps_mode = smps_mode;
+		}
 	}
 }
 
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index d23c5a7..dad8262 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2295,3 +2295,28 @@ void ieee80211_radar_detected(struct ieee80211_hw *hw)
 	ieee80211_queue_work(hw, &local->radar_detected_work);
 }
 EXPORT_SYMBOL(ieee80211_radar_detected);
+
+/*
+ * Returns true if smps_mode_new is strictly more restrictive than
+ * smps_mode_old.
+ */
+bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old,
+				   enum ieee80211_smps_mode smps_mode_new)
+{
+	if (WARN_ON_ONCE(smps_mode_old == IEEE80211_SMPS_AUTOMATIC ||
+			 smps_mode_new == IEEE80211_SMPS_AUTOMATIC))
+		return false;
+
+	switch (smps_mode_old) {
+	case IEEE80211_SMPS_STATIC:
+		return false;
+	case IEEE80211_SMPS_DYNAMIC:
+		return smps_mode_new == IEEE80211_SMPS_STATIC;
+	case IEEE80211_SMPS_OFF:
+		return smps_mode_new != IEEE80211_SMPS_OFF;
+	default:
+		WARN_ON(1);
+	}
+
+	return false;
+}
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH v2] ath9k_htc: Restore skb headroom when returning skb to mac80211
From: Helmut Schaa @ 2013-08-20 12:57 UTC (permalink / raw)
  To: Marc Kleine-Budde, John Linville
  Cc: Marc Kleine-Budde, linux-wireless, Oleksij Rempel, ath9k-devel
In-Reply-To: <52133070.2050301@blackshift.org>

Hi John, Hi Marc,

On Tue, Aug 20, 2013 at 11:01 AM, Marc Kleine-Budde <mkl@blackshift.org> wrote:
> On 08/16/2013 09:39 PM, Marc Kleine-Budde wrote:
>> From: Helmut Schaa <helmut.schaa@googlemail.com>
>>
>> ath9k_htc adds padding between the 802.11 header and the payload during
>> TX by moving the header. When handing the frame back to mac80211 for TX
>> status handling the header is not moved back into its original position.
>> This can result in a too small skb headroom when entering ath9k_htc
>> again (due to a soft retransmission for example) causing an
>> skb_under_panic oops.
>>
>> Fix this by moving the 802.11 header back into its original position
>> before returning the frame to mac80211 as other drivers like rt2x00
>> or ath5k do.
>>
>> Reported-by: Marc Kleine-Budde <mkl@blackshift.org>
>> Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
>> Tested-by: Marc Kleine-Budde <mkl@blackshift.org>
>> Signed-off-by: Marc Kleine-Budde <mkl@blackshift.org>
>> ---
>> Hello Helmut,
>>
>> I've change the patch a bit, I've used ieee80211_get_hdrlen_from_skb() instead
>> of open coding it.
>>
>> Tested in ARMv5 with USB device
>>   "ID 0cf3:7015 Atheros Communications, Inc. TP-Link TL-WN821N v3 802.11n [Atheros AR7010+AR9287]"
>> for four weeks. Without that patch the kernel oopes after about one week.
>>
>> I think this is a candidate for stable, can you add stable to Cc?
>
> ping

Sorry, completely forgot about this patch. You're right, this is
indeed a stable candidate.

John, could you please add  "Cc: stable@vger.kernel.org" when applying
this to your tree?

Thanks,
Helmut

^ permalink raw reply

* Re: [PATCH v2] ath9k_htc: Restore skb headroom when returning skb to mac80211
From: Helmut Schaa @ 2013-08-20 12:59 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-wireless, Oleksij Rempel, ath9k-devel, Marc Kleine-Budde
In-Reply-To: <1376681980-27831-1-git-send-email-mkl@pengutronix.de>

On Fri, Aug 16, 2013 at 9:39 PM, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> Tested in ARMv5 with USB device
>   "ID 0cf3:7015 Atheros Communications, Inc. TP-Link TL-WN821N v3 802.11n [Atheros AR7010+AR9287]"
> for four weeks. Without that patch the kernel oopes after about one week.

Thanks for testing by the way!
Helmut

^ permalink raw reply

* Intel PRO/Wireless 2100 Driver Firmware
From: Marcus Laitala @ 2013-08-20 13:44 UTC (permalink / raw)
  To: linux-wireless

I tried to download the Intel PRO/Wireless 2100 Driver Firmware
from: http://ipw2100.sourceforge.net/firmware.php

I only get the following error:
This webpage is not available"

As if the files/webpage is no longer there/online. I just wanted to
tell who ever is in charge of those that those files are no longer
downloadable.

//Marcus

^ permalink raw reply

* [PATCH 05/12] brcmsmac: update transmit gain table for lcn phy
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

Update the transmit gain table for bcm4313 chip family.

Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c   |  216 ++++++++++----------
 1 file changed, 108 insertions(+), 108 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
index deae3a7..efd5a58 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
@@ -2959,134 +2959,134 @@ dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
 };
 
 const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
-	{7, 0, 31, 0, 72},
-	{7, 0, 31, 0, 70},
-	{7, 0, 31, 0, 68},
-	{7, 0, 30, 0, 67},
-	{7, 0, 29, 0, 68},
-	{7, 0, 28, 0, 68},
-	{7, 0, 27, 0, 69},
-	{7, 0, 26, 0, 70},
-	{7, 0, 25, 0, 70},
-	{7, 0, 24, 0, 71},
-	{7, 0, 23, 0, 72},
-	{7, 0, 23, 0, 70},
-	{7, 0, 22, 0, 71},
-	{7, 0, 21, 0, 72},
-	{7, 0, 21, 0, 70},
-	{7, 0, 21, 0, 68},
-	{7, 0, 21, 0, 66},
-	{7, 0, 21, 0, 64},
-	{7, 0, 21, 0, 63},
-	{7, 0, 20, 0, 64},
-	{7, 0, 19, 0, 65},
-	{7, 0, 19, 0, 64},
-	{7, 0, 18, 0, 65},
-	{7, 0, 18, 0, 64},
-	{7, 0, 17, 0, 65},
-	{7, 0, 17, 0, 64},
-	{7, 0, 16, 0, 65},
-	{7, 0, 16, 0, 64},
-	{7, 0, 16, 0, 62},
-	{7, 0, 16, 0, 60},
-	{7, 0, 16, 0, 58},
-	{7, 0, 15, 0, 61},
-	{7, 0, 15, 0, 59},
-	{7, 0, 14, 0, 61},
-	{7, 0, 14, 0, 60},
-	{7, 0, 14, 0, 58},
-	{7, 0, 13, 0, 60},
-	{7, 0, 13, 0, 59},
-	{7, 0, 12, 0, 62},
-	{7, 0, 12, 0, 60},
-	{7, 0, 12, 0, 58},
-	{7, 0, 11, 0, 62},
-	{7, 0, 11, 0, 60},
-	{7, 0, 11, 0, 59},
-	{7, 0, 11, 0, 57},
-	{7, 0, 10, 0, 61},
-	{7, 0, 10, 0, 59},
-	{7, 0, 10, 0, 57},
-	{7, 0, 9, 0, 62},
-	{7, 0, 9, 0, 60},
-	{7, 0, 9, 0, 58},
-	{7, 0, 9, 0, 57},
-	{7, 0, 8, 0, 62},
-	{7, 0, 8, 0, 60},
-	{7, 0, 8, 0, 58},
-	{7, 0, 8, 0, 57},
-	{7, 0, 8, 0, 55},
-	{7, 0, 7, 0, 61},
+	{15, 0, 31, 0, 72},
+	{15, 0, 31, 0, 70},
+	{15, 0, 31, 0, 68},
+	{15, 0, 30, 0, 68},
+	{15, 0, 29, 0, 69},
+	{15, 0, 28, 0, 69},
+	{15, 0, 27, 0, 70},
+	{15, 0, 26, 0, 70},
+	{15, 0, 25, 0, 71},
+	{15, 0, 24, 0, 72},
+	{15, 0, 23, 0, 73},
+	{15, 0, 23, 0, 71},
+	{15, 0, 22, 0, 72},
+	{15, 0, 21, 0, 73},
+	{15, 0, 21, 0, 71},
+	{15, 0, 21, 0, 69},
+	{15, 0, 21, 0, 67},
+	{15, 0, 21, 0, 65},
+	{15, 0, 21, 0, 63},
+	{15, 0, 20, 0, 65},
+	{15, 0, 19, 0, 66},
+	{15, 0, 19, 0, 64},
+	{15, 0, 18, 0, 66},
+	{15, 0, 18, 0, 64},
+	{15, 0, 17, 0, 66},
+	{15, 0, 17, 0, 64},
+	{15, 0, 16, 0, 66},
+	{15, 0, 16, 0, 64},
+	{15, 0, 16, 0, 62},
+	{15, 0, 16, 0, 61},
+	{15, 0, 16, 0, 59},
+	{15, 0, 15, 0, 61},
+	{15, 0, 15, 0, 59},
+	{15, 0, 14, 0, 62},
+	{15, 0, 14, 0, 60},
+	{15, 0, 14, 0, 58},
+	{15, 0, 13, 0, 61},
+	{15, 0, 13, 0, 59},
+	{15, 0, 12, 0, 62},
+	{15, 0, 12, 0, 61},
+	{15, 0, 12, 0, 59},
+	{15, 0, 11, 0, 62},
+	{15, 0, 11, 0, 61},
+	{15, 0, 11, 0, 59},
+	{15, 0, 11, 0, 57},
+	{15, 0, 10, 0, 61},
+	{15, 0, 10, 0, 59},
+	{15, 0, 10, 0, 58},
+	{15, 0, 9, 0, 62},
+	{15, 0, 9, 0, 61},
+	{15, 0, 9, 0, 59},
+	{15, 0, 9, 0, 57},
+	{15, 0, 8, 0, 62},
+	{15, 0, 8, 0, 61},
+	{15, 0, 8, 0, 59},
+	{15, 0, 8, 0, 57},
+	{15, 0, 8, 0, 56},
+	{15, 0, 8, 0, 54},
+	{15, 0, 8, 0, 53},
+	{15, 0, 8, 0, 51},
+	{15, 0, 8, 0, 50},
+	{7, 0, 7, 0, 69},
+	{7, 0, 7, 0, 67},
+	{7, 0, 7, 0, 65},
+	{7, 0, 7, 0, 64},
+	{7, 0, 7, 0, 62},
 	{7, 0, 7, 0, 60},
 	{7, 0, 7, 0, 58},
-	{7, 0, 7, 0, 56},
+	{7, 0, 7, 0, 57},
 	{7, 0, 7, 0, 55},
 	{7, 0, 6, 0, 62},
-	{7, 0, 6, 0, 60},
-	{7, 0, 6, 0, 58},
+	{7, 0, 6, 0, 61},
+	{7, 0, 6, 0, 59},
 	{7, 0, 6, 0, 57},
-	{7, 0, 6, 0, 55},
+	{7, 0, 6, 0, 56},
 	{7, 0, 6, 0, 54},
-	{7, 0, 6, 0, 52},
+	{7, 0, 6, 0, 53},
 	{7, 0, 5, 0, 61},
-	{7, 0, 5, 0, 59},
-	{7, 0, 5, 0, 57},
+	{7, 0, 5, 0, 60},
+	{7, 0, 5, 0, 58},
 	{7, 0, 5, 0, 56},
-	{7, 0, 5, 0, 54},
+	{7, 0, 5, 0, 55},
 	{7, 0, 5, 0, 53},
-	{7, 0, 5, 0, 51},
-	{7, 0, 4, 0, 62},
-	{7, 0, 4, 0, 60},
-	{7, 0, 4, 0, 58},
+	{7, 0, 5, 0, 52},
+	{7, 0, 5, 0, 50},
+	{7, 0, 5, 0, 49},
+	{7, 0, 5, 0, 47},
 	{7, 0, 4, 0, 57},
-	{7, 0, 4, 0, 55},
+	{7, 0, 4, 0, 56},
 	{7, 0, 4, 0, 54},
-	{7, 0, 4, 0, 52},
+	{7, 0, 4, 0, 53},
 	{7, 0, 4, 0, 51},
-	{7, 0, 4, 0, 49},
+	{7, 0, 4, 0, 50},
 	{7, 0, 4, 0, 48},
+	{7, 0, 4, 0, 47},
 	{7, 0, 4, 0, 46},
-	{7, 0, 3, 0, 60},
-	{7, 0, 3, 0, 58},
-	{7, 0, 3, 0, 57},
-	{7, 0, 3, 0, 55},
-	{7, 0, 3, 0, 54},
-	{7, 0, 3, 0, 52},
+	{7, 0, 4, 0, 44},
+	{7, 0, 4, 0, 43},
+	{7, 0, 4, 0, 42},
+	{7, 0, 4, 0, 41},
+	{7, 0, 4, 0, 40},
 	{7, 0, 3, 0, 51},
-	{7, 0, 3, 0, 49},
+	{7, 0, 3, 0, 50},
 	{7, 0, 3, 0, 48},
+	{7, 0, 3, 0, 47},
 	{7, 0, 3, 0, 46},
-	{7, 0, 3, 0, 45},
 	{7, 0, 3, 0, 44},
 	{7, 0, 3, 0, 43},
+	{7, 0, 3, 0, 42},
 	{7, 0, 3, 0, 41},
-	{7, 0, 2, 0, 61},
-	{7, 0, 2, 0, 59},
-	{7, 0, 2, 0, 57},
-	{7, 0, 2, 0, 56},
-	{7, 0, 2, 0, 54},
-	{7, 0, 2, 0, 53},
-	{7, 0, 2, 0, 51},
-	{7, 0, 2, 0, 50},
-	{7, 0, 2, 0, 48},
-	{7, 0, 2, 0, 47},
-	{7, 0, 2, 0, 46},
-	{7, 0, 2, 0, 44},
-	{7, 0, 2, 0, 43},
-	{7, 0, 2, 0, 42},
-	{7, 0, 2, 0, 41},
-	{7, 0, 2, 0, 39},
-	{7, 0, 2, 0, 38},
-	{7, 0, 2, 0, 37},
-	{7, 0, 2, 0, 36},
-	{7, 0, 2, 0, 35},
-	{7, 0, 2, 0, 34},
-	{7, 0, 2, 0, 33},
-	{7, 0, 2, 0, 32},
-	{7, 0, 1, 0, 63},
-	{7, 0, 1, 0, 61},
-	{7, 0, 1, 0, 59},
-	{7, 0, 1, 0, 57},
+	{3, 0, 3, 0, 56},
+	{3, 0, 3, 0, 54},
+	{3, 0, 3, 0, 53},
+	{3, 0, 3, 0, 51},
+	{3, 0, 3, 0, 50},
+	{3, 0, 3, 0, 48},
+	{3, 0, 3, 0, 47},
+	{3, 0, 3, 0, 46},
+	{3, 0, 3, 0, 44},
+	{3, 0, 3, 0, 43},
+	{3, 0, 3, 0, 42},
+	{3, 0, 3, 0, 41},
+	{3, 0, 3, 0, 39},
+	{3, 0, 3, 0, 38},
+	{3, 0, 3, 0, 37},
+	{3, 0, 3, 0, 36},
+	{3, 0, 3, 0, 35},
+	{3, 0, 3, 0, 34},
 };
 
 const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 00/12] brcmsmac: bcm4313 iPA support
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

This series replaces the patch "brcmsmac: support 4313iPA" with
Message-ID: <1376130450-29746-13-git-send-email-arend@broadcom.com>.
That patch has been split up and other review comments from Jonas
Gorski have been taken into account.

The series is intended for v3.12 and applies to the master
branch of the wireless-next repository.

Arend van Spriel (12):
  brcmsmac: cosmetic change in phy_lcn.c
  brcmsmac: change pa_gain for bcm4313 iPA
  brcmsmac: use ARRAY_SIZE in phytbl_lcn.c
  brcmsmac: add debug info message providing phy and radio info
  brcmsmac: update transmit gain table for lcn phy
  brcmsmac: change lcnphy receive i/q calibration routine
  brcmsmac: fix TSSI idle estimation
  brcmsmac: avoid calling set_txpwr_by_index() twice
  brcmsmac: rework switch control table init including iPA BT-combo
  brcmsmac: correct phy registers for TSSI-based power control
  brcmsmac: reinitialize TSSI power control upon channel switch
  brcmsmac: add support for BCM4313 iPA variant

 drivers/net/wireless/brcm80211/brcmsmac/main.c     |    4 +-
 .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c  |  397 +++++++++++--------
 .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c   |  405 +++++++++++---------
 .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h   |    1 +
 4 files changed, 475 insertions(+), 332 deletions(-)

-- 
1.7.10.4



^ permalink raw reply

* [PATCH 02/12] brcmsmac: change pa_gain for bcm4313 iPA
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel, Jonas Gorski
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

The function wlc_lcnphy_load_tx_gain_table() has a target PA
gain specified for the iPA variant of the bcm4313. This gain
value is reduced to avoid PA distortion. The if-statement is
removed because it was rather redundant in the first place.
Please note that this patch does not provide full iPA support.

Cc: Jonas Gorski <jogo@openwrt.org>
Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index e646ba0..8dc5d0f 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -4282,13 +4282,10 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
 	u16 pa_gain;
 	u16 gm_gain;
 
-	if (CHSPEC_IS5G(pi->radio_chanspec))
-		pa_gain = 0x70;
-	else
-		pa_gain = 0x70;
-
 	if (pi->sh->boardflags & BFL_FEM)
 		pa_gain = 0x10;
+	else
+		pa_gain = 0x60;
 	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
 	tab.tbl_width = 32;
 	tab.tbl_len = 1;
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 01/12] brcmsmac: cosmetic change in phy_lcn.c
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel, Jonas Gorski
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

Cleaning up some code fragments reducing indentation and uncluttering
some lines. Apart from whitespace there are no actual code changes
made.

Cc: Jonas Gorski <jogo@openwrt.org>
Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c  |  213 ++++++++++----------
 1 file changed, 106 insertions(+), 107 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index 3d6b16c..e646ba0 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -1137,8 +1137,9 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
 	gain0_15 = ((biq1 & 0xf) << 12) |
 		   ((tia & 0xf) << 8) |
 		   ((lna2 & 0x3) << 6) |
-		   ((lna2 &
-		     0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
+		   ((lna2 & 0x3) << 4) |
+		   ((lna1 & 0x3) << 2) |
+		   ((lna1 & 0x3) << 0);
 
 	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
 	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@@ -1368,126 +1369,124 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
 		goto cal_done;
 	}
 
-	if (module == 1) {
+	WARN_ON(module != 1);
+	tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
 
-		tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
-		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+	for (i = 0; i < 11; i++)
+		values_to_save[i] =
+			read_radio_reg(pi, rxiq_cal_rf_reg[i]);
+	Core1TxControl_old = read_phy_reg(pi, 0x631);
+
+	or_phy_reg(pi, 0x631, 0x0015);
+
+	RFOverride0_old = read_phy_reg(pi, 0x44c);
+	RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
+	rfoverride2_old = read_phy_reg(pi, 0x4b0);
+	rfoverride2val_old = read_phy_reg(pi, 0x4b1);
+	rfoverride3_old = read_phy_reg(pi, 0x4f9);
+	rfoverride3val_old = read_phy_reg(pi, 0x4fa);
+	rfoverride4_old = read_phy_reg(pi, 0x938);
+	rfoverride4val_old = read_phy_reg(pi, 0x939);
+	afectrlovr_old = read_phy_reg(pi, 0x43b);
+	afectrlovrval_old = read_phy_reg(pi, 0x43c);
+	old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+	old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
 
-		for (i = 0; i < 11; i++)
-			values_to_save[i] =
-				read_radio_reg(pi, rxiq_cal_rf_reg[i]);
-		Core1TxControl_old = read_phy_reg(pi, 0x631);
-
-		or_phy_reg(pi, 0x631, 0x0015);
-
-		RFOverride0_old = read_phy_reg(pi, 0x44c);
-		RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
-		rfoverride2_old = read_phy_reg(pi, 0x4b0);
-		rfoverride2val_old = read_phy_reg(pi, 0x4b1);
-		rfoverride3_old = read_phy_reg(pi, 0x4f9);
-		rfoverride3val_old = read_phy_reg(pi, 0x4fa);
-		rfoverride4_old = read_phy_reg(pi, 0x938);
-		rfoverride4val_old = read_phy_reg(pi, 0x939);
-		afectrlovr_old = read_phy_reg(pi, 0x43b);
-		afectrlovrval_old = read_phy_reg(pi, 0x43c);
-		old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
-		old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
-
-		tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
-		if (tx_gain_override_old) {
-			wlc_lcnphy_get_tx_gain(pi, &old_gains);
-			tx_gain_index_old = pi_lcn->lcnphy_current_index;
-		}
+	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+	if (tx_gain_override_old) {
+		wlc_lcnphy_get_tx_gain(pi, &old_gains);
+		tx_gain_index_old = pi_lcn->lcnphy_current_index;
+	}
 
-		wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
+	wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
 
-		mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
-		mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+	mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+	mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
 
-		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
-		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+	mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+	mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
 
-		write_radio_reg(pi, RADIO_2064_REG116, 0x06);
-		write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
-		write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
-		write_radio_reg(pi, RADIO_2064_REG098, 0x03);
-		write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
-		mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
-		write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
-		write_radio_reg(pi, RADIO_2064_REG114, 0x01);
-		write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
-		write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
-
-		mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
-		mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
-		mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
-		mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
-		mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
-		mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
-		mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
-		mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
-		mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
-		mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
-
-		mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
-		mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
-
-		wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
-		write_phy_reg(pi, 0x6da, 0xffff);
-		or_phy_reg(pi, 0x6db, 0x3);
-		wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
-		wlc_lcnphy_rx_gain_override_enable(pi, true);
-
-		tia_gain = 8;
-		rx_pwr_threshold = 950;
-		while (tia_gain > 0) {
-			tia_gain -= 1;
-			wlc_lcnphy_set_rx_gain_by_distribution(pi,
-							       0, 0, 2, 2,
-							       (u16)
-							       tia_gain, 1, 0);
-			udelay(500);
+	write_radio_reg(pi, RADIO_2064_REG116, 0x06);
+	write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
+	write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
+	write_radio_reg(pi, RADIO_2064_REG098, 0x03);
+	write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+	mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
+	write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
+	write_radio_reg(pi, RADIO_2064_REG114, 0x01);
+	write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
+	write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
+
+	mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
+	mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
+	mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
+	mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
+	mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
+	mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
+	mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
+	mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
+	mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
+	mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
 
-			received_power =
-				wlc_lcnphy_measure_digital_power(pi, 2000);
-			if (received_power < rx_pwr_threshold)
-				break;
-		}
-		result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
+	mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+	mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
 
-		wlc_lcnphy_stop_tx_tone(pi);
+	wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
+	write_phy_reg(pi, 0x6da, 0xffff);
+	or_phy_reg(pi, 0x6db, 0x3);
+	wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
+	wlc_lcnphy_rx_gain_override_enable(pi, true);
 
-		write_phy_reg(pi, 0x631, Core1TxControl_old);
+	tia_gain = 8;
+	rx_pwr_threshold = 950;
+	while (tia_gain > 0) {
+		tia_gain -= 1;
+		wlc_lcnphy_set_rx_gain_by_distribution(pi,
+						       0, 0, 2, 2,
+						       (u16)
+						       tia_gain, 1, 0);
+		udelay(500);
 
-		write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
-		write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
-		write_phy_reg(pi, 0x4b0, rfoverride2_old);
-		write_phy_reg(pi, 0x4b1, rfoverride2val_old);
-		write_phy_reg(pi, 0x4f9, rfoverride3_old);
-		write_phy_reg(pi, 0x4fa, rfoverride3val_old);
-		write_phy_reg(pi, 0x938, rfoverride4_old);
-		write_phy_reg(pi, 0x939, rfoverride4val_old);
-		write_phy_reg(pi, 0x43b, afectrlovr_old);
-		write_phy_reg(pi, 0x43c, afectrlovrval_old);
-		write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
-		write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
+		received_power =
+			wlc_lcnphy_measure_digital_power(pi, 2000);
+		if (received_power < rx_pwr_threshold)
+			break;
+	}
+	result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
 
-		wlc_lcnphy_clear_trsw_override(pi);
+	wlc_lcnphy_stop_tx_tone(pi);
 
-		mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
+	write_phy_reg(pi, 0x631, Core1TxControl_old);
+
+	write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
+	write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
+	write_phy_reg(pi, 0x4b0, rfoverride2_old);
+	write_phy_reg(pi, 0x4b1, rfoverride2val_old);
+	write_phy_reg(pi, 0x4f9, rfoverride3_old);
+	write_phy_reg(pi, 0x4fa, rfoverride3val_old);
+	write_phy_reg(pi, 0x938, rfoverride4_old);
+	write_phy_reg(pi, 0x939, rfoverride4val_old);
+	write_phy_reg(pi, 0x43b, afectrlovr_old);
+	write_phy_reg(pi, 0x43c, afectrlovrval_old);
+	write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+	write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
 
-		for (i = 0; i < 11; i++)
-			write_radio_reg(pi, rxiq_cal_rf_reg[i],
-					values_to_save[i]);
+	wlc_lcnphy_clear_trsw_override(pi);
 
-		if (tx_gain_override_old)
-			wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
-		else
-			wlc_lcnphy_disable_tx_gain_override(pi);
+	mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
 
-		wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
-		wlc_lcnphy_rx_gain_override_enable(pi, false);
-	}
+	for (i = 0; i < 11; i++)
+		write_radio_reg(pi, rxiq_cal_rf_reg[i],
+				values_to_save[i]);
+
+	if (tx_gain_override_old)
+		wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
+	else
+		wlc_lcnphy_disable_tx_gain_override(pi);
+
+	wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
+	wlc_lcnphy_rx_gain_override_enable(pi, false);
 
 cal_done:
 	kfree(ptr);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 08/12] brcmsmac: avoid calling set_txpwr_by_index() twice
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

For lcnphy revision 1 or when hardware supports i/q calibration the
function wlc_lcnphy_set_txpwr_by_index() was called twice.

Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index e08b73a..caced82 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -3897,7 +3897,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
 	target_gains.pad_gain = 21;
 	target_gains.dac_gain = 0;
 	wlc_lcnphy_set_tx_gain(pi, &target_gains);
-	wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
 
 	if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
 
@@ -3908,6 +3907,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
 					lcnphy_recal ? LCNPHY_CAL_RECAL :
 					LCNPHY_CAL_FULL), false);
 	} else {
+		wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
 		wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
 	}
 
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 12/12] brcmsmac: add support for BCM4313 iPA variant
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

This patch completes the changes needed for supporting the
iPA variant cards of the BCM4313 wireless chipset.

Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c  |   71 ++++++++++++++------
 1 file changed, 51 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index 8fb1048..54f96f8 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -1826,6 +1826,17 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
 		write_radio_reg(pi, RADIO_2064_REG038, 3);
 		write_radio_reg(pi, RADIO_2064_REG091, 7);
 	}
+
+	if (!(pi->sh->boardflags & BFL_FEM)) {
+		u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc,
+			0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0};
+
+		write_radio_reg(pi, RADIO_2064_REG02A, 0xf);
+		write_radio_reg(pi, RADIO_2064_REG091, 0x3);
+		write_radio_reg(pi, RADIO_2064_REG038, 0x3);
+
+		write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]);
+	}
 }
 
 static int
@@ -2123,7 +2134,16 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
 {
 	struct phytbl_info tab;
 	u32 rfseq, ind;
+	enum lcnphy_tssi_mode mode;
+	u8 tssi_sel;
 
+	if (pi->sh->boardflags & BFL_FEM) {
+		tssi_sel = 0x1;
+		mode = LCNPHY_TSSI_EXT;
+	} else {
+		tssi_sel = 0xe;
+		mode = LCNPHY_TSSI_POST_PA;
+	}
 	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
 	tab.tbl_width = 32;
 	tab.tbl_ptr = &ind;
@@ -2144,7 +2164,7 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
 
 	mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
 
-	wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
+	wlc_lcnphy_set_tssi_mux(pi, mode);
 	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
 
 	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
@@ -2180,9 +2200,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
 	mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
 
 	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
-		mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
+		mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel);
 		mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
 	} else {
+		mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1);
 		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
 		mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
 	}
@@ -4358,8 +4379,11 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
 	tab.tbl_len = 1;
 	tab.tbl_ptr = &val;
 
+	/* fixed gm_gain value for iPA */
+	gm_gain = 15;
 	for (j = 0; j < 128; j++) {
-		gm_gain = gain_table[j].gm;
+		if (pi->sh->boardflags & BFL_FEM)
+			gm_gain = gain_table[j].gm;
 		val = (((u32) pa_gain << 24) |
 		       (gain_table[j].pad << 16) |
 		       (gain_table[j].pga << 8) | gm_gain);
@@ -4570,7 +4594,10 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
 
 	write_phy_reg(pi, 0x4ea, 0x4688);
 
-	mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+	if (pi->sh->boardflags & BFL_FEM)
+		mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+	else
+		mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0);
 
 	mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
 
@@ -4581,6 +4608,13 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
 	wlc_lcnphy_rcal(pi);
 
 	wlc_lcnphy_rc_cal(pi);
+
+	if (!(pi->sh->boardflags & BFL_FEM)) {
+		write_radio_reg(pi, RADIO_2064_REG032, 0x6f);
+		write_radio_reg(pi, RADIO_2064_REG033, 0x19);
+		write_radio_reg(pi, RADIO_2064_REG039, 0xe);
+	}
+
 }
 
 static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
@@ -4611,22 +4645,20 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
 		wlc_lcnphy_write_table(pi, &tab);
 	}
 
-	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
-	tab.tbl_width = 16;
-	tab.tbl_ptr = &val;
-	tab.tbl_len = 1;
-
-	val = 114;
-	tab.tbl_offset = 0;
-	wlc_lcnphy_write_table(pi, &tab);
+	if (!(pi->sh->boardflags & BFL_FEM)) {
+		tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+		tab.tbl_width = 16;
+		tab.tbl_ptr = &val;
+		tab.tbl_len = 1;
 
-	val = 130;
-	tab.tbl_offset = 1;
-	wlc_lcnphy_write_table(pi, &tab);
+		val = 150;
+		tab.tbl_offset = 0;
+		wlc_lcnphy_write_table(pi, &tab);
 
-	val = 6;
-	tab.tbl_offset = 8;
-	wlc_lcnphy_write_table(pi, &tab);
+		val = 220;
+		tab.tbl_offset = 1;
+		wlc_lcnphy_write_table(pi, &tab);
+	}
 
 	if (CHSPEC_IS2G(pi->radio_chanspec)) {
 		if (pi->sh->boardflags & BFL_FEM)
@@ -5059,8 +5091,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
 	if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
 		return false;
 
-	if ((pi->sh->boardflags & BFL_FEM) &&
-	    (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
+	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
 		if (pi_lcn->lcnphy_tempsense_option == 3) {
 			pi->hwpwrctrl = true;
 			pi->hwpwrctrl_capable = true;
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 11/12] brcmsmac: reinitialize TSSI power control upon channel switch
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

When changing channels the TSSI based power control needs to be
reinitialized.

Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index 2917f5c..8fb1048 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -5019,6 +5019,8 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
 		wlc_lcnphy_load_tx_iir_filter(pi, true, 3);
 
 	mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
+	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
+		wlc_lcnphy_tssi_setup(pi);
 }
 
 void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 09/12] brcmsmac: rework switch control table init including iPA BT-combo
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

Rework the code path in lcnphy tbl_init() for switch control
table programming. This also takes the iPA BT-combo card into
account.

Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c  |   31 +++++----
 .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c   |   72 ++++++++++++++++++++
 .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h   |    1 +
 3 files changed, 89 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index caced82..08bcae4 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -4573,6 +4573,7 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
 	uint idx;
 	u8 phybw40;
 	struct phytbl_info tab;
+	const struct phytbl_info *tb;
 	u32 val;
 
 	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
@@ -4619,7 +4620,6 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
 	}
 
 	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
-		const struct phytbl_info *tb;
 		int l;
 
 		if (CHSPEC_IS2G(pi->radio_chanspec)) {
@@ -4640,21 +4640,22 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
 			wlc_lcnphy_write_table(pi, &tb[idx]);
 	}
 
-	if ((pi->sh->boardflags & BFL_FEM)
-	    && !(pi->sh->boardflags & BFL_FEM_BT))
-		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa);
-	else if (pi->sh->boardflags & BFL_FEM_BT) {
-		if (pi->sh->boardrev < 0x1250)
-			wlc_lcnphy_write_table(
-				pi,
-				&dot11lcn_sw_ctrl_tbl_info_4313_bt_epa);
+	if (pi->sh->boardflags & BFL_FEM) {
+		if (pi->sh->boardflags & BFL_FEM_BT) {
+			if (pi->sh->boardrev < 0x1250)
+				tb = &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
+			else
+				tb = &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
+		} else {
+			tb = &dot11lcn_sw_ctrl_tbl_info_4313_epa;
+		}
+	} else {
+		if (pi->sh->boardflags & BFL_FEM_BT)
+			tb = &dot11lcn_sw_ctrl_tbl_info_4313_bt_ipa;
 		else
-			wlc_lcnphy_write_table(
-				pi,
-				&dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250);
-	} else
-		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313);
-
+			tb = &dot11lcn_sw_ctrl_tbl_info_4313;
+	}
+	wlc_lcnphy_write_table(pi, tb);
 	wlc_lcnphy_load_rfpower(pi);
 
 	wlc_lcnphy_clear_papd_comptable(pi);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
index efd5a58..d7fa312 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
@@ -2044,6 +2044,73 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
 	0x0005,
 };
 
+static const u16 dot11lcn_sw_ctrl_tbl_4313_ipa_rev0_combo[] = {
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+	0x0005,
+	0x0006,
+	0x0009,
+	0x000a,
+};
+
 static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
 	0x0004,
 	0x0004,
@@ -2808,6 +2875,11 @@ const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313 = {
 	ARRAY_SIZE(dot11lcn_sw_ctrl_tbl_4313_rev0), 15, 0, 16
 };
 
+const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_ipa = {
+	&dot11lcn_sw_ctrl_tbl_4313_ipa_rev0_combo,
+	ARRAY_SIZE(dot11lcn_sw_ctrl_tbl_4313_ipa_rev0_combo), 15, 0, 16
+};
+
 const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa = {
 	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
 	ARRAY_SIZE(dot11lcn_sw_ctrl_tbl_4313_epa_rev0), 15, 0, 16
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
index 5f75e16..489422a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
@@ -20,6 +20,7 @@
 extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[];
 extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
 extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313;
+extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_ipa;
 extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa;
 extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
 extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 06/12] brcmsmac: change lcnphy receive i/q calibration routine
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel, Jonas Gorski
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

The gain level control for the test tone has been changed. This
calbration test tone is used to determine the i/q compensation.
The i/q calibration routine has been reworked to accomodate this.

Cc: Jonas Gorski <jogo@openwrt.org>
Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c  |   78 +++++++++++++++-----
 1 file changed, 58 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index 8dc5d0f..236e8d9 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -1329,6 +1329,43 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
 	return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
 }
 
+static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
+				      u16 tia_gain, u16 lna2_gain)
+{
+	u32 i_thresh_l, q_thresh_l;
+	u32 i_thresh_h, q_thresh_h;
+	struct lcnphy_iq_est iq_est_h, iq_est_l;
+
+	wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
+					       lna2_gain, 0);
+
+	wlc_lcnphy_rx_gain_override_enable(pi, true);
+	wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
+	udelay(500);
+	write_radio_reg(pi, RADIO_2064_REG112, 0);
+	if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
+		return false;
+
+	wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
+	udelay(500);
+	write_radio_reg(pi, RADIO_2064_REG112, 0);
+	if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
+		return false;
+
+	i_thresh_l = (iq_est_l.i_pwr << 1);
+	i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;
+
+	q_thresh_l = (iq_est_l.q_pwr << 1);
+	q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
+	if ((iq_est_h.i_pwr > i_thresh_l) &&
+	    (iq_est_h.i_pwr < i_thresh_h) &&
+	    (iq_est_h.q_pwr > q_thresh_l) &&
+	    (iq_est_h.q_pwr < q_thresh_h))
+		return true;
+
+	return false;
+}
+
 static bool
 wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
 		     const struct lcnphy_rx_iqcomp *iqcomp,
@@ -1343,8 +1380,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
 	    RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
 	    rfoverride3_old, rfoverride3val_old, rfoverride4_old,
 	    rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
-	int tia_gain;
-	u32 received_power, rx_pwr_threshold;
+	int tia_gain, lna2_gain, biq1_gain;
+	bool set_gain;
 	u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
 	u16 values_to_save[11];
 	s16 *ptr;
@@ -1432,29 +1469,30 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
 	mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
 	mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
 
-	wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
 	write_phy_reg(pi, 0x6da, 0xffff);
 	or_phy_reg(pi, 0x6db, 0x3);
-	wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
-	wlc_lcnphy_rx_gain_override_enable(pi, true);
-
-	tia_gain = 8;
-	rx_pwr_threshold = 950;
-	while (tia_gain > 0) {
-		tia_gain -= 1;
-		wlc_lcnphy_set_rx_gain_by_distribution(pi,
-						       0, 0, 2, 2,
-						       (u16)
-						       tia_gain, 1, 0);
-		udelay(500);
 
-		received_power =
-			wlc_lcnphy_measure_digital_power(pi, 2000);
-		if (received_power < rx_pwr_threshold)
-			break;
+	wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
+	for (lna2_gain = 3; lna2_gain >= 0; lna2_gain--) {
+		for (tia_gain = 4; tia_gain >= 0; tia_gain--) {
+			for (biq1_gain = 6; biq1_gain >= 0; biq1_gain--) {
+				set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
+								     (u16)
+								     biq1_gain,
+								     (u16)
+								     tia_gain,
+								     (u16)
+								     lna2_gain);
+				if (!set_gain)
+					continue;
+
+				result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
+				goto stop_tone;
+			}
+		}
 	}
-	result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
 
+stop_tone:
 	wlc_lcnphy_stop_tx_tone(pi);
 
 	write_phy_reg(pi, 0x631, Core1TxControl_old);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 03/12] brcmsmac: use ARRAY_SIZE in phytbl_lcn.c
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel, Jonas Gorski
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

This patch converts all sizeof(x)/sizeof(x[0]) instances to
ARRAY_SIZE macro in phytbl_lcn.c. The patch was made using
spatch with ARRAY_SIZE.cocci (see [1]).

[1] https://github.com/coccinelle/coccinelle/tree/master/demos/janitorings

Cc: Jonas Gorski <jogo@openwrt.org>
Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c   |  117 ++++++++------------
 1 file changed, 44 insertions(+), 73 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
index 622c01c..deae3a7 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
@@ -1507,117 +1507,103 @@ static const u32 dot11lcn_gain_tbl_5G[] = {
 
 const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[] = {
 	{&dot11lcn_gain_tbl_rev0,
-	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
+	 ARRAY_SIZE(dot11lcn_gain_tbl_rev0), 18,
 	 0, 32}
 	,
 	{&dot11lcn_aux_gain_idx_tbl_rev0,
-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+	 ARRAY_SIZE(dot11lcn_aux_gain_idx_tbl_rev0), 14, 0, 16}
 	,
 	{&dot11lcn_gain_idx_tbl_rev0,
-	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
-	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+	 ARRAY_SIZE(dot11lcn_gain_idx_tbl_rev0), 13, 0, 32}
 	,
 };
 
 static const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev1[] = {
 	{&dot11lcn_gain_tbl_rev1,
-	 sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18,
+	 ARRAY_SIZE(dot11lcn_gain_tbl_rev1), 18,
 	 0, 32}
 	,
 	{&dot11lcn_aux_gain_idx_tbl_rev0,
-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+	 ARRAY_SIZE(dot11lcn_aux_gain_idx_tbl_rev0), 14, 0, 16}
 	,
 	{&dot11lcn_gain_idx_tbl_rev0,
-	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
-	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+	 ARRAY_SIZE(dot11lcn_gain_idx_tbl_rev0), 13, 0, 32}
 	,
 };
 
 const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
 	{&dot11lcn_gain_tbl_2G,
-	 sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0,
+	 ARRAY_SIZE(dot11lcn_gain_tbl_2G), 18, 0,
 	 32}
 	,
 	{&dot11lcn_aux_gain_idx_tbl_2G,
-	 sizeof(dot11lcn_aux_gain_idx_tbl_2G) /
-	 sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16}
+	 ARRAY_SIZE(dot11lcn_aux_gain_idx_tbl_2G), 14, 0, 16}
 	,
 	{&dot11lcn_gain_idx_tbl_2G,
-	 sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]),
+	 ARRAY_SIZE(dot11lcn_gain_idx_tbl_2G),
 	 13, 0, 32}
 	,
 	{&dot11lcn_gain_val_tbl_2G,
-	 sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]),
+	 ARRAY_SIZE(dot11lcn_gain_val_tbl_2G),
 	 17, 0, 8}
 };
 
 const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
 	{&dot11lcn_gain_tbl_5G,
-	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
+	 ARRAY_SIZE(dot11lcn_gain_tbl_5G), 18, 0,
 	 32}
 	,
 	{&dot11lcn_aux_gain_idx_tbl_5G,
-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
+	 ARRAY_SIZE(dot11lcn_aux_gain_idx_tbl_5G), 14, 0, 16}
 	,
 	{&dot11lcn_gain_idx_tbl_5G,
-	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
+	 ARRAY_SIZE(dot11lcn_gain_idx_tbl_5G),
 	 13, 0, 32}
 	,
 	{&dot11lcn_gain_val_tbl_5G,
-	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
+	 ARRAY_SIZE(dot11lcn_gain_val_tbl_5G),
 	 17, 0, 8}
 };
 
 const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
 	{&dot11lcn_gain_tbl_extlna_2G,
-	 sizeof(dot11lcn_gain_tbl_extlna_2G) /
-	 sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32}
+	 ARRAY_SIZE(dot11lcn_gain_tbl_extlna_2G), 18, 0, 32}
 	,
 	{&dot11lcn_aux_gain_idx_tbl_extlna_2G,
-	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) /
-	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16}
+	 ARRAY_SIZE(dot11lcn_aux_gain_idx_tbl_extlna_2G), 14, 0, 16}
 	,
 	{&dot11lcn_gain_idx_tbl_extlna_2G,
-	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G) /
-	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32}
+	 ARRAY_SIZE(dot11lcn_gain_idx_tbl_extlna_2G), 13, 0, 32}
 	,
 	{&dot11lcn_gain_val_tbl_extlna_2G,
-	 sizeof(dot11lcn_gain_val_tbl_extlna_2G) /
-	 sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8}
+	 ARRAY_SIZE(dot11lcn_gain_val_tbl_extlna_2G), 17, 0, 8}
 };
 
 const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
 	{&dot11lcn_gain_tbl_5G,
-	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
+	 ARRAY_SIZE(dot11lcn_gain_tbl_5G), 18, 0,
 	 32}
 	,
 	{&dot11lcn_aux_gain_idx_tbl_5G,
-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
+	 ARRAY_SIZE(dot11lcn_aux_gain_idx_tbl_5G), 14, 0, 16}
 	,
 	{&dot11lcn_gain_idx_tbl_5G,
-	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
+	 ARRAY_SIZE(dot11lcn_gain_idx_tbl_5G),
 	 13, 0, 32}
 	,
 	{&dot11lcn_gain_val_tbl_5G,
-	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
+	 ARRAY_SIZE(dot11lcn_gain_val_tbl_5G),
 	 17, 0, 8}
 };
 
 const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 =
-	sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
-	sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
+	ARRAY_SIZE(dot11lcnphytbl_rx_gain_info_rev0);
 
 const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz =
-	sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
-	sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
+	ARRAY_SIZE(dot11lcnphytbl_rx_gain_info_2G_rev2);
 
 const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz =
-	sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
-	sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
+	ARRAY_SIZE(dot11lcnphytbl_rx_gain_info_5G_rev2);
 
 static const u16 dot11lcn_min_sig_sq_tbl_rev0[] = {
 	0x014d,
@@ -2771,89 +2757,74 @@ static const u32 dot11lcn_papd_compdelta_tbl_rev0[] = {
 
 const struct phytbl_info dot11lcnphytbl_info_rev0[] = {
 	{&dot11lcn_min_sig_sq_tbl_rev0,
-	 sizeof(dot11lcn_min_sig_sq_tbl_rev0) /
-	 sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16}
+	 ARRAY_SIZE(dot11lcn_min_sig_sq_tbl_rev0), 2, 0, 16}
 	,
 	{&dot11lcn_noise_scale_tbl_rev0,
-	 sizeof(dot11lcn_noise_scale_tbl_rev0) /
-	 sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16}
+	 ARRAY_SIZE(dot11lcn_noise_scale_tbl_rev0), 1, 0, 16}
 	,
 	{&dot11lcn_fltr_ctrl_tbl_rev0,
-	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0) /
-	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32}
+	 ARRAY_SIZE(dot11lcn_fltr_ctrl_tbl_rev0), 11, 0, 32}
 	,
 	{&dot11lcn_ps_ctrl_tbl_rev0,
-	 sizeof(dot11lcn_ps_ctrl_tbl_rev0) /
-	 sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32}
+	 ARRAY_SIZE(dot11lcn_ps_ctrl_tbl_rev0), 12, 0, 32}
 	,
 	{&dot11lcn_gain_idx_tbl_rev0,
-	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
-	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+	 ARRAY_SIZE(dot11lcn_gain_idx_tbl_rev0), 13, 0, 32}
 	,
 	{&dot11lcn_aux_gain_idx_tbl_rev0,
-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+	 ARRAY_SIZE(dot11lcn_aux_gain_idx_tbl_rev0), 14, 0, 16}
 	,
 	{&dot11lcn_sw_ctrl_tbl_rev0,
-	 sizeof(dot11lcn_sw_ctrl_tbl_rev0) /
-	 sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16}
+	 ARRAY_SIZE(dot11lcn_sw_ctrl_tbl_rev0), 15, 0, 16}
 	,
 	{&dot11lcn_nf_table_rev0,
-	 sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16,
+	 ARRAY_SIZE(dot11lcn_nf_table_rev0), 16,
 	 0, 8}
 	,
 	{&dot11lcn_gain_val_tbl_rev0,
-	 sizeof(dot11lcn_gain_val_tbl_rev0) /
-	 sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8}
+	 ARRAY_SIZE(dot11lcn_gain_val_tbl_rev0), 17, 0, 8}
 	,
 	{&dot11lcn_gain_tbl_rev0,
-	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
+	 ARRAY_SIZE(dot11lcn_gain_tbl_rev0), 18,
 	 0, 32}
 	,
 	{&dot11lcn_spur_tbl_rev0,
-	 sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20,
+	 ARRAY_SIZE(dot11lcn_spur_tbl_rev0), 20,
 	 0, 8}
 	,
 	{&dot11lcn_unsup_mcs_tbl_rev0,
-	 sizeof(dot11lcn_unsup_mcs_tbl_rev0) /
-	 sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16}
+	 ARRAY_SIZE(dot11lcn_unsup_mcs_tbl_rev0), 23, 0, 16}
 	,
 	{&dot11lcn_iq_local_tbl_rev0,
-	 sizeof(dot11lcn_iq_local_tbl_rev0) /
-	 sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16}
+	 ARRAY_SIZE(dot11lcn_iq_local_tbl_rev0), 0, 0, 16}
 	,
 	{&dot11lcn_papd_compdelta_tbl_rev0,
-	 sizeof(dot11lcn_papd_compdelta_tbl_rev0) /
-	 sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32}
+	 ARRAY_SIZE(dot11lcn_papd_compdelta_tbl_rev0), 24, 0, 32}
 	,
 };
 
 const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313 = {
 	&dot11lcn_sw_ctrl_tbl_4313_rev0,
-	sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) /
-	sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16
+	ARRAY_SIZE(dot11lcn_sw_ctrl_tbl_4313_rev0), 15, 0, 16
 };
 
 const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa = {
 	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
-	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) /
-	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16
+	ARRAY_SIZE(dot11lcn_sw_ctrl_tbl_4313_epa_rev0), 15, 0, 16
 };
 
 const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
 	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo,
-	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) /
-	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16
+	ARRAY_SIZE(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo), 15, 0, 16
 };
 
 const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
 	&dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0,
-	sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) /
-	sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16
+	ARRAY_SIZE(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0), 15, 0, 16
 };
 
 const u32 dot11lcnphytbl_info_sz_rev0 =
-	sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
+	ARRAY_SIZE(dot11lcnphytbl_info_rev0);
 
 const struct lcnphy_tx_gain_tbl_entry
 dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 10/12] brcmsmac: correct phy registers for TSSI-based power control
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

A number of additional phy registers needs to be programmed when
using TSSI-based power control.

Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c  |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index 08bcae4..2917f5c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -2020,6 +2020,16 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
 		} else {
 			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
 			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+			mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0);
+			mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2);
+			mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0);
+			mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4);
+			mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
+			mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77);
+			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1);
+			mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7);
+			mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1);
+			mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4);
 		}
 	} else {
 		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
@@ -2106,6 +2116,7 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
 		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
 
 	mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
+	mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0));
 }
 
 static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
@@ -2218,6 +2229,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
 
 	mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
 
+	mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0);
+	mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
+	mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+
 	wlc_lcnphy_pwrctrl_rssiparams(pi);
 }
 
@@ -3096,6 +3111,11 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
 			wlc_lcnphy_write_table(pi, &tab);
 			tab.tbl_offset++;
 		}
+		mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0);
+		mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0);
+		mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8);
+		mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4);
+		mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2);
 
 		mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
 
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 07/12] brcmsmac: fix TSSI idle estimation
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

The baseband multiplier must be zero during TSSI idle estimation
and restored afterwards.

Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Tested-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index 236e8d9..e08b73a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -2836,6 +2836,8 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
 		read_radio_reg(pi, RADIO_2064_REG007) & 1;
 	u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
 	u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
+	u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi);
+
 	idleTssi = read_phy_reg(pi, 0x4ab);
 	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
 			 MCTL_EN_MAC));
@@ -2853,6 +2855,12 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
 	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
 	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
 	wlc_lcnphy_tssi_setup(pi);
+
+	mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0));
+	mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6));
+
+	wlc_lcnphy_set_bbmult(pi, 0x0);
+
 	wlc_phy_do_dummy_tx(pi, true, OFF);
 	idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
 		    >> 0);
@@ -2874,6 +2882,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
 
 	mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
 
+	wlc_lcnphy_set_bbmult(pi, SAVE_bbmult);
 	wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
 	wlc_lcnphy_set_tx_gain(pi, &old_gains);
 	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 04/12] brcmsmac: add debug info message providing phy and radio info
From: Arend van Spriel @ 2013-08-20 14:00 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1377007246-9957-1-git-send-email-arend@broadcom.com>

For debug purposes it is good to have the phy and radio information
available in the log. Only logged when driver is built when BRCMDBG
or BRCM_TRACING kconfig are set.

Tested-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmsmac/main.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 7ca10bf..c3c6123 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4652,7 +4652,9 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
 		wlc->band->phyrev = wlc_hw->band->phyrev;
 		wlc->band->radioid = wlc_hw->band->radioid;
 		wlc->band->radiorev = wlc_hw->band->radiorev;
-
+		brcms_dbg_info(core, "wl%d: phy %u/%u radio %x/%u\n", unit,
+			       wlc->band->phytype, wlc->band->phyrev,
+			       wlc->band->radioid, wlc->band->radiorev);
 		/* default contention windows size limits */
 		wlc_hw->band->CWmin = APHY_CWMIN;
 		wlc_hw->band->CWmax = PHY_CWMAX;
-- 
1.7.10.4



^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox