Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH] ath9k_htc: keep calibrated noise floor value for oper channel
From: Rajkumar Manoharan @ 2011-01-14 20:03 UTC (permalink / raw)
  To: linux-wireless; +Cc: Rajkumar Manoharan

The ath9k_hw assumes that caldata is valid only for
oper channel. But with ath9k_htc case, the caldata is
passed for all channels on hw_reset though we are not doing
calibration on that channel. So the oper channel's nf history
got cleared to default due to mismatch in channel flags.
This patch also saves some space.

Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com>
---
 drivers/net/wireless/ath/ath9k/htc.h          |    2 +-
 drivers/net/wireless/ath/ath9k/htc_drv_main.c |    7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 1ce506f..c976600 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -366,7 +366,7 @@ struct ath9k_htc_priv {
 	u16 seq_no;
 	u32 bmiss_cnt;
 
-	struct ath9k_hw_cal_data caldata[ATH9K_NUM_CHANNELS];
+	struct ath9k_hw_cal_data caldata;
 
 	spinlock_t beacon_lock;
 
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index f4d576b..187af5b 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -121,7 +121,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
 	struct ath_hw *ah = priv->ah;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ieee80211_channel *channel = priv->hw->conf.channel;
-	struct ath9k_hw_cal_data *caldata;
+	struct ath9k_hw_cal_data *caldata = NULL;
 	enum htc_phymode mode;
 	__be16 htc_mode;
 	u8 cmd_rsp;
@@ -139,7 +139,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
 	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
 	WMI_CMD(WMI_STOP_RECV_CMDID);
 
-	caldata = &priv->caldata[channel->hw_value];
+	caldata = &priv->caldata;
 	ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
 	if (ret) {
 		ath_err(common,
@@ -202,7 +202,8 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
 		channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
 		fastcc);
 
-	caldata = &priv->caldata[channel->hw_value];
+	if (!fastcc)
+		caldata = &priv->caldata;
 	ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
 	if (ret) {
 		ath_err(common,
-- 
1.7.3.5


^ permalink raw reply related

* Re: [PATCH] ath9k: preserve caldata history buffer across scanning
From: Felix Fietkau @ 2011-01-14 19:38 UTC (permalink / raw)
  To: Rajkumar Manoharan; +Cc: linux-wireless
In-Reply-To: <1295033482-12257-1-git-send-email-rmanoharan@atheros.com>

On 2011-01-14 8:31 PM, Rajkumar Manoharan wrote:
> caldata's channel info is never filled with operating channel
> info which is causing the operating channel's noise floor
> history buffer is reset to default nf during channel change.
>
> Signed-off-by: Rajkumar Manoharan<rmanoharan@atheros.com>
Acked-by: Felix Fietkau <nbd@openwrt.org>

^ permalink raw reply

* [PATCH] mwifiex: remove duplicated NULL checks
From: Bing Zhao @ 2011-01-14 19:36 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Johannes Berg, Amitkumar Karwar, Kiran Divekar,
	Frank Huang, Bing Zhao

From: Amitkumar Karwar <akarwar@marvell.com>

Some functions have unnecessory NULL check for an input parameter
because the caller to those functions is already checking the parameter
for NULL before calling them.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
 drivers/net/wireless/mwifiex/cmdevt.c    |   25 -------------------------
 drivers/net/wireless/mwifiex/scan.c      |    5 +----
 drivers/net/wireless/mwifiex/sta_ioctl.c |    6 ------
 drivers/net/wireless/mwifiex/util.c      |    2 --
 4 files changed, 1 insertions(+), 37 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 60aeea4..5c512d5 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -41,11 +41,6 @@ mwifiex_init_cmd_node(struct mwifiex_private *priv,
 {
 	ENTER();
 
-	if (cmd_node == NULL) {
-		LEAVE();
-		return;
-	}
-
 	cmd_node->priv = priv;
 	cmd_node->cmd_oid = cmd_oid;
 	cmd_node->ioctl_buf = ioctl_buf;
@@ -74,11 +69,6 @@ mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
 
 	ENTER();
 
-	if (adapter == NULL) {
-		LEAVE();
-		return NULL;
-	}
-
 	spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
 	if (list_empty(&adapter->cmd_free_q)) {
 		PRINTM(MERROR,
@@ -112,10 +102,6 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
 {
 	ENTER();
 
-	if (cmd_node == NULL) {
-		LEAVE();
-		return;
-	}
 	cmd_node->cmd_oid = 0;
 	cmd_node->cmd_flag = 0;
 	cmd_node->ioctl_buf = NULL;
@@ -720,11 +706,6 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
 
 	ENTER();
 
-	if (cmd_node == NULL) {
-		PRINTM(MERROR, "QUEUE_CMD: cmd_node is NULL\n");
-		goto done;
-	}
-
 	host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_buf->buffer +
 					       cmd_node->cmd_buf->data_offset);
 	if (host_cmd == NULL) {
@@ -782,12 +763,6 @@ mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
 
 	ENTER();
 
-	/* Sanity test */
-	if (adapter == NULL) {
-		PRINTM(MERROR, "EXEC_NEXT_CMD: adapter is NULL\n");
-		ret = MWIFIEX_STATUS_FAILURE;
-		goto done;
-	}
 	/* Check if already in processing */
 	if (adapter->curr_cmd) {
 		PRINTM(MERROR,
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index df4a77c..6da0612 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -3162,13 +3162,10 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
 
 	ENTER();
 
-	if (cmd_node == NULL)
-		goto done;
-
 	spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
 	list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
 	spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
-done:
+
 	LEAVE();
 }
 
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 04a6154..f4fcb74 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -42,12 +42,6 @@ mwifiex_ioctl(struct mwifiex_adapter *adapter,
 
 	ENTER();
 
-	if (ioctl_req == NULL) {
-		PRINTM(MERROR, "%s: IOCTL request buffer is NULL\n", __func__);
-		ret = MWIFIEX_STATUS_FAILURE;
-		goto exit;
-	}
-
 	if (ioctl_req->action == MWIFIEX_ACT_CANCEL) {
 		mwifiex_cancel_pending_ioctl(adapter, ioctl_req);
 		ret = MWIFIEX_STATUS_SUCCESS;
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 7e1bc9b..c16f5f5 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -546,8 +546,6 @@ mwifiex_process_ioctl_resp(struct mwifiex_private *priv,
 {
 	ENTER();
 
-	if (priv == NULL)
-		return;
 	switch (req->req_id) {
 	case MWIFIEX_IOCTL_GET_INFO:
 		mwifiex_ioctl_get_info_resp(priv,
-- 
1.7.0.2


^ permalink raw reply related

* Re: [RFC] ath9k: Handle interface changes properly
From: Felix Fietkau @ 2011-01-14 19:34 UTC (permalink / raw)
  To: Ben Greear
  Cc: Rajkumar Manoharan, Rajkumar Manoharan, Björn Smedman,
	linux-wireless@vger.kernel.org
In-Reply-To: <4D30A3FC.7040609@candelatech.com>

On 2011-01-14 8:29 PM, Ben Greear wrote:
> On 01/14/2011 11:24 AM, Rajkumar Manoharan wrote:
>>  On Sat, Jan 15, 2011 at 12:36:42AM +0530, Felix Fietkau wrote:
>>>  On 2011-01-14 7:53 PM, Rajkumar Manoharan wrote:
>>>>  On Fri, Jan 14, 2011 at 11:52:02PM +0530, Felix Fietkau wrote:
>>>>>    On 2011-01-14 7:13 PM, Rajkumar Manoharan wrote:
>>>>>    >    On Thu, Jan 13, 2011 at 10:19:38PM +0530, Felix Fietkau wrote:
>>>>>    >>     On 2011-01-13 5:35 PM, Rajkumar Manoharan wrote:
>>>>>    >>     >     Instead of setting opmde as AP for WDS, it is better to handle WDS
>>>>>    >>     >     case in ath9k_hw.
>>>>>    >>     Why? Right now I don't even see any NL80211_IFTYPE_WDS handling in
>>>>>    >>     ath9k_hw, and I can't think of anything that should be handled
>>>>>    >>     differently in ath9k_hw compared to the AP opmode.
>>>>>    >    For WDS station, what should be the interface type? Forgive if I'm wrong.
>>>>>    There is no WDS station opmode. 'WDS station' is a regular station
>>>>>    interface with 4-addr mode enabled. It needs no special handling in ath9k.
>>>>  still not convinced. Then what is the point mac80211 is informing about
>>>>  WDS type to drivers. mac itself can pass it as AP type like what it
>>>>  is doing for p2p GO.
>>>  The WDS type is something else. If you have two APs, you can link them
>>>  together with a separate WDS vif on each side pointing at the remote MAC
>>>  address of the other node.
>>>  I think that when we use ah->opmode, we should only use it for very
>>>  generic operating modes:
>>>
>>>  AP: no TSF sync, beacon tx can be enabled.
>>>  ADHOC: TSF sync against IBSS cell, beacon tx can be enabled
>>>  STATION: TSF sync against one AP, only station beacon timers for PS.
>>>
>>>  Only the above distinctions are relevant for ath9k_hw, everything else
>>>  is handled by the driver/stack. There is no reason for adding extra
>>>  checks to ath9k_hw for mesh and WDS, since they work best with
>>>  ah->opmode set to AP, and there is nothing extra on the *hardware* side
>>>  that should be configured there via a different opmode. That's why I
>>>  think leaking the mac80211 interface types to ath9k_hw is a bad idea.
>>  Thanks for your detailed explanation. And meanwhile Ben is also
>>  fixing hw mode based on vif counter. It would be better if he make
>>  use this thread and address the same.
>>
>>  Ben,
>>  Any comments.
>
> If all I need to do is to treat WDS and MESH like an AP, that shouldn't
> be too hard.
>
> Does WDS need a beacon?
No

> Is there any limitations to the number of WDS vifs allowed, including
> combinations with other VIF types?
I don't think so.

- Felix

^ permalink raw reply

* [PATCH] ath9k: preserve caldata history buffer across scanning
From: Rajkumar Manoharan @ 2011-01-14 19:31 UTC (permalink / raw)
  To: linux-wireless; +Cc: Rajkumar Manoharan

caldata's channel info is never filled with operating channel
info which is causing the operating channel's noise floor
history buffer is reset to default nf during channel change.

Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com>
---
 drivers/net/wireless/ath/ath9k/calib.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index b68a1ac..b4a92a4 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -382,9 +382,8 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
 	s16 default_nf;
 	int i, j;
 
-	if (!ah->caldata)
-		return;
-
+	ah->caldata->channel = chan->channel;
+	ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT;
 	h = ah->caldata->nfCalHist;
 	default_nf = ath9k_hw_get_default_nf(ah, chan);
 	for (i = 0; i < NUM_NF_READINGS; i++) {
-- 
1.7.3.5


^ permalink raw reply related

* Re: [RFC] ath9k: Handle interface changes properly
From: Ben Greear @ 2011-01-14 19:29 UTC (permalink / raw)
  To: Rajkumar Manoharan
  Cc: Felix Fietkau, Rajkumar Manoharan, Björn Smedman,
	linux-wireless@vger.kernel.org
In-Reply-To: <20110114192414.GA12090@vmraj-lnx.users.atheros.com>

On 01/14/2011 11:24 AM, Rajkumar Manoharan wrote:
> On Sat, Jan 15, 2011 at 12:36:42AM +0530, Felix Fietkau wrote:
>> On 2011-01-14 7:53 PM, Rajkumar Manoharan wrote:
>>> On Fri, Jan 14, 2011 at 11:52:02PM +0530, Felix Fietkau wrote:
>>>>   On 2011-01-14 7:13 PM, Rajkumar Manoharan wrote:
>>>>   >   On Thu, Jan 13, 2011 at 10:19:38PM +0530, Felix Fietkau wrote:
>>>>   >>    On 2011-01-13 5:35 PM, Rajkumar Manoharan wrote:
>>>>   >>    >    Instead of setting opmde as AP for WDS, it is better to handle WDS
>>>>   >>    >    case in ath9k_hw.
>>>>   >>    Why? Right now I don't even see any NL80211_IFTYPE_WDS handling in
>>>>   >>    ath9k_hw, and I can't think of anything that should be handled
>>>>   >>    differently in ath9k_hw compared to the AP opmode.
>>>>   >   For WDS station, what should be the interface type? Forgive if I'm wrong.
>>>>   There is no WDS station opmode. 'WDS station' is a regular station
>>>>   interface with 4-addr mode enabled. It needs no special handling in ath9k.
>>> still not convinced. Then what is the point mac80211 is informing about
>>> WDS type to drivers. mac itself can pass it as AP type like what it
>>> is doing for p2p GO.
>> The WDS type is something else. If you have two APs, you can link them
>> together with a separate WDS vif on each side pointing at the remote MAC
>> address of the other node.
>> I think that when we use ah->opmode, we should only use it for very
>> generic operating modes:
>>
>> AP: no TSF sync, beacon tx can be enabled.
>> ADHOC: TSF sync against IBSS cell, beacon tx can be enabled
>> STATION: TSF sync against one AP, only station beacon timers for PS.
>>
>> Only the above distinctions are relevant for ath9k_hw, everything else
>> is handled by the driver/stack. There is no reason for adding extra
>> checks to ath9k_hw for mesh and WDS, since they work best with
>> ah->opmode set to AP, and there is nothing extra on the *hardware* side
>> that should be configured there via a different opmode. That's why I
>> think leaking the mac80211 interface types to ath9k_hw is a bad idea.
> Thanks for your detailed explanation. And meanwhile Ben is also
> fixing hw mode based on vif counter. It would be better if he make
> use this thread and address the same.
>
> Ben,
> Any comments.

If all I need to do is to treat WDS and MESH like an AP, that shouldn't
be too hard.

Does WDS need a beacon?

Is there any limitations to the number of WDS vifs allowed, including
combinations with other VIF types?

Thanks,
Ben

>
> --
> Rajkumar


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply

* Re: [RFC] ath9k: Handle interface changes properly
From: Rajkumar Manoharan @ 2011-01-14 19:24 UTC (permalink / raw)
  To: Felix Fietkau, greearb
  Cc: Rajkumar Manoharan, Björn Smedman,
	linux-wireless@vger.kernel.org
In-Reply-To: <4D309EC2.2060409@openwrt.org>

On Sat, Jan 15, 2011 at 12:36:42AM +0530, Felix Fietkau wrote:
> On 2011-01-14 7:53 PM, Rajkumar Manoharan wrote:
> > On Fri, Jan 14, 2011 at 11:52:02PM +0530, Felix Fietkau wrote:
> >>  On 2011-01-14 7:13 PM, Rajkumar Manoharan wrote:
> >>  >  On Thu, Jan 13, 2011 at 10:19:38PM +0530, Felix Fietkau wrote:
> >>  >>   On 2011-01-13 5:35 PM, Rajkumar Manoharan wrote:
> >>  >>   >   Instead of setting opmde as AP for WDS, it is better to handle WDS
> >>  >>   >   case in ath9k_hw.
> >>  >>   Why? Right now I don't even see any NL80211_IFTYPE_WDS handling in
> >>  >>   ath9k_hw, and I can't think of anything that should be handled
> >>  >>   differently in ath9k_hw compared to the AP opmode.
> >>  >  For WDS station, what should be the interface type? Forgive if I'm wrong.
> >>  There is no WDS station opmode. 'WDS station' is a regular station
> >>  interface with 4-addr mode enabled. It needs no special handling in ath9k.
> > still not convinced. Then what is the point mac80211 is informing about
> > WDS type to drivers. mac itself can pass it as AP type like what it
> > is doing for p2p GO.
> The WDS type is something else. If you have two APs, you can link them 
> together with a separate WDS vif on each side pointing at the remote MAC 
> address of the other node.
> I think that when we use ah->opmode, we should only use it for very 
> generic operating modes:
> 
> AP: no TSF sync, beacon tx can be enabled.
> ADHOC: TSF sync against IBSS cell, beacon tx can be enabled
> STATION: TSF sync against one AP, only station beacon timers for PS.
> 
> Only the above distinctions are relevant for ath9k_hw, everything else 
> is handled by the driver/stack. There is no reason for adding extra 
> checks to ath9k_hw for mesh and WDS, since they work best with 
> ah->opmode set to AP, and there is nothing extra on the *hardware* side 
> that should be configured there via a different opmode. That's why I 
> think leaking the mac80211 interface types to ath9k_hw is a bad idea.
Thanks for your detailed explanation. And meanwhile Ben is also
fixing hw mode based on vif counter. It would be better if he make
use this thread and address the same.

Ben,
Any comments.

--
Rajkumar

^ permalink raw reply

* Re: [RFC 1/2] ath9k:  Fix up hardware mode and beacons with multiple vifs.
From: Ben Greear @ 2011-01-14 19:12 UTC (permalink / raw)
  To: sbrown; +Cc: linux-wireless, ath9k-devel
In-Reply-To: <1295031482.3703.16.camel@mythtv.ewol.com>

On 01/14/2011 10:58 AM, Steve Brown wrote:
> On Fri, 2011-01-14 at 09:27 -0800, greearb@candelatech.com wrote:
>> From: Ben Greear<greearb@candelatech.com>
>>
>> When using a mixture of AP and Station interfaces,
>> the hardware mode was using the type of the
>> last VIF registered.  Instead, we should keep track
>> of the number of different types of vifs and set the
>> mode accordingly.
>>
>> In addtion, use the vif type instead of hardware opmode
>> when dealing with beacons.
>>
>> Attempt to move some of the common setup code into smaller
>> methods so we can re-use it when changing vif mode as
>> well as adding/deleting vifs.
>>
>> This needs review.
>>
>> Signed-off-by: Ben Greear<greearb@candelatech.com>
>> ---
>> :100644 100644 3108699... a2da259... M	drivers/net/wireless/ath/ath9k/ath9k.h
>> :100644 100644 385ba03... 8de591e... M	drivers/net/wireless/ath/ath9k/beacon.c
>> :100644 100644 0452580... 1a65e53... M	drivers/net/wireless/ath/ath9k/main.c
>> :100644 100644 ea2f67c... 9a2b4a8... M	drivers/net/wireless/ath/ath9k/recv.c
>>   drivers/net/wireless/ath/ath9k/ath9k.h  |   10 +-
>>   drivers/net/wireless/ath/ath9k/beacon.c |   14 +-
>>   drivers/net/wireless/ath/ath9k/main.c   |  263 ++++++++++++++++++++++---------
>>   drivers/net/wireless/ath/ath9k/recv.c   |   17 ++-
>>   4 files changed, 214 insertions(+), 90 deletions(-)
>>
>
> It would be really useful to have both an AP and MESH vif. With the mesh
> and ap vif's bridged, a station connected to the ap could ping outside
> the mesh. Currently, if you add the mesh vif and then the ap vif, it
> sort of works. The other way around, the mesh interval value causes
> beacons to be sent only for the vif associated with slot 0.
>
> Is it possible to consider this case as you overhaul ath9k beaconing?

Perhaps someone else would be better.  I have no way to test mesh
right now, and still do not understand this code too well.

Hopefully the vif-counting work would help with dealing with
your scenario, however...

Also, could you try with my patch(es)?  Part of the problem with the old
code is that if you added mesh second, you would not be in AP mode anymore.
I think that part will be fixed now.  There may be other issues remaining,
however.

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply

* Re: [RFC] ath9k: Handle interface changes properly
From: Felix Fietkau @ 2011-01-14 19:06 UTC (permalink / raw)
  To: Rajkumar Manoharan; +Cc: Björn Smedman, linux-wireless@vger.kernel.org
In-Reply-To: <20110114185317.GA12051@vmraj-lnx.users.atheros.com>

On 2011-01-14 7:53 PM, Rajkumar Manoharan wrote:
> On Fri, Jan 14, 2011 at 11:52:02PM +0530, Felix Fietkau wrote:
>>  On 2011-01-14 7:13 PM, Rajkumar Manoharan wrote:
>>  >  On Thu, Jan 13, 2011 at 10:19:38PM +0530, Felix Fietkau wrote:
>>  >>   On 2011-01-13 5:35 PM, Rajkumar Manoharan wrote:
>>  >>   >   Instead of setting opmde as AP for WDS, it is better to handle WDS
>>  >>   >   case in ath9k_hw.
>>  >>   Why? Right now I don't even see any NL80211_IFTYPE_WDS handling in
>>  >>   ath9k_hw, and I can't think of anything that should be handled
>>  >>   differently in ath9k_hw compared to the AP opmode.
>>  >  For WDS station, what should be the interface type? Forgive if I'm wrong.
>>  There is no WDS station opmode. 'WDS station' is a regular station
>>  interface with 4-addr mode enabled. It needs no special handling in ath9k.
> still not convinced. Then what is the point mac80211 is informing about
> WDS type to drivers. mac itself can pass it as AP type like what it
> is doing for p2p GO.
The WDS type is something else. If you have two APs, you can link them 
together with a separate WDS vif on each side pointing at the remote MAC 
address of the other node.
I think that when we use ah->opmode, we should only use it for very 
generic operating modes:

AP: no TSF sync, beacon tx can be enabled.
ADHOC: TSF sync against IBSS cell, beacon tx can be enabled
STATION: TSF sync against one AP, only station beacon timers for PS.

Only the above distinctions are relevant for ath9k_hw, everything else 
is handled by the driver/stack. There is no reason for adding extra 
checks to ath9k_hw for mesh and WDS, since they work best with 
ah->opmode set to AP, and there is nothing extra on the *hardware* side 
that should be configured there via a different opmode. That's why I 
think leaking the mac80211 interface types to ath9k_hw is a bad idea.

- Felix

^ permalink raw reply

* Re: [RFC 1/2] ath9k:  Fix up hardware mode and beacons with multiple vifs.
From: Steve Brown @ 2011-01-14 18:58 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless, ath9k-devel
In-Reply-To: <1295026029-21130-1-git-send-email-greearb@candelatech.com>

On Fri, 2011-01-14 at 09:27 -0800, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> When using a mixture of AP and Station interfaces,
> the hardware mode was using the type of the
> last VIF registered.  Instead, we should keep track
> of the number of different types of vifs and set the
> mode accordingly.
> 
> In addtion, use the vif type instead of hardware opmode
> when dealing with beacons.
> 
> Attempt to move some of the common setup code into smaller
> methods so we can re-use it when changing vif mode as
> well as adding/deleting vifs.
> 
> This needs review.
> 
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> :100644 100644 3108699... a2da259... M	drivers/net/wireless/ath/ath9k/ath9k.h
> :100644 100644 385ba03... 8de591e... M	drivers/net/wireless/ath/ath9k/beacon.c
> :100644 100644 0452580... 1a65e53... M	drivers/net/wireless/ath/ath9k/main.c
> :100644 100644 ea2f67c... 9a2b4a8... M	drivers/net/wireless/ath/ath9k/recv.c
>  drivers/net/wireless/ath/ath9k/ath9k.h  |   10 +-
>  drivers/net/wireless/ath/ath9k/beacon.c |   14 +-
>  drivers/net/wireless/ath/ath9k/main.c   |  263 ++++++++++++++++++++++---------
>  drivers/net/wireless/ath/ath9k/recv.c   |   17 ++-
>  4 files changed, 214 insertions(+), 90 deletions(-)
> 

It would be really useful to have both an AP and MESH vif. With the mesh
and ap vif's bridged, a station connected to the ap could ping outside
the mesh. Currently, if you add the mesh vif and then the ap vif, it
sort of works. The other way around, the mesh interval value causes
beacons to be sent only for the vif associated with slot 0.

Is it possible to consider this case as you overhaul ath9k beaconing?

Steve



^ permalink raw reply

* intermittent eap authentication failure
From: Chuck Crisler @ 2011-01-14 18:51 UTC (permalink / raw)
  To: linux-wireless

I am running wpa_supplicant v. 0.6.10. I am having a problem remaining on a 
network with PEEP authentication. I can initially get on the network but 
then fail with the first session timeout sent by the AP. Sometimes if the 
ESS is hidden I will have a subsequent probe request fail, causing me to 
re-start the entire process, which will then succeed, only to fail with the 
next session timeout.

Sometime ago I found a conflict between the supplicant and the MAC80211 code 
dealing with Cisco session timeouts. When we were 'deauthenticated', the MAC 
code notified the supplicant AND re-associated with the AP. When the driver 
got the association response, it then notified the supplicant, which was in 
the process of running a scan, which had often already been sent to the 
driver, causing a mess. We modified the driver so that if it received a 
de-auth with reason code 1 (undefined?), it would *NOT* notify the 
supplicant but would re-associate, then notify the supplicant of the new 
association. We modified the supplicant so that when it was in the completed 
state and received an association event, it went through the disassociation 
sequence of calls, then proceeded with whatever was remaining for the 
authentication. Later we determined that we could receive the deauth with a 
reason code = 4 also, so that was added.
Specifically, this is what we do with a COMPLETED->ASSOCIATED transition in 
wpa_supplicant_event_assoc in events.c:

wpa_clear_keys(wpa_s, wpa_s->bssid);
eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
    eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
wpa_sm_set_config(wpa_s->eapol, NULL, NULL);
wpa_s->new_connection = 1;

This works fine with WPA/WPA2, but seems to fail with PEEP and (I guess) the 
other EAP methods. I don't know EAP well enough yet to understand why this 
is failing or what I need to do to make WPA/WPA2 and EAP all work. Would 
someone please shed some light on this for me?

Thank you,
Chuck Crisler 


^ permalink raw reply

* Re: [RFC] ath9k: Handle interface changes properly
From: Rajkumar Manoharan @ 2011-01-14 18:53 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: Rajkumar Manoharan, Björn Smedman,
	linux-wireless@vger.kernel.org
In-Reply-To: <4D30944A.30100@openwrt.org>

On Fri, Jan 14, 2011 at 11:52:02PM +0530, Felix Fietkau wrote:
> On 2011-01-14 7:13 PM, Rajkumar Manoharan wrote:
> > On Thu, Jan 13, 2011 at 10:19:38PM +0530, Felix Fietkau wrote:
> >>  On 2011-01-13 5:35 PM, Rajkumar Manoharan wrote:
> >>  >  Instead of setting opmde as AP for WDS, it is better to handle WDS
> >>  >  case in ath9k_hw.
> >>  Why? Right now I don't even see any NL80211_IFTYPE_WDS handling in
> >>  ath9k_hw, and I can't think of anything that should be handled
> >>  differently in ath9k_hw compared to the AP opmode.
> > For WDS station, what should be the interface type? Forgive if I'm wrong.
> There is no WDS station opmode. 'WDS station' is a regular station 
> interface with 4-addr mode enabled. It needs no special handling in ath9k.
still not convinced. Then what is the point mac80211 is informing about
WDS type to drivers. mac itself can pass it as AP type like what it 
is doing for p2p GO.

--
Rajkumar

^ permalink raw reply

* Re: ath9k  - cannot reconnect few meters from the antenna
From: Rajkumar Manoharan @ 2011-01-14 18:23 UTC (permalink / raw)
  To: Tomasz; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <loom.20110113T233025-142@post.gmane.org>

On Fri, Jan 14, 2011 at 04:16:37AM +0530, Tomasz wrote:
> Hi All
> I've spend a lot of time on this issue and I cannot fix it, thus I am asking for
> help
> It looks like that:
> 
> I am running wireless access point based on:
> Ubuntu 10.04  vmlinuz-2.6.32-27-generic
> compat-wireless-2010-12-26
> hostapd 0.7.3 (wpa/wpa2)
> Dnsmasq version 2.52
> Zotac Ion board
> Minipcie card: ieee80211 phy0: Atheros AR9285 Rev:2
> ath9k driver
> Single antenna (but the behaviour with two antenna is similar)
> 
> Everything works perfectly fine when I am within the few meters from the antenna.
> So the clients are connecting and I get 25 mbps data rates.
> But if more then 10 meters from the antenna strange things are happening.
> - If I am connected to the network and will walk away everything works perfect.
> - But if i disconnect (disassociate) when I am away I cannot connect back. -
> this also means I cannot connect when turning the notebook on :)
> - if I go closer to antenna I am able to connect and while walking away the
> connection seems perfectly stable ...
Hi Tomasz,

Do you have any interference with the oper channel? Please enable debug option
CONFIG_ATH_DEBUG=y in config.mk and modprobe ath9k debug=0x701 and
post dmesg/kern.log 

--
Rajkumar

^ permalink raw reply

* Re: [RFC] ath9k: Handle interface changes properly
From: Felix Fietkau @ 2011-01-14 18:22 UTC (permalink / raw)
  To: Rajkumar Manoharan; +Cc: Björn Smedman, linux-wireless@vger.kernel.org
In-Reply-To: <20110114181309.GA11920@vmraj-lnx.users.atheros.com>

On 2011-01-14 7:13 PM, Rajkumar Manoharan wrote:
> On Thu, Jan 13, 2011 at 10:19:38PM +0530, Felix Fietkau wrote:
>>  On 2011-01-13 5:35 PM, Rajkumar Manoharan wrote:
>>  >  Instead of setting opmde as AP for WDS, it is better to handle WDS
>>  >  case in ath9k_hw.
>>  Why? Right now I don't even see any NL80211_IFTYPE_WDS handling in
>>  ath9k_hw, and I can't think of anything that should be handled
>>  differently in ath9k_hw compared to the AP opmode.
> For WDS station, what should be the interface type? Forgive if I'm wrong.
There is no WDS station opmode. 'WDS station' is a regular station 
interface with 4-addr mode enabled. It needs no special handling in ath9k.

- Felix

^ permalink raw reply

* Re: [ath9k-devel] [RFC 1/2] ath9k: Fix up hardware mode and beacons with multiple vifs.
From: Ben Greear @ 2011-01-14 18:16 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, ath9k-devel
In-Reply-To: <4D309086.7070703@openwrt.org>

On 01/14/2011 10:05 AM, Felix Fietkau wrote:
> On 2011-01-14 6:27 PM, greearb@candelatech.com wrote:

>> diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h
>> b/drivers/net/wireless/ath/ath9k/ath9k.h
>> index 3108699..a2da259 100644
>> --- a/drivers/net/wireless/ath/ath9k/ath9k.h
>> +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
>> @@ -607,10 +607,15 @@ struct ath_softc {
>> u32 sc_flags; /* SC_OP_* */
>> u16 ps_flags; /* PS_* */
>> u16 curtxpow;
>> - u8 nbcnvifs;
>> - u16 nvifs;
>> bool ps_enabled;
>> bool ps_idle;
>> + short nbcnvifs;
>> + short nvifs;
>> + short naps; /* number of APs */
>> + short nmeshes;
>> + short nstations;
>> + short nwds;
>> + short nadhocs;
>> unsigned long ps_usecount;
>>
>> struct ath_config config;
> Do we really need all those counters? Wouldn't it be better to iterate
> over active interfaces instead?

Well, I like the counters.  If they ever do not match
expected results, it will be a clue that we have bugs
in our setup/teardown/change logic.

Seems we use counters like this for ath5k with good
results, btw.

>> if (!ieee80211_is_beacon(fc) ||
>> - compare_ether_addr(hdr->addr3, common->curbssid))
>> + compare_ether_addr(hdr->addr3, common->curbssid)) {
>> + /* TODO: This doesn't work well if you have stations
>> + * associated to two different APs because curbssid
>> + * is just the last AP that any of the stations associated
>> + * with.
>> + */
>> return;
>> + }
>>
>> if (rx_stats->rs_rssi != ATH9K_RSSI_BAD&& !rx_stats->rs_moreaggr)
>> ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi);
> Checking for the STA opmode is correct, this code should not be used for
> STA+AP. For the multi-STA case, it may make sense to process the RSSI
> average per vif and using the minimum for ANI.

Ok.  I'll leave that alone for now.

Thanks,
Ben


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply

* Re: [RFC] ath9k: Handle interface changes properly
From: Rajkumar Manoharan @ 2011-01-14 18:13 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: Rajkumar Manoharan, Björn Smedman,
	linux-wireless@vger.kernel.org
In-Reply-To: <4D2F2D22.6070301@openwrt.org>

On Thu, Jan 13, 2011 at 10:19:38PM +0530, Felix Fietkau wrote:
> On 2011-01-13 5:35 PM, Rajkumar Manoharan wrote:
> > On Thu, Jan 13, 2011 at 07:53:27PM +0530, Felix Fietkau wrote:
> >>  On 2011-01-13 6:18 AM, Rajkumar Manoharan wrote:
> >>  >  On Thu, Jan 13, 2011 at 01:21:47AM +0530, Felix Fietkau wrote:
> >>  >>   On 2011-01-12 10:06 AM, Björn Smedman wrote:
> >>  >>   >   On Wed, Jan 12, 2011 at 3:30 PM, Rajkumar Manoharan
> >>  >>   >   <rmanoharan@atheros.com>    wrote:
> >>  >>   >>    The commit ""ath9k: Add change_interface callback" was failed
> >>  >>   >>    to update of hw opmode, ani and interrupt mask. This leads
> >>  >>   >>    to break p2p functionality on ath9k. And the existing add and
> >>  >>   >>    remove interface functions are not handling hw opmode and
> >>  >>   >>    ANI properly.
> >>  >>   >>
> >>  >>   >>    This patch combines the common code in interface callbacks
> >>  >>   >>    and also takes care of multi-vif cases.
> >>  >>   >
> >>  >>   >   How does your patch handle the race condition between the interface
> >>  >>   >   change done in process context and the beacon tasklet triggered by
> >>  >>   >   SWBA?
> >>  >>   >
> >>  >>   >   Also, perhaps more applicable to the commit log than the patch, how
> >>  >>   >   can opmode be properly handled in multi-vif cases? I mean let's say I
> >>  >>   >   have two AP vifs and then change one into STA, is the opmode then STA?
> >>  >>   >   Compare that to the case where I have two STA vifs and change one into
> >>  >>   >   AP; so again I have one AP and one STA vif but this time opmode is AP,
> >>  >>   >   right? I can see how I can be wrong about these examples but I can't
> >>  >>   >   really see how the opmode concept can be properly handled in multi-vif
> >>  >>   >   cases.
> >>  >>   I think opmode should be handled as follows:
> >>  >>   If there is at least one AP interface, opmode should be AP, regardless
> >>  >>   of what the other interfaces are set to.
> >>  >>   If there is no AP vif, opmode can be set to the primary vif type.
> >>  >>
> >>  >  Correct. this RFC patch does the same.
> >>  Really? I don't see that being handled properly, it still seems to
> >>  overwrite ah->opmode based on a single vif type for some types.
> >>  Also, there is no reason to have a WDS opmode in ath9k_hw. WDS is
> >>  typically used along with AP mode interfaces, and where it is not, the
> >>  AP opmode should be used for ath9k_hw anyway.
> > Instead of setting opmde as AP for WDS, it is better to handle WDS
> > case in ath9k_hw.
> Why? Right now I don't even see any NL80211_IFTYPE_WDS handling in 
> ath9k_hw, and I can't think of anything that should be handled 
> differently in ath9k_hw compared to the AP opmode.
For WDS station, what should be the interface type? Forgive if I'm wrong.
> >>  Maybe it would be a good idea to clean this up and first limit the
> >>  number of different types that we pass to ath9k_hw (i.e. only AP, ADHOC,
> >>  STA). Later we can make a separate enum for that to avoid passing the
> >>  type as-is entirely.
> > Just to stick with the currently supported interfaces list, WDS also included.
> >>  I think the mesh point opmode has no place in ath9k_hw. Right now it is
> >>  treated like ad-hoc, but I think that's completely wrong. Mesh should
> >>  behave just like AP mode, as no ad-hoc style TSF synchronization should
> >>  be done by the hardware, and 802.11s mesh nodes do not compete for
> >>  beacon transmission.
> > This is a different issue and it has to be addressed in separate patch.
> I agree.
> 
> - Felix

^ permalink raw reply

* Re: [ath9k-devel] [RFC 1/2] ath9k: Fix up hardware mode and beacons with multiple vifs.
From: Felix Fietkau @ 2011-01-14 18:05 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless, ath9k-devel
In-Reply-To: <1295026029-21130-1-git-send-email-greearb@candelatech.com>

On 2011-01-14 6:27 PM, greearb@candelatech.com wrote:
> From: Ben Greear<greearb@candelatech.com>
>
> When using a mixture of AP and Station interfaces,
> the hardware mode was using the type of the
> last VIF registered.  Instead, we should keep track
> of the number of different types of vifs and set the
> mode accordingly.
>
> In addtion, use the vif type instead of hardware opmode
> when dealing with beacons.
>
> Attempt to move some of the common setup code into smaller
> methods so we can re-use it when changing vif mode as
> well as adding/deleting vifs.
>
> This needs review.
>
> Signed-off-by: Ben Greear<greearb@candelatech.com>
> ---
> :100644 100644 3108699... a2da259... M	drivers/net/wireless/ath/ath9k/ath9k.h
> :100644 100644 385ba03... 8de591e... M	drivers/net/wireless/ath/ath9k/beacon.c
> :100644 100644 0452580... 1a65e53... M	drivers/net/wireless/ath/ath9k/main.c
> :100644 100644 ea2f67c... 9a2b4a8... M	drivers/net/wireless/ath/ath9k/recv.c
>   drivers/net/wireless/ath/ath9k/ath9k.h  |   10 +-
>   drivers/net/wireless/ath/ath9k/beacon.c |   14 +-
>   drivers/net/wireless/ath/ath9k/main.c   |  263 ++++++++++++++++++++++---------
>   drivers/net/wireless/ath/ath9k/recv.c   |   17 ++-
>   4 files changed, 214 insertions(+), 90 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
> index 3108699..a2da259 100644
> --- a/drivers/net/wireless/ath/ath9k/ath9k.h
> +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
> @@ -607,10 +607,15 @@ struct ath_softc {
>   	u32 sc_flags; /* SC_OP_* */
>   	u16 ps_flags; /* PS_* */
>   	u16 curtxpow;
> -	u8 nbcnvifs;
> -	u16 nvifs;
>   	bool ps_enabled;
>   	bool ps_idle;
> +	short nbcnvifs;
> +	short nvifs;
> +	short naps; /* number of APs */
> +	short nmeshes;
> +	short nstations;
> +	short nwds;
> +	short nadhocs;
>   	unsigned long ps_usecount;
>
>   	struct ath_config config;
Do we really need all those counters? Wouldn't it be better to iterate 
over active interfaces instead?

> diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
> index ea2f67c..9a2b4a8 100644
> --- a/drivers/net/wireless/ath/ath9k/recv.c
> +++ b/drivers/net/wireless/ath/ath9k/recv.c
> @@ -589,8 +589,14 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
>   		return;
>
>   	mgmt = (struct ieee80211_mgmt *)skb->data;
> -	if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0)
> +	if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) {
> +		/* TODO:  This doesn't work well if you have stations
> +		 * associated to two different APs because curbssid
> +		 * is just the last AP that any of the stations associated
> +		 * with.
> +		 */
>   		return; /* not from our current AP */
> +	}
>
>   	sc->ps_flags&= ~PS_WAIT_FOR_BEACON;
>
> @@ -980,13 +986,20 @@ static void ath9k_process_rssi(struct ath_common *common,
>   	int last_rssi;
>   	__le16 fc;
>
> +	/* TODO:  Maybe need to accept this if we have STA vifs active?? */
>   	if (ah->opmode != NL80211_IFTYPE_STATION)
>   		return;
>
>   	fc = hdr->frame_control;
>   	if (!ieee80211_is_beacon(fc) ||
> -	    compare_ether_addr(hdr->addr3, common->curbssid))
> +	    compare_ether_addr(hdr->addr3, common->curbssid)) {
> +		/* TODO:  This doesn't work well if you have stations
> +		 * associated to two different APs because curbssid
> +		 * is just the last AP that any of the stations associated
> +		 * with.
> +		 */
>   		return;
> +	}
>
>   	if (rx_stats->rs_rssi != ATH9K_RSSI_BAD&&  !rx_stats->rs_moreaggr)
>   		ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi);
Checking for the STA opmode is correct, this code should not be used for 
STA+AP. For the multi-STA case, it may make sense to process the RSSI 
average per vif and using the minimum for ANI.

- Felix

^ permalink raw reply

* Why multiple ESSIDS in one CELL
From: y bhanu @ 2011-01-14 17:39 UTC (permalink / raw)
  To: linux-wireless

I am trying to scan to scan for my under-test Access Point from a ubuntu client.
It shows me multiple ESSIDs in a a single cell and also it marks the
Mode "Unknown/bug".
Any clues why this is happening?

                   ESSID:"Atheros_XSpan_2G"

ESSID:"\x06\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                   Mode:Unknown/bug

         Cell 06 - Address: 00:00:83:31:25:33
                   Channel:6
                   Frequency:2.437 GHz (Channel 6)
                   Quality=70/70  Signal level=-31 dBm
                   Encryption key:off
                   ESSID:"Atheros_XSpan_2G"
                   Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
                             9 Mb/s; 12 Mb/s; 18 Mb/s
                   Bit Rates:24 Mb/s; 36 Mb/s; 48 Mb/s; 54 Mb/s

ESSID:"\x06\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                   Mode:Unknown/bug
                   Extra:tsf=0000000001eadf50
                   Extra: Last beacon: 13748ms ago
                   IE: Unknown: 001041746865726F735F585370616E5F3247
                   IE: Unknown: 010882848B960C121824
                   IE: Unknown: 030106
                   IE: Unknown: 0706555320010B1B
                   IE: Unknown: 200100
                   IE: Unknown: 2A0100
                   IE: Unknown: 32043048606C
                   IE: Unknown:
2D1A0C001BFFFF000000000000000000000000000000000000000000
                   IE: Unknown:
331A0C001BFFFF000000000000000000000000000000000000000000
                   IE: Unknown:
3D1606080000000000000000000000000000000000000000
                   IE: Unknown:
341606080000000000000000000000000000000000000000
                   IE: Unknown: 4A0E14000A002C01C800140005001900
                   IE: Unknown: 7F0101
                   IE: Unknown:
DD180050F2020101810003A4000027A4000042435E0062322F00
                   IE: Unknown: DD0900037F01010000FF7F
Thanks
bhanu

^ permalink raw reply

* [PATCH] mac80211:  Show max retry-counts in kernel messages.
From: greearb @ 2011-01-14 17:32 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 45fbb9e... eecbb1f... M	net/mac80211/mlme.c
 net/mac80211/mlme.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 45fbb9e..eecbb1f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1972,9 +1972,9 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 				wiphy_debug(local->hw.wiphy,
 					    "%s: No ack for nullfunc frame to"
-					    " AP %pM, try %d\n",
+					    " AP %pM, try %d/%i\n",
 					    sdata->name, bssid,
-					    ifmgd->probe_send_count);
+					    ifmgd->probe_send_count, max_tries);
 #endif
 				ieee80211_mgd_probe_ap_send(sdata);
 			} else {
@@ -2001,10 +2001,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 			wiphy_debug(local->hw.wiphy,
 				    "%s: No probe response from AP %pM"
-				    " after %dms, try %d\n",
+				    " after %dms, try %d/%i\n",
 				    sdata->name,
 				    bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ,
-				    ifmgd->probe_send_count);
+				    ifmgd->probe_send_count, max_tries);
 #endif
 			ieee80211_mgd_probe_ap_send(sdata);
 		} else {
-- 
1.7.2.3


^ permalink raw reply related

* [RFC 2/2] ath9k:  Add 'misc' file to debugfs, fix queue indexes.
From: greearb @ 2011-01-14 17:27 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Ben Greear
In-Reply-To: <1295026029-21130-1-git-send-email-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

Add a misc file to show hardware op-mode, irq setup,
number of various types of VIFs and more.

Also, previous patches were using the wrong xmit queue
indexes.  Change to use the internal ath9k indexes instead
of the mac80211 queue indexes.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 b0cb792... 5005621... M	drivers/net/wireless/ath/ath9k/debug.c
 drivers/net/wireless/ath/ath9k/debug.c |  128 +++++++++++++++++++++++++++++---
 1 files changed, 116 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index b0cb792..5005621 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -595,10 +595,10 @@ static const struct file_operations fops_wiphy = {
 do {									\
 	len += snprintf(buf + len, size - len,				\
 			"%s%13u%11u%10u%10u\n", str,			\
-			(unsigned int)(sc->tx.txq[WME_AC_BE].elem),	\
-			(unsigned int)(sc->tx.txq[WME_AC_BK].elem),	\
-			(unsigned int)(sc->tx.txq[WME_AC_VI].elem),	\
-			(unsigned int)(sc->tx.txq[WME_AC_VO].elem));	\
+			(unsigned int)(sc->tx.txq[ATH_TXQ_AC_BE].elem),	\
+			(unsigned int)(sc->tx.txq[ATH_TXQ_AC_BK].elem),	\
+			(unsigned int)(sc->tx.txq[ATH_TXQ_AC_VI].elem),	\
+			(unsigned int)(sc->tx.txq[ATH_TXQ_AC_VO].elem));	\
 	if (len >= size)						\
 		goto done;						\
 } while(0)
@@ -607,10 +607,10 @@ do {									\
 do {									\
 	len += snprintf(buf + len, size - len,				\
 			"%s%13i%11i%10i%10i\n", str,			\
-			list_empty(&sc->tx.txq[WME_AC_BE].elem),	\
-			list_empty(&sc->tx.txq[WME_AC_BK].elem),	\
-			list_empty(&sc->tx.txq[WME_AC_VI].elem),	\
-			list_empty(&sc->tx.txq[WME_AC_VO].elem));	\
+			list_empty(&sc->tx.txq[ATH_TXQ_AC_BE].elem),	\
+			list_empty(&sc->tx.txq[ATH_TXQ_AC_BK].elem),	\
+			list_empty(&sc->tx.txq[ATH_TXQ_AC_VI].elem),	\
+			list_empty(&sc->tx.txq[ATH_TXQ_AC_VO].elem));	\
 	if (len >= size)						\
 		goto done;						\
 } while (0)
@@ -657,10 +657,10 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
 	PR("hw-tx-proc-desc: ", txprocdesc);
 	len += snprintf(buf + len, size - len,
 			"%s%11p%11p%10p%10p\n", "txq-memory-address:",
-			&(sc->tx.txq[WME_AC_BE]),
-			&(sc->tx.txq[WME_AC_BK]),
-			&(sc->tx.txq[WME_AC_VI]),
-			&(sc->tx.txq[WME_AC_VO]));
+			&(sc->tx.txq[ATH_TXQ_AC_BE]),
+			&(sc->tx.txq[ATH_TXQ_AC_BK]),
+			&(sc->tx.txq[ATH_TXQ_AC_VI]),
+			&(sc->tx.txq[ATH_TXQ_AC_VO]));
 	if (len >= size)
 		goto done;
 
@@ -777,6 +777,99 @@ done:
 	return retval;
 }
 
+static ssize_t read_file_misc(struct file *file, char __user *user_buf,
+			      size_t count, loff_t *ppos)
+{
+	struct ath_softc *sc = file->private_data;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ath_hw *ah = sc->sc_ah;
+	char *buf;
+	unsigned int len = 0, size = 8000;
+	ssize_t retval = 0;
+	const char *tmp;
+	unsigned int reg;
+
+	buf = kzalloc(size, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	switch (sc->sc_ah->opmode) {
+	case  NL80211_IFTYPE_ADHOC:
+		tmp = "ADHOC";
+		break;
+	case  NL80211_IFTYPE_MESH_POINT:
+		tmp = "MESH";
+		break;
+	case  NL80211_IFTYPE_AP:
+		tmp = "AP";
+		break;
+	case  NL80211_IFTYPE_STATION:
+		tmp = "STATION";
+		break;
+	default:
+		tmp = "???";
+		break;
+	}
+
+	len += snprintf(buf + len, size - len,
+			"curbssid: %pM\n"
+			"OP-Mode: %s(%i)\n"
+			"Beacon-Timer-Register: 0x%x\n",
+			common->curbssid,
+			tmp, (int)(sc->sc_ah->opmode),
+			REG_READ(ah, AR_BEACON_PERIOD));
+
+	reg = REG_READ(ah, AR_TIMER_MODE);
+	len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (",
+			reg);
+	if (reg & AR_TBTT_TIMER_EN)
+		len += snprintf(buf + len, size - len, "TBTT ");
+	if (reg & AR_DBA_TIMER_EN)
+		len += snprintf(buf + len, size - len, "DBA ");
+	if (reg & AR_SWBA_TIMER_EN)
+		len += snprintf(buf + len, size - len, "SWBA ");
+	if (reg & AR_HCF_TIMER_EN)
+		len += snprintf(buf + len, size - len, "HCF ");
+	if (reg & AR_TIM_TIMER_EN)
+		len += snprintf(buf + len, size - len, "TIM ");
+	if (reg & AR_DTIM_TIMER_EN)
+		len += snprintf(buf + len, size - len, "DTIM ");
+	len += snprintf(buf + len, size - len, ")\n");
+
+	reg = sc->sc_ah->imask;
+	len += snprintf(buf + len, size - len, "imask: 0x%x (", reg);
+	if (reg & ATH9K_INT_SWBA)
+		len += snprintf(buf + len, size - len, "SWBA ");
+	if (reg & ATH9K_INT_BMISS)
+		len += snprintf(buf + len, size - len, "BMISS ");
+	if (reg & ATH9K_INT_CST)
+		len += snprintf(buf + len, size - len, "CST ");
+	if (reg & ATH9K_INT_RX)
+		len += snprintf(buf + len, size - len, "RX ");
+	if (reg & ATH9K_INT_RXHP)
+		len += snprintf(buf + len, size - len, "RXHP ");
+	if (reg & ATH9K_INT_RXLP)
+		len += snprintf(buf + len, size - len, "RXLP ");
+	if (reg & ATH9K_INT_BB_WATCHDOG)
+		len += snprintf(buf + len, size - len, "BB_WATCHDOG ");
+	/* there are other IRQs if one wanted to add them. */
+	len += snprintf(buf + len, size - len, ")\n");
+
+	len += snprintf(buf + len, size - len,
+			"VIF Counts: AP: %hi STA: %hi MESH: %hi WDS: %hi"
+			" ADHOC: %hi nvifs: %hi beacon-vifs: %hi\n",
+			sc->naps, sc->nstations, sc->nmeshes, sc->nwds,
+			sc->nadhocs, sc->nvifs, sc->nbcnvifs);
+
+	if (len > size)
+		len = size;
+
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+
+	return retval;
+}
+
 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
 		       struct ath_tx_status *ts)
 {
@@ -822,6 +915,13 @@ static const struct file_operations fops_stations = {
 	.llseek = default_llseek,
 };
 
+static const struct file_operations fops_misc = {
+	.read = read_file_misc,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 static ssize_t read_file_recv(struct file *file, char __user *user_buf,
 			      size_t count, loff_t *ppos)
 {
@@ -1063,6 +1163,10 @@ int ath9k_init_debug(struct ath_hw *ah)
 			sc, &fops_stations))
 		goto err;
 
+	if (!debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy,
+			sc, &fops_misc))
+		goto err;
+
 	if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy,
 			sc, &fops_recv))
 		goto err;
-- 
1.7.2.3


^ permalink raw reply related

* [RFC 1/2] ath9k:  Fix up hardware mode and beacons with multiple vifs.
From: greearb @ 2011-01-14 17:27 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Ben Greear

From: Ben Greear <greearb@candelatech.com>

When using a mixture of AP and Station interfaces,
the hardware mode was using the type of the
last VIF registered.  Instead, we should keep track
of the number of different types of vifs and set the
mode accordingly.

In addtion, use the vif type instead of hardware opmode
when dealing with beacons.

Attempt to move some of the common setup code into smaller
methods so we can re-use it when changing vif mode as
well as adding/deleting vifs.

This needs review.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 3108699... a2da259... M	drivers/net/wireless/ath/ath9k/ath9k.h
:100644 100644 385ba03... 8de591e... M	drivers/net/wireless/ath/ath9k/beacon.c
:100644 100644 0452580... 1a65e53... M	drivers/net/wireless/ath/ath9k/main.c
:100644 100644 ea2f67c... 9a2b4a8... M	drivers/net/wireless/ath/ath9k/recv.c
 drivers/net/wireless/ath/ath9k/ath9k.h  |   10 +-
 drivers/net/wireless/ath/ath9k/beacon.c |   14 +-
 drivers/net/wireless/ath/ath9k/main.c   |  263 ++++++++++++++++++++++---------
 drivers/net/wireless/ath/ath9k/recv.c   |   17 ++-
 4 files changed, 214 insertions(+), 90 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 3108699..a2da259 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -607,10 +607,15 @@ struct ath_softc {
 	u32 sc_flags; /* SC_OP_* */
 	u16 ps_flags; /* PS_* */
 	u16 curtxpow;
-	u8 nbcnvifs;
-	u16 nvifs;
 	bool ps_enabled;
 	bool ps_idle;
+	short nbcnvifs;
+	short nvifs;
+	short naps; /* number of APs */
+	short nmeshes;
+	short nstations;
+	short nwds;
+	short nadhocs;
 	unsigned long ps_usecount;
 
 	struct ath_config config;
@@ -694,6 +699,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
 void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
 void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
 bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
+bool ath9k_uses_beacons(int type);
 
 #ifdef CONFIG_PCI
 int ath_pci_init(void);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 385ba03..8de591e 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -244,9 +244,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
 						 struct ath_buf, list);
 		list_del(&avp->av_bcbuf->list);
 
-		if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
-		    sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC ||
-		    sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
+		if (ath9k_uses_beacons(vif->type)) {
 			int slot;
 			/*
 			 * Assign the vif to a beacon xmit slot. As
@@ -282,7 +280,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
 	/* NB: the beacon data buffer must be 32-bit aligned. */
 	skb = ieee80211_beacon_get(sc->hw, vif);
 	if (skb == NULL) {
-		ath_dbg(common, ATH_DBG_BEACON, "cannot get skb\n");
+		ath_err(common, "ieee80211_beacon_get failed\n");
 		return -ENOMEM;
 	}
 
@@ -720,10 +718,10 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
 		iftype = sc->sc_ah->opmode;
 	}
 
-		cur_conf->listen_interval = 1;
-		cur_conf->dtim_count = 1;
-		cur_conf->bmiss_timeout =
-			ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
+	cur_conf->listen_interval = 1;
+	cur_conf->dtim_count = 1;
+	cur_conf->bmiss_timeout =
+		ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
 
 	/*
 	 * It looks like mac80211 may end up using beacon interval of zero in
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 0452580..1a65e53 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1366,71 +1366,107 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
 }
 
-static int ath9k_add_interface(struct ieee80211_hw *hw,
-			       struct ieee80211_vif *vif)
+static void decrement_vif_type(struct ath_softc *sc, int type)
 {
-	struct ath_wiphy *aphy = hw->priv;
-	struct ath_softc *sc = aphy->sc;
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath_vif *avp = (void *)vif->drv_priv;
-	enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
-	int ret = 0;
-
-	mutex_lock(&sc->mutex);
-
-	switch (vif->type) {
+	switch (type) {
+	case NL80211_IFTYPE_AP:
+		sc->naps--;
+		break;
 	case NL80211_IFTYPE_STATION:
-		ic_opmode = NL80211_IFTYPE_STATION;
+		sc->nstations--;
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		sc->nadhocs--;
+		break;
+	case NL80211_IFTYPE_MESH_POINT:
+		sc->nmeshes--;
 		break;
 	case NL80211_IFTYPE_WDS:
-		ic_opmode = NL80211_IFTYPE_WDS;
+		sc->nwds--;
 		break;
-	case NL80211_IFTYPE_ADHOC:
+	}
+}
+
+static void increment_vif_type(struct ath_softc *sc, int type)
+{
+	switch (type) {
 	case NL80211_IFTYPE_AP:
+		sc->naps++;
+		break;
+	case NL80211_IFTYPE_STATION:
+		sc->nstations++;
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		sc->nadhocs++;
+		break;
 	case NL80211_IFTYPE_MESH_POINT:
-		if (sc->nbcnvifs >= ATH_BCBUF) {
-			ret = -ENOBUFS;
-			goto out;
-		}
-		ic_opmode = vif->type;
+		sc->nmeshes++;
+		break;
+	case NL80211_IFTYPE_WDS:
+		sc->nwds++;
 		break;
+	}
+}
+
+bool ath9k_uses_beacons(int type)
+{
+	switch (type) {
+	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_MESH_POINT:
+		return true;
 	default:
-		ath_err(common, "Interface type %d not yet supported\n",
-			vif->type);
-		ret = -EOPNOTSUPP;
-		goto out;
+		return false;
 	}
+}
 
-	ath_dbg(common, ATH_DBG_CONFIG,
-		"Attach a VIF of type: %d\n", ic_opmode);
+static void ath9k_reclaim_beacon(struct ath_softc *sc,
+				 struct ieee80211_vif *vif)
+{
+	struct ath_vif *avp = (void *)vif->drv_priv;
 
-	/* Set the VIF opmode */
-	avp->av_opmode = ic_opmode;
-	avp->av_bslot = -1;
+	/* Disable SWBA interrupt */
+	sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
+	ath9k_ps_wakeup(sc);
+	ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
+	ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+	tasklet_kill(&sc->bcon_tasklet);
+	ath9k_ps_restore(sc);
 
-	sc->nvifs++;
+	ath_beacon_return(sc, avp);
+	sc->sc_flags &= ~SC_OP_BEACONS;
 
-	ath9k_set_bssid_mask(hw, vif);
+	if (sc->nbcnvifs > 0) {
+		/* Re-enable beaconing */
+		sc->sc_ah->imask |= ATH9K_INT_SWBA;
+		ath9k_ps_wakeup(sc);
+		ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
+		ath9k_ps_restore(sc);
+	}
+}
 
-	if (sc->nvifs > 1)
-		goto out; /* skip global settings for secondary vif */
+/* Called with sc->mutex held, vif counts set up properly. */
+static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 
-	if (ic_opmode == NL80211_IFTYPE_AP) {
+	ath9k_set_bssid_mask(hw, vif);
+
+	if (sc->naps > 0) {
 		ath9k_hw_set_tsfadjust(ah, 1);
 		sc->sc_flags |= SC_OP_TSF_RESET;
-	}
-
-	/* Set the device opmode */
-	ah->opmode = ic_opmode;
+		ah->opmode = NL80211_IFTYPE_AP;
+	} else
+		ah->opmode = vif->type;
 
 	/*
 	 * Enable MIB interrupts when there are hardware phy counters.
-	 * Note we only do this (at the moment) for station mode.
 	 */
-	if ((vif->type == NL80211_IFTYPE_STATION) ||
-	    (vif->type == NL80211_IFTYPE_ADHOC) ||
-	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+	if ((sc->nstations + sc->nadhocs + sc->nmeshes) > 0) {
 		if (ah->config.enable_ani)
 			ah->imask |= ATH9K_INT_MIB;
 		ah->imask |= ATH9K_INT_TSFOOR;
@@ -1438,40 +1474,87 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
 
 	ath9k_hw_set_interrupts(ah, ah->imask);
 
-	if (vif->type == NL80211_IFTYPE_AP    ||
-	    vif->type == NL80211_IFTYPE_ADHOC) {
+	if ((sc->naps + sc->nadhocs) > 0) {
 		sc->sc_flags |= SC_OP_ANI_RUN;
 		ath_start_ani(common);
 	}
 
-out:
-	mutex_unlock(&sc->mutex);
-	return ret;
+	if (ath9k_uses_beacons(vif->type)) {
+		int error;
+		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+		/* This may fail because upper levels do not have beacons
+		 * properly configured yet.  That's OK, we assume it
+		 * will be properly configured and then we will be notified
+		 * in the info_changed method and set up beacons properly
+		 * there.
+		 */
+		error = ath_beacon_alloc(aphy, vif);
+		if (error)
+			ath9k_reclaim_beacon(sc, vif);
+		else
+			ath_beacon_config(sc, vif);
+	}
 }
 
-static void ath9k_reclaim_beacon(struct ath_softc *sc,
-				 struct ieee80211_vif *vif)
+
+static int ath9k_add_interface(struct ieee80211_hw *hw,
+			       struct ieee80211_vif *vif)
 {
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_vif *avp = (void *)vif->drv_priv;
+	int ret = 0;
 
-	/* Disable SWBA interrupt */
-	sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
-	ath9k_ps_wakeup(sc);
-	ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
-	ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-	tasklet_kill(&sc->bcon_tasklet);
-	ath9k_ps_restore(sc);
+	mutex_lock(&sc->mutex);
 
-	ath_beacon_return(sc, avp);
-	sc->sc_flags &= ~SC_OP_BEACONS;
+	switch (vif->type) {
+	case NL80211_IFTYPE_STATION:
+	case NL80211_IFTYPE_WDS:
+	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_MESH_POINT:
+		break;
+	default:
+		ath_err(common, "Interface type %d not yet supported\n",
+			vif->type);
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
 
-	if (sc->nbcnvifs > 0) {
-		/* Re-enable beaconing */
-		sc->sc_ah->imask |= ATH9K_INT_SWBA;
-		ath9k_ps_wakeup(sc);
-		ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
-		ath9k_ps_restore(sc);
+	if (ath9k_uses_beacons(vif->type)) {
+		if (sc->nbcnvifs >= ATH_BCBUF) {
+			ath_err(common, "Not enough beacon buffers when adding"
+				" new interface of type: %i\n",
+				vif->type);
+			ret = -ENOBUFS;
+			goto out;
+		}
+	}
+
+	if ((vif->type == NL80211_IFTYPE_ADHOC) &&
+	    sc->nvifs > 0) {
+		ath_err(common, "Cannot create ADHOC interface when other"
+			" interfaces already exist.\n");
+		ret = -EINVAL;
+		goto out;
 	}
+
+	ath_dbg(common, ATH_DBG_CONFIG,
+		"Attach a VIF of type: %d\n", vif->type);
+
+	/* Set the VIF opmode */
+	avp->av_opmode = vif->type;
+	avp->av_bslot = -1;
+
+	increment_vif_type(sc, vif->type);
+	sc->nvifs++;
+
+	ath9k_do_vif_add_setup(hw, vif);
+out:
+	mutex_unlock(&sc->mutex);
+	return ret;
 }
 
 static int ath9k_change_interface(struct ieee80211_hw *hw,
@@ -1487,6 +1570,11 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
 	ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n");
 	mutex_lock(&sc->mutex);
 
+	decrement_vif_type(sc, vif->type);
+
+	if (ath9k_uses_beacons(vif->type))
+		ath9k_reclaim_beacon(sc, vif);
+
 	switch (new_type) {
 	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_ADHOC:
@@ -1497,12 +1585,11 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
 		}
 		break;
 	case NL80211_IFTYPE_STATION:
-		/* Stop ANI */
-		sc->sc_flags &= ~SC_OP_ANI_RUN;
-		del_timer_sync(&common->ani.timer);
-		if ((vif->type == NL80211_IFTYPE_AP) ||
-		    (vif->type == NL80211_IFTYPE_ADHOC))
-			ath9k_reclaim_beacon(sc, vif);
+		if ((sc->naps + sc->nadhocs) == 0) {
+			/* Stop ANI */
+			sc->sc_flags &= ~SC_OP_ANI_RUN;
+			del_timer_sync(&common->ani.timer);
+		}
 		break;
 	default:
 		ath_err(common, "Interface type %d not yet supported\n",
@@ -1513,6 +1600,8 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
 	vif->type = new_type;
 	vif->p2p = p2p;
 
+	increment_vif_type(sc, vif->type);
+	ath9k_do_vif_add_setup(hw, vif);
 out:
 	mutex_unlock(&sc->mutex);
 	return ret;
@@ -1524,22 +1613,40 @@ static void ath9k_remove_interface(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);
+	struct ath_hw *ah = sc->sc_ah;
 
 	ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
 
 	mutex_lock(&sc->mutex);
 
-	/* Stop ANI */
-	sc->sc_flags &= ~SC_OP_ANI_RUN;
-	del_timer_sync(&common->ani.timer);
+	decrement_vif_type(sc, vif->type);
+	sc->nvifs--;
+
+	if ((sc->naps + sc->nadhocs) == 0) {
+		/* Stop ANI */
+		sc->sc_flags &= ~SC_OP_ANI_RUN;
+		del_timer_sync(&common->ani.timer);
+	}
 
 	/* Reclaim beacon resources */
-	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
-	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
-	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT))
+	if (ath9k_uses_beacons(vif->type))
 		ath9k_reclaim_beacon(sc, vif);
 
-	sc->nvifs--;
+	ath9k_set_bssid_mask(hw, NULL);
+
+	if (sc->naps == 0) {
+		ath9k_hw_set_tsfadjust(ah, 0);
+		sc->sc_flags &= ~SC_OP_TSF_RESET;
+		if (sc->nwds)
+			ah->opmode = NL80211_IFTYPE_WDS;
+		else if (sc->nmeshes)
+			ah->opmode = NL80211_IFTYPE_MESH_POINT;
+		else if (sc->nadhocs)
+			ah->opmode = NL80211_IFTYPE_ADHOC;
+		else
+			ah->opmode = NL80211_IFTYPE_STATION;
+	} else
+		ah->opmode = NL80211_IFTYPE_AP;
 
 	mutex_unlock(&sc->mutex);
 }
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index ea2f67c..9a2b4a8 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -589,8 +589,14 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
 		return;
 
 	mgmt = (struct ieee80211_mgmt *)skb->data;
-	if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0)
+	if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) {
+		/* TODO:  This doesn't work well if you have stations
+		 * associated to two different APs because curbssid
+		 * is just the last AP that any of the stations associated
+		 * with.
+		 */
 		return; /* not from our current AP */
+	}
 
 	sc->ps_flags &= ~PS_WAIT_FOR_BEACON;
 
@@ -980,13 +986,20 @@ static void ath9k_process_rssi(struct ath_common *common,
 	int last_rssi;
 	__le16 fc;
 
+	/* TODO:  Maybe need to accept this if we have STA vifs active?? */
 	if (ah->opmode != NL80211_IFTYPE_STATION)
 		return;
 
 	fc = hdr->frame_control;
 	if (!ieee80211_is_beacon(fc) ||
-	    compare_ether_addr(hdr->addr3, common->curbssid))
+	    compare_ether_addr(hdr->addr3, common->curbssid)) {
+		/* TODO:  This doesn't work well if you have stations
+		 * associated to two different APs because curbssid
+		 * is just the last AP that any of the stations associated
+		 * with.
+		 */
 		return;
+	}
 
 	if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr)
 		ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi);
-- 
1.7.2.3


^ permalink raw reply related

* [PATCH 1/1] mac80211: mesh only parameter mppath maybe unused
From: wey-yi.w.guy @ 2011-01-14 16:07 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Wey-Yi Guy

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

mppath is mesh related parameter and maybe unused

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 net/mac80211/tx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index dc261bb..2378305 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1750,7 +1750,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 	__le16 fc;
 	struct ieee80211_hdr hdr;
 	struct ieee80211s_hdr mesh_hdr __maybe_unused;
-	struct mesh_path *mppath = NULL;
+	struct mesh_path __maybe_unused *mppath = NULL;
 	const u8 *encaps_data;
 	int encaps_len, skip_header_bytes;
 	int nh_pos, h_pos;
-- 
1.6.0.4


^ permalink raw reply related

* RE: cfg80211 rfkill interface
From: Arend Van Spriel @ 2011-01-14 15:05 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1295017068.3853.3.camel@jlt3.sipsolutions.net>

Thanks for quick response. I will have to dig in deeper, than.

Gr. AvS
________________________________________
From: Johannes Berg [johannes@sipsolutions.net]
Sent: Friday, January 14, 2011 3:57 PM
To: Arend Van Spriel
Cc: linux-wireless@vger.kernel.org
Subject: RE: cfg80211 rfkill interface

On Fri, 2011-01-14 at 06:54 -0800, Arend Van Spriel wrote:

> Thanks for you thoughts on this. Especially the last remark was reason
> for me to verify several usage scenarios. I ran into a issue with
> unloading the driver module while it was in blocked rfkill state and
> polling was active. Turns out the call to ieee80211_unregister_hw
> takes a loooong time before it returns and dmesg shows message from
> unregister_netdevice which seems related about refcount not being
> zero. This is only observed in this scenario. Any suggestion on how to
> handle this?

No, I can see no reason for this to happen?? rfkill doesn't take a
netdev refcount.

johannes




^ permalink raw reply

* RE: cfg80211 rfkill interface
From: Johannes Berg @ 2011-01-14 14:57 UTC (permalink / raw)
  To: Arend Van Spriel; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <2EFC2EC4C7011444989031FE55348CDA9549080E26@SJEXCHCCR02.corp.ad.broadcom.com>

On Fri, 2011-01-14 at 06:54 -0800, Arend Van Spriel wrote:

> Thanks for you thoughts on this. Especially the last remark was reason
> for me to verify several usage scenarios. I ran into a issue with
> unloading the driver module while it was in blocked rfkill state and
> polling was active. Turns out the call to ieee80211_unregister_hw
> takes a loooong time before it returns and dmesg shows message from
> unregister_netdevice which seems related about refcount not being
> zero. This is only observed in this scenario. Any suggestion on how to
> handle this?

No, I can see no reason for this to happen?? rfkill doesn't take a
netdev refcount.

johannes


^ permalink raw reply

* RE: cfg80211 rfkill interface
From: Arend Van Spriel @ 2011-01-14 14:54 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1294688709.3583.25.camel@jlt3.sipsolutions.net>

Hi Johannes,

Thanks for you thoughts on this. Especially the last remark was reason for me to verify several usage scenarios. I ran into a issue with unloading the driver module while it was in blocked rfkill state and polling was active. Turns out the call to ieee80211_unregister_hw takes a loooong time before it returns and dmesg shows message from unregister_netdevice which seems related about refcount not being zero. This is only observed in this scenario. Any suggestion on how to handle this?

Gr. AvS

|-----Original Message-----
|From: Johannes Berg [mailto:johannes@sipsolutions.net]
|Sent: Monday, January 10, 2011 8:45 PM
|To: Arend Van Spriel
|Cc: linux-wireless@vger.kernel.org
|Subject: Re: cfg80211 rfkill interface
|
|Hi Arend,
|
|> I am looking into implementing rfkill into our brcm80211 open-source
|> driver. Our driver detects disable switch by an interrupt, but
|> switching back does not give an interrupt.
|
|Interesting, but I guess it makes some sense.
|
|> For the latter I wanted to use the rfkill_poll callback and
|> wiphy_rfkill_start_polling.
|
|Right, makes sense.
|
|> However, I tried a wiphy_rfkill_stop_polling in the rfkill_poll
|> callback when rf is unblocked, and this resulted in a system hang.
|
|Yeah, I'm not surprised. start_polling will work from anywhere, but
|stop_polling needs to actually completely sync the poll stop so it can't
|be done from within the poll or from within any rfkill callbacks.
|
|> So I moved the wiphy_rfkill_stop_polling to the start callback. Does
|> that make sense or is there another way you would recommend?
|
|I think that makes sense.
|
|However, where do you start polling? You have to poll even if the device
|is not start()ed, I guess?
|
|johannes
|



^ permalink raw reply


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