void pcie_tx_xmit_ndp(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) { struct mwl_priv *priv = hw->priv; struct pcie_priv *pcie_priv = priv->hif.priv; struct ieee80211_tx_info *tx_info; struct ieee80211_key_conf *k_conf; struct mwl_vif *mwl_vif; int index; struct ieee80211_sta *sta; struct mwl_sta *sta_info; struct ieee80211_hdr *wh; u8 *da; u16 qos; u8 tid = 0; struct mwl_ampdu_stream *stream = NULL; u16 tx_que_priority; bool mgmtframe = false; struct ieee80211_mgmt *mgmt; bool eapol_frame = false; bool start_ba_session = false; struct pcie_tx_ctrl_ndp *tx_ctrl; tx_info = IEEE80211_SKB_CB(skb); k_conf = tx_info->control.hw_key; mwl_vif = mwl_dev_get_vif(tx_info->control.vif); index = skb_get_queue_mapping(skb); sta = control->sta; sta_info = sta ? mwl_dev_get_sta(sta) : NULL; wh = (struct ieee80211_hdr *)skb->data; if (ieee80211_is_data_qos(wh->frame_control)) qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh))); else qos = 0xFFFF; if (skb->protocol == cpu_to_be16(ETH_P_PAE)) { index = IEEE80211_AC_VO; eapol_frame = true; } if (ieee80211_is_mgmt(wh->frame_control)) { mgmtframe = true; mgmt = (struct ieee80211_mgmt *)skb->data; } if (mgmtframe) { u16 capab; if (unlikely(ieee80211_is_action(wh->frame_control) && mgmt->u.action.category == WLAN_CATEGORY_BACK && mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ)) { capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; index = utils_tid_to_ac(tid); } if (unlikely(ieee80211_is_assoc_req(wh->frame_control))) utils_add_basic_rates(hw->conf.chandef.chan->band, skb); if (ieee80211_is_probe_req(wh->frame_control) || ieee80211_is_probe_resp(wh->frame_control)) tx_que_priority = PROBE_RESPONSE_TXQNUM; else { if (( (mwl_vif->macid == SYSADPT_NUM_OF_AP) && (!ieee80211_has_protected(wh->frame_control) || (ieee80211_has_protected(wh->frame_control) && ieee80211_is_auth(wh->frame_control))) ) || !sta || ieee80211_is_auth(wh->frame_control) || ieee80211_is_assoc_req(wh->frame_control) || ieee80211_is_assoc_resp(wh->frame_control)) tx_que_priority = MGMT_TXQNUM; else { if (is_multicast_ether_addr(wh->addr1) && (mwl_vif->macid != SYSADPT_NUM_OF_AP)) tx_que_priority = mwl_vif->macid * SYSADPT_MAX_TID; else tx_que_priority = SYSADPT_MAX_TID * (sta_info->stnid + QUEUE_STAOFFSET) + 6; } } if (ieee80211_is_assoc_resp(wh->frame_control) || ieee80211_is_reassoc_resp(wh->frame_control)) { struct sk_buff *ack_skb; struct ieee80211_tx_info *ack_info; ack_skb = skb_copy(skb, GFP_ATOMIC); ack_info = IEEE80211_SKB_CB(ack_skb); pcie_tx_prepare_info(priv, 0, ack_info); ieee80211_tx_status(hw, ack_skb); } pcie_tx_encapsulate_frame(priv, skb, k_conf, NULL); } else {
/** * iwl_dbg_report_frame - dump frame to syslog during debug sessions * * You may hack this function to show different aspects of received frames, * including selective frame dumps. * group100 parameter selects whether to show 1 out of 100 good data frames. * All beacon and probe response frames are printed. */ static void iwl_dbg_report_frame(struct iwl_priv *priv, struct iwl_rx_phy_res *phy_res, u16 length, struct ieee80211_hdr *header, int group100) { u32 to_us; u32 print_summary = 0; u32 print_dump = 0; /* set to 1 to dump all frames' contents */ u32 hundred = 0; u32 dataframe = 0; __le16 fc; u16 seq_ctl; u16 channel; u16 phy_flags; u32 rate_n_flags; u32 tsf_low; int rssi; if (likely(!(iwl_get_debug_level(priv) & IWL_DL_RX))) return; /* MAC header */ fc = header->frame_control; seq_ctl = le16_to_cpu(header->seq_ctrl); /* metadata */ channel = le16_to_cpu(phy_res->channel); phy_flags = le16_to_cpu(phy_res->phy_flags); rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); /* signal statistics */ rssi = iwl_calc_rssi(priv, phy_res); tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff; to_us = !compare_ether_addr(header->addr1, priv->mac_addr); /* if data frame is to us and all is good, * (optionally) print summary for only 1 out of every 100 */ if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) == cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { dataframe = 1; if (!group100) print_summary = 1; /* print each frame */ else if (priv->framecnt_to_us < 100) { priv->framecnt_to_us++; print_summary = 0; } else { priv->framecnt_to_us = 0; print_summary = 1; hundred = 1; } } else { /* print summary for all other frames */ print_summary = 1; } if (print_summary) { char *title; int rate_idx; u32 bitrate; if (hundred) title = "100Frames"; else if (ieee80211_has_retry(fc)) title = "Retry"; else if (ieee80211_is_assoc_resp(fc)) title = "AscRsp"; else if (ieee80211_is_reassoc_resp(fc)) title = "RasRsp"; else if (ieee80211_is_probe_resp(fc)) { title = "PrbRsp"; print_dump = 1; /* dump frame contents */ } else if (ieee80211_is_beacon(fc)) { title = "Beacon"; print_dump = 1; /* dump frame contents */ } else if (ieee80211_is_atim(fc)) title = "ATIM"; else if (ieee80211_is_auth(fc)) title = "Auth"; else if (ieee80211_is_deauth(fc)) title = "DeAuth"; else if (ieee80211_is_disassoc(fc)) title = "DisAssoc"; else title = "Frame"; rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) { bitrate = 0; WARN_ON_ONCE(1); } else { bitrate = iwl_rates[rate_idx].ieee / 2; } /* print frame summary. * MAC addresses show just the last byte (for brevity), * but you can hack it to show more, if you'd like to. */ if (dataframe) IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, " "len=%u, rssi=%d, chnl=%d, rate=%u, \n", title, le16_to_cpu(fc), header->addr1[5], length, rssi, channel, bitrate); else { /* src/dst addresses assume managed mode */ IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, " "len=%u, rssi=%d, tim=%lu usec, " "phy=0x%02x, chnl=%d\n", title, le16_to_cpu(fc), header->addr1[5], header->addr3[5], length, rssi, tsf_low - priv->scan_start_tsf, phy_flags, channel); } } if (print_dump) iwl_print_hex_dump(priv, IWL_DL_RX, header, length); }
void pcie_tx_done_ndp(struct ieee80211_hw *hw) { struct mwl_priv *priv = hw->priv; struct pcie_priv *pcie_priv = priv->hif.priv; struct pcie_desc_data_ndp *desc = &pcie_priv->desc_data_ndp; u32 tx_done_head, tx_done_tail; struct tx_ring_done *ptx_ring_done; u32 index; struct sk_buff *skb; struct ieee80211_tx_info *tx_info; struct pcie_tx_ctrl_ndp *tx_ctrl; struct pcie_dma_data *dma_data; u16 hdrlen; spin_lock_bh(&pcie_priv->tx_desc_lock); tx_done_head = readl(pcie_priv->iobase1 + MACREG_REG_TXDONEHEAD); tx_done_tail = desc->tx_done_tail & (MAX_TX_RING_DONE_SIZE - 1); tx_done_head &= (MAX_TX_RING_DONE_SIZE - 1); while (tx_done_head != tx_done_tail) { ptx_ring_done = &desc->ptx_ring_done[tx_done_tail]; index = le32_to_cpu(ptx_ring_done->user); ptx_ring_done->user = 0; if (index >= MAX_TX_RING_SEND_SIZE) { wiphy_err(hw->wiphy, "corruption for index of buffer\n"); break; } skb = desc->tx_vbuflist[index]; if (!skb) { wiphy_err(hw->wiphy, "buffer is NULL for tx done ring\n"); break; } pci_unmap_single(pcie_priv->pdev, desc->pphys_tx_buflist[index], skb->len, PCI_DMA_TODEVICE); desc->pphys_tx_buflist[index] = 0; desc->tx_vbuflist[index] = NULL; tx_info = IEEE80211_SKB_CB(skb); tx_ctrl = (struct pcie_tx_ctrl_ndp *) tx_info->status.status_driver_data; if (tx_ctrl->flags & TX_CTRL_TYPE_DATA) { dev_kfree_skb_any(skb); goto bypass_ack; } else { /* Remove H/W dma header */ dma_data = (struct pcie_dma_data *)skb->data; if (ieee80211_is_assoc_resp( dma_data->wh.frame_control) || ieee80211_is_reassoc_resp( dma_data->wh.frame_control)) { dev_kfree_skb_any(skb); goto bypass_ack; } hdrlen = ieee80211_hdrlen( dma_data->wh.frame_control); memmove(dma_data->data - hdrlen, &dma_data->wh, hdrlen); skb_pull(skb, sizeof(*dma_data) - hdrlen); } pcie_tx_prepare_info(priv, 0, tx_info); ieee80211_tx_status(hw, skb); bypass_ack: if (++tx_done_tail >= MAX_TX_RING_DONE_SIZE) tx_done_tail = 0; desc->tx_desc_busy_cnt--; } writel(tx_done_tail, pcie_priv->iobase1 + MACREG_REG_TXDONETAIL); desc->tx_done_tail = tx_done_tail; spin_unlock_bh(&pcie_priv->tx_desc_lock); }