1 /* 2 * Marvell Wireless LAN device driver: generic TX/RX data handling 3 * 4 * Copyright (C) 2011-2014, Marvell International Ltd. 5 * 6 * This software file (the "File") is distributed by Marvell International 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 8 * (the "License"). You may use, redistribute and/or modify this File in 9 * accordance with the terms and conditions of the License, a copy of which 10 * is available by writing to the Free Software Foundation, Inc., 11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the 12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 13 * 14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about 17 * this warranty disclaimer. 18 */ 19 20 #include "decl.h" 21 #include "ioctl.h" 22 #include "util.h" 23 #include "fw.h" 24 #include "main.h" 25 #include "wmm.h" 26 27 /* 28 * This function processes the received buffer. 29 * 30 * Main responsibility of this function is to parse the RxPD to 31 * identify the correct interface this packet is headed for and 32 * forwarding it to the associated handling function, where the 33 * packet will be further processed and sent to kernel/upper layer 34 * if required. 35 */ 36 int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, 37 struct sk_buff *skb) 38 { 39 struct mwifiex_private *priv = 40 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 41 struct rxpd *local_rx_pd; 42 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); 43 int ret; 44 45 local_rx_pd = (struct rxpd *) (skb->data); 46 /* Get the BSS number from rxpd, get corresponding priv */ 47 priv = mwifiex_get_priv_by_id(adapter, local_rx_pd->bss_num & 48 BSS_NUM_MASK, local_rx_pd->bss_type); 49 if (!priv) 50 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 51 52 if (!priv) { 53 mwifiex_dbg(adapter, ERROR, 54 "data: priv not found. Drop RX packet\n"); 55 dev_kfree_skb_any(skb); 56 return -1; 57 } 58 59 mwifiex_dbg_dump(adapter, DAT_D, "rx pkt:", skb->data, 60 min_t(size_t, skb->len, DEBUG_DUMP_DATA_MAX_LEN)); 61 62 memset(rx_info, 0, sizeof(*rx_info)); 63 rx_info->bss_num = priv->bss_num; 64 rx_info->bss_type = priv->bss_type; 65 66 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) 67 ret = mwifiex_process_uap_rx_packet(priv, skb); 68 else 69 ret = mwifiex_process_sta_rx_packet(priv, skb); 70 71 return ret; 72 } 73 EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); 74 75 /* 76 * This function sends a packet to device. 77 * 78 * It processes the packet to add the TxPD, checks condition and 79 * sends the processed packet to firmware for transmission. 80 * 81 * On successful completion, the function calls the completion callback 82 * and logs the time. 83 */ 84 int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, 85 struct mwifiex_tx_param *tx_param) 86 { 87 int hroom, ret = -1; 88 struct mwifiex_adapter *adapter = priv->adapter; 89 u8 *head_ptr; 90 struct txpd *local_tx_pd = NULL; 91 struct mwifiex_sta_node *dest_node; 92 struct ethhdr *hdr = (void *)skb->data; 93 94 hroom = (adapter->iface_type == MWIFIEX_USB) ? 0 : INTF_HEADER_LEN; 95 96 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) { 97 dest_node = mwifiex_get_sta_entry(priv, hdr->h_dest); 98 if (dest_node) { 99 dest_node->stats.tx_bytes += skb->len; 100 dest_node->stats.tx_packets++; 101 } 102 103 head_ptr = mwifiex_process_uap_txpd(priv, skb); 104 } else { 105 head_ptr = mwifiex_process_sta_txpd(priv, skb); 106 } 107 108 if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) { 109 skb_queue_tail(&adapter->tx_data_q, skb); 110 atomic_inc(&adapter->tx_queued); 111 return 0; 112 } 113 114 if (head_ptr) { 115 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) 116 local_tx_pd = (struct txpd *)(head_ptr + hroom); 117 if (adapter->iface_type == MWIFIEX_USB) { 118 ret = adapter->if_ops.host_to_card(adapter, 119 priv->usb_port, 120 skb, NULL); 121 } else { 122 ret = adapter->if_ops.host_to_card(adapter, 123 MWIFIEX_TYPE_DATA, 124 skb, tx_param); 125 } 126 } 127 mwifiex_dbg_dump(adapter, DAT_D, "tx pkt:", skb->data, 128 min_t(size_t, skb->len, DEBUG_DUMP_DATA_MAX_LEN)); 129 130 switch (ret) { 131 case -ENOSR: 132 mwifiex_dbg(adapter, DATA, "data: -ENOSR is returned\n"); 133 break; 134 case -EBUSY: 135 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && 136 (adapter->pps_uapsd_mode) && (adapter->tx_lock_flag)) { 137 priv->adapter->tx_lock_flag = false; 138 if (local_tx_pd) 139 local_tx_pd->flags = 0; 140 } 141 mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n"); 142 break; 143 case -1: 144 mwifiex_dbg(adapter, ERROR, 145 "mwifiex_write_data_async failed: 0x%X\n", 146 ret); 147 adapter->dbg.num_tx_host_to_card_failure++; 148 mwifiex_write_data_complete(adapter, skb, 0, ret); 149 break; 150 case -EINPROGRESS: 151 break; 152 case 0: 153 mwifiex_write_data_complete(adapter, skb, 0, ret); 154 break; 155 default: 156 break; 157 } 158 159 return ret; 160 } 161 162 static int mwifiex_host_to_card(struct mwifiex_adapter *adapter, 163 struct sk_buff *skb, 164 struct mwifiex_tx_param *tx_param) 165 { 166 struct txpd *local_tx_pd = NULL; 167 u8 *head_ptr = skb->data; 168 int ret = 0; 169 struct mwifiex_private *priv; 170 struct mwifiex_txinfo *tx_info; 171 172 tx_info = MWIFIEX_SKB_TXCB(skb); 173 priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num, 174 tx_info->bss_type); 175 if (!priv) { 176 mwifiex_dbg(adapter, ERROR, 177 "data: priv not found. Drop TX packet\n"); 178 adapter->dbg.num_tx_host_to_card_failure++; 179 mwifiex_write_data_complete(adapter, skb, 0, 0); 180 return ret; 181 } 182 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) { 183 if (adapter->iface_type == MWIFIEX_USB) 184 local_tx_pd = (struct txpd *)head_ptr; 185 else 186 local_tx_pd = (struct txpd *) (head_ptr + 187 INTF_HEADER_LEN); 188 } 189 190 if (adapter->iface_type == MWIFIEX_USB) { 191 ret = adapter->if_ops.host_to_card(adapter, 192 priv->usb_port, 193 skb, NULL); 194 } else { 195 ret = adapter->if_ops.host_to_card(adapter, 196 MWIFIEX_TYPE_DATA, 197 skb, tx_param); 198 } 199 switch (ret) { 200 case -ENOSR: 201 mwifiex_dbg(adapter, ERROR, "data: -ENOSR is returned\n"); 202 break; 203 case -EBUSY: 204 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && 205 (adapter->pps_uapsd_mode) && 206 (adapter->tx_lock_flag)) { 207 priv->adapter->tx_lock_flag = false; 208 if (local_tx_pd) 209 local_tx_pd->flags = 0; 210 } 211 skb_queue_head(&adapter->tx_data_q, skb); 212 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT) 213 atomic_add(tx_info->aggr_num, &adapter->tx_queued); 214 else 215 atomic_inc(&adapter->tx_queued); 216 mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n"); 217 break; 218 case -1: 219 mwifiex_dbg(adapter, ERROR, 220 "mwifiex_write_data_async failed: 0x%X\n", ret); 221 adapter->dbg.num_tx_host_to_card_failure++; 222 mwifiex_write_data_complete(adapter, skb, 0, ret); 223 break; 224 case -EINPROGRESS: 225 break; 226 case 0: 227 mwifiex_write_data_complete(adapter, skb, 0, ret); 228 break; 229 default: 230 break; 231 } 232 return ret; 233 } 234 235 static int 236 mwifiex_dequeue_tx_queue(struct mwifiex_adapter *adapter) 237 { 238 struct sk_buff *skb, *skb_next; 239 struct mwifiex_txinfo *tx_info; 240 struct mwifiex_tx_param tx_param; 241 242 skb = skb_dequeue(&adapter->tx_data_q); 243 if (!skb) 244 return -1; 245 246 tx_info = MWIFIEX_SKB_TXCB(skb); 247 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT) 248 atomic_sub(tx_info->aggr_num, &adapter->tx_queued); 249 else 250 atomic_dec(&adapter->tx_queued); 251 252 if (!skb_queue_empty(&adapter->tx_data_q)) 253 skb_next = skb_peek(&adapter->tx_data_q); 254 else 255 skb_next = NULL; 256 tx_param.next_pkt_len = ((skb_next) ? skb_next->len : 0); 257 if (!tx_param.next_pkt_len) { 258 if (!mwifiex_wmm_lists_empty(adapter)) 259 tx_param.next_pkt_len = 1; 260 } 261 return mwifiex_host_to_card(adapter, skb, &tx_param); 262 } 263 264 void 265 mwifiex_process_tx_queue(struct mwifiex_adapter *adapter) 266 { 267 do { 268 if (adapter->data_sent || adapter->tx_lock_flag) 269 break; 270 if (mwifiex_dequeue_tx_queue(adapter)) 271 break; 272 } while (!skb_queue_empty(&adapter->tx_data_q)); 273 } 274 275 /* 276 * Packet send completion callback handler. 277 * 278 * It either frees the buffer directly or forwards it to another 279 * completion callback which checks conditions, updates statistics, 280 * wakes up stalled traffic queue if required, and then frees the buffer. 281 */ 282 int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, 283 struct sk_buff *skb, int aggr, int status) 284 { 285 struct mwifiex_private *priv; 286 struct mwifiex_txinfo *tx_info; 287 struct netdev_queue *txq; 288 int index; 289 290 if (!skb) 291 return 0; 292 293 tx_info = MWIFIEX_SKB_TXCB(skb); 294 priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num, 295 tx_info->bss_type); 296 if (!priv) 297 goto done; 298 299 mwifiex_set_trans_start(priv->netdev); 300 301 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) 302 atomic_dec_return(&adapter->pending_bridged_pkts); 303 304 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT) 305 goto done; 306 307 if (!status) { 308 priv->stats.tx_packets++; 309 priv->stats.tx_bytes += tx_info->pkt_len; 310 if (priv->tx_timeout_cnt) 311 priv->tx_timeout_cnt = 0; 312 } else { 313 priv->stats.tx_errors++; 314 } 315 316 if (aggr) 317 /* For skb_aggr, do not wake up tx queue */ 318 goto done; 319 320 atomic_dec(&adapter->tx_pending); 321 322 index = mwifiex_1d_to_wmm_queue[skb->priority]; 323 if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) { 324 txq = netdev_get_tx_queue(priv->netdev, index); 325 if (netif_tx_queue_stopped(txq)) { 326 netif_tx_wake_queue(txq); 327 mwifiex_dbg(adapter, DATA, "wake queue: %d\n", index); 328 } 329 } 330 done: 331 dev_kfree_skb_any(skb); 332 333 return 0; 334 } 335 EXPORT_SYMBOL_GPL(mwifiex_write_data_complete); 336 337 void mwifiex_parse_tx_status_event(struct mwifiex_private *priv, 338 void *event_body) 339 { 340 struct tx_status_event *tx_status = (void *)priv->adapter->event_body; 341 struct sk_buff *ack_skb; 342 unsigned long flags; 343 struct mwifiex_txinfo *tx_info; 344 345 if (!tx_status->tx_token_id) 346 return; 347 348 spin_lock_irqsave(&priv->ack_status_lock, flags); 349 ack_skb = idr_find(&priv->ack_status_frames, tx_status->tx_token_id); 350 if (ack_skb) 351 idr_remove(&priv->ack_status_frames, tx_status->tx_token_id); 352 spin_unlock_irqrestore(&priv->ack_status_lock, flags); 353 354 if (ack_skb) { 355 tx_info = MWIFIEX_SKB_TXCB(ack_skb); 356 357 if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) { 358 /* consumes ack_skb */ 359 skb_complete_wifi_ack(ack_skb, !tx_status->status); 360 } else { 361 /* Remove broadcast address which was added by driver */ 362 memmove(ack_skb->data + 363 sizeof(struct ieee80211_hdr_3addr) + 364 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(u16), 365 ack_skb->data + 366 sizeof(struct ieee80211_hdr_3addr) + 367 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(u16) + 368 ETH_ALEN, ack_skb->len - 369 (sizeof(struct ieee80211_hdr_3addr) + 370 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(u16) + 371 ETH_ALEN)); 372 ack_skb->len = ack_skb->len - ETH_ALEN; 373 /* Remove driver's proprietary header including 2 bytes 374 * of packet length and pass actual management frame buffer 375 * to cfg80211. 376 */ 377 cfg80211_mgmt_tx_status(&priv->wdev, tx_info->cookie, 378 ack_skb->data + 379 MWIFIEX_MGMT_FRAME_HEADER_SIZE + 380 sizeof(u16), ack_skb->len - 381 (MWIFIEX_MGMT_FRAME_HEADER_SIZE 382 + sizeof(u16)), 383 !tx_status->status, GFP_ATOMIC); 384 dev_kfree_skb_any(ack_skb); 385 } 386 } 387 } 388