0001
0002
0003
0004
0005
0006
0007
0008 #include "decl.h"
0009 #include "ioctl.h"
0010 #include "util.h"
0011 #include "fw.h"
0012 #include "main.h"
0013 #include "wmm.h"
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
0025 struct sk_buff *skb)
0026 {
0027 struct mwifiex_private *priv =
0028 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
0029 struct rxpd *local_rx_pd;
0030 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
0031 int ret;
0032
0033 local_rx_pd = (struct rxpd *) (skb->data);
0034
0035 priv = mwifiex_get_priv_by_id(adapter, local_rx_pd->bss_num &
0036 BSS_NUM_MASK, local_rx_pd->bss_type);
0037 if (!priv)
0038 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
0039
0040 if (!priv) {
0041 mwifiex_dbg(adapter, ERROR,
0042 "data: priv not found. Drop RX packet\n");
0043 dev_kfree_skb_any(skb);
0044 return -1;
0045 }
0046
0047 mwifiex_dbg_dump(adapter, DAT_D, "rx pkt:", skb->data,
0048 min_t(size_t, skb->len, DEBUG_DUMP_DATA_MAX_LEN));
0049
0050 memset(rx_info, 0, sizeof(*rx_info));
0051 rx_info->bss_num = priv->bss_num;
0052 rx_info->bss_type = priv->bss_type;
0053
0054 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
0055 ret = mwifiex_process_uap_rx_packet(priv, skb);
0056 else
0057 ret = mwifiex_process_sta_rx_packet(priv, skb);
0058
0059 return ret;
0060 }
0061 EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
0073 struct mwifiex_tx_param *tx_param)
0074 {
0075 int hroom, ret = -1;
0076 struct mwifiex_adapter *adapter = priv->adapter;
0077 u8 *head_ptr;
0078 struct txpd *local_tx_pd = NULL;
0079 struct mwifiex_sta_node *dest_node;
0080 struct ethhdr *hdr = (void *)skb->data;
0081
0082 hroom = adapter->intf_hdr_len;
0083
0084 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) {
0085 dest_node = mwifiex_get_sta_entry(priv, hdr->h_dest);
0086 if (dest_node) {
0087 dest_node->stats.tx_bytes += skb->len;
0088 dest_node->stats.tx_packets++;
0089 }
0090
0091 head_ptr = mwifiex_process_uap_txpd(priv, skb);
0092 } else {
0093 head_ptr = mwifiex_process_sta_txpd(priv, skb);
0094 }
0095
0096 if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) {
0097 skb_queue_tail(&adapter->tx_data_q, skb);
0098 atomic_inc(&adapter->tx_queued);
0099 return 0;
0100 }
0101
0102 if (head_ptr) {
0103 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
0104 local_tx_pd = (struct txpd *)(head_ptr + hroom);
0105 if (adapter->iface_type == MWIFIEX_USB) {
0106 ret = adapter->if_ops.host_to_card(adapter,
0107 priv->usb_port,
0108 skb, tx_param);
0109 } else {
0110 ret = adapter->if_ops.host_to_card(adapter,
0111 MWIFIEX_TYPE_DATA,
0112 skb, tx_param);
0113 }
0114 }
0115 mwifiex_dbg_dump(adapter, DAT_D, "tx pkt:", skb->data,
0116 min_t(size_t, skb->len, DEBUG_DUMP_DATA_MAX_LEN));
0117
0118 switch (ret) {
0119 case -ENOSR:
0120 mwifiex_dbg(adapter, DATA, "data: -ENOSR is returned\n");
0121 break;
0122 case -EBUSY:
0123 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
0124 (adapter->pps_uapsd_mode) && (adapter->tx_lock_flag)) {
0125 priv->adapter->tx_lock_flag = false;
0126 if (local_tx_pd)
0127 local_tx_pd->flags = 0;
0128 }
0129 mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n");
0130 break;
0131 case -1:
0132 mwifiex_dbg(adapter, ERROR,
0133 "mwifiex_write_data_async failed: 0x%X\n",
0134 ret);
0135 adapter->dbg.num_tx_host_to_card_failure++;
0136 mwifiex_write_data_complete(adapter, skb, 0, ret);
0137 break;
0138 case -EINPROGRESS:
0139 break;
0140 case 0:
0141 mwifiex_write_data_complete(adapter, skb, 0, ret);
0142 break;
0143 default:
0144 break;
0145 }
0146
0147 return ret;
0148 }
0149
0150 static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
0151 struct sk_buff *skb,
0152 struct mwifiex_tx_param *tx_param)
0153 {
0154 struct txpd *local_tx_pd = NULL;
0155 u8 *head_ptr = skb->data;
0156 int ret = 0;
0157 struct mwifiex_private *priv;
0158 struct mwifiex_txinfo *tx_info;
0159
0160 tx_info = MWIFIEX_SKB_TXCB(skb);
0161 priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
0162 tx_info->bss_type);
0163 if (!priv) {
0164 mwifiex_dbg(adapter, ERROR,
0165 "data: priv not found. Drop TX packet\n");
0166 adapter->dbg.num_tx_host_to_card_failure++;
0167 mwifiex_write_data_complete(adapter, skb, 0, 0);
0168 return ret;
0169 }
0170 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
0171 local_tx_pd = (struct txpd *)(head_ptr + adapter->intf_hdr_len);
0172
0173 if (adapter->iface_type == MWIFIEX_USB) {
0174 ret = adapter->if_ops.host_to_card(adapter,
0175 priv->usb_port,
0176 skb, tx_param);
0177 } else {
0178 ret = adapter->if_ops.host_to_card(adapter,
0179 MWIFIEX_TYPE_DATA,
0180 skb, tx_param);
0181 }
0182 switch (ret) {
0183 case -ENOSR:
0184 mwifiex_dbg(adapter, ERROR, "data: -ENOSR is returned\n");
0185 break;
0186 case -EBUSY:
0187 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
0188 (adapter->pps_uapsd_mode) &&
0189 (adapter->tx_lock_flag)) {
0190 priv->adapter->tx_lock_flag = false;
0191 if (local_tx_pd)
0192 local_tx_pd->flags = 0;
0193 }
0194 skb_queue_head(&adapter->tx_data_q, skb);
0195 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
0196 atomic_add(tx_info->aggr_num, &adapter->tx_queued);
0197 else
0198 atomic_inc(&adapter->tx_queued);
0199 mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n");
0200 break;
0201 case -1:
0202 mwifiex_dbg(adapter, ERROR,
0203 "mwifiex_write_data_async failed: 0x%X\n", ret);
0204 adapter->dbg.num_tx_host_to_card_failure++;
0205 mwifiex_write_data_complete(adapter, skb, 0, ret);
0206 break;
0207 case -EINPROGRESS:
0208 break;
0209 case 0:
0210 mwifiex_write_data_complete(adapter, skb, 0, ret);
0211 break;
0212 default:
0213 break;
0214 }
0215 return ret;
0216 }
0217
0218 static int
0219 mwifiex_dequeue_tx_queue(struct mwifiex_adapter *adapter)
0220 {
0221 struct sk_buff *skb, *skb_next;
0222 struct mwifiex_txinfo *tx_info;
0223 struct mwifiex_tx_param tx_param;
0224
0225 skb = skb_dequeue(&adapter->tx_data_q);
0226 if (!skb)
0227 return -1;
0228
0229 tx_info = MWIFIEX_SKB_TXCB(skb);
0230 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
0231 atomic_sub(tx_info->aggr_num, &adapter->tx_queued);
0232 else
0233 atomic_dec(&adapter->tx_queued);
0234
0235 if (!skb_queue_empty(&adapter->tx_data_q))
0236 skb_next = skb_peek(&adapter->tx_data_q);
0237 else
0238 skb_next = NULL;
0239 tx_param.next_pkt_len = ((skb_next) ? skb_next->len : 0);
0240 if (!tx_param.next_pkt_len) {
0241 if (!mwifiex_wmm_lists_empty(adapter))
0242 tx_param.next_pkt_len = 1;
0243 }
0244 return mwifiex_host_to_card(adapter, skb, &tx_param);
0245 }
0246
0247 void
0248 mwifiex_process_tx_queue(struct mwifiex_adapter *adapter)
0249 {
0250 do {
0251 if (adapter->data_sent || adapter->tx_lock_flag)
0252 break;
0253 if (mwifiex_dequeue_tx_queue(adapter))
0254 break;
0255 } while (!skb_queue_empty(&adapter->tx_data_q));
0256 }
0257
0258
0259
0260
0261
0262
0263
0264
0265 int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
0266 struct sk_buff *skb, int aggr, int status)
0267 {
0268 struct mwifiex_private *priv;
0269 struct mwifiex_txinfo *tx_info;
0270 struct netdev_queue *txq;
0271 int index;
0272
0273 if (!skb)
0274 return 0;
0275
0276 tx_info = MWIFIEX_SKB_TXCB(skb);
0277 priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
0278 tx_info->bss_type);
0279 if (!priv)
0280 goto done;
0281
0282 mwifiex_set_trans_start(priv->netdev);
0283
0284 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT)
0285 atomic_dec_return(&adapter->pending_bridged_pkts);
0286
0287 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
0288 goto done;
0289
0290 if (!status) {
0291 priv->stats.tx_packets++;
0292 priv->stats.tx_bytes += tx_info->pkt_len;
0293 if (priv->tx_timeout_cnt)
0294 priv->tx_timeout_cnt = 0;
0295 } else {
0296 priv->stats.tx_errors++;
0297 }
0298
0299 if (aggr)
0300
0301 goto done;
0302
0303 atomic_dec(&adapter->tx_pending);
0304
0305 index = mwifiex_1d_to_wmm_queue[skb->priority];
0306 if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) {
0307 txq = netdev_get_tx_queue(priv->netdev, index);
0308 if (netif_tx_queue_stopped(txq)) {
0309 netif_tx_wake_queue(txq);
0310 mwifiex_dbg(adapter, DATA, "wake queue: %d\n", index);
0311 }
0312 }
0313 done:
0314 dev_kfree_skb_any(skb);
0315
0316 return 0;
0317 }
0318 EXPORT_SYMBOL_GPL(mwifiex_write_data_complete);
0319
0320 void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
0321 void *event_body)
0322 {
0323 struct tx_status_event *tx_status = (void *)priv->adapter->event_body;
0324 struct sk_buff *ack_skb;
0325 struct mwifiex_txinfo *tx_info;
0326
0327 if (!tx_status->tx_token_id)
0328 return;
0329
0330 spin_lock_bh(&priv->ack_status_lock);
0331 ack_skb = idr_remove(&priv->ack_status_frames, tx_status->tx_token_id);
0332 spin_unlock_bh(&priv->ack_status_lock);
0333
0334 if (ack_skb) {
0335 tx_info = MWIFIEX_SKB_TXCB(ack_skb);
0336
0337 if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
0338
0339 skb_complete_wifi_ack(ack_skb, !tx_status->status);
0340 } else {
0341
0342 memmove(ack_skb->data +
0343 sizeof(struct ieee80211_hdr_3addr) +
0344 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(u16),
0345 ack_skb->data +
0346 sizeof(struct ieee80211_hdr_3addr) +
0347 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(u16) +
0348 ETH_ALEN, ack_skb->len -
0349 (sizeof(struct ieee80211_hdr_3addr) +
0350 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(u16) +
0351 ETH_ALEN));
0352 ack_skb->len = ack_skb->len - ETH_ALEN;
0353
0354
0355
0356
0357 cfg80211_mgmt_tx_status(&priv->wdev, tx_info->cookie,
0358 ack_skb->data +
0359 MWIFIEX_MGMT_FRAME_HEADER_SIZE +
0360 sizeof(u16), ack_skb->len -
0361 (MWIFIEX_MGMT_FRAME_HEADER_SIZE
0362 + sizeof(u16)),
0363 !tx_status->status, GFP_ATOMIC);
0364 dev_kfree_skb_any(ack_skb);
0365 }
0366 }
0367 }