1 /********************************************************************************************************************************
2 * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is
3 * related to TS, this part need some struture defined in QOS side code. Also TX RX is going to be resturctured, so how to send
4 * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
6 * *****************************************************************************************************************************/
8 #include "rtl819x_BA.h"
10 /********************************************************************************************************************
11 *function: Activate BA entry. And if Time is nozero, start timer.
12 * input: PBA_RECORD pBA //BA entry to be enabled
13 * u16 Time //indicate time delay.
15 ********************************************************************************************************************/
16 void ActivateBAEntry(struct ieee80211_device
* ieee
, PBA_RECORD pBA
, u16 Time
)
20 mod_timer(&pBA
->Timer
, jiffies
+ MSECS(Time
));
23 /********************************************************************************************************************
24 *function: deactivate BA entry, including its timer.
25 * input: PBA_RECORD pBA //BA entry to be disabled
27 ********************************************************************************************************************/
28 void DeActivateBAEntry( struct ieee80211_device
* ieee
, PBA_RECORD pBA
)
31 del_timer_sync(&pBA
->Timer
);
33 /********************************************************************************************************************
34 *function: deactivete BA entry in Tx Ts, and send DELBA.
36 * PTX_TS_RECORD pTxTs //Tx Ts which is to deactivate BA entry.
38 * notice: As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME
39 ********************************************************************************************************************/
40 u8
TxTsDeleteBA( struct ieee80211_device
* ieee
, PTX_TS_RECORD pTxTs
)
42 PBA_RECORD pAdmittedBa
= &pTxTs
->TxAdmittedBARecord
; //These two BA entries must exist in TS structure
43 PBA_RECORD pPendingBa
= &pTxTs
->TxPendingBARecord
;
44 u8 bSendDELBA
= false;
47 if(pPendingBa
->bValid
)
49 DeActivateBAEntry(ieee
, pPendingBa
);
54 if(pAdmittedBa
->bValid
)
56 DeActivateBAEntry(ieee
, pAdmittedBa
);
63 /********************************************************************************************************************
64 *function: deactivete BA entry in Tx Ts, and send DELBA.
66 * PRX_TS_RECORD pRxTs //Rx Ts which is to deactivate BA entry.
68 * notice: As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above
69 ********************************************************************************************************************/
70 u8
RxTsDeleteBA( struct ieee80211_device
* ieee
, PRX_TS_RECORD pRxTs
)
72 PBA_RECORD pBa
= &pRxTs
->RxAdmittedBARecord
;
73 u8 bSendDELBA
= false;
77 DeActivateBAEntry(ieee
, pBa
);
84 /********************************************************************************************************************
85 *function: reset BA entry
87 * PBA_RECORD pBA //entry to be reset
89 ********************************************************************************************************************/
90 void ResetBaEntry( PBA_RECORD pBA
)
93 pBA
->BaParamSet
.shortData
= 0;
94 pBA
->BaTimeoutValue
= 0;
96 pBA
->BaStartSeqCtrl
.ShortData
= 0;
98 //These functions need porting here or not?
99 /*******************************************************************************************************************************
100 *function: construct ADDBAREQ and ADDBARSP frame here together.
101 * input: u8* Dst //ADDBA frame's destination
102 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA.
103 * u16 StatusCode //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
104 * u8 type //indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
106 * return: sk_buff* skb //return constructed skb to xmit
107 *******************************************************************************************************************************/
108 static struct sk_buff
* ieee80211_ADDBA(struct ieee80211_device
* ieee
, u8
* Dst
, PBA_RECORD pBA
, u16 StatusCode
, u8 type
)
110 struct sk_buff
*skb
= NULL
;
111 struct ieee80211_hdr_3addr
* BAReq
= NULL
;
114 u16 len
= ieee
->tx_headroom
+ 9;
115 //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
116 IEEE80211_DEBUG(IEEE80211_DL_TRACE
| IEEE80211_DL_BA
, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__
, type
, Dst
, ieee
->dev
);
117 if (pBA
== NULL
||ieee
== NULL
)
119 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA
, ieee
);
122 skb
= dev_alloc_skb(len
+ sizeof( struct ieee80211_hdr_3addr
)); //need to add something others? FIXME
125 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't alloc skb for ADDBA_REQ\n");
129 memset(skb
->data
, 0, sizeof( struct ieee80211_hdr_3addr
)); //I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb.
130 skb_reserve(skb
, ieee
->tx_headroom
);
132 BAReq
= ( struct ieee80211_hdr_3addr
*) skb_put(skb
,sizeof( struct ieee80211_hdr_3addr
));
134 memcpy(BAReq
->addr1
, Dst
, ETH_ALEN
);
135 memcpy(BAReq
->addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
137 memcpy(BAReq
->addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
139 BAReq
->frame_ctl
= cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT
); //action frame
141 //tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
142 tag
= (u8
*)skb_put(skb
, 9);
146 *tag
++= pBA
->DialogToken
;
148 if (ACT_ADDBARSP
== type
)
151 printk("=====>to send ADDBARSP\n");
152 tmp
= cpu_to_le16(StatusCode
);
153 memcpy(tag
, (u8
*)&tmp
, 2);
157 tmp
= cpu_to_le16(pBA
->BaParamSet
.shortData
);
158 memcpy(tag
, (u8
*)&tmp
, 2);
161 tmp
= cpu_to_le16(pBA
->BaTimeoutValue
);
162 memcpy(tag
, (u8
*)&tmp
, 2);
165 if (ACT_ADDBAREQ
== type
)
168 memcpy(tag
,(u8
*)&(pBA
->BaStartSeqCtrl
), 2);
172 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
177 /********************************************************************************************************************
178 *function: construct DELBA frame
179 * input: u8* dst //DELBA frame's destination
180 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
181 * TR_SELECT TxRxSelect //TX RX direction
182 * u16 ReasonCode //status code.
184 * return: sk_buff* skb //return constructed skb to xmit
185 ********************************************************************************************************************/
186 static struct sk_buff
* ieee80211_DELBA(
187 struct ieee80211_device
* ieee
,
190 TR_SELECT TxRxSelect
,
194 DELBA_PARAM_SET DelbaParamSet
;
195 struct sk_buff
*skb
= NULL
;
196 struct ieee80211_hdr_3addr
* Delba
= NULL
;
199 //len = head len + DELBA Parameter Set(2) + Reason Code(2)
200 u16 len
= 6 + ieee
->tx_headroom
;
203 IEEE80211_DEBUG(IEEE80211_DL_TRACE
| IEEE80211_DL_BA
, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__
, ReasonCode
, dst
);
205 memset(&DelbaParamSet
, 0, 2);
207 DelbaParamSet
.field
.Initiator
= (TxRxSelect
==TX_DIR
)?1:0;
208 DelbaParamSet
.field
.TID
= pBA
->BaParamSet
.field
.TID
;
210 skb
= dev_alloc_skb(len
+ sizeof( struct ieee80211_hdr_3addr
)); //need to add something others? FIXME
213 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't alloc skb for ADDBA_REQ\n");
216 // memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr));
217 skb_reserve(skb
, ieee
->tx_headroom
);
219 Delba
= ( struct ieee80211_hdr_3addr
*) skb_put(skb
,sizeof( struct ieee80211_hdr_3addr
));
221 memcpy(Delba
->addr1
, dst
, ETH_ALEN
);
222 memcpy(Delba
->addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
223 memcpy(Delba
->addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
224 Delba
->frame_ctl
= cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT
); //action frame
226 tag
= (u8
*)skb_put(skb
, 6);
231 // DELBA Parameter Set
232 tmp
= cpu_to_le16(DelbaParamSet
.shortData
);
233 memcpy(tag
, (u8
*)&tmp
, 2);
236 tmp
= cpu_to_le16(ReasonCode
);
237 memcpy(tag
, (u8
*)&tmp
, 2);
240 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
242 IEEE80211_DEBUG(IEEE80211_DL_TRACE
| IEEE80211_DL_BA
, "<=====%s()\n", __FUNCTION__
);
246 /********************************************************************************************************************
247 *function: send ADDBAReq frame out
248 * input: u8* dst //ADDBAReq frame's destination
249 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
251 * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
252 ********************************************************************************************************************/
253 void ieee80211_send_ADDBAReq(struct ieee80211_device
* ieee
, u8
* dst
, PBA_RECORD pBA
)
255 struct sk_buff
*skb
= NULL
;
256 skb
= ieee80211_ADDBA(ieee
, dst
, pBA
, 0, ACT_ADDBAREQ
); //construct ACT_ADDBAREQ frames so set statuscode zero.
260 softmac_mgmt_xmit(skb
, ieee
);
261 //add statistic needed here.
262 //and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit()
267 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "alloc skb error in function %s()\n", __FUNCTION__
);
272 /********************************************************************************************************************
273 *function: send ADDBARSP frame out
274 * input: u8* dst //DELBA frame's destination
275 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
276 * u16 StatusCode //RSP StatusCode
278 * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
279 ********************************************************************************************************************/
280 void ieee80211_send_ADDBARsp(struct ieee80211_device
* ieee
, u8
* dst
, PBA_RECORD pBA
, u16 StatusCode
)
282 struct sk_buff
*skb
= NULL
;
283 skb
= ieee80211_ADDBA(ieee
, dst
, pBA
, StatusCode
, ACT_ADDBARSP
); //construct ACT_ADDBARSP frames
286 softmac_mgmt_xmit(skb
, ieee
);
291 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "alloc skb error in function %s()\n", __FUNCTION__
);
297 /********************************************************************************************************************
298 *function: send ADDBARSP frame out
299 * input: u8* dst //DELBA frame's destination
300 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
301 * TR_SELECT TxRxSelect //TX or RX
302 * u16 ReasonCode //DEL ReasonCode
304 * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
305 ********************************************************************************************************************/
307 void ieee80211_send_DELBA(struct ieee80211_device
* ieee
, u8
* dst
, PBA_RECORD pBA
, TR_SELECT TxRxSelect
, u16 ReasonCode
)
309 struct sk_buff
*skb
= NULL
;
310 skb
= ieee80211_DELBA(ieee
, dst
, pBA
, TxRxSelect
, ReasonCode
); //construct ACT_ADDBARSP frames
313 softmac_mgmt_xmit(skb
, ieee
);
318 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "alloc skb error in function %s()\n", __FUNCTION__
);
323 /********************************************************************************************************************
324 *function: RX ADDBAReq
325 * input: struct sk_buff * skb //incoming ADDBAReq skb.
326 * return: 0(pass), other(fail)
327 * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
328 ********************************************************************************************************************/
329 int ieee80211_rx_ADDBAReq( struct ieee80211_device
* ieee
, struct sk_buff
*skb
)
331 struct ieee80211_hdr_3addr
* req
= NULL
;
333 u8
* dst
= NULL
, *pDialogToken
= NULL
, *tag
= NULL
;
334 PBA_RECORD pBA
= NULL
;
335 PBA_PARAM_SET pBaParamSet
= NULL
;
336 u16
* pBaTimeoutVal
= NULL
;
337 PSEQUENCE_CONTROL pBaStartSeqCtrl
= NULL
;
338 PRX_TS_RECORD pTS
= NULL
;
340 if (skb
->len
< sizeof( struct ieee80211_hdr_3addr
) + 9)
342 IEEE80211_DEBUG(IEEE80211_DL_ERR
,
343 " Invalid skb len in BAREQ(%d / %zd)\n",
345 sizeof(struct ieee80211_hdr_3addr
) + 9);
349 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
351 req
= ( struct ieee80211_hdr_3addr
*) skb
->data
;
353 dst
= (u8
*)(&req
->addr2
[0]);
354 tag
+= sizeof( struct ieee80211_hdr_3addr
);
355 pDialogToken
= tag
+ 2; //category+action
356 pBaParamSet
= (PBA_PARAM_SET
)(tag
+ 3); //+DialogToken
357 pBaTimeoutVal
= (u16
*)(tag
+ 5);
358 pBaStartSeqCtrl
= (PSEQUENCE_CONTROL
)(req
+ 7);
360 printk("====================>rx ADDBAREQ from :%pM\n", dst
);
361 //some other capability is not ready now.
362 if( (ieee
->current_network
.qos_data
.active
== 0) ||
363 (ieee
->pHTInfo
->bCurrentHTSupport
== false) ||
364 (ieee
->pHTInfo
->IOTAction
& HT_IOT_ACT_REJECT_ADDBA_REQ
)) //||
365 // (ieee->pStaQos->bEnableRxImmBA == false) )
367 rc
= ADDBA_STATUS_REFUSED
;
368 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee
->current_network
.qos_data
.active
, ieee
->pHTInfo
->bCurrentHTSupport
);
369 goto OnADDBAReq_Fail
;
371 // Search for related traffic stream.
372 // If there is no matched TS, reject the ADDBA request.
375 (PTS_COMMON_INFO
*)(&pTS
),
377 (u8
)(pBaParamSet
->field
.TID
),
381 rc
= ADDBA_STATUS_REFUSED
;
382 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS in %s()\n", __FUNCTION__
);
383 goto OnADDBAReq_Fail
;
385 pBA
= &pTS
->RxAdmittedBARecord
;
386 // To Determine the ADDBA Req content
387 // We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl...
388 // I want to check StartSeqCtrl to make sure when we start aggregation!!!
390 if(pBaParamSet
->field
.BAPolicy
== BA_POLICY_DELAYED
)
392 rc
= ADDBA_STATUS_INVALID_PARAM
;
393 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "BA Policy is not correct in %s()\n", __FUNCTION__
);
394 goto OnADDBAReq_Fail
;
396 // Admit the ADDBA Request
398 DeActivateBAEntry(ieee
, pBA
);
399 pBA
->DialogToken
= *pDialogToken
;
400 pBA
->BaParamSet
= *pBaParamSet
;
401 pBA
->BaTimeoutValue
= *pBaTimeoutVal
;
402 pBA
->BaStartSeqCtrl
= *pBaStartSeqCtrl
;
403 //for half N mode we only aggregate 1 frame
404 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
)||
405 (ieee
->pHTInfo
->IOTAction
& HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT
))
406 pBA
->BaParamSet
.field
.BufferSize
= 1;
408 pBA
->BaParamSet
.field
.BufferSize
= 32;
409 ActivateBAEntry(ieee
, pBA
, 0);//pBA->BaTimeoutValue);
410 ieee80211_send_ADDBARsp(ieee
, dst
, pBA
, ADDBA_STATUS_SUCCESS
);
418 BA
.BaParamSet
= *pBaParamSet
;
419 BA
.BaTimeoutValue
= *pBaTimeoutVal
;
420 BA
.DialogToken
= *pDialogToken
;
421 BA
.BaParamSet
.field
.BAPolicy
= BA_POLICY_IMMEDIATE
;
422 ieee80211_send_ADDBARsp(ieee
, dst
, &BA
, rc
);
423 return 0; //we send RSP out.
428 /********************************************************************************************************************
429 *function: RX ADDBARSP
430 * input: struct sk_buff * skb //incoming ADDBAReq skb.
431 * return: 0(pass), other(fail)
432 * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
433 ********************************************************************************************************************/
434 int ieee80211_rx_ADDBARsp( struct ieee80211_device
* ieee
, struct sk_buff
*skb
)
436 struct ieee80211_hdr_3addr
* rsp
= NULL
;
437 PBA_RECORD pPendingBA
, pAdmittedBA
;
438 PTX_TS_RECORD pTS
= NULL
;
439 u8
* dst
= NULL
, *pDialogToken
= NULL
, *tag
= NULL
;
440 u16
* pStatusCode
= NULL
, *pBaTimeoutVal
= NULL
;
441 PBA_PARAM_SET pBaParamSet
= NULL
;
444 if (skb
->len
< sizeof( struct ieee80211_hdr_3addr
) + 9)
446 IEEE80211_DEBUG(IEEE80211_DL_ERR
,
447 " Invalid skb len in BARSP(%d / %zd)\n",
449 sizeof(struct ieee80211_hdr_3addr
) + 9);
452 rsp
= ( struct ieee80211_hdr_3addr
*)skb
->data
;
454 dst
= (u8
*)(&rsp
->addr2
[0]);
455 tag
+= sizeof( struct ieee80211_hdr_3addr
);
456 pDialogToken
= tag
+ 2;
457 pStatusCode
= (u16
*)(tag
+ 3);
458 pBaParamSet
= (PBA_PARAM_SET
)(tag
+ 5);
459 pBaTimeoutVal
= (u16
*)(tag
+ 7);
461 // Check the capability
462 // Since we can always receive A-MPDU, we just check if it is under HT mode.
463 if( ieee
->current_network
.qos_data
.active
== 0 ||
464 ieee
->pHTInfo
->bCurrentHTSupport
== false ||
465 ieee
->pHTInfo
->bCurrentAMPDUEnable
== false )
467 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee
->current_network
.qos_data
.active
, ieee
->pHTInfo
->bCurrentHTSupport
, ieee
->pHTInfo
->bCurrentAMPDUEnable
);
468 ReasonCode
= DELBA_REASON_UNKNOWN_BA
;
469 goto OnADDBARsp_Reject
;
474 // Search for related TS.
475 // If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame.
479 (PTS_COMMON_INFO
*)(&pTS
),
481 (u8
)(pBaParamSet
->field
.TID
),
485 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS in %s()\n", __FUNCTION__
);
486 ReasonCode
= DELBA_REASON_UNKNOWN_BA
;
487 goto OnADDBARsp_Reject
;
490 pTS
->bAddBaReqInProgress
= false;
491 pPendingBA
= &pTS
->TxPendingBARecord
;
492 pAdmittedBA
= &pTS
->TxAdmittedBARecord
;
496 // Check if related BA is waiting for setup.
497 // If not, reject by sending DELBA frame.
499 if((pAdmittedBA
->bValid
==true))
501 // Since BA is already setup, we ignore all other ADDBA Response.
502 IEEE80211_DEBUG(IEEE80211_DL_BA
, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
505 else if((pPendingBA
->bValid
== false) ||(*pDialogToken
!= pPendingBA
->DialogToken
))
507 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
508 ReasonCode
= DELBA_REASON_UNKNOWN_BA
;
509 goto OnADDBARsp_Reject
;
513 IEEE80211_DEBUG(IEEE80211_DL_BA
, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode
);
514 DeActivateBAEntry(ieee
, pPendingBA
);
518 if(*pStatusCode
== ADDBA_STATUS_SUCCESS
)
521 // Determine ADDBA Rsp content here.
522 // We can compare the value of BA parameter set that Peer returned and Self sent.
523 // If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
525 if(pBaParamSet
->field
.BAPolicy
== BA_POLICY_DELAYED
)
527 // Since this is a kind of ADDBA failed, we delay next ADDBA process.
528 pTS
->bAddBaReqDelayed
= true;
529 DeActivateBAEntry(ieee
, pAdmittedBA
);
530 ReasonCode
= DELBA_REASON_END_BA
;
531 goto OnADDBARsp_Reject
;
536 // Admitted condition
538 pAdmittedBA
->DialogToken
= *pDialogToken
;
539 pAdmittedBA
->BaTimeoutValue
= *pBaTimeoutVal
;
540 pAdmittedBA
->BaStartSeqCtrl
= pPendingBA
->BaStartSeqCtrl
;
541 pAdmittedBA
->BaParamSet
= *pBaParamSet
;
542 DeActivateBAEntry(ieee
, pAdmittedBA
);
543 ActivateBAEntry(ieee
, pAdmittedBA
, *pBaTimeoutVal
);
547 // Delay next ADDBA process.
548 pTS
->bAddBaReqDelayed
= true;
557 BA
.BaParamSet
= *pBaParamSet
;
558 ieee80211_send_DELBA(ieee
, dst
, &BA
, TX_DIR
, ReasonCode
);
564 /********************************************************************************************************************
566 * input: struct sk_buff * skb //incoming ADDBAReq skb.
567 * return: 0(pass), other(fail)
568 * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
569 ********************************************************************************************************************/
570 int ieee80211_rx_DELBA(struct ieee80211_device
* ieee
,struct sk_buff
*skb
)
572 struct ieee80211_hdr_3addr
* delba
= NULL
;
573 PDELBA_PARAM_SET pDelBaParamSet
= NULL
;
574 u16
* pReasonCode
= NULL
;
577 if (skb
->len
< sizeof( struct ieee80211_hdr_3addr
) + 6)
579 IEEE80211_DEBUG(IEEE80211_DL_ERR
,
580 " Invalid skb len in DELBA(%d / %zd)\n",
582 sizeof(struct ieee80211_hdr_3addr
) + 6);
586 if(ieee
->current_network
.qos_data
.active
== 0 ||
587 ieee
->pHTInfo
->bCurrentHTSupport
== false )
589 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee
->current_network
.qos_data
.active
, ieee
->pHTInfo
->bCurrentHTSupport
);
593 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
594 delba
= ( struct ieee80211_hdr_3addr
*)skb
->data
;
595 dst
= (u8
*)(&delba
->addr2
[0]);
596 delba
+= sizeof( struct ieee80211_hdr_3addr
);
597 pDelBaParamSet
= (PDELBA_PARAM_SET
)(delba
+2);
598 pReasonCode
= (u16
*)(delba
+4);
600 if(pDelBaParamSet
->field
.Initiator
== 1)
606 (PTS_COMMON_INFO
*)&pRxTs
,
608 (u8
)pDelBaParamSet
->field
.TID
,
612 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS for RXTS in %s()\n", __FUNCTION__
);
616 RxTsDeleteBA(ieee
, pRxTs
);
624 (PTS_COMMON_INFO
*)&pTxTs
,
626 (u8
)pDelBaParamSet
->field
.TID
,
630 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS for TXTS in %s()\n", __FUNCTION__
);
634 pTxTs
->bUsingBa
= false;
635 pTxTs
->bAddBaReqInProgress
= false;
636 pTxTs
->bAddBaReqDelayed
= false;
637 del_timer_sync(&pTxTs
->TsAddBaTimer
);
638 //PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer);
639 TxTsDeleteBA(ieee
, pTxTs
);
645 // ADDBA initiate. This can only be called by TX side.
649 struct ieee80211_device
* ieee
,
655 PBA_RECORD pBA
= &pTS
->TxPendingBARecord
;
657 if(pBA
->bValid
==true && bOverwritePending
==false)
660 // Set parameters to "Pending" variable set
661 DeActivateBAEntry(ieee
, pBA
);
663 pBA
->DialogToken
++; // DialogToken: Only keep the latest dialog token
664 pBA
->BaParamSet
.field
.AMSDU_Support
= 0; // Do not support A-MSDU with A-MPDU now!!
665 pBA
->BaParamSet
.field
.BAPolicy
= Policy
; // Policy: Delayed or Immediate
666 pBA
->BaParamSet
.field
.TID
= pTS
->TsCommonInfo
.TSpec
.f
.TSInfo
.field
.ucTSID
; // TID
667 // BufferSize: This need to be set according to A-MPDU vector
668 pBA
->BaParamSet
.field
.BufferSize
= 32; // BufferSize: This need to be set according to A-MPDU vector
669 pBA
->BaTimeoutValue
= 0; // Timeout value: Set 0 to disable Timer
670 pBA
->BaStartSeqCtrl
.field
.SeqNum
= (pTS
->TxCurSeq
+ 3) % 4096; // Block Ack will start after 3 packets later.
672 ActivateBAEntry(ieee
, pBA
, BA_SETUP_TIMEOUT
);
674 ieee80211_send_ADDBAReq(ieee
, pTS
->TsCommonInfo
.Addr
, pBA
);
678 TsInitDelBA( struct ieee80211_device
* ieee
, PTS_COMMON_INFO pTsCommonInfo
, TR_SELECT TxRxSelect
)
681 if(TxRxSelect
== TX_DIR
)
683 PTX_TS_RECORD pTxTs
= (PTX_TS_RECORD
)pTsCommonInfo
;
685 if(TxTsDeleteBA(ieee
, pTxTs
))
686 ieee80211_send_DELBA(
689 (pTxTs
->TxAdmittedBARecord
.bValid
)?(&pTxTs
->TxAdmittedBARecord
):(&pTxTs
->TxPendingBARecord
),
691 DELBA_REASON_END_BA
);
693 else if(TxRxSelect
== RX_DIR
)
695 PRX_TS_RECORD pRxTs
= (PRX_TS_RECORD
)pTsCommonInfo
;
696 if(RxTsDeleteBA(ieee
, pRxTs
))
697 ieee80211_send_DELBA(
700 &pRxTs
->RxAdmittedBARecord
,
702 DELBA_REASON_END_BA
);
705 /********************************************************************************************************************
706 *function: BA setup timer
707 * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
710 ********************************************************************************************************************/
711 void BaSetupTimeOut(unsigned long data
)
713 PTX_TS_RECORD pTxTs
= (PTX_TS_RECORD
)data
;
715 pTxTs
->bAddBaReqInProgress
= false;
716 pTxTs
->bAddBaReqDelayed
= true;
717 pTxTs
->TxPendingBARecord
.bValid
= false;
720 void TxBaInactTimeout(unsigned long data
)
722 PTX_TS_RECORD pTxTs
= (PTX_TS_RECORD
)data
;
723 struct ieee80211_device
*ieee
= container_of(pTxTs
, struct ieee80211_device
, TxTsRecord
[pTxTs
->num
]);
724 TxTsDeleteBA(ieee
, pTxTs
);
725 ieee80211_send_DELBA(
727 pTxTs
->TsCommonInfo
.Addr
,
728 &pTxTs
->TxAdmittedBARecord
,
730 DELBA_REASON_TIMEOUT
);
733 void RxBaInactTimeout(unsigned long data
)
735 PRX_TS_RECORD pRxTs
= (PRX_TS_RECORD
)data
;
736 struct ieee80211_device
*ieee
= container_of(pRxTs
, struct ieee80211_device
, RxTsRecord
[pRxTs
->num
]);
738 RxTsDeleteBA(ieee
, pRxTs
);
739 ieee80211_send_DELBA(
741 pRxTs
->TsCommonInfo
.Addr
,
742 &pRxTs
->RxAdmittedBARecord
,
744 DELBA_REASON_TIMEOUT
);