Search Linux Wireless

[PATCH 7/9] libertas_tf: Add tx feedback to libertas_tf_sdio

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds tx-feedback to libertas_tf_sdio so that mac80211 rate
adaptation and other bookkeeping tasks function properly.

Signed-off-by: Steve deRosier <steve@xxxxxxxxxxx>
---
 drivers/net/wireless/libertas_tf/deb_defs.h |    5 ++
 drivers/net/wireless/libertas_tf/if_sdio.c  |   42 +++++++++++------
 drivers/net/wireless/libertas_tf/main.c     |   65 ++++++++++++++++----------
 3 files changed, 72 insertions(+), 40 deletions(-)

diff --git a/drivers/net/wireless/libertas_tf/deb_defs.h b/drivers/net/wireless/libertas_tf/deb_defs.h
index 99a7478..8e86e11 100644
--- a/drivers/net/wireless/libertas_tf/deb_defs.h
+++ b/drivers/net/wireless/libertas_tf/deb_defs.h
@@ -43,6 +43,9 @@
 #define LBTF_DEB_HEX	0x00200000
 #define LBTF_DEB_SDIO	0x00400000
 #define LBTF_DEB_MACOPS	0x00800000
+#define LBTF_DEB_STATS	0x01000000
+#define LBTF_DEB_INT    0x02000000
+#define LBTF_DEB_SCRATCH 0x04000000
 
 extern unsigned int lbtf_debug;
 
@@ -87,6 +90,8 @@ do { if ((lbtf_debug & (grp)) == (grp)) \
 #define lbtf_deb_thread(fmt, args...)    LBTF_DEB_LL(LBTF_DEB_THREAD, " thread", fmt, ##args)
 #define lbtf_deb_sdio(fmt, args...)      LBTF_DEB_LL(LBTF_DEB_SDIO, " sdio", fmt, ##args)
 #define lbtf_deb_macops(fmt, args...)      LBTF_DEB_LL(LBTF_DEB_MACOPS, " thread", fmt, ##args)
+#define lbtf_deb_stats(fmt, args...)      LBTF_DEB_LL(LBTF_DEB_STATS, " statistics", fmt, ##args)
+#define lbtf_deb_int(fmt, args...)      LBTF_DEB_LL(LBTF_DEB_INT, " int", fmt, ##args)
 
 #ifdef DEBUG
 static inline void lbtf_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len)
diff --git a/drivers/net/wireless/libertas_tf/if_sdio.c b/drivers/net/wireless/libertas_tf/if_sdio.c
index 189b820..5074f8b 100644
--- a/drivers/net/wireless/libertas_tf/if_sdio.c
+++ b/drivers/net/wireless/libertas_tf/if_sdio.c
@@ -148,7 +148,7 @@ static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
 	int ret;
 	u16 scratch;
 
-	lbtf_deb_enter(LBTF_DEB_SDIO);
+	lbtf_deb_enter(LBTF_DEB_SCRATCH);
 
 	scratch = sdio_readb(card->func, card->scratch_reg, &ret);
 	if (!ret)
@@ -161,7 +161,7 @@ static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
 	if (ret)
 		return 0xffff;
 
-	lbtf_deb_leave_args(LBTF_DEB_SDIO, "scratch %x", scratch);
+	lbtf_deb_leave_args(LBTF_DEB_SCRATCH, "scratch %x", scratch);
 	return scratch;
 }
 
@@ -232,7 +232,7 @@ static int if_sdio_handle_data(struct if_sdio_card *card,
 	struct sk_buff *skb;
 	char *data;
 
-	lbtf_deb_enter(LBTF_DEB_SDIO);
+	lbtf_deb_enter(LBTF_DEB_INT);
 
 	if (size > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
 		lbtf_deb_sdio("response packet too large (%d bytes)\n",
@@ -258,7 +258,7 @@ static int if_sdio_handle_data(struct if_sdio_card *card,
 	ret = 0;
 
 out:
-	lbtf_deb_leave_args(LBTF_DEB_SDIO, "ret %d", ret);
+	lbtf_deb_leave_args(LBTF_DEB_INT, "ret %d", ret);
 
 	return ret;
 }
@@ -291,7 +291,21 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
 		event |= buffer[0] << 0;
 	}
 
-	lbtf_deb_sdio("**EVENT** 0x%X\n", event);
+	lbtf_deb_stats("**EVENT** 0x%X\n", event);
+
+	if (event & 0xffff0000) {
+			u16 tmp;
+			u8 retrycnt;
+			u8 failure;
+
+			tmp = event >> 16;
+			retrycnt = tmp & 0x00ff;
+			failure = (tmp & 0xff00) >> 8;
+			lbtf_deb_stats("Got feedback event. retry: %d, failure: %d", retrycnt, failure);
+			lbtf_send_tx_feedback(card->priv, retrycnt, failure);
+		} else if (event == LBTF_EVENT_BCN_SENT)
+			lbtf_bcn_sent(card->priv);
+
 	ret = 0;
 
 out:
@@ -326,7 +340,7 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
 	int ret;
 	u16 size, type, chunk;
 
-	lbtf_deb_enter(LBTF_DEB_SDIO);
+	lbtf_deb_enter(LBTF_DEB_INT);
 
 
 	size = if_sdio_read_rx_len(card, &ret);
@@ -358,7 +372,7 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
 	chunk = card->buffer[0] | (card->buffer[1] << 8);
 	type = card->buffer[2] | (card->buffer[3] << 8);
 
-	lbtf_deb_sdio("packet of type %d and size %d bytes\n",
+	lbtf_deb_int("packet of type %d and size %d bytes\n",
 		(int)type, (int)chunk);
 
 	if (chunk > size) {
@@ -400,7 +414,7 @@ out:
 	if (ret)
 		pr_err("problem fetching packet from firmware\n");
 
-	lbtf_deb_leave_args(LBTF_DEB_SDIO, "ret %d", ret);
+	lbtf_deb_leave_args(LBTF_DEB_INT, "ret %d", ret);
 
 	return ret;
 }
@@ -1063,25 +1077,23 @@ static void if_sdio_interrupt(struct sdio_func *func)
 	struct if_sdio_card *card;
 	u8 cause;
 
-	lbtf_deb_enter(LBTF_DEB_SDIO);
+	lbtf_deb_enter(LBTF_DEB_INT);
 
 	card = sdio_get_drvdata(func);
 
 	cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret);
-	lbtf_deb_sdio("interrupt: 0x%X\n", (unsigned)cause);
-	lbtf_deb_sdio("interrupt ret: 0x%X\n", ret);
+	lbtf_deb_int("interrupt: 0x%X\n", (unsigned)cause);
+	lbtf_deb_int("interrupt ret: 0x%X\n", ret);
 	if (ret)
 		goto out;
 
-//	lbtf_deb_sdio("interrupt: 0x%X\n", (unsigned)cause);
-
 	sdio_writeb(card->func, ~cause, IF_SDIO_H_INT_STATUS, &ret);
 	if (ret)
 		goto out;
 
 	/*
 	 * Ignore the define name, this really means the card has
-	 * successfully received the command.
+	 * successfully received the command or packet.
 	 */
 	if (cause & IF_SDIO_H_INT_DNLD)
 		if (card->priv)
@@ -1096,7 +1108,7 @@ static void if_sdio_interrupt(struct sdio_func *func)
 	ret = 0;
 
 out:
-	lbtf_deb_leave_args(LBTF_DEB_SDIO, "ret %d", ret);
+	lbtf_deb_leave_args(LBTF_DEB_INT, "ret %d", ret);
 }
 
 static int if_sdio_probe(struct sdio_func *func,
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index b797787..cc2217c 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -296,12 +296,14 @@ static void lbtf_tx_work(struct work_struct *work)
 	/* Activate per-packet rate selection */
 	txpd->tx_control |= cpu_to_le32(MRVL_PER_PACKET_RATE |
 			     ieee80211_get_tx_rate(priv->hw, info)->hw_value);
+	lbtf_deb_tx("tx_control: %x", txpd->tx_control );
 
 	/* copy destination address from 802.11 header */
 	memcpy(txpd->tx_dest_addr_high, skb->data + sizeof(struct txpd) + 4,
 		ETH_ALEN);
 	txpd->tx_packet_length = cpu_to_le16(len);
 	txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
+
 	lbtf_deb_hex(LBTF_DEB_TX, "TX Data ", skb->data, min_t(unsigned int, skb->len, 100));
 
 	WARN_ON(priv->tx_skb);
@@ -729,10 +731,18 @@ EXPORT_SYMBOL_GPL(lbtf_add_card);
 
 int lbtf_remove_card(struct lbtf_private *priv)
 {
+	struct sk_buff *skb = NULL;
 	struct ieee80211_hw *hw = priv->hw;
 
 	lbtf_deb_enter(LBTF_DEB_MAIN);
 
+	ieee80211_stop_queues(priv->hw);
+
+	while (!skb_queue_empty(&priv->tx_skb_buf)) {
+		skb = skb_dequeue(&priv->tx_skb_buf);
+		dev_kfree_skb_any(skb);
+	}
+
 	priv->surpriseremoved = 1;
 	del_timer(&priv->command_timer);
 	lbtf_free_adapter(priv);
@@ -747,24 +757,37 @@ EXPORT_SYMBOL_GPL(lbtf_remove_card);
 
 void lbtf_send_tx_feedback(struct lbtf_private *priv, u8 retrycnt, u8 fail)
 {
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb);
+	struct ieee80211_tx_info *info;
+	lbtf_deb_enter(LBTF_DEB_MAIN);
 
-	ieee80211_tx_info_clear_status(info);
-	/*
-	 * Commented out, otherwise we never go beyond 1Mbit/s using mac80211
-	 * default pid rc algorithm.
-	 *
-	 * info->status.retry_count = MRVL_DEFAULT_RETRIES - retrycnt;
-	 */
-	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !fail)
-		info->flags |= IEEE80211_TX_STAT_ACK;
-	skb_pull(priv->tx_skb, sizeof(struct txpd));
-	ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
-	priv->tx_skb = NULL;
-	if (!priv->skb_to_tx && skb_queue_empty(&priv->bc_ps_buf))
-		ieee80211_wake_queues(priv->hw);
-	else
-		queue_work(lbtf_wq, &priv->tx_work);
+	if(priv->tx_skb == 0) {
+		lbtf_deb_stats("tx_skb is null");
+	} else {
+
+		lbtf_deb_stats("tx_skb is ok");
+
+		info = IEEE80211_SKB_CB(priv->tx_skb);
+		ieee80211_tx_info_clear_status(info);
+		/*
+		 * Commented out, otherwise we never go beyond 1Mbit/s using mac80211
+		 * default pid rc algorithm.
+		 *
+		 * info->status.retry_count = MRVL_DEFAULT_RETRIES - retrycnt;
+		 */
+		if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !fail) {
+			info->flags |= IEEE80211_TX_STAT_ACK;
+		}
+		skb_pull(priv->tx_skb, sizeof(struct txpd));
+		ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
+	}
+
+		priv->tx_skb = NULL;
+		if (!priv->skb_to_tx && skb_queue_empty(&priv->bc_ps_buf))
+			ieee80211_wake_queues(priv->hw);
+		else
+			queue_work(lbtf_wq, &priv->tx_work);
+
+	lbtf_deb_leave(LBTF_DEB_MAIN);
 }
 EXPORT_SYMBOL_GPL(lbtf_send_tx_feedback);
 
@@ -782,19 +805,11 @@ void lbtf_host_to_card_done(struct lbtf_private *priv )
 #endif
 
 	if (priv->tx_skb) {
-		ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
-		priv->tx_skb = NULL;
 		lbtf_deb_main("Got done on packet.");
 	} else {
 		lbtf_deb_main("Got done on command.");
 	}
 
-	if (!priv->skb_to_tx && skb_queue_empty(&priv->bc_ps_buf)) {
-		ieee80211_wake_queues(priv->hw);
-	} else {
-		queue_work(lbtf_wq, &priv->tx_work);
-	}
-
 	lbtf_deb_leave(LBTF_DEB_THREAD);
 }
 EXPORT_SYMBOL_GPL(lbtf_host_to_card_done);
-- 
1.7.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux