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 u8
TxTsDeleteBA( struct ieee80211_device
* ieee
, PTX_TS_RECORD pTxTs
)
35 PBA_RECORD pAdmittedBa
= &pTxTs
->TxAdmittedBARecord
; //These two BA entries must exist in TS structure
36 PBA_RECORD pPendingBa
= &pTxTs
->TxPendingBARecord
;
37 u8 bSendDELBA
= false;
40 if(pPendingBa
->bValid
)
42 DeActivateBAEntry(ieee
, pPendingBa
);
47 if(pAdmittedBa
->bValid
)
49 DeActivateBAEntry(ieee
, pAdmittedBa
);
56 u8
RxTsDeleteBA( struct ieee80211_device
* ieee
, PRX_TS_RECORD pRxTs
)
58 PBA_RECORD pBa
= &pRxTs
->RxAdmittedBARecord
;
59 u8 bSendDELBA
= false;
63 DeActivateBAEntry(ieee
, pBa
);
70 /********************************************************************************************************************
71 *function: reset BA entry
73 * PBA_RECORD pBA //entry to be reset
75 ********************************************************************************************************************/
76 void ResetBaEntry( PBA_RECORD pBA
)
79 pBA
->BaParamSet
.shortData
= 0;
80 pBA
->BaTimeoutValue
= 0;
82 pBA
->BaStartSeqCtrl
.ShortData
= 0;
84 //These functions need porting here or not?
85 /*******************************************************************************************************************************
86 *function: construct ADDBAREQ and ADDBARSP frame here together.
87 * input: u8* Dst //ADDBA frame's destination
88 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA.
89 * u16 StatusCode //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
90 * u8 type //indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
92 * return: sk_buff* skb //return constructed skb to xmit
93 *******************************************************************************************************************************/
94 static struct sk_buff
* ieee80211_ADDBA(struct ieee80211_device
* ieee
, u8
* Dst
, PBA_RECORD pBA
, u16 StatusCode
, u8 type
)
96 struct sk_buff
*skb
= NULL
;
97 struct ieee80211_hdr_3addr
* BAReq
= NULL
;
100 u16 len
= ieee
->tx_headroom
+ 9;
101 //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
102 IEEE80211_DEBUG(IEEE80211_DL_TRACE
| IEEE80211_DL_BA
, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__
, type
, Dst
, ieee
->dev
);
103 if (pBA
== NULL
||ieee
== NULL
)
105 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA
, ieee
);
108 skb
= dev_alloc_skb(len
+ sizeof( struct ieee80211_hdr_3addr
));
111 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't alloc skb for ADDBA_REQ\n");
115 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.
116 skb_reserve(skb
, ieee
->tx_headroom
);
118 BAReq
= ( struct ieee80211_hdr_3addr
*) skb_put(skb
,sizeof( struct ieee80211_hdr_3addr
));
120 memcpy(BAReq
->addr1
, Dst
, ETH_ALEN
);
121 memcpy(BAReq
->addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
123 memcpy(BAReq
->addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
125 BAReq
->frame_ctl
= cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT
); //action frame
127 //tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
128 tag
= (u8
*)skb_put(skb
, 9);
132 *tag
++= pBA
->DialogToken
;
134 if (ACT_ADDBARSP
== type
)
137 printk("=====>to send ADDBARSP\n");
138 tmp
= cpu_to_le16(StatusCode
);
139 memcpy(tag
, (u8
*)&tmp
, 2);
143 tmp
= cpu_to_le16(pBA
->BaParamSet
.shortData
);
144 memcpy(tag
, (u8
*)&tmp
, 2);
147 tmp
= cpu_to_le16(pBA
->BaTimeoutValue
);
148 memcpy(tag
, (u8
*)&tmp
, 2);
151 if (ACT_ADDBAREQ
== type
)
154 memcpy(tag
,(u8
*)&(pBA
->BaStartSeqCtrl
), 2);
158 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
164 /********************************************************************************************************************
165 *function: construct DELBA frame
166 * input: u8* dst //DELBA frame's destination
167 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
168 * TR_SELECT TxRxSelect //TX RX direction
169 * u16 ReasonCode //status code.
171 * return: sk_buff* skb //return constructed skb to xmit
172 ********************************************************************************************************************/
173 static struct sk_buff
* ieee80211_DELBA(
174 struct ieee80211_device
* ieee
,
177 TR_SELECT TxRxSelect
,
181 DELBA_PARAM_SET DelbaParamSet
;
182 struct sk_buff
*skb
= NULL
;
183 struct ieee80211_hdr_3addr
* Delba
= NULL
;
186 //len = head len + DELBA Parameter Set(2) + Reason Code(2)
187 u16 len
= 6 + ieee
->tx_headroom
;
190 IEEE80211_DEBUG(IEEE80211_DL_TRACE
| IEEE80211_DL_BA
, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__
, ReasonCode
, dst
);
192 memset(&DelbaParamSet
, 0, 2);
194 DelbaParamSet
.field
.Initiator
= (TxRxSelect
==TX_DIR
)?1:0;
195 DelbaParamSet
.field
.TID
= pBA
->BaParamSet
.field
.TID
;
197 skb
= dev_alloc_skb(len
+ sizeof( struct ieee80211_hdr_3addr
));
200 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't alloc skb for ADDBA_REQ\n");
203 // memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr));
204 skb_reserve(skb
, ieee
->tx_headroom
);
206 Delba
= ( struct ieee80211_hdr_3addr
*) skb_put(skb
,sizeof( struct ieee80211_hdr_3addr
));
208 memcpy(Delba
->addr1
, dst
, ETH_ALEN
);
209 memcpy(Delba
->addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
210 memcpy(Delba
->addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
211 Delba
->frame_ctl
= cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT
); //action frame
213 tag
= (u8
*)skb_put(skb
, 6);
218 // DELBA Parameter Set
219 tmp
= cpu_to_le16(DelbaParamSet
.shortData
);
220 memcpy(tag
, (u8
*)&tmp
, 2);
223 tmp
= cpu_to_le16(ReasonCode
);
224 memcpy(tag
, (u8
*)&tmp
, 2);
227 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
229 IEEE80211_DEBUG(IEEE80211_DL_TRACE
| IEEE80211_DL_BA
, "<=====%s()\n", __FUNCTION__
);
233 /********************************************************************************************************************
234 *function: send ADDBAReq frame out
235 * input: u8* dst //ADDBAReq frame's destination
236 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
238 * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
239 ********************************************************************************************************************/
240 void ieee80211_send_ADDBAReq(struct ieee80211_device
* ieee
, u8
* dst
, PBA_RECORD pBA
)
242 struct sk_buff
*skb
= NULL
;
243 skb
= ieee80211_ADDBA(ieee
, dst
, pBA
, 0, ACT_ADDBAREQ
); //construct ACT_ADDBAREQ frames so set statuscode zero.
247 softmac_mgmt_xmit(skb
, ieee
);
248 //add statistic needed here.
249 //and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit()
254 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "alloc skb error in function %s()\n", __FUNCTION__
);
259 /********************************************************************************************************************
260 *function: send ADDBARSP frame out
261 * input: u8* dst //DELBA frame's destination
262 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
263 * u16 StatusCode //RSP StatusCode
265 * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
266 ********************************************************************************************************************/
267 void ieee80211_send_ADDBARsp(struct ieee80211_device
* ieee
, u8
* dst
, PBA_RECORD pBA
, u16 StatusCode
)
269 struct sk_buff
*skb
= NULL
;
270 skb
= ieee80211_ADDBA(ieee
, dst
, pBA
, StatusCode
, ACT_ADDBARSP
); //construct ACT_ADDBARSP frames
273 softmac_mgmt_xmit(skb
, ieee
);
278 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "alloc skb error in function %s()\n", __FUNCTION__
);
284 /********************************************************************************************************************
285 *function: send ADDBARSP frame out
286 * input: u8* dst //DELBA frame's destination
287 * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
288 * TR_SELECT TxRxSelect //TX or RX
289 * u16 ReasonCode //DEL ReasonCode
291 * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
292 ********************************************************************************************************************/
294 void ieee80211_send_DELBA(struct ieee80211_device
* ieee
, u8
* dst
, PBA_RECORD pBA
, TR_SELECT TxRxSelect
, u16 ReasonCode
)
296 struct sk_buff
*skb
= NULL
;
297 skb
= ieee80211_DELBA(ieee
, dst
, pBA
, TxRxSelect
, ReasonCode
); //construct ACT_ADDBARSP frames
300 softmac_mgmt_xmit(skb
, ieee
);
305 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "alloc skb error in function %s()\n", __FUNCTION__
);
310 /********************************************************************************************************************
311 *function: RX ADDBAReq
312 * input: struct sk_buff * skb //incoming ADDBAReq skb.
313 * return: 0(pass), other(fail)
314 * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
315 ********************************************************************************************************************/
316 int ieee80211_rx_ADDBAReq( struct ieee80211_device
* ieee
, struct sk_buff
*skb
)
318 struct ieee80211_hdr_3addr
* req
= NULL
;
320 u8
* dst
= NULL
, *pDialogToken
= NULL
, *tag
= NULL
;
321 PBA_RECORD pBA
= NULL
;
322 PBA_PARAM_SET pBaParamSet
= NULL
;
323 u16
* pBaTimeoutVal
= NULL
;
324 PSEQUENCE_CONTROL pBaStartSeqCtrl
= NULL
;
325 PRX_TS_RECORD pTS
= NULL
;
327 if (skb
->len
< sizeof( struct ieee80211_hdr_3addr
) + 9)
329 IEEE80211_DEBUG(IEEE80211_DL_ERR
, " Invalid skb len in BAREQ(%d / %zu)\n", skb
->len
, (sizeof( struct ieee80211_hdr_3addr
) + 9));
333 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
335 req
= ( struct ieee80211_hdr_3addr
*) skb
->data
;
337 dst
= (u8
*)(&req
->addr2
[0]);
338 tag
+= sizeof( struct ieee80211_hdr_3addr
);
339 pDialogToken
= tag
+ 2; //category+action
340 pBaParamSet
= (PBA_PARAM_SET
)(tag
+ 3); //+DialogToken
341 pBaTimeoutVal
= (u16
*)(tag
+ 5);
342 pBaStartSeqCtrl
= (PSEQUENCE_CONTROL
)(req
+ 7);
344 printk("====================>rx ADDBAREQ from :%pM\n", dst
);
345 //some other capability is not ready now.
346 if( (ieee
->current_network
.qos_data
.active
== 0) ||
347 (ieee
->pHTInfo
->bCurrentHTSupport
== false)) //||
348 // (ieee->pStaQos->bEnableRxImmBA == false) )
350 rc
= ADDBA_STATUS_REFUSED
;
351 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
);
352 goto OnADDBAReq_Fail
;
354 // Search for related traffic stream.
355 // If there is no matched TS, reject the ADDBA request.
358 (PTS_COMMON_INFO
*)(&pTS
),
360 (u8
)(pBaParamSet
->field
.TID
),
364 rc
= ADDBA_STATUS_REFUSED
;
365 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS in %s()\n", __FUNCTION__
);
366 goto OnADDBAReq_Fail
;
368 pBA
= &pTS
->RxAdmittedBARecord
;
369 // To Determine the ADDBA Req content
370 // We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl...
371 // I want to check StartSeqCtrl to make sure when we start aggregation!!!
373 if(pBaParamSet
->field
.BAPolicy
== BA_POLICY_DELAYED
)
375 rc
= ADDBA_STATUS_INVALID_PARAM
;
376 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "BA Policy is not correct in %s()\n", __FUNCTION__
);
377 goto OnADDBAReq_Fail
;
379 // Admit the ADDBA Request
381 DeActivateBAEntry(ieee
, pBA
);
382 pBA
->DialogToken
= *pDialogToken
;
383 pBA
->BaParamSet
= *pBaParamSet
;
384 pBA
->BaTimeoutValue
= *pBaTimeoutVal
;
385 pBA
->BaStartSeqCtrl
= *pBaStartSeqCtrl
;
386 //for half N mode we only aggregate 1 frame
387 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
))
388 pBA
->BaParamSet
.field
.BufferSize
= 1;
390 pBA
->BaParamSet
.field
.BufferSize
= 32;
391 ActivateBAEntry(ieee
, pBA
, pBA
->BaTimeoutValue
);
392 ieee80211_send_ADDBARsp(ieee
, dst
, pBA
, ADDBA_STATUS_SUCCESS
);
400 BA
.BaParamSet
= *pBaParamSet
;
401 BA
.BaTimeoutValue
= *pBaTimeoutVal
;
402 BA
.DialogToken
= *pDialogToken
;
403 BA
.BaParamSet
.field
.BAPolicy
= BA_POLICY_IMMEDIATE
;
404 ieee80211_send_ADDBARsp(ieee
, dst
, &BA
, rc
);
405 return 0; //we send RSP out.
410 /********************************************************************************************************************
411 *function: RX ADDBARSP
412 * input: struct sk_buff * skb //incoming ADDBAReq skb.
413 * return: 0(pass), other(fail)
414 * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
415 ********************************************************************************************************************/
416 int ieee80211_rx_ADDBARsp( struct ieee80211_device
* ieee
, struct sk_buff
*skb
)
418 struct ieee80211_hdr_3addr
* rsp
= NULL
;
419 PBA_RECORD pPendingBA
, pAdmittedBA
;
420 PTX_TS_RECORD pTS
= NULL
;
421 u8
* dst
= NULL
, *pDialogToken
= NULL
, *tag
= NULL
;
422 u16
* pStatusCode
= NULL
, *pBaTimeoutVal
= NULL
;
423 PBA_PARAM_SET pBaParamSet
= NULL
;
426 if (skb
->len
< sizeof( struct ieee80211_hdr_3addr
) + 9)
428 IEEE80211_DEBUG(IEEE80211_DL_ERR
, " Invalid skb len in BARSP(%d / %zu)\n", skb
->len
, (sizeof( struct ieee80211_hdr_3addr
) + 9));
431 rsp
= ( struct ieee80211_hdr_3addr
*)skb
->data
;
433 dst
= (u8
*)(&rsp
->addr2
[0]);
434 tag
+= sizeof( struct ieee80211_hdr_3addr
);
435 pDialogToken
= tag
+ 2;
436 pStatusCode
= (u16
*)(tag
+ 3);
437 pBaParamSet
= (PBA_PARAM_SET
)(tag
+ 5);
438 pBaTimeoutVal
= (u16
*)(tag
+ 7);
440 // Check the capability
441 // Since we can always receive A-MPDU, we just check if it is under HT mode.
442 if( ieee
->current_network
.qos_data
.active
== 0 ||
443 ieee
->pHTInfo
->bCurrentHTSupport
== false ||
444 ieee
->pHTInfo
->bCurrentAMPDUEnable
== false )
446 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
);
447 ReasonCode
= DELBA_REASON_UNKNOWN_BA
;
448 goto OnADDBARsp_Reject
;
453 // Search for related TS.
454 // If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame.
458 (PTS_COMMON_INFO
*)(&pTS
),
460 (u8
)(pBaParamSet
->field
.TID
),
464 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS in %s()\n", __FUNCTION__
);
465 ReasonCode
= DELBA_REASON_UNKNOWN_BA
;
466 goto OnADDBARsp_Reject
;
469 pTS
->bAddBaReqInProgress
= false;
470 pPendingBA
= &pTS
->TxPendingBARecord
;
471 pAdmittedBA
= &pTS
->TxAdmittedBARecord
;
475 // Check if related BA is waiting for setup.
476 // If not, reject by sending DELBA frame.
478 if((pAdmittedBA
->bValid
==true))
480 // Since BA is already setup, we ignore all other ADDBA Response.
481 IEEE80211_DEBUG(IEEE80211_DL_BA
, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
484 else if((pPendingBA
->bValid
== false) ||(*pDialogToken
!= pPendingBA
->DialogToken
))
486 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
487 ReasonCode
= DELBA_REASON_UNKNOWN_BA
;
488 goto OnADDBARsp_Reject
;
492 IEEE80211_DEBUG(IEEE80211_DL_BA
, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode
);
493 DeActivateBAEntry(ieee
, pPendingBA
);
497 if(*pStatusCode
== ADDBA_STATUS_SUCCESS
)
500 // Determine ADDBA Rsp content here.
501 // We can compare the value of BA parameter set that Peer returned and Self sent.
502 // If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
504 if(pBaParamSet
->field
.BAPolicy
== BA_POLICY_DELAYED
)
506 // Since this is a kind of ADDBA failed, we delay next ADDBA process.
507 pTS
->bAddBaReqDelayed
= true;
508 DeActivateBAEntry(ieee
, pAdmittedBA
);
509 ReasonCode
= DELBA_REASON_END_BA
;
510 goto OnADDBARsp_Reject
;
515 // Admitted condition
517 pAdmittedBA
->DialogToken
= *pDialogToken
;
518 pAdmittedBA
->BaTimeoutValue
= *pBaTimeoutVal
;
519 pAdmittedBA
->BaStartSeqCtrl
= pPendingBA
->BaStartSeqCtrl
;
520 pAdmittedBA
->BaParamSet
= *pBaParamSet
;
521 DeActivateBAEntry(ieee
, pAdmittedBA
);
522 ActivateBAEntry(ieee
, pAdmittedBA
, *pBaTimeoutVal
);
526 // Delay next ADDBA process.
527 pTS
->bAddBaReqDelayed
= true;
536 BA
.BaParamSet
= *pBaParamSet
;
537 ieee80211_send_DELBA(ieee
, dst
, &BA
, TX_DIR
, ReasonCode
);
543 /********************************************************************************************************************
545 * input: struct sk_buff * skb //incoming ADDBAReq skb.
546 * return: 0(pass), other(fail)
547 * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
548 ********************************************************************************************************************/
549 int ieee80211_rx_DELBA(struct ieee80211_device
* ieee
,struct sk_buff
*skb
)
551 struct ieee80211_hdr_3addr
* delba
= NULL
;
552 PDELBA_PARAM_SET pDelBaParamSet
= NULL
;
553 u16
* pReasonCode
= NULL
;
556 if (skb
->len
< sizeof( struct ieee80211_hdr_3addr
) + 6)
558 IEEE80211_DEBUG(IEEE80211_DL_ERR
, " Invalid skb len in DELBA(%d / %zu)\n", skb
->len
, (sizeof( struct ieee80211_hdr_3addr
) + 6));
562 if(ieee
->current_network
.qos_data
.active
== 0 ||
563 ieee
->pHTInfo
->bCurrentHTSupport
== false )
565 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
);
569 IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA
|IEEE80211_DL_BA
, skb
->data
, skb
->len
);
570 delba
= ( struct ieee80211_hdr_3addr
*)skb
->data
;
571 dst
= (u8
*)(&delba
->addr2
[0]);
572 delba
+= sizeof( struct ieee80211_hdr_3addr
);
573 pDelBaParamSet
= (PDELBA_PARAM_SET
)(delba
+2);
574 pReasonCode
= (u16
*)(delba
+4);
576 if(pDelBaParamSet
->field
.Initiator
== 1)
582 (PTS_COMMON_INFO
*)&pRxTs
,
584 (u8
)pDelBaParamSet
->field
.TID
,
588 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS for RXTS in %s()\n", __FUNCTION__
);
592 RxTsDeleteBA(ieee
, pRxTs
);
600 (PTS_COMMON_INFO
*)&pTxTs
,
602 (u8
)pDelBaParamSet
->field
.TID
,
606 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't get TS for TXTS in %s()\n", __FUNCTION__
);
610 pTxTs
->bUsingBa
= false;
611 pTxTs
->bAddBaReqInProgress
= false;
612 pTxTs
->bAddBaReqDelayed
= false;
613 del_timer_sync(&pTxTs
->TsAddBaTimer
);
614 //PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer);
615 TxTsDeleteBA(ieee
, pTxTs
);
621 // ADDBA initiate. This can only be called by TX side.
625 struct ieee80211_device
* ieee
,
631 PBA_RECORD pBA
= &pTS
->TxPendingBARecord
;
633 if(pBA
->bValid
==true && bOverwritePending
==false)
636 // Set parameters to "Pending" variable set
637 DeActivateBAEntry(ieee
, pBA
);
639 pBA
->DialogToken
++; // DialogToken: Only keep the latest dialog token
640 pBA
->BaParamSet
.field
.AMSDU_Support
= 0; // Do not support A-MSDU with A-MPDU now!!
641 pBA
->BaParamSet
.field
.BAPolicy
= Policy
; // Policy: Delayed or Immediate
642 pBA
->BaParamSet
.field
.TID
= pTS
->TsCommonInfo
.TSpec
.f
.TSInfo
.field
.ucTSID
; // TID
643 // BufferSize: This need to be set according to A-MPDU vector
644 pBA
->BaParamSet
.field
.BufferSize
= 32; // BufferSize: This need to be set according to A-MPDU vector
645 pBA
->BaTimeoutValue
= 0; // Timeout value: Set 0 to disable Timer
646 pBA
->BaStartSeqCtrl
.field
.SeqNum
= (pTS
->TxCurSeq
+ 3) % 4096; // Block Ack will start after 3 packets later.
648 ActivateBAEntry(ieee
, pBA
, BA_SETUP_TIMEOUT
);
650 ieee80211_send_ADDBAReq(ieee
, pTS
->TsCommonInfo
.Addr
, pBA
);
654 TsInitDelBA( struct ieee80211_device
* ieee
, PTS_COMMON_INFO pTsCommonInfo
, TR_SELECT TxRxSelect
)
657 if(TxRxSelect
== TX_DIR
)
659 PTX_TS_RECORD pTxTs
= (PTX_TS_RECORD
)pTsCommonInfo
;
661 if(TxTsDeleteBA(ieee
, pTxTs
))
662 ieee80211_send_DELBA(
665 (pTxTs
->TxAdmittedBARecord
.bValid
)?(&pTxTs
->TxAdmittedBARecord
):(&pTxTs
->TxPendingBARecord
),
667 DELBA_REASON_END_BA
);
669 else if(TxRxSelect
== RX_DIR
)
671 PRX_TS_RECORD pRxTs
= (PRX_TS_RECORD
)pTsCommonInfo
;
672 if(RxTsDeleteBA(ieee
, pRxTs
))
673 ieee80211_send_DELBA(
676 &pRxTs
->RxAdmittedBARecord
,
678 DELBA_REASON_END_BA
);
681 /********************************************************************************************************************
682 *function: BA setup timer
683 * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
686 ********************************************************************************************************************/
687 void BaSetupTimeOut(unsigned long data
)
689 PTX_TS_RECORD pTxTs
= (PTX_TS_RECORD
)data
;
691 pTxTs
->bAddBaReqInProgress
= false;
692 pTxTs
->bAddBaReqDelayed
= true;
693 pTxTs
->TxPendingBARecord
.bValid
= false;
696 void TxBaInactTimeout(unsigned long data
)
698 PTX_TS_RECORD pTxTs
= (PTX_TS_RECORD
)data
;
699 struct ieee80211_device
*ieee
= container_of(pTxTs
, struct ieee80211_device
, TxTsRecord
[pTxTs
->num
]);
700 TxTsDeleteBA(ieee
, pTxTs
);
701 ieee80211_send_DELBA(
703 pTxTs
->TsCommonInfo
.Addr
,
704 &pTxTs
->TxAdmittedBARecord
,
706 DELBA_REASON_TIMEOUT
);
709 void RxBaInactTimeout(unsigned long data
)
711 PRX_TS_RECORD pRxTs
= (PRX_TS_RECORD
)data
;
712 struct ieee80211_device
*ieee
= container_of(pRxTs
, struct ieee80211_device
, RxTsRecord
[pRxTs
->num
]);
714 RxTsDeleteBA(ieee
, pRxTs
);
715 ieee80211_send_DELBA(
717 pRxTs
->TsCommonInfo
.Addr
,
718 &pRxTs
->RxAdmittedBARecord
,
720 DELBA_REASON_TIMEOUT
);