* Re: [BUG] after starting wimaxd at boot iwlagn module will crash for intel 6250 card
From: Guy, Wey-Yi @ 2010-07-28 0:04 UTC (permalink / raw)
To: Sternberg, Jay E, Inaky Perez-Gonzalez
Cc: alexxy@gentoo.org, wimax@linuxwimax.org,
linux-wireless@vger.kernel.org
In-Reply-To: <1280270313.26204.288.camel@localhost.localdomain>
Hi,
On Tue, 2010-07-27 at 15:38 -0700, Inaky Perez-Gonzalez wrote:
> On Tue, 2010-07-27 at 13:28 -0700, Alexey Shvetsov wrote:
> > Hi all!
>
> [apologies, I forgot to mention to CC the linux-wireless mailing list,
> where the iwlagn guys lurk around -- done].
>
> Guys, seems the wifi device is tripping in the 6250 when we switch on
> WiMAX. Do you see anything interesting?
>
> > Seems i fund bug on my 64bit system. I have installed 32bit version
> > of wimax stack 1.5 and i'm running 2.6.35-rc6 kernel.
> >
> > After starting
> > wimaxd at boot time iwlagn driver will crash when i try to scan or connect
> > to any network. Stacktrace will be the following
> >
> > iwlagn 0000:02:00.0:
> > RF_KILL bit toggled to enable radio.
> > i2400m_usb 2-1.3:1.0: 'RF Control'
> > (0x4602) command failed: -84 - invalid state (3)
> > iwlagn 0000:02:00.0:
> > Microcode SW error detected. Restarting 0x2000000.
> > iwlagn 0000:02:00.0:
> > Loaded firmware version: 9.201.4.1 build 24255
> > iwlagn 0000:02:00.0: Start
> > IWL Error Log Dump:
> > iwlagn 0000:02:00.0: Status: 0x00020224, count: 5
> > iwlagn
> > 0000:02:00.0: Desc Time data1 data2
> > line
> > iwlagn 0000:02:00.0: SYSASSERT (#05) 0000012334
> > 0x0000008D 0x8000000D 453
> > iwlagn 0000:02:00.0: pc blink1 blink2
> > ilink1 ilink2 hcmd
> > iwlagn 0000:02:00.0: 0x1D074 0x1D066 0x1D066 0x009B2
> > 0x00000 0x400005A
> > iwlagn 0000:02:00.0: CSR values:
> > iwlagn 0000:02:00.0: (2nd
> > byte of CSR_INT_COALESCING is CSR_INT_PERIODIC_REG)
> > iwlagn 0000:02:00.0:
> > CSR_HW_IF_CONFIG_REG: 0X00480303
> > iwlagn 0000:02:00.0:
> > CSR_INT_COALESCING: 0X0000ff40
> > iwlagn 0000:02:00.0:
> > CSR_INT: 0X00000000
> > iwlagn 0000:02:00.0: CSR_INT_MASK:
> > 0X00000000
> > iwlagn 0000:02:00.0: CSR_FH_INT_STATUS:
> > 0X00000000
> > iwlagn 0000:02:00.0: CSR_GPIO_IN:
> > 0X0000000f
> > iwlagn 0000:02:00.0: CSR_RESET:
> > 0X00000000
> > iwlagn 0000:02:00.0: CSR_GP_CNTRL:
> > 0X080403c5
> > iwlagn 0000:02:00.0: CSR_HW_REV:
> > 0X00000084
> > iwlagn 0000:02:00.0: CSR_EEPROM_REG:
> > 0Xe0a20ffd
> > iwlagn 0000:02:00.0: CSR_EEPROM_GP:
> > 0X90000801
> > iwlagn 0000:02:00.0: CSR_OTP_GP_REG:
> > 0X00030001
> > iwlagn 0000:02:00.0: CSR_GIO_REG:
> > 0X00080046
> > iwlagn 0000:02:00.0: CSR_GP_UCODE_REG:
> > 0X00000002
> > iwlagn 0000:02:00.0: CSR_GP_DRIVER_REG:
> > 0X00000004
> > iwlagn 0000:02:00.0: CSR_UCODE_DRV_GP1:
> > 0X00000000
> > iwlagn 0000:02:00.0: CSR_UCODE_DRV_GP2:
> > 0X00000000
> > iwlagn 0000:02:00.0: CSR_LED_REG:
> > 0X00000018
> > iwlagn 0000:02:00.0: CSR_DRAM_INT_TBL_REG:
> > 0X00000000
> > iwlagn 0000:02:00.0: CSR_GIO_CHICKEN_BITS:
> > 0X27800200
> > iwlagn 0000:02:00.0: CSR_ANA_PLL_CFG:
> > 0X00000000
> > iwlagn 0000:02:00.0: CSR_HW_REV_WA_REG:
> > 0X0001001a
> > iwlagn 0000:02:00.0: CSR_DBG_HPET_MEM_REG:
> > 0Xffff0000
> > iwlagn 0000:02:00.0: FH register values:
> > iwlagn 0000:02:00.0:
> > FH_RSCSR_CHNL0_STTS_WPTR_REG: 0X0ffede00
> > iwlagn 0000:02:00.0:
> > FH_RSCSR_CHNL0_RBDCB_BASE_REG: 0X00ffedf0
> > iwlagn 0000:02:00.0:
> > FH_RSCSR_CHNL0_WPTR: 0X00000000
> > iwlagn 0000:02:00.0:
> > FH_MEM_RCSR_CHNL0_CONFIG_REG: 0X80819104
> > iwlagn 0000:02:00.0:
> > FH_MEM_RSSR_SHARED_CTRL_REG: 0X000000fc
> > iwlagn 0000:02:00.0:
> > FH_MEM_RSSR_RX_STATUS_REG: 0X07030000
> > iwlagn 0000:02:00.0:
> > FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV: 0X00000000
> > iwlagn 0000:02:00.0:
> > FH_TSSR_TX_STATUS_REG: 0X07ff0001
> > iwlagn 0000:02:00.0:
> > FH_TSSR_TX_ERROR_REG: 0X00000000
> > iwlagn 0000:02:00.0: Start IWL Event Log
> > Dump: display last 20 entries
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004384:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004385:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004385:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004387:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004388:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004388:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004389:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004390:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004391:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004391:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004392:0x000000ff:1100
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004402:0x000003b1:0601
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004402:0x10000000:0600
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004403:0x000003c1:0660
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000004407:0x00000000:0661
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000012227:0x0400005a:0401
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000012228:0x0400005a:1513
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000012228:0x00000000:1513
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000012229:0x00000001:1523
> > iwlagn 0000:02:00.0:
> > EVT_LOGT:0000012344:0x00000000:0125
> > iwlagn 0000:02:00.0: Command
> > REPLY_PHY_CALIBRATION_CMD failed: FW Error
> > iwlagn 0000:02:00.0: Error -5
> > iteration 0
> > usb 1-1.4: new full speed USB device using ehci_hcd and address
> > 5
> > iwlagn 0000:02:00.0: Error sending CALIBRATION_CFG_CMD: time out after
> > 500ms.
> > Bluetooth: Generic Bluetooth USB driver ver 0.6
> > usbcore: registered
> > new interface driver btusb
> > Bluetooth: BNEP (Ethernet Emulation) ver
> > 1.3
> > Bluetooth: BNEP filters: protocol multicast
> > Bluetooth: SCO (Voice Link)
> > ver 0.6
> > Bluetooth: SCO socket layer initialized
> > iwlagn 0000:02:00.0:
> > START_ALIVE timeout after 4000ms.
> >
> >
Looks like iwlwifi driver stuck on loading uCode and performing
WiFi/WiMAX coex operation. I will forward the information to our uCode
team to look into it.
Thanks
Wey
^ permalink raw reply
* [PATCH] mac80211: inform drivers about the off-channel status on channel changes
From: Felix Fietkau @ 2010-07-28 0:40 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville, Johannes Berg
For some drivers it can be useful to know whether the channel they're
supposed to switch to is going to be used for short off-channel work or
scanning, or whether the hardware is expected to stay on it for a while
longer. This is important for various kinds of calibration work, which
takes longer to complete and should keep some persistent state, even if
the channel temporarily changes.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
I need something like this for properly getting rid of the ath9k sw
scanning callback and for fixing various calibration bugs.
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -625,11 +625,14 @@ struct ieee80211_rx_status {
* may turn the device off as much as possible. Typically, this flag will
* be set when an interface is set UP but not associated or scanning, but
* it can also be unset in that case when monitor interfaces are active.
+ * @IEEE80211_CONF_OFFCHANNEL: The device is currently not on its main
+ * operating channel.
*/
enum ieee80211_conf_flags {
IEEE80211_CONF_MONITOR = (1<<0),
IEEE80211_CONF_PS = (1<<1),
IEEE80211_CONF_IDLE = (1<<2),
+ IEEE80211_CONF_OFFCHANNEL = (1<<3),
};
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -111,12 +111,15 @@ int ieee80211_hw_config(struct ieee80211
if (scan_chan) {
chan = scan_chan;
channel_type = NL80211_CHAN_NO_HT;
+ local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
} else if (local->tmp_channel) {
chan = scan_chan = local->tmp_channel;
channel_type = local->tmp_channel_type;
+ local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
} else {
chan = local->oper_channel;
channel_type = local->_oper_channel_type;
+ local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
}
if (chan != local->hw.conf.channel ||
^ permalink raw reply
* Re: [PATCH v4 1/3] cfg80211: Add nl80211 antenna configuration
From: Bruno Randolf @ 2010-07-28 2:03 UTC (permalink / raw)
To: Johannes Berg; +Cc: linville, linux-wireless, lrodriguez, Felix Fietkau
In-Reply-To: <1280225142.19098.10.camel@jlt3.sipsolutions.net>
On Tue July 27 2010 19:05:42 you wrote:
> I'm still not convinced that this is the best approach. Can you discuss
> this a bit?
well... i am mainly concerned about what you call "legacy" hardware at the
moment, but i am trying to make the API useful for 802.11n devices as well.
first, thinking only about legacy devices with 2 antennas, the three most
common settings are "fixed antenna 1", "fixed antenna 2" and "antenna
diversity". luis suggested to use a simple value and constants for this, but i
believe that this covers only 90% of the cases, the others being antenna
setups i have described (in the commit message and per email before), which
use a different antenna for TX than for RX, or diversity for RX and a single
fixed antenna for TX. also, while not hugely popular or common, there *is*
"legacy" hardware out there which has more than two antennas (e.g.: "pre-11n
RangeMax" and "large phased array switch" which were based on ath5k chipsets)
and at least the atheros eeprom supports more antennas. i'm not sure about
other hardware, but i think it's good to have the flexibility to support more
than two antennas in the API, also since this matches with what we need for
802.11n. that's why a bitmask makes sense.
honestly, i don't know too much about 802.11n, so i need the help of people
who work with 802.11n to see if this is useful for them and possibly extend
it, or update the documentation to make the API more clear. but i believe that
if you think 'chainmask' instead of 'antenna' it should be o.k...
in the end we are just talking about antennas :) for most of the users the
antenna settings will just be default, but sometimes, especially in outdoor
installations less antennas are present, or special setups can be desired and
this API can be used to inform the HW about available antennas, wether it's
802.11n or not.
bruno
^ permalink raw reply
* Re: [PATCH v4 1/3] cfg80211: Add nl80211 antenna configuration
From: Bruno Randolf @ 2010-07-28 2:06 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: Felix Fietkau, johannes, linville, linux-wireless
In-Reply-To: <AANLkTi=QWMwVTqOqL3wNUnLAWHDw60HmYXtngXJrQOu+@mail.gmail.com>
On Wed July 28 2010 01:47:34 Luis R. Rodriguez wrote:
> On Tue, Jul 27, 2010 at 9:39 AM, Felix Fietkau <nbd@openwrt.org> wrote:
> > On 2010-07-27 6:19 PM, Luis R. Rodriguez wrote:
> >>> + * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for
> >>> transmitting. + * Each bit represents one antenna, starting with
> >>> antenna 1 at the first + * bit. If the bitmap is zero (0), the TX
> >>> antenna follows RX diversity.
> >>
> >> What about for 802.11n? What if you want to disable TX?
> >
> > Disabling tx shouldn't be handled by the antenna setting, IMHO.
> >
> >>> + * If multiple antennas are selected all selected antennas have to
> >>> be used + * for transmitting (801.11n multiple TX chains).
> >>
> >> I rather call this TX / RX chainmask then.
> >
> > Well, for legacy hardware, these aren't really chains, as there is only
> > one rx and one tx path, just with switching onto multiple antennas.
> >
> >>> + * Drivers may reject configurations they cannot support.
> >>> + *
> >>> + * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for
> >>> receiving. + * Each bit represents one antenna, starting with
> >>> antenna 1 at the first + * bit. If multiple antennas are selected
> >>> in the bitmap, 802.11n devices + * should use multiple RX chains
> >>> on these antennas, while non-802.11n + * drivers should use
> >>> antenna diversity between these antennas.
> >>
> >> What about TX beamforming, and STBC?
> >
> > Disabling one antenna/chain on a two-chain device would naturally
> > disable TxBF and STBC as well, since it limits the number of available
> > chains. The driver should simply act as if the disabled chains didn't
> > exist.
>
> That would work.
>
> >> Unless 802.11n is completely dealt with I really prefer this patch to
> >> only address legacy. Otherwise I see sloppyness and inconsistencies on
> >> supporting this feature throughout different drivers. I'd like to
> >> avoid that at all costs on nl80211. What you are trying to address is
> >> legacy antenna setup, not 802.11n RX/TX chainmask dynamic settings so
> >> I'd really try to avoid it unless you really want to address all
> >> aspects of chain configuration for 802.11n and even then what I'm
> >> leading on to say is I think you'll see if you try to address both it
> >> just gets messy.
> >
> > I think 802.11n is already completely dealt with if you treat this as
> > the chainmask on 11n devices.
>
> Its fine by me if the above cases are also embedded into the
> documentation, just don't want these questions lingering. I can't
> think of other 802.11n special cases.
thanks felix :)
luis, could you tell me what exactly you would want to include in the
documentation?
bruno
^ permalink raw reply
* Re: [PATCH 2/2] iw: Add antenna configuration commands
From: Bruno Randolf @ 2010-07-28 2:07 UTC (permalink / raw)
To: Johannes Berg; +Cc: linville, linux-wireless
In-Reply-To: <1280225061.19098.8.camel@jlt3.sipsolutions.net>
On Tue July 27 2010 19:04:21 Johannes Berg wrote:
> On Tue, 2010-07-27 at 18:49 +0900, Bruno Randolf wrote:
> > + if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
> > + tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
> > + printf("\tAntenna: TX %d RX %d\n",
> > + nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]),
> > + nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]));
>
> That's like the worst possible way to show the info.
which way would you prefer?
bruno
^ permalink raw reply
* Re: [PATCH] mac80211: inform drivers about the off-channel status on channel changes
From: Johannes Berg @ 2010-07-28 6:50 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless, John W. Linville
In-Reply-To: <4C4F7C91.9000300@openwrt.org>
On Wed, 2010-07-28 at 02:40 +0200, Felix Fietkau wrote:
> For some drivers it can be useful to know whether the channel they're
> supposed to switch to is going to be used for short off-channel work or
> scanning, or whether the hardware is expected to stay on it for a while
> longer. This is important for various kinds of calibration work, which
> takes longer to complete and should keep some persistent state, even if
> the channel temporarily changes.
>
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> ---
> I need something like this for properly getting rid of the ath9k sw
> scanning callback and for fixing various calibration bugs.
Fine with me, I'll just have to hope people don't abuse it too
much... :-)
johannes
> --- a/include/net/mac80211.h
> +++ b/include/net/mac80211.h
> @@ -625,11 +625,14 @@ struct ieee80211_rx_status {
> * may turn the device off as much as possible. Typically, this flag will
> * be set when an interface is set UP but not associated or scanning, but
> * it can also be unset in that case when monitor interfaces are active.
> + * @IEEE80211_CONF_OFFCHANNEL: The device is currently not on its main
> + * operating channel.
> */
> enum ieee80211_conf_flags {
> IEEE80211_CONF_MONITOR = (1<<0),
> IEEE80211_CONF_PS = (1<<1),
> IEEE80211_CONF_IDLE = (1<<2),
> + IEEE80211_CONF_OFFCHANNEL = (1<<3),
> };
>
>
> --- a/net/mac80211/main.c
> +++ b/net/mac80211/main.c
> @@ -111,12 +111,15 @@ int ieee80211_hw_config(struct ieee80211
> if (scan_chan) {
> chan = scan_chan;
> channel_type = NL80211_CHAN_NO_HT;
> + local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
> } else if (local->tmp_channel) {
> chan = scan_chan = local->tmp_channel;
> channel_type = local->tmp_channel_type;
> + local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
> } else {
> chan = local->oper_channel;
> channel_type = local->_oper_channel_type;
> + local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
> }
>
> if (chan != local->hw.conf.channel ||
>
^ permalink raw reply
* Re: [stable] [PATCH 1/4 2.6.33.y] mac80211: explicitly disable/enable QoS
From: Stanislaw Gruszka @ 2010-07-28 6:50 UTC (permalink / raw)
To: Greg KH; +Cc: Ben Hutchings, stable, linux-wireless
In-Reply-To: <20100727235451.GA12332@kroah.com>
On Tue, 27 Jul 2010 16:54:51 -0700
Greg KH <greg@kroah.com> wrote:
> On Wed, Jul 28, 2010 at 12:15:25AM +0100, Ben Hutchings wrote:
> > On Tue, 2010-07-27 at 15:40 -0700, Greg KH wrote:
> > > On Mon, Jun 07, 2010 at 12:00:24PM +0200, Stanislaw Gruszka wrote:
> > > > commit e1b3ec1a2a336c328c336cfa5485a5f0484cc90d upstream.
> > > >
> > > > Add interface to disable/enable QoS (aka WMM or WME). Currently drivers
> > > > enable it explicitly when ->conf_tx method is called, and newer disable.
> > > > Disabling is needed for some APs, which do not support QoS, such
> > > > we should send QoS frames to them.
> > >
> > > Why is this a patch for a -stable tree? It looks like it adds a new api
> > > for a new feature, right?
> > [...]
> >
> > It extends the interface between the 802.11 stack and drivers so that
> > drivers can avoid sending QoS frames to APs that don't support them.
> > There is no new interface to userland. My understanding is that iwlwifi
> > becomes unable to communicate with non-QoS-capable APs after having once
> > associated with a QoS-capable AP, without this and the following change
> > in iwlwifi itself.
>
> Is this really true? And is it a bug that people are hitting?
Yes, without that patch iwlwifi devices are not able to connect with some
old APs. I had only two Fedora bug reports about that, so do not think
this is something critical. Fill free to drop that patch (together with
"iwlwifi: manage QoS by mac stack" which is part of the fix and do not have
sense alone), or apply only to 2.6.34.
Stanislaw
^ permalink raw reply
* Re: [PATCH 2/2] iw: Add antenna configuration commands
From: Johannes Berg @ 2010-07-28 6:50 UTC (permalink / raw)
To: Bruno Randolf; +Cc: linville, linux-wireless
In-Reply-To: <201007281107.04455.br1@einfach.org>
On Wed, 2010-07-28 at 11:07 +0900, Bruno Randolf wrote:
> On Tue July 27 2010 19:04:21 Johannes Berg wrote:
> > On Tue, 2010-07-27 at 18:49 +0900, Bruno Randolf wrote:
> > > + if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
> > > + tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
> > > + printf("\tAntenna: TX %d RX %d\n",
> > > + nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]),
> > > + nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]));
> >
> > That's like the worst possible way to show the info.
>
> which way would you prefer?
It occurred to me later that with the normal numbers we have (1 through
7) it won't matter much ... but still, I'd prefer %#x.
johannes
^ permalink raw reply
* Re: [PATCH 2/3] mac80211_hwsim: supress scan conflict message
From: Johannes Berg @ 2010-07-28 6:52 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linville, linux-wireless
In-Reply-To: <1280262788-9890-3-git-send-email-lrodriguez@atheros.com>
On Tue, 2010-07-27 at 16:33 -0400, Luis R. Rodriguez wrote:
> Johannes already debugged this and determined it was due
> to a race condition in mac80211, in order to fix this though
> we would need to change drivers quite a bit so for now just
> supress this and we'll correct this on the next kernel release.
This one can stay for all I care since it's not used in practise by
actual users that get confused :-)
johannes
^ permalink raw reply
* Re: [stable] [PATCH 2/2 2.6.32.y] mac80211: fix supported rates IE if AP doesn't give us it's rates
From: Stanislaw Gruszka @ 2010-07-28 6:53 UTC (permalink / raw)
To: Greg KH; +Cc: stable, linux-wireless, Ben Hutchings
In-Reply-To: <20100727223932.GL14257@kroah.com>
On Tue, 27 Jul 2010 15:39:32 -0700
Greg KH <greg@kroah.com> wrote:
> On Mon, Jun 07, 2010 at 11:59:43AM +0200, Stanislaw Gruszka wrote:
> > If AP do not provide us supported rates before assiociation, send
> > all rates we are supporting instead of empty information element.
> >
> > Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> > ---
> > net/mac80211/mlme.c | 17 +++++++++++------
>
> What is the commit id of this patch upstream?
76f273640134f3eb8257179cd5b3bc6ba5fe4a96
Cheers
Stanislaw
^ permalink raw reply
* Re: [PATCH 2/2] iw: Add antenna configuration commands
From: Bruno Randolf @ 2010-07-28 8:29 UTC (permalink / raw)
To: Johannes Berg; +Cc: linville, linux-wireless
In-Reply-To: <1280299848.3832.2.camel@jlt3.sipsolutions.net>
On Wed July 28 2010 15:50:48 Johannes Berg wrote:
> On Wed, 2010-07-28 at 11:07 +0900, Bruno Randolf wrote:
> > On Tue July 27 2010 19:04:21 Johannes Berg wrote:
> > > On Tue, 2010-07-27 at 18:49 +0900, Bruno Randolf wrote:
> > > > + if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
> > > > + tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
> > > > + printf("\tAntenna: TX %d RX %d\n",
> > > > + nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]),
> > > > + nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]));
> > >
> > > That's like the worst possible way to show the info.
> >
> > which way would you prefer?
>
> It occurred to me later that with the normal numbers we have (1 through
> 7) it won't matter much ... but still, I'd prefer %#x.
ok. changed that and the command line parsing to use "strtoul(argv[1], &end,
0)" so we can use hex, decimal or octal for the setting. i will resend the
patches once a consensus is reached (or after an unspecified timeout ;)).
bruno
^ permalink raw reply
* Re: iw dev wlan0 link - "Not connected"
From: Zhongliang Zhao @ 2010-07-28 10:20 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linux-wireless
In-Reply-To: <AANLkTinfWZaiMsmPTmm5qrBRcqMAvQpv1Xq86fxo+S3Z@mail.gmail.com>
On 07/26/2010 07:23 PM, Luis R. Rodriguez wrote:
> On Mon, Jul 26, 2010 at 2:29 AM, Zhongliang Zhao<zhao@iam.unibe.ch> wrote:
>
>> Dear all,
>>
>> When I use "iw dev wlan0 link" to get information on wlan0 (basically to
>> check the channel used on wlan0),
>> it says: " Not connected "
>>
>> Can someone tell me how to fix this?
>>
> Refer to:
>
> http://wireless.kernel.org/en/users/Documentation/iw#Getting_link_status
>
> And then:
>
> http://wireless.kernel.org/en/users/Documentation/iw#Establishing_a_basic_connection
>
> What you really want to use is:
>
> http://wireless.kernel.org/en/users/Documentation/wpa_supplicant
>
> Luis
>
Luis, thanks for the reply. But actually we're working on mesh nodes
with the iw-tool installed, so maybe we should use the "mesh" interface
mode. In this case, how to solve the problem?
Thanks, zhongliang
^ permalink raw reply
* [RFC] iwlwifi: fix scan abort
From: Stanislaw Gruszka @ 2010-07-28 13:45 UTC (permalink / raw)
To: Wey-Yi Guy, Reinette Chatre, John W. Linville; +Cc: linux-wireless
We can not call cancel_delayed_work_sync(&priv->scan_check) with
priv->mutex locked because workqueue function iwl_bg_scan_check()
take that lock internally.
We do not need to synchronize when canceling priv->scan_check work.
We can avoid races (sending double abort command or send no
command at all) using STATUS_SCAN_ABORT bit. Moreover
current iwl_bg_scan_check() code seems to be broken, as
we should not send abort commands when currently aborting.
I did not test patch yet, just want to know if it is theoretically
correct. Except obvious circular priv->mutex locking fix, maybe it
can help with warning in ieee80211_scan_completed, which is still
reported by the users from time to time.
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 2a7c399..b0c6b04 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -429,11 +429,10 @@ void iwl_bg_scan_check(struct work_struct *data)
return;
mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCANNING, &priv->status) ||
- test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting "
- "adapter (%dms)\n",
- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
+ if (test_bit(STATUS_SCANNING, &priv->status) &&
+ !test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n",
+ jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
iwl_send_scan_abort(priv);
@@ -498,12 +497,11 @@ void iwl_bg_abort_scan(struct work_struct *work)
!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
return;
- mutex_lock(&priv->mutex);
-
- cancel_delayed_work_sync(&priv->scan_check);
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- iwl_send_scan_abort(priv);
+ cancel_delayed_work(&priv->scan_check);
+ mutex_lock(&priv->mutex);
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status))
+ iwl_send_scan_abort(priv);
mutex_unlock(&priv->mutex);
}
EXPORT_SYMBOL(iwl_bg_abort_scan);
^ permalink raw reply related
* Re: [RFC] iwlwifi: fix scan abort
From: Guy, Wey-Yi @ 2010-07-28 14:34 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: Chatre, Reinette, John W. Linville,
linux-wireless@vger.kernel.org
In-Reply-To: <20100728154509.77e8e85b@dhcp-lab-109.englab.brq.redhat.com>
Hi Gruszka,
On Wed, 2010-07-28 at 06:45 -0700, Stanislaw Gruszka wrote:
> We can not call cancel_delayed_work_sync(&priv->scan_check) with
> priv->mutex locked because workqueue function iwl_bg_scan_check()
> take that lock internally.
>
> We do not need to synchronize when canceling priv->scan_check work.
> We can avoid races (sending double abort command or send no
> command at all) using STATUS_SCAN_ABORT bit. Moreover
> current iwl_bg_scan_check() code seems to be broken, as
> we should not send abort commands when currently aborting.
>
> I did not test patch yet, just want to know if it is theoretically
> correct. Except obvious circular priv->mutex locking fix, maybe it
> can help with warning in ieee80211_scan_completed, which is still
> reported by the users from time to time.
>
> diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
> index 2a7c399..b0c6b04 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-scan.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
> @@ -429,11 +429,10 @@ void iwl_bg_scan_check(struct work_struct *data)
> return;
>
> mutex_lock(&priv->mutex);
> - if (test_bit(STATUS_SCANNING, &priv->status) ||
> - test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
> - IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting "
> - "adapter (%dms)\n",
> - jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
> + if (test_bit(STATUS_SCANNING, &priv->status) &&
> + !test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
> + IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n",
> + jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
make sense here, the code is broken, we should not abort scan if already
doing it.
>
> if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
> iwl_send_scan_abort(priv);
> @@ -498,12 +497,11 @@ void iwl_bg_abort_scan(struct work_struct *work)
> !test_bit(STATUS_GEO_CONFIGURED, &priv->status))
> return;
>
> - mutex_lock(&priv->mutex);
> -
> - cancel_delayed_work_sync(&priv->scan_check);
> - set_bit(STATUS_SCAN_ABORTING, &priv->status);
> - iwl_send_scan_abort(priv);
> + cancel_delayed_work(&priv->scan_check);
>
> + mutex_lock(&priv->mutex);
> + if (test_bit(STATUS_SCAN_ABORTING, &priv->status))
> + iwl_send_scan_abort(priv);
> mutex_unlock(&priv->mutex);
> }
Looks right to me, thanks a lot to catch this one.
Wey
^ permalink raw reply
* Re: [WIP] mac80211: AMPDU rx reorder timeout timer
From: Christian Lamparter @ 2010-07-28 15:16 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Felix Fietkau
In-Reply-To: <1280219845.19098.4.camel@jlt3.sipsolutions.net>
On Tuesday 27 July 2010 10:37:25 Johannes Berg wrote:
> On Tue, 2010-07-27 at 08:20 +0200, Christian Lamparter wrote:
> > This (rather _unfinished_ :-D ) patch adds a timer which
> > if trigger schedules the automatic release of all expired
> > A-MPDU frames. This implementation has the advantage that
> > all queued-up MPDU will now arrive in the network core
> > within a timely manner.
> >
> > In my "experiments", the patch helped to ironed out the
> > sudden throughput drops that have been _killing_ my
> > average tcp performance ever since I can remember.
>
> But why is your BA session so damaged to start with? This is not a
> normal situtation!
I can think of at least one possible reason:
commit 3ef83d745bf5220bef3a0fd11b96eb9ac64c8e8e
Author: Felix Fietkau <nbd@openwrt.org>
Date: Tue May 4 09:58:57 2010 +0200
ath9k: fix another source of corrupt frames
Atheros hardware supports receiving frames that span multiple
descriptors and buffers. In this case, the rx status of every
descriptor except for the last one is invalid and may contain random
data. Because the driver does not support this, it needs to drop such
frames.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
and obviously, the HW marked the "last one" in the BA scoreboard
as successfully received. Therefore we don't get a second attempt
because the driver dropped it :(
(The same applies to ar9170, which will print "missing tags!",
or stream corruption in such a case)
> > But there is a catch: The logs will quickly fill up with:
> > "release an RX reorder frame due to timeout on earlier frames".
> > and the package loss will goes through the roof...
> >
> > Now, I can think of several reasons why this could happen:
> > 1. we don't wait long enough for the HT peer to
> > finish their _retry_ procedure?
> >
> > 2. previously - when the stream simply _stopped_ - we had
> > to wait until the tcp retry kick in again. So we had
> > some "silent" periods and therefore less noise from
> > the reordering code?
> >
> > 3. ->bugs<- but where are they?
>
> I'm having a hard time understanding this patch, can you split out the
> no-op code reorg parts or explain what it does?
Sure, just finished clean-up.
Regards,
Chr
^ permalink raw reply
* [WIP 1/3] mac80211: put rx handlers into seperate functions
From: Christian Lamparter @ 2010-07-28 15:17 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1280219845.19098.4.camel@jlt3.sipsolutions.net>
Note: In order to keep diff from removing and re-adding code,
I used forward declarations. So it should be easier to verify
that I didn't change anything related to the reordering logic.
---
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fa0f37e..8179e62 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -574,6 +574,11 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
}
}
+static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
+ struct tid_ampdu_rx *tid_agg_rx,
+ struct sk_buff_head *frames);
+
+
/*
* Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If
* the skb was added to the buffer longer than this time ago, the earlier
@@ -643,6 +648,17 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
tid_agg_rx->reorder_buf[index] = skb;
tid_agg_rx->reorder_time[index] = jiffies;
tid_agg_rx->stored_mpdu_num++;
+ ieee80211_sta_reorder_release(hw, tid_agg_rx, frames);
+
+ return true;
+}
+
+static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
+ struct tid_ampdu_rx *tid_agg_rx,
+ struct sk_buff_head *frames)
+{
+ int index;
+
/* release the buffer until next missing frame */
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
@@ -686,8 +702,6 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
}
-
- return true;
}
/*
@@ -2267,6 +2281,11 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
dev_kfree_skb(skb);
}
+static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
+ ieee80211_rx_result res);
+
+static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
+ struct sk_buff_head *frames);
static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
struct ieee80211_rx_data *rx,
@@ -2288,17 +2307,34 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
goto rxh_next; \
} while (0);
- /*
- * NB: the rxh_next label works even if we jump
- * to it from here because then the list will
- * be empty, which is a trivial check
- */
CALL_RXH(ieee80211_rx_h_passive_scan)
CALL_RXH(ieee80211_rx_h_check)
ieee80211_rx_reorder_ampdu(rx, &reorder_release);
- while ((skb = __skb_dequeue(&reorder_release))) {
+ ieee80211_rx_handlers(rx, &reorder_release);
+ return;
+
+ rxh_next:
+ ieee80211_rx_handlers_result(rx, res);
+
+#undef CALL_RXH
+}
+
+static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
+ struct sk_buff_head *frames)
+{
+ ieee80211_rx_result res = RX_DROP_MONITOR;
+ struct sk_buff *skb;
+
+#define CALL_RXH(rxh) \
+ do { \
+ res = rxh(rx); \
+ if (res != RX_CONTINUE) \
+ goto rxh_next; \
+ } while (0);
+
+ while ((skb = __skb_dequeue(frames))) {
/*
* all the other fields are valid across frames
* that belong to an aMPDU since they are on the
@@ -2316,41 +2352,58 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
CALL_RXH(ieee80211_rx_h_remove_qos_control)
CALL_RXH(ieee80211_rx_h_amsdu)
#ifdef CONFIG_MAC80211_MESH
- if (ieee80211_vif_is_mesh(&sdata->vif))
+ if (ieee80211_vif_is_mesh(&rx->sdata->vif))
CALL_RXH(ieee80211_rx_h_mesh_fwding);
#endif
CALL_RXH(ieee80211_rx_h_data)
/* special treatment -- needs the queue */
- res = ieee80211_rx_h_ctrl(rx, &reorder_release);
+ res = ieee80211_rx_h_ctrl(rx, frames);
if (res != RX_CONTINUE)
goto rxh_next;
CALL_RXH(ieee80211_rx_h_action)
CALL_RXH(ieee80211_rx_h_mgmt)
+ rxh_next:
+ ieee80211_rx_handlers_result(rx, res);
+
#undef CALL_RXH
+ }
+}
- rxh_next:
- switch (res) {
- case RX_DROP_MONITOR:
- I802_DEBUG_INC(sdata->local->rx_handlers_drop);
- if (rx->sta)
- rx->sta->rx_dropped++;
- /* fall through */
- case RX_CONTINUE:
- ieee80211_rx_cooked_monitor(rx, rate);
- break;
- case RX_DROP_UNUSABLE:
- I802_DEBUG_INC(sdata->local->rx_handlers_drop);
- if (rx->sta)
- rx->sta->rx_dropped++;
- dev_kfree_skb(rx->skb);
- break;
- case RX_QUEUED:
- I802_DEBUG_INC(sdata->local->rx_handlers_queued);
- break;
+static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
+ ieee80211_rx_result res)
+{
+ switch (res) {
+ case RX_DROP_MONITOR:
+ I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
+ if (rx->sta)
+ rx->sta->rx_dropped++;
+ /* fall through */
+ case RX_CONTINUE: {
+ struct ieee80211_rate *rate = NULL;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_rx_status *status;
+
+ status = IEEE80211_SKB_RXCB((rx->skb));
+
+ sband = rx->local->hw.wiphy->bands[status->band];
+ if (!(status->flag & RX_FLAG_HT))
+ rate = &sband->bitrates[status->rate_idx];
+
+ ieee80211_rx_cooked_monitor(rx, rate);
+ break;
}
+ case RX_DROP_UNUSABLE:
+ I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
+ if (rx->sta)
+ rx->sta->rx_dropped++;
+ dev_kfree_skb(rx->skb);
+ break;
+ case RX_QUEUED:
+ I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
+ break;
}
}
^ permalink raw reply related
* [WIP 2/3] mac80211: remove (now) unused rate function parameters
From: Christian Lamparter @ 2010-07-28 15:21 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1280219845.19098.4.camel@jlt3.sipsolutions.net>
dead code removal. This can probably go in in one form
or another.
---
additionally: we could drop the extra sdata parameter of
prepare_for_handlers
ieee80211_invoke_rx_handlers
and use the one from the rx_data structure?
---
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8179e62..6cb5541 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -538,20 +538,12 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
int index,
struct sk_buff_head *frames)
{
- struct ieee80211_supported_band *sband;
- struct ieee80211_rate *rate = NULL;
struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
- struct ieee80211_rx_status *status;
if (!skb)
goto no_frame;
- status = IEEE80211_SKB_RXCB(skb);
-
- /* release the reordered frames to stack */
- sband = hw->wiphy->bands[status->band];
- if (!(status->flag & RX_FLAG_HT))
- rate = &sband->bitrates[status->rate_idx];
+ /* release the frame from the reorder ring buffer */
tid_agg_rx->stored_mpdu_num--;
tid_agg_rx->reorder_buf[index] = NULL;
__skb_queue_tail(frames, skb);
@@ -2289,8 +2281,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
struct ieee80211_rx_data *rx,
- struct sk_buff *skb,
- struct ieee80211_rate *rate)
+ struct sk_buff *skb)
{
struct sk_buff_head reorder_release;
ieee80211_rx_result res = RX_DROP_MONITOR;
@@ -2500,8 +2491,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
* be called with rcu_read_lock protection.
*/
static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
- struct sk_buff *skb,
- struct ieee80211_rate *rate)
+ struct sk_buff *skb)
{
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_local *local = hw_to_local(hw);
@@ -2609,7 +2599,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
prev->name);
goto next;
}
- ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
+ ieee80211_invoke_rx_handlers(prev, &rx, skb_new);
next:
prev = sdata;
}
@@ -2625,7 +2615,7 @@ next:
}
}
if (prev)
- ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);
+ ieee80211_invoke_rx_handlers(prev, &rx, skb);
else
dev_kfree_skb(skb);
}
@@ -2711,7 +2701,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
return;
}
- __ieee80211_rx_handle_packet(hw, skb, rate);
+ __ieee80211_rx_handle_packet(hw, skb);
rcu_read_unlock();
^ permalink raw reply related
* [WIP 3/3] mac80211: AMPDU rx reorder timeout timer
From: Christian Lamparter @ 2010-07-28 15:21 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1280219845.19098.4.camel@jlt3.sipsolutions.net>
Everytime a hole is discovered in the reorder ring-buffer,
the release timer (for this tid_ampdu_rx) is set to fire
after HT_RX_REORDER_BUF_TIMEOUT jiffies.
If the missing frame(s) is/are arriving in time, the
timer gets deactivated/postponed(another hole has opened up).
Or, if the frame is really "lost", then the timer puts
the reorder tid_ampdu_rx into the local device's
"tid_rx_reorder" list and schedules the tasklet, which
will look-up the tid_ampdu_rx and release all expired frames.
---
Hmm, I'm not sure if the tasklet code is 100% sane.
On one hand: we set rx.flags and sdata/sta pointers
without the usual rcu-protection.
but on the other hand,it should be OK because the
sta/sdata don't disappear without initiating a teardown.
(or simply poison reorder_head by using list_del)
---
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 965b272..393f4e5 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -86,6 +86,11 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
tid, 0, reason);
del_timer_sync(&tid_rx->session_timer);
+ del_timer_sync(&tid_rx->reorder_timer);
+
+ spin_lock_bh(&local->tid_rx_reorder_lock);
+ list_del_init(&tid_rx->reorder_list);
+ spin_unlock_bh(&local->tid_rx_reorder_lock);
call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx);
}
@@ -120,6 +125,24 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
}
+static void sta_rx_agg_reorder_timer_expired(unsigned long data)
+{
+ u8 *ptid = (u8 *)data;
+ u8 *timer_to_id = ptid - *ptid;
+ struct sta_info *sta = container_of(timer_to_id, struct sta_info,
+ timer_to_tid[0]);
+
+ struct ieee80211_local *local = sta->local;
+ struct tid_ampdu_rx *tid_rx = sta->ampdu_mlme.tid_rx[*ptid];
+
+ spin_lock(&local->tid_rx_reorder_lock);
+ if (list_empty(&tid_rx->reorder_list))
+ list_add_tail(&tid_rx->reorder_list, &local->tid_rx_reorder);
+ spin_unlock(&local->tid_rx_reorder_lock);
+
+ tasklet_schedule(&local->tasklet);
+}
+
static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
u8 dialog_token, u16 status, u16 policy,
u16 buf_size, u16 timeout)
@@ -256,6 +279,12 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];
init_timer(&tid_agg_rx->session_timer);
+ /* rx reorder timer */
+ INIT_LIST_HEAD(&tid_agg_rx->reorder_list);
+ tid_agg_rx->reorder_timer.function = sta_rx_agg_reorder_timer_expired;
+ tid_agg_rx->reorder_timer.data = (unsigned long)&sta->timer_to_tid[tid];
+ init_timer(&tid_agg_rx->reorder_timer);
+
/* prepare reordering buffer */
tid_agg_rx->reorder_buf =
kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ef47006..fd658ef 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -704,6 +704,8 @@ struct ieee80211_local {
struct tasklet_struct tasklet;
struct sk_buff_head skb_queue;
struct sk_buff_head skb_queue_unreliable;
+ spinlock_t tid_rx_reorder_lock;
+ struct list_head tid_rx_reorder;
/* Station data */
/*
@@ -1130,6 +1132,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid);
void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid);
void ieee80211_ba_session_work(struct work_struct *work);
void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid);
+void ieee80211_release_expired_mpdus(struct ieee80211_local *local);
/* Spectrum management */
void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0e95c75..7d8e556 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -281,6 +281,8 @@ static void ieee80211_tasklet_handler(unsigned long data)
break;
}
}
+
+ ieee80211_release_expired_mpdus(local);
}
static void ieee80211_restart_work(struct work_struct *work)
@@ -448,6 +450,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
INIT_LIST_HEAD(&local->interfaces);
+ INIT_LIST_HEAD(&local->tid_rx_reorder);
__hw_addr_init(&local->mc_list);
@@ -457,6 +460,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
mutex_init(&local->key_mtx);
spin_lock_init(&local->filter_lock);
spin_lock_init(&local->queue_stop_reason_lock);
+ spin_lock_init(&local->tid_rx_reorder_lock);
INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6cb5541..e56b5da 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -570,7 +570,6 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
struct tid_ampdu_rx *tid_agg_rx,
struct sk_buff_head *frames);
-
/*
* Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If
* the skb was added to the buffer longer than this time ago, the earlier
@@ -649,7 +648,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
struct tid_ampdu_rx *tid_agg_rx,
struct sk_buff_head *frames)
{
- int index;
+ int index, j;
/* release the buffer until next missing frame */
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
@@ -660,7 +659,6 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
* No buffers ready to be released, but check whether any
* frames in the reorder buffer have timed out.
*/
- int j;
int skipped = 1;
for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
j = (j + 1) % tid_agg_rx->buf_size) {
@@ -670,7 +668,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
}
if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
HT_RX_REORDER_BUF_TIMEOUT))
- break;
+ goto set_release_timer;
#ifdef CONFIG_MAC80211_HT_DEBUG
if (net_ratelimit())
@@ -694,6 +692,26 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
tid_agg_rx->buf_size;
}
+
+ if ((tid_agg_rx->stored_mpdu_num) &&
+ list_empty(&tid_agg_rx->reorder_list)) {
+ j = index = seq_sub(tid_agg_rx->head_seq_num,
+ tid_agg_rx->ssn) % tid_agg_rx->buf_size;
+
+ for (; j != (index - 1) % tid_agg_rx->buf_size;
+ j = (j + 1) % tid_agg_rx->buf_size) {
+ if (tid_agg_rx->reorder_buf[j])
+ break;
+ }
+
+ set_release_timer:
+
+ mod_timer(&tid_agg_rx->reorder_timer, round_jiffies_up(
+ (tid_agg_rx->reorder_time[j] +
+ HT_RX_REORDER_BUF_TIMEOUT) + 1));
+ } else {
+ del_timer(&tid_agg_rx->reorder_timer);
+ }
}
/*
@@ -2398,6 +2416,61 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
}
}
+static void ieee80211_release_reorder_timeout(struct sta_info *sta,
+ unsigned int tid)
+{
+ struct sk_buff_head frames;
+ struct ieee80211_rx_data rx = { };
+
+ __skb_queue_head_init(&frames);
+
+ /* construct rx struct */
+ rx.sta = sta;
+ rx.sdata = sta->sdata;
+ rx.local = sta->local;
+ rx.queue = tid;
+ rx.flags |= IEEE80211_RX_RA_MATCH;
+
+ if (unlikely(test_bit(SCAN_HW_SCANNING, &sta->local->scanning) ||
+ test_bit(SCAN_OFF_CHANNEL, &sta->local->scanning)))
+ rx.flags |= IEEE80211_RX_IN_SCAN;
+
+ ieee80211_sta_reorder_release(&sta->local->hw,
+ sta->ampdu_mlme.tid_rx[tid], &frames);
+
+ /*
+ * key references and virtual interfaces are protected using RCU
+ * and this requires that we are in a read-side RCU section during
+ * receive processing
+ */
+ rcu_read_lock();
+ ieee80211_rx_handlers(&rx, &frames);
+ rcu_read_unlock();
+}
+
+void ieee80211_release_expired_mpdus(struct ieee80211_local *local)
+{
+ struct tid_ampdu_rx *iter;
+ struct sta_info *sta;
+ u8 *ptid, *timer_to_id;
+
+ spin_lock(&local->tid_rx_reorder_lock);
+ while (!list_empty(&local->tid_rx_reorder)) {
+ iter = list_first_entry(&local->tid_rx_reorder,
+ struct tid_ampdu_rx,
+ reorder_list);
+
+ ptid = (u8 *)iter->session_timer.data;
+ timer_to_id = ptid - *ptid;
+ sta = container_of(timer_to_id, struct sta_info,
+ timer_to_tid[0]);
+
+ list_del_init(&iter->reorder_list);
+ ieee80211_release_reorder_timeout(sta, *ptid);
+ }
+ spin_unlock(&local->tid_rx_reorder_lock);
+}
+
/* main receive path */
static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 54262e7..5040c47 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -110,6 +110,7 @@ struct tid_ampdu_tx {
* @timeout: reset timer value (in TUs).
* @dialog_token: dialog token for aggregation session
* @rcu_head: RCU head used for freeing this struct
+ * @reorder_list: used to release expired frames
*
* This structure is protected by RCU and the per-station
* spinlock. Assignments to the array holding it must hold
@@ -121,9 +122,11 @@ struct tid_ampdu_tx {
*/
struct tid_ampdu_rx {
struct rcu_head rcu_head;
+ struct list_head reorder_list;
struct sk_buff **reorder_buf;
unsigned long *reorder_time;
struct timer_list session_timer;
+ struct timer_list reorder_timer;
u16 head_seq_num;
u16 stored_mpdu_num;
u16 ssn;
^ permalink raw reply related
* [PATCH] ath9k: enable serialize_regmode for non-PCIE AR9160
From: John W. Linville @ 2010-07-28 15:15 UTC (permalink / raw)
To: linux-wireless; +Cc: ath9k-devel, John W. Linville
https://bugzilla.kernel.org/show_bug.cgi?id=16476
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
Is there a better (i.e. either more precise or more inclusive) test
to be using here?
drivers/net/wireless/ath/ath9k/hw.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index c33f17d..1041965 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -537,7 +537,8 @@ static int __ath9k_hw_init(struct ath_hw *ah)
if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
- (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
+ ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) &&
+ !ah->is_pciexpress)) {
ah->config.serialize_regmode =
SER_REG_MODE_ON;
} else {
--
1.7.1.1
^ permalink raw reply related
* [PATCH] ath5k: add led_disable module option
From: John W. Linville @ 2010-07-28 16:31 UTC (permalink / raw)
To: linux-wireless; +Cc: ath5k-devel, Bob Copeland, John W. Linville
Not everyone agrees about LED behaviour...give them an escape hatch that
will at least stop the lights from annoying them.
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
drivers/net/wireless/ath/ath5k/led.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index 67aa52e..6c416db 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -43,6 +43,10 @@
#include "ath5k.h"
#include "base.h"
+static int modparam_led_disable;
+module_param_named(led_disable, modparam_led_disable, bool, S_IRUGO);
+MODULE_PARM_DESC(led_disable, "Disable software-controlled LEDs.");
+
#define ATH_SDEVICE(subv,subd) \
.vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
.subvendor = (subv), .subdevice = (subd)
@@ -165,6 +169,9 @@ int ath5k_init_leds(struct ath5k_softc *sc)
char name[ATH5K_LED_MAX_NAME_LEN + 1];
const struct pci_device_id *match;
+ if (modparam_led_disable)
+ goto out;
+
match = pci_match_id(&ath5k_led_devices[0], pdev);
if (match) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
--
1.7.1.1
^ permalink raw reply related
* Re: [PATCH] ath5k: add led_disable module option
From: Bob Copeland @ 2010-07-28 17:10 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, ath5k-devel
In-Reply-To: <1280334711-6141-1-git-send-email-linville@tuxdriver.com>
On Wed, Jul 28, 2010 at 12:31 PM, John W. Linville
<linville@tuxdriver.com> wrote:
> Not everyone agrees about LED behaviour...give them an escape hatch that
> will at least stop the lights from annoying them.
>
> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Fine with me...
--
Bob Copeland %% www.bobcopeland.com
^ permalink raw reply
* Re: [PATCH v4 1/3] cfg80211: Add nl80211 antenna configuration
From: Luis R. Rodriguez @ 2010-07-28 17:24 UTC (permalink / raw)
To: Bruno Randolf; +Cc: Felix Fietkau, johannes, linville, linux-wireless
In-Reply-To: <201007281106.06813.br1@einfach.org>
On Tue, Jul 27, 2010 at 7:06 PM, Bruno Randolf <br1@einfach.org> wrote:
> On Wed July 28 2010 01:47:34 Luis R. Rodriguez wrote:
>> On Tue, Jul 27, 2010 at 9:39 AM, Felix Fietkau <nbd@openwrt.org> wrote:
>> > On 2010-07-27 6:19 PM, Luis R. Rodriguez wrote:
>> >>> + * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for
>> >>> transmitting. + * Each bit represents one antenna, starting with
>> >>> antenna 1 at the first + * bit. If the bitmap is zero (0), the TX
>> >>> antenna follows RX diversity.
>> >>
>> >> What about for 802.11n? What if you want to disable TX?
>> >
>> > Disabling tx shouldn't be handled by the antenna setting, IMHO.
>> >
>> >>> + * If multiple antennas are selected all selected antennas have to
>> >>> be used + * for transmitting (801.11n multiple TX chains).
>> >>
>> >> I rather call this TX / RX chainmask then.
>> >
>> > Well, for legacy hardware, these aren't really chains, as there is only
>> > one rx and one tx path, just with switching onto multiple antennas.
>> >
>> >>> + * Drivers may reject configurations they cannot support.
>> >>> + *
>> >>> + * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for
>> >>> receiving. + * Each bit represents one antenna, starting with
>> >>> antenna 1 at the first + * bit. If multiple antennas are selected
>> >>> in the bitmap, 802.11n devices + * should use multiple RX chains
>> >>> on these antennas, while non-802.11n + * drivers should use
>> >>> antenna diversity between these antennas.
>> >>
>> >> What about TX beamforming, and STBC?
>> >
>> > Disabling one antenna/chain on a two-chain device would naturally
>> > disable TxBF and STBC as well, since it limits the number of available
>> > chains. The driver should simply act as if the disabled chains didn't
>> > exist.
>>
>> That would work.
>>
>> >> Unless 802.11n is completely dealt with I really prefer this patch to
>> >> only address legacy. Otherwise I see sloppyness and inconsistencies on
>> >> supporting this feature throughout different drivers. I'd like to
>> >> avoid that at all costs on nl80211. What you are trying to address is
>> >> legacy antenna setup, not 802.11n RX/TX chainmask dynamic settings so
>> >> I'd really try to avoid it unless you really want to address all
>> >> aspects of chain configuration for 802.11n and even then what I'm
>> >> leading on to say is I think you'll see if you try to address both it
>> >> just gets messy.
>> >
>> > I think 802.11n is already completely dealt with if you treat this as
>> > the chainmask on 11n devices.
>>
>> Its fine by me if the above cases are also embedded into the
>> documentation, just don't want these questions lingering. I can't
>> think of other 802.11n special cases.
>
> thanks felix :)
>
> luis, could you tell me what exactly you would want to include in the
> documentation?
Sure, but after some though I'm sticking to my preference for an API
for this, legacy and 802.11n chainmask / antenna selection should be
dealt with separately.
Reason is I just reviewed the IEEE 802.11 sections 19.19 for TX
beamforming but also happened to stumble upon section 19.20 Antenna
selection. This Antenna Selection section indicates you can support
more antennas than chains and you can use and that the antenna you use
for your chains can vary over time. You select which antenna to use
based on training/sounding tests on each antenna. Antenna selection as
per 19.19 supports up to 8 antennas and up to 4 RF chains. Section
19.20.2 deals with how a STA can initiate antenna selection training
with another STA. Now granted we don't have code for this and I don't
think this is all done explicitly in hardware so one can argue we can
deal with this when/if we do add support for this but this just
highlights how different "antenna selection" or knobs to tune antennas
is even from a standard perspective than legacy. For STBC and TX
beamforming requirements I would like to see mac80211 actually have
code which disables STBC and later TX beamforming (once we have code
for it) if we enable only one chain, I don't see why drivers should
deal with this.
So if you want to define an API I do believe its best to treat these
separately, for legacy I think your API can be fine tuned to consider
FIXED_A, FIXED_B, or DIVERSITY. If you really want some knobs to even
allow for 11n I would recommend debugfs for now which would let you do
anything you want.
Luis
^ permalink raw reply
* Re: [PATCH 2/3] mac80211_hwsim: supress scan conflict message
From: Luis R. Rodriguez @ 2010-07-28 17:31 UTC (permalink / raw)
To: Johannes Berg; +Cc: linville, linux-wireless
In-Reply-To: <1280299929.3832.3.camel@jlt3.sipsolutions.net>
On Tue, Jul 27, 2010 at 11:52 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Tue, 2010-07-27 at 16:33 -0400, Luis R. Rodriguez wrote:
>> Johannes already debugged this and determined it was due
>> to a race condition in mac80211, in order to fix this though
>> we would need to change drivers quite a bit so for now just
>> supress this and we'll correct this on the next kernel release.
>
> This one can stay for all I care since it's not used in practise by
> actual users that get confused :-)
Whatever works.
Luis
^ permalink raw reply
* [PATCH 3/3] ath9k_hw: fix a noise floor calibration related race condition
From: Felix Fietkau @ 2010-07-28 17:45 UTC (permalink / raw)
To: linux-wireless; +Cc: linville, lrodriguez
In-Reply-To: <1280339151-37084-2-git-send-email-nbd@openwrt.org>
On AR5008-AR9002, other forms of calibration must not be started while
the noise floor calibration is running, as this can create invalid
readings which were sometimes not even recoverable by any further
calibration attempts.
This patch also ensures that the result of noise floor measurements
are processed faster and also allows the result of the initial
calibration on reset to make it into the NF history buffer
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/ar9002_calib.c | 32 ++++++++++++++++--------
drivers/net/wireless/ath/ath9k/calib.c | 15 ++++++-----
drivers/net/wireless/ath/ath9k/calib.h | 3 +-
drivers/net/wireless/ath/ath9k/hw.h | 1 +
4 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 4a7bcfa..916cde7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -687,8 +687,13 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
{
bool iscaldone = true;
struct ath9k_cal_list *currCal = ah->cal_list_curr;
+ bool nfcal, nfcal_pending = false;
- if (currCal &&
+ nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
+ if (ah->caldata)
+ nfcal_pending = ah->caldata->nfcal_pending;
+
+ if (currCal && !nfcal &&
(currCal->calState == CAL_RUNNING ||
currCal->calState == CAL_WAITING)) {
iscaldone = ar9002_hw_per_calibration(ah, chan,
@@ -704,7 +709,7 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
}
/* Do NF cal only at longer intervals */
- if (longcal) {
+ if (longcal || nfcal_pending) {
/* Do periodic PAOffset Cal */
ar9002_hw_pa_cal(ah, false);
ar9002_hw_olc_temp_compensation(ah);
@@ -713,16 +718,18 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
* Get the value from the previous NF cal and update
* history buffer.
*/
- ath9k_hw_getnf(ah, chan);
-
- /*
- * Load the NF from history buffer of the current channel.
- * NF is slow time-variant, so it is OK to use a historical
- * value.
- */
- ath9k_hw_loadnf(ah, ah->curchan);
+ if (ath9k_hw_getnf(ah, chan)) {
+ /*
+ * Load the NF from history buffer of the current
+ * channel.
+ * NF is slow time-variant, so it is OK to use a
+ * historical value.
+ */
+ ath9k_hw_loadnf(ah, ah->curchan);
+ }
- ath9k_hw_start_nfcal(ah);
+ if (longcal)
+ ath9k_hw_start_nfcal(ah);
}
return iscaldone;
@@ -873,6 +880,9 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
+ if (ah->caldata)
+ ah->caldata->nfcal_pending = true;
+
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
/* Enable IQ, ADC Gain and ADC DC offset CALs */
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 52460bc..787657b 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -156,6 +156,9 @@ EXPORT_SYMBOL(ath9k_hw_reset_calvalid);
void ath9k_hw_start_nfcal(struct ath_hw *ah)
{
+ if (ah->caldata)
+ ah->caldata->nfcal_pending = true;
+
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_ENABLE_NF);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
@@ -282,8 +285,7 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
}
}
-int16_t ath9k_hw_getnf(struct ath_hw *ah,
- struct ath9k_channel *chan)
+bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
{
struct ath_common *common = ath9k_hw_common(ah);
int16_t nf, nfThresh;
@@ -293,7 +295,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
struct ath9k_hw_cal_data *caldata = ah->caldata;
if (!caldata)
- return ath9k_hw_get_default_nf(ah, chan);
+ return false;
chan->channelFlags &= (~CHANNEL_CW_INT);
if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
@@ -301,7 +303,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
"NF did not complete in calibration window\n");
nf = 0;
caldata->rawNoiseFloor = nf;
- return caldata->rawNoiseFloor;
+ return false;
} else {
ath9k_hw_do_getnf(ah, nfarray);
ath9k_hw_nf_sanitize(ah, nfarray);
@@ -317,11 +319,10 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
}
h = caldata->nfCalHist;
-
+ caldata->nfcal_pending = false;
ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
caldata->rawNoiseFloor = h[0].privNF;
-
- return ah->caldata->rawNoiseFloor;
+ return true;
}
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 09a0ed2..8381e81 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -110,8 +110,7 @@ struct ath9k_pacal_info{
bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
void ath9k_hw_start_nfcal(struct ath_hw *ah);
void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
-int16_t ath9k_hw_getnf(struct ath_hw *ah,
- struct ath9k_channel *chan);
+bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
struct ath9k_channel *chan);
s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index c1b7011..399f7c1 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -354,6 +354,7 @@ struct ath9k_hw_cal_data {
int8_t qCoff;
int16_t rawNoiseFloor;
bool paprd_done;
+ bool nfcal_pending;
u16 small_signal_gain[AR9300_MAX_CHAINS];
u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
--
1.6.4.2
^ permalink raw reply related
* [PATCH 1/3] ath9k: prevent calibration during off-channel activity
From: Felix Fietkau @ 2010-07-28 17:45 UTC (permalink / raw)
To: linux-wireless; +Cc: linville, lrodriguez
Previously the software scan callback was used to indicate to the hardware,
when it was safe to calibrate. This didn't really work properly, because it
depends on a specific order of software scan callbacks vs. channel changes.
Also, software scans are not the only thing that triggers off-channel
activity, so it's better to use the newly added indication from mac80211 for
this and not use the software scan callback for anything calibration related.
This fixes at least some of the invalid noise floor readings that I've seen
in AP mode on AR9160
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 3 +-
drivers/net/wireless/ath/ath9k/main.c | 75 ++++++++++++++++---------------
drivers/net/wireless/ath/ath9k/recv.c | 4 +-
3 files changed, 42 insertions(+), 40 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 998ae2c..9e967b1 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -510,13 +510,12 @@ void ath_deinit_leds(struct ath_softc *sc);
#define SC_OP_BEACONS BIT(1)
#define SC_OP_RXAGGR BIT(2)
#define SC_OP_TXAGGR BIT(3)
-#define SC_OP_FULL_RESET BIT(4)
#define SC_OP_PREAMBLE_SHORT BIT(5)
#define SC_OP_PROTECT_ENABLE BIT(6)
#define SC_OP_RXFLUSH BIT(7)
#define SC_OP_LED_ASSOCIATED BIT(8)
#define SC_OP_LED_ON BIT(9)
-#define SC_OP_SCANNING BIT(10)
+#define SC_OP_OFFCHANNEL BIT(10)
#define SC_OP_TSF_RESET BIT(11)
#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
#define SC_OP_BT_SCAN BIT(13)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 0429dda..c82d8c4 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -154,6 +154,27 @@ void ath9k_ps_restore(struct ath_softc *sc)
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
}
+static void ath_start_ani(struct ath_common *common)
+{
+ struct ath_hw *ah = common->ah;
+ unsigned long timestamp = jiffies_to_msecs(jiffies);
+ struct ath_softc *sc = (struct ath_softc *) common->priv;
+
+ if (!(sc->sc_flags & SC_OP_ANI_RUN))
+ return;
+
+ if (sc->sc_flags & SC_OP_OFFCHANNEL)
+ return;
+
+ common->ani.longcal_timer = timestamp;
+ common->ani.shortcal_timer = timestamp;
+ common->ani.checkani_timer = timestamp;
+
+ mod_timer(&common->ani.timer,
+ jiffies +
+ msecs_to_jiffies((u32)ah->config.ani_poll_interval));
+}
+
/*
* Set/change channels. If the channel is really being changed, it's done
* by reseting the chip. To accomplish this we must first cleanup any pending
@@ -172,6 +193,11 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
if (sc->sc_flags & SC_OP_INVALID)
return -EIO;
+ del_timer_sync(&common->ani.timer);
+ cancel_work_sync(&sc->paprd_work);
+ cancel_work_sync(&sc->hw_check_work);
+ cancel_delayed_work_sync(&sc->tx_complete_work);
+
ath9k_ps_wakeup(sc);
/*
@@ -191,7 +217,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
* to flush data frames already in queue because of
* changing channel. */
- if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
+ if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL))
fastcc = false;
ath_print(common, ATH_DBG_CONFIG,
@@ -212,8 +238,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
}
spin_unlock_bh(&sc->sc_resetlock);
- sc->sc_flags &= ~SC_OP_FULL_RESET;
-
if (ath_startrecv(sc) != 0) {
ath_print(common, ATH_DBG_FATAL,
"Unable to restart recv logic\n");
@@ -225,6 +249,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
ath_update_txpow(sc);
ath9k_hw_set_interrupts(ah, ah->imask);
+ if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) {
+ ath_start_ani(common);
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
+ ath_beacon_config(sc, NULL);
+ }
+
ps_restore:
ath9k_ps_restore(sc);
return r;
@@ -439,8 +469,7 @@ set_timer:
cal_interval = min(cal_interval, (u32)short_cal_interval);
mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) &&
- !(sc->sc_flags & SC_OP_SCANNING)) {
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) {
if (!sc->sc_ah->curchan->paprd_done)
ieee80211_queue_work(sc->hw, &sc->paprd_work);
else
@@ -448,24 +477,6 @@ set_timer:
}
}
-static void ath_start_ani(struct ath_common *common)
-{
- struct ath_hw *ah = common->ah;
- unsigned long timestamp = jiffies_to_msecs(jiffies);
- struct ath_softc *sc = (struct ath_softc *) common->priv;
-
- if (!(sc->sc_flags & SC_OP_ANI_RUN))
- return;
-
- common->ani.longcal_timer = timestamp;
- common->ani.shortcal_timer = timestamp;
- common->ani.checkani_timer = timestamp;
-
- mod_timer(&common->ani.timer,
- jiffies +
- msecs_to_jiffies((u32)ah->config.ani_poll_interval));
-}
-
/*
* Update tx/rx chainmask. For legacy association,
* hard code chainmask to 1x1, for 11n association, use
@@ -477,7 +488,7 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- if ((sc->sc_flags & SC_OP_SCANNING) || is_ht ||
+ if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht ||
(ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
common->tx_chainmask = ah->caps.tx_chainmask;
common->rx_chainmask = ah->caps.rx_chainmask;
@@ -1579,6 +1590,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
aphy->chan_idx = pos;
aphy->chan_is_ht = conf_is_ht(conf);
+ if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+ sc->sc_flags |= SC_OP_OFFCHANNEL;
+ else
+ sc->sc_flags &= ~SC_OP_OFFCHANNEL;
if (aphy->state == ATH_WIPHY_SCAN ||
aphy->state == ATH_WIPHY_ACTIVE)
@@ -1990,7 +2005,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
mutex_lock(&sc->mutex);
if (ath9k_wiphy_scanning(sc)) {
@@ -2007,11 +2021,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
aphy->state = ATH_WIPHY_SCAN;
ath9k_wiphy_pause_all_forced(sc, aphy);
- sc->sc_flags |= SC_OP_SCANNING;
- del_timer_sync(&common->ani.timer);
- cancel_work_sync(&sc->paprd_work);
- cancel_work_sync(&sc->hw_check_work);
- cancel_delayed_work_sync(&sc->tx_complete_work);
mutex_unlock(&sc->mutex);
}
@@ -2023,15 +2032,9 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
mutex_lock(&sc->mutex);
aphy->state = ATH_WIPHY_ACTIVE;
- sc->sc_flags &= ~SC_OP_SCANNING;
- sc->sc_flags |= SC_OP_FULL_RESET;
- ath_start_ani(common);
- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
- ath_beacon_config(sc, NULL);
mutex_unlock(&sc->mutex);
}
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index da0cfe9..4125ca2 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -292,7 +292,7 @@ static void ath_edma_start_recv(struct ath_softc *sc)
ath_opmode_init(sc);
- ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING));
+ ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
}
static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -498,7 +498,7 @@ int ath_startrecv(struct ath_softc *sc)
start_recv:
spin_unlock_bh(&sc->rx.rxbuflock);
ath_opmode_init(sc);
- ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING));
+ ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
return 0;
}
--
1.6.4.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox