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
);
178 /********************************************************************************************************************
179 *function: construct DELBA frame
180 * input: u8* dst //DELBA frame's destination
181 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
182 * TR_SELECT TxRxSelect //TX RX direction
183 * u16 ReasonCode //status code.
185 * return: sk_buff* skb //return constructed skb to xmit
186 ********************************************************************************************************************/
187 static struct sk_buff
* ieee80211_DELBA(
188 struct ieee80211_device
* ieee
,
191 TR_SELECT TxRxSelect
,
195 DELBA_PARAM_SET DelbaParamSet
;
196 struct sk_buff
*skb
= NULL
;
197 struct ieee80211_hdr_3addr
* Delba
= NULL
;
200 //len = head len + DELBA Parameter Set(2) + Reason Code(2)
201 u16 len
= 6 + ieee
->tx_headroom
;
204 IEEE80211_DEBUG(IEEE80211_DL_TRACE
| IEEE80211_DL_BA
, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__
, ReasonCode
, dst
);
206 memset(&DelbaParamSet
, 0, 2);
208 DelbaParamSet
.field
.Initiator
= (TxRxSelect
==TX_DIR
)?1:0;
209 DelbaParamSet
.field
.TID
= pBA
->BaParamSet
.field
.TID
;
211 skb
= dev_alloc_skb(len
+ sizeof( struct ieee80211_hdr_3addr
)); //need to add something others? FIXME
214 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't alloc skb for ADDBA_REQ\n");
217 // memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr));
218 skb_reserve(skb
, ieee
->tx_headroom
);
220 Delba
= ( struct ieee80211_hdr_3addr
*) skb_put(skb
,sizeof( struct ieee80211_hdr_3addr
));
222 memcpy(Delba
->addr1
, dst
, ETH_ALEN
);
223 memcpy(Delba
->addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
224 memcpy(Delba
->addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
225 Delba
->frame_ctl
= cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT
); //action frame
227 tag
= (u8
*)skb_put(skb
, 6);
232 // DELBA Parameter Set
233 tmp
= cpu_to_le16(DelbaParamSet
.shortData
);
234 memcpy(tag
, (u8
*)&tmp
, 2);
237 tmp
= cpu_to_le16(ReasonCode
);
238 memcpy(tag
, (u8
*)&tmp
, 2);
241 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
243 IEEE80211_DEBUG(IEEE80211_DL_TRACE
| IEEE80211_DL_BA
, "<=====%s()\n", __FUNCTION__
);
247 /********************************************************************************************************************
248 *function: send ADDBAReq frame out
249 * input: u8* dst //ADDBAReq frame's destination
250 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
252 * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
253 ********************************************************************************************************************/
254 void ieee80211_send_ADDBAReq(struct ieee80211_device
* ieee
, u8
* dst
, PBA_RECORD pBA
)
256 struct sk_buff
*skb
= NULL
;
257 skb
= ieee80211_ADDBA(ieee
, dst
, pBA
, 0, ACT_ADDBAREQ
); //construct ACT_ADDBAREQ frames so set statuscode zero.
261 softmac_mgmt_xmit(skb
, ieee
);
262 //add statistic needed here.
263 //and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit()
268 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "alloc skb error in function %s()\n", __FUNCTION__
);
273 /********************************************************************************************************************
274 *function: send ADDBARSP frame out
275 * input: u8* dst //DELBA frame's destination
276 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
277 * u16 StatusCode //RSP StatusCode
279 * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
280 ********************************************************************************************************************/
281 void ieee80211_send_ADDBARsp(struct ieee80211_device
* ieee
, u8
* dst
, PBA_RECORD pBA
, u16 StatusCode
)
283 struct sk_buff
*skb
= NULL
;
284 skb
= ieee80211_ADDBA(ieee
, dst
, pBA
, StatusCode
, ACT_ADDBARSP
); //construct ACT_ADDBARSP frames
287 softmac_mgmt_xmit(skb
, ieee
);
292 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "alloc skb error in function %s()\n", __FUNCTION__
);
298 /********************************************************************************************************************
299 *function: send ADDBARSP frame out
300 * input: u8* dst //DELBA frame's destination
301 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
302 * TR_SELECT TxRxSelect //TX or RX
303 * u16 ReasonCode //DEL ReasonCode
305 * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
306 ********************************************************************************************************************/
308 void ieee80211_send_DELBA(struct ieee80211_device
* ieee
, u8
* dst
, PBA_RECORD pBA
, TR_SELECT TxRxSelect
, u16 ReasonCode
)
310 struct sk_buff
*skb
= NULL
;
311 skb
= ieee80211_DELBA(ieee
, dst
, pBA
, TxRxSelect
, ReasonCode
); //construct ACT_ADDBARSP frames
314 softmac_mgmt_xmit(skb
, ieee
);
319 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "alloc skb error in function %s()\n", __FUNCTION__
);
324 /********************************************************************************************************************
325 *function: RX ADDBAReq
326 * input: struct sk_buff * skb //incoming ADDBAReq skb.
327 * return: 0(pass), other(fail)
328 * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
329 ********************************************************************************************************************/
330 int ieee80211_rx_ADDBAReq( struct ieee80211_device
* ieee
, struct sk_buff
*skb
)
332 struct ieee80211_hdr_3addr
* req
= NULL
;
334 u8
* dst
= NULL
, *pDialogToken
= NULL
, *tag
= NULL
;
335 PBA_RECORD pBA
= NULL
;
336 PBA_PARAM_SET pBaParamSet
= NULL
;
337 u16
* pBaTimeoutVal
= NULL
;
338 PSEQUENCE_CONTROL pBaStartSeqCtrl
= NULL
;
339 PRX_TS_RECORD pTS
= NULL
;
341 if (skb
->len
< sizeof( struct ieee80211_hdr_3addr
) + 9)
343 IEEE80211_DEBUG(IEEE80211_DL_ERR
, " Invalid skb len in BAREQ(%d / %zu)\n", skb
->len
, (sizeof( struct ieee80211_hdr_3addr
) + 9));
347 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
349 req
= ( struct ieee80211_hdr_3addr
*) skb
->data
;
351 dst
= (u8
*)(&req
->addr2
[0]);
352 tag
+= sizeof( struct ieee80211_hdr_3addr
);
353 pDialogToken
= tag
+ 2; //category+action
354 pBaParamSet
= (PBA_PARAM_SET
)(tag
+ 3); //+DialogToken
355 pBaTimeoutVal
= (u16
*)(tag
+ 5);
356 pBaStartSeqCtrl
= (PSEQUENCE_CONTROL
)(req
+ 7);
358 printk("====================>rx ADDBAREQ from :%pM\n", dst
);
359 //some other capability is not ready now.
360 if( (ieee
->current_network
.qos_data
.active
== 0) ||
361 (ieee
->pHTInfo
->bCurrentHTSupport
== false)) //||
362 // (ieee->pStaQos->bEnableRxImmBA == false) )
364 rc
= ADDBA_STATUS_REFUSED
;
365 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
);
366 goto OnADDBAReq_Fail
;
368 // Search for related traffic stream.
369 // If there is no matched TS, reject the ADDBA request.
372 (PTS_COMMON_INFO
*)(&pTS
),
374 (u8
)(pBaParamSet
->field
.TID
),
378 rc
= ADDBA_STATUS_REFUSED
;
379 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS in %s()\n", __FUNCTION__
);
380 goto OnADDBAReq_Fail
;
382 pBA
= &pTS
->RxAdmittedBARecord
;
383 // To Determine the ADDBA Req content
384 // We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl...
385 // I want to check StartSeqCtrl to make sure when we start aggregation!!!
387 if(pBaParamSet
->field
.BAPolicy
== BA_POLICY_DELAYED
)
389 rc
= ADDBA_STATUS_INVALID_PARAM
;
390 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "BA Policy is not correct in %s()\n", __FUNCTION__
);
391 goto OnADDBAReq_Fail
;
393 // Admit the ADDBA Request
395 DeActivateBAEntry(ieee
, pBA
);
396 pBA
->DialogToken
= *pDialogToken
;
397 pBA
->BaParamSet
= *pBaParamSet
;
398 pBA
->BaTimeoutValue
= *pBaTimeoutVal
;
399 pBA
->BaStartSeqCtrl
= *pBaStartSeqCtrl
;
400 //for half N mode we only aggregate 1 frame
401 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
))
402 pBA
->BaParamSet
.field
.BufferSize
= 1;
404 pBA
->BaParamSet
.field
.BufferSize
= 32;
405 ActivateBAEntry(ieee
, pBA
, pBA
->BaTimeoutValue
);
406 ieee80211_send_ADDBARsp(ieee
, dst
, pBA
, ADDBA_STATUS_SUCCESS
);
414 BA
.BaParamSet
= *pBaParamSet
;
415 BA
.BaTimeoutValue
= *pBaTimeoutVal
;
416 BA
.DialogToken
= *pDialogToken
;
417 BA
.BaParamSet
.field
.BAPolicy
= BA_POLICY_IMMEDIATE
;
418 ieee80211_send_ADDBARsp(ieee
, dst
, &BA
, rc
);
419 return 0; //we send RSP out.
424 /********************************************************************************************************************
425 *function: RX ADDBARSP
426 * input: struct sk_buff * skb //incoming ADDBAReq skb.
427 * return: 0(pass), other(fail)
428 * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
429 ********************************************************************************************************************/
430 int ieee80211_rx_ADDBARsp( struct ieee80211_device
* ieee
, struct sk_buff
*skb
)
432 struct ieee80211_hdr_3addr
* rsp
= NULL
;
433 PBA_RECORD pPendingBA
, pAdmittedBA
;
434 PTX_TS_RECORD pTS
= NULL
;
435 u8
* dst
= NULL
, *pDialogToken
= NULL
, *tag
= NULL
;
436 u16
* pStatusCode
= NULL
, *pBaTimeoutVal
= NULL
;
437 PBA_PARAM_SET pBaParamSet
= NULL
;
440 if (skb
->len
< sizeof( struct ieee80211_hdr_3addr
) + 9)
442 IEEE80211_DEBUG(IEEE80211_DL_ERR
, " Invalid skb len in BARSP(%d / %zu)\n", skb
->len
, (sizeof( struct ieee80211_hdr_3addr
) + 9));
445 rsp
= ( struct ieee80211_hdr_3addr
*)skb
->data
;
447 dst
= (u8
*)(&rsp
->addr2
[0]);
448 tag
+= sizeof( struct ieee80211_hdr_3addr
);
449 pDialogToken
= tag
+ 2;
450 pStatusCode
= (u16
*)(tag
+ 3);
451 pBaParamSet
= (PBA_PARAM_SET
)(tag
+ 5);
452 pBaTimeoutVal
= (u16
*)(tag
+ 7);
454 // Check the capability
455 // Since we can always receive A-MPDU, we just check if it is under HT mode.
456 if( ieee
->current_network
.qos_data
.active
== 0 ||
457 ieee
->pHTInfo
->bCurrentHTSupport
== false ||
458 ieee
->pHTInfo
->bCurrentAMPDUEnable
== false )
460 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
);
461 ReasonCode
= DELBA_REASON_UNKNOWN_BA
;
462 goto OnADDBARsp_Reject
;
467 // Search for related TS.
468 // If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame.
472 (PTS_COMMON_INFO
*)(&pTS
),
474 (u8
)(pBaParamSet
->field
.TID
),
478 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS in %s()\n", __FUNCTION__
);
479 ReasonCode
= DELBA_REASON_UNKNOWN_BA
;
480 goto OnADDBARsp_Reject
;
483 pTS
->bAddBaReqInProgress
= false;
484 pPendingBA
= &pTS
->TxPendingBARecord
;
485 pAdmittedBA
= &pTS
->TxAdmittedBARecord
;
489 // Check if related BA is waiting for setup.
490 // If not, reject by sending DELBA frame.
492 if((pAdmittedBA
->bValid
==true))
494 // Since BA is already setup, we ignore all other ADDBA Response.
495 IEEE80211_DEBUG(IEEE80211_DL_BA
, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
498 else if((pPendingBA
->bValid
== false) ||(*pDialogToken
!= pPendingBA
->DialogToken
))
500 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
501 ReasonCode
= DELBA_REASON_UNKNOWN_BA
;
502 goto OnADDBARsp_Reject
;
506 IEEE80211_DEBUG(IEEE80211_DL_BA
, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode
);
507 DeActivateBAEntry(ieee
, pPendingBA
);
511 if(*pStatusCode
== ADDBA_STATUS_SUCCESS
)
514 // Determine ADDBA Rsp content here.
515 // We can compare the value of BA parameter set that Peer returned and Self sent.
516 // If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
518 if(pBaParamSet
->field
.BAPolicy
== BA_POLICY_DELAYED
)
520 // Since this is a kind of ADDBA failed, we delay next ADDBA process.
521 pTS
->bAddBaReqDelayed
= true;
522 DeActivateBAEntry(ieee
, pAdmittedBA
);
523 ReasonCode
= DELBA_REASON_END_BA
;
524 goto OnADDBARsp_Reject
;
529 // Admitted condition
531 pAdmittedBA
->DialogToken
= *pDialogToken
;
532 pAdmittedBA
->BaTimeoutValue
= *pBaTimeoutVal
;
533 pAdmittedBA
->BaStartSeqCtrl
= pPendingBA
->BaStartSeqCtrl
;
534 pAdmittedBA
->BaParamSet
= *pBaParamSet
;
535 DeActivateBAEntry(ieee
, pAdmittedBA
);
536 ActivateBAEntry(ieee
, pAdmittedBA
, *pBaTimeoutVal
);
540 // Delay next ADDBA process.
541 pTS
->bAddBaReqDelayed
= true;
550 BA
.BaParamSet
= *pBaParamSet
;
551 ieee80211_send_DELBA(ieee
, dst
, &BA
, TX_DIR
, ReasonCode
);
557 /********************************************************************************************************************
559 * input: struct sk_buff * skb //incoming ADDBAReq skb.
560 * return: 0(pass), other(fail)
561 * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
562 ********************************************************************************************************************/
563 int ieee80211_rx_DELBA(struct ieee80211_device
* ieee
,struct sk_buff
*skb
)
565 struct ieee80211_hdr_3addr
* delba
= NULL
;
566 PDELBA_PARAM_SET pDelBaParamSet
= NULL
;
567 u16
* pReasonCode
= NULL
;
570 if (skb
->len
< sizeof( struct ieee80211_hdr_3addr
) + 6)
572 IEEE80211_DEBUG(IEEE80211_DL_ERR
, " Invalid skb len in DELBA(%d / %zu)\n", skb
->len
, (sizeof( struct ieee80211_hdr_3addr
) + 6));
576 if(ieee
->current_network
.qos_data
.active
== 0 ||
577 ieee
->pHTInfo
->bCurrentHTSupport
== false )
579 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
);
583 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
584 delba
= ( struct ieee80211_hdr_3addr
*)skb
->data
;
585 dst
= (u8
*)(&delba
->addr2
[0]);
586 delba
+= sizeof( struct ieee80211_hdr_3addr
);
587 pDelBaParamSet
= (PDELBA_PARAM_SET
)(delba
+2);
588 pReasonCode
= (u16
*)(delba
+4);
590 if(pDelBaParamSet
->field
.Initiator
== 1)
596 (PTS_COMMON_INFO
*)&pRxTs
,
598 (u8
)pDelBaParamSet
->field
.TID
,
602 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS for RXTS in %s()\n", __FUNCTION__
);
606 RxTsDeleteBA(ieee
, pRxTs
);
614 (PTS_COMMON_INFO
*)&pTxTs
,
616 (u8
)pDelBaParamSet
->field
.TID
,
620 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS for TXTS in %s()\n", __FUNCTION__
);
624 pTxTs
->bUsingBa
= false;
625 pTxTs
->bAddBaReqInProgress
= false;
626 pTxTs
->bAddBaReqDelayed
= false;
627 del_timer_sync(&pTxTs
->TsAddBaTimer
);
628 //PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer);
629 TxTsDeleteBA(ieee
, pTxTs
);
635 // ADDBA initiate. This can only be called by TX side.
639 struct ieee80211_device
* ieee
,
645 PBA_RECORD pBA
= &pTS
->TxPendingBARecord
;
647 if(pBA
->bValid
==true && bOverwritePending
==false)
650 // Set parameters to "Pending" variable set
651 DeActivateBAEntry(ieee
, pBA
);
653 pBA
->DialogToken
++; // DialogToken: Only keep the latest dialog token
654 pBA
->BaParamSet
.field
.AMSDU_Support
= 0; // Do not support A-MSDU with A-MPDU now!!
655 pBA
->BaParamSet
.field
.BAPolicy
= Policy
; // Policy: Delayed or Immediate
656 pBA
->BaParamSet
.field
.TID
= pTS
->TsCommonInfo
.TSpec
.f
.TSInfo
.field
.ucTSID
; // TID
657 // BufferSize: This need to be set according to A-MPDU vector
658 pBA
->BaParamSet
.field
.BufferSize
= 32; // BufferSize: This need to be set according to A-MPDU vector
659 pBA
->BaTimeoutValue
= 0; // Timeout value: Set 0 to disable Timer
660 pBA
->BaStartSeqCtrl
.field
.SeqNum
= (pTS
->TxCurSeq
+ 3) % 4096; // Block Ack will start after 3 packets later.
662 ActivateBAEntry(ieee
, pBA
, BA_SETUP_TIMEOUT
);
664 ieee80211_send_ADDBAReq(ieee
, pTS
->TsCommonInfo
.Addr
, pBA
);
668 TsInitDelBA( struct ieee80211_device
* ieee
, PTS_COMMON_INFO pTsCommonInfo
, TR_SELECT TxRxSelect
)
671 if(TxRxSelect
== TX_DIR
)
673 PTX_TS_RECORD pTxTs
= (PTX_TS_RECORD
)pTsCommonInfo
;
675 if(TxTsDeleteBA(ieee
, pTxTs
))
676 ieee80211_send_DELBA(
679 (pTxTs
->TxAdmittedBARecord
.bValid
)?(&pTxTs
->TxAdmittedBARecord
):(&pTxTs
->TxPendingBARecord
),
681 DELBA_REASON_END_BA
);
683 else if(TxRxSelect
== RX_DIR
)
685 PRX_TS_RECORD pRxTs
= (PRX_TS_RECORD
)pTsCommonInfo
;
686 if(RxTsDeleteBA(ieee
, pRxTs
))
687 ieee80211_send_DELBA(
690 &pRxTs
->RxAdmittedBARecord
,
692 DELBA_REASON_END_BA
);
695 /********************************************************************************************************************
696 *function: BA setup timer
697 * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
700 ********************************************************************************************************************/
701 void BaSetupTimeOut(unsigned long data
)
703 PTX_TS_RECORD pTxTs
= (PTX_TS_RECORD
)data
;
705 pTxTs
->bAddBaReqInProgress
= false;
706 pTxTs
->bAddBaReqDelayed
= true;
707 pTxTs
->TxPendingBARecord
.bValid
= false;
710 void TxBaInactTimeout(unsigned long data
)
712 PTX_TS_RECORD pTxTs
= (PTX_TS_RECORD
)data
;
713 struct ieee80211_device
*ieee
= container_of(pTxTs
, struct ieee80211_device
, TxTsRecord
[pTxTs
->num
]);
714 TxTsDeleteBA(ieee
, pTxTs
);
715 ieee80211_send_DELBA(
717 pTxTs
->TsCommonInfo
.Addr
,
718 &pTxTs
->TxAdmittedBARecord
,
720 DELBA_REASON_TIMEOUT
);
723 void RxBaInactTimeout(unsigned long data
)
725 PRX_TS_RECORD pRxTs
= (PRX_TS_RECORD
)data
;
726 struct ieee80211_device
*ieee
= container_of(pRxTs
, struct ieee80211_device
, RxTsRecord
[pRxTs
->num
]);
728 RxTsDeleteBA(ieee
, pRxTs
);
729 ieee80211_send_DELBA(
731 pRxTs
->TsCommonInfo
.Addr
,
732 &pRxTs
->RxAdmittedBARecord
,
734 DELBA_REASON_TIMEOUT
);