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 ActivateBAEntry(struct ba_record *pBA, u16 Time) 14 { 15 pBA->b_valid = true; 16 if (Time != 0) 17 mod_timer(&pBA->timer, jiffies + msecs_to_jiffies(Time)); 18 } 19 20 static void DeActivateBAEntry(struct rtllib_device *ieee, struct ba_record *pBA) 21 { 22 pBA->b_valid = false; 23 del_timer_sync(&pBA->timer); 24 } 25 26 static u8 TxTsDeleteBA(struct rtllib_device *ieee, struct tx_ts_record *pTxTs) 27 { 28 struct ba_record *pAdmittedBa = &pTxTs->TxAdmittedBARecord; 29 struct ba_record *pPendingBa = &pTxTs->TxPendingBARecord; 30 u8 bSendDELBA = false; 31 32 if (pPendingBa->b_valid) { 33 DeActivateBAEntry(ieee, pPendingBa); 34 bSendDELBA = true; 35 } 36 37 if (pAdmittedBa->b_valid) { 38 DeActivateBAEntry(ieee, pAdmittedBa); 39 bSendDELBA = true; 40 } 41 return bSendDELBA; 42 } 43 44 static u8 RxTsDeleteBA(struct rtllib_device *ieee, struct rx_ts_record *pRxTs) 45 { 46 struct ba_record *pBa = &pRxTs->rx_admitted_ba_record; 47 u8 bSendDELBA = false; 48 49 if (pBa->b_valid) { 50 DeActivateBAEntry(ieee, pBa); 51 bSendDELBA = true; 52 } 53 54 return bSendDELBA; 55 } 56 57 void ResetBaEntry(struct ba_record *pBA) 58 { 59 pBA->b_valid = false; 60 pBA->ba_param_set.short_data = 0; 61 pBA->ba_timeout_value = 0; 62 pBA->dialog_token = 0; 63 pBA->ba_start_seq_ctrl.short_data = 0; 64 } 65 static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, 66 struct ba_record *pBA, 67 u16 StatusCode, u8 type) 68 { 69 struct sk_buff *skb = NULL; 70 struct rtllib_hdr_3addr *BAReq = NULL; 71 u8 *tag = NULL; 72 u16 len = ieee->tx_headroom + 9; 73 74 netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n", 75 __func__, type, Dst, ieee->dev); 76 77 if (!pBA) { 78 netdev_warn(ieee->dev, "pBA is NULL\n"); 79 return NULL; 80 } 81 skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); 82 if (!skb) 83 return NULL; 84 85 memset(skb->data, 0, sizeof(struct rtllib_hdr_3addr)); 86 87 skb_reserve(skb, ieee->tx_headroom); 88 89 BAReq = skb_put(skb, sizeof(struct rtllib_hdr_3addr)); 90 91 ether_addr_copy(BAReq->addr1, Dst); 92 ether_addr_copy(BAReq->addr2, ieee->dev->dev_addr); 93 94 ether_addr_copy(BAReq->addr3, ieee->current_network.bssid); 95 BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); 96 97 tag = skb_put(skb, 9); 98 *tag++ = ACT_CAT_BA; 99 *tag++ = type; 100 *tag++ = pBA->dialog_token; 101 102 if (type == ACT_ADDBARSP) { 103 put_unaligned_le16(StatusCode, tag); 104 tag += 2; 105 } 106 107 put_unaligned_le16(pBA->ba_param_set.short_data, tag); 108 tag += 2; 109 110 put_unaligned_le16(pBA->ba_timeout_value, tag); 111 tag += 2; 112 113 if (type == ACT_ADDBAREQ) { 114 memcpy(tag, (u8 *)&(pBA->ba_start_seq_ctrl), 2); 115 tag += 2; 116 } 117 118 #ifdef VERBOSE_DEBUG 119 print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data, 120 __func__, skb->len); 121 #endif 122 return skb; 123 } 124 125 static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, 126 struct ba_record *pBA, 127 enum tr_select TxRxSelect, u16 ReasonCode) 128 { 129 union delba_param_set DelbaParamSet; 130 struct sk_buff *skb = NULL; 131 struct rtllib_hdr_3addr *Delba = NULL; 132 u8 *tag = NULL; 133 u16 len = 6 + ieee->tx_headroom; 134 135 if (net_ratelimit()) 136 netdev_dbg(ieee->dev, "%s(): ReasonCode(%d) sentd to: %pM\n", 137 __func__, ReasonCode, dst); 138 139 memset(&DelbaParamSet, 0, 2); 140 141 DelbaParamSet.field.initiator = (TxRxSelect == TX_DIR) ? 1 : 0; 142 DelbaParamSet.field.tid = pBA->ba_param_set.field.tid; 143 144 skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); 145 if (!skb) 146 return NULL; 147 148 skb_reserve(skb, ieee->tx_headroom); 149 150 Delba = skb_put(skb, sizeof(struct rtllib_hdr_3addr)); 151 152 ether_addr_copy(Delba->addr1, dst); 153 ether_addr_copy(Delba->addr2, ieee->dev->dev_addr); 154 ether_addr_copy(Delba->addr3, ieee->current_network.bssid); 155 Delba->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); 156 157 tag = skb_put(skb, 6); 158 159 *tag++ = ACT_CAT_BA; 160 *tag++ = ACT_DELBA; 161 162 163 put_unaligned_le16(DelbaParamSet.short_data, tag); 164 tag += 2; 165 166 put_unaligned_le16(ReasonCode, 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 *pBA) 178 { 179 struct sk_buff *skb; 180 181 skb = rtllib_ADDBA(ieee, dst, pBA, 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 190 static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst, 191 struct ba_record *pBA, u16 StatusCode) 192 { 193 struct sk_buff *skb; 194 195 skb = rtllib_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); 196 if (skb) 197 softmac_mgmt_xmit(skb, ieee); 198 else 199 netdev_dbg(ieee->dev, "Failed to generate ADDBARsp packet.\n"); 200 } 201 202 static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst, 203 struct ba_record *pBA, enum tr_select TxRxSelect, 204 u16 ReasonCode) 205 { 206 struct sk_buff *skb; 207 208 skb = rtllib_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); 209 if (skb) 210 softmac_mgmt_xmit(skb, ieee); 211 else 212 netdev_dbg(ieee->dev, "Failed to generate DELBA packet.\n"); 213 } 214 215 int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) 216 { 217 struct rtllib_hdr_3addr *req = NULL; 218 u16 rc = 0; 219 u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; 220 struct ba_record *pBA = NULL; 221 union ba_param_set *pBaParamSet = NULL; 222 u16 *pBaTimeoutVal = NULL; 223 union sequence_control *pBaStartSeqCtrl = NULL; 224 struct rx_ts_record *pTS = NULL; 225 226 if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { 227 netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n", 228 (int)skb->len, 229 (int)(sizeof(struct rtllib_hdr_3addr) + 9)); 230 return -1; 231 } 232 233 #ifdef VERBOSE_DEBUG 234 print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, __func__, 235 skb->data, skb->len); 236 #endif 237 238 req = (struct rtllib_hdr_3addr *)skb->data; 239 tag = (u8 *)req; 240 dst = (u8 *)(&req->addr2[0]); 241 tag += sizeof(struct rtllib_hdr_3addr); 242 pDialogToken = tag + 2; 243 pBaParamSet = (union ba_param_set *)(tag + 3); 244 pBaTimeoutVal = (u16 *)(tag + 5); 245 pBaStartSeqCtrl = (union sequence_control *)(req + 7); 246 247 if (!ieee->current_network.qos_data.active || 248 !ieee->pHTInfo->bCurrentHTSupport || 249 (ieee->pHTInfo->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) { 250 rc = ADDBA_STATUS_REFUSED; 251 netdev_warn(ieee->dev, 252 "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", 253 ieee->current_network.qos_data.active, 254 ieee->pHTInfo->bCurrentHTSupport); 255 goto OnADDBAReq_Fail; 256 } 257 if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, 258 (u8)(pBaParamSet->field.tid), RX_DIR, true)) { 259 rc = ADDBA_STATUS_REFUSED; 260 netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); 261 goto OnADDBAReq_Fail; 262 } 263 pBA = &pTS->rx_admitted_ba_record; 264 265 if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) { 266 rc = ADDBA_STATUS_INVALID_PARAM; 267 netdev_warn(ieee->dev, "%s(): BA Policy is not correct\n", 268 __func__); 269 goto OnADDBAReq_Fail; 270 } 271 272 rtllib_FlushRxTsPendingPkts(ieee, pTS); 273 274 DeActivateBAEntry(ieee, pBA); 275 pBA->dialog_token = *pDialogToken; 276 pBA->ba_param_set = *pBaParamSet; 277 pBA->ba_timeout_value = *pBaTimeoutVal; 278 pBA->ba_start_seq_ctrl = *pBaStartSeqCtrl; 279 280 if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) || 281 (ieee->pHTInfo->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT)) 282 pBA->ba_param_set.field.buffer_size = 1; 283 else 284 pBA->ba_param_set.field.buffer_size = 32; 285 286 ActivateBAEntry(pBA, 0); 287 rtllib_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS); 288 289 return 0; 290 291 OnADDBAReq_Fail: 292 { 293 struct ba_record BA; 294 295 BA.ba_param_set = *pBaParamSet; 296 BA.ba_timeout_value = *pBaTimeoutVal; 297 BA.dialog_token = *pDialogToken; 298 BA.ba_param_set.field.ba_policy = BA_POLICY_IMMEDIATE; 299 rtllib_send_ADDBARsp(ieee, dst, &BA, rc); 300 return 0; 301 } 302 } 303 304 int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) 305 { 306 struct rtllib_hdr_3addr *rsp = NULL; 307 struct ba_record *pPendingBA, *pAdmittedBA; 308 struct tx_ts_record *pTS = NULL; 309 u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; 310 u16 *pStatusCode = NULL, *pBaTimeoutVal = NULL; 311 union ba_param_set *pBaParamSet = NULL; 312 u16 ReasonCode; 313 314 if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { 315 netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n", 316 (int)skb->len, 317 (int)(sizeof(struct rtllib_hdr_3addr) + 9)); 318 return -1; 319 } 320 rsp = (struct rtllib_hdr_3addr *)skb->data; 321 tag = (u8 *)rsp; 322 dst = (u8 *)(&rsp->addr2[0]); 323 tag += sizeof(struct rtllib_hdr_3addr); 324 pDialogToken = tag + 2; 325 pStatusCode = (u16 *)(tag + 3); 326 pBaParamSet = (union ba_param_set *)(tag + 5); 327 pBaTimeoutVal = (u16 *)(tag + 7); 328 329 if (!ieee->current_network.qos_data.active || 330 !ieee->pHTInfo->bCurrentHTSupport || 331 !ieee->pHTInfo->bCurrentAMPDUEnable) { 332 netdev_warn(ieee->dev, 333 "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n", 334 ieee->current_network.qos_data.active, 335 ieee->pHTInfo->bCurrentHTSupport, 336 ieee->pHTInfo->bCurrentAMPDUEnable); 337 ReasonCode = DELBA_REASON_UNKNOWN_BA; 338 goto OnADDBARsp_Reject; 339 } 340 341 if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, 342 (u8)(pBaParamSet->field.tid), TX_DIR, false)) { 343 netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); 344 ReasonCode = DELBA_REASON_UNKNOWN_BA; 345 goto OnADDBARsp_Reject; 346 } 347 348 pTS->bAddBaReqInProgress = false; 349 pPendingBA = &pTS->TxPendingBARecord; 350 pAdmittedBA = &pTS->TxAdmittedBARecord; 351 352 if (pAdmittedBA->b_valid) { 353 netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n", 354 __func__); 355 return -1; 356 } else if (!pPendingBA->b_valid || 357 (*pDialogToken != pPendingBA->dialog_token)) { 358 netdev_warn(ieee->dev, 359 "%s(): ADDBA Rsp. BA invalid, DELBA!\n", 360 __func__); 361 ReasonCode = DELBA_REASON_UNKNOWN_BA; 362 goto OnADDBARsp_Reject; 363 } else { 364 netdev_dbg(ieee->dev, 365 "%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", 366 __func__, *pStatusCode); 367 DeActivateBAEntry(ieee, pPendingBA); 368 } 369 370 if (*pStatusCode == ADDBA_STATUS_SUCCESS) { 371 if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) { 372 pTS->bAddBaReqDelayed = true; 373 DeActivateBAEntry(ieee, pAdmittedBA); 374 ReasonCode = DELBA_REASON_END_BA; 375 goto OnADDBARsp_Reject; 376 } 377 378 379 pAdmittedBA->dialog_token = *pDialogToken; 380 pAdmittedBA->ba_timeout_value = *pBaTimeoutVal; 381 pAdmittedBA->ba_start_seq_ctrl = pPendingBA->ba_start_seq_ctrl; 382 pAdmittedBA->ba_param_set = *pBaParamSet; 383 DeActivateBAEntry(ieee, pAdmittedBA); 384 ActivateBAEntry(pAdmittedBA, *pBaTimeoutVal); 385 } else { 386 pTS->bAddBaReqDelayed = true; 387 pTS->bDisable_AddBa = true; 388 ReasonCode = DELBA_REASON_END_BA; 389 goto OnADDBARsp_Reject; 390 } 391 392 return 0; 393 394 OnADDBARsp_Reject: 395 { 396 struct ba_record BA; 397 398 BA.ba_param_set = *pBaParamSet; 399 rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode); 400 return 0; 401 } 402 } 403 404 int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) 405 { 406 struct rtllib_hdr_3addr *delba = NULL; 407 union delba_param_set *pDelBaParamSet = NULL; 408 u8 *dst = NULL; 409 410 if (skb->len < sizeof(struct rtllib_hdr_3addr) + 6) { 411 netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n", 412 (int)skb->len, 413 (int)(sizeof(struct rtllib_hdr_3addr) + 6)); 414 return -1; 415 } 416 417 if (!ieee->current_network.qos_data.active || 418 !ieee->pHTInfo->bCurrentHTSupport) { 419 netdev_warn(ieee->dev, 420 "received DELBA while QOS or HT is not supported(%d, %d)\n", 421 ieee->current_network. qos_data.active, 422 ieee->pHTInfo->bCurrentHTSupport); 423 return -1; 424 } 425 426 #ifdef VERBOSE_DEBUG 427 print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data, 428 __func__, skb->len); 429 #endif 430 delba = (struct rtllib_hdr_3addr *)skb->data; 431 dst = (u8 *)(&delba->addr2[0]); 432 pDelBaParamSet = (union delba_param_set *)&delba->payload[2]; 433 434 if (pDelBaParamSet->field.initiator == 1) { 435 struct rx_ts_record *pRxTs; 436 437 if (!GetTs(ieee, (struct ts_common_info **)&pRxTs, dst, 438 (u8)pDelBaParamSet->field.tid, RX_DIR, false)) { 439 netdev_warn(ieee->dev, 440 "%s(): can't get TS for RXTS. dst:%pM TID:%d\n", 441 __func__, dst, 442 (u8)pDelBaParamSet->field.tid); 443 return -1; 444 } 445 446 RxTsDeleteBA(ieee, pRxTs); 447 } else { 448 struct tx_ts_record *pTxTs; 449 450 if (!GetTs(ieee, (struct ts_common_info **)&pTxTs, dst, 451 (u8)pDelBaParamSet->field.tid, TX_DIR, false)) { 452 netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n", 453 __func__); 454 return -1; 455 } 456 457 pTxTs->bUsingBa = false; 458 pTxTs->bAddBaReqInProgress = false; 459 pTxTs->bAddBaReqDelayed = false; 460 del_timer_sync(&pTxTs->TsAddBaTimer); 461 TxTsDeleteBA(ieee, pTxTs); 462 } 463 return 0; 464 } 465 466 void TsInitAddBA(struct rtllib_device *ieee, struct tx_ts_record *pTS, 467 u8 Policy, u8 bOverwritePending) 468 { 469 struct ba_record *pBA = &pTS->TxPendingBARecord; 470 471 if (pBA->b_valid && !bOverwritePending) 472 return; 473 474 DeActivateBAEntry(ieee, pBA); 475 476 pBA->dialog_token++; 477 pBA->ba_param_set.field.amsdu_support = 0; 478 pBA->ba_param_set.field.ba_policy = Policy; 479 pBA->ba_param_set.field.tid = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID; 480 pBA->ba_param_set.field.buffer_size = 32; 481 pBA->ba_timeout_value = 0; 482 pBA->ba_start_seq_ctrl.field.seq_num = (pTS->TxCurSeq + 3) % 4096; 483 484 ActivateBAEntry(pBA, BA_SETUP_TIMEOUT); 485 486 rtllib_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA); 487 } 488 489 void TsInitDelBA(struct rtllib_device *ieee, 490 struct ts_common_info *pTsCommonInfo, 491 enum tr_select TxRxSelect) 492 { 493 if (TxRxSelect == TX_DIR) { 494 struct tx_ts_record *pTxTs = 495 (struct tx_ts_record *)pTsCommonInfo; 496 497 if (TxTsDeleteBA(ieee, pTxTs)) 498 rtllib_send_DELBA(ieee, pTsCommonInfo->Addr, 499 (pTxTs->TxAdmittedBARecord.b_valid) ? 500 (&pTxTs->TxAdmittedBARecord) : 501 (&pTxTs->TxPendingBARecord), 502 TxRxSelect, DELBA_REASON_END_BA); 503 } else if (TxRxSelect == RX_DIR) { 504 struct rx_ts_record *pRxTs = 505 (struct rx_ts_record *)pTsCommonInfo; 506 if (RxTsDeleteBA(ieee, pRxTs)) 507 rtllib_send_DELBA(ieee, pTsCommonInfo->Addr, 508 &pRxTs->rx_admitted_ba_record, 509 TxRxSelect, DELBA_REASON_END_BA); 510 } 511 } 512 513 void BaSetupTimeOut(struct timer_list *t) 514 { 515 struct tx_ts_record *pTxTs = from_timer(pTxTs, t, 516 TxPendingBARecord.timer); 517 518 pTxTs->bAddBaReqInProgress = false; 519 pTxTs->bAddBaReqDelayed = true; 520 pTxTs->TxPendingBARecord.b_valid = false; 521 } 522 523 void TxBaInactTimeout(struct timer_list *t) 524 { 525 struct tx_ts_record *pTxTs = from_timer(pTxTs, t, 526 TxAdmittedBARecord.timer); 527 struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device, 528 TxTsRecord[pTxTs->num]); 529 TxTsDeleteBA(ieee, pTxTs); 530 rtllib_send_DELBA(ieee, pTxTs->TsCommonInfo.Addr, 531 &pTxTs->TxAdmittedBARecord, TX_DIR, 532 DELBA_REASON_TIMEOUT); 533 } 534 535 void RxBaInactTimeout(struct timer_list *t) 536 { 537 struct rx_ts_record *pRxTs = from_timer(pRxTs, t, 538 rx_admitted_ba_record.timer); 539 struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, 540 RxTsRecord[pRxTs->num]); 541 542 RxTsDeleteBA(ieee, pRxTs); 543 rtllib_send_DELBA(ieee, pRxTs->ts_common_info.Addr, 544 &pRxTs->rx_admitted_ba_record, RX_DIR, 545 DELBA_REASON_TIMEOUT); 546 } 547