linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/6] staging: brcm80211: implement flush driver callback for mac80211
@ 2011-04-18 13:31 Arend van Spriel
  2011-04-18 13:31 ` [PATCH 2/6] staging: brcm80211: rename active_queue identifier Arend van Spriel
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Arend van Spriel @ 2011-04-18 13:31 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-wireless

The mac80211 interface has a flush callback which is used by mac80211
to assure all pending transmit packets have been transmitted. This
is used before scanning off-channel.

Reviewed-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Henry Ptasinski <henryp@broadcom.com>
Reviewed-by: Brett Rudley <brudley@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Cc: devel@linuxdriverproject.org
Cc: linux-wireless@vger.kernel.org
---
 drivers/staging/brcm80211/brcmsmac/wl_export.h   |    1 +
 drivers/staging/brcm80211/brcmsmac/wl_mac80211.c |   24 ++++++++++++++++++++++
 drivers/staging/brcm80211/brcmsmac/wlc_main.c    |   13 +++++++++++
 drivers/staging/brcm80211/brcmsmac/wlc_pub.h     |    1 +
 4 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/brcm80211/brcmsmac/wl_export.h b/drivers/staging/brcm80211/brcmsmac/wl_export.h
index 9ff760f..0fe0b24 100644
--- a/drivers/staging/brcm80211/brcmsmac/wl_export.h
+++ b/drivers/staging/brcm80211/brcmsmac/wl_export.h
@@ -42,5 +42,6 @@ extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer);
 extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms,
 			 int periodic);
 extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer);
+extern void wl_msleep(struct wl_info *wl, uint ms);
 
 #endif				/* _wl_export_h_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
index 169d26b..6ea747f 100644
--- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
+++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
@@ -151,6 +151,7 @@ static int wl_ops_ampdu_action(struct ieee80211_hw *hw,
 			       struct ieee80211_sta *sta, u16 tid, u16 *ssn,
 			       u8 buf_size);
 static void wl_ops_rfkill_poll(struct ieee80211_hw *hw);
+static void wl_ops_flush(struct ieee80211_hw *hw, bool drop);
 
 static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
@@ -690,6 +691,18 @@ static void wl_ops_rfkill_poll(struct ieee80211_hw *hw)
 	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
 }
 
+static void wl_ops_flush(struct ieee80211_hw *hw, bool drop)
+{
+	struct wl_info *wl = HW_TO_WL(hw);
+
+	no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
+
+	/* wait for packet queue and dma fifos to run empty */
+	WL_LOCK(wl);
+	wlc_wait_for_tx_completion(wl->wlc, drop);
+	WL_UNLOCK(wl);
+}
+
 static const struct ieee80211_ops wl_ops = {
 	.tx = wl_ops_tx,
 	.start = wl_ops_start,
@@ -711,6 +724,7 @@ static const struct ieee80211_ops wl_ops = {
 	.sta_remove = wl_ops_sta_remove,
 	.ampdu_action = wl_ops_ampdu_action,
 	.rfkill_poll = wl_ops_rfkill_poll,
+	.flush = wl_ops_flush,
 };
 
 /*
@@ -1981,3 +1995,13 @@ bool wl_rfkill_set_hw_state(struct wl_info *wl)
 	WL_LOCK(wl);
 	return blocked;
 }
+
+/*
+ * precondition: perimeter lock has been acquired
+ */
+void wl_msleep(struct wl_info *wl, uint ms)
+{
+	WL_UNLOCK(wl);
+	msleep(ms);
+	WL_LOCK(wl);
+}
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
index 93e2f2c..3e5d884 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
@@ -8097,3 +8097,16 @@ int wlc_get_curband(struct wlc_info *wlc)
 {
 	return wlc->band->bandunit;
 }
+
+void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop)
+{
+	/* flush packet queue when requested */
+	if (drop)
+		pktq_flush(&wlc->active_queue->q, false, NULL, 0);
+
+	/* wait for queue and DMA fifos to run dry */
+	while (!pktq_empty(&wlc->active_queue->q) ||
+	       TXPKTPENDTOT(wlc) > 0) {
+		wl_msleep(wlc->wl, 1);
+	}
+}
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h
index eea9aa7..626d424 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h
@@ -569,6 +569,7 @@ extern void wlc_scan_start(struct wlc_info *wlc);
 extern void wlc_scan_stop(struct wlc_info *wlc);
 extern void wlc_associate_upd(struct wlc_info *wlc, bool state);
 extern int wlc_get_curband(struct wlc_info *wlc);
+extern void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop);
 
 static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name,
 				    uint *arg)
-- 
1.7.1



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

* [PATCH 2/6] staging: brcm80211: rename active_queue identifier
  2011-04-18 13:31 [PATCH 1/6] staging: brcm80211: implement flush driver callback for mac80211 Arend van Spriel
@ 2011-04-18 13:31 ` Arend van Spriel
  2011-04-18 13:31 ` [PATCH 3/6] staging: brcm80211: remove queue info parameter from wlc_send_q Arend van Spriel
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Arend van Spriel @ 2011-04-18 13:31 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-wireless

The queue for pending transmit packets is called active_queue, but
the driver is only using one single queue. Therefor a more appro-
priate name has been given, ie. pkt_queue.

Reviewed-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Brett Rudley <brudley@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Cc: devel@linuxdriverproject.org
Cc: linux-wireless@vger.kernel.org
---
 drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c |    4 ++--
 drivers/staging/brcm80211/brcmsmac/wlc_bmac.c  |    8 ++++----
 drivers/staging/brcm80211/brcmsmac/wlc_main.c  |   22 ++++++++++------------
 drivers/staging/brcm80211/brcmsmac/wlc_main.h  |    4 +---
 4 files changed, 17 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
index dfdcc83..1950ae0 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
@@ -1140,7 +1140,7 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
 
 		p = GETNEXTTXP(wlc, queue);
 	}
-	wlc_send_q(wlc, wlc->active_queue);
+	wlc_send_q(wlc, wlc->pkt_queue);
 
 	/* update rate state */
 	antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel);
@@ -1347,7 +1347,7 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a)
 void wlc_ampdu_flush(struct wlc_info *wlc,
 		     struct ieee80211_sta *sta, u16 tid)
 {
-	struct wlc_txq_info *qi = wlc->active_queue;
+	struct wlc_txq_info *qi = wlc->pkt_queue;
 	struct pktq *pq = &qi->q;
 	int prec;
 	struct cb_del_ampdu_pars ampdu_pars;
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
index 7be3fa1..a8520ee 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
@@ -417,8 +417,8 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded)
 	}
 
 	/* send any enq'd tx packets. Just makes sure to jump start tx */
-	if (!pktq_empty(&wlc->active_queue->q))
-		wlc_send_q(wlc, wlc->active_queue);
+	if (!pktq_empty(&wlc->pkt_queue->q))
+		wlc_send_q(wlc, wlc->pkt_queue);
 
 	/* it isn't done and needs to be resched if macintstatus is non-zero */
 	return wlc->macintstatus != 0;
@@ -3077,8 +3077,8 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal)
 	if (n >= max_tx_num)
 		morepending = true;
 
-	if (!pktq_empty(&wlc->active_queue->q))
-		wlc_send_q(wlc, wlc->active_queue);
+	if (!pktq_empty(&wlc->pkt_queue->q))
+		wlc_send_q(wlc, wlc->pkt_queue);
 
 	return morepending;
 }
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
index 3e5d884..b01c9f5 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
@@ -1612,7 +1612,6 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode,
 	uint err = 0;
 	uint j;
 	struct wlc_pub *pub;
-	struct wlc_txq_info *qi;
 	uint n_disabled;
 
 	no_printk("wl%d: %s: vendor 0x%x device 0x%x\n",
@@ -1781,14 +1780,13 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode,
 	 */
 
 	/* allocate our initial queue */
-	qi = wlc_txq_alloc(wlc);
-	if (qi == NULL) {
+	wlc->pkt_queue = wlc_txq_alloc(wlc);
+	if (wlc->pkt_queue == NULL) {
 		dev_err(dev, "wl%d: %s: failed to malloc tx queue\n",
 			 unit, __func__);
 		err = 100;
 		goto fail;
 	}
-	wlc->active_queue = qi;
 
 	wlc->bsscfg[0] = wlc->cfg;
 	wlc->cfg->_idx = 0;
@@ -4886,7 +4884,7 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
 			     uint prec)
 {
 	struct wlc_info *wlc = (struct wlc_info *) ctx;
-	struct wlc_txq_info *qi = wlc->active_queue;	/* Check me */
+	struct wlc_txq_info *qi = wlc->pkt_queue;	/* Check me */
 	struct pktq *q = &qi->q;
 	int prio;
 
@@ -4942,7 +4940,7 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
 	    (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0)))
 		return -EINVAL;
 	wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio));
-	wlc_send_q(wlc, wlc->active_queue);
+	wlc_send_q(wlc, wlc->pkt_queue);
 
 	wlc->pub->_cnt->ieee_tx++;
 	return 0;
@@ -4958,8 +4956,8 @@ void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi)
 	struct pktq *q = &qi->q;
 	struct ieee80211_tx_info *tx_info;
 
-	/* only do work for the active queue */
-	if (qi != wlc->active_queue)
+	/* only do work for the packet queue */
+	if (qi != wlc->pkt_queue)
 		return;
 
 	if (in_send_q)
@@ -6183,8 +6181,8 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus)
 	}
 
 	/* send any enq'd tx packets. Just makes sure to jump start tx */
-	if (!pktq_empty(&wlc->active_queue->q))
-		wlc_send_q(wlc, wlc->active_queue);
+	if (!pktq_empty(&wlc->pkt_queue->q))
+		wlc_send_q(wlc, wlc->pkt_queue);
 }
 
 static void wlc_war16165(struct wlc_info *wlc, bool tx)
@@ -8102,10 +8100,10 @@ void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop)
 {
 	/* flush packet queue when requested */
 	if (drop)
-		pktq_flush(&wlc->active_queue->q, false, NULL, 0);
+		pktq_flush(&wlc->pkt_queue->q, false, NULL, 0);
 
 	/* wait for queue and DMA fifos to run dry */
-	while (!pktq_empty(&wlc->active_queue->q) ||
+	while (!pktq_empty(&wlc->pkt_queue->q) ||
 	       TXPKTPENDTOT(wlc) > 0) {
 		wl_msleep(wlc->wl, 1);
 	}
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h
index 3a34870..3d7df6f 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.h
@@ -743,9 +743,7 @@ struct wlc_info {
 	u16 next_bsscfg_ID;
 
 	struct wlc_if *wlcif_list;	/* linked list of wlc_if structs */
-	struct wlc_txq_info *active_queue; /* txq for the currently active
-					    * transmit context
-					    */
+	struct wlc_txq_info *pkt_queue; /* txq for transmit packets */
 	u32 mpc_dur;		/* total time (ms) in mpc mode except for the
 				 * portion since radio is turned off last time
 				 */
-- 
1.7.1



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

* [PATCH 3/6] staging: brcm80211: remove queue info parameter from wlc_send_q
  2011-04-18 13:31 [PATCH 1/6] staging: brcm80211: implement flush driver callback for mac80211 Arend van Spriel
  2011-04-18 13:31 ` [PATCH 2/6] staging: brcm80211: rename active_queue identifier Arend van Spriel
@ 2011-04-18 13:31 ` Arend van Spriel
  2011-04-18 13:31 ` [PATCH 4/6] staging: brcm80211: provide TSF value in receive status Arend van Spriel
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Arend van Spriel @ 2011-04-18 13:31 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-wireless

There is only one queue on which the wlc_send_q has to operate. This
queue is available under the struct wlc_info parameter passed so
the additional queue info parameter is redundant.

Reviewed-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Brett Rudley <brudley@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Cc: devel@linuxdriverproject.org
Cc: linux-wireless@vger.kernel.org
---
 drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c |    2 +-
 drivers/staging/brcm80211/brcmsmac/wlc_bmac.c  |    4 ++--
 drivers/staging/brcm80211/brcmsmac/wlc_main.c  |   11 ++++-------
 drivers/staging/brcm80211/brcmsmac/wlc_main.h  |    2 +-
 4 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
index 1950ae0..1b92767 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
@@ -1140,7 +1140,7 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
 
 		p = GETNEXTTXP(wlc, queue);
 	}
-	wlc_send_q(wlc, wlc->pkt_queue);
+	wlc_send_q(wlc);
 
 	/* update rate state */
 	antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel);
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
index a8520ee..4c15110 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
@@ -418,7 +418,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded)
 
 	/* send any enq'd tx packets. Just makes sure to jump start tx */
 	if (!pktq_empty(&wlc->pkt_queue->q))
-		wlc_send_q(wlc, wlc->pkt_queue);
+		wlc_send_q(wlc);
 
 	/* it isn't done and needs to be resched if macintstatus is non-zero */
 	return wlc->macintstatus != 0;
@@ -3078,7 +3078,7 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal)
 		morepending = true;
 
 	if (!pktq_empty(&wlc->pkt_queue->q))
-		wlc_send_q(wlc, wlc->pkt_queue);
+		wlc_send_q(wlc);
 
 	return morepending;
 }
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
index b01c9f5..0eb1040 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
@@ -4940,26 +4940,23 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
 	    (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0)))
 		return -EINVAL;
 	wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio));
-	wlc_send_q(wlc, wlc->pkt_queue);
+	wlc_send_q(wlc);
 
 	wlc->pub->_cnt->ieee_tx++;
 	return 0;
 }
 
-void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi)
+void BCMFASTPATH wlc_send_q(struct wlc_info *wlc)
 {
 	struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
 	int prec;
 	u16 prec_map;
 	int err = 0, i, count;
 	uint fifo;
+	struct wlc_txq_info *qi = wlc->pkt_queue;
 	struct pktq *q = &qi->q;
 	struct ieee80211_tx_info *tx_info;
 
-	/* only do work for the packet queue */
-	if (qi != wlc->pkt_queue)
-		return;
-
 	if (in_send_q)
 		return;
 	else
@@ -6182,7 +6179,7 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus)
 
 	/* send any enq'd tx packets. Just makes sure to jump start tx */
 	if (!pktq_empty(&wlc->pkt_queue->q))
-		wlc_send_q(wlc, wlc->pkt_queue);
+		wlc_send_q(wlc);
 }
 
 static void wlc_war16165(struct wlc_info *wlc, bool tx)
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h
index 3d7df6f..d1114e8 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.h
@@ -856,7 +856,7 @@ extern void wlc_txflowcontrol_override(struct wlc_info *wlc,
 				       bool on, uint override);
 extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc,
 					 struct wlc_txq_info *qi, int prio);
-extern void wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi);
+extern void wlc_send_q(struct wlc_info *wlc);
 extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo);
 
 extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec,
-- 
1.7.1



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

* [PATCH 4/6] staging: brcm80211: provide TSF value in receive status
  2011-04-18 13:31 [PATCH 1/6] staging: brcm80211: implement flush driver callback for mac80211 Arend van Spriel
  2011-04-18 13:31 ` [PATCH 2/6] staging: brcm80211: rename active_queue identifier Arend van Spriel
  2011-04-18 13:31 ` [PATCH 3/6] staging: brcm80211: remove queue info parameter from wlc_send_q Arend van Spriel
@ 2011-04-18 13:31 ` Arend van Spriel
  2011-04-18 13:31 ` [PATCH 5/6] staging: brcm80211: remove tsf retrieval from wlc_bmac.c Arend van Spriel
  2011-04-18 13:31 ` [PATCH 6/6] staging: brcm80211: remove retrieval function for tsf in wlc_main.c Arend van Spriel
  4 siblings, 0 replies; 6+ messages in thread
From: Arend van Spriel @ 2011-04-18 13:31 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-wireless

Packets passed to the mac80211 stack have a mactime field in the
receive status indicating the actual time it was received by the
phy radio. It was not (properly) filled in before this change.

Reviewed-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Henry Ptasinski <henryp@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Cc: devel@linuxdriverproject.org
Cc: linux-wireless@vger.kernel.org
---
 drivers/staging/brcm80211/brcmsmac/wlc_main.c |   50 ++++++++++++++++++++----
 1 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
index 0eb1040..34584be 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
@@ -282,6 +282,7 @@ static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp);
 static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp);
 static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate,
 				    u8 preamble_type, uint next_frag_len);
+static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh);
 static void wlc_recvctl(struct wlc_info *wlc,
 			d11rxhdr_t *rxh, struct sk_buff *p);
 static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate,
@@ -6472,25 +6473,56 @@ void wlc_bcn_li_upd(struct wlc_info *wlc)
 			      (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
 }
 
+/*
+ * recover 64bit TSF value from the 16bit TSF value in the rx header
+ * given the assumption that the TSF passed in header is within 65ms
+ * of the current tsf.
+ *
+ * 6       5       4       4       3       2       1
+ * 3.......6.......8.......0.......2.......4.......6.......8......0
+ * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
+ *
+ * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
+ * tsf_l is filled in by wlc_bmac_recv, which is done earlier in the
+ * receive call sequence after rx interrupt. Only the higher 16 bits
+ * are used. Finally, the tsf_h is read from the tsf register.
+ */
+static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh)
+{
+	u32 tsf_h, tsf_l;
+	u16 rx_tsf_0_15, rx_tsf_16_31;
+
+	wlc_bmac_read_tsf(wlc->hw, &tsf_l, &tsf_h);
+
+	rx_tsf_16_31 = (u16)(tsf_l >> 16);
+	rx_tsf_0_15 = rxh->rxhdr.RxTSFTime;
+
+	/*
+	 * a greater tsf time indicates the low 16 bits of
+	 * tsf_l wrapped, so decrement the high 16 bits.
+	 */
+	if ((u16)tsf_l < rx_tsf_0_15) {
+		rx_tsf_16_31 -= 1;
+		if (rx_tsf_16_31 == 0xffff)
+			tsf_h -= 1;
+	}
+
+	return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
+}
+
 static void
 prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p,
 		     struct ieee80211_rx_status *rx_status)
 {
-	u32 tsf_l, tsf_h;
 	wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh;
 	int preamble;
 	int channel;
 	ratespec_t rspec;
 	unsigned char *plcp;
 
-#if 0
-	/* Clearly, this is bogus -- reading the TSF now is wrong */
-	wlc_read_tsf(wlc, &tsf_l, &tsf_h);	/* mactime */
-	rx_status->mactime = tsf_h;
-	rx_status->mactime <<= 32;
-	rx_status->mactime |= tsf_l;
-	rx_status->flag |= RX_FLAG_MACTIME_MPDU; /* clearly wrong */
-#endif
+	/* fill in TSF and flag its presence */
+	rx_status->mactime = wlc_recover_tsf64(wlc, wlc_rxh);
+	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
 
 	channel = WLC_CHAN_CHANNEL(rxh->RxChan);
 
-- 
1.7.1



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

* [PATCH 5/6] staging: brcm80211: remove tsf retrieval from wlc_bmac.c
  2011-04-18 13:31 [PATCH 1/6] staging: brcm80211: implement flush driver callback for mac80211 Arend van Spriel
                   ` (2 preceding siblings ...)
  2011-04-18 13:31 ` [PATCH 4/6] staging: brcm80211: provide TSF value in receive status Arend van Spriel
@ 2011-04-18 13:31 ` Arend van Spriel
  2011-04-18 13:31 ` [PATCH 6/6] staging: brcm80211: remove retrieval function for tsf in wlc_main.c Arend van Spriel
  4 siblings, 0 replies; 6+ messages in thread
From: Arend van Spriel @ 2011-04-18 13:31 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-wireless

Upon receiving a packet the lowest 32 bits of tsf are filled in
by wlc_bmac in wlc_bmac_recv, but this is not useful as wlc_main
needs to reconstruct 64 bit tsf which is retrieves to recover the
actual tsf value at which packet is received. Therefore tsf
retrieval is removed from wlc_bmac.c.

Reviewed-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Henry Ptasinski <henryp@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Cc: devel@linuxdriverproject.org
Cc: linux-wireless@vger.kernel.org
---
 drivers/staging/brcm80211/brcmsmac/wlc_bmac.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
index 4c15110..fd3669e 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
@@ -264,7 +264,6 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound)
 	struct sk_buff *tail = NULL;
 	uint n = 0;
 	uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1;
-	u32 tsf_h, tsf_l;
 	wlc_d11rxhdr_t *wlc_rxhdr = NULL;
 
 	WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__);
@@ -283,9 +282,6 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound)
 			break;
 	}
 
-	/* get the TSF REG reading */
-	wlc_bmac_read_tsf(wlc_hw, &tsf_l, &tsf_h);
-
 	/* post more rbufs */
 	dma_rxfill(wlc_hw->di[fifo]);
 
@@ -294,9 +290,7 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound)
 		head = head->prev;
 		p->prev = NULL;
 
-		/* record the tsf_l in wlc_rxd11hdr */
 		wlc_rxhdr = (wlc_d11rxhdr_t *) p->data;
-		wlc_rxhdr->tsf_l = cpu_to_le32(tsf_l);
 
 		/* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */
 		wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr);
-- 
1.7.1



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

* [PATCH 6/6] staging: brcm80211: remove retrieval function for tsf in wlc_main.c
  2011-04-18 13:31 [PATCH 1/6] staging: brcm80211: implement flush driver callback for mac80211 Arend van Spriel
                   ` (3 preceding siblings ...)
  2011-04-18 13:31 ` [PATCH 5/6] staging: brcm80211: remove tsf retrieval from wlc_bmac.c Arend van Spriel
@ 2011-04-18 13:31 ` Arend van Spriel
  4 siblings, 0 replies; 6+ messages in thread
From: Arend van Spriel @ 2011-04-18 13:31 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-wireless

wlc_main.c provides a function to read the tsf, but it is not used.
Consequently, it is removed.

Reviewed-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Henry Ptasinski <henryp@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Cc: devel@linuxdriverproject.org
Cc: linux-wireless@vger.kernel.org
---
 drivers/staging/brcm80211/brcmsmac/wlc_main.c |    5 -----
 drivers/staging/brcm80211/brcmsmac/wlc_main.h |    2 --
 2 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
index 34584be..6fb9d9c 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
@@ -7861,11 +7861,6 @@ void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr)
 	wlc_bmac_set_rcmta(wlc->hw, idx, addr);
 }
 
-void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr)
-{
-	wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr);
-}
-
 void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin)
 {
 	wlc->band->CWmin = newmin;
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h
index d1114e8..34023fa 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.h
@@ -813,8 +813,6 @@ extern void wlc_get_rcmta(struct wlc_info *wlc, int idx,
 #endif
 extern void wlc_set_rcmta(struct wlc_info *wlc, int idx,
 			  const u8 *addr);
-extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr,
-			 u32 *tsf_h_ptr);
 extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin);
 extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax);
 extern void wlc_fifoerrors(struct wlc_info *wlc);
-- 
1.7.1



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

end of thread, other threads:[~2011-04-18 13:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-18 13:31 [PATCH 1/6] staging: brcm80211: implement flush driver callback for mac80211 Arend van Spriel
2011-04-18 13:31 ` [PATCH 2/6] staging: brcm80211: rename active_queue identifier Arend van Spriel
2011-04-18 13:31 ` [PATCH 3/6] staging: brcm80211: remove queue info parameter from wlc_send_q Arend van Spriel
2011-04-18 13:31 ` [PATCH 4/6] staging: brcm80211: provide TSF value in receive status Arend van Spriel
2011-04-18 13:31 ` [PATCH 5/6] staging: brcm80211: remove tsf retrieval from wlc_bmac.c Arend van Spriel
2011-04-18 13:31 ` [PATCH 6/6] staging: brcm80211: remove retrieval function for tsf in wlc_main.c Arend van Spriel

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).