/* * This function processes the received buffer. * * Main responsibility of this function is to parse the RxPD to * identify the correct interface this packet is headed for and * forwarding it to the associated handling function, where the * packet will be further processed and sent to kernel/upper layer * if required.
*/ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
{ struct mwifiex_private *priv; struct rxpd *local_rx_pd; struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); int ret;
local_rx_pd = (struct rxpd *) (skb->data); /* Get the BSS number from rxpd, get corresponding priv */
priv = mwifiex_get_priv_by_id(adapter, local_rx_pd->bss_num &
BSS_NUM_MASK, local_rx_pd->bss_type); if (!priv)
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
if (!priv) {
mwifiex_dbg(adapter, ERROR, "data: priv not found. Drop RX packet\n");
dev_kfree_skb_any(skb); return -1;
}
/* * This function sends a packet to device. * * It processes the packet to add the TxPD, checks condition and * sends the processed packet to firmware for transmission. * * On successful completion, the function calls the completion callback * and logs the time.
*/ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, struct mwifiex_tx_param *tx_param)
{ int hroom, ret; struct mwifiex_adapter *adapter = priv->adapter; struct txpd *local_tx_pd = NULL; struct mwifiex_sta_node *dest_node; struct ethhdr *hdr = (void *)skb->data;
if (unlikely(!skb->len ||
skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN)) {
ret = -EINVAL; goto out;
}
hroom = adapter->intf_hdr_len;
if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) {
dest_node = mwifiex_get_sta_entry(priv, hdr->h_dest); if (dest_node) {
dest_node->stats.tx_bytes += skb->len;
dest_node->stats.tx_packets++;
}
if (!skb_queue_empty(&adapter->tx_data_q))
skb_next = skb_peek(&adapter->tx_data_q); else
skb_next = NULL;
tx_param.next_pkt_len = ((skb_next) ? skb_next->len : 0); if (!tx_param.next_pkt_len) { if (!mwifiex_wmm_lists_empty(adapter))
tx_param.next_pkt_len = 1;
} return mwifiex_host_to_card(adapter, skb, &tx_param);
}
void
mwifiex_process_tx_queue(struct mwifiex_adapter *adapter)
{ do { if (adapter->data_sent || adapter->tx_lock_flag) break; if (mwifiex_dequeue_tx_queue(adapter)) break;
} while (!skb_queue_empty(&adapter->tx_data_q));
}
/* * 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 aggr, int status)
{ struct mwifiex_private *priv; struct mwifiex_txinfo *tx_info; struct netdev_queue *txq; int index;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.