Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1 | /****************************************************************************** |
| 2 | * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. |
| 3 | * |
| 4 | * This program is distributed in the hope that it will be useful, but WITHOUT |
| 5 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 6 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 7 | * more details. |
| 8 | * |
| 9 | * You should have received a copy of the GNU General Public License along with |
| 10 | * this program; if not, write to the Free Software Foundation, Inc., |
| 11 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
| 12 | * |
| 13 | * The full GNU General Public License is included in this distribution in the |
| 14 | * file called LICENSE. |
| 15 | * |
| 16 | * Contact Information: |
| 17 | * wlanfae <wlanfae@realtek.com> |
| 18 | ******************************************************************************/ |
| 19 | #include "rtllib.h" |
| 20 | #include "rtl819x_BA.h" |
| 21 | #include "rtl_core.h" |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 22 | |
Larry Finger | ec0dc6be | 2011-08-25 14:07:04 -0500 | [diff] [blame] | 23 | static void ActivateBAEntry(struct rtllib_device *ieee, struct ba_record *pBA, |
| 24 | u16 Time) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 25 | { |
| 26 | pBA->bValid = true; |
| 27 | if (Time != 0) |
| 28 | mod_timer(&pBA->Timer, jiffies + MSECS(Time)); |
| 29 | } |
| 30 | |
Larry Finger | ec0dc6be | 2011-08-25 14:07:04 -0500 | [diff] [blame] | 31 | static void DeActivateBAEntry(struct rtllib_device *ieee, struct ba_record *pBA) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 32 | { |
| 33 | pBA->bValid = false; |
| 34 | del_timer_sync(&pBA->Timer); |
| 35 | } |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 36 | |
Larry Finger | ec0dc6be | 2011-08-25 14:07:04 -0500 | [diff] [blame] | 37 | static u8 TxTsDeleteBA(struct rtllib_device *ieee, struct tx_ts_record *pTxTs) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 38 | { |
Larry Finger | 8cf3331 | 2011-07-18 21:03:22 -0500 | [diff] [blame] | 39 | struct ba_record *pAdmittedBa = &pTxTs->TxAdmittedBARecord; |
| 40 | struct ba_record *pPendingBa = &pTxTs->TxPendingBARecord; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 41 | u8 bSendDELBA = false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 42 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 43 | if (pPendingBa->bValid) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 44 | DeActivateBAEntry(ieee, pPendingBa); |
| 45 | bSendDELBA = true; |
| 46 | } |
| 47 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 48 | if (pAdmittedBa->bValid) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 49 | DeActivateBAEntry(ieee, pAdmittedBa); |
| 50 | bSendDELBA = true; |
| 51 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 52 | return bSendDELBA; |
| 53 | } |
| 54 | |
Larry Finger | ec0dc6be | 2011-08-25 14:07:04 -0500 | [diff] [blame] | 55 | static u8 RxTsDeleteBA(struct rtllib_device *ieee, struct rx_ts_record *pRxTs) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 56 | { |
Larry Finger | 8cf3331 | 2011-07-18 21:03:22 -0500 | [diff] [blame] | 57 | struct ba_record *pBa = &pRxTs->RxAdmittedBARecord; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 58 | u8 bSendDELBA = false; |
| 59 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 60 | if (pBa->bValid) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 61 | DeActivateBAEntry(ieee, pBa); |
| 62 | bSendDELBA = true; |
| 63 | } |
| 64 | |
| 65 | return bSendDELBA; |
| 66 | } |
| 67 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 68 | void ResetBaEntry(struct ba_record *pBA) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 69 | { |
| 70 | pBA->bValid = false; |
| 71 | pBA->BaParamSet.shortData = 0; |
| 72 | pBA->BaTimeoutValue = 0; |
| 73 | pBA->DialogToken = 0; |
| 74 | pBA->BaStartSeqCtrl.ShortData = 0; |
| 75 | } |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 76 | static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, |
| 77 | struct ba_record *pBA, |
| 78 | u16 StatusCode, u8 type) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 79 | { |
| 80 | struct sk_buff *skb = NULL; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 81 | struct rtllib_hdr_3addr *BAReq = NULL; |
| 82 | u8 *tag = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 83 | u16 tmp = 0; |
| 84 | u16 len = ieee->tx_headroom + 9; |
Larry Finger | ce7b393 | 2011-09-01 12:23:18 -0500 | [diff] [blame] | 85 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 86 | RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), frame(%d)" |
Larry Finger | ac50dda | 2011-08-25 14:07:03 -0500 | [diff] [blame] | 87 | " sentd to: %pM, ieee->dev:%p\n", __func__, |
| 88 | type, Dst, ieee->dev); |
Larry Finger | ce7b393 | 2011-09-01 12:23:18 -0500 | [diff] [blame] | 89 | if (pBA == NULL) { |
Larry Finger | a85fe2c | 2011-09-01 12:32:28 -0500 | [diff] [blame^] | 90 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "pBA is NULL\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 91 | return NULL; |
| 92 | } |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 93 | skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); |
| 94 | if (skb == NULL) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 95 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); |
| 96 | return NULL; |
| 97 | } |
| 98 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 99 | memset(skb->data, 0, sizeof(struct rtllib_hdr_3addr)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 100 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 101 | skb_reserve(skb, ieee->tx_headroom); |
| 102 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 103 | BAReq = (struct rtllib_hdr_3addr *)skb_put(skb, |
| 104 | sizeof(struct rtllib_hdr_3addr)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 105 | |
| 106 | memcpy(BAReq->addr1, Dst, ETH_ALEN); |
| 107 | memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN); |
| 108 | |
| 109 | memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN); |
| 110 | BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); |
| 111 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 112 | tag = (u8 *)skb_put(skb, 9); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 113 | *tag ++= ACT_CAT_BA; |
| 114 | *tag ++= type; |
| 115 | *tag ++= pBA->DialogToken; |
| 116 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 117 | if (ACT_ADDBARSP == type) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 118 | RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n"); |
| 119 | tmp = cpu_to_le16(StatusCode); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 120 | memcpy(tag, (u8 *)&tmp, 2); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 121 | tag += 2; |
| 122 | } |
| 123 | tmp = cpu_to_le16(pBA->BaParamSet.shortData); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 124 | memcpy(tag, (u8 *)&tmp, 2); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 125 | tag += 2; |
| 126 | tmp = cpu_to_le16(pBA->BaTimeoutValue); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 127 | memcpy(tag, (u8 *)&tmp, 2); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 128 | tag += 2; |
| 129 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 130 | if (ACT_ADDBAREQ == type) { |
| 131 | memcpy(tag, (u8 *)&(pBA->BaStartSeqCtrl), 2); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 132 | tag += 2; |
| 133 | } |
| 134 | |
| 135 | RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); |
| 136 | return skb; |
| 137 | } |
| 138 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 139 | static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, |
| 140 | struct ba_record *pBA, |
| 141 | enum tr_select TxRxSelect, u16 ReasonCode) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 142 | { |
Larry Finger | f198db0 | 2011-07-19 10:17:01 -0500 | [diff] [blame] | 143 | union delba_param_set DelbaParamSet; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 144 | struct sk_buff *skb = NULL; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 145 | struct rtllib_hdr_3addr *Delba = NULL; |
| 146 | u8 *tag = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 147 | u16 tmp = 0; |
| 148 | u16 len = 6 + ieee->tx_headroom; |
| 149 | |
| 150 | if (net_ratelimit()) |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 151 | RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, |
| 152 | "========>%s(), Reason" |
Larry Finger | ac50dda | 2011-08-25 14:07:03 -0500 | [diff] [blame] | 153 | "Code(%d) sentd to: %pM\n", __func__, |
| 154 | ReasonCode, dst); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 155 | |
| 156 | memset(&DelbaParamSet, 0, 2); |
| 157 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 158 | DelbaParamSet.field.Initiator = (TxRxSelect == TX_DIR) ? 1 : 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 159 | DelbaParamSet.field.TID = pBA->BaParamSet.field.TID; |
| 160 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 161 | skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); |
| 162 | if (skb == NULL) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 163 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); |
| 164 | return NULL; |
| 165 | } |
| 166 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 167 | skb_reserve(skb, ieee->tx_headroom); |
| 168 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 169 | Delba = (struct rtllib_hdr_3addr *) skb_put(skb, |
| 170 | sizeof(struct rtllib_hdr_3addr)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 171 | |
| 172 | memcpy(Delba->addr1, dst, ETH_ALEN); |
| 173 | memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN); |
| 174 | memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN); |
| 175 | Delba->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); |
| 176 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 177 | tag = (u8 *)skb_put(skb, 6); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 178 | |
| 179 | *tag ++= ACT_CAT_BA; |
| 180 | *tag ++= ACT_DELBA; |
| 181 | |
| 182 | tmp = cpu_to_le16(DelbaParamSet.shortData); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 183 | memcpy(tag, (u8 *)&tmp, 2); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 184 | tag += 2; |
| 185 | tmp = cpu_to_le16(ReasonCode); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 186 | memcpy(tag, (u8 *)&tmp, 2); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 187 | tag += 2; |
| 188 | |
| 189 | RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); |
| 190 | if (net_ratelimit()) |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 191 | RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "<=====%s()\n", |
| 192 | __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 193 | return skb; |
| 194 | } |
| 195 | |
Larry Finger | ec0dc6be | 2011-08-25 14:07:04 -0500 | [diff] [blame] | 196 | static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst, |
| 197 | struct ba_record *pBA) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 198 | { |
| 199 | struct sk_buff *skb = NULL; |
| 200 | skb = rtllib_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); |
| 201 | |
| 202 | if (skb) { |
| 203 | RT_TRACE(COMP_DBG, "====>to send ADDBAREQ!!!!!\n"); |
| 204 | softmac_mgmt_xmit(skb, ieee); |
| 205 | } else { |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 206 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function" |
| 207 | " %s()\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 208 | } |
| 209 | return; |
| 210 | } |
| 211 | |
Larry Finger | ec0dc6be | 2011-08-25 14:07:04 -0500 | [diff] [blame] | 212 | static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst, |
| 213 | struct ba_record *pBA, u16 StatusCode) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 214 | { |
| 215 | struct sk_buff *skb = NULL; |
| 216 | skb = rtllib_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); |
| 217 | if (skb) |
| 218 | softmac_mgmt_xmit(skb, ieee); |
| 219 | else |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 220 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function" |
| 221 | " %s()\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 222 | return; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 223 | } |
| 224 | |
Larry Finger | ec0dc6be | 2011-08-25 14:07:04 -0500 | [diff] [blame] | 225 | static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst, |
| 226 | struct ba_record *pBA, enum tr_select TxRxSelect, |
| 227 | u16 ReasonCode) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 228 | { |
| 229 | struct sk_buff *skb = NULL; |
| 230 | skb = rtllib_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); |
| 231 | if (skb) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 232 | softmac_mgmt_xmit(skb, ieee); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 233 | else |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 234 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in func" |
| 235 | "tion %s()\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 236 | return ; |
| 237 | } |
| 238 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 239 | int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 240 | { |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 241 | struct rtllib_hdr_3addr *req = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 242 | u16 rc = 0; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 243 | u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; |
Larry Finger | 8cf3331 | 2011-07-18 21:03:22 -0500 | [diff] [blame] | 244 | struct ba_record *pBA = NULL; |
Larry Finger | 6857f36 | 2011-07-19 10:14:55 -0500 | [diff] [blame] | 245 | union ba_param_set *pBaParamSet = NULL; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 246 | u16 *pBaTimeoutVal = NULL; |
Larry Finger | 7baf954 | 2011-07-19 10:11:23 -0500 | [diff] [blame] | 247 | union sequence_control *pBaStartSeqCtrl = NULL; |
Larry Finger | 2c47ae2 | 2011-07-18 20:11:56 -0500 | [diff] [blame] | 248 | struct rx_ts_record *pTS = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 249 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 250 | if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { |
| 251 | RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BAREQ(%d / " |
| 252 | "%d)\n", (int)skb->len, |
| 253 | (int)(sizeof(struct rtllib_hdr_3addr) + 9)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 254 | return -1; |
| 255 | } |
| 256 | |
| 257 | RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); |
| 258 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 259 | req = (struct rtllib_hdr_3addr *) skb->data; |
| 260 | tag = (u8 *)req; |
| 261 | dst = (u8 *)(&req->addr2[0]); |
| 262 | tag += sizeof(struct rtllib_hdr_3addr); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 263 | pDialogToken = tag + 2; |
Larry Finger | 6857f36 | 2011-07-19 10:14:55 -0500 | [diff] [blame] | 264 | pBaParamSet = (union ba_param_set *)(tag + 3); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 265 | pBaTimeoutVal = (u16 *)(tag + 5); |
Larry Finger | 7baf954 | 2011-07-19 10:11:23 -0500 | [diff] [blame] | 266 | pBaStartSeqCtrl = (union sequence_control *)(req + 7); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 267 | |
Larry Finger | ac50dda | 2011-08-25 14:07:03 -0500 | [diff] [blame] | 268 | RT_TRACE(COMP_DBG, "====>rx ADDBAREQ from : %pM\n", dst); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 269 | if (ieee->current_network.qos_data.active == 0 || |
| 270 | (ieee->pHTInfo->bCurrentHTSupport == false) || |
| 271 | (ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ)) { |
| 272 | rc = ADDBA_STATUS_REFUSED; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 273 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "Failed to reply on ADDBA_REQ as " |
| 274 | "some capability is not ready(%d, %d)\n", |
| 275 | ieee->current_network.qos_data.active, |
| 276 | ieee->pHTInfo->bCurrentHTSupport); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 277 | goto OnADDBAReq_Fail; |
| 278 | } |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 279 | if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, |
| 280 | (u8)(pBaParamSet->field.TID), RX_DIR, true)) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 281 | rc = ADDBA_STATUS_REFUSED; |
| 282 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__); |
| 283 | goto OnADDBAReq_Fail; |
| 284 | } |
| 285 | pBA = &pTS->RxAdmittedBARecord; |
| 286 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 287 | if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 288 | rc = ADDBA_STATUS_INVALID_PARAM; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 289 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "BA Policy is not correct in " |
| 290 | "%s()\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 291 | goto OnADDBAReq_Fail; |
| 292 | } |
| 293 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 294 | rtllib_FlushRxTsPendingPkts(ieee, pTS); |
| 295 | |
| 296 | DeActivateBAEntry(ieee, pBA); |
| 297 | pBA->DialogToken = *pDialogToken; |
| 298 | pBA->BaParamSet = *pBaParamSet; |
| 299 | pBA->BaTimeoutValue = *pBaTimeoutVal; |
| 300 | pBA->BaStartSeqCtrl = *pBaStartSeqCtrl; |
| 301 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 302 | if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) || |
| 303 | (ieee->pHTInfo->IOTAction & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT)) |
| 304 | pBA->BaParamSet.field.BufferSize = 1; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 305 | else |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 306 | pBA->BaParamSet.field.BufferSize = 32; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 307 | |
| 308 | ActivateBAEntry(ieee, pBA, 0); |
| 309 | rtllib_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS); |
| 310 | |
| 311 | return 0; |
| 312 | |
| 313 | OnADDBAReq_Fail: |
| 314 | { |
Larry Finger | 8cf3331 | 2011-07-18 21:03:22 -0500 | [diff] [blame] | 315 | struct ba_record BA; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 316 | BA.BaParamSet = *pBaParamSet; |
| 317 | BA.BaTimeoutValue = *pBaTimeoutVal; |
| 318 | BA.DialogToken = *pDialogToken; |
| 319 | BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE; |
| 320 | rtllib_send_ADDBARsp(ieee, dst, &BA, rc); |
| 321 | return 0; |
| 322 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 323 | } |
| 324 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 325 | int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 326 | { |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 327 | struct rtllib_hdr_3addr *rsp = NULL; |
Larry Finger | 8cf3331 | 2011-07-18 21:03:22 -0500 | [diff] [blame] | 328 | struct ba_record *pPendingBA, *pAdmittedBA; |
Larry Finger | 60554f2 | 2011-07-18 20:10:03 -0500 | [diff] [blame] | 329 | struct tx_ts_record *pTS = NULL; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 330 | u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; |
| 331 | u16 *pStatusCode = NULL, *pBaTimeoutVal = NULL; |
Larry Finger | 6857f36 | 2011-07-19 10:14:55 -0500 | [diff] [blame] | 332 | union ba_param_set *pBaParamSet = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 333 | u16 ReasonCode; |
| 334 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 335 | if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { |
| 336 | RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BARSP(%d / " |
| 337 | "%d)\n", (int)skb->len, |
| 338 | (int)(sizeof(struct rtllib_hdr_3addr) + 9)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 339 | return -1; |
| 340 | } |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 341 | rsp = (struct rtllib_hdr_3addr *)skb->data; |
| 342 | tag = (u8 *)rsp; |
| 343 | dst = (u8 *)(&rsp->addr2[0]); |
| 344 | tag += sizeof(struct rtllib_hdr_3addr); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 345 | pDialogToken = tag + 2; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 346 | pStatusCode = (u16 *)(tag + 3); |
Larry Finger | 6857f36 | 2011-07-19 10:14:55 -0500 | [diff] [blame] | 347 | pBaParamSet = (union ba_param_set *)(tag + 5); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 348 | pBaTimeoutVal = (u16 *)(tag + 7); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 349 | |
Larry Finger | ac50dda | 2011-08-25 14:07:03 -0500 | [diff] [blame] | 350 | RT_TRACE(COMP_DBG, "====>rx ADDBARSP from : %pM\n", dst); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 351 | if (ieee->current_network.qos_data.active == 0 || |
| 352 | ieee->pHTInfo->bCurrentHTSupport == false || |
| 353 | ieee->pHTInfo->bCurrentAMPDUEnable == false) { |
| 354 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "reject to ADDBA_RSP as some capab" |
| 355 | "ility is not ready(%d, %d, %d)\n", |
| 356 | ieee->current_network.qos_data.active, |
| 357 | ieee->pHTInfo->bCurrentHTSupport, |
| 358 | ieee->pHTInfo->bCurrentAMPDUEnable); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 359 | ReasonCode = DELBA_REASON_UNKNOWN_BA; |
| 360 | goto OnADDBARsp_Reject; |
| 361 | } |
| 362 | |
| 363 | |
Larry Finger | 74724de | 2011-07-18 20:19:19 -0500 | [diff] [blame] | 364 | if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 365 | (u8)(pBaParamSet->field.TID), TX_DIR, false)) { |
| 366 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__); |
| 367 | ReasonCode = DELBA_REASON_UNKNOWN_BA; |
| 368 | goto OnADDBARsp_Reject; |
| 369 | } |
| 370 | |
| 371 | pTS->bAddBaReqInProgress = false; |
| 372 | pPendingBA = &pTS->TxPendingBARecord; |
| 373 | pAdmittedBA = &pTS->TxAdmittedBARecord; |
| 374 | |
| 375 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 376 | if ((pAdmittedBA->bValid == true)) { |
| 377 | RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp." |
| 378 | " Drop because already admit it!\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 379 | return -1; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 380 | } else if ((pPendingBA->bValid == false) || |
| 381 | (*pDialogToken != pPendingBA->DialogToken)) { |
| 382 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. " |
| 383 | "BA invalid, DELBA!\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 384 | ReasonCode = DELBA_REASON_UNKNOWN_BA; |
| 385 | goto OnADDBARsp_Reject; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 386 | } else { |
| 387 | RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA " |
| 388 | "is admitted! Status code:%X\n", *pStatusCode); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 389 | DeActivateBAEntry(ieee, pPendingBA); |
| 390 | } |
| 391 | |
| 392 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 393 | if (*pStatusCode == ADDBA_STATUS_SUCCESS) { |
| 394 | if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 395 | pTS->bAddBaReqDelayed = true; |
| 396 | DeActivateBAEntry(ieee, pAdmittedBA); |
| 397 | ReasonCode = DELBA_REASON_END_BA; |
| 398 | goto OnADDBARsp_Reject; |
| 399 | } |
| 400 | |
| 401 | |
| 402 | pAdmittedBA->DialogToken = *pDialogToken; |
| 403 | pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal; |
| 404 | pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl; |
| 405 | pAdmittedBA->BaParamSet = *pBaParamSet; |
| 406 | DeActivateBAEntry(ieee, pAdmittedBA); |
| 407 | ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal); |
| 408 | } else { |
| 409 | pTS->bAddBaReqDelayed = true; |
| 410 | pTS->bDisable_AddBa = true; |
| 411 | ReasonCode = DELBA_REASON_END_BA; |
| 412 | goto OnADDBARsp_Reject; |
| 413 | } |
| 414 | |
| 415 | return 0; |
| 416 | |
| 417 | OnADDBARsp_Reject: |
| 418 | { |
Larry Finger | 8cf3331 | 2011-07-18 21:03:22 -0500 | [diff] [blame] | 419 | struct ba_record BA; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 420 | BA.BaParamSet = *pBaParamSet; |
| 421 | rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode); |
| 422 | return 0; |
| 423 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 424 | } |
| 425 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 426 | int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 427 | { |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 428 | struct rtllib_hdr_3addr *delba = NULL; |
Larry Finger | f198db0 | 2011-07-19 10:17:01 -0500 | [diff] [blame] | 429 | union delba_param_set *pDelBaParamSet = NULL; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 430 | u16 *pReasonCode = NULL; |
| 431 | u8 *dst = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 432 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 433 | if (skb->len < sizeof(struct rtllib_hdr_3addr) + 6) { |
| 434 | RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in DELBA(%d /" |
| 435 | " %d)\n", (int)skb->len, |
| 436 | (int)(sizeof(struct rtllib_hdr_3addr) + 6)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 437 | return -1; |
| 438 | } |
| 439 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 440 | if (ieee->current_network.qos_data.active == 0 || |
| 441 | ieee->pHTInfo->bCurrentHTSupport == false) { |
| 442 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "received DELBA while QOS or HT " |
| 443 | "is not supported(%d, %d)\n", |
| 444 | ieee->current_network. qos_data.active, |
| 445 | ieee->pHTInfo->bCurrentHTSupport); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 446 | return -1; |
| 447 | } |
| 448 | |
| 449 | RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 450 | delba = (struct rtllib_hdr_3addr *)skb->data; |
| 451 | dst = (u8 *)(&delba->addr2[0]); |
| 452 | delba += sizeof(struct rtllib_hdr_3addr); |
Larry Finger | f198db0 | 2011-07-19 10:17:01 -0500 | [diff] [blame] | 453 | pDelBaParamSet = (union delba_param_set *)(delba+2); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 454 | pReasonCode = (u16 *)(delba+4); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 455 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 456 | if (pDelBaParamSet->field.Initiator == 1) { |
Larry Finger | 2c47ae2 | 2011-07-18 20:11:56 -0500 | [diff] [blame] | 457 | struct rx_ts_record *pRxTs; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 458 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 459 | if (!GetTs(ieee, (struct ts_common_info **)&pRxTs, dst, |
| 460 | (u8)pDelBaParamSet->field.TID, RX_DIR, false)) { |
| 461 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS for RXTS in " |
Larry Finger | ac50dda | 2011-08-25 14:07:03 -0500 | [diff] [blame] | 462 | "%s().dst: %pM TID:%d\n", __func__, dst, |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 463 | (u8)pDelBaParamSet->field.TID); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 464 | return -1; |
| 465 | } |
| 466 | |
| 467 | RxTsDeleteBA(ieee, pRxTs); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 468 | } else { |
Larry Finger | 60554f2 | 2011-07-18 20:10:03 -0500 | [diff] [blame] | 469 | struct tx_ts_record *pTxTs; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 470 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 471 | if (!GetTs(ieee, (struct ts_common_info **)&pTxTs, dst, |
| 472 | (u8)pDelBaParamSet->field.TID, TX_DIR, false)) { |
| 473 | RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS for TXTS in " |
| 474 | "%s()\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 475 | return -1; |
| 476 | } |
| 477 | |
| 478 | pTxTs->bUsingBa = false; |
| 479 | pTxTs->bAddBaReqInProgress = false; |
| 480 | pTxTs->bAddBaReqDelayed = false; |
| 481 | del_timer_sync(&pTxTs->TsAddBaTimer); |
| 482 | TxTsDeleteBA(ieee, pTxTs); |
| 483 | } |
| 484 | return 0; |
| 485 | } |
| 486 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 487 | void TsInitAddBA(struct rtllib_device *ieee, struct tx_ts_record *pTS, |
| 488 | u8 Policy, u8 bOverwritePending) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 489 | { |
Larry Finger | 8cf3331 | 2011-07-18 21:03:22 -0500 | [diff] [blame] | 490 | struct ba_record *pBA = &pTS->TxPendingBARecord; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 491 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 492 | if (pBA->bValid == true && bOverwritePending == false) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 493 | return; |
| 494 | |
| 495 | DeActivateBAEntry(ieee, pBA); |
| 496 | |
| 497 | pBA->DialogToken++; |
| 498 | pBA->BaParamSet.field.AMSDU_Support = 0; |
| 499 | pBA->BaParamSet.field.BAPolicy = Policy; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 500 | pBA->BaParamSet.field.TID = |
| 501 | pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 502 | pBA->BaParamSet.field.BufferSize = 32; |
| 503 | pBA->BaTimeoutValue = 0; |
| 504 | pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; |
| 505 | |
| 506 | ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT); |
| 507 | |
| 508 | rtllib_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA); |
| 509 | } |
| 510 | |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 511 | void TsInitDelBA(struct rtllib_device *ieee, |
| 512 | struct ts_common_info *pTsCommonInfo, |
| 513 | enum tr_select TxRxSelect) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 514 | { |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 515 | if (TxRxSelect == TX_DIR) { |
| 516 | struct tx_ts_record *pTxTs = |
| 517 | (struct tx_ts_record *)pTsCommonInfo; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 518 | |
| 519 | if (TxTsDeleteBA(ieee, pTxTs)) |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 520 | rtllib_send_DELBA(ieee, pTsCommonInfo->Addr, |
| 521 | (pTxTs->TxAdmittedBARecord.bValid) ? |
| 522 | (&pTxTs->TxAdmittedBARecord) : |
| 523 | (&pTxTs->TxPendingBARecord), |
| 524 | TxRxSelect, DELBA_REASON_END_BA); |
| 525 | } else if (TxRxSelect == RX_DIR) { |
| 526 | struct rx_ts_record *pRxTs = |
| 527 | (struct rx_ts_record *)pTsCommonInfo; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 528 | if (RxTsDeleteBA(ieee, pRxTs)) |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 529 | rtllib_send_DELBA(ieee, pTsCommonInfo->Addr, |
| 530 | &pRxTs->RxAdmittedBARecord, |
| 531 | TxRxSelect, DELBA_REASON_END_BA); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 532 | } |
| 533 | } |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 534 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 535 | void BaSetupTimeOut(unsigned long data) |
| 536 | { |
Larry Finger | 60554f2 | 2011-07-18 20:10:03 -0500 | [diff] [blame] | 537 | struct tx_ts_record *pTxTs = (struct tx_ts_record *)data; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 538 | |
| 539 | pTxTs->bAddBaReqInProgress = false; |
| 540 | pTxTs->bAddBaReqDelayed = true; |
| 541 | pTxTs->TxPendingBARecord.bValid = false; |
| 542 | } |
| 543 | |
| 544 | void TxBaInactTimeout(unsigned long data) |
| 545 | { |
Larry Finger | 60554f2 | 2011-07-18 20:10:03 -0500 | [diff] [blame] | 546 | struct tx_ts_record *pTxTs = (struct tx_ts_record *)data; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 547 | struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device, |
| 548 | TxTsRecord[pTxTs->num]); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 549 | TxTsDeleteBA(ieee, pTxTs); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 550 | rtllib_send_DELBA(ieee, pTxTs->TsCommonInfo.Addr, |
| 551 | &pTxTs->TxAdmittedBARecord, TX_DIR, |
| 552 | DELBA_REASON_TIMEOUT); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 553 | } |
| 554 | |
| 555 | void RxBaInactTimeout(unsigned long data) |
| 556 | { |
Larry Finger | 2c47ae2 | 2011-07-18 20:11:56 -0500 | [diff] [blame] | 557 | struct rx_ts_record *pRxTs = (struct rx_ts_record *)data; |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 558 | struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, |
| 559 | RxTsRecord[pRxTs->num]); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 560 | |
| 561 | RxTsDeleteBA(ieee, pRxTs); |
Larry Finger | 831cb9d | 2011-08-25 11:48:17 -0500 | [diff] [blame] | 562 | rtllib_send_DELBA(ieee, pRxTs->TsCommonInfo.Addr, |
| 563 | &pRxTs->RxAdmittedBARecord, RX_DIR, |
| 564 | DELBA_REASON_TIMEOUT); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 565 | return ; |
| 566 | } |