diff options
author | Itzhak | 2022-11-02 02:25:13 -0500 |
---|---|---|
committer | Itzhak | 2022-11-02 02:25:13 -0500 |
commit | 7a344003463805161cbbc892f65e52a8c3afab15 (patch) | |
tree | dd6fe7096e347c47f4452660c51f04c0bb7449a5 | |
parent | 50346d3272b509936d58987c7ed5a2bb6e824e40 (diff) | |
download | build-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.patch | 261 |
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 @@ | |||
1 | From 73dfb5ef6d7543db360248c7dad39f02c6a0c14a Mon Sep 17 00:00:00 2001 | ||
2 | From: Itzhak <shlomii@ti.com> | ||
3 | Date: Wed, 27 Jul 2022 15:48:40 +0300 | ||
4 | Subject: [PATCH 23/23] wlcore: Fixing PN drift on encrypted link after recovery | ||
5 | |||
6 | Signed-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 | |||
15 | diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c | ||
16 | index 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 = | ||
28 | diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h | ||
29 | index 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 | |||
54 | diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c | ||
55 | index 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 | |||
82 | diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c | ||
83 | index 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) | ||
237 | diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h | ||
238 | index 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 | -- | ||
260 | 2.25.0.windows.1 | ||
261 | |||