1 /****************************************************************************
3 * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
5 ****************************************************************************/
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");
17 #define BA_WINDOW_BOUNDARY 2048
19 #define SN_TO_INDEX(__ba_session_rx, __sn) (((__sn - __ba_session_rx->start_sn) & 0xFFF) % __ba_session_rx->buffer_size)
21 #define ADVANCE_EXPECTED_SN(__ba_session_rx) \
23 __ba_session_rx->expected_sn++; \
24 __ba_session_rx->expected_sn &= 0xFFF; \
27 #define FREE_BUFFER_SLOT(__ba_session_rx, __index) \
29 __ba_session_rx->occupied_slots--; \
30 __ba_session_rx->buffer[__index].active = false; \
33 #define IS_SN_LESS(sn1, sn2) ((((sn1) - (sn2)) & 0xFFF) > BA_WINDOW_BOUNDARY)
35 void slsi_rx_ba_init(struct slsi_dev
*sdev
)
39 for (i
= 0; i
< SLSI_MAX_RX_BA_SESSIONS
; i
++)
40 slsi_spinlock_create(&sdev
->rx_ba_buffer_pool
[i
].ba_lock
);
42 slsi_spinlock_create(&sdev
->rx_ba_buffer_pool_lock
);
45 static struct slsi_ba_session_rx
*slsi_rx_ba_alloc_buffer(struct net_device
*dev
)
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
;
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
);
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
];
65 slsi_spinlock_unlock(&sdev
->rx_ba_buffer_pool_lock
);
68 SLSI_NET_ERR(dev
, "No free RX BA buffer\n");
73 static void slsi_rx_ba_free_buffer(struct net_device
*dev
, struct slsi_peer
*peer
, int tid
)
75 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
76 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
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
;
83 slsi_spinlock_unlock(&sdev
->rx_ba_buffer_pool_lock
);
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
);
91 /* This code - slsi_ba_process_complete()
92 * is called in the data workqueue context with the
93 * netdev_vif mutex held.
95 void slsi_ba_process_complete(struct net_device
*dev
, bool from_ba_timer
)
97 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
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
);
104 static void slsi_ba_signal_process_complete(struct net_device
*dev
)
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;
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
);
118 slsi_skb_schedule_work(&ndev_vif
->rx_data
);
122 static void ba_add_frame_to_ba_complete(struct net_device
*dev
, struct slsi_ba_frame_desc
*frame_desc
)
124 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
126 slsi_skb_queue_tail(&ndev_vif
->ba_complete
, frame_desc
->signal
);
129 static void ba_update_expected_sn(struct net_device
*dev
,
130 struct slsi_ba_session_rx
*ba_session_rx
, u16 sn
)
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
);
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
);
146 SLSI_NET_DBG3(dev
, SLSI_RX_BA
, "Empty slot at index = %d\n", i
);
148 ADVANCE_EXPECTED_SN(ba_session_rx
);
150 ba_session_rx
->expected_sn
= sn
;
153 static void ba_complete_ready_sequence(struct net_device
*dev
,
154 struct slsi_ba_session_rx
*ba_session_rx
)
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
);
169 static void ba_scroll_window(struct net_device
*dev
,
170 struct slsi_ba_session_rx
*ba_session_rx
, u16 sn
)
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
);
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
)
183 #ifdef CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT
184 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
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;
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
);
197 if (!(((sn
- sn_temp
) & 0xFFF) > BA_WINDOW_BOUNDARY
)) {
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
)
204 new_expected_sn
= (sn_temp
+ 1) & 0xFFF;
205 ba_update_expected_sn(dev
, ba_session_rx
, new_expected_sn
);
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
)
213 ADVANCE_EXPECTED_SN(ba_session_rx
);
214 ba_add_frame_to_ba_complete(dev
, frame_desc
);
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
);
221 slsi_kfree_skb(frame_desc
->signal
);
224 if (!IS_SN_LESS(sn
, ba_session_rx
->highest_received_sn
))
225 ba_session_rx
->highest_received_sn
= sn
;
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
);
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.
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
);
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.
246 * If it lies in the window pass the frame to next process else discard the frame here.
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
);
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
,
258 slsi_kfree_skb(frame_desc
->signal
);
266 #if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE
267 static void slsi_ba_aging_timeout_handler(struct timer_list
*t
)
269 static void slsi_ba_aging_timeout_handler(unsigned long data
)
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
);
275 struct slsi_ba_session_rx
*ba_session_rx
= (struct slsi_ba_session_rx
*)data
;
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;
287 SLSI_NET_DBG3(dev
, SLSI_RX_BA
, "\n");
289 slsi_spinlock_lock(&ba_session_rx
->ba_lock
);
291 ba_session_rx
->timer_on
= false;
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.
298 temp_sn
= (ba_session_rx
->expected_sn
+ 1) & 0xFFF;
300 for (j
= 0; j
< ba_session_rx
->buffer_size
; j
++) {
301 i
= SN_TO_INDEX(ba_session_rx
, temp_sn
);
303 if (ba_session_rx
->buffer
[i
].active
) {
305 ADVANCE_EXPECTED_SN(ba_session_rx
);
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
);
314 /* advance temp sequence number and frame gap */
315 temp_sn
= (temp_sn
+ 1) & 0xFFF;
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;
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);
332 slsi_ba_signal_process_complete(dev
);
334 slsi_ba_signal_process_complete(dev
);
337 slsi_spinlock_unlock(&ba_session_rx
->ba_lock
);
341 int slsi_ba_process_frame(struct net_device
*dev
, struct slsi_peer
*peer
,
342 struct sk_buff
*skb
, u16 sequence_number
, u16 tid
)
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;
349 SLSI_NET_DBG4(dev
, SLSI_RX_BA
, "Got frame(sn=%d)\n", sequence_number
);
351 if (WARN_ON(tid
> FAPI_PRIORITY_QOS_UP7
)) {
352 SLSI_NET_ERR(dev
, "tid=%d\n", tid
);
359 slsi_spinlock_lock(&ba_session_rx
->ba_lock
);
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
);
367 frame_desc
.signal
= skb
;
368 frame_desc
.sn
= sequence_number
;
369 frame_desc
.active
= true;
371 i
= ba_consume_frame_or_get_buffer_index(dev
, peer
, ba_session_rx
, sequence_number
, &frame_desc
, &stop_timer
);
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
++;
377 SLSI_NET_DBG4(dev
, SLSI_RX_BA
, "Frame consumed - sn = %d\n", sequence_number
);
380 ba_complete_ready_sequence(dev
, ba_session_rx
);
384 * If the timer is not running (timer_on=false)
385 * Start the timer if there are holes (occupied_slots!=0)
387 * If the timer is running (timer_on=true)
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)
396 if (!ba_session_rx
->timer_on
) {
397 if (ba_session_rx
->occupied_slots
) {
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;
403 } else if (!ba_session_rx
->occupied_slots
) {
405 } else if (stop_timer
) {
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;
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
);
418 slsi_spinlock_unlock(&ba_session_rx
->ba_lock
);
420 slsi_ba_signal_process_complete(dev
);
424 bool slsi_ba_check(struct slsi_peer
*peer
, u16 tid
)
426 if (tid
> FAPI_PRIORITY_QOS_UP7
)
428 if (!peer
->ba_session_rx
[tid
])
431 return peer
->ba_session_rx
[tid
]->active
;
434 static void __slsi_rx_ba_stop(struct net_device
*dev
, struct slsi_ba_session_rx
*ba_session_rx
)
438 SLSI_NET_DBG1(dev
, SLSI_RX_BA
, "Stopping BA session: tid = %d\n", ba_session_rx
->tid
);
440 if (WARN_ON(!ba_session_rx
->active
)) {
441 SLSI_NET_ERR(dev
, "No BA session exists\n");
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
);
454 ba_session_rx
->active
= false;
457 static void slsi_rx_ba_stop_lock_held(struct net_device
*dev
, struct slsi_ba_session_rx
*ba_session_rx
)
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
);
468 static void slsi_rx_ba_stop_lock_unheld(struct net_device
*dev
, struct slsi_ba_session_rx
*ba_session_rx
)
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
);
477 slsi_spinlock_unlock(&ba_session_rx
->ba_lock
);
481 void slsi_rx_ba_stop_all(struct net_device
*dev
, struct slsi_peer
*peer
)
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
);
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
)
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
);
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
);
504 slsi_spinlock_lock(&ba_session_rx
->ba_lock
);
506 if (ba_session_rx
->active
) {
507 SLSI_NET_DBG1(dev
, SLSI_RX_BA
, "BA session already exists\n");
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",
515 slsi_spinlock_unlock(&ba_session_rx
->ba_lock
);
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
);
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);
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
);
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
);
543 slsi_spinlock_unlock(&ba_session_rx
->ba_lock
);
544 slsi_ba_signal_process_complete(dev
);
549 static void slsi_ba_process_error(struct net_device
*dev
,
550 struct slsi_ba_session_rx
*ba_session_rx
, u16 sequence_number
)
552 slsi_spinlock_lock(&ba_session_rx
->ba_lock
);
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
);
560 ba_scroll_window(dev
, ba_session_rx
, sequence_number
);
562 slsi_spinlock_unlock(&ba_session_rx
->ba_lock
);
563 slsi_ba_signal_process_complete(dev
);
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
)
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;
574 SLSI_UNUSED_PARAMETER(vif
);
575 SLSI_UNUSED_PARAMETER(peer_qsta_address
);
577 if (WARN_ON(user_priority
> FAPI_PRIORITY_QOS_UP7
)) {
578 SLSI_NET_ERR(dev
, "Invalid user_priority=%d\n", user_priority
);
583 case FAPI_DIRECTION_TRANSMIT
:
585 case FAPI_DIRECTION_RECEIVE
:
586 ba_session_rx
= peer
->ba_session_rx
[user_priority
];
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
);
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
);
597 case FAPI_REASONCODE_END
:
599 slsi_rx_ba_stop_lock_unheld(dev
, ba_session_rx
);
600 slsi_rx_ba_free_buffer(dev
, peer
, user_priority
);
603 case FAPI_REASONCODE_UNSPECIFIED_REASON
:
605 slsi_ba_process_error(dev
, ba_session_rx
, sequence_number
);
608 SLSI_NET_ERR(dev
, "Invalid value: reason_code=%d\n", reason_code
);
613 SLSI_NET_ERR(dev
, "Invalid value: direction=%d\n", direction
);