aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorItzhak2022-11-02 02:25:13 -0500
committerItzhak2022-11-02 02:25:13 -0500
commit7a344003463805161cbbc892f65e52a8c3afab15 (patch)
treedd6fe7096e347c47f4452660c51f04c0bb7449a5
parent50346d3272b509936d58987c7ed5a2bb6e824e40 (diff)
downloadbuild-utilites-7a344003463805161cbbc892f65e52a8c3afab15.tar.gz
build-utilites-7a344003463805161cbbc892f65e52a8c3afab15.tar.xz
build-utilites-7a344003463805161cbbc892f65e52a8c3afab15.zip
New driver must be used with firmware 8.9.1.0.0 and later.r8.8
Fixes include: - PN drift fix - High retransmission fix in QoS data during 11n BA session - WFA fixes Signed-off-by: Itzhak <shlomii@ti.com>
-rw-r--r--patches/kernel_patches/4.19.38/0023-wlcore-Fixing-PN-drift-on-encrypted-link-after-recov.patch261
1 files changed, 261 insertions, 0 deletions
diff --git a/patches/kernel_patches/4.19.38/0023-wlcore-Fixing-PN-drift-on-encrypted-link-after-recov.patch b/patches/kernel_patches/4.19.38/0023-wlcore-Fixing-PN-drift-on-encrypted-link-after-recov.patch
new file mode 100644
index 0000000..c5335aa
--- /dev/null
+++ b/patches/kernel_patches/4.19.38/0023-wlcore-Fixing-PN-drift-on-encrypted-link-after-recov.patch
@@ -0,0 +1,261 @@
1From 73dfb5ef6d7543db360248c7dad39f02c6a0c14a Mon Sep 17 00:00:00 2001
2From: Itzhak <shlomii@ti.com>
3Date: Wed, 27 Jul 2022 15:48:40 +0300
4Subject: [PATCH 23/23] wlcore: Fixing PN drift on encrypted link after recovery
5
6Signed-off-by: Itzhak <shlomii@ti.com>
7---
8 drivers/net/wireless/ti/wl18xx/main.c | 2 +
9 drivers/net/wireless/ti/wl18xx/wl18xx.h | 7 +-
10 drivers/net/wireless/ti/wlcore/cmd.c | 10 ++-
11 drivers/net/wireless/ti/wlcore/main.c | 97 +++++++++++++++++++++--
12 drivers/net/wireless/ti/wlcore/wlcore_i.h | 4 +-
13 5 files changed, 109 insertions(+), 11 deletions(-)
14
15diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
16index 1032a2f7a9a1..feded8c57da2 100644
17--- a/drivers/net/wireless/ti/wl18xx/main.c
18+++ b/drivers/net/wireless/ti/wl18xx/main.c
19@@ -1214,6 +1214,8 @@ static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
20 int_fw_status->counters.tx_released_pkts;
21 fw_status->counters.tx_lnk_free_pkts =
22 int_fw_status->counters.tx_lnk_free_pkts;
23+ fw_status->counters.tx_lnk_sec_pn16 =
24+ int_fw_status->counters.tx_lnk_sec_pn16;
25 fw_status->counters.tx_voice_released_blks =
26 int_fw_status->counters.tx_voice_released_blks;
27 fw_status->counters.tx_last_rate =
28diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
29index 5c4e8bd609a4..2c20ed3ff6b1 100644
30--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
31+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
32@@ -27,9 +27,9 @@
33 /* minimum FW required for driver */
34 #define WL18XX_CHIP_VER 8
35 #define WL18XX_IFTYPE_VER 9
36-#define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE
37+#define WL18XX_MAJOR_VER 1
38 #define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE
39-#define WL18XX_MINOR_VER 83
40+#define WL18XX_MINOR_VER 0
41
42 #define WL18XX_CMD_MAX_SIZE 740
43
44@@ -118,7 +118,8 @@ struct wl18xx_fw_packet_counters {
45
46 /* Cumulative counter of freed packets per HLID */
47 u8 tx_lnk_free_pkts[WL18XX_MAX_LINKS];
48-
49+ /* PN16 of last TKIP/AES seq-num per HLID */
50+ u16 tx_lnk_sec_pn16[WL18XX_MAX_LINKS];
51 /* Cumulative counter of released Voice memory blocks */
52 u8 tx_voice_released_blks;
53
54diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
55index 49c96a50ea87..68b4272c1eb8 100644
56--- a/drivers/net/wireless/ti/wlcore/cmd.c
57+++ b/drivers/net/wireless/ti/wlcore/cmd.c
58@@ -347,7 +347,14 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
59 wl->links[link].prev_freed_pkts =
60 wl->fw_status->counters.tx_lnk_free_pkts[link];
61 wl->links[link].wlvif = wlvif;
62-
63+ /*
64+ * take the last sec_pn16 value from the current FW status.
65+ * on recovery, we might not have fw_status yet, and
66+ * tx_lnk_sec_pn16 will be NULL. check for it.
67+ */
68+ if (wl->fw_status->counters.tx_lnk_sec_pn16)
69+ wl->links[link].prev_sec_pn16 =
70+ wl->fw_status->counters.tx_lnk_sec_pn16[link];
71 /*
72 * Take saved value for total freed packets from wlvif, in case this is
73 * recovery/resume
74@@ -376,6 +383,7 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
75
76 wl->links[*hlid].allocated_pkts = 0;
77 wl->links[*hlid].prev_freed_pkts = 0;
78+ wl->links[*hlid].prev_sec_pn16 = 0;
79 wl->links[*hlid].ba_bitmap = 0;
80 eth_zero_addr(wl->links[*hlid].addr);
81
82diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
83index d3ecb8b8cdea..3d3070a94454 100644
84--- a/drivers/net/wireless/ti/wlcore/main.c
85+++ b/drivers/net/wireless/ti/wlcore/main.c
86@@ -400,12 +400,16 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
87
88 static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status)
89 {
90+ struct wl12xx_vif *wlvifSta;
91+ struct wl12xx_vif *wlvifAp;
92 struct wl12xx_vif *wlvif;
93 u32 old_tx_blk_count = wl->tx_blocks_available;
94 int avail, freed_blocks;
95 int i;
96 int ret;
97 struct wl1271_link *lnk;
98+ bool isSta = false;
99+ bool isAp = false;
100
101 ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR,
102 wl->raw_fw_status,
103@@ -431,25 +435,88 @@ static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status)
104 wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i];
105 }
106
107+ wl12xx_for_each_wlvif_sta(wl, wlvifSta) {
108+ if (wlvifSta->sta.hlid != WL12XX_INVALID_LINK_ID) {
109+ isSta = true;
110+ break;
111+ }
112+ }
113+
114+ wl12xx_for_each_wlvif(wl, wlvifAp) {
115+ if (wlvifAp->bss_type == BSS_TYPE_AP_BSS) {
116+ isAp = true;
117+ break;
118+ }
119+ }
120
121 for_each_set_bit(i, wl->links_map, wl->num_links) {
122 u8 diff;
123+ u16 diff16;
124+
125 lnk = &wl->links[i];
126
127 /* prevent wrap-around in freed-packets counter */
128 diff = (status->counters.tx_lnk_free_pkts[i] -
129 lnk->prev_freed_pkts) & 0xff;
130
131- if (diff == 0)
132- continue;
133+ /* prevent wrap-around in pn16 counter */
134+ diff16 = (status->counters.tx_lnk_sec_pn16[i] -
135+ lnk->prev_sec_pn16) & 0xffff;
136+
137+ if (diff != 0)
138+ {
139+ lnk->allocated_pkts -= diff;
140+ lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[i];
141+ }
142
143- lnk->allocated_pkts -= diff;
144- lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[i];
145+ /* for station:
146+ * ensure pn16 is considered only after the link is authorized
147+ * Also, for recovery, wait until at least a single host generated packet is notified
148+ */
149+ if ( (isSta == true) && (i == wlvifSta->sta.hlid) && (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvifSta->flags)) && (status->counters.tx_lnk_free_pkts[i] > 0) )
150+ {
151+ if ( (wlvifSta->encryption_type == KEY_TKIP) || (wlvifSta->encryption_type == KEY_AES) )
152+ {
153+ if (diff16 != 0)
154+ {
155+ lnk->prev_sec_pn16 = status->counters.tx_lnk_sec_pn16[i];
156+ }
157+
158+ /* accumulate the prev_freed_pkts counter according to the PN from firmware */
159+ lnk->total_freed_pkts += diff16;
160+ }
161+ else
162+ {
163+ /* accumulate the prev_freed_pkts counter according to the free packets count from firmware */
164+ lnk->total_freed_pkts += diff;
165+ }
166+ }
167
168- /* accumulate the prev_freed_pkts counter */
169- lnk->total_freed_pkts += diff;
170+ /* for ap:
171+ * ensure pn16 is considered only after the AP is started and not during connection
172+ * Also, for recovery, wait until at least a single host generated packet is notified
173+ */
174+ if ( (isAp == true) && (test_bit(i, &wlvifAp->ap.sta_hlid_map[0])) && (test_bit(WLVIF_FLAG_AP_STARTED, &wlvifAp->flags)) && (wlvifAp->inconn_count == 0) && (status->counters.tx_lnk_free_pkts[i] > 0) )
175+ {
176+ if ( (wlvifAp->encryption_type == KEY_TKIP) || (wlvifAp->encryption_type == KEY_AES) )
177+ {
178+ if (diff16 != 0)
179+ {
180+ lnk->prev_sec_pn16 = status->counters.tx_lnk_sec_pn16[i];
181+ }
182+
183+ /* accumulate the prev_freed_pkts counter according to the PN from firmware */
184+ lnk->total_freed_pkts += diff16;
185+ }
186+ else
187+ {
188+ /* accumulate the prev_freed_pkts counter according to the free packets count from firmware */
189+ lnk->total_freed_pkts += diff;
190+ }
191+ }
192 }
193
194+
195 /* prevent wrap-around in total blocks counter */
196 if (likely(wl->tx_blocks_freed <= status->total_released_blks))
197 freed_blocks = status->total_released_blks -
198@@ -1993,6 +2060,7 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
199 /* The system link is always allocated */
200 wl->links[WL12XX_SYSTEM_HLID].allocated_pkts = 0;
201 wl->links[WL12XX_SYSTEM_HLID].prev_freed_pkts = 0;
202+ wl->links[WL12XX_SYSTEM_HLID].prev_sec_pn16 = 0;
203 __set_bit(WL12XX_SYSTEM_HLID, wl->links_map);
204
205 /*
206@@ -3542,6 +3610,16 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
207 u64 tx_seq = wl->links[hlid].total_freed_pkts;
208 tx_seq_32 = WL1271_TX_SECURITY_HI32(tx_seq);
209 tx_seq_16 = WL1271_TX_SECURITY_LO16(tx_seq);
210+
211+ /*
212+ * initialize previous prev_sec_pn16 to total_freed_pkts for reconnection cases so PN restarts counting.
213+ * apply it when UNICAST key is set.
214+ */
215+ if ( ( (key_conf->cipher == WLAN_CIPHER_SUITE_TKIP) || (key_conf->cipher == WLAN_CIPHER_SUITE_CCMP) ) &&
216+ (cmd == SET_KEY) && (key_conf->flags & IEEE80211_KEY_FLAG_PAIRWISE) )
217+ {
218+ wl->links[hlid].prev_sec_pn16 = tx_seq_16;
219+ }
220 }
221
222 switch (key_conf->cipher) {
223@@ -3583,6 +3661,13 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
224 wl1271_error("Could not add or replace key");
225 return ret;
226 }
227+ /*
228+ * storing ap encryption key type if it was changed
229+ */
230+ if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
231+ wlvif->encryption_type != key_type) {
232+ wlvif->encryption_type = key_type;
233+ }
234
235 /*
236 * reconfiguring arp response if the unicast (or common)
237diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
238index 7ebcb563bc20..31f81f92dd25 100644
239--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
240+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
241@@ -164,7 +164,8 @@ struct wl_fw_status {
242 * (length of the array is wl->num_links)
243 */
244 u8 *tx_lnk_free_pkts;
245-
246+ /* PN16 of last TKIP/AES seq-num per HLID */
247+ u16 *tx_lnk_sec_pn16;
248 /* Cumulative counter of released Voice memory blocks */
249 u8 tx_voice_released_blks;
250
251@@ -273,6 +274,7 @@ struct wl1271_link {
252 /* accounting for allocated / freed packets in FW */
253 u8 allocated_pkts;
254 u8 prev_freed_pkts;
255+ u16 prev_sec_pn16;
256
257 u8 addr[ETH_ALEN];
258
259--
2602.25.0.windows.1
261