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