/* * This function processes the received packet before sending it to the * kernel. * * It extracts the SKB from the received buffer and sends it to kernel. * In case the received buffer does not contain the data in SKB format, * the function creates a blank SKB, fills it with the data from the * received buffer and then sends this new SKB to the kernel. */ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) { struct mwifiex_rxinfo *rx_info; struct mwifiex_private *priv; if (!skb) return -1; rx_info = MWIFIEX_SKB_RXCB(skb); priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index); if (!priv) return -1; skb->dev = priv->netdev; skb->protocol = eth_type_trans(skb, priv->netdev); skb->ip_summed = CHECKSUM_NONE; priv->stats.rx_bytes += skb->len; priv->stats.rx_packets++; if (in_interrupt()) netif_rx(skb); else netif_rx_ni(skb); return 0; }
/* * Packet send completion callback handler. * * It either frees the buffer directly or forwards it to another * completion callback which checks conditions, updates statistics, * wakes up stalled traffic queue if required, and then frees the buffer. */ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, struct sk_buff *skb, int status) { struct mwifiex_private *priv, *tpriv; struct mwifiex_txinfo *tx_info; int i; if (!skb) return 0; tx_info = MWIFIEX_SKB_TXCB(skb); priv = mwifiex_bss_index_to_priv(adapter, tx_info->bss_index); if (!priv) goto done; priv->netdev->trans_start = jiffies; if (!status) { priv->stats.tx_packets++; priv->stats.tx_bytes += skb->len; } else { priv->stats.tx_errors++; } if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING) goto done; for (i = 0; i < adapter->priv_num; i++) { tpriv = adapter->priv[i]; if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) && (tpriv->media_connected)) { if (netif_queue_stopped(tpriv->netdev)) netif_wake_queue(tpriv->netdev); } } done: dev_kfree_skb_any(skb); return 0; }