linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/13] wlcore/wl18xx: some patches for 3.10
@ 2013-03-12 13:44 Luciano Coelho
  2013-03-12 13:44 ` [PATCH 01/13] wlcore: enter elp in force ps mode in 5ms Luciano Coelho
                   ` (13 more replies)
  0 siblings, 14 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho

Hi,

These are some of the TI wireless drivers patches that are intended
for 3.10.

A bunch of fixes and small improvements here and there.

Please review.

--
Cheers,
Luca.


Arik Nemtsov (8):
  wlcore: fix link count in single-link-PSM optimization
  wlcore: don't risk using stale HLID during .sta_state callback
  wlcore: consolidate tx_seq handling on recovery
  wlcore: change warn on missing lock in wlcore_queue_xx funcs
  wlcore: free AP global links properly on recovery
  wlcore: AP-mode - recover security seq num for stations
  wlcore: correctly check state before regdomain conf
  wlcore: consider dummy packets when tx queues are empty

Eyal Shapira (1):
  wlcore: don't attempt to roam in case of p2p

Igal Chernobelsky (2):
  wlcore: enter elp in force ps mode in 5ms
  wlcore: set max num of Rx BA sessions per chip

Nadim Zubidat (1):
  wlcore: report rssi from roaming statistics

Victor Goldenshtein (1):
  wl18xx: print chip info during boot

 drivers/net/wireless/ti/wl12xx/main.c     |    1 +
 drivers/net/wireless/ti/wl12xx/wl12xx.h   |    2 +
 drivers/net/wireless/ti/wl18xx/main.c     |   25 ++++-
 drivers/net/wireless/ti/wl18xx/reg.h      |   29 ++++++
 drivers/net/wireless/ti/wl18xx/wl18xx.h   |    4 +-
 drivers/net/wireless/ti/wlcore/acx.c      |   29 ++++++
 drivers/net/wireless/ti/wlcore/acx.h      |   16 +++-
 drivers/net/wireless/ti/wlcore/cmd.c      |   32 +++++++
 drivers/net/wireless/ti/wlcore/debugfs.c  |    3 +-
 drivers/net/wireless/ti/wlcore/event.c    |    9 +-
 drivers/net/wireless/ti/wlcore/main.c     |  145 +++++++++++++++++++++--------
 drivers/net/wireless/ti/wlcore/ps.c       |    4 +-
 drivers/net/wireless/ti/wlcore/tx.c       |   39 +++-----
 drivers/net/wireless/ti/wlcore/wlcore.h   |    3 +
 drivers/net/wireless/ti/wlcore/wlcore_i.h |   28 ++++--
 15 files changed, 289 insertions(+), 80 deletions(-)

-- 
1.7.10.4


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

* [PATCH 01/13] wlcore: enter elp in force ps mode in 5ms
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 02/13] wlcore: set max num of Rx BA sessions per chip Luciano Coelho
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Igal Chernobelsky

From: Igal Chernobelsky <igalc@ti.com>

It is requiered to enter sleep mode with smaller delay in forced PS mode.
This fixes issue of testing force PS mode during VoIP traffic where packets
are sent every 20ms. Chip never enters ps mode with default 30 ms delay
in such test.

Signed-off-by: Igal Chernobelsky <igalc@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/ps.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 9b7b6e2..9654577 100644
--- a/drivers/net/wireless/ti/wlcore/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -29,6 +29,7 @@
 #define WL1271_WAKEUP_TIMEOUT 500
 
 #define ELP_ENTRY_DELAY  30
+#define ELP_ENTRY_DELAY_FORCE_PS  5
 
 void wl1271_elp_work(struct work_struct *work)
 {
@@ -98,7 +99,8 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
 			return;
 	}
 
-	timeout = ELP_ENTRY_DELAY;
+	timeout = wl->conf.conn.forced_ps ?
+			ELP_ENTRY_DELAY_FORCE_PS : ELP_ENTRY_DELAY;
 	ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
 				     msecs_to_jiffies(timeout));
 }
-- 
1.7.10.4


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

* [PATCH 02/13] wlcore: set max num of Rx BA sessions per chip
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
  2013-03-12 13:44 ` [PATCH 01/13] wlcore: enter elp in force ps mode in 5ms Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 03/13] wlcore: fix link count in single-link-PSM optimization Luciano Coelho
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Igal Chernobelsky

From: Igal Chernobelsky <igalc@ti.com>

Maximum number of supported RX BA sessions depends on chip type.
wl18xx supports 5 RX BA sessions while wl12xx supports 3.

Signed-off-by: Igal Chernobelsky <igalc@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wl12xx/main.c   |    1 +
 drivers/net/wireless/ti/wl12xx/wl12xx.h |    2 ++
 drivers/net/wireless/ti/wl18xx/main.c   |    1 +
 drivers/net/wireless/ti/wl18xx/wl18xx.h |    4 +++-
 drivers/net/wireless/ti/wlcore/acx.h    |    2 --
 drivers/net/wireless/ti/wlcore/main.c   |    2 +-
 drivers/net/wireless/ti/wlcore/wlcore.h |    3 +++
 7 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index 09694e3..1c627da 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -723,6 +723,7 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
 	wl->sched_scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
 	wl->sched_scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
 	wl->max_channels_5 = WL12XX_MAX_CHANNELS_5GHZ;
+	wl->ba_rx_session_count_max = WL12XX_RX_BA_MAX_SESSIONS;
 out:
 	return ret;
 }
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
index d455285..222d035 100644
--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -63,6 +63,8 @@
 
 #define WL12XX_NUM_MAC_ADDRESSES 2
 
+#define WL12XX_RX_BA_MAX_SESSIONS 3
+
 struct wl127x_rx_mem_pool_addr {
 	u32 addr;
 	u32 addr_extra;
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index da3ef1b..b670776 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -678,6 +678,7 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
 	wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
 	wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
 	wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
+	wl->ba_rx_session_count_max = WL18XX_RX_BA_MAX_SESSIONS;
 out:
 	return ret;
 }
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index b6739e7..9204e07 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -29,7 +29,7 @@
 #define WL18XX_IFTYPE_VER	5
 #define WL18XX_MAJOR_VER	WLCORE_FW_VER_IGNORE
 #define WL18XX_SUBTYPE_VER	WLCORE_FW_VER_IGNORE
-#define WL18XX_MINOR_VER	28
+#define WL18XX_MINOR_VER	39
 
 #define WL18XX_CMD_MAX_SIZE          740
 
@@ -40,6 +40,8 @@
 
 #define WL18XX_NUM_MAC_ADDRESSES 3
 
+#define WL18XX_RX_BA_MAX_SESSIONS 5
+
 struct wl18xx_priv {
 	/* buffer for sending commands to FW */
 	u8 cmd_buf[WL18XX_CMD_MAX_SIZE];
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index 126536c..1a61e85 100644
--- a/drivers/net/wireless/ti/wlcore/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -728,8 +728,6 @@ struct wl1271_acx_ht_information {
 	u8 padding[2];
 } __packed;
 
-#define RX_BA_MAX_SESSIONS 3
-
 struct wl1271_acx_ba_initiator_policy {
 	struct acx_header header;
 
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 2c2ff3e..3fc86c4 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -4784,7 +4784,7 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
 			break;
 		}
 
-		if (wl->ba_rx_session_count >= RX_BA_MAX_SESSIONS) {
+		if (wl->ba_rx_session_count >= wl->ba_rx_session_count_max) {
 			ret = -EBUSY;
 			wl1271_error("exceeded max RX BA sessions");
 			break;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index af9feca..0034979 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -390,6 +390,9 @@ struct wl1271 {
 	/* number of currently active RX BA sessions */
 	int ba_rx_session_count;
 
+	/* Maximum number of supported RX BA sessions */
+	int ba_rx_session_count_max;
+
 	/* AP-mode - number of currently connected stations */
 	int active_sta_count;
 
-- 
1.7.10.4


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

* [PATCH 03/13] wlcore: fix link count in single-link-PSM optimization
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
  2013-03-12 13:44 ` [PATCH 01/13] wlcore: enter elp in force ps mode in 5ms Luciano Coelho
  2013-03-12 13:44 ` [PATCH 02/13] wlcore: set max num of Rx BA sessions per chip Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 04/13] wlcore: don't risk using stale HLID during .sta_state callback Luciano Coelho
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Arik Nemtsov

From: Arik Nemtsov <arik@wizery.com>

commit 144614f3eebd7d only allowed a single active link when
turning on the optimization, ignoring the fact that an AP has two
additional global links.
Use 3 links as an indication for a single active link. Use the
FW PSM bits to verify the extra active link belongs to the AP role.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/main.c |   10 +++++++---
 drivers/net/wireless/ti/wlcore/tx.c   |   10 +++++++---
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 3fc86c4..389ae1a 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -332,10 +332,9 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
 					struct wl12xx_vif *wlvif,
 					u8 hlid, u8 tx_pkts)
 {
-	bool fw_ps, single_link;
+	bool fw_ps;
 
 	fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
-	single_link = (wl->active_link_count == 1);
 
 	/*
 	 * Wake up from high level PS if the STA is asleep with too little
@@ -348,8 +347,13 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
 	 * Start high-level PS if the STA is asleep with enough blocks in FW.
 	 * Make an exception if this is the only connected link. In this
 	 * case FW-memory congestion is less of a problem.
+	 * Note that a single connected STA means 3 active links, since we must
+	 * account for the global and broadcast AP links. The "fw_ps" check
+	 * assures us the third link is a STA connected to the AP. Otherwise
+	 * the FW would not set the PSM bit.
 	 */
-	else if (!single_link && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
+	else if (wl->active_link_count > 3 && fw_ps &&
+		 tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
 		wl12xx_ps_link_start(wl, wlvif, hlid, true);
 }
 
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index ece392c..07a3e42 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -104,7 +104,7 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
 				    struct wl12xx_vif *wlvif,
 				    u8 hlid)
 {
-	bool fw_ps, single_link;
+	bool fw_ps;
 	u8 tx_pkts;
 
 	if (WARN_ON(!test_bit(hlid, wlvif->links_map)))
@@ -112,15 +112,19 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
 
 	fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
 	tx_pkts = wl->links[hlid].allocated_pkts;
-	single_link = (wl->active_link_count == 1);
 
 	/*
 	 * if in FW PS and there is enough data in FW we can put the link
 	 * into high-level PS and clean out its TX queues.
 	 * Make an exception if this is the only connected link. In this
 	 * case FW-memory congestion is less of a problem.
+	 * Note that a single connected STA means 3 active links, since we must
+	 * account for the global and broadcast AP links. The "fw_ps" check
+	 * assures us the third link is a STA connected to the AP. Otherwise
+	 * the FW would not set the PSM bit.
 	 */
-	if (!single_link && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
+	if (wl->active_link_count > 3 && fw_ps &&
+	    tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
 		wl12xx_ps_link_start(wl, wlvif, hlid, true);
 }
 
-- 
1.7.10.4


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

* [PATCH 04/13] wlcore: don't risk using stale HLID during .sta_state callback
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (2 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 03/13] wlcore: fix link count in single-link-PSM optimization Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 05/13] wlcore: consolidate tx_seq handling on recovery Luciano Coelho
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Arik Nemtsov

From: Arik Nemtsov <arik@wizery.com>

The HLID of a STA can change, particularly during recovery. Don't cache
the HLID before it was potentially allocated.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/main.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 389ae1a..c3e2471 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -4620,13 +4620,11 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
 				   enum ieee80211_sta_state new_state)
 {
 	struct wl1271_station *wl_sta;
-	u8 hlid;
 	bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
 	bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
 	int ret;
 
 	wl_sta = (struct wl1271_station *)sta->drv_priv;
-	hlid = wl_sta->hlid;
 
 	/* Add station (AP mode) */
 	if (is_ap &&
@@ -4652,12 +4650,12 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
 	/* Authorize station (AP mode) */
 	if (is_ap &&
 	    new_state == IEEE80211_STA_AUTHORIZED) {
-		ret = wl12xx_cmd_set_peer_state(wl, wlvif, hlid);
+		ret = wl12xx_cmd_set_peer_state(wl, wlvif, wl_sta->hlid);
 		if (ret < 0)
 			return ret;
 
 		ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true,
-						     hlid);
+						     wl_sta->hlid);
 		if (ret)
 			return ret;
 
-- 
1.7.10.4


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

* [PATCH 05/13] wlcore: consolidate tx_seq handling on recovery
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (3 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 04/13] wlcore: don't risk using stale HLID during .sta_state callback Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 06/13] wlcore: report rssi from roaming statistics Luciano Coelho
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Arik Nemtsov

From: Arik Nemtsov <arik@wizery.com>

Accumulate the total number of sent packets per-link to find out how far
the encryption sequence number has progressed. Use this number as the
initial security sequence number after recovery.

This consolidates security sequence handling for both chip families, as
we no longer have to rely on 12xx specific Tx completion.

A fortunate side effect of this is correct management of seq numbers for
AP roles and multi-role scenarios.

When a link is removed we save the last seq number on a persistent part
of the wlvif. This helps the data survive through recoveries/suspends,
which also entail changes in the hlid of the link.

This functionality is STA only currently.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/cmd.c      |   26 ++++++++++++++
 drivers/net/wireless/ti/wlcore/debugfs.c  |    3 +-
 drivers/net/wireless/ti/wlcore/main.c     |   55 +++++++++++++++--------------
 drivers/net/wireless/ti/wlcore/tx.c       |   19 ----------
 drivers/net/wireless/ti/wlcore/wlcore_i.h |   19 +++++-----
 5 files changed, 66 insertions(+), 56 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 6331f9e..56d248a 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -327,6 +327,14 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
 	wl->links[link].prev_freed_pkts =
 			wl->fw_status_2->counters.tx_lnk_free_pkts[link];
 	wl->links[link].wlvif = wlvif;
+
+	/*
+	 * Take saved value for total freed packets from wlvif, in case this is
+	 * recovery/resume
+	 */
+	if (wlvif->bss_type != BSS_TYPE_AP_BSS)
+		wl->links[link].total_freed_pkts = wlvif->total_freed_pkts;
+
 	*hlid = link;
 
 	wl->active_link_count++;
@@ -358,6 +366,24 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
 	wl1271_tx_reset_link_queues(wl, *hlid);
 	wl->links[*hlid].wlvif = NULL;
 
+	if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
+		/*
+		 * save the total freed packets in the wlvif, in case this is
+		 * recovery or suspend
+		 */
+		wlvif->total_freed_pkts = wl->links[*hlid].total_freed_pkts;
+
+		/*
+		 * increment the initial seq number on recovery to account for
+		 * transmitted packets that we haven't yet got in the FW status
+		 */
+		if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
+			wlvif->total_freed_pkts +=
+					WL1271_TX_SQN_POST_RECOVERY_PADDING;
+	}
+
+	wl->links[*hlid].total_freed_pkts = 0;
+
 	*hlid = WL12XX_INVALID_LINK_ID;
 	wl->active_link_count--;
 	WARN_ON_ONCE(wl->active_link_count < 0);
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index e70a7c8..c3e1f79 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -598,8 +598,7 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
 		VIF_STATE_PRINT_INT(last_rssi_event);
 		VIF_STATE_PRINT_INT(ba_support);
 		VIF_STATE_PRINT_INT(ba_allowed);
-		VIF_STATE_PRINT_LLHEX(tx_security_seq);
-		VIF_STATE_PRINT_INT(tx_security_last_seq_lsb);
+		VIF_STATE_PRINT_LLHEX(total_freed_pkts);
 	}
 
 #undef VIF_STATE_PRINT_INT
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index c3e2471..c1a60cd 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -418,13 +418,21 @@ static int wlcore_fw_status(struct wl1271 *wl,
 
 
 	for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) {
+		u8 diff;
 		lnk = &wl->links[i];
+
 		/* prevent wrap-around in freed-packets counter */
-		lnk->allocated_pkts -=
-			(status_2->counters.tx_lnk_free_pkts[i] -
-			 lnk->prev_freed_pkts) & 0xff;
+		diff = (status_2->counters.tx_lnk_free_pkts[i] -
+		       lnk->prev_freed_pkts) & 0xff;
+
+		if (diff == 0)
+			continue;
 
+		lnk->allocated_pkts -= diff;
 		lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i];
+
+		/* accumulate the prev_freed_pkts counter */
+		lnk->total_freed_pkts += diff;
 	}
 
 	/* prevent wrap-around in total blocks counter */
@@ -923,18 +931,6 @@ static void wl1271_recovery_work(struct work_struct *work)
 		goto out_unlock;
 	}
 
-	/*
-	 * Advance security sequence number to overcome potential progress
-	 * in the firmware during recovery. This doens't hurt if the network is
-	 * not encrypted.
-	 */
-	wl12xx_for_each_wlvif(wl, wlvif) {
-		if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
-		    test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
-			wlvif->tx_security_seq +=
-				WL1271_TX_SQN_POST_RECOVERY_PADDING;
-	}
-
 	/* Prevent spurious TX during FW restart */
 	wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
 
@@ -2864,10 +2860,6 @@ static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 				     wlvif->sta.klv_template_id,
 				     ACX_KEEP_ALIVE_TPL_INVALID);
 
-	/* reset TX security counters on a clean disconnect */
-	wlvif->tx_security_last_seq_lsb = 0;
-	wlvif->tx_security_seq = 0;
-
 	return 0;
 }
 
@@ -3266,6 +3258,7 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
 	u32 tx_seq_32 = 0;
 	u16 tx_seq_16 = 0;
 	u8 key_type;
+	u8 hlid;
 
 	wl1271_debug(DEBUG_MAC80211, "mac80211 set key");
 
@@ -3275,6 +3268,22 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
 		     key_conf->keylen, key_conf->flags);
 	wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
 
+	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
+		if (sta) {
+			struct wl1271_station *wl_sta = (void *)sta->drv_priv;
+			hlid = wl_sta->hlid;
+		} else {
+			hlid = wlvif->ap.bcast_hlid;
+		}
+	else
+		hlid = wlvif->sta.hlid;
+
+	if (hlid != WL12XX_INVALID_LINK_ID) {
+		u64 tx_seq = wl->links[hlid].total_freed_pkts;
+		tx_seq_32 = WL1271_TX_SECURITY_HI32(tx_seq);
+		tx_seq_16 = WL1271_TX_SECURITY_LO16(tx_seq);
+	}
+
 	switch (key_conf->cipher) {
 	case WLAN_CIPHER_SUITE_WEP40:
 	case WLAN_CIPHER_SUITE_WEP104:
@@ -3284,22 +3293,14 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
 		break;
 	case WLAN_CIPHER_SUITE_TKIP:
 		key_type = KEY_TKIP;
-
 		key_conf->hw_key_idx = key_conf->keyidx;
-		tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
-		tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
 		break;
 	case WLAN_CIPHER_SUITE_CCMP:
 		key_type = KEY_AES;
-
 		key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
-		tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
-		tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
 		break;
 	case WL1271_CIPHER_SUITE_GEM:
 		key_type = KEY_GEM;
-		tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
-		tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
 		break;
 	default:
 		wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 07a3e42..8599556 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -932,25 +932,6 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
 
 	wl->stats.retry_count += result->ack_failures;
 
-	/*
-	 * update sequence number only when relevant, i.e. only in
-	 * sessions of TKIP, AES and GEM (not in open or WEP sessions)
-	 */
-	if (info->control.hw_key &&
-	    (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP ||
-	     info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP ||
-	     info->control.hw_key->cipher == WL1271_CIPHER_SUITE_GEM)) {
-		u8 fw_lsb = result->tx_security_sequence_number_lsb;
-		u8 cur_lsb = wlvif->tx_security_last_seq_lsb;
-
-		/*
-		 * update security sequence number, taking care of potential
-		 * wrap-around
-		 */
-		wlvif->tx_security_seq += (fw_lsb - cur_lsb) & 0xff;
-		wlvif->tx_security_last_seq_lsb = fw_lsb;
-	}
-
 	/* remove private header from packet */
 	skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
 
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 508f5b0..1ae26ff 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -274,6 +274,13 @@ struct wl1271_link {
 
 	/* The wlvif this link belongs to. Might be null for global links */
 	struct wl12xx_vif *wlvif;
+
+	/*
+	 * total freed FW packets on the link - used for tracking the AES/TKIP
+	 * PN across recoveries. Re-initialized each time from the wl1271_station
+	 * structure.
+	 */
+	u64 total_freed_pkts;
 };
 
 #define WL1271_MAX_RX_FILTERS 5
@@ -449,16 +456,12 @@ struct wl12xx_vif {
 	 */
 	struct {
 		u8 persistent[0];
+
 		/*
-		 * Security sequence number
-		 *     bits 0-15: lower 16 bits part of sequence number
-		 *     bits 16-47: higher 32 bits part of sequence number
-		 *     bits 48-63: not in use
+		 * total freed FW packets on the link - used for storing the AES/TKIP
+		 * PN during recovery, as this structure is not zeroed out.
 		 */
-		u64 tx_security_seq;
-
-		/* 8 bits of the last sequence number in use */
-		u8 tx_security_last_seq_lsb;
+		u64 total_freed_pkts;
 	};
 };
 
-- 
1.7.10.4


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

* [PATCH 06/13] wlcore: report rssi from roaming statistics
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (4 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 05/13] wlcore: consolidate tx_seq handling on recovery Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 07/13] wlcore: change warn on missing lock in wlcore_queue_xx funcs Luciano Coelho
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Nadim Zubidat

From: Nadim Zubidat <nadimz@ti.com>

report the average beacon rssi which is calculated
by firmware for roaming statistics instead of the
last rx packet rssi. this results a more accurate
rssi reporting

Signed-off-by: Nadim Zubidat <nadimz@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/acx.c  |   29 ++++++++++++++++++++++++++++
 drivers/net/wireless/ti/wlcore/acx.h  |   14 ++++++++++++++
 drivers/net/wireless/ti/wlcore/main.c |   34 +++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index c796543..7a970cd 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -1736,6 +1736,35 @@ out:
 
 }
 
+int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+			    s8 *avg_rssi)
+{
+	struct acx_roaming_stats *acx;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_ACX, "acx roaming statistics");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->role_id = wlvif->role_id;
+	ret = wl1271_cmd_interrogate(wl, ACX_ROAMING_STATISTICS_TBL,
+				     acx, sizeof(*acx));
+	if (ret	< 0) {
+		wl1271_warning("acx roaming statistics failed: %d", ret);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	*avg_rssi = acx->rssi_beacon;
+out:
+	kfree(acx);
+	return ret;
+}
+
 #ifdef CONFIG_PM
 /* Set the global behaviour of RX filters - On/Off + default action */
 int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index 1a61e85..6dcfad9 100644
--- a/drivers/net/wireless/ti/wlcore/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -953,6 +953,18 @@ struct acx_rx_filter_cfg {
 	u8 fields[0];
 } __packed;
 
+struct acx_roaming_stats {
+	struct acx_header header;
+
+	u8	role_id;
+	u8	pad[3];
+	u32	missed_beacons;
+	u8	snr_data;
+	u8	snr_bacon;
+	s8	rssi_data;
+	s8	rssi_beacon;
+} __packed;
+
 enum {
 	ACX_WAKE_UP_CONDITIONS           = 0x0000,
 	ACX_MEM_CFG                      = 0x0001,
@@ -1110,6 +1122,8 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
 int wl1271_acx_fm_coex(struct wl1271 *wl);
 int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
 int wl12xx_acx_config_hangover(struct wl1271 *wl);
+int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+			    s8 *avg_rssi);
 
 #ifdef CONFIG_PM
 int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index c1a60cd..bf86c71 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5094,6 +5094,39 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
 	wlcore_hw_sta_rc_update(wl, wlvif, sta, changed);
 }
 
+static int wlcore_op_get_rssi(struct ieee80211_hw *hw,
+			       struct ieee80211_vif *vif,
+			       struct ieee80211_sta *sta,
+			       s8 *rssi_dbm)
+{
+	struct wl1271 *wl = hw->priv;
+	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
+	int ret = 0;
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi");
+
+	mutex_lock(&wl->mutex);
+
+	if (unlikely(wl->state != WLCORE_STATE_ON))
+		goto out;
+
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out_sleep;
+
+	ret = wlcore_acx_average_rssi(wl, wlvif, rssi_dbm);
+	if (ret < 0)
+		goto out_sleep;
+
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
 static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
 {
 	struct wl1271 *wl = hw->priv;
@@ -5293,6 +5326,7 @@ static const struct ieee80211_ops wl1271_ops = {
 	.assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
 	.unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx,
 	.sta_rc_update = wlcore_op_sta_rc_update,
+	.get_rssi = wlcore_op_get_rssi,
 	CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
 };
 
-- 
1.7.10.4


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

* [PATCH 07/13] wlcore: change warn on missing lock in wlcore_queue_xx funcs
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (5 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 06/13] wlcore: report rssi from roaming statistics Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 08/13] wlcore: don't attempt to roam in case of p2p Luciano Coelho
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Arik Nemtsov

From: Arik Nemtsov <arik@wizery.com>

On !CONFIG_SMP builds spin_is_locked always returns 0. Assert the
locking using assert_spin_locked, which is written to behave correctly
in all cases.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/tx.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 8599556..e0d9504 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/etherdevice.h>
+#include <linux/spinlock.h>
 
 #include "wlcore.h"
 #include "debug.h"
@@ -1289,7 +1290,7 @@ bool wlcore_is_queue_stopped_by_reason_locked(struct wl1271 *wl,
 {
 	int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
 
-	WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock));
+	assert_spin_locked(&wl->wl_lock);
 	return test_bit(reason, &wl->queue_stop_reasons[hwq]);
 }
 
@@ -1298,6 +1299,6 @@ bool wlcore_is_queue_stopped_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 {
 	int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
 
-	WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock));
+	assert_spin_locked(&wl->wl_lock);
 	return !!wl->queue_stop_reasons[hwq];
 }
-- 
1.7.10.4


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

* [PATCH 08/13] wlcore: don't attempt to roam in case of p2p
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (6 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 07/13] wlcore: change warn on missing lock in wlcore_queue_xx funcs Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 09/13] wl18xx: print chip info during boot Luciano Coelho
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Eyal Shapira

From: Eyal Shapira <eyal@wizery.com>

For STA we report beacon loss to higher levels so that wpa_s
can attempt to roam without disconnecting. In case of P2P CLI
we don't want to attempt roaming and instead disconnect immediately
upon beacon loss.

Signed-off-by: Eyal Shapira <eyal@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/event.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c
index 70f289a..67f6168 100644
--- a/drivers/net/wireless/ti/wlcore/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -237,6 +237,14 @@ void wlcore_event_beacon_loss(struct wl1271 *wl, unsigned long roles_bitmap)
 		    !test_bit(wlvif->role_id , &roles_bitmap))
 			continue;
 
+		vif = wl12xx_wlvif_to_vif(wlvif);
+
+		/* don't attempt roaming in case of p2p */
+		if (wlvif->p2p) {
+			ieee80211_connection_loss(vif);
+			continue;
+		}
+
 		/*
 		 * if the work is already queued, it should take place.
 		 * We don't want to delay the connection loss
@@ -246,7 +254,6 @@ void wlcore_event_beacon_loss(struct wl1271 *wl, unsigned long roles_bitmap)
 					     &wlvif->connection_loss_work,
 					     msecs_to_jiffies(delay));
 
-		vif = wl12xx_wlvif_to_vif(wlvif);
 		ieee80211_cqm_rssi_notify(
 				vif,
 				NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
-- 
1.7.10.4


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

* [PATCH 09/13] wl18xx: print chip info during boot
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (7 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 08/13] wlcore: don't attempt to roam in case of p2p Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 10/13] wlcore: free AP global links properly on recovery Luciano Coelho
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Victor Goldenshtein

From: Victor Goldenshtein <victorg@ti.com>

Print board type, PG with metal and ROM versions.
This might help debugging HW related issues.

Signed-off-by: Victor Goldenshtein <victorg@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wl18xx/main.c |   24 +++++++++++++++++++++++-
 drivers/net/wireless/ti/wl18xx/reg.h  |   29 +++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index b670776..9fa692d 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -1145,6 +1145,7 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
 static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
 {
 	u32 fuse;
+	s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0;
 	int ret;
 
 	ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
@@ -1155,8 +1156,29 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
 	if (ret < 0)
 		goto out;
 
+	pg_ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
+	rom = (fuse & WL18XX_ROM_VER_MASK) >> WL18XX_ROM_VER_OFFSET;
+
+	if (rom <= 0xE)
+		metal = (fuse & WL18XX_METAL_VER_MASK) >>
+			WL18XX_METAL_VER_OFFSET;
+	else
+		metal = (fuse & WL18XX_NEW_METAL_VER_MASK) >>
+			WL18XX_NEW_METAL_VER_OFFSET;
+
+	ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
+	if (ret < 0)
+		goto out;
+
+	rdl_ver = (fuse & WL18XX_RDL_VER_MASK) >> WL18XX_RDL_VER_OFFSET;
+	if (rdl_ver > RDL_MAX)
+		rdl_ver = RDL_NONE;
+
+	wl1271_info("wl18xx HW: RDL %d, %s, PG %x.%x (ROM %x)",
+		    rdl_ver, rdl_names[rdl_ver], pg_ver, metal, rom);
+
 	if (ver)
-		*ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
+		*ver = pg_ver;
 
 	ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
 
diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h
index 937b71d..6306e04 100644
--- a/drivers/net/wireless/ti/wl18xx/reg.h
+++ b/drivers/net/wireless/ti/wl18xx/reg.h
@@ -131,6 +131,16 @@
 #define WL18XX_REG_FUSE_DATA_1_3	0xA0260C
 #define WL18XX_PG_VER_MASK		0x70
 #define WL18XX_PG_VER_OFFSET		4
+#define WL18XX_ROM_VER_MASK		0x3
+#define WL18XX_ROM_VER_OFFSET		0
+#define WL18XX_METAL_VER_MASK		0xC
+#define WL18XX_METAL_VER_OFFSET		2
+#define WL18XX_NEW_METAL_VER_MASK	0x180
+#define WL18XX_NEW_METAL_VER_OFFSET	7
+
+#define WL18XX_REG_FUSE_DATA_2_3	0xA02614
+#define WL18XX_RDL_VER_MASK		0x1f00
+#define WL18XX_RDL_VER_OFFSET		8
 
 #define WL18XX_REG_FUSE_BD_ADDR_1	0xA02602
 #define WL18XX_REG_FUSE_BD_ADDR_2	0xA02606
@@ -188,4 +198,23 @@ enum {
 	NUM_BOARD_TYPES,
 };
 
+enum {
+	RDL_NONE	= 0,
+	RDL_1_HP	= 1,
+	RDL_2_SP	= 2,
+	RDL_3_HP	= 3,
+	RDL_4_SP	= 4,
+
+	_RDL_LAST,
+	RDL_MAX = _RDL_LAST - 1,
+};
+
+static const char * const rdl_names[] = {
+	[RDL_NONE]	= "",
+	[RDL_1_HP]	= "1853 SISO",
+	[RDL_2_SP]	= "1857 MIMO",
+	[RDL_3_HP]	= "1893 SISO",
+	[RDL_4_SP]	= "1897 MIMO",
+};
+
 #endif /* __REG_H__ */
-- 
1.7.10.4


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

* [PATCH 10/13] wlcore: free AP global links properly on recovery
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (8 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 09/13] wl18xx: print chip info during boot Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 11/13] wlcore: AP-mode - recover security seq num for stations Luciano Coelho
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Arik Nemtsov

From: Arik Nemtsov <arik@wizery.com>

Dont use free_sta() on AP global links. It would fail an internal check
within the function and various structures within the link struct would
not be reset.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/main.c |    3 ++-
 drivers/net/wireless/ti/wlcore/tx.c   |    3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index bf86c71..4da5584 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -2523,6 +2523,8 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
 		wl1271_ps_elp_sleep(wl);
 	}
 deinit:
+	wl12xx_tx_reset_wlvif(wl, wlvif);
+
 	/* clear all hlids (except system_hlid) */
 	wlvif->dev_hlid = WL12XX_INVALID_LINK_ID;
 
@@ -2546,7 +2548,6 @@ deinit:
 
 	dev_kfree_skb(wlvif->probereq);
 	wlvif->probereq = NULL;
-	wl12xx_tx_reset_wlvif(wl, wlvif);
 	if (wl->last_wlvif == wlvif)
 		wl->last_wlvif = NULL;
 	list_del(&wlvif->list);
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index e0d9504..85003c0 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -1047,7 +1047,8 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 
 	/* TX failure */
 	for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) {
-		if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
+		if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
+		    i != wlvif->ap.bcast_hlid && i != wlvif->ap.global_hlid) {
 			/* this calls wl12xx_free_link */
 			wl1271_free_sta(wl, wlvif, i);
 		} else {
-- 
1.7.10.4


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

* [PATCH 11/13] wlcore: AP-mode - recover security seq num for stations
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (9 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 10/13] wlcore: free AP global links properly on recovery Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 12/13] wlcore: correctly check state before regdomain conf Luciano Coelho
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Arik Nemtsov

From: Arik Nemtsov <arik@wizery.com>

Save the sequence number of the broadcast AP link in the wlvif. For each
connected station, save the sequence number in the drv_priv part of
ieee80211_sta. Use the saved numbers on recovery/resume, with the
obligatory increment on recovery.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/cmd.c      |    8 +++++++-
 drivers/net/wireless/ti/wlcore/main.c     |   28 ++++++++++++++++++++++++++++
 drivers/net/wireless/ti/wlcore/wlcore_i.h |    9 +++++++++
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 56d248a..c9e0607 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -366,7 +366,9 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
 	wl1271_tx_reset_link_queues(wl, *hlid);
 	wl->links[*hlid].wlvif = NULL;
 
-	if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
+	if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
+	    (wlvif->bss_type == BSS_TYPE_AP_BSS &&
+	     *hlid == wlvif->ap.bcast_hlid)) {
 		/*
 		 * save the total freed packets in the wlvif, in case this is
 		 * recovery or suspend
@@ -635,6 +637,10 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 	if (ret < 0)
 		goto out_free_global;
 
+	/* use the previous security seq, if this is a recovery/resume */
+	wl->links[wlvif->ap.bcast_hlid].total_freed_pkts =
+						wlvif->total_freed_pkts;
+
 	cmd->role_id = wlvif->role_id;
 	cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period);
 	cmd->ap.bss_index = WL1271_AP_BSS_INDEX;
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 4da5584..43865d1 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -4505,6 +4505,9 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
 		return -EBUSY;
 	}
 
+	/* use the previous security seq, if this is a recovery/resume */
+	wl->links[wl_sta->hlid].total_freed_pkts = wl_sta->total_freed_pkts;
+
 	set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map);
 	memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN);
 	wl->active_sta_count++;
@@ -4513,12 +4516,37 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
 
 void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
 {
+	struct wl1271_station *wl_sta;
+	struct ieee80211_sta *sta;
+	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
+
 	if (!test_bit(hlid, wlvif->ap.sta_hlid_map))
 		return;
 
 	clear_bit(hlid, wlvif->ap.sta_hlid_map);
 	__clear_bit(hlid, &wl->ap_ps_map);
 	__clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
+
+	/*
+	 * save the last used PN in the private part of iee80211_sta,
+	 * in case of recovery/suspend
+	 */
+	rcu_read_lock();
+	sta = ieee80211_find_sta(vif, wl->links[hlid].addr);
+	if (sta) {
+		wl_sta = (void *)sta->drv_priv;
+		wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts;
+
+		/*
+		 * increment the initial seq number on recovery to account for
+		 * transmitted packets that we haven't yet got in the FW status
+		 */
+		if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
+			wl_sta->total_freed_pkts +=
+					WL1271_TX_SQN_POST_RECOVERY_PADDING;
+	}
+	rcu_read_unlock();
+
 	wl12xx_free_link(wl, wlvif, &hlid);
 	wl->active_sta_count--;
 
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 1ae26ff..ea3c2bb 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -325,6 +325,13 @@ struct wl12xx_rx_filter {
 struct wl1271_station {
 	u8 hlid;
 	bool in_connection;
+
+	/*
+	 * total freed FW packets on the link to the STA - used for tracking the
+	 * AES/TKIP PN across recoveries. Re-initialized each time from the
+	 * wl1271_station structure.
+	 */
+	u64 total_freed_pkts;
 };
 
 struct wl12xx_vif {
@@ -460,6 +467,8 @@ struct wl12xx_vif {
 		/*
 		 * total freed FW packets on the link - used for storing the AES/TKIP
 		 * PN during recovery, as this structure is not zeroed out.
+		 * For STA this holds the PN of the link to the AP.
+		 * For AP this holds the PN of the broadcast link.
 		 */
 		u64 total_freed_pkts;
 	};
-- 
1.7.10.4


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

* [PATCH 12/13] wlcore: correctly check state before regdomain conf
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (10 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 11/13] wlcore: AP-mode - recover security seq num for stations Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 13:44 ` [PATCH 13/13] wlcore: consider dummy packets when tx queues are empty Luciano Coelho
  2013-03-12 15:21 ` [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Arik Nemtsov

From: Arik Nemtsov <arik@wizery.com>

The wlcore state was checked without the mutex being taken. This leads
to WARN_ONs sometimes if a notification arrives when the driver
is on, but the mutex is only taken after it is off. This usually
happens if stopping the driver while connected to a network.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/main.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 43865d1..248daa9 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -108,8 +108,7 @@ static void wl1271_reg_notify(struct wiphy *wiphy,
 
 	}
 
-	if (likely(wl->state == WLCORE_STATE_ON))
-		wlcore_regdomain_config(wl);
+	wlcore_regdomain_config(wl);
 }
 
 static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
@@ -3364,6 +3363,10 @@ void wlcore_regdomain_config(struct wl1271 *wl)
 		return;
 
 	mutex_lock(&wl->mutex);
+
+	if (unlikely(wl->state != WLCORE_STATE_ON))
+		goto out;
+
 	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
-- 
1.7.10.4


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

* [PATCH 13/13] wlcore: consider dummy packets when tx queues are empty
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (11 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 12/13] wlcore: correctly check state before regdomain conf Luciano Coelho
@ 2013-03-12 13:44 ` Luciano Coelho
  2013-03-12 15:21 ` [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
  13 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 13:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: coelho, Arik Nemtsov

From: Arik Nemtsov <arik@wizery.com>

Don't ignore dummy packets when our queues are empty. This causes dummy
packets never to be sent when traffic is not suspended by FW thresholds,
which happens only in high Tx throughput situations. This may hurt Rx
performance.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 drivers/net/wireless/ti/wlcore/tx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 85003c0..004d02e 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -644,6 +644,7 @@ next:
 
 	}
 
+out:
 	if (!skb &&
 	    test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
 		int q;
@@ -657,7 +658,6 @@ next:
 		spin_unlock_irqrestore(&wl->wl_lock, flags);
 	}
 
-out:
 	return skb;
 }
 
-- 
1.7.10.4


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

* Re: [PATCH 00/13] wlcore/wl18xx: some patches for 3.10
  2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
                   ` (12 preceding siblings ...)
  2013-03-12 13:44 ` [PATCH 13/13] wlcore: consider dummy packets when tx queues are empty Luciano Coelho
@ 2013-03-12 15:21 ` Luciano Coelho
  2013-03-25 10:35   ` Luciano Coelho
  13 siblings, 1 reply; 16+ messages in thread
From: Luciano Coelho @ 2013-03-12 15:21 UTC (permalink / raw)
  To: linux-wireless

On Tue, 2013-03-12 at 15:44 +0200, Luciano Coelho wrote:
> Hi,
> 
> These are some of the TI wireless drivers patches that are intended
> for 3.10.
> 
> A bunch of fixes and small improvements here and there.
> 
> Please review.

There were a couple of checkpatch >80 chars warnings in this series.
I'll fix them before applying.

--
Luca.


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

* Re: [PATCH 00/13] wlcore/wl18xx: some patches for 3.10
  2013-03-12 15:21 ` [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
@ 2013-03-25 10:35   ` Luciano Coelho
  0 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2013-03-25 10:35 UTC (permalink / raw)
  To: linux-wireless

On Tue, 2013-03-12 at 17:21 +0200, Luciano Coelho wrote:
> On Tue, 2013-03-12 at 15:44 +0200, Luciano Coelho wrote:
> > Hi,
> > 
> > These are some of the TI wireless drivers patches that are intended
> > for 3.10.
> > 
> > A bunch of fixes and small improvements here and there.
> > 
> > Please review.
> 
> There were a couple of checkpatch >80 chars warnings in this series.
> I'll fix them before applying.

Applied.

-- 
Luca.


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

end of thread, other threads:[~2013-03-25 10:36 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-12 13:44 [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
2013-03-12 13:44 ` [PATCH 01/13] wlcore: enter elp in force ps mode in 5ms Luciano Coelho
2013-03-12 13:44 ` [PATCH 02/13] wlcore: set max num of Rx BA sessions per chip Luciano Coelho
2013-03-12 13:44 ` [PATCH 03/13] wlcore: fix link count in single-link-PSM optimization Luciano Coelho
2013-03-12 13:44 ` [PATCH 04/13] wlcore: don't risk using stale HLID during .sta_state callback Luciano Coelho
2013-03-12 13:44 ` [PATCH 05/13] wlcore: consolidate tx_seq handling on recovery Luciano Coelho
2013-03-12 13:44 ` [PATCH 06/13] wlcore: report rssi from roaming statistics Luciano Coelho
2013-03-12 13:44 ` [PATCH 07/13] wlcore: change warn on missing lock in wlcore_queue_xx funcs Luciano Coelho
2013-03-12 13:44 ` [PATCH 08/13] wlcore: don't attempt to roam in case of p2p Luciano Coelho
2013-03-12 13:44 ` [PATCH 09/13] wl18xx: print chip info during boot Luciano Coelho
2013-03-12 13:44 ` [PATCH 10/13] wlcore: free AP global links properly on recovery Luciano Coelho
2013-03-12 13:44 ` [PATCH 11/13] wlcore: AP-mode - recover security seq num for stations Luciano Coelho
2013-03-12 13:44 ` [PATCH 12/13] wlcore: correctly check state before regdomain conf Luciano Coelho
2013-03-12 13:44 ` [PATCH 13/13] wlcore: consider dummy packets when tx queues are empty Luciano Coelho
2013-03-12 15:21 ` [PATCH 00/13] wlcore/wl18xx: some patches for 3.10 Luciano Coelho
2013-03-25 10:35   ` Luciano Coelho

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