static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_tx_control txctl; memset(&txctl, 0, sizeof(struct ath_tx_control)); txctl.txq = sc->beacon.cabq; ath_dbg(common, XMIT, "transmitting CABQ packet, skb: %p\n", skb); if (ath_tx_start(hw, skb, &txctl) != 0) { ath_dbg(common, XMIT, "CABQ TX failed\n"); dev_kfree_skb_any(skb); } }
static int ath9k_send_nullfunc(struct ath_wiphy *aphy, struct ieee80211_vif *vif, const u8 *bssid, int ps) { struct ath_softc *sc = aphy->sc; struct ath_tx_control txctl; struct sk_buff *skb; struct ieee80211_hdr *hdr; __le16 fc; struct ieee80211_tx_info *info; skb = dev_alloc_skb(24); if (skb == NULL) return -ENOMEM; hdr = (struct ieee80211_hdr *) skb_put(skb, 24); memset(hdr, 0, 24); fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS); if (ps) fc |= cpu_to_le16(IEEE80211_FCTL_PM); hdr->frame_control = fc; memcpy(hdr->addr1, bssid, ETH_ALEN); memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN); memcpy(hdr->addr3, bssid, ETH_ALEN); info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS; info->control.vif = vif; info->control.rates[0].idx = 0; info->control.rates[0].count = 4; info->control.rates[1].idx = -1; memset(&txctl, 0, sizeof(struct ath_tx_control)); txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE; if (ath_tx_start(aphy->hw, skb, &txctl) != 0) goto exit; return 0; exit: dev_kfree_skb_any(skb); return -1; }
static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) { struct ieee80211_hw *hw = sc->hw; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath_tx_control txctl; int time_left; memset(&txctl, 0, sizeof(txctl)); txctl.txq = sc->tx.txq_map[WME_AC_BE]; memset(tx_info, 0, sizeof(*tx_info)); tx_info->band = hw->conf.channel->band; tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; tx_info->control.rates[0].idx = 0; tx_info->control.rates[0].count = 1; tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; tx_info->control.rates[1].idx = -1; init_completion(&sc->paprd_complete); txctl.paprd = BIT(chain); if (ath_tx_start(hw, skb, &txctl) != 0) { ath_dbg(common, ATH_DBG_CALIBRATE, "PAPRD TX failed\n"); dev_kfree_skb_any(skb); return false; } time_left = wait_for_completion_timeout(&sc->paprd_complete, msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); if (!time_left) ath_dbg(common, ATH_DBG_CALIBRATE, "Timeout waiting for paprd training on TX chain %d\n", chain); return !!time_left; }