Commit 821f9414 authored by Sujith Manoharan's avatar Sujith Manoharan Committed by John W. Linville

ath9k_htc: Use helper routines for transmission

Signed-off-by: default avatarSujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 2f80194c
...@@ -211,61 +211,70 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, ...@@ -211,61 +211,70 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
return error; return error;
} }
int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv,
struct ath9k_htc_vif *avp,
struct sk_buff *skb, struct sk_buff *skb,
u8 slot, bool is_cab) u8 sta_idx, u8 vif_idx, u8 slot)
{ {
struct ieee80211_hdr *hdr;
struct ieee80211_mgmt *mgmt;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_mgmt *mgmt;
struct ieee80211_vif *vif = tx_info->control.vif; struct ieee80211_hdr *hdr;
struct ath9k_htc_sta *ista; struct tx_mgmt_hdr mgmt_hdr;
struct ath9k_htc_vif *avp = NULL;
struct ath9k_htc_tx_ctl *tx_ctl; struct ath9k_htc_tx_ctl *tx_ctl;
u16 qnum;
__le16 fc;
u8 *tx_fhdr; u8 *tx_fhdr;
u8 sta_idx, vif_idx;
tx_ctl = HTC_SKB_CB(skb); tx_ctl = HTC_SKB_CB(skb);
memset(tx_ctl, 0, sizeof(*tx_ctl));
hdr = (struct ieee80211_hdr *) skb->data; hdr = (struct ieee80211_hdr *) skb->data;
fc = hdr->frame_control;
memset(tx_ctl, 0, sizeof(*tx_ctl));
memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
/* /*
* Find out on which interface this packet has to be * Set the TSF adjust value for probe response
* sent out. * frame also.
*/ */
if (vif) { if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
avp = (struct ath9k_htc_vif *) vif->drv_priv; mgmt = (struct ieee80211_mgmt *)skb->data;
vif_idx = avp->index; mgmt->u.probe_resp.timestamp = avp->tsfadjust;
} else {
if (!priv->ah->is_monitoring) {
ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
"VIF is null, but no monitor interface !\n");
return -EINVAL;
} }
vif_idx = priv->mon_vif_idx; tx_ctl->type = ATH9K_HTC_MGMT;
}
/* mgmt_hdr.node_idx = sta_idx;
* Find out which station this packet is destined for. mgmt_hdr.vif_idx = vif_idx;
*/ mgmt_hdr.tidno = 0;
if (sta) { mgmt_hdr.flags = 0;
ista = (struct ath9k_htc_sta *) sta->drv_priv; mgmt_hdr.cookie = slot;
sta_idx = ista->index;
} else { mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
sta_idx = priv->vif_sta_pos[vif_idx]; if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
} mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
else
mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
tx_ctl->epid = priv->mgmt_ep;
}
if (ieee80211_is_data(fc)) { static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif,
struct sk_buff *skb,
u8 sta_idx, u8 vif_idx, u8 slot,
bool is_cab)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr;
struct ath9k_htc_tx_ctl *tx_ctl;
struct tx_frame_hdr tx_hdr; struct tx_frame_hdr tx_hdr;
u32 flags = 0; u32 flags = 0;
u8 *qc; u8 *qc, *tx_fhdr;
u16 qnum;
tx_ctl = HTC_SKB_CB(skb);
hdr = (struct ieee80211_hdr *) skb->data;
memset(tx_ctl, 0, sizeof(*tx_ctl));
memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
tx_hdr.node_idx = sta_idx; tx_hdr.node_idx = sta_idx;
...@@ -288,7 +297,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, ...@@ -288,7 +297,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
tx_hdr.data_type = ATH9K_HTC_NORMAL; tx_hdr.data_type = ATH9K_HTC_NORMAL;
} }
if (ieee80211_is_data_qos(fc)) { if (ieee80211_is_data_qos(hdr->frame_control)) {
qc = ieee80211_get_qos_ctl(hdr); qc = ieee80211_get_qos_ctl(hdr);
tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
} }
...@@ -316,44 +325,62 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, ...@@ -316,44 +325,62 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
if (is_cab) { if (is_cab) {
CAB_STAT_INC; CAB_STAT_INC;
tx_ctl->epid = priv->cab_ep; tx_ctl->epid = priv->cab_ep;
goto send; return;
} }
qnum = skb_get_queue_mapping(skb); qnum = skb_get_queue_mapping(skb);
tx_ctl->epid = get_htc_epid(priv, qnum); tx_ctl->epid = get_htc_epid(priv, qnum);
} else { }
struct tx_mgmt_hdr mgmt_hdr;
memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
struct sk_buff *skb,
u8 slot, bool is_cab)
{
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_sta *sta = tx_info->control.sta;
struct ieee80211_vif *vif = tx_info->control.vif;
struct ath9k_htc_sta *ista;
struct ath9k_htc_vif *avp = NULL;
u8 sta_idx, vif_idx;
hdr = (struct ieee80211_hdr *) skb->data;
/* /*
* Set the TSF adjust value for probe response * Find out on which interface this packet has to be
* frame also. * sent out.
*/ */
if (avp && unlikely(ieee80211_is_probe_resp(fc))) { if (vif) {
mgmt = (struct ieee80211_mgmt *)skb->data; avp = (struct ath9k_htc_vif *) vif->drv_priv;
mgmt->u.probe_resp.timestamp = avp->tsfadjust; vif_idx = avp->index;
} else {
if (!priv->ah->is_monitoring) {
ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
"VIF is null, but no monitor interface !\n");
return -EINVAL;
} }
tx_ctl->type = ATH9K_HTC_MGMT; vif_idx = priv->mon_vif_idx;
}
mgmt_hdr.node_idx = sta_idx; /*
mgmt_hdr.vif_idx = vif_idx; * Find out which station this packet is destined for.
mgmt_hdr.tidno = 0; */
mgmt_hdr.flags = 0; if (sta) {
mgmt_hdr.cookie = slot; ista = (struct ath9k_htc_sta *) sta->drv_priv;
sta_idx = ista->index;
} else {
sta_idx = priv->vif_sta_pos[vif_idx];
}
mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); if (ieee80211_is_data(hdr->frame_control))
if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) ath9k_htc_tx_data(priv, vif, skb,
mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; sta_idx, vif_idx, slot, is_cab);
else else
mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; ath9k_htc_tx_mgmt(priv, avp, skb,
sta_idx, vif_idx, slot);
tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
tx_ctl->epid = priv->mgmt_ep;
}
send:
return htc_send(priv->htc, skb); return htc_send(priv->htc, skb);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment