]>
Commit | Line | Data |
---|---|---|
18056f34 GKH |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
94a79942 LF |
3 | * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. |
4 | * | |
18056f34 GKH |
5 | * Contact Information: wlanfae <wlanfae@realtek.com> |
6 | */ | |
94a79942 LF |
7 | #include "rtllib.h" |
8 | #include <linux/etherdevice.h> | |
9 | #include "rtl819x_TS.h" | |
cb762154 | 10 | |
96bc1f2a | 11 | static void TsSetupTimeOut(struct timer_list *unused) |
94a79942 LF |
12 | { |
13 | } | |
14 | ||
96bc1f2a | 15 | static void TsInactTimeout(struct timer_list *unused) |
94a79942 LF |
16 | { |
17 | } | |
18 | ||
96bc1f2a | 19 | static void RxPktPendingTimeout(struct timer_list *t) |
94a79942 | 20 | { |
96bc1f2a KC |
21 | struct rx_ts_record *pRxTs = from_timer(pRxTs, t, |
22 | RxPktPendingTimer); | |
f88ec6cb LF |
23 | struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, |
24 | RxTsRecord[pRxTs->num]); | |
94a79942 | 25 | |
8cba1432 | 26 | struct rx_reorder_entry *pReorderEntry = NULL; |
94a79942 LF |
27 | |
28 | unsigned long flags = 0; | |
94a79942 LF |
29 | u8 index = 0; |
30 | bool bPktInBuf = false; | |
31 | ||
32 | spin_lock_irqsave(&(ieee->reorder_spinlock), flags); | |
f88ec6cb LF |
33 | if (pRxTs->RxTimeoutIndicateSeq != 0xffff) { |
34 | while (!list_empty(&pRxTs->RxPendingPktList)) { | |
35 | pReorderEntry = (struct rx_reorder_entry *) | |
36 | list_entry(pRxTs->RxPendingPktList.prev, | |
37 | struct rx_reorder_entry, List); | |
94a79942 LF |
38 | if (index == 0) |
39 | pRxTs->RxIndicateSeq = pReorderEntry->SeqNum; | |
40 | ||
35e33b04 MK |
41 | if (SN_LESS(pReorderEntry->SeqNum, |
42 | pRxTs->RxIndicateSeq) || | |
43 | SN_EQUAL(pReorderEntry->SeqNum, | |
44 | pRxTs->RxIndicateSeq)) { | |
94a79942 LF |
45 | list_del_init(&pReorderEntry->List); |
46 | ||
f88ec6cb LF |
47 | if (SN_EQUAL(pReorderEntry->SeqNum, |
48 | pRxTs->RxIndicateSeq)) | |
49 | pRxTs->RxIndicateSeq = | |
50 | (pRxTs->RxIndicateSeq + 1) % 4096; | |
94a79942 | 51 | |
b94436b5 MK |
52 | netdev_dbg(ieee->dev, |
53 | "%s(): Indicate SeqNum: %d\n", | |
54 | __func__, pReorderEntry->SeqNum); | |
2eed3dee | 55 | ieee->stats_IndicateArray[index] = |
f88ec6cb | 56 | pReorderEntry->prxb; |
94a79942 LF |
57 | index++; |
58 | ||
f88ec6cb LF |
59 | list_add_tail(&pReorderEntry->List, |
60 | &ieee->RxReorder_Unused_List); | |
61 | } else { | |
94a79942 LF |
62 | bPktInBuf = true; |
63 | break; | |
64 | } | |
65 | } | |
66 | } | |
67 | ||
f88ec6cb | 68 | if (index > 0) { |
94a79942 LF |
69 | pRxTs->RxTimeoutIndicateSeq = 0xffff; |
70 | ||
f88ec6cb | 71 | if (index > REORDER_WIN_SIZE) { |
11e672c3 MK |
72 | netdev_warn(ieee->dev, |
73 | "%s(): Rx Reorder struct buffer full\n", | |
74 | __func__); | |
f88ec6cb LF |
75 | spin_unlock_irqrestore(&(ieee->reorder_spinlock), |
76 | flags); | |
94a79942 LF |
77 | return; |
78 | } | |
2eed3dee | 79 | rtllib_indicate_packets(ieee, ieee->stats_IndicateArray, index); |
94a79942 LF |
80 | bPktInBuf = false; |
81 | } | |
82 | ||
f88ec6cb | 83 | if (bPktInBuf && (pRxTs->RxTimeoutIndicateSeq == 0xffff)) { |
94a79942 | 84 | pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq; |
f88ec6cb | 85 | mod_timer(&pRxTs->RxPktPendingTimer, jiffies + |
35e33b04 MK |
86 | msecs_to_jiffies(ieee->pHTInfo->RxReorderPendingTime) |
87 | ); | |
94a79942 LF |
88 | } |
89 | spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); | |
90 | } | |
91 | ||
96bc1f2a | 92 | static void TsAddBaProcess(struct timer_list *t) |
94a79942 | 93 | { |
96bc1f2a | 94 | struct tx_ts_record *pTxTs = from_timer(pTxTs, t, TsAddBaTimer); |
94a79942 | 95 | u8 num = pTxTs->num; |
f88ec6cb LF |
96 | struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device, |
97 | TxTsRecord[num]); | |
94a79942 LF |
98 | |
99 | TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false); | |
b94436b5 | 100 | netdev_dbg(ieee->dev, "%s(): ADDBA Req is started\n", __func__); |
94a79942 LF |
101 | } |
102 | ||
ec0dc6be | 103 | static void ResetTsCommonInfo(struct ts_common_info *pTsCommonInfo) |
94a79942 | 104 | { |
3e3148c5 | 105 | eth_zero_addr(pTsCommonInfo->Addr); |
ed306e48 | 106 | memset(&pTsCommonInfo->TSpec, 0, sizeof(union tspec_body)); |
626f951d | 107 | memset(&pTsCommonInfo->TClass, 0, sizeof(union qos_tclas)*TCLAS_NUM); |
94a79942 LF |
108 | pTsCommonInfo->TClasProc = 0; |
109 | pTsCommonInfo->TClasNum = 0; | |
110 | } | |
111 | ||
ec0dc6be | 112 | static void ResetTxTsEntry(struct tx_ts_record *pTS) |
94a79942 LF |
113 | { |
114 | ResetTsCommonInfo(&pTS->TsCommonInfo); | |
115 | pTS->TxCurSeq = 0; | |
116 | pTS->bAddBaReqInProgress = false; | |
117 | pTS->bAddBaReqDelayed = false; | |
118 | pTS->bUsingBa = false; | |
119 | pTS->bDisable_AddBa = false; | |
120 | ResetBaEntry(&pTS->TxAdmittedBARecord); | |
121 | ResetBaEntry(&pTS->TxPendingBARecord); | |
122 | } | |
123 | ||
ec0dc6be | 124 | static void ResetRxTsEntry(struct rx_ts_record *pTS) |
94a79942 LF |
125 | { |
126 | ResetTsCommonInfo(&pTS->TsCommonInfo); | |
127 | pTS->RxIndicateSeq = 0xffff; | |
128 | pTS->RxTimeoutIndicateSeq = 0xffff; | |
129 | ResetBaEntry(&pTS->RxAdmittedBARecord); | |
130 | } | |
94a79942 LF |
131 | |
132 | void TSInitialize(struct rtllib_device *ieee) | |
133 | { | |
60554f2b | 134 | struct tx_ts_record *pTxTS = ieee->TxTsRecord; |
2c47ae28 | 135 | struct rx_ts_record *pRxTS = ieee->RxTsRecord; |
8cba1432 | 136 | struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry; |
94a79942 | 137 | u8 count = 0; |
3a6b70c3 | 138 | |
b94436b5 | 139 | netdev_vdbg(ieee->dev, "%s()\n", __func__); |
94a79942 LF |
140 | INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List); |
141 | INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List); | |
142 | INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List); | |
143 | ||
f88ec6cb | 144 | for (count = 0; count < TOTAL_TS_NUM; count++) { |
94a79942 | 145 | pTxTS->num = count; |
96bc1f2a KC |
146 | timer_setup(&pTxTS->TsCommonInfo.SetupTimer, TsSetupTimeOut, |
147 | 0); | |
94a79942 | 148 | |
96bc1f2a KC |
149 | timer_setup(&pTxTS->TsCommonInfo.InactTimer, TsInactTimeout, |
150 | 0); | |
94a79942 | 151 | |
96bc1f2a | 152 | timer_setup(&pTxTS->TsAddBaTimer, TsAddBaProcess, 0); |
94a79942 | 153 | |
96bc1f2a KC |
154 | timer_setup(&pTxTS->TxPendingBARecord.Timer, BaSetupTimeOut, |
155 | 0); | |
156 | timer_setup(&pTxTS->TxAdmittedBARecord.Timer, | |
157 | TxBaInactTimeout, 0); | |
94a79942 LF |
158 | |
159 | ResetTxTsEntry(pTxTS); | |
160 | list_add_tail(&pTxTS->TsCommonInfo.List, | |
161 | &ieee->Tx_TS_Unused_List); | |
162 | pTxTS++; | |
163 | } | |
164 | ||
165 | INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List); | |
166 | INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List); | |
167 | INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List); | |
f88ec6cb | 168 | for (count = 0; count < TOTAL_TS_NUM; count++) { |
94a79942 LF |
169 | pRxTS->num = count; |
170 | INIT_LIST_HEAD(&pRxTS->RxPendingPktList); | |
171 | ||
96bc1f2a KC |
172 | timer_setup(&pRxTS->TsCommonInfo.SetupTimer, TsSetupTimeOut, |
173 | 0); | |
94a79942 | 174 | |
96bc1f2a KC |
175 | timer_setup(&pRxTS->TsCommonInfo.InactTimer, TsInactTimeout, |
176 | 0); | |
94a79942 | 177 | |
96bc1f2a KC |
178 | timer_setup(&pRxTS->RxAdmittedBARecord.Timer, |
179 | RxBaInactTimeout, 0); | |
94a79942 | 180 | |
96bc1f2a | 181 | timer_setup(&pRxTS->RxPktPendingTimer, RxPktPendingTimeout, 0); |
94a79942 LF |
182 | |
183 | ResetRxTsEntry(pRxTS); | |
f88ec6cb LF |
184 | list_add_tail(&pRxTS->TsCommonInfo.List, |
185 | &ieee->Rx_TS_Unused_List); | |
94a79942 LF |
186 | pRxTS++; |
187 | } | |
188 | INIT_LIST_HEAD(&ieee->RxReorder_Unused_List); | |
f88ec6cb LF |
189 | for (count = 0; count < REORDER_ENTRY_NUM; count++) { |
190 | list_add_tail(&pRxReorderEntry->List, | |
191 | &ieee->RxReorder_Unused_List); | |
94a79942 LF |
192 | if (count == (REORDER_ENTRY_NUM-1)) |
193 | break; | |
194 | pRxReorderEntry = &ieee->RxReorderEntry[count+1]; | |
195 | } | |
196 | ||
197 | } | |
198 | ||
ec0dc6be LF |
199 | static void AdmitTS(struct rtllib_device *ieee, |
200 | struct ts_common_info *pTsCommonInfo, u32 InactTime) | |
94a79942 LF |
201 | { |
202 | del_timer_sync(&pTsCommonInfo->SetupTimer); | |
203 | del_timer_sync(&pTsCommonInfo->InactTimer); | |
204 | ||
f88ec6cb LF |
205 | if (InactTime != 0) |
206 | mod_timer(&pTsCommonInfo->InactTimer, jiffies + | |
8b9733c1 | 207 | msecs_to_jiffies(InactTime)); |
94a79942 LF |
208 | } |
209 | ||
ec0dc6be LF |
210 | static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee, |
211 | u8 *Addr, u8 TID, | |
212 | enum tr_select TxRxSelect) | |
94a79942 LF |
213 | { |
214 | u8 dir; | |
ec0dc6be | 215 | bool search_dir[4] = {0}; |
f88ec6cb | 216 | struct list_head *psearch_list; |
74724de1 | 217 | struct ts_common_info *pRet = NULL; |
3a6b70c3 | 218 | |
f88ec6cb LF |
219 | if (ieee->iw_mode == IW_MODE_MASTER) { |
220 | if (TxRxSelect == TX_DIR) { | |
94a79942 | 221 | search_dir[DIR_DOWN] = true; |
f88ec6cb LF |
222 | search_dir[DIR_BI_DIR] = true; |
223 | } else { | |
224 | search_dir[DIR_UP] = true; | |
225 | search_dir[DIR_BI_DIR] = true; | |
94a79942 | 226 | } |
f88ec6cb | 227 | } else if (ieee->iw_mode == IW_MODE_ADHOC) { |
94a79942 | 228 | if (TxRxSelect == TX_DIR) |
f88ec6cb | 229 | search_dir[DIR_UP] = true; |
94a79942 LF |
230 | else |
231 | search_dir[DIR_DOWN] = true; | |
f88ec6cb LF |
232 | } else { |
233 | if (TxRxSelect == TX_DIR) { | |
234 | search_dir[DIR_UP] = true; | |
235 | search_dir[DIR_BI_DIR] = true; | |
236 | search_dir[DIR_DIRECT] = true; | |
237 | } else { | |
94a79942 | 238 | search_dir[DIR_DOWN] = true; |
f88ec6cb LF |
239 | search_dir[DIR_BI_DIR] = true; |
240 | search_dir[DIR_DIRECT] = true; | |
94a79942 LF |
241 | } |
242 | } | |
243 | ||
244 | if (TxRxSelect == TX_DIR) | |
245 | psearch_list = &ieee->Tx_TS_Admit_List; | |
246 | else | |
247 | psearch_list = &ieee->Rx_TS_Admit_List; | |
248 | ||
f88ec6cb | 249 | for (dir = 0; dir <= DIR_BI_DIR; dir++) { |
4bb01423 | 250 | if (!search_dir[dir]) |
94a79942 | 251 | continue; |
f88ec6cb | 252 | list_for_each_entry(pRet, psearch_list, List) { |
35e33b04 MK |
253 | if (memcmp(pRet->Addr, Addr, 6) == 0 && |
254 | pRet->TSpec.f.TSInfo.field.ucTSID == TID && | |
255 | pRet->TSpec.f.TSInfo.field.ucDirection == dir) | |
256 | break; | |
94a79942 LF |
257 | |
258 | } | |
259 | if (&pRet->List != psearch_list) | |
260 | break; | |
261 | } | |
262 | ||
d7613e53 | 263 | if (pRet && &pRet->List != psearch_list) |
6af19767 | 264 | return pRet; |
13402f7b | 265 | return NULL; |
94a79942 LF |
266 | } |
267 | ||
ec0dc6be LF |
268 | static void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *Addr, |
269 | union tspec_body *pTSPEC, union qos_tclas *pTCLAS, | |
270 | u8 TCLAS_Num, u8 TCLAS_Proc) | |
94a79942 LF |
271 | { |
272 | u8 count; | |
273 | ||
274 | if (pTsCommonInfo == NULL) | |
275 | return; | |
276 | ||
277 | memcpy(pTsCommonInfo->Addr, Addr, 6); | |
278 | ||
279 | if (pTSPEC != NULL) | |
f88ec6cb LF |
280 | memcpy((u8 *)(&(pTsCommonInfo->TSpec)), (u8 *)pTSPEC, |
281 | sizeof(union tspec_body)); | |
94a79942 LF |
282 | |
283 | for (count = 0; count < TCLAS_Num; count++) | |
f88ec6cb LF |
284 | memcpy((u8 *)(&(pTsCommonInfo->TClass[count])), |
285 | (u8 *)pTCLAS, sizeof(union qos_tclas)); | |
94a79942 LF |
286 | |
287 | pTsCommonInfo->TClasProc = TCLAS_Proc; | |
288 | pTsCommonInfo->TClasNum = TCLAS_Num; | |
289 | } | |
290 | ||
f88ec6cb LF |
291 | bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, |
292 | u8 *Addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs) | |
94a79942 LF |
293 | { |
294 | u8 UP = 0; | |
285b7c00 MK |
295 | union tspec_body TSpec; |
296 | union qos_tsinfo *pTSInfo = &TSpec.f.TSInfo; | |
297 | struct list_head *pUnusedList; | |
298 | struct list_head *pAddmitList; | |
299 | enum direction_value Dir; | |
3a6b70c3 | 300 | |
14fc4235 | 301 | if (is_multicast_ether_addr(Addr)) { |
11e672c3 | 302 | netdev_warn(ieee->dev, "Get TS for Broadcast or Multicast\n"); |
94a79942 LF |
303 | return false; |
304 | } | |
305 | if (ieee->current_network.qos_data.supported == 0) { | |
306 | UP = 0; | |
307 | } else { | |
94a79942 LF |
308 | switch (TID) { |
309 | case 0: | |
310 | case 3: | |
311 | UP = 0; | |
312 | break; | |
313 | case 1: | |
314 | case 2: | |
315 | UP = 2; | |
316 | break; | |
317 | case 4: | |
318 | case 5: | |
319 | UP = 5; | |
320 | break; | |
321 | case 6: | |
322 | case 7: | |
323 | UP = 7; | |
324 | break; | |
95d93e27 MP |
325 | default: |
326 | netdev_warn(ieee->dev, "%s(): TID(%d) is not valid\n", | |
327 | __func__, TID); | |
328 | return false; | |
94a79942 LF |
329 | } |
330 | } | |
331 | ||
f88ec6cb | 332 | *ppTS = SearchAdmitTRStream(ieee, Addr, UP, TxRxSelect); |
285b7c00 | 333 | if (*ppTS != NULL) |
94a79942 | 334 | return true; |
285b7c00 MK |
335 | |
336 | if (!bAddNewTs) { | |
b94436b5 | 337 | netdev_dbg(ieee->dev, "add new TS failed(tid:%d)\n", UP); |
285b7c00 MK |
338 | return false; |
339 | } | |
340 | ||
341 | pUnusedList = (TxRxSelect == TX_DIR) ? | |
f88ec6cb LF |
342 | (&ieee->Tx_TS_Unused_List) : |
343 | (&ieee->Rx_TS_Unused_List); | |
344 | ||
285b7c00 | 345 | pAddmitList = (TxRxSelect == TX_DIR) ? |
f88ec6cb LF |
346 | (&ieee->Tx_TS_Admit_List) : |
347 | (&ieee->Rx_TS_Admit_List); | |
348 | ||
285b7c00 MK |
349 | Dir = (ieee->iw_mode == IW_MODE_MASTER) ? |
350 | ((TxRxSelect == TX_DIR) ? DIR_DOWN : DIR_UP) : | |
351 | ((TxRxSelect == TX_DIR) ? DIR_UP : DIR_DOWN); | |
352 | ||
285b7c00 MK |
353 | if (!list_empty(pUnusedList)) { |
354 | (*ppTS) = list_entry(pUnusedList->next, | |
355 | struct ts_common_info, List); | |
356 | list_del_init(&(*ppTS)->List); | |
357 | if (TxRxSelect == TX_DIR) { | |
358 | struct tx_ts_record *tmp = | |
359 | container_of(*ppTS, | |
360 | struct tx_ts_record, | |
361 | TsCommonInfo); | |
362 | ResetTxTsEntry(tmp); | |
363 | } else { | |
364 | struct rx_ts_record *tmp = | |
365 | container_of(*ppTS, | |
366 | struct rx_ts_record, | |
367 | TsCommonInfo); | |
368 | ResetRxTsEntry(tmp); | |
94a79942 | 369 | } |
285b7c00 | 370 | |
b94436b5 MK |
371 | netdev_dbg(ieee->dev, |
372 | "to init current TS, UP:%d, Dir:%d, addr: %pM ppTs=%p\n", | |
373 | UP, Dir, Addr, *ppTS); | |
285b7c00 MK |
374 | pTSInfo->field.ucTrafficType = 0; |
375 | pTSInfo->field.ucTSID = UP; | |
376 | pTSInfo->field.ucDirection = Dir; | |
377 | pTSInfo->field.ucAccessPolicy = 1; | |
378 | pTSInfo->field.ucAggregation = 0; | |
379 | pTSInfo->field.ucPSB = 0; | |
380 | pTSInfo->field.ucUP = UP; | |
381 | pTSInfo->field.ucTSInfoAckPolicy = 0; | |
382 | pTSInfo->field.ucSchedule = 0; | |
383 | ||
384 | MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0); | |
385 | AdmitTS(ieee, *ppTS, 0); | |
386 | list_add_tail(&((*ppTS)->List), pAddmitList); | |
387 | ||
388 | return true; | |
94a79942 | 389 | } |
285b7c00 | 390 | |
11e672c3 MK |
391 | netdev_warn(ieee->dev, |
392 | "There is not enough dir=%d(0=up down=1) TS record to be used!", | |
393 | Dir); | |
285b7c00 | 394 | return false; |
94a79942 LF |
395 | } |
396 | ||
35e33b04 MK |
397 | static void RemoveTsEntry(struct rtllib_device *ieee, |
398 | struct ts_common_info *pTs, enum tr_select TxRxSelect) | |
94a79942 LF |
399 | { |
400 | del_timer_sync(&pTs->SetupTimer); | |
401 | del_timer_sync(&pTs->InactTimer); | |
402 | TsInitDelBA(ieee, pTs, TxRxSelect); | |
403 | ||
f88ec6cb | 404 | if (TxRxSelect == RX_DIR) { |
8cba1432 | 405 | struct rx_reorder_entry *pRxReorderEntry; |
2c47ae28 | 406 | struct rx_ts_record *pRxTS = (struct rx_ts_record *)pTs; |
94a79942 LF |
407 | |
408 | if (timer_pending(&pRxTS->RxPktPendingTimer)) | |
409 | del_timer_sync(&pRxTS->RxPktPendingTimer); | |
410 | ||
f88ec6cb LF |
411 | while (!list_empty(&pRxTS->RxPendingPktList)) { |
412 | pRxReorderEntry = (struct rx_reorder_entry *) | |
413 | list_entry(pRxTS->RxPendingPktList.prev, | |
414 | struct rx_reorder_entry, List); | |
b94436b5 MK |
415 | netdev_dbg(ieee->dev, "%s(): Delete SeqNum %d!\n", |
416 | __func__, pRxReorderEntry->SeqNum); | |
94a79942 LF |
417 | list_del_init(&pRxReorderEntry->List); |
418 | { | |
419 | int i = 0; | |
f88ec6cb | 420 | struct rtllib_rxb *prxb = pRxReorderEntry->prxb; |
3a6b70c3 | 421 | |
f88ec6cb | 422 | if (unlikely(!prxb)) |
94a79942 | 423 | return; |
f88ec6cb | 424 | for (i = 0; i < prxb->nr_subframes; i++) |
94a79942 | 425 | dev_kfree_skb(prxb->subframes[i]); |
94a79942 LF |
426 | kfree(prxb); |
427 | prxb = NULL; | |
428 | } | |
f88ec6cb LF |
429 | list_add_tail(&pRxReorderEntry->List, |
430 | &ieee->RxReorder_Unused_List); | |
94a79942 | 431 | } |
f88ec6cb | 432 | } else { |
60554f2b | 433 | struct tx_ts_record *pTxTS = (struct tx_ts_record *)pTs; |
3a6b70c3 | 434 | |
94a79942 LF |
435 | del_timer_sync(&pTxTS->TsAddBaTimer); |
436 | } | |
437 | } | |
438 | ||
f88ec6cb | 439 | void RemovePeerTS(struct rtllib_device *ieee, u8 *Addr) |
94a79942 | 440 | { |
74724de1 | 441 | struct ts_common_info *pTS, *pTmpTS; |
3a6b70c3 | 442 | |
b99692f4 | 443 | netdev_info(ieee->dev, "===========>%s, %pM\n", __func__, Addr); |
4f6807e8 | 444 | |
f88ec6cb LF |
445 | list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { |
446 | if (memcmp(pTS->Addr, Addr, 6) == 0) { | |
94a79942 LF |
447 | RemoveTsEntry(ieee, pTS, TX_DIR); |
448 | list_del_init(&pTS->List); | |
449 | list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); | |
450 | } | |
451 | } | |
452 | ||
f88ec6cb LF |
453 | list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) { |
454 | if (memcmp(pTS->Addr, Addr, 6) == 0) { | |
d69d2054 MK |
455 | netdev_info(ieee->dev, |
456 | "====>remove Tx_TS_admin_list\n"); | |
94a79942 LF |
457 | RemoveTsEntry(ieee, pTS, TX_DIR); |
458 | list_del_init(&pTS->List); | |
459 | list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); | |
460 | } | |
461 | } | |
462 | ||
f88ec6cb LF |
463 | list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) { |
464 | if (memcmp(pTS->Addr, Addr, 6) == 0) { | |
94a79942 LF |
465 | RemoveTsEntry(ieee, pTS, RX_DIR); |
466 | list_del_init(&pTS->List); | |
467 | list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); | |
468 | } | |
469 | } | |
470 | ||
f88ec6cb LF |
471 | list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) { |
472 | if (memcmp(pTS->Addr, Addr, 6) == 0) { | |
94a79942 LF |
473 | RemoveTsEntry(ieee, pTS, RX_DIR); |
474 | list_del_init(&pTS->List); | |
475 | list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); | |
476 | } | |
477 | } | |
94a79942 | 478 | } |
3b28499c | 479 | EXPORT_SYMBOL(RemovePeerTS); |
94a79942 | 480 | |
f88ec6cb | 481 | void RemoveAllTS(struct rtllib_device *ieee) |
94a79942 | 482 | { |
74724de1 | 483 | struct ts_common_info *pTS, *pTmpTS; |
4f6807e8 | 484 | |
f88ec6cb | 485 | list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { |
94a79942 LF |
486 | RemoveTsEntry(ieee, pTS, TX_DIR); |
487 | list_del_init(&pTS->List); | |
488 | list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); | |
489 | } | |
490 | ||
f88ec6cb | 491 | list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) { |
94a79942 LF |
492 | RemoveTsEntry(ieee, pTS, TX_DIR); |
493 | list_del_init(&pTS->List); | |
494 | list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); | |
495 | } | |
496 | ||
f88ec6cb | 497 | list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) { |
94a79942 LF |
498 | RemoveTsEntry(ieee, pTS, RX_DIR); |
499 | list_del_init(&pTS->List); | |
500 | list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); | |
501 | } | |
502 | ||
f88ec6cb | 503 | list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) { |
94a79942 LF |
504 | RemoveTsEntry(ieee, pTS, RX_DIR); |
505 | list_del_init(&pTS->List); | |
506 | list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); | |
507 | } | |
94a79942 LF |
508 | } |
509 | ||
f88ec6cb | 510 | void TsStartAddBaProcess(struct rtllib_device *ieee, struct tx_ts_record *pTxTS) |
94a79942 | 511 | { |
f88ec6cb | 512 | if (pTxTS->bAddBaReqInProgress == false) { |
94a79942 | 513 | pTxTS->bAddBaReqInProgress = true; |
4f6807e8 | 514 | |
f88ec6cb | 515 | if (pTxTS->bAddBaReqDelayed) { |
b94436b5 | 516 | netdev_dbg(ieee->dev, "Start ADDBA after 60 sec!!\n"); |
f88ec6cb | 517 | mod_timer(&pTxTS->TsAddBaTimer, jiffies + |
8b9733c1 | 518 | msecs_to_jiffies(TS_ADDBA_DELAY)); |
f88ec6cb | 519 | } else { |
b94436b5 | 520 | netdev_dbg(ieee->dev, "Immediately Start ADDBA\n"); |
94a79942 LF |
521 | mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); |
522 | } | |
f88ec6cb | 523 | } else |
b94436b5 | 524 | netdev_dbg(ieee->dev, "BA timer is already added\n"); |
94a79942 | 525 | } |