linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/8] staging: vt6656: turn radio off after mac registered.
@ 2014-07-05 18:24 Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 2/8] staging: vt6656: vnt_rf_set_txpower use power for priv->byCurPwr Malcolm Priestley
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Malcolm Priestley @ 2014-07-05 18:24 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless, Malcolm Priestley

Turn the radio off to save power is the device is unused
on system.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/main_usb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 8a4695e..9d0441f 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -1074,6 +1074,8 @@ int vnt_init(struct vnt_private *priv)
 
 	priv->mac_hw = true;
 
+	vnt_radio_power_off(priv);
+
 	return 0;
 }
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/8] staging: vt6656: vnt_rf_set_txpower use power for priv->byCurPwr
  2014-07-05 18:24 [PATCH 1/8] staging: vt6656: turn radio off after mac registered Malcolm Priestley
@ 2014-07-05 18:24 ` Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 3/8] staging: vt6656: vnt_rf_setpower rate <= RATE_11M check array bound Malcolm Priestley
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Malcolm Priestley @ 2014-07-05 18:24 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless, Malcolm Priestley

The byCurPwr value can change state while in another thread,.

Change to local variable power which is the last set value.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/rf.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c
index 8c2c2bd..971f844 100644
--- a/drivers/staging/vt6656/rf.c
+++ b/drivers/staging/vt6656/rf.c
@@ -821,11 +821,10 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
 
 	switch (priv->byRFType) {
 	case RF_AL2230:
-		if (priv->byCurPwr >= AL2230_PWR_IDX_LEN)
+		if (power >= AL2230_PWR_IDX_LEN)
 			return false;
 
-		ret &= vnt_rf_write_embedded(priv,
-			al2230_power_table[priv->byCurPwr]);
+		ret &= vnt_rf_write_embedded(priv, al2230_power_table[power]);
 
 		if (rate <= RATE_11M)
 			ret &= vnt_rf_write_embedded(priv, 0x0001b400 +
@@ -835,11 +834,10 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
 				(BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
 		break;
 	case RF_AL2230S:
-		if (priv->byCurPwr >= AL2230_PWR_IDX_LEN)
+		if (power >= AL2230_PWR_IDX_LEN)
 			return false;
 
-		ret &= vnt_rf_write_embedded(priv,
-			al2230_power_table[priv->byCurPwr]);
+		ret &= vnt_rf_write_embedded(priv, al2230_power_table[power]);
 
 		if (rate <= RATE_11M) {
 			ret &= vnt_rf_write_embedded(priv, 0x040c1400 +
@@ -862,14 +860,14 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
 			ret &= vnt_rf_write_embedded(priv, 0x221bb900 +
 				(BY_AL7230_REG_LEN << 3)+IFREGCTL_REGW);
 
-		if (priv->byCurPwr > AL7230_PWR_IDX_LEN)
+		if (power >= AL7230_PWR_IDX_LEN)
 			return false;
 
 		/*
 		* 0x080F1B00 for 3 wire control TxGain(D10)
 		* and 0x31 as TX Gain value
 		*/
-		power_setting = 0x080c0b00 | ((priv->byCurPwr) << 12) |
+		power_setting = 0x080c0b00 | (power << 12) |
 				(BY_AL7230_REG_LEN << 3) | IFREGCTL_REGW;
 
 		ret &= vnt_rf_write_embedded(priv, power_setting);
@@ -877,22 +875,22 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
 		break;
 
 	case RF_VT3226:
-		if (priv->byCurPwr >= VT3226_PWR_IDX_LEN)
+		if (power >= VT3226_PWR_IDX_LEN)
 			return false;
-		power_setting = ((0x3f - priv->byCurPwr) << 20) | (0x17 << 8) |
+		power_setting = ((0x3f - power) << 20) | (0x17 << 8) |
 				(BY_VT3226_REG_LEN << 3) | IFREGCTL_REGW;
 
 		ret &= vnt_rf_write_embedded(priv, power_setting);
 
 		break;
 	case RF_VT3226D0:
-		if (priv->byCurPwr >= VT3226_PWR_IDX_LEN)
+		if (power >= VT3226_PWR_IDX_LEN)
 			return false;
 
 		if (rate <= RATE_11M) {
 			u16 hw_value = priv->hw->conf.chandef.chan->hw_value;
 
-			power_setting = ((0x3f-priv->byCurPwr) << 20) |
+			power_setting = ((0x3f - power) << 20) |
 				(0xe07 << 8) | (BY_VT3226_REG_LEN << 3) |
 						IFREGCTL_REGW;
 
@@ -915,7 +913,7 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
 			dev_dbg(&priv->usb->dev,
 					"@@@@ vnt_rf_set_txpower> 11G mode\n");
 
-			power_setting = ((0x3f-priv->byCurPwr) << 20) |
+			power_setting = ((0x3f - power) << 20) |
 				(0x7 << 8) | (BY_VT3226_REG_LEN << 3) |
 					IFREGCTL_REGW;
 
@@ -930,10 +928,10 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
 		break;
 
 	case RF_VT3342A0:
-		if (priv->byCurPwr >= VT3342_PWR_IDX_LEN)
+		if (power >= VT3342_PWR_IDX_LEN)
 			return false;
 
-		power_setting =  ((0x3F-priv->byCurPwr) << 20) |
+		power_setting =  ((0x3f - power) << 20) |
 			(0x27 << 8) | (BY_VT3342_REG_LEN << 3) |
 					IFREGCTL_REGW;
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/8] staging: vt6656: vnt_rf_setpower rate <= RATE_11M check array bound
  2014-07-05 18:24 [PATCH 1/8] staging: vt6656: turn radio off after mac registered Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 2/8] staging: vt6656: vnt_rf_set_txpower use power for priv->byCurPwr Malcolm Priestley
@ 2014-07-05 18:24 ` Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 4/8] staging: vt6656: vnt_tx_packet don't change power when off channel Malcolm Priestley
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Malcolm Priestley @ 2014-07-05 18:24 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless, Malcolm Priestley

decrement channel by one and check array bound.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/rf.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c
index 971f844..4124131 100644
--- a/drivers/staging/vt6656/rf.c
+++ b/drivers/staging/vt6656/rf.c
@@ -744,7 +744,10 @@ int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel)
 	case RATE_2M:
 	case RATE_5M:
 	case RATE_11M:
-		power = priv->abyCCKPwrTbl[channel-1];
+		channel--;
+
+		if (channel < sizeof(priv->abyCCKPwrTbl))
+			power = priv->abyCCKPwrTbl[channel];
 		break;
 	case RATE_6M:
 	case RATE_9M:
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/8] staging: vt6656: vnt_tx_packet don't change power when off channel.
  2014-07-05 18:24 [PATCH 1/8] staging: vt6656: turn radio off after mac registered Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 2/8] staging: vt6656: vnt_rf_set_txpower use power for priv->byCurPwr Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 3/8] staging: vt6656: vnt_rf_setpower rate <= RATE_11M check array bound Malcolm Priestley
@ 2014-07-05 18:24 ` Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 5/8] staging: vt6656: vnt_rx_data add track rsr and new_rsr errors Malcolm Priestley
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Malcolm Priestley @ 2014-07-05 18:24 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless, Malcolm Priestley

The changing channel is so fast when off channel that changing power is pointless.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/rxtx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index e896dfe5d..95b6cf3 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -900,7 +900,8 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
 	rate = ieee80211_get_tx_rate(priv->hw, info);
 
 	current_rate = rate->hw_value;
-	if (priv->wCurrentRate != current_rate) {
+	if (priv->wCurrentRate != current_rate &&
+			!(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
 		priv->wCurrentRate = current_rate;
 		bScheduleCommand(priv, WLAN_CMD_SETPOWER, NULL);
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/8] staging: vt6656: vnt_rx_data add track rsr and new_rsr errors
  2014-07-05 18:24 [PATCH 1/8] staging: vt6656: turn radio off after mac registered Malcolm Priestley
                   ` (2 preceding siblings ...)
  2014-07-05 18:24 ` [PATCH 4/8] staging: vt6656: vnt_tx_packet don't change power when off channel Malcolm Priestley
@ 2014-07-05 18:24 ` Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 6/8] staging: vt6656: vnt_set_channel remove power setting functions Malcolm Priestley
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Malcolm Priestley @ 2014-07-05 18:24 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless, Malcolm Priestley

Add rsr and new_rsr error packet error drop.

if NEWRSR_DECRYPTOK fails drop packet altogether.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/dpc.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
index ca55554..f3da0db 100644
--- a/drivers/staging/vt6656/dpc.c
+++ b/drivers/staging/vt6656/dpc.c
@@ -143,7 +143,10 @@ int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
 
 	new_rsr = skb_data + 8 + pay_load_with_padding + 9;
 	rssi = skb_data + 8 + pay_load_with_padding + 10;
+
 	rsr = skb_data + 8 + pay_load_with_padding + 11;
+	if (*rsr & (RSR_IVLDTYP | RSR_IVLDLEN))
+		return false;
 
 	frame_size = *pay_load_len;
 
@@ -163,14 +166,24 @@ int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
 	rx_status.flag = 0;
 	rx_status.freq = hw->conf.chandef.chan->center_freq;
 
+	if (!(*rsr & RSR_CRCOK))
+		rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
+
 	hdr = (struct ieee80211_hdr *)(skb->data);
 	fc = hdr->frame_control;
 
 	rx_status.rate_idx = rate_idx;
 
 	if (ieee80211_has_protected(fc)) {
-		if (priv->byLocalID > REV_ID_VT3253_A1)
-			rx_status.flag = RX_FLAG_DECRYPTED;
+		if (priv->byLocalID > REV_ID_VT3253_A1) {
+			rx_status.flag |= RX_FLAG_DECRYPTED;
+
+			/* Drop packet */
+			if (!(*new_rsr & NEWRSR_DECRYPTOK)) {
+				dev_kfree_skb(skb);
+				return true;
+			}
+		}
 	}
 
 	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/8] staging: vt6656: vnt_set_channel remove power setting functions
  2014-07-05 18:24 [PATCH 1/8] staging: vt6656: turn radio off after mac registered Malcolm Priestley
                   ` (3 preceding siblings ...)
  2014-07-05 18:24 ` [PATCH 5/8] staging: vt6656: vnt_rx_data add track rsr and new_rsr errors Malcolm Priestley
@ 2014-07-05 18:24 ` Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 7/8] staging: vt6656: Include re_alloc_skb within lock Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 8/8] stagingL vt6656: implement fall back rates reporting Malcolm Priestley
  6 siblings, 0 replies; 8+ messages in thread
From: Malcolm Priestley @ 2014-07-05 18:24 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless, Malcolm Priestley

Power setting is already done in vnt_config and vnt_tx_packet.

Just check that for connection_channel, if invalid return.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/card.c | 25 ++-----------------------
 1 file changed, 2 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
index 1849e34..a5f8df1 100644
--- a/drivers/staging/vt6656/card.c
+++ b/drivers/staging/vt6656/card.c
@@ -74,15 +74,8 @@ static const u16 cwRXBCNTSFOff[MAX_RATE] =
 void vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
 {
 
-	if (priv->byBBType == BB_TYPE_11A) {
-		if ((connection_channel < (CB_MAX_CHANNEL_24G + 1)) ||
-					(connection_channel > CB_MAX_CHANNEL))
-			connection_channel = (CB_MAX_CHANNEL_24G + 1);
-	} else {
-		if ((connection_channel > CB_MAX_CHANNEL_24G) ||
-						(connection_channel == 0))
-			connection_channel = 1;
-	}
+	if (connection_channel > CB_MAX_CHANNEL || !connection_channel)
+		return;
 
 	/* clear NAV */
 	vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV);
@@ -93,20 +86,6 @@ void vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
 	vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNLE,
 					connection_channel, 0, 0, NULL);
 
-	if (priv->byBBType == BB_TYPE_11A) {
-		priv->byCurPwr = 0xff;
-		vnt_rf_set_txpower(priv,
-			priv->abyOFDMAPwrTbl[connection_channel-15], RATE_54M);
-	} else if (priv->byBBType == BB_TYPE_11G) {
-		priv->byCurPwr = 0xff;
-		vnt_rf_set_txpower(priv,
-			priv->abyOFDMPwrTbl[connection_channel-1], RATE_54M);
-	} else {
-		priv->byCurPwr = 0xff;
-		vnt_rf_set_txpower(priv,
-			priv->abyCCKPwrTbl[connection_channel-1], RATE_1M);
-	}
-
 	vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
 		(u8)(connection_channel|0x80));
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 7/8] staging: vt6656: Include re_alloc_skb within lock.
  2014-07-05 18:24 [PATCH 1/8] staging: vt6656: turn radio off after mac registered Malcolm Priestley
                   ` (4 preceding siblings ...)
  2014-07-05 18:24 ` [PATCH 6/8] staging: vt6656: vnt_set_channel remove power setting functions Malcolm Priestley
@ 2014-07-05 18:24 ` Malcolm Priestley
  2014-07-05 18:24 ` [PATCH 8/8] stagingL vt6656: implement fall back rates reporting Malcolm Priestley
  6 siblings, 0 replies; 8+ messages in thread
From: Malcolm Priestley @ 2014-07-05 18:24 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless, Malcolm Priestley

Remove variable re_alloc_skb and merge code within urb->actual_length.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/usbpipe.c | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index c5d4047..a7af4f58 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -276,7 +276,6 @@ static void s_nsBulkInUsbIoCompleteRead(struct urb *urb)
 	struct vnt_rcb *rcb = urb->context;
 	struct vnt_private *priv = rcb->pDevice;
 	unsigned long flags;
-	int re_alloc_skb = false;
 
 	switch (urb->status) {
 	case 0:
@@ -294,24 +293,22 @@ static void s_nsBulkInUsbIoCompleteRead(struct urb *urb)
 	if (urb->actual_length) {
 		spin_lock_irqsave(&priv->lock, flags);
 
-		if (vnt_rx_data(priv, rcb, urb->actual_length))
-			re_alloc_skb = true;
+		if (vnt_rx_data(priv, rcb, urb->actual_length)) {
+			rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
+			if (!rcb->skb) {
+				dev_dbg(&priv->usb->dev,
+					"Failed to re-alloc rx skb\n");
 
-		spin_unlock_irqrestore(&priv->lock, flags);
-	}
-
-	if (re_alloc_skb) {
-		rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
-		if (!rcb->skb) {
-			dev_dbg(&priv->usb->dev, "Failed to re-alloc rx skb\n");
-
-			rcb->bBoolInUse = false;
-
-			return;
+				rcb->bBoolInUse = false;
+				spin_unlock_irqrestore(&priv->lock, flags);
+				return;
+			}
 		}
 
 		urb->transfer_buffer = skb_put(rcb->skb,
 						skb_tailroom(rcb->skb));
+
+		spin_unlock_irqrestore(&priv->lock, flags);
 	}
 
 	if (usb_submit_urb(urb, GFP_ATOMIC)) {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 8/8] stagingL vt6656: implement fall back rates reporting.
  2014-07-05 18:24 [PATCH 1/8] staging: vt6656: turn radio off after mac registered Malcolm Priestley
                   ` (5 preceding siblings ...)
  2014-07-05 18:24 ` [PATCH 7/8] staging: vt6656: Include re_alloc_skb within lock Malcolm Priestley
@ 2014-07-05 18:24 ` Malcolm Priestley
  6 siblings, 0 replies; 8+ messages in thread
From: Malcolm Priestley @ 2014-07-05 18:24 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless, Malcolm Priestley

The driver reports the rate tried in struct vnt_interrupt_data tsr* variables
which is available in INTnsProcessData via interrupt urb context.

Instead of closing apTD tx context in s_nsBulkOutIoCompleteWrite by setting
in_use to false. Keep the context open and allow vnt_int_report_rate to
close it.

If the tx_retry value is correct it will report back the sucessful RATE tried.

struct vnt_usb_send_context add pkt_no which is index of apTD

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/device.h   |   2 +
 drivers/staging/vt6656/int.c      | 104 +++++++++++++++++++++++++++++---------
 drivers/staging/vt6656/main_usb.c |   1 +
 drivers/staging/vt6656/rxtx.c     |   8 +--
 drivers/staging/vt6656/usbpipe.c  |  23 +++------
 5 files changed, 93 insertions(+), 45 deletions(-)

diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 4d1eb22..789c55d 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -246,6 +246,8 @@ struct vnt_usb_send_context {
 	unsigned int buf_len;
 	u16 tx_hdr_size;
 	u8 type;
+	u8 pkt_no;
+	u8 fb_option;
 	bool in_use;
 	unsigned char data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS];
 };
diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c
index 1913b73..1cc9364 100644
--- a/drivers/staging/vt6656/int.c
+++ b/drivers/staging/vt6656/int.c
@@ -39,6 +39,22 @@
 
 static int msglevel = MSG_LEVEL_INFO; /* MSG_LEVEL_DEBUG */
 
+static const u8 fallback_rate0[5][5] = {
+	{RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
+	{RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
+	{RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
+	{RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
+	{RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
+};
+
+static const u8 fallback_rate1[5][5] = {
+	{RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
+	{RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
+	{RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
+	{RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M},
+	{RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M}
+};
+
 /*+
  *
  *  Function:   InterruptPollingThread
@@ -75,6 +91,62 @@ void INTvWorkItem(struct vnt_private *pDevice)
 	spin_unlock_irqrestore(&pDevice->lock, flags);
 }
 
+static int vnt_int_report_rate(struct vnt_private *priv, u8 pkt_no, u8 tsr)
+{
+	struct vnt_usb_send_context *context;
+	struct ieee80211_tx_info *info;
+	struct ieee80211_rate *rate;
+	u8 tx_retry = (tsr & 0xf0) >> 4;
+	s8 idx;
+
+	if (pkt_no >= priv->cbTD)
+		return -EINVAL;
+
+	context = priv->apTD[pkt_no];
+
+	if (!context->skb)
+		return -EINVAL;
+
+	info = IEEE80211_SKB_CB(context->skb);
+	idx = info->control.rates[0].idx;
+
+	if (context->fb_option && !(tsr & (TSR_TMO | TSR_RETRYTMO))) {
+		u8 tx_rate;
+		u8 retry = tx_retry;
+
+		rate = ieee80211_get_tx_rate(priv->hw, info);
+		tx_rate = rate->hw_value - RATE_18M;
+
+		if (retry > 4)
+			retry = 4;
+
+		if (context->fb_option == AUTO_FB_0)
+			tx_rate = fallback_rate0[tx_rate][retry];
+		else if (context->fb_option == AUTO_FB_1)
+			tx_rate = fallback_rate1[tx_rate][retry];
+
+		if (info->band == IEEE80211_BAND_5GHZ)
+			idx = tx_rate - RATE_6M;
+		else
+			idx = tx_rate;
+	}
+
+	ieee80211_tx_info_clear_status(info);
+
+	info->status.rates[0].count = tx_retry;
+
+	if (!(tsr & (TSR_TMO | TSR_RETRYTMO))) {
+		info->status.rates[0].idx = idx;
+		info->flags |= IEEE80211_TX_STAT_ACK;
+	}
+
+	ieee80211_tx_status_irqsafe(priv->hw, context->skb);
+
+	context->in_use = false;
+
+	return 0;
+}
+
 void INTnsProcessData(struct vnt_private *priv)
 {
 	struct vnt_interrupt_data *int_data;
@@ -85,33 +157,17 @@ void INTnsProcessData(struct vnt_private *priv)
 
 	int_data = (struct vnt_interrupt_data *)priv->int_buf.data_buf;
 
-	if (int_data->tsr0 & TSR_VALID) {
-		if (int_data->tsr0 & (TSR_TMO | TSR_RETRYTMO))
-			priv->wstats.discard.retries++;
-		else
-			stats->tx_packets++;
-	}
+	if (int_data->tsr0 & TSR_VALID)
+		vnt_int_report_rate(priv, int_data->pkt0, int_data->tsr0);
 
-	if (int_data->tsr1 & TSR_VALID) {
-		if (int_data->tsr1 & (TSR_TMO | TSR_RETRYTMO))
-			priv->wstats.discard.retries++;
-		else
-			stats->tx_packets++;
-	}
+	if (int_data->tsr1 & TSR_VALID)
+		vnt_int_report_rate(priv, int_data->pkt1, int_data->tsr1);
 
-	if (int_data->tsr2 & TSR_VALID) {
-		if (int_data->tsr2 & (TSR_TMO | TSR_RETRYTMO))
-			priv->wstats.discard.retries++;
-		else
-			stats->tx_packets++;
-	}
+	if (int_data->tsr2 & TSR_VALID)
+		vnt_int_report_rate(priv, int_data->pkt2, int_data->tsr2);
 
-	if (int_data->tsr3 & TSR_VALID) {
-		if (int_data->tsr3 & (TSR_TMO | TSR_RETRYTMO))
-			priv->wstats.discard.retries++;
-		else
-			stats->tx_packets++;
-	}
+	if (int_data->tsr3 & TSR_VALID)
+		vnt_int_report_rate(priv, int_data->pkt3, int_data->tsr3);
 
 	if (int_data->isr0 != 0) {
 		if (int_data->isr0 & ISR_BNTX &&
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 9d0441f..4cdf29e 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -557,6 +557,7 @@ static bool device_alloc_bufs(struct vnt_private *priv)
 
 		priv->apTD[ii] = tx_context;
 		tx_context->priv = priv;
+		tx_context->pkt_no = ii;
 
 		/* allocate URBs */
 		tx_context->urb = usb_alloc_urb(0, GFP_ATOMIC);
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 95b6cf3..264e3c9 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -1021,6 +1021,8 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
 		}
 	}
 
+	tx_context->fb_option = fb_option;
+
 	duration_id = s_vGenerateTxParameter(tx_context, pkt_type, current_rate,
 				tx_buffer, &mic_hdr, need_mic, frame_size,
 						need_ack, NULL, need_rts);
@@ -1050,8 +1052,7 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
 						IEEE80211_SCTL_SEQ) >> 4;
 
 	tx_buffer->tx_byte_count = cpu_to_le16(tx_bytes);
-	tx_buffer->byPKTNO = (u8)(((current_rate << 4) & 0xf0) |
-		(priv->wSeqCounter & 0xf));
+	tx_buffer->byPKTNO = tx_context->pkt_no;
 	tx_buffer->byType = 0x00;
 
 	tx_bytes += 4;
@@ -1147,8 +1148,7 @@ static int vnt_beacon_xmit(struct vnt_private *priv,
 	count = sizeof(struct vnt_tx_short_buf_head) + skb->len;
 
 	beacon_buffer->tx_byte_count = cpu_to_le16(count);
-	beacon_buffer->byPKTNO = (u8)(((current_rate << 4) & 0xf0) |
-				((priv->wSeqCounter - 1) & 0x000f));
+	beacon_buffer->byPKTNO = context->pkt_no;
 	beacon_buffer->byType = 0x01;
 
 	context->type = CONTEXT_BEACON_PACKET;
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index a7af4f58..c8b0ed5 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -398,7 +398,6 @@ static void s_nsBulkOutIoCompleteWrite(struct urb *urb)
 {
 	struct vnt_usb_send_context *context = urb->context;
 	struct vnt_private *priv = context->priv;
-	struct ieee80211_tx_info *info;
 
 	switch (urb->status) {
 	case 0:
@@ -415,25 +414,15 @@ static void s_nsBulkOutIoCompleteWrite(struct urb *urb)
 		break;
 	}
 
-	if (context->skb) {
-		s8 idx;
-
-		info = IEEE80211_SKB_CB(context->skb);
-
-		idx = info->control.rates[0].idx;
-
-		ieee80211_tx_info_clear_status(info);
-		info->status.rates[0].idx = idx;
-		info->status.rates[0].count = 0;
-		if (!urb->status)
-			info->flags |= IEEE80211_TX_STAT_ACK;
-		ieee80211_tx_status_irqsafe(priv->hw, context->skb);
-	}
-
 	if (context->type == CONTEXT_DATA_PACKET)
 		ieee80211_wake_queues(priv->hw);
 
-	context->in_use = false;
+	if (urb->status || context->type == CONTEXT_BEACON_PACKET) {
+		if (context->skb)
+			ieee80211_free_txskb(priv->hw, context->skb);
+
+		context->in_use = false;
+	}
 
 	return;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-07-05 18:25 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-05 18:24 [PATCH 1/8] staging: vt6656: turn radio off after mac registered Malcolm Priestley
2014-07-05 18:24 ` [PATCH 2/8] staging: vt6656: vnt_rf_set_txpower use power for priv->byCurPwr Malcolm Priestley
2014-07-05 18:24 ` [PATCH 3/8] staging: vt6656: vnt_rf_setpower rate <= RATE_11M check array bound Malcolm Priestley
2014-07-05 18:24 ` [PATCH 4/8] staging: vt6656: vnt_tx_packet don't change power when off channel Malcolm Priestley
2014-07-05 18:24 ` [PATCH 5/8] staging: vt6656: vnt_rx_data add track rsr and new_rsr errors Malcolm Priestley
2014-07-05 18:24 ` [PATCH 6/8] staging: vt6656: vnt_set_channel remove power setting functions Malcolm Priestley
2014-07-05 18:24 ` [PATCH 7/8] staging: vt6656: Include re_alloc_skb within lock Malcolm Priestley
2014-07-05 18:24 ` [PATCH 8/8] stagingL vt6656: implement fall back rates reporting Malcolm Priestley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).