Merge tag 'staging-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[sfrench/cifs-2.6.git] / drivers / staging / rtl8192e / rtl819x_BAProc.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
4  *
5  * Contact Information: wlanfae <wlanfae@realtek.com>
6  */
7 #include <asm/byteorder.h>
8 #include <asm/unaligned.h>
9 #include <linux/etherdevice.h>
10 #include "rtllib.h"
11 #include "rtl819x_BA.h"
12
13 static void activate_ba_entry(struct ba_record *ba, u16 time)
14 {
15         ba->b_valid = true;
16         if (time != 0)
17                 mod_timer(&ba->timer, jiffies + msecs_to_jiffies(time));
18 }
19
20 static void deactivate_ba_entry(struct rtllib_device *ieee, struct ba_record *ba)
21 {
22         ba->b_valid = false;
23         del_timer_sync(&ba->timer);
24 }
25
26 static u8 tx_ts_delete_ba(struct rtllib_device *ieee, struct tx_ts_record *ts)
27 {
28         struct ba_record *admitted_ba = &ts->tx_admitted_ba_record;
29         struct ba_record *pending_ba = &ts->tx_pending_ba_record;
30         u8 send_del_ba = false;
31
32         if (pending_ba->b_valid) {
33                 deactivate_ba_entry(ieee, pending_ba);
34                 send_del_ba = true;
35         }
36
37         if (admitted_ba->b_valid) {
38                 deactivate_ba_entry(ieee, admitted_ba);
39                 send_del_ba = true;
40         }
41         return send_del_ba;
42 }
43
44 static u8 rx_ts_delete_ba(struct rtllib_device *ieee, struct rx_ts_record *ts)
45 {
46         struct ba_record *ba = &ts->rx_admitted_ba_record;
47         u8                      send_del_ba = false;
48
49         if (ba->b_valid) {
50                 deactivate_ba_entry(ieee, ba);
51                 send_del_ba = true;
52         }
53
54         return send_del_ba;
55 }
56
57 void rtllib_reset_ba_entry(struct ba_record *ba)
58 {
59         ba->b_valid                      = false;
60         ba->ba_param_set.short_data      = 0;
61         ba->ba_timeout_value             = 0;
62         ba->dialog_token                 = 0;
63         ba->ba_start_seq_ctrl.short_data = 0;
64 }
65
66 static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *dst,
67                                     struct ba_record *ba,
68                                     u16 status_code, u8 type)
69 {
70         struct sk_buff *skb = NULL;
71         struct ieee80211_hdr_3addr *ba_req = NULL;
72         u8 *tag = NULL;
73         u16 len = ieee->tx_headroom + 9;
74
75         netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n",
76                    __func__, type, dst, ieee->dev);
77
78         if (!ba) {
79                 netdev_warn(ieee->dev, "ba is NULL\n");
80                 return NULL;
81         }
82         skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr));
83         if (!skb)
84                 return NULL;
85
86         memset(skb->data, 0, sizeof(struct ieee80211_hdr_3addr));
87
88         skb_reserve(skb, ieee->tx_headroom);
89
90         ba_req = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
91
92         ether_addr_copy(ba_req->addr1, dst);
93         ether_addr_copy(ba_req->addr2, ieee->dev->dev_addr);
94
95         ether_addr_copy(ba_req->addr3, ieee->current_network.bssid);
96         ba_req->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);
97
98         tag = skb_put(skb, 9);
99         *tag++ = ACT_CAT_BA;
100         *tag++ = type;
101         *tag++ = ba->dialog_token;
102
103         if (type == ACT_ADDBARSP) {
104                 put_unaligned_le16(status_code, tag);
105                 tag += 2;
106         }
107
108         put_unaligned_le16(ba->ba_param_set.short_data, tag);
109         tag += 2;
110
111         put_unaligned_le16(ba->ba_timeout_value, tag);
112         tag += 2;
113
114         if (type == ACT_ADDBAREQ) {
115                 memcpy(tag, (u8 *)&ba->ba_start_seq_ctrl, 2);
116                 tag += 2;
117         }
118
119 #ifdef VERBOSE_DEBUG
120         print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
121                              __func__, skb->len);
122 #endif
123         return skb;
124 }
125
126 static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst,
127                                     struct ba_record *ba,
128                                     enum tr_select TxRxSelect, u16 reason_code)
129 {
130         union delba_param_set del_ba_param_set;
131         struct sk_buff *skb = NULL;
132         struct ieee80211_hdr_3addr *del_ba = NULL;
133         u8 *tag = NULL;
134         u16 len = 6 + ieee->tx_headroom;
135
136         if (net_ratelimit())
137                 netdev_dbg(ieee->dev, "%s(): reason_code(%d) sentd to: %pM\n",
138                            __func__, reason_code, dst);
139
140         memset(&del_ba_param_set, 0, 2);
141
142         del_ba_param_set.field.initiator = (TxRxSelect == TX_DIR) ? 1 : 0;
143         del_ba_param_set.field.tid      = ba->ba_param_set.field.tid;
144
145         skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr));
146         if (!skb)
147                 return NULL;
148
149         skb_reserve(skb, ieee->tx_headroom);
150
151         del_ba = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
152
153         ether_addr_copy(del_ba->addr1, dst);
154         ether_addr_copy(del_ba->addr2, ieee->dev->dev_addr);
155         ether_addr_copy(del_ba->addr3, ieee->current_network.bssid);
156         del_ba->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);
157
158         tag = skb_put(skb, 6);
159
160         *tag++ = ACT_CAT_BA;
161         *tag++ = ACT_DELBA;
162
163         put_unaligned_le16(del_ba_param_set.short_data, tag);
164         tag += 2;
165
166         put_unaligned_le16(reason_code, tag);
167         tag += 2;
168
169 #ifdef VERBOSE_DEBUG
170         print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
171                              __func__, skb->len);
172 #endif
173         return skb;
174 }
175
176 static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst,
177                                  struct ba_record *ba)
178 {
179         struct sk_buff *skb;
180
181         skb = rtllib_ADDBA(ieee, dst, ba, 0, ACT_ADDBAREQ);
182
183         if (skb)
184                 softmac_mgmt_xmit(skb, ieee);
185         else
186                 netdev_dbg(ieee->dev, "Failed to generate ADDBAReq packet.\n");
187 }
188
189 static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst,
190                                  struct ba_record *ba, u16 status_code)
191 {
192         struct sk_buff *skb;
193
194         skb = rtllib_ADDBA(ieee, dst, ba, status_code, ACT_ADDBARSP);
195         if (skb)
196                 softmac_mgmt_xmit(skb, ieee);
197         else
198                 netdev_dbg(ieee->dev, "Failed to generate ADDBARsp packet.\n");
199 }
200
201 static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst,
202                               struct ba_record *ba, enum tr_select TxRxSelect,
203                               u16 reason_code)
204 {
205         struct sk_buff *skb;
206
207         skb = rtllib_DELBA(ieee, dst, ba, TxRxSelect, reason_code);
208         if (skb)
209                 softmac_mgmt_xmit(skb, ieee);
210         else
211                 netdev_dbg(ieee->dev, "Failed to generate DELBA packet.\n");
212 }
213
214 int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb)
215 {
216         struct ieee80211_hdr_3addr *req = NULL;
217         u16 rc = 0;
218         u8 *dst = NULL, *dialog_token = NULL, *tag = NULL;
219         struct ba_record *ba = NULL;
220         union ba_param_set *ba_param_set = NULL;
221         u16 *ba_timeout_value = NULL;
222         union sequence_control *ba_start_seq_ctrl = NULL;
223         struct rx_ts_record *ts = NULL;
224
225         if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) {
226                 netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n",
227                             (int)skb->len,
228                             (int)(sizeof(struct ieee80211_hdr_3addr) + 9));
229                 return -1;
230         }
231
232 #ifdef VERBOSE_DEBUG
233         print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, __func__,
234                              skb->data, skb->len);
235 #endif
236
237         req = (struct ieee80211_hdr_3addr *)skb->data;
238         tag = (u8 *)req;
239         dst = (u8 *)(&req->addr2[0]);
240         tag += sizeof(struct ieee80211_hdr_3addr);
241         dialog_token = tag + 2;
242         ba_param_set = (union ba_param_set *)(tag + 3);
243         ba_timeout_value = (u16 *)(tag + 5);
244         ba_start_seq_ctrl = (union sequence_control *)(req + 7);
245
246         if (!ieee->current_network.qos_data.active ||
247             !ieee->ht_info->current_ht_support ||
248             (ieee->ht_info->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) {
249                 rc = ADDBA_STATUS_REFUSED;
250                 netdev_warn(ieee->dev,
251                             "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n",
252                             ieee->current_network.qos_data.active,
253                             ieee->ht_info->current_ht_support);
254                 goto OnADDBAReq_Fail;
255         }
256         if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
257                    (u8)(ba_param_set->field.tid), RX_DIR, true)) {
258                 rc = ADDBA_STATUS_REFUSED;
259                 netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
260                 goto OnADDBAReq_Fail;
261         }
262         ba = &ts->rx_admitted_ba_record;
263
264         if (ba_param_set->field.ba_policy == BA_POLICY_DELAYED) {
265                 rc = ADDBA_STATUS_INVALID_PARAM;
266                 netdev_warn(ieee->dev, "%s(): BA Policy is not correct\n",
267                             __func__);
268                 goto OnADDBAReq_Fail;
269         }
270
271         rtllib_FlushRxTsPendingPkts(ieee, ts);
272
273         deactivate_ba_entry(ieee, ba);
274         ba->dialog_token = *dialog_token;
275         ba->ba_param_set = *ba_param_set;
276         ba->ba_timeout_value = *ba_timeout_value;
277         ba->ba_start_seq_ctrl = *ba_start_seq_ctrl;
278
279         if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) ||
280            (ieee->ht_info->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT))
281                 ba->ba_param_set.field.buffer_size = 1;
282         else
283                 ba->ba_param_set.field.buffer_size = 32;
284
285         activate_ba_entry(ba, 0);
286         rtllib_send_ADDBARsp(ieee, dst, ba, ADDBA_STATUS_SUCCESS);
287
288         return 0;
289
290 OnADDBAReq_Fail:
291         {
292                 struct ba_record BA;
293
294                 BA.ba_param_set = *ba_param_set;
295                 BA.ba_timeout_value = *ba_timeout_value;
296                 BA.dialog_token = *dialog_token;
297                 BA.ba_param_set.field.ba_policy = BA_POLICY_IMMEDIATE;
298                 rtllib_send_ADDBARsp(ieee, dst, &BA, rc);
299                 return 0;
300         }
301 }
302
303 int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb)
304 {
305         struct ieee80211_hdr_3addr *rsp = NULL;
306         struct ba_record *pending_ba, *admitted_ba;
307         struct tx_ts_record *ts = NULL;
308         u8 *dst = NULL, *dialog_token = NULL, *tag = NULL;
309         u16 *status_code = NULL, *ba_timeout_value = NULL;
310         union ba_param_set *ba_param_set = NULL;
311         u16                     reason_code;
312
313         if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) {
314                 netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n",
315                             (int)skb->len,
316                             (int)(sizeof(struct ieee80211_hdr_3addr) + 9));
317                 return -1;
318         }
319         rsp = (struct ieee80211_hdr_3addr *)skb->data;
320         tag = (u8 *)rsp;
321         dst = (u8 *)(&rsp->addr2[0]);
322         tag += sizeof(struct ieee80211_hdr_3addr);
323         dialog_token = tag + 2;
324         status_code = (u16 *)(tag + 3);
325         ba_param_set = (union ba_param_set *)(tag + 5);
326         ba_timeout_value = (u16 *)(tag + 7);
327
328         if (!ieee->current_network.qos_data.active ||
329             !ieee->ht_info->current_ht_support ||
330             !ieee->ht_info->current_ampdu_enable) {
331                 netdev_warn(ieee->dev,
332                             "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",
333                             ieee->current_network.qos_data.active,
334                             ieee->ht_info->current_ht_support,
335                             ieee->ht_info->current_ampdu_enable);
336                 reason_code = DELBA_REASON_UNKNOWN_BA;
337                 goto OnADDBARsp_Reject;
338         }
339
340         if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
341                    (u8)(ba_param_set->field.tid), TX_DIR, false)) {
342                 netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
343                 reason_code = DELBA_REASON_UNKNOWN_BA;
344                 goto OnADDBARsp_Reject;
345         }
346
347         ts->add_ba_req_in_progress = false;
348         pending_ba = &ts->tx_pending_ba_record;
349         admitted_ba = &ts->tx_admitted_ba_record;
350
351         if (admitted_ba->b_valid) {
352                 netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n",
353                            __func__);
354                 return -1;
355         } else if (!pending_ba->b_valid ||
356                    (*dialog_token != pending_ba->dialog_token)) {
357                 netdev_warn(ieee->dev,
358                             "%s(): ADDBA Rsp. BA invalid, DELBA!\n",
359                             __func__);
360                 reason_code = DELBA_REASON_UNKNOWN_BA;
361                 goto OnADDBARsp_Reject;
362         } else {
363                 netdev_dbg(ieee->dev,
364                            "%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n",
365                            __func__, *status_code);
366                 deactivate_ba_entry(ieee, pending_ba);
367         }
368
369         if (*status_code == ADDBA_STATUS_SUCCESS) {
370                 if (ba_param_set->field.ba_policy == BA_POLICY_DELAYED) {
371                         ts->add_ba_req_delayed = true;
372                         deactivate_ba_entry(ieee, admitted_ba);
373                         reason_code = DELBA_REASON_END_BA;
374                         goto OnADDBARsp_Reject;
375                 }
376
377                 admitted_ba->dialog_token = *dialog_token;
378                 admitted_ba->ba_timeout_value = *ba_timeout_value;
379                 admitted_ba->ba_start_seq_ctrl = pending_ba->ba_start_seq_ctrl;
380                 admitted_ba->ba_param_set = *ba_param_set;
381                 deactivate_ba_entry(ieee, admitted_ba);
382                 activate_ba_entry(admitted_ba, *ba_timeout_value);
383         } else {
384                 ts->add_ba_req_delayed = true;
385                 ts->disable_add_ba = true;
386                 reason_code = DELBA_REASON_END_BA;
387                 goto OnADDBARsp_Reject;
388         }
389
390         return 0;
391
392 OnADDBARsp_Reject:
393         {
394                 struct ba_record BA;
395
396                 BA.ba_param_set = *ba_param_set;
397                 rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, reason_code);
398                 return 0;
399         }
400 }
401
402 int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb)
403 {
404         struct ieee80211_hdr_3addr *delba = NULL;
405         union delba_param_set *del_ba_param_set = NULL;
406         u8 *dst = NULL;
407
408         if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 6) {
409                 netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n",
410                             (int)skb->len,
411                             (int)(sizeof(struct ieee80211_hdr_3addr) + 6));
412                 return -1;
413         }
414
415         if (!ieee->current_network.qos_data.active ||
416             !ieee->ht_info->current_ht_support) {
417                 netdev_warn(ieee->dev,
418                             "received DELBA while QOS or HT is not supported(%d, %d)\n",
419                             ieee->current_network. qos_data.active,
420                             ieee->ht_info->current_ht_support);
421                 return -1;
422         }
423
424 #ifdef VERBOSE_DEBUG
425         print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
426                              __func__, skb->len);
427 #endif
428         delba = (struct ieee80211_hdr_3addr *)skb->data;
429         dst = (u8 *)(&delba->addr2[0]);
430         del_ba_param_set = (union delba_param_set *)&delba->seq_ctrl + 2;
431
432         if (del_ba_param_set->field.initiator == 1) {
433                 struct rx_ts_record *ts;
434
435                 if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
436                            (u8)del_ba_param_set->field.tid, RX_DIR, false)) {
437                         netdev_warn(ieee->dev,
438                                     "%s(): can't get TS for RXTS. dst:%pM TID:%d\n",
439                                     __func__, dst,
440                                     (u8)del_ba_param_set->field.tid);
441                         return -1;
442                 }
443
444                 rx_ts_delete_ba(ieee, ts);
445         } else {
446                 struct tx_ts_record *ts;
447
448                 if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
449                            (u8)del_ba_param_set->field.tid, TX_DIR, false)) {
450                         netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n",
451                                     __func__);
452                         return -1;
453                 }
454
455                 ts->using_ba = false;
456                 ts->add_ba_req_in_progress = false;
457                 ts->add_ba_req_delayed = false;
458                 del_timer_sync(&ts->ts_add_ba_timer);
459                 tx_ts_delete_ba(ieee, ts);
460         }
461         return 0;
462 }
463
464 void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts,
465                            u8 policy, u8        overwrite_pending)
466 {
467         struct ba_record *ba = &ts->tx_pending_ba_record;
468
469         if (ba->b_valid && !overwrite_pending)
470                 return;
471
472         deactivate_ba_entry(ieee, ba);
473
474         ba->dialog_token++;
475         ba->ba_param_set.field.amsdu_support = 0;
476         ba->ba_param_set.field.ba_policy = policy;
477         ba->ba_param_set.field.tid = ts->ts_common_info.tspec.ts_id;
478         ba->ba_param_set.field.buffer_size = 32;
479         ba->ba_timeout_value = 0;
480         ba->ba_start_seq_ctrl.field.seq_num = (ts->tx_cur_seq + 3) % 4096;
481
482         activate_ba_entry(ba, BA_SETUP_TIMEOUT);
483
484         rtllib_send_ADDBAReq(ieee, ts->ts_common_info.addr, ba);
485 }
486
487 void rtllib_ts_init_del_ba(struct rtllib_device *ieee,
488                            struct ts_common_info *ts_common_info,
489                            enum tr_select TxRxSelect)
490 {
491         if (TxRxSelect == TX_DIR) {
492                 struct tx_ts_record *ts =
493                          (struct tx_ts_record *)ts_common_info;
494
495                 if (tx_ts_delete_ba(ieee, ts))
496                         rtllib_send_DELBA(ieee, ts_common_info->addr,
497                                           (ts->tx_admitted_ba_record.b_valid) ?
498                                          (&ts->tx_admitted_ba_record) :
499                                         (&ts->tx_pending_ba_record),
500                                          TxRxSelect, DELBA_REASON_END_BA);
501         } else if (TxRxSelect == RX_DIR) {
502                 struct rx_ts_record *ts =
503                                  (struct rx_ts_record *)ts_common_info;
504                 if (rx_ts_delete_ba(ieee, ts))
505                         rtllib_send_DELBA(ieee, ts_common_info->addr,
506                                           &ts->rx_admitted_ba_record,
507                                           TxRxSelect, DELBA_REASON_END_BA);
508         }
509 }
510
511 void rtllib_ba_setup_timeout(struct timer_list *t)
512 {
513         struct tx_ts_record *ts = from_timer(ts, t,
514                                               tx_pending_ba_record.timer);
515
516         ts->add_ba_req_in_progress = false;
517         ts->add_ba_req_delayed = true;
518         ts->tx_pending_ba_record.b_valid = false;
519 }
520
521 void rtllib_tx_ba_inact_timeout(struct timer_list *t)
522 {
523         struct tx_ts_record *ts = from_timer(ts, t,
524                                               tx_admitted_ba_record.timer);
525         struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
526                                      tx_ts_records[ts->num]);
527         tx_ts_delete_ba(ieee, ts);
528         rtllib_send_DELBA(ieee, ts->ts_common_info.addr,
529                           &ts->tx_admitted_ba_record, TX_DIR,
530                           DELBA_REASON_TIMEOUT);
531 }
532
533 void rtllib_rx_ba_inact_timeout(struct timer_list *t)
534 {
535         struct rx_ts_record *ts = from_timer(ts, t,
536                                               rx_admitted_ba_record.timer);
537         struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
538                                      rx_ts_records[ts->num]);
539
540         rx_ts_delete_ba(ieee, ts);
541         rtllib_send_DELBA(ieee, ts->ts_common_info.addr,
542                           &ts->rx_admitted_ba_record, RX_DIR,
543                           DELBA_REASON_TIMEOUT);
544 }