Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: ath5k deadlock w/ blob transfer
From: Bob Copeland @ 2010-05-08  1:18 UTC (permalink / raw)
  To: Nils Radtke; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20100507105059.GE3479@localhost>

On Fri, May 7, 2010 at 6:50 AM, Nils Radtke <lkml@think-future.de> wrote:
>  Hi,
>
>  Guess, this is better suited in here:
>>   - ath5k: when starting a blob transfer eg. ssh summer.jpg to the
>>     notebook with the ath5k driver running, the wNIC freezes almost
>>     immediately! Dead device. This is unfortunately too easily reproducible.

> So where should I be posting this?

You're in the right place...

> When both drivers deadlock it's either a common
> base in the wireless driver premisses or yet up the path somewhere in the
> kernel code.

(Or hardware.  madwifi doesn't use mac80211 so it is probably not
common code, but ath5k could have inherited a bug from it.)

> Ideas?

I missed the first email.  What type of machine?  System lockup
or the connection drops?  Do you get any output on the console or
in dmesg? (try switching to a text console before your scp test.)
If not, any output after lockup booting with nmi_watchdog=1?

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply

* Re: [RFC] minstrel_ht: refine STBC handling
From: Johannes Berg @ 2010-05-08  8:27 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: Felix Fietkau, linux-wireless
In-Reply-To: <201005080241.16634.chunkeey@googlemail.com>

On Sat, 2010-05-08 at 02:41 +0200, Christian Lamparter wrote:

> I noticed that only the peer's HT capabilities are fully evaluated,
> but the actual capabilities of the sending device (stored
> in sband->ht_cap.cap) are not considered.

mac80211 will give you the peer's capabilities already restricted down
to our own.

johannes


^ permalink raw reply

* Re: ath5k deadlock w/ blob transfer
From: Nils Radtke @ 2010-05-08 14:11 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-kernel, linux-wireless
In-Reply-To: <p2pb6c5339f1005071818u489804e7ud40fe3feb5459bb8@mail.gmail.com>

  Hi,

> I missed the first email.  What type of machine?  System lockup
> or the connection drops?  Do you get any output on the console or
> in dmesg? (try switching to a text console before your scp test.)
> If not, any output after lockup booting with nmi_watchdog=1?

IRC, no system lockup, only driver lockup. But I avoided using wireless for
blob transfer for the reliability of the lockups, so it's a couple of months
since I deliberately crashed it.. Maybe once in a while it lead to a complete
system lockup, but treat this as rumble in my memories (and could be due to
the other BUGs reported, also)..

notebook: ACER Extensa 5220
kernels since  Linux host 2.6.32.2 #4 PREEMPT Wed Dec 30 15:19:58 CET 2009 i686 and even before
lspci:
04:00.0 Ethernet controller: Atheros Communications Inc. AR5001 Wireless Network Adapter (rev 01)
        Subsystem: Device 1a32:0105
        Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+
+FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR-
+<PERR- INTx-
        Interrupt: pin A routed to IRQ 17
        Region 0: Memory at f8000000 (64-bit, non-prefetchable) [size=64K]
        Capabilities: <access denied>

There's another bugreport for this machine, w/ hw info: http://lkml.org/lkml/2010/2/18/104

Ok, trying to lockup the machine once more, will report back then.

  Thanks,

  Nils


^ permalink raw reply

* Re: The case of the bogus SSID
From: pigiron @ 2010-05-08 14:34 UTC (permalink / raw)
  To: Javier Cardona, linux-wireless
In-Reply-To: <w2r445f43ac1005070929uacb5472dj231ff72ef0343860@mail.gmail.com>

On Fri, 7 May 2010 09:29:18 -0700 Javier Cardona <javier@cozybit.com> wrote:

> Hi,
> 
> On Thu, May 6, 2010 at 7:56 PM, pigiron <pigiron@gmx.com> wrote:
> > On Thu, 6 May 2010 11:12:15 -0700 Steve deRosier <steve@cozybit.com> wrote:
> >
> >> On Wed, May 5, 2010 at 10:01 AM, pigiron <pigiron@gmx.com> wrote:
> >> > I noticed that decimal 52 is assigned to WLAN_EID_MESH_ID in the
> >> > ieee80211.h file, and recently the same 52 was also assigned to
> >> > WLAN_EID_NEIGHBOR_REPORT in the same enumerated ieee80211_eid{}
> >> > structure.
> >> >
> >>
> >> I can't answer the rest of your question, but AFAIK, the element IDs
> >> for 802.11s mesh haven't been approved yet as the 802.11s draft
> >> contains a note to that effect.  The current ANA database sheet I
> >> could find (Feb 2010) does have 52 assigned to Neighbor Report, and
> >> the mesh element IDs are nowhere to be found.
> >>
> > I agree. The 802.11k-2008 standard has already been approved with Element ID
> > 52 = Neighbor Report, so it's probably almost a guarantee that 802.11s
> > won't be assigning 52 to anything in the future.
> >
> > I'm kind of stuck on this problem. I could probably find out what's causing
> > the failure and create a patch... but the patch wouldn't be "The Right
> > Thing To Do(tm)" if the router isn't supposed to be spewing that data to
> > begin with.
> 
> I don't know about the router, nor if the IE ID clash is causing your
> problem, but moving the mesh codes somewhere else in the unassigned ID
> space would be a "A Good Thing To Do (tm)".
> 
> Cheers,
> 
> Javier

Really?

Wouldn't that cause a problem for the kids running OLPC? For instance, where
some of the laptops are running an old level of code where WLAN_EID_MESH_ID=52
and others are running new code where WLAN_EID_MESH_ID=X.

Especially, since as far as I can tell with my untrained eye, this Neighbor
Report that I've been fretting about should only be coming over the air when
specifically asked for... and we don't have any code (yet) to do that?

peace,
Bob

^ permalink raw reply

* [patch 0/9] smatch issues in wireless-next
From: Dan Carpenter @ 2010-05-08 16:19 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

I pulled
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6.git#master
and fixed most of the new smatch issues.

regards,
dan carpenter

^ permalink raw reply

* [patch 1/9] iwlwifi: remove stray mutex_unlock()
From: Dan Carpenter @ 2010-05-08 16:21 UTC (permalink / raw)
  To: Zhu Yi
  Cc: Reinette Chatre, Intel Linux Wireless, John W. Linville,
	Wey-Yi Guy, Johannes Berg, Abhijeet Kolekar, linux-wireless

This mutex_unlock() has been here from the initial commit, but as nearly
as I can tell, there isn't a reason for it.

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 9dad867..3faa78c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2482,7 +2482,6 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
 				   &priv->_3945.shared_phys, GFP_KERNEL);
 	if (!priv->_3945.shared_virt) {
 		IWL_ERR(priv, "failed to allocate pci memory\n");
-		mutex_unlock(&priv->mutex);
 		return -ENOMEM;
 	}
 

^ permalink raw reply related

* [patch 2/9] ath9k: range checking issues in htc_hst.c
From: Dan Carpenter @ 2010-05-08 16:22 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Jouni Malinen, Sujith Manoharan, Vasanthakumar Thiagarajan,
	Senthil Balasubramanian, John W. Linville, Ming Lei,
	linux-wireless, ath9k-devel

The original code had ENDPOINT_MAX and HST_ENDPOINT_MAX switched.

Also the first loop was off by one, it started past the end of the array
and went down to 1 instead of going down to 0.  The test at the end of
the loop to see if we exited via a break wasn't right because
"tmp_endpoint" is always non-null here.

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 7bf6ce1..0c062d0 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -116,7 +116,7 @@ static void htc_process_conn_rsp(struct htc_target *target,
 		max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
 		endpoint = &target->endpoint[epid];
 
-		for (tepid = ENDPOINT_MAX; tepid > ENDPOINT0; tepid--) {
+		for (tepid = HST_ENDPOINT_MAX - 1; tepid >= ENDPOINT0; tepid--) {
 			tmp_endpoint = &target->endpoint[tepid];
 			if (tmp_endpoint->service_id == service_id) {
 				tmp_endpoint->service_id = 0;
@@ -124,7 +124,7 @@ static void htc_process_conn_rsp(struct htc_target *target,
 			}
 		}
 
-		if (!tmp_endpoint)
+		if (tepid < ENDPOINT0)
 			return;
 
 		endpoint->service_id = service_id;
@@ -297,7 +297,7 @@ void htc_stop(struct htc_target *target)
 	enum htc_endpoint_id epid;
 	struct htc_endpoint *endpoint;
 
-	for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
+	for (epid = ENDPOINT0; epid < HST_ENDPOINT_MAX; epid++) {
 		endpoint = &target->endpoint[epid];
 		if (endpoint->service_id != 0)
 			target->hif->stop(target->hif_dev, endpoint->ul_pipeid);
@@ -309,7 +309,7 @@ void htc_start(struct htc_target *target)
 	enum htc_endpoint_id epid;
 	struct htc_endpoint *endpoint;
 
-	for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
+	for (epid = ENDPOINT0; epid < HST_ENDPOINT_MAX; epid++) {
 		endpoint = &target->endpoint[epid];
 		if (endpoint->service_id != 0)
 			target->hif->start(target->hif_dev,
@@ -377,7 +377,7 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
 	htc_hdr = (struct htc_frame_hdr *) skb->data;
 	epid = htc_hdr->endpoint_id;
 
-	if (epid >= ENDPOINT_MAX) {
+	if (epid >= HST_ENDPOINT_MAX) {
 		if (pipe_id != USB_REG_IN_PIPE)
 			dev_kfree_skb_any(skb);
 		else

^ permalink raw reply related

* [patch 3/9] ath9k: cleanup: u32 => bool
From: Dan Carpenter @ 2010-05-08 16:22 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Jouni Malinen, Sujith Manoharan, Vasanthakumar Thiagarajan,
	Senthil Balasubramanian, John W. Linville, Felix Fietkau,
	linux-wireless, ath9k-devel

This is used as a boolean variable so changing it to a boolean type is a
cleanup.

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index b2c17c9..f685b8b 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1082,7 +1082,7 @@ static bool ar5008_hw_ani_control(struct ath_hw *ah,
 		const int m2Thresh[] = { 127, 0x40 };
 		const int m2CountThr[] = { 31, 16 };
 		const int m2CountThrLow[] = { 63, 48 };
-		u32 on = param ? 1 : 0;
+		bool on = param ? 1 : 0;
 
 		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
 			      AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 80431a2..0c34154 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -771,7 +771,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
 		const int m2Thresh[] = { 127, 0x40 };
 		const int m2CountThr[] = { 31, 16 };
 		const int m2CountThrLow[] = { 63, 48 };
-		u32 on = param ? 1 : 0;
+		bool on = param ? 1 : 0;
 
 		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
 			      AR_PHY_SFCORR_LOW_M1_THRESH_LOW,

^ permalink raw reply related

* [patch 4/9] ath9k/htc_drv_main: null dereference typo
From: Dan Carpenter @ 2010-05-08 16:23 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Jouni Malinen, Sujith Manoharan, Vasanthakumar Thiagarajan,
	Senthil Balasubramanian, John W. Linville, Vivek Natarajan,
	linux-wireless, ath9k-devel

This is a stray null dereference.  We initialize "ista" properly later on.

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index f503586..e75db06 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -461,7 +461,7 @@ static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
 	struct ath_common *common = ath9k_hw_common(priv->ah);
 	struct ath9k_htc_target_aggr aggr;
 	struct ieee80211_sta *sta = NULL;
-	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
+	struct ath9k_htc_sta *ista;
 	int ret = 0;
 	u8 cmd_rsp;
 

^ permalink raw reply related

* [patch 5/9] ath9k/htc_drv_main: off by one error
From: Dan Carpenter @ 2010-05-08 16:24 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Jouni Malinen, Sujith Manoharan, Vasanthakumar Thiagarajan,
	Senthil Balasubramanian, John W. Linville, Vivek Natarajan,
	linux-wireless, ath9k-devel

I changed "> ATH9K_HTC_MAX_TID" to ">= ATH9K_HTC_MAX_TID" to avoid a
potential overflow.

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index e75db06..6c386da 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -465,7 +465,7 @@ static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
 	int ret = 0;
 	u8 cmd_rsp;
 
-	if (tid > ATH9K_HTC_MAX_TID)
+	if (tid >= ATH9K_HTC_MAX_TID)
 		return -EINVAL;
 
 	memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));

^ permalink raw reply related

* [patch 6/9] ath5k: several off by one range checks
From: Dan Carpenter @ 2010-05-08 16:24 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Nick Kossifidis, Luis R. Rodriguez, Bob Copeland,
	John W. Linville, Bruno Randolf, linux-wireless, ath5k-devel

There are several places that use > ARRAY_SIZE() instead of 
>= ARRAY_SIZE().

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index 584a328..f2311ab 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -73,7 +73,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
 	const s8 hi[] = { -14, -12 };
 	const s8 fr[] = { -78, -80 };
 #endif
-	if (level < 0 || level > ARRAY_SIZE(sz)) {
+	if (level < 0 || level >= ARRAY_SIZE(sz)) {
 		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
 			"level out of range %d", level);
 		return;
@@ -104,7 +104,7 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
 {
 	const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
 
-	if (level < 0 || level > ARRAY_SIZE(val) ||
+	if (level < 0 || level >= ARRAY_SIZE(val) ||
 	    level > ah->ah_sc->ani_state.max_spur_level) {
 		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
 			"level out of range %d", level);
@@ -129,7 +129,7 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
 {
 	const int val[] = { 0, 4, 8 };
 
-	if (level < 0 || level > ARRAY_SIZE(val)) {
+	if (level < 0 || level >= ARRAY_SIZE(val)) {
 		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
 			"level out of range %d", level);
 		return;

^ permalink raw reply related

* [patch 7/9] wl1271: add missing spin_lock()
From: Dan Carpenter @ 2010-05-08 16:25 UTC (permalink / raw)
  To: Luciano Coelho
  Cc: John W. Linville, Juuso Oikarinen, Teemu Paasikivi, Kalle Valo,
	linux-wireless

We should start the loop consistently with the "wl_lock" lock held.

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 3e4b9fb..b61cd10 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -466,6 +466,7 @@ static void wl1271_irq_work(struct work_struct *work)
 		intr = le32_to_cpu(wl->fw_status->intr);
 		if (!intr) {
 			wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
+			spin_lock_irqsave(&wl->wl_lock, flags);
 			continue;
 		}
 

^ permalink raw reply related

* [patch 8/9] wl1271: fix notifier interface supported test
From: Dan Carpenter @ 2010-05-08 16:25 UTC (permalink / raw)
  To: Luciano Coelho
  Cc: John W. Linville, Juuso Oikarinen, Teemu Paasikivi, Kalle Valo,
	linux-wireless

The "(wl == NULL)" test doesn't work here because "wl" is always
non-null.  The intent of the code is to return if the interface
was not supported by the driver.

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index b61cd10..55aa813 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -852,7 +852,7 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
 		if (wl == wl_temp)
 			break;
 	}
-	if (wl == NULL)
+	if (wl != wl_temp)
 		return NOTIFY_DONE;
 
 	/* Get the interface IP address for the device. "ifa" will become

^ permalink raw reply related

* [patch 9/9] wl1271: remove some unneeded code
From: Dan Carpenter @ 2010-05-08 16:26 UTC (permalink / raw)
  To: Luciano Coelho
  Cc: John W. Linville, Juuso Oikarinen, Teemu Paasikivi, Kalle Valo,
	linux-wireless

The goto and the break are equivelent.  I removed the goto in memory of
Edsger Dijkstra who famously hated gotos and who would have been eighty
years old next Tuesday.

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 55aa813..da40cee 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1563,8 +1563,6 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	default:
 		wl1271_error("Unsupported key cmd 0x%x", cmd);
 		ret = -EOPNOTSUPP;
-		goto out_sleep;
-
 		break;
 	}
 

^ permalink raw reply related

* [PATCH 3/9] rt2x00: Don't check whether hardware crypto is enabled when reading RXD.
From: Gertjan van Wingerde @ 2010-05-08 21:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273354826-4335-1-git-send-email-gwingerde@gmail.com>

We should simply follow what the hardware told us it has done.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2500usb.c |    8 +++-----
 drivers/net/wireless/rt2x00/rt2800pci.c |   17 +++++++----------
 drivers/net/wireless/rt2x00/rt2800usb.c |    8 ++------
 drivers/net/wireless/rt2x00/rt61pci.c   |    8 ++------
 drivers/net/wireless/rt2x00/rt73usb.c   |    8 ++------
 5 files changed, 16 insertions(+), 33 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index c6e6e7b..f90b308 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1213,11 +1213,9 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
 	if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
 		rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
 
-	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
-		rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER);
-		if (rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR))
-			rxdesc->cipher_status = RX_CRYPTO_FAIL_KEY;
-	}
+	rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER);
+	if (rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR))
+		rxdesc->cipher_status = RX_CRYPTO_FAIL_KEY;
 
 	if (rxdesc->cipher != CIPHER_NONE) {
 		_rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index df2c3fb..b9ec081 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -840,16 +840,13 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
 	if (rt2x00_get_field32(rxd3, RXD_W3_CRC_ERROR))
 		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
 
-	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
-		/*
-		 * Unfortunately we don't know the cipher type used during
-		 * decryption. This prevents us from correct providing
-		 * correct statistics through debugfs.
-		 */
-		rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
-		rxdesc->cipher_status =
-		    rt2x00_get_field32(rxd3, RXD_W3_CIPHER_ERROR);
-	}
+	/*
+	 * Unfortunately we don't know the cipher type used during
+	 * decryption. This prevents us from correct providing
+	 * correct statistics through debugfs.
+	 */
+	rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
+	rxdesc->cipher_status = rt2x00_get_field32(rxd3, RXD_W3_CIPHER_ERROR);
 
 	if (rt2x00_get_field32(rxd3, RXD_W3_DECRYPTED)) {
 		/*
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 94b6812..df7ad98 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -549,7 +549,6 @@ static void rt2800usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 				  struct rxdone_entry_desc *rxdesc)
 {
-	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 	__le32 *rxi = (__le32 *)entry->skb->data;
 	__le32 *rxwi;
@@ -595,11 +594,8 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 	if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR))
 		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
 
-	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
-		rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
-		rxdesc->cipher_status =
-		    rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
-	}
+	rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
+	rxdesc->cipher_status = rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
 
 	if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) {
 		/*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 8099eca..1b0c70d 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1968,12 +1968,8 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry,
 	if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
 		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
 
-	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
-		rxdesc->cipher =
-		    rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG);
-		rxdesc->cipher_status =
-		    rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR);
-	}
+	rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG);
+	rxdesc->cipher_status = rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR);
 
 	if (rxdesc->cipher != CIPHER_NONE) {
 		_rt2x00_desc_read(entry_priv->desc, 2, &rxdesc->iv[0]);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 1399c18..6acba62 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1644,12 +1644,8 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
 	if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
 		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
 
-	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
-		rxdesc->cipher =
-		    rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG);
-		rxdesc->cipher_status =
-		    rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR);
-	}
+	rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG);
+	rxdesc->cipher_status = rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR);
 
 	if (rxdesc->cipher != CIPHER_NONE) {
 		_rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]);
-- 
1.7.1


^ permalink raw reply related

* [PATCH 6/9] rt2x00: Clean up generic procedures on descriptor writing.
From: Gertjan van Wingerde @ 2010-05-08 21:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273354826-4335-1-git-send-email-gwingerde@gmail.com>

With a little bit of restructuring it isn't necessary to have special
cases in rt2x00queue_write_tx_descriptor for writing the descriptor
for beacons.
Simply split off the kicking of the TX queue to a separate function
with is only called for non-beacons.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00queue.c |   16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 59d9459..8768c6f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -428,20 +428,23 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
 	 * it is now ready to be dumped to userspace through debugfs.
 	 */
 	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb);
+}
+
+static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
+				      struct txentry_desc *txdesc)
+{
+	struct data_queue *queue = entry->queue;
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
 
 	/*
 	 * Check if we need to kick the queue, there are however a few rules
-	 *	1) Don't kick beacon queue
-	 *	2) Don't kick unless this is the last in frame in a burst.
+	 *	1) Don't kick unless this is the last in frame in a burst.
 	 *	   When the burst flag is set, this frame is always followed
 	 *	   by another frame which in some way are related to eachother.
 	 *	   This is true for fragments, RTS or CTS-to-self frames.
-	 *	3) Rule 2 can be broken when the available entries
+	 *	2) Rule 2 can be broken when the available entries
 	 *	   in the queue are less then a certain threshold.
 	 */
-	if (entry->queue->qid == QID_BEACON)
-		return;
-
 	if (rt2x00queue_threshold(queue) ||
 	    !test_bit(ENTRY_TXD_BURST, &txdesc->flags))
 		rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
@@ -537,6 +540,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
 
 	rt2x00queue_index_inc(queue, Q_INDEX);
 	rt2x00queue_write_tx_descriptor(entry, &txdesc);
+	rt2x00queue_kick_tx_queue(entry, &txdesc);
 
 	return 0;
 }
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/9] rt2x00: Cleanups and fixes.
From: Gertjan van Wingerde @ 2010-05-08 21:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde

Some assorted cleanups and fixes for rt2x00.
First patch fixes the rt61pci security issues reported by Pavel Roskin.
The remaining patches clean up the code and work towards the final patch
which fixes beaconing on rt2800.

Gertjan van Wingerde (9):
  rt2x00: Fix setting of txdesc->length field.
  rt2x00: Clean up rt2800usb.h.
  rt2x00: Don't check whether hardware crypto is enabled when reading
    RXD.
  rt2x00: Factor out TXWI writing to common rt2800 code.
  rt2x00: Factor out RXWI processing to common rt2800 code.
  rt2x00: Clean up generic procedures on descriptor writing.
  rt2x00: Clean up all driver's kick_tx_queue callback functions.
  rt2x00: provide beacon's txdesc to write_beacon callback function.
  rt2x00: Fix beaconing on rt2800.

 drivers/net/wireless/rt2x00/rt2400pci.c    |   22 ++--
 drivers/net/wireless/rt2x00/rt2500pci.c    |   22 ++--
 drivers/net/wireless/rt2x00/rt2500usb.c    |   66 ++++------
 drivers/net/wireless/rt2x00/rt2800lib.c    |   98 +++++++++++++++
 drivers/net/wireless/rt2x00/rt2800lib.h    |    3 +
 drivers/net/wireless/rt2x00/rt2800pci.c    |  166 ++++++--------------------
 drivers/net/wireless/rt2x00/rt2800usb.c    |  180 +++++++---------------------
 drivers/net/wireless/rt2x00/rt2800usb.h    |   40 ------
 drivers/net/wireless/rt2x00/rt2x00.h       |    3 +-
 drivers/net/wireless/rt2x00/rt2x00crypto.c |    1 +
 drivers/net/wireless/rt2x00/rt2x00queue.c  |   23 ++--
 drivers/net/wireless/rt2x00/rt61pci.c      |   41 +++----
 drivers/net/wireless/rt2x00/rt73usb.c      |   51 +++-----
 13 files changed, 280 insertions(+), 436 deletions(-)


^ permalink raw reply

* [PATCH 1/9] rt2x00: Fix setting of txdesc->length field.
From: Gertjan van Wingerde @ 2010-05-08 21:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273354826-4335-1-git-send-email-gwingerde@gmail.com>

We should take the stripping of the IV into account for the txdesc->length
field.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00crypto.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index d291c78..583dacd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -128,6 +128,7 @@ void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
 
 	/* Pull buffer to correct size */
 	skb_pull(skb, txdesc->iv_len);
+	txdesc->length -= txdesc->iv_len;
 
 	/* IV/EIV data has officially been stripped */
 	skbdesc->flags |= SKBDESC_IV_STRIPPED;
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/9] rt2x00: Clean up rt2800usb.h.
From: Gertjan van Wingerde @ 2010-05-08 21:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273354826-4335-1-git-send-email-gwingerde@gmail.com>

Remove unused RXD_DESC_SIZE define and remove duplicated RXWI definitions
from rt2800.h.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800usb.h |   40 -------------------------------
 1 files changed, 0 insertions(+), 40 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index d1d8ae9..2bca6a7 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -79,8 +79,6 @@
  */
 #define TXINFO_DESC_SIZE		( 1 * sizeof(__le32) )
 #define RXINFO_DESC_SIZE		( 1 * sizeof(__le32) )
-#define RXWI_DESC_SIZE			( 4 * sizeof(__le32) )
-#define RXD_DESC_SIZE			( 1 * sizeof(__le32) )
 
 /*
  * TX Info structure
@@ -113,44 +111,6 @@
 #define RXINFO_W0_USB_DMA_RX_PKT_LEN	FIELD32(0x0000ffff)
 
 /*
- * RX WI structure
- */
-
-/*
- * Word0
- */
-#define RXWI_W0_WIRELESS_CLI_ID		FIELD32(0x000000ff)
-#define RXWI_W0_KEY_INDEX		FIELD32(0x00000300)
-#define RXWI_W0_BSSID			FIELD32(0x00001c00)
-#define RXWI_W0_UDF			FIELD32(0x0000e000)
-#define RXWI_W0_MPDU_TOTAL_BYTE_COUNT	FIELD32(0x0fff0000)
-#define RXWI_W0_TID			FIELD32(0xf0000000)
-
-/*
- * Word1
- */
-#define RXWI_W1_FRAG			FIELD32(0x0000000f)
-#define RXWI_W1_SEQUENCE		FIELD32(0x0000fff0)
-#define RXWI_W1_MCS			FIELD32(0x007f0000)
-#define RXWI_W1_BW			FIELD32(0x00800000)
-#define RXWI_W1_SHORT_GI		FIELD32(0x01000000)
-#define RXWI_W1_STBC			FIELD32(0x06000000)
-#define RXWI_W1_PHYMODE			FIELD32(0xc0000000)
-
-/*
- * Word2
- */
-#define RXWI_W2_RSSI0			FIELD32(0x000000ff)
-#define RXWI_W2_RSSI1			FIELD32(0x0000ff00)
-#define RXWI_W2_RSSI2			FIELD32(0x00ff0000)
-
-/*
- * Word3
- */
-#define RXWI_W3_SNR0			FIELD32(0x000000ff)
-#define RXWI_W3_SNR1			FIELD32(0x0000ff00)
-
-/*
  * RX descriptor format for RX Ring.
  */
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 8/9] rt2x00: provide beacon's txdesc to write_beacon callback function.
From: Gertjan van Wingerde @ 2010-05-08 21:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273354826-4335-1-git-send-email-gwingerde@gmail.com>

Preparation to fix rt2800 beaconing.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2400pci.c   |    3 ++-
 drivers/net/wireless/rt2x00/rt2500pci.c   |    3 ++-
 drivers/net/wireless/rt2x00/rt2500usb.c   |    3 ++-
 drivers/net/wireless/rt2x00/rt2800pci.c   |    3 ++-
 drivers/net/wireless/rt2x00/rt2800usb.c   |    3 ++-
 drivers/net/wireless/rt2x00/rt2x00.h      |    3 ++-
 drivers/net/wireless/rt2x00/rt2x00queue.c |    2 +-
 drivers/net/wireless/rt2x00/rt61pci.c     |    3 ++-
 drivers/net/wireless/rt2x00/rt73usb.c     |    3 ++-
 9 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 9c13a4e..4b38451 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1059,7 +1059,8 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 /*
  * TX data initialization
  */
-static void rt2400pci_write_beacon(struct queue_entry *entry)
+static void rt2400pci_write_beacon(struct queue_entry *entry,
+				   struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 84ab56e..d876c6d 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1216,7 +1216,8 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 /*
  * TX data initialization
  */
-static void rt2500pci_write_beacon(struct queue_entry *entry)
+static void rt2500pci_write_beacon(struct queue_entry *entry,
+				   struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 5ee9b9f..30c0544 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1082,7 +1082,8 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
  */
 static void rt2500usb_beacondone(struct urb *urb);
 
-static void rt2500usb_write_beacon(struct queue_entry *entry)
+static void rt2500usb_write_beacon(struct queue_entry *entry,
+				   struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 6d56460..80c6768 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -678,7 +678,8 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 /*
  * TX data initialization
  */
-static void rt2800pci_write_beacon(struct queue_entry *entry)
+static void rt2800pci_write_beacon(struct queue_entry *entry,
+				   struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index dbec718..d992a93 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -427,7 +427,8 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 /*
  * TX data initialization
  */
-static void rt2800usb_write_beacon(struct queue_entry *entry)
+static void rt2800usb_write_beacon(struct queue_entry *entry,
+				   struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 4f9b666..6c1ff4c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -551,7 +551,8 @@ struct rt2x00lib_ops {
 			       struct txentry_desc *txdesc);
 	int (*write_tx_data) (struct queue_entry *entry,
 			      struct txentry_desc *txdesc);
-	void (*write_beacon) (struct queue_entry *entry);
+	void (*write_beacon) (struct queue_entry *entry,
+			      struct txentry_desc *txdesc);
 	int (*get_tx_data_len) (struct queue_entry *entry);
 	void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
 			       const enum data_queue_qid queue);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 7ab4fbb..47f127c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -608,7 +608,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Send beacon to hardware and enable beacon genaration..
 	 */
-	rt2x00dev->ops->lib->write_beacon(intf->beacon);
+	rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc);
 
 	mutex_unlock(&intf->beacon_skb_mutex);
 
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 9e3a1ee..2436363 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1842,7 +1842,8 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 /*
  * TX data initialization
  */
-static void rt61pci_write_beacon(struct queue_entry *entry)
+static void rt61pci_write_beacon(struct queue_entry *entry,
+				 struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index ca3707a..81f6db1 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1504,7 +1504,8 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 /*
  * TX data initialization
  */
-static void rt73usb_write_beacon(struct queue_entry *entry)
+static void rt73usb_write_beacon(struct queue_entry *entry,
+				 struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
-- 
1.7.1


^ permalink raw reply related

* [PATCH 7/9] rt2x00: Clean up all driver's kick_tx_queue callback functions.
From: Gertjan van Wingerde @ 2010-05-08 21:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273354826-4335-1-git-send-email-gwingerde@gmail.com>

All of the driver's kick_tx_queue callback functions treat the TX queue
for beacons in a special manner.
Clean this up by integrating the kicking of the beacon queue into the
write_beacon callback function, and let the generic code no longer call
the kick_tx_queue callback function when updating the beacon.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2400pci.c   |   19 ++++------
 drivers/net/wireless/rt2x00/rt2500pci.c   |   19 ++++------
 drivers/net/wireless/rt2x00/rt2500usb.c   |   55 +++++++++++-----------------
 drivers/net/wireless/rt2x00/rt2800pci.c   |   20 ++++------
 drivers/net/wireless/rt2x00/rt2800usb.c   |   29 +++++----------
 drivers/net/wireless/rt2x00/rt2x00queue.c |    5 +--
 drivers/net/wireless/rt2x00/rt61pci.c     |   30 +++++++---------
 drivers/net/wireless/rt2x00/rt73usb.c     |   40 +++++++-------------
 8 files changed, 83 insertions(+), 134 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 6f89891..9c13a4e 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1089,6 +1089,14 @@ static void rt2400pci_write_beacon(struct queue_entry *entry)
 	rt2x00_desc_read(entry_priv->desc, 1, &word);
 	rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
 	rt2x00_desc_write(entry_priv->desc, 1, word);
+
+	/*
+	 * Enable beaconing again.
+	 */
+	rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
+	rt2x00_set_field32(&reg, CSR14_TBCN, 1);
+	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
+	rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 }
 
 static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
@@ -1096,17 +1104,6 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 {
 	u32 reg;
 
-	if (queue == QID_BEACON) {
-		rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
-		if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
-			rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
-			rt2x00_set_field32(&reg, CSR14_TBCN, 1);
-			rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
-			rt2x00pci_register_write(rt2x00dev, CSR14, reg);
-		}
-		return;
-	}
-
 	rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 	rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
 	rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index d9b6304..84ab56e 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1246,6 +1246,14 @@ static void rt2500pci_write_beacon(struct queue_entry *entry)
 	rt2x00_desc_read(entry_priv->desc, 1, &word);
 	rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
 	rt2x00_desc_write(entry_priv->desc, 1, word);
+
+	/*
+	 * Enable beaconing again.
+	 */
+	rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
+	rt2x00_set_field32(&reg, CSR14_TBCN, 1);
+	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
+	rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 }
 
 static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
@@ -1253,17 +1261,6 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 {
 	u32 reg;
 
-	if (queue == QID_BEACON) {
-		rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
-		if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
-			rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
-			rt2x00_set_field32(&reg, CSR14_TBCN, 1);
-			rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
-			rt2x00pci_register_write(rt2x00dev, CSR14, reg);
-		}
-		return;
-	}
-
 	rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
 	rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
 	rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index f90b308..5ee9b9f 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1090,7 +1090,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 	int pipe = usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint);
 	int length;
-	u16 reg;
+	u16 reg, reg0;
 
 	/*
 	 * Add the descriptor in front of the skb.
@@ -1132,6 +1132,26 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
 	 * Send out the guardian byte.
 	 */
 	usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC);
+
+	/*
+	 * Enable beaconing again.
+	 */
+	rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
+	rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
+	reg0 = reg;
+	rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);
+	/*
+	 * Beacon generation will fail initially.
+	 * To prevent this we need to change the TXRX_CSR19
+	 * register several times (reg0 is the same as reg
+	 * except for TXRX_CSR19_BEACON_GEN, which is 0 in reg0
+	 * and 1 in reg).
+	 */
+	rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
+	rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
+	rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
+	rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
+	rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
 }
 
 static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
@@ -1148,37 +1168,6 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
 	return length;
 }
 
-static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
-				    const enum data_queue_qid queue)
-{
-	u16 reg, reg0;
-
-	if (queue != QID_BEACON) {
-		rt2x00usb_kick_tx_queue(rt2x00dev, queue);
-		return;
-	}
-
-	rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
-	if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) {
-		rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
-		rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
-		reg0 = reg;
-		rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);
-		/*
-		 * Beacon generation will fail initially.
-		 * To prevent this we need to change the TXRX_CSR19
-		 * register several times (reg0 is the same as reg
-		 * except for TXRX_CSR19_BEACON_GEN, which is 0 in reg0
-		 * and 1 in reg).
-		 */
-		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
-		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
-		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
-		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
-		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
-	}
-}
-
 /*
  * RX control handlers
  */
@@ -1777,7 +1766,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
 	.write_tx_data		= rt2x00usb_write_tx_data,
 	.write_beacon		= rt2500usb_write_beacon,
 	.get_tx_data_len	= rt2500usb_get_tx_data_len,
-	.kick_tx_queue		= rt2500usb_kick_tx_queue,
+	.kick_tx_queue		= rt2x00usb_kick_tx_queue,
 	.kill_tx_queue		= rt2x00usb_kill_tx_queue,
 	.fill_rxdone		= rt2500usb_fill_rxdone,
 	.config_shared_key	= rt2500usb_config_key,
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 308842a..6d56460 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -705,6 +705,14 @@ static void rt2800pci_write_beacon(struct queue_entry *entry)
 				      entry->skb->data, entry->skb->len);
 
 	/*
+	 * Enable beaconing again.
+	 */
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
+	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+	/*
 	 * Clean up beacon skb.
 	 */
 	dev_kfree_skb_any(entry->skb);
@@ -716,18 +724,6 @@ static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 {
 	struct data_queue *queue;
 	unsigned int idx, qidx = 0;
-	u32 reg;
-
-	if (queue_idx == QID_BEACON) {
-		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
-		if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
-			rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
-			rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
-			rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
-			rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-		}
-		return;
-	}
 
 	if (queue_idx > QID_HCCA && queue_idx != QID_MGMT)
 		return;
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index db37119..dbec718 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -459,6 +459,14 @@ static void rt2800usb_write_beacon(struct queue_entry *entry)
 					    REGISTER_TIMEOUT32(entry->skb->len));
 
 	/*
+	 * Enable beaconing again.
+	 */
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
+	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+	/*
 	 * Clean up the beacon skb.
 	 */
 	dev_kfree_skb(entry->skb);
@@ -480,25 +488,6 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
 	return length;
 }
 
-static void rt2800usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
-				    const enum data_queue_qid queue)
-{
-	u32 reg;
-
-	if (queue != QID_BEACON) {
-		rt2x00usb_kick_tx_queue(rt2x00dev, queue);
-		return;
-	}
-
-	rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
-	if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
-		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-	}
-}
-
 /*
  * RX control handlers
  */
@@ -667,7 +656,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
 	.write_tx_data		= rt2x00usb_write_tx_data,
 	.write_beacon		= rt2800usb_write_beacon,
 	.get_tx_data_len	= rt2800usb_get_tx_data_len,
-	.kick_tx_queue		= rt2800usb_kick_tx_queue,
+	.kick_tx_queue		= rt2x00usb_kick_tx_queue,
 	.kill_tx_queue		= rt2x00usb_kill_tx_queue,
 	.fill_rxdone		= rt2800usb_fill_rxdone,
 	.config_shared_key	= rt2800_config_shared_key,
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 8768c6f..7ab4fbb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -606,12 +606,9 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
 	rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
 
 	/*
-	 * Send beacon to hardware.
-	 * Also enable beacon generation, which might have been disabled
-	 * by the driver during the config_beacon() callback function.
+	 * Send beacon to hardware and enable beacon genaration..
 	 */
 	rt2x00dev->ops->lib->write_beacon(intf->beacon);
-	rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
 
 	mutex_unlock(&intf->beacon_skb_mutex);
 
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 1b0c70d..9e3a1ee 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1869,6 +1869,19 @@ static void rt61pci_write_beacon(struct queue_entry *entry)
 				      entry->skb->data, entry->skb->len);
 
 	/*
+	 * Enable beaconing again.
+	 *
+	 * For Wi-Fi faily generated beacons between participating
+	 * stations. Set TBTT phase adaptive adjustment step to 8us.
+	 */
+	rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
+
+	rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
+	rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+
+	/*
 	 * Clean up beacon skb.
 	 */
 	dev_kfree_skb_any(entry->skb);
@@ -1880,23 +1893,6 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 {
 	u32 reg;
 
-	if (queue == QID_BEACON) {
-		/*
-		 * For Wi-Fi faily generated beacons between participating
-		 * stations. Set TBTT phase adaptive adjustment step to 8us.
-		 */
-		rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
-
-		rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
-		if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
-			rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
-			rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
-			rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
-			rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
-		}
-		return;
-	}
-
 	rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
 	rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE));
 	rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK));
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 6acba62..ca3707a 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1536,6 +1536,19 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
 					    REGISTER_TIMEOUT32(entry->skb->len));
 
 	/*
+	 * Enable beaconing again.
+	 *
+	 * For Wi-Fi faily generated beacons between participating stations.
+	 * Set TBTT phase adaptive adjustment step to 8us (default 16us)
+	 */
+	rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
+
+	rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
+	rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+
+	/*
 	 * Clean up the beacon skb.
 	 */
 	dev_kfree_skb(entry->skb);
@@ -1556,31 +1569,6 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry)
 	return length;
 }
 
-static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
-				  const enum data_queue_qid queue)
-{
-	u32 reg;
-
-	if (queue != QID_BEACON) {
-		rt2x00usb_kick_tx_queue(rt2x00dev, queue);
-		return;
-	}
-
-	/*
-	 * For Wi-Fi faily generated beacons between participating stations.
-	 * Set TBTT phase adaptive adjustment step to 8us (default 16us)
-	 */
-	rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
-
-	rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
-	if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
-		rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
-		rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
-		rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
-		rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
-	}
-}
-
 /*
  * RX control handlers
  */
@@ -2261,7 +2249,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
 	.write_tx_data		= rt2x00usb_write_tx_data,
 	.write_beacon		= rt73usb_write_beacon,
 	.get_tx_data_len	= rt73usb_get_tx_data_len,
-	.kick_tx_queue		= rt73usb_kick_tx_queue,
+	.kick_tx_queue		= rt2x00usb_kick_tx_queue,
 	.kill_tx_queue		= rt2x00usb_kill_tx_queue,
 	.fill_rxdone		= rt73usb_fill_rxdone,
 	.config_shared_key	= rt73usb_config_shared_key,
-- 
1.7.1


^ permalink raw reply related

* [PATCH 5/9] rt2x00: Factor out RXWI processing to common rt2800 code.
From: Gertjan van Wingerde @ 2010-05-08 21:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273354826-4335-1-git-send-email-gwingerde@gmail.com>

RXWI processing is exactly the same for rt2800pci and rt2800usb, so
make it common code.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800lib.c |   44 ++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800lib.h |    1 +
 drivers/net/wireless/rt2x00/rt2800pci.c |   57 +++++-------------------
 drivers/net/wireless/rt2x00/rt2800usb.c |   74 ++++++++++---------------------
 4 files changed, 79 insertions(+), 97 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 28d82ce..7410ac1 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -335,6 +335,50 @@ void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc)
 }
 EXPORT_SYMBOL_GPL(rt2800_write_txwi);
 
+void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *rxdesc)
+{
+	__le32 *rxwi = (__le32 *) skb->data;
+	u32 word;
+
+	rt2x00_desc_read(rxwi, 0, &word);
+
+	rxdesc->cipher = rt2x00_get_field32(word, RXWI_W0_UDF);
+	rxdesc->size = rt2x00_get_field32(word, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
+
+	rt2x00_desc_read(rxwi, 1, &word);
+
+	if (rt2x00_get_field32(word, RXWI_W1_SHORT_GI))
+		rxdesc->flags |= RX_FLAG_SHORT_GI;
+
+	if (rt2x00_get_field32(word, RXWI_W1_BW))
+		rxdesc->flags |= RX_FLAG_40MHZ;
+
+	/*
+	 * Detect RX rate, always use MCS as signal type.
+	 */
+	rxdesc->dev_flags |= RXDONE_SIGNAL_MCS;
+	rxdesc->signal = rt2x00_get_field32(word, RXWI_W1_MCS);
+	rxdesc->rate_mode = rt2x00_get_field32(word, RXWI_W1_PHYMODE);
+
+	/*
+	 * Mask of 0x8 bit to remove the short preamble flag.
+	 */
+	if (rxdesc->rate_mode == RATE_MODE_CCK)
+		rxdesc->signal &= ~0x8;
+
+	rt2x00_desc_read(rxwi, 2, &word);
+
+	rxdesc->rssi =
+	    (rt2x00_get_field32(word, RXWI_W2_RSSI0) +
+	     rt2x00_get_field32(word, RXWI_W2_RSSI1)) / 2;
+
+	/*
+	 * Remove RXWI descriptor from start of buffer.
+	 */
+	skb_pull(skb, RXWI_DESC_SIZE);
+}
+EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
+
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 const struct rt2x00debug rt2800_rt2x00debug = {
 	.owner	= THIS_MODULE,
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index b805310..94de999 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -112,6 +112,7 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
 			const u8 arg0, const u8 arg1);
 
 void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc);
+void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc);
 
 extern const struct rt2x00debug rt2800_rt2x00debug;
 
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index bd56cd1..308842a 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -770,20 +770,11 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
 	__le32 *rxd = entry_priv->desc;
-	__le32 *rxwi = (__le32 *)entry->skb->data;
-	u32 rxd3;
-	u32 rxwi0;
-	u32 rxwi1;
-	u32 rxwi2;
-	u32 rxwi3;
-
-	rt2x00_desc_read(rxd, 3, &rxd3);
-	rt2x00_desc_read(rxwi, 0, &rxwi0);
-	rt2x00_desc_read(rxwi, 1, &rxwi1);
-	rt2x00_desc_read(rxwi, 2, &rxwi2);
-	rt2x00_desc_read(rxwi, 3, &rxwi3);
-
-	if (rt2x00_get_field32(rxd3, RXD_W3_CRC_ERROR))
+	u32 word;
+
+	rt2x00_desc_read(rxd, 3, &word);
+
+	if (rt2x00_get_field32(word, RXD_W3_CRC_ERROR))
 		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
 
 	/*
@@ -791,10 +782,9 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
 	 * decryption. This prevents us from correct providing
 	 * correct statistics through debugfs.
 	 */
-	rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
-	rxdesc->cipher_status = rt2x00_get_field32(rxd3, RXD_W3_CIPHER_ERROR);
+	rxdesc->cipher_status = rt2x00_get_field32(word, RXD_W3_CIPHER_ERROR);
 
-	if (rt2x00_get_field32(rxd3, RXD_W3_DECRYPTED)) {
+	if (rt2x00_get_field32(word, RXD_W3_DECRYPTED)) {
 		/*
 		 * Hardware has stripped IV/EIV data from 802.11 frame during
 		 * decryption. Unfortunately the descriptor doesn't contain
@@ -809,47 +799,22 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
 			rxdesc->flags |= RX_FLAG_MMIC_ERROR;
 	}
 
-	if (rt2x00_get_field32(rxd3, RXD_W3_MY_BSS))
+	if (rt2x00_get_field32(word, RXD_W3_MY_BSS))
 		rxdesc->dev_flags |= RXDONE_MY_BSS;
 
-	if (rt2x00_get_field32(rxd3, RXD_W3_L2PAD))
+	if (rt2x00_get_field32(word, RXD_W3_L2PAD))
 		rxdesc->dev_flags |= RXDONE_L2PAD;
 
-	if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
-		rxdesc->flags |= RX_FLAG_SHORT_GI;
-
-	if (rt2x00_get_field32(rxwi1, RXWI_W1_BW))
-		rxdesc->flags |= RX_FLAG_40MHZ;
-
 	/*
-	 * Detect RX rate, always use MCS as signal type.
+	 * Process the RXWI structure that is at the start of the buffer.
 	 */
-	rxdesc->dev_flags |= RXDONE_SIGNAL_MCS;
-	rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE);
-	rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS);
-
-	/*
-	 * Mask of 0x8 bit to remove the short preamble flag.
-	 */
-	if (rxdesc->rate_mode == RATE_MODE_CCK)
-		rxdesc->signal &= ~0x8;
-
-	rxdesc->rssi =
-	    (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) +
-	     rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2;
-
-	rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
+	rt2800_process_rxwi(entry->skb, rxdesc);
 
 	/*
 	 * Set RX IDX in register to inform hardware that we have handled
 	 * this entry and it is available for reuse again.
 	 */
 	rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx);
-
-	/*
-	 * Remove TXWI descriptor from start of buffer.
-	 */
-	skb_pull(entry->skb, RXWI_DESC_SIZE);
 }
 
 /*
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index b39b858..db37119 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -507,53 +507,45 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 {
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 	__le32 *rxi = (__le32 *)entry->skb->data;
-	__le32 *rxwi;
 	__le32 *rxd;
-	u32 rxi0;
-	u32 rxwi0;
-	u32 rxwi1;
-	u32 rxwi2;
-	u32 rxwi3;
-	u32 rxd0;
+	u32 word;
 	int rx_pkt_len;
 
 	/*
+	 * Copy descriptor to the skbdesc->desc buffer, making it safe from
+	 * moving of frame data in rt2x00usb.
+	 */
+	memcpy(skbdesc->desc, rxi, skbdesc->desc_len);
+
+	/*
 	 * RX frame format is :
 	 * | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad |
 	 *          |<------------ rx_pkt_len -------------->|
 	 */
-	rt2x00_desc_read(rxi, 0, &rxi0);
-	rx_pkt_len = rt2x00_get_field32(rxi0, RXINFO_W0_USB_DMA_RX_PKT_LEN);
-
-	rxwi = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE);
+	rt2x00_desc_read(rxi, 0, &word);
+	rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN);
 
 	/*
-	 * FIXME : we need to check for rx_pkt_len validity
+	 * Remove the RXINFO structure from the sbk.
 	 */
-	rxd = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE + rx_pkt_len);
+	skb_pull(entry->skb, RXINFO_DESC_SIZE);
 
 	/*
-	 * Copy descriptor to the skbdesc->desc buffer, making it safe from
-	 * moving of frame data in rt2x00usb.
+	 * FIXME: we need to check for rx_pkt_len validity
 	 */
-	memcpy(skbdesc->desc, rxi, skbdesc->desc_len);
+	rxd = (__le32 *)(entry->skb->data + rx_pkt_len);
 
 	/*
 	 * It is now safe to read the descriptor on all architectures.
 	 */
-	rt2x00_desc_read(rxwi, 0, &rxwi0);
-	rt2x00_desc_read(rxwi, 1, &rxwi1);
-	rt2x00_desc_read(rxwi, 2, &rxwi2);
-	rt2x00_desc_read(rxwi, 3, &rxwi3);
-	rt2x00_desc_read(rxd, 0, &rxd0);
+	rt2x00_desc_read(rxd, 0, &word);
 
-	if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR))
+	if (rt2x00_get_field32(word, RXD_W0_CRC_ERROR))
 		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
 
-	rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
-	rxdesc->cipher_status = rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
+	rxdesc->cipher_status = rt2x00_get_field32(word, RXD_W0_CIPHER_ERROR);
 
-	if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) {
+	if (rt2x00_get_field32(word, RXD_W0_DECRYPTED)) {
 		/*
 		 * Hardware has stripped IV/EIV data from 802.11 frame during
 		 * decryption. Unfortunately the descriptor doesn't contain
@@ -568,41 +560,21 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 			rxdesc->flags |= RX_FLAG_MMIC_ERROR;
 	}
 
-	if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
+	if (rt2x00_get_field32(word, RXD_W0_MY_BSS))
 		rxdesc->dev_flags |= RXDONE_MY_BSS;
 
-	if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD))
+	if (rt2x00_get_field32(word, RXD_W0_L2PAD))
 		rxdesc->dev_flags |= RXDONE_L2PAD;
 
-	if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
-		rxdesc->flags |= RX_FLAG_SHORT_GI;
-
-	if (rt2x00_get_field32(rxwi1, RXWI_W1_BW))
-		rxdesc->flags |= RX_FLAG_40MHZ;
-
 	/*
-	 * Detect RX rate, always use MCS as signal type.
+	 * Remove RXD descriptor from end of buffer.
 	 */
-	rxdesc->dev_flags |= RXDONE_SIGNAL_MCS;
-	rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE);
-	rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS);
-
-	/*
-	 * Mask of 0x8 bit to remove the short preamble flag.
-	 */
-	if (rxdesc->rate_mode == RATE_MODE_CCK)
-		rxdesc->signal &= ~0x8;
-
-	rxdesc->rssi =
-	    (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) +
-	     rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2;
-
-	rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
+	skb_trim(entry->skb, rx_pkt_len);
 
 	/*
-	 * Remove RXWI descriptor from start of buffer.
+	 * Process the RXWI structure.
 	 */
-	skb_pull(entry->skb, skbdesc->desc_len);
+	rt2800_process_rxwi(entry->skb, rxdesc);
 }
 
 /*
-- 
1.7.1


^ permalink raw reply related

* [PATCH 9/9] rt2x00: Fix beaconing on rt2800.
From: Gertjan van Wingerde @ 2010-05-08 21:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273354826-4335-1-git-send-email-gwingerde@gmail.com>

According to the Ralink vendor driver for rt2800 we don't need a full
TXD for a beacon but just a TXWI in front of the actual beacon.
Fix the rt2800pci and rt2800usb beaconing code accordingly.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |   17 +++++++++--------
 drivers/net/wireless/rt2x00/rt2800usb.c |   14 ++++++--------
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 80c6768..7d4778d 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -682,7 +682,6 @@ static void rt2800pci_write_beacon(struct queue_entry *entry,
 				   struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 	unsigned int beacon_base;
 	u32 reg;
 
@@ -695,15 +694,17 @@ static void rt2800pci_write_beacon(struct queue_entry *entry,
 	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 
 	/*
-	 * Write entire beacon with descriptor to register.
+	 * Add the TXWI for the beacon to the skb.
+	 */
+	rt2800_write_txwi(entry->skb, txdesc);
+	skb_push(entry->skb, TXWI_DESC_SIZE);
+
+	/*
+	 * Write entire beacon with TXWI to register.
 	 */
 	beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
-	rt2800_register_multiwrite(rt2x00dev,
-				      beacon_base,
-				      skbdesc->desc, skbdesc->desc_len);
-	rt2800_register_multiwrite(rt2x00dev,
-				      beacon_base + skbdesc->desc_len,
-				      entry->skb->data, entry->skb->len);
+	rt2800_register_multiwrite(rt2x00dev, beacon_base,
+				   entry->skb->data, entry->skb->len);
 
 	/*
 	 * Enable beaconing again.
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index d992a93..00e7906 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -431,18 +431,10 @@ static void rt2800usb_write_beacon(struct queue_entry *entry,
 				   struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 	unsigned int beacon_base;
 	u32 reg;
 
 	/*
-	 * Add the descriptor in front of the skb.
-	 */
-	skb_push(entry->skb, entry->queue->desc_size);
-	memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
-	skbdesc->desc = entry->skb->data;
-
-	/*
 	 * Disable beaconing while we are reloading the beacon data,
 	 * otherwise we might be sending out invalid data.
 	 */
@@ -451,6 +443,12 @@ static void rt2800usb_write_beacon(struct queue_entry *entry,
 	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 
 	/*
+	 * Add the TXWI for the beacon to the skb.
+	 */
+	rt2800_write_txwi(entry->skb, txdesc);
+	skb_push(entry->skb, TXWI_DESC_SIZE);
+
+	/*
 	 * Write entire beacon with descriptor to register.
 	 */
 	beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
-- 
1.7.1


^ permalink raw reply related

* [PATCH 4/9] rt2x00: Factor out TXWI writing to common rt2800 code.
From: Gertjan van Wingerde @ 2010-05-08 21:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273354826-4335-1-git-send-email-gwingerde@gmail.com>

TXWI writing is exactly the same for rt2800pci and rt2800usb, so
make it common code.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800lib.c |   54 +++++++++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800lib.h |    2 +
 drivers/net/wireless/rt2x00/rt2800pci.c |   56 +------------------------------
 drivers/net/wireless/rt2x00/rt2800usb.c |   50 ++--------------------------
 4 files changed, 60 insertions(+), 102 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 525267d..28d82ce 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -281,6 +281,60 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
 }
 EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready);
 
+void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc)
+{
+	__le32 *txwi = (__le32 *)(skb->data - TXWI_DESC_SIZE);
+	u32 word;
+
+	/*
+	 * Initialize TX Info descriptor
+	 */
+	rt2x00_desc_read(txwi, 0, &word);
+	rt2x00_set_field32(&word, TXWI_W0_FRAG,
+			   test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
+	rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
+	rt2x00_set_field32(&word, TXWI_W0_TS,
+			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W0_AMPDU,
+			   test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
+	rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->txop);
+	rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
+	rt2x00_set_field32(&word, TXWI_W0_BW,
+			   test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
+			   test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
+	rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
+	rt2x00_desc_write(txwi, 0, word);
+
+	rt2x00_desc_read(txwi, 1, &word);
+	rt2x00_set_field32(&word, TXWI_W1_ACK,
+			   test_bit(ENTRY_TXD_ACK, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W1_NSEQ,
+			   test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
+	rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
+			   test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
+			   txdesc->key_idx : 0xff);
+	rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
+			   txdesc->length);
+	rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1);
+	rt2x00_desc_write(txwi, 1, word);
+
+	/*
+	 * Always write 0 to IV/EIV fields, hardware will insert the IV
+	 * from the IVEIV register when TXD_W3_WIV is set to 0.
+	 * When TXD_W3_WIV is set to 1 it will use the IV data
+	 * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
+	 * crypto entry in the registers should be used to encrypt the frame.
+	 */
+	_rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
+	_rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
+}
+EXPORT_SYMBOL_GPL(rt2800_write_txwi);
+
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 const struct rt2x00debug rt2800_rt2x00debug = {
 	.owner	= THIS_MODULE,
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index ebabeae..b805310 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -111,6 +111,8 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
 			const u8 command, const u8 token,
 			const u8 arg0, const u8 arg1);
 
+void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc);
+
 extern const struct rt2x00debug rt2800_rt2x00debug;
 
 int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index b9ec081..bd56cd1 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -616,67 +616,13 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 static int rt2800pci_write_tx_data(struct queue_entry* entry,
 				   struct txentry_desc *txdesc)
 {
-	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-	struct sk_buff *skb = entry->skb;
-	struct skb_frame_desc *skbdesc;
 	int ret;
-	__le32 *txwi;
-	u32 word;
 
 	ret = rt2x00pci_write_tx_data(entry, txdesc);
 	if (ret)
 		return ret;
 
-	skbdesc = get_skb_frame_desc(skb);
-	txwi = (__le32 *)(skb->data - rt2x00dev->ops->extra_tx_headroom);
-
-	/*
-	 * Initialize TX Info descriptor
-	 */
-	rt2x00_desc_read(txwi, 0, &word);
-	rt2x00_set_field32(&word, TXWI_W0_FRAG,
-			   test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
-	rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
-	rt2x00_set_field32(&word, TXWI_W0_TS,
-			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W0_AMPDU,
-			   test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
-	rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->txop);
-	rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
-	rt2x00_set_field32(&word, TXWI_W0_BW,
-			   test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
-			   test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
-	rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
-	rt2x00_desc_write(txwi, 0, word);
-
-	rt2x00_desc_read(txwi, 1, &word);
-	rt2x00_set_field32(&word, TXWI_W1_ACK,
-			   test_bit(ENTRY_TXD_ACK, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W1_NSEQ,
-			   test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
-	rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
-			   test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
-			   txdesc->key_idx : 0xff);
-	rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
-			   txdesc->length);
-	rt2x00_set_field32(&word, TXWI_W1_PACKETID,
-			   skbdesc->entry->queue->qid + 1);
-	rt2x00_desc_write(txwi, 1, word);
-
-	/*
-	 * Always write 0 to IV/EIV fields, hardware will insert the IV
-	 * from the IVEIV register when TXD_W3_WIV is set to 0.
-	 * When TXD_W3_WIV is set to 1 it will use the IV data
-	 * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
-	 * crypto entry in the registers should be used to encrypt the frame.
-	 */
-	_rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
-	_rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
+	rt2800_write_txwi(entry->skb, txdesc);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index df7ad98..b39b858 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -401,59 +401,15 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 {
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
 	__le32 *txi = skbdesc->desc;
-	__le32 *txwi = &txi[TXINFO_DESC_SIZE / sizeof(__le32)];
 	u32 word;
 
 	/*
-	 * Initialize TX Info descriptor
+	 * Initialize TXWI descriptor
 	 */
-	rt2x00_desc_read(txwi, 0, &word);
-	rt2x00_set_field32(&word, TXWI_W0_FRAG,
-			   test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
-	rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
-	rt2x00_set_field32(&word, TXWI_W0_TS,
-			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W0_AMPDU,
-			   test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
-	rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->txop);
-	rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
-	rt2x00_set_field32(&word, TXWI_W0_BW,
-			   test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
-			   test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
-	rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
-	rt2x00_desc_write(txwi, 0, word);
-
-	rt2x00_desc_read(txwi, 1, &word);
-	rt2x00_set_field32(&word, TXWI_W1_ACK,
-			   test_bit(ENTRY_TXD_ACK, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W1_NSEQ,
-			   test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
-	rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
-	rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
-			   test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
-			   txdesc->key_idx : 0xff);
-	rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
-			   txdesc->length);
-	rt2x00_set_field32(&word, TXWI_W1_PACKETID,
-			   skbdesc->entry->queue->qid + 1);
-	rt2x00_desc_write(txwi, 1, word);
+	rt2800_write_txwi(skb, txdesc);
 
 	/*
-	 * Always write 0 to IV/EIV fields, hardware will insert the IV
-	 * from the IVEIV register when TXINFO_W0_WIV is set to 0.
-	 * When TXINFO_W0_WIV is set to 1 it will use the IV data
-	 * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
-	 * crypto entry in the registers should be used to encrypt the frame.
-	 */
-	_rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
-	_rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
-
-	/*
-	 * Initialize TX descriptor
+	 * Initialize TXINFO descriptor
 	 */
 	rt2x00_desc_read(txi, 0, &word);
 	rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
-- 
1.7.1


^ permalink raw reply related

* Re: [patch 6/9] ath5k: several off by one range checks
From: Bob Copeland @ 2010-05-08 22:33 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Jiri Slaby, Nick Kossifidis, Luis R. Rodriguez, John W. Linville,
	Bruno Randolf, linux-wireless, ath5k-devel
In-Reply-To: <20100508162438.GR27064@bicker>

On Sat, May 08, 2010 at 06:24:38PM +0200, Dan Carpenter wrote:
> There are several places that use > ARRAY_SIZE() instead of 
> >= ARRAY_SIZE().
> 
> Signed-off-by: Dan Carpenter <error27@gmail.com>

Thanks,
Acked-by: Bob Copeland <me@bobcopeland.com>

-- 
Bob Copeland %% www.bobcopeland.com


^ 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