[RAMEN9610-20413][9610] wlbt: SCSC Driver version 10.6.1.0
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / net / wireless / scsc / ba.c
1 /****************************************************************************
2 *
3 * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
4 *
5 ****************************************************************************/
6
7 #include "debug.h"
8 #include "dev.h"
9 #include "ba.h"
10 #include "mgt.h"
11
12 /* Age value for frames in MPDU reorder buffer */
13 static int ba_mpdu_reorder_age_timeout = 150; /* 150 milli seconds */
14 module_param(ba_mpdu_reorder_age_timeout, int, S_IRUGO | S_IWUSR);
15 MODULE_PARM_DESC(ba_mpdu_reorder_age_timeout, "Timeout (in ms) before a BA frame in Reorder buffer is passed to upper layers");
16
17 #define BA_WINDOW_BOUNDARY 2048
18
19 #define SN_TO_INDEX(__ba_session_rx, __sn) (((__sn - __ba_session_rx->start_sn) & 0xFFF) % __ba_session_rx->buffer_size)
20
21 #define ADVANCE_EXPECTED_SN(__ba_session_rx) \
22 { \
23 __ba_session_rx->expected_sn++; \
24 __ba_session_rx->expected_sn &= 0xFFF; \
25 }
26
27 #define FREE_BUFFER_SLOT(__ba_session_rx, __index) \
28 { \
29 __ba_session_rx->occupied_slots--; \
30 __ba_session_rx->buffer[__index].active = false; \
31 }
32
33 #define IS_SN_LESS(sn1, sn2) ((((sn1) - (sn2)) & 0xFFF) > BA_WINDOW_BOUNDARY)
34
35 void slsi_rx_ba_init(struct slsi_dev *sdev)
36 {
37 int i;
38
39 for (i = 0; i < SLSI_MAX_RX_BA_SESSIONS; i++)
40 slsi_spinlock_create(&sdev->rx_ba_buffer_pool[i].ba_lock);
41
42 slsi_spinlock_create(&sdev->rx_ba_buffer_pool_lock);
43 }
44
45 static struct slsi_ba_session_rx *slsi_rx_ba_alloc_buffer(struct net_device *dev)
46 {
47 struct netdev_vif *ndev_vif = netdev_priv(dev);
48 struct slsi_dev *sdev = ndev_vif->sdev;
49 struct slsi_ba_session_rx *buffer = NULL;
50 int i;
51
52 SLSI_NET_DBG3(dev, SLSI_RX_BA, "RX BA buffer pool status: %d,%d,%d,%d,%d,%d,%d,%d\n",
53 sdev->rx_ba_buffer_pool[0].used, sdev->rx_ba_buffer_pool[1].used, sdev->rx_ba_buffer_pool[2].used,
54 sdev->rx_ba_buffer_pool[3].used, sdev->rx_ba_buffer_pool[4].used, sdev->rx_ba_buffer_pool[5].used,
55 sdev->rx_ba_buffer_pool[6].used, sdev->rx_ba_buffer_pool[7].used);
56
57 slsi_spinlock_lock(&sdev->rx_ba_buffer_pool_lock);
58 for (i = 0; i < SLSI_MAX_RX_BA_SESSIONS; i++) {
59 if (!sdev->rx_ba_buffer_pool[i].used) {
60 sdev->rx_ba_buffer_pool[i].used = true;
61 buffer = &sdev->rx_ba_buffer_pool[i];
62 break;
63 }
64 }
65 slsi_spinlock_unlock(&sdev->rx_ba_buffer_pool_lock);
66
67 if (!buffer)
68 SLSI_NET_ERR(dev, "No free RX BA buffer\n");
69
70 return buffer;
71 }
72
73 static void slsi_rx_ba_free_buffer(struct net_device *dev, struct slsi_peer *peer, int tid)
74 {
75 struct netdev_vif *ndev_vif = netdev_priv(dev);
76 struct slsi_dev *sdev = ndev_vif->sdev;
77
78 slsi_spinlock_lock(&sdev->rx_ba_buffer_pool_lock);
79 if (peer && peer->ba_session_rx[tid]) {
80 peer->ba_session_rx[tid]->used = false;
81 peer->ba_session_rx[tid] = NULL;
82 }
83 slsi_spinlock_unlock(&sdev->rx_ba_buffer_pool_lock);
84
85 SLSI_NET_DBG3(dev, SLSI_RX_BA, "RX BA buffer pool status: %d,%d,%d,%d,%d,%d,%d,%d\n",
86 sdev->rx_ba_buffer_pool[0].used, sdev->rx_ba_buffer_pool[1].used, sdev->rx_ba_buffer_pool[2].used,
87 sdev->rx_ba_buffer_pool[3].used, sdev->rx_ba_buffer_pool[4].used, sdev->rx_ba_buffer_pool[5].used,
88 sdev->rx_ba_buffer_pool[6].used, sdev->rx_ba_buffer_pool[7].used);
89 }
90
91 /* This code - slsi_ba_process_complete()
92 * is called in the data workqueue context with the
93 * netdev_vif mutex held.
94 */
95 void slsi_ba_process_complete(struct net_device *dev, bool from_ba_timer)
96 {
97 struct netdev_vif *ndev_vif = netdev_priv(dev);
98 struct sk_buff *skb;
99
100 while ((skb = slsi_skb_dequeue(&ndev_vif->ba_complete)) != NULL)
101 slsi_rx_data_deliver_skb(ndev_vif->sdev, dev, skb, from_ba_timer);
102 }
103
104 static void slsi_ba_signal_process_complete(struct net_device *dev)
105 {
106 struct netdev_vif *ndev_vif = netdev_priv(dev);
107 #ifdef CONFIG_SCSC_WLAN_RX_NAPI
108 struct slsi_dev *sdev = ndev_vif->sdev;
109 u32 conf_hip4_ver = 0;
110 #endif
111
112 atomic_set(&ndev_vif->ba_flush, 1);
113 #ifdef CONFIG_SCSC_WLAN_RX_NAPI
114 conf_hip4_ver = scsc_wifi_get_hip_config_version(&sdev->hip4_inst.hip_control->init);
115 if (conf_hip4_ver == 5)
116 slsi_skb_schedule_work(&ndev_vif->rx_data);
117 #else
118 slsi_skb_schedule_work(&ndev_vif->rx_data);
119 #endif
120 }
121
122 static void ba_add_frame_to_ba_complete(struct net_device *dev, struct slsi_ba_frame_desc *frame_desc)
123 {
124 struct netdev_vif *ndev_vif = netdev_priv(dev);
125
126 slsi_skb_queue_tail(&ndev_vif->ba_complete, frame_desc->signal);
127 }
128
129 static void ba_update_expected_sn(struct net_device *dev,
130 struct slsi_ba_session_rx *ba_session_rx, u16 sn)
131 {
132 u32 i, j;
133 u16 gap;
134
135 gap = (sn - ba_session_rx->expected_sn) & 0xFFF;
136 SLSI_NET_DBG3(dev, SLSI_RX_BA, "Proccess the frames up to new expected_sn = %d gap = %d\n", sn, gap);
137
138 for (j = 0; j < gap && j < ba_session_rx->buffer_size; j++) {
139 i = SN_TO_INDEX(ba_session_rx, ba_session_rx->expected_sn);
140 SLSI_NET_DBG3(dev, SLSI_RX_BA, "Proccess the slot index = %d\n", i);
141 if (ba_session_rx->buffer[i].active) {
142 ba_add_frame_to_ba_complete(dev, &ba_session_rx->buffer[i]);
143 SLSI_NET_DBG3(dev, SLSI_RX_BA, "Proccess the frame at index = %d expected_sn = %d\n", i, ba_session_rx->expected_sn);
144 FREE_BUFFER_SLOT(ba_session_rx, i);
145 } else {
146 SLSI_NET_DBG3(dev, SLSI_RX_BA, "Empty slot at index = %d\n", i);
147 }
148 ADVANCE_EXPECTED_SN(ba_session_rx);
149 }
150 ba_session_rx->expected_sn = sn;
151 }
152
153 static void ba_complete_ready_sequence(struct net_device *dev,
154 struct slsi_ba_session_rx *ba_session_rx)
155 {
156 int i;
157
158 i = SN_TO_INDEX(ba_session_rx, ba_session_rx->expected_sn);
159 while (ba_session_rx->buffer[i].active) {
160 ba_add_frame_to_ba_complete(dev, &ba_session_rx->buffer[i]);
161 SLSI_NET_DBG4(dev, SLSI_RX_BA, "Completed stored frame (expected_sn=%d) at i = %d\n",
162 ba_session_rx->expected_sn, i);
163 FREE_BUFFER_SLOT(ba_session_rx, i);
164 ADVANCE_EXPECTED_SN(ba_session_rx);
165 i = SN_TO_INDEX(ba_session_rx, ba_session_rx->expected_sn);
166 }
167 }
168
169 static void ba_scroll_window(struct net_device *dev,
170 struct slsi_ba_session_rx *ba_session_rx, u16 sn)
171 {
172 if (((sn - ba_session_rx->expected_sn) & 0xFFF) <= BA_WINDOW_BOUNDARY) {
173 ba_update_expected_sn(dev, ba_session_rx, sn);
174 ba_complete_ready_sequence(dev, ba_session_rx);
175 }
176 }
177
178 static int ba_consume_frame_or_get_buffer_index(struct net_device *dev, struct slsi_peer *peer,
179 struct slsi_ba_session_rx *ba_session_rx, u16 sn, struct slsi_ba_frame_desc *frame_desc, bool *stop_timer)
180 {
181 int i;
182 u16 sn_temp;
183 #ifdef CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT
184 struct netdev_vif *ndev_vif = netdev_priv(dev);
185 #endif
186
187 *stop_timer = false;
188
189 if (((sn - ba_session_rx->expected_sn) & 0xFFF) <= BA_WINDOW_BOUNDARY) {
190 /* Once we are in BA window, set the flag for BA trigger */
191 if (!ba_session_rx->trigger_ba_after_ssn)
192 ba_session_rx->trigger_ba_after_ssn = true;
193
194 sn_temp = ba_session_rx->expected_sn + ba_session_rx->buffer_size;
195 SLSI_NET_DBG4(dev, SLSI_RX_BA, "New frame: sn=%d\n", sn);
196
197 if (!(((sn - sn_temp) & 0xFFF) > BA_WINDOW_BOUNDARY)) {
198 u16 new_expected_sn;
199
200 SLSI_NET_DBG2(dev, SLSI_RX_BA, "Frame is out of window\n");
201 sn_temp = (sn - ba_session_rx->buffer_size) & 0xFFF;
202 if (ba_session_rx->timer_on)
203 *stop_timer = true;
204 new_expected_sn = (sn_temp + 1) & 0xFFF;
205 ba_update_expected_sn(dev, ba_session_rx, new_expected_sn);
206 }
207
208 i = -1;
209 if (sn == ba_session_rx->expected_sn) {
210 SLSI_NET_DBG4(dev, SLSI_RX_BA, "sn = ba_session_rx->expected_sn = %d\n", sn);
211 if (ba_session_rx->timer_on)
212 *stop_timer = true;
213 ADVANCE_EXPECTED_SN(ba_session_rx);
214 ba_add_frame_to_ba_complete(dev, frame_desc);
215 } else {
216 i = SN_TO_INDEX(ba_session_rx, sn);
217 SLSI_NET_DBG4(dev, SLSI_RX_BA, "sn (%d) != ba_session_rx->expected_sn(%d), i = %d\n", sn, ba_session_rx->expected_sn, i);
218 if (ba_session_rx->buffer[i].active) {
219 SLSI_NET_DBG3(dev, SLSI_RX_BA, "free frame at i = %d\n", i);
220 i = -1;
221 slsi_kfree_skb(frame_desc->signal);
222 }
223 }
224 if (!IS_SN_LESS(sn, ba_session_rx->highest_received_sn))
225 ba_session_rx->highest_received_sn = sn;
226 } else {
227 i = -1;
228 if (!ba_session_rx->trigger_ba_after_ssn) {
229 SLSI_NET_DBG3(dev, SLSI_RX_BA, "frame before ssn, pass it up: sn=%d\n", sn);
230 ba_add_frame_to_ba_complete(dev, frame_desc);
231 } else {
232 if (slsi_is_tdls_peer(dev, peer)) {
233 /* Don't drop old frames in TDLS AMPDU-reordering for interoperability with third party devices.
234 * When the TDLS link is established the peer sends few packets with AP's sequence number.
235 * BA reorder logic updates the expected sequence number. After that peer sends packets with
236 * starting sequence number negotiated in BA (0). But those frames are getting dropped here.
237 * Because of this TCP traffic does not work and TDLS link is getting disconnected.
238 */
239 SLSI_NET_DBG1(dev, SLSI_RX_BA, "tdls: forward old frame: sn=%d, expected_sn=%d\n", sn, ba_session_rx->expected_sn);
240 ba_add_frame_to_ba_complete(dev, frame_desc);
241 } else {
242 /* this frame is deemed as old. But it may so happen that the reorder process did not wait long
243 * enough for this frame and moved to new window. So check here that the current frame still lies in
244 * originators transmit window by comparing it with highest sequence number received from originator.
245 *
246 * If it lies in the window pass the frame to next process else discard the frame here.
247 */
248 if (IS_SN_LESS(ba_session_rx->highest_received_sn, (((sn + ba_session_rx->buffer_size) & 0xFFF) - 1))) {
249 SLSI_NET_DBG4(dev, SLSI_RX_BA, "old frame, but still in window: sn=%d, highest_received_sn=%d\n", sn, ba_session_rx->highest_received_sn);
250 ba_add_frame_to_ba_complete(dev, frame_desc);
251 } else {
252 SLSI_NET_DBG1(dev, SLSI_RX_BA, "old frame, drop: sn=%d, expected_sn=%d\n", sn, ba_session_rx->expected_sn);
253 #ifdef CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT
254 if (ndev_vif->enhanced_arp_detect_enabled)
255 slsi_fill_enhanced_arp_out_of_order_drop_counter(ndev_vif,
256 frame_desc->signal);
257 #endif
258 slsi_kfree_skb(frame_desc->signal);
259 }
260 }
261 }
262 }
263 return i;
264 }
265
266 #if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE
267 static void slsi_ba_aging_timeout_handler(struct timer_list *t)
268 #else
269 static void slsi_ba_aging_timeout_handler(unsigned long data)
270 #endif
271 {
272 #if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE
273 struct slsi_ba_session_rx *ba_session_rx = from_timer(ba_session_rx, t, ba_age_timer);
274 #else
275 struct slsi_ba_session_rx *ba_session_rx = (struct slsi_ba_session_rx *)data;
276 #endif
277 u8 i, j;
278 u8 gap = 1;
279 u16 temp_sn;
280 struct net_device *dev = ba_session_rx->dev;
281 #ifdef CONFIG_SCSC_WLAN_RX_NAPI
282 struct netdev_vif *ndev_vif = netdev_priv(dev);
283 struct slsi_dev *sdev = ndev_vif->sdev;
284 u32 conf_hip4_ver = 0;
285 #endif
286
287 SLSI_NET_DBG3(dev, SLSI_RX_BA, "\n");
288
289 slsi_spinlock_lock(&ba_session_rx->ba_lock);
290
291 ba_session_rx->timer_on = false;
292
293 if (ba_session_rx->active && ba_session_rx->occupied_slots) {
294 /* expected sequence has not arrived so start searching from next
295 * sequence number until a frame is available and determine the gap.
296 * Release all the frames upto next hole from the reorder buffer.
297 */
298 temp_sn = (ba_session_rx->expected_sn + 1) & 0xFFF;
299
300 for (j = 0; j < ba_session_rx->buffer_size; j++) {
301 i = SN_TO_INDEX(ba_session_rx, temp_sn);
302
303 if (ba_session_rx->buffer[i].active) {
304 while (gap--)
305 ADVANCE_EXPECTED_SN(ba_session_rx);
306
307 SLSI_NET_DBG3(dev, SLSI_RX_BA, "Completed stored frame (expected_sn=%d) at i = %d\n", ba_session_rx->expected_sn, i);
308 ba_add_frame_to_ba_complete(dev, &ba_session_rx->buffer[i]);
309 FREE_BUFFER_SLOT(ba_session_rx, i);
310 ADVANCE_EXPECTED_SN(ba_session_rx);
311 ba_complete_ready_sequence(dev, ba_session_rx);
312 break;
313 }
314 /* advance temp sequence number and frame gap */
315 temp_sn = (temp_sn + 1) & 0xFFF;
316 gap++;
317 }
318
319 /* Check for next hole in the buffer, if hole exists create the timer for next missing frame */
320 if (ba_session_rx->occupied_slots) {
321 SLSI_NET_DBG3(dev, SLSI_RX_BA, "Timer start\n");
322 mod_timer(&ba_session_rx->ba_age_timer, jiffies + msecs_to_jiffies(ba_mpdu_reorder_age_timeout));
323 ba_session_rx->timer_on = true;
324 }
325 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
326 /* Process the data now marked as completed */
327 #ifdef CONFIG_SCSC_WLAN_RX_NAPI
328 conf_hip4_ver = scsc_wifi_get_hip_config_version(&sdev->hip4_inst.hip_control->init);
329 if (conf_hip4_ver == 4)
330 slsi_ba_process_complete(dev, true);
331 else
332 slsi_ba_signal_process_complete(dev);
333 #else
334 slsi_ba_signal_process_complete(dev);
335 #endif
336 } else {
337 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
338 }
339 }
340
341 int slsi_ba_process_frame(struct net_device *dev, struct slsi_peer *peer,
342 struct sk_buff *skb, u16 sequence_number, u16 tid)
343 {
344 int i;
345 struct slsi_ba_session_rx *ba_session_rx = peer->ba_session_rx[tid];
346 struct slsi_ba_frame_desc frame_desc;
347 bool stop_timer = false;
348
349 SLSI_NET_DBG4(dev, SLSI_RX_BA, "Got frame(sn=%d)\n", sequence_number);
350
351 if (WARN_ON(tid > FAPI_PRIORITY_QOS_UP7)) {
352 SLSI_NET_ERR(dev, "tid=%d\n", tid);
353 return -EINVAL;
354 }
355
356 if (!ba_session_rx)
357 return -EINVAL;
358
359 slsi_spinlock_lock(&ba_session_rx->ba_lock);
360
361 if (!ba_session_rx->active) {
362 SLSI_NET_ERR(dev, "No BA session exists\n");
363 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
364 return -EINVAL;
365 }
366
367 frame_desc.signal = skb;
368 frame_desc.sn = sequence_number;
369 frame_desc.active = true;
370
371 i = ba_consume_frame_or_get_buffer_index(dev, peer, ba_session_rx, sequence_number, &frame_desc, &stop_timer);
372 if (i >= 0) {
373 SLSI_NET_DBG4(dev, SLSI_RX_BA, "Store frame(sn=%d) at i = %d\n", sequence_number, i);
374 ba_session_rx->buffer[i] = frame_desc;
375 ba_session_rx->occupied_slots++;
376 } else {
377 SLSI_NET_DBG4(dev, SLSI_RX_BA, "Frame consumed - sn = %d\n", sequence_number);
378 }
379
380 ba_complete_ready_sequence(dev, ba_session_rx);
381
382 /* Timer decision:
383 *
384 * If the timer is not running (timer_on=false)
385 * Start the timer if there are holes (occupied_slots!=0)
386 *
387 * If the timer is running (timer_on=true)
388 * Stop the timer if
389 * There are no holes (occupied_slots=0)
390 * Restart the timer if
391 * stop_timer=true and there are holes (occupied_slots!=0)
392 * Leave the timer running (do nothing) if
393 * stop_timer=false and there are holes (occupied_slots!=0)
394 */
395
396 if (!ba_session_rx->timer_on) {
397 if (ba_session_rx->occupied_slots) {
398 stop_timer = false;
399 SLSI_NET_DBG4(dev, SLSI_RX_BA, "Timer start\n");
400 mod_timer(&ba_session_rx->ba_age_timer, jiffies + msecs_to_jiffies(ba_mpdu_reorder_age_timeout));
401 ba_session_rx->timer_on = true;
402 }
403 } else if (!ba_session_rx->occupied_slots) {
404 stop_timer = true;
405 } else if (stop_timer) {
406 stop_timer = false;
407 SLSI_NET_DBG4(dev, SLSI_RX_BA, "Timer restart\n");
408 mod_timer(&ba_session_rx->ba_age_timer, jiffies + msecs_to_jiffies(ba_mpdu_reorder_age_timeout));
409 ba_session_rx->timer_on = true;
410 }
411
412 if (stop_timer) {
413 ba_session_rx->timer_on = false;
414 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
415 SLSI_NET_DBG4(dev, SLSI_RX_BA, "Timer stop\n");
416 del_timer_sync(&ba_session_rx->ba_age_timer);
417 } else {
418 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
419 }
420 slsi_ba_signal_process_complete(dev);
421 return 0;
422 }
423
424 bool slsi_ba_check(struct slsi_peer *peer, u16 tid)
425 {
426 if (tid > FAPI_PRIORITY_QOS_UP7)
427 return false;
428 if (!peer->ba_session_rx[tid])
429 return false;
430
431 return peer->ba_session_rx[tid]->active;
432 }
433
434 static void __slsi_rx_ba_stop(struct net_device *dev, struct slsi_ba_session_rx *ba_session_rx)
435 {
436 u8 i, j;
437
438 SLSI_NET_DBG1(dev, SLSI_RX_BA, "Stopping BA session: tid = %d\n", ba_session_rx->tid);
439
440 if (WARN_ON(!ba_session_rx->active)) {
441 SLSI_NET_ERR(dev, "No BA session exists\n");
442 return;
443 }
444
445 for (i = SN_TO_INDEX(ba_session_rx, ba_session_rx->expected_sn), j = 0;
446 j < ba_session_rx->buffer_size; i++, j++) {
447 i %= ba_session_rx->buffer_size;
448 if (ba_session_rx->buffer[i].active) {
449 ba_add_frame_to_ba_complete(dev, &ba_session_rx->buffer[i]);
450 SLSI_NET_DBG3(dev, SLSI_RX_BA, "Completed stored frame at i = %d\n", i);
451 FREE_BUFFER_SLOT(ba_session_rx, i);
452 }
453 }
454 ba_session_rx->active = false;
455 }
456
457 static void slsi_rx_ba_stop_lock_held(struct net_device *dev, struct slsi_ba_session_rx *ba_session_rx)
458 {
459 __slsi_rx_ba_stop(dev, ba_session_rx);
460 if (ba_session_rx->timer_on) {
461 ba_session_rx->timer_on = false;
462 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
463 del_timer_sync(&ba_session_rx->ba_age_timer);
464 slsi_spinlock_lock(&ba_session_rx->ba_lock);
465 }
466 }
467
468 static void slsi_rx_ba_stop_lock_unheld(struct net_device *dev, struct slsi_ba_session_rx *ba_session_rx)
469 {
470 slsi_spinlock_lock(&ba_session_rx->ba_lock);
471 __slsi_rx_ba_stop(dev, ba_session_rx);
472 if (ba_session_rx->timer_on) {
473 ba_session_rx->timer_on = false;
474 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
475 del_timer_sync(&ba_session_rx->ba_age_timer);
476 } else {
477 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
478 }
479 }
480
481 void slsi_rx_ba_stop_all(struct net_device *dev, struct slsi_peer *peer)
482 {
483 int i;
484
485 for (i = 0; i < NUM_BA_SESSIONS_PER_PEER; i++)
486 if (peer->ba_session_rx[i] && peer->ba_session_rx[i]->active) {
487 slsi_rx_ba_stop_lock_unheld(dev, peer->ba_session_rx[i]);
488 slsi_rx_ba_free_buffer(dev, peer, i);
489 }
490 }
491
492 static int slsi_rx_ba_start(struct net_device *dev,
493 struct slsi_ba_session_rx *ba_session_rx,
494 u16 tid, u16 buffer_size, u16 start_sn)
495 {
496 SLSI_NET_DBG1(dev, SLSI_RX_BA, "Request to start a new BA session tid=%d buffer_size=%d start_sn=%d\n",
497 tid, buffer_size, start_sn);
498
499 if (WARN_ON((!buffer_size) || (buffer_size > SLSI_BA_BUFFER_SIZE_MAX))) {
500 SLSI_NET_ERR(dev, "Invalid window size: buffer_size=%d\n", buffer_size);
501 return -EINVAL;
502 }
503
504 slsi_spinlock_lock(&ba_session_rx->ba_lock);
505
506 if (ba_session_rx->active) {
507 SLSI_NET_DBG1(dev, SLSI_RX_BA, "BA session already exists\n");
508
509 if ((ba_session_rx->buffer_size == buffer_size) &&
510 (ba_session_rx->expected_sn == start_sn)) {
511 SLSI_NET_DBG1(dev, SLSI_RX_BA,
512 "BA session tid=%d already exists. The parameters match so keep the existing session\n",
513 tid);
514
515 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
516
517 return 0;
518 }
519 SLSI_NET_DBG1(dev, SLSI_RX_BA, "Parameters don't match so stop the existing BA session: tid=%d\n", tid);
520 slsi_rx_ba_stop_lock_held(dev, ba_session_rx);
521 }
522
523 ba_session_rx->dev = dev;
524 ba_session_rx->buffer_size = buffer_size;
525 ba_session_rx->start_sn = start_sn;
526 ba_session_rx->expected_sn = start_sn;
527 ba_session_rx->highest_received_sn = 0;
528 ba_session_rx->trigger_ba_after_ssn = false;
529 ba_session_rx->tid = tid;
530 ba_session_rx->timer_on = false;
531 #if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE
532 timer_setup(&ba_session_rx->ba_age_timer, slsi_ba_aging_timeout_handler, 0);
533 #else
534 ba_session_rx->ba_age_timer.function = slsi_ba_aging_timeout_handler;
535 ba_session_rx->ba_age_timer.data = (unsigned long)ba_session_rx;
536 init_timer(&ba_session_rx->ba_age_timer);
537 #endif
538
539 ba_session_rx->active = true;
540 SLSI_NET_DBG1(dev, SLSI_RX_BA, "Started a new BA session tid=%d buffer_size=%d start_sn=%d\n",
541 tid, buffer_size, start_sn);
542
543 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
544 slsi_ba_signal_process_complete(dev);
545
546 return 0;
547 }
548
549 static void slsi_ba_process_error(struct net_device *dev,
550 struct slsi_ba_session_rx *ba_session_rx, u16 sequence_number)
551 {
552 slsi_spinlock_lock(&ba_session_rx->ba_lock);
553
554 if (WARN_ON(!ba_session_rx->active)) {
555 SLSI_NET_ERR(dev, "No BA session exists\n");
556 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
557 return;
558 }
559
560 ba_scroll_window(dev, ba_session_rx, sequence_number);
561
562 slsi_spinlock_unlock(&ba_session_rx->ba_lock);
563 slsi_ba_signal_process_complete(dev);
564 }
565
566 void slsi_handle_blockack(struct net_device *dev, struct slsi_peer *peer,
567 u16 vif, u8 *peer_qsta_address, u16 parameter_set, u16 sequence_number,
568 u16 reason_code, u16 direction)
569 {
570 struct slsi_ba_session_rx *ba_session_rx;
571 u16 user_priority = (parameter_set >> 2) & 0x000F;
572 u16 buffer_size = (parameter_set >> 6) & 0x03FF;
573
574 SLSI_UNUSED_PARAMETER(vif);
575 SLSI_UNUSED_PARAMETER(peer_qsta_address);
576
577 if (WARN_ON(user_priority > FAPI_PRIORITY_QOS_UP7)) {
578 SLSI_NET_ERR(dev, "Invalid user_priority=%d\n", user_priority);
579 return;
580 }
581
582 switch (direction) {
583 case FAPI_DIRECTION_TRANSMIT:
584 break;
585 case FAPI_DIRECTION_RECEIVE:
586 ba_session_rx = peer->ba_session_rx[user_priority];
587
588 switch (reason_code) {
589 case FAPI_REASONCODE_START:
590 if (!peer->ba_session_rx[user_priority])
591 peer->ba_session_rx[user_priority] = slsi_rx_ba_alloc_buffer(dev);
592
593 if (peer->ba_session_rx[user_priority])
594 if (slsi_rx_ba_start(dev, peer->ba_session_rx[user_priority], user_priority, buffer_size, sequence_number) != 0)
595 slsi_rx_ba_free_buffer(dev, peer, user_priority);
596 break;
597 case FAPI_REASONCODE_END:
598 if (ba_session_rx) {
599 slsi_rx_ba_stop_lock_unheld(dev, ba_session_rx);
600 slsi_rx_ba_free_buffer(dev, peer, user_priority);
601 }
602 break;
603 case FAPI_REASONCODE_UNSPECIFIED_REASON:
604 if (ba_session_rx)
605 slsi_ba_process_error(dev, ba_session_rx, sequence_number);
606 break;
607 default:
608 SLSI_NET_ERR(dev, "Invalid value: reason_code=%d\n", reason_code);
609 break;
610 }
611 break;
612 default:
613 SLSI_NET_ERR(dev, "Invalid value: direction=%d\n", direction);
614 break;
615 }
616 }