2015-11-02 14:04:02

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 0/8] ath10k: clean up ath10k_skb_cb

The ath10k_skb_cb structure wasn't really space
efficient. Some stuff is removed or replaced with
more compact representation.

This cleanup is necessary for future features.

The size of ath10k_skb_cb:

before after
x86-32 26 12
x86-64 34 20


Michal Kazior (8):
ath10k: merge is_protected with nohwcrypt
ath10k: rename function to adhere to naming convention
ath10k: remove txmode from skb_cb
ath10k: remove is_offchan
ath10k: remove freq from skb_cb
ath10k: pack up flags in skb_cb
ath10k: replace vdev_id and tid in skb cb
ath10k: store msdu_id instead of txbuf pointers

drivers/net/wireless/ath/ath10k/core.h | 27 +++----
drivers/net/wireless/ath/ath10k/htt.h | 3 +-
drivers/net/wireless/ath/ath10k/htt_tx.c | 111 ++++++++++++++++++-----------
drivers/net/wireless/ath/ath10k/mac.c | 116 +++++++++++++++----------------
drivers/net/wireless/ath/ath10k/mac.h | 1 +
drivers/net/wireless/ath/ath10k/txrx.c | 7 +-
drivers/net/wireless/ath/ath10k/wmi.c | 22 ++++--
7 files changed, 165 insertions(+), 122 deletions(-)

--
2.1.4



2015-11-18 05:59:36

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v3 5/9] ath10k: remove freq from skb_cb

It was wasteful to keep it in the struct.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/htt_tx.c | 9 +++++++--
drivers/net/wireless/ath/ath10k/mac.c | 5 +----
3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 89a83e3c5cb6..804fd2e5bc38 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -88,7 +88,6 @@ struct ath10k_skb_cb {

struct {
u8 tid;
- u16 freq;
bool nohwcrypt;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index f6fb4f131542..a7d8798b2f37 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -538,6 +538,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
struct ath10k *ar = htt->ar;
struct device *dev = ar->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
struct htt_data_tx_desc_frag *frags;
@@ -547,6 +548,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
int res;
u8 flags0 = 0;
u16 msdu_id, flags1 = 0;
+ u16 freq = 0;
u32 frags_paddr = 0;
struct htt_msdu_ext_desc *ext_desc = NULL;
bool limit_mgmt_desc = false;
@@ -598,6 +600,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
goto err_free_msdu_id;
}

+ if (unlikely(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN))
+ freq = ar->scan.roc_freq;
+
switch (txmode) {
case ATH10K_HW_TXRX_RAW:
case ATH10K_HW_TXRX_NATIVE_WIFI:
@@ -690,7 +695,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
skb_cb->htt.txbuf->cmd_tx.offchan_tx.peerid =
__cpu_to_le16(HTT_INVALID_PEERID);
skb_cb->htt.txbuf->cmd_tx.offchan_tx.freq =
- __cpu_to_le16(skb_cb->htt.freq);
+ __cpu_to_le16(freq);
} else {
skb_cb->htt.txbuf->cmd_tx.peerid =
__cpu_to_le32(HTT_INVALID_PEERID);
@@ -700,7 +705,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
ath10k_dbg(ar, ATH10K_DBG_HTT,
"htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu freq %hu\n",
flags0, flags1, msdu->len, msdu_id, frags_paddr,
- (u32)skb_cb->paddr, vdev_id, tid, skb_cb->htt.freq);
+ (u32)skb_cb->paddr, vdev_id, tid, freq);
ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ",
msdu->data, msdu->len);
trace_ath10k_tx_hdr(ar, msdu->data, msdu->len);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 164a3e5ae6da..0ca5d5bea509 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3528,6 +3528,7 @@ void __ath10k_scan_finish(struct ath10k *ar)
case ATH10K_SCAN_STARTING:
ar->scan.state = ATH10K_SCAN_IDLE;
ar->scan_channel = NULL;
+ ar->scan.roc_freq = 0;
ath10k_offchan_tx_purge(ar);
cancel_delayed_work(&ar->scan.timeout);
complete_all(&ar->scan.completed);
@@ -3683,7 +3684,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,

txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);

- ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
@@ -3708,13 +3708,10 @@ static void ath10k_tx(struct ieee80211_hw *hw,

if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
spin_lock_bh(&ar->data_lock);
- ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
spin_unlock_bh(&ar->data_lock);

if (!ath10k_mac_tx_frm_has_freq(ar)) {
- ATH10K_SKB_CB(skb)->htt.freq = 0;
-
ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
skb);

--
2.1.4


2015-11-18 05:59:42

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v3 9/9] ath10k: store msdu_id instead of txbuf pointers

Txbuf is no longer a DMA pool and can be easily
tracked with a mere msdu_id. This saves 10 bytes
on 64bit systems and 6 bytes on 32bit systems of
precious sk_buff control buffer.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 6 +---
drivers/net/wireless/ath/ath10k/htt_tx.c | 55 ++++++++++++++++----------------
2 files changed, 28 insertions(+), 33 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 75dee79ec206..ec19260bf5d1 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -93,12 +93,8 @@ struct ath10k_skb_cb {
dma_addr_t paddr;
u8 flags;
u8 eid;
+ u16 msdu_id;
struct ieee80211_vif *vif;
-
- struct {
- struct ath10k_htt_txbuf *txbuf;
- u32 txbuf_paddr;
- } __packed htt;
} __packed;

struct ath10k_skb_rxcb {
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 23e047b0aca3..5274f5bb0b45 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -539,8 +539,6 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
memcpy(cmd->mgmt_tx.hdr, msdu->data,
min_t(int, msdu->len, HTT_MGMT_FRM_HDR_DOWNLOAD_LEN));

- skb_cb->htt.txbuf = NULL;
-
res = ath10k_htc_send(&htt->ar->htc, htt->eid, txdesc);
if (res)
goto err_unmap_msdu;
@@ -570,6 +568,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
+ struct ath10k_htt_txbuf *txbuf;
struct htt_data_tx_desc_frag *frags;
bool is_eth = (txmode == ATH10K_HW_TXRX_ETHERNET);
u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
@@ -580,6 +579,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
u16 msdu_id, flags1 = 0;
u16 freq = 0;
u32 frags_paddr = 0;
+ u32 txbuf_paddr;
struct htt_msdu_ext_desc *ext_desc = NULL;
bool limit_mgmt_desc = false;
bool is_probe_resp = false;
@@ -607,9 +607,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
prefetch_len = min(htt->prefetch_len, msdu->len);
prefetch_len = roundup(prefetch_len, 4);

- skb_cb->htt.txbuf = &htt->txbuf.vaddr[msdu_id];
- skb_cb->htt.txbuf_paddr = htt->txbuf.paddr +
- (sizeof(struct ath10k_htt_txbuf) * msdu_id);
+ txbuf = &htt->txbuf.vaddr[msdu_id];
+ txbuf_paddr = htt->txbuf.paddr +
+ (sizeof(struct ath10k_htt_txbuf) * msdu_id);

if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
@@ -653,14 +653,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
frags_paddr = htt->frag_desc.paddr +
(sizeof(struct htt_msdu_ext_desc) * msdu_id);
} else {
- frags = skb_cb->htt.txbuf->frags;
+ frags = txbuf->frags;
frags[0].dword_addr.paddr =
__cpu_to_le32(skb_cb->paddr);
frags[0].dword_addr.len = __cpu_to_le32(msdu->len);
frags[1].dword_addr.paddr = 0;
frags[1].dword_addr.len = 0;

- frags_paddr = skb_cb->htt.txbuf_paddr;
+ frags_paddr = txbuf_paddr;
}
flags0 |= SM(txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
break;
@@ -689,12 +689,11 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
* avoid extra memory allocations, compress data structures and thus
* improve performance. */

- skb_cb->htt.txbuf->htc_hdr.eid = htt->eid;
- skb_cb->htt.txbuf->htc_hdr.len = __cpu_to_le16(
- sizeof(skb_cb->htt.txbuf->cmd_hdr) +
- sizeof(skb_cb->htt.txbuf->cmd_tx) +
- prefetch_len);
- skb_cb->htt.txbuf->htc_hdr.flags = 0;
+ txbuf->htc_hdr.eid = htt->eid;
+ txbuf->htc_hdr.len = __cpu_to_le16(sizeof(txbuf->cmd_hdr) +
+ sizeof(txbuf->cmd_tx) +
+ prefetch_len);
+ txbuf->htc_hdr.flags = 0;

if (skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
@@ -715,19 +714,19 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
*/
flags1 |= HTT_DATA_TX_DESC_FLAGS1_POSTPONED;

- skb_cb->htt.txbuf->cmd_hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
- skb_cb->htt.txbuf->cmd_tx.flags0 = flags0;
- skb_cb->htt.txbuf->cmd_tx.flags1 = __cpu_to_le16(flags1);
- skb_cb->htt.txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
- skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
- skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
+ txbuf->cmd_hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
+ txbuf->cmd_tx.flags0 = flags0;
+ txbuf->cmd_tx.flags1 = __cpu_to_le16(flags1);
+ txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
+ txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
+ txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
if (ath10k_mac_tx_frm_has_freq(ar)) {
- skb_cb->htt.txbuf->cmd_tx.offchan_tx.peerid =
+ txbuf->cmd_tx.offchan_tx.peerid =
__cpu_to_le16(HTT_INVALID_PEERID);
- skb_cb->htt.txbuf->cmd_tx.offchan_tx.freq =
+ txbuf->cmd_tx.offchan_tx.freq =
__cpu_to_le16(freq);
} else {
- skb_cb->htt.txbuf->cmd_tx.peerid =
+ txbuf->cmd_tx.peerid =
__cpu_to_le32(HTT_INVALID_PEERID);
}

@@ -743,12 +742,12 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,

sg_items[0].transfer_id = 0;
sg_items[0].transfer_context = NULL;
- sg_items[0].vaddr = &skb_cb->htt.txbuf->htc_hdr;
- sg_items[0].paddr = skb_cb->htt.txbuf_paddr +
- sizeof(skb_cb->htt.txbuf->frags);
- sg_items[0].len = sizeof(skb_cb->htt.txbuf->htc_hdr) +
- sizeof(skb_cb->htt.txbuf->cmd_hdr) +
- sizeof(skb_cb->htt.txbuf->cmd_tx);
+ sg_items[0].vaddr = &txbuf->htc_hdr;
+ sg_items[0].paddr = txbuf_paddr +
+ sizeof(txbuf->frags);
+ sg_items[0].len = sizeof(txbuf->htc_hdr) +
+ sizeof(txbuf->cmd_hdr) +
+ sizeof(txbuf->cmd_tx);

sg_items[1].transfer_id = 0;
sg_items[1].transfer_context = NULL;
--
2.1.4


2015-11-10 13:13:06

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v2 3/9] ath10k: remove txmode from skb_cb

It was wasteful to keep it in the struct because
it can be passed as function argument down the tx
path.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/htt.h | 4 +++-
drivers/net/wireless/ath/ath10k/htt_tx.c | 9 +++----
drivers/net/wireless/ath/ath10k/mac.c | 40 ++++++++++++++++++++++++--------
4 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 48db7dd36164..2f48772418ec 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -85,7 +85,6 @@ struct ath10k_skb_cb {
dma_addr_t paddr;
u8 eid;
u8 vdev_id;
- enum ath10k_hw_txrx_mode txmode;

struct {
u8 tid;
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 74ccfb291fcc..f06370e66417 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1597,7 +1597,9 @@ void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt, bool limit_mgmt_desc);
int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb);
void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id);
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *);
-int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *);
+int ath10k_htt_tx(struct ath10k_htt *htt,
+ enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *msdu);
void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
struct sk_buff *skb);

diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 31c172848d10..e9ab0c9075c2 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -532,7 +532,8 @@ err:
return res;
}

-int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
+int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *msdu)
{
struct ath10k *ar = htt->ar;
struct device *dev = ar->dev;
@@ -584,7 +585,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (!skb_cb->htt.nohwcrypt &&
- skb_cb->txmode == ATH10K_HW_TXRX_RAW &&
+ txmode == ATH10K_HW_TXRX_RAW &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
}
@@ -597,7 +598,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
goto err_free_msdu_id;
}

- switch (skb_cb->txmode) {
+ switch (txmode) {
case ATH10K_HW_TXRX_RAW:
case ATH10K_HW_TXRX_NATIVE_WIFI:
flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
@@ -626,7 +627,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)

frags_paddr = skb_cb->htt.txbuf_paddr;
}
- flags0 |= SM(skb_cb->txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
+ flags0 |= SM(txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
break;
case ATH10K_HW_TXRX_MGMT:
flags0 |= SM(ATH10K_HW_TXRX_MGMT,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 374187e25f2d..dd4770ec7ecc 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3331,24 +3331,24 @@ unlock:
return ret;
}

-static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
+static void ath10k_mac_tx(struct ath10k *ar, enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *skb)
{
- struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
struct ath10k_htt *htt = &ar->htt;
int ret = 0;

- switch (cb->txmode) {
+ switch (txmode) {
case ATH10K_HW_TXRX_RAW:
case ATH10K_HW_TXRX_NATIVE_WIFI:
case ATH10K_HW_TXRX_ETHERNET:
- ret = ath10k_htt_tx(htt, skb);
+ ret = ath10k_htt_tx(htt, txmode, skb);
break;
case ATH10K_HW_TXRX_MGMT:
if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
ar->fw_features))
ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
else if (ar->htt.target_version_major >= 3)
- ret = ath10k_htt_tx(htt, skb);
+ ret = ath10k_htt_tx(htt, txmode, skb);
else
ret = ath10k_htt_mgmt_tx(htt, skb);
break;
@@ -3378,9 +3378,13 @@ void ath10k_offchan_tx_work(struct work_struct *work)
{
struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
struct ath10k_peer *peer;
+ struct ath10k_vif *arvif;
struct ieee80211_hdr *hdr;
+ struct ieee80211_vif *vif;
+ struct ieee80211_sta *sta;
struct sk_buff *skb;
const u8 *peer_addr;
+ enum ath10k_hw_txrx_mode txmode;
int vdev_id;
int ret;
unsigned long time_left;
@@ -3430,7 +3434,22 @@ void ath10k_offchan_tx_work(struct work_struct *work)
ar->offchan_tx_skb = skb;
spin_unlock_bh(&ar->data_lock);

- ath10k_mac_tx(ar, skb);
+ /* It's safe to access vif and sta - conf_mutex guarantees that
+ * sta_state() and remove_interface() are locked exclusively
+ * out wrt to this offchannel worker.
+ */
+ arvif = ath10k_get_arvif(ar, vdev_id);
+ if (arvif) {
+ vif = arvif->vif;
+ sta = ieee80211_find_sta(vif, peer_addr);
+ } else {
+ vif = NULL;
+ sta = NULL;
+ }
+
+ txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
+
+ ath10k_mac_tx(ar, txmode, skb);

time_left =
wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
@@ -3652,20 +3671,21 @@ static void ath10k_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ enum ath10k_hw_txrx_mode txmode;

/* We should disable CCK RATE due to P2P */
if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");

+ txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
+
ATH10K_SKB_CB(skb)->htt.is_offchan = false;
ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
- ATH10K_SKB_CB(skb)->txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta,
- skb);

- switch (ATH10K_SKB_CB(skb)->txmode) {
+ switch (txmode) {
case ATH10K_HW_TXRX_MGMT:
case ATH10K_HW_TXRX_NATIVE_WIFI:
ath10k_tx_h_nwifi(hw, skb);
@@ -3702,7 +3722,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
}
}

- ath10k_mac_tx(ar, skb);
+ ath10k_mac_tx(ar, txmode, skb);
}

/* Must not be called with conf_mutex held as workers can use that also. */
--
2.1.4


2015-11-18 05:59:31

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v3 0/9] ath10k: clean up ath10k_skb_cb

The ath10k_skb_cb structure wasn't really space
efficient. Some stuff is removed or replaced with
more compact representation.

This cleanup is necessary for future features.

The size of ath10k_skb_cb:

before after
x86-32 26 12
x86-64 34 20


v3:
* rebase

v2:
* fix a bug (patch 7/9 introduced)


Michal Kazior (9):
ath10k: merge is_protected with nohwcrypt
ath10k: rename function to adhere to naming convention
ath10k: remove txmode from skb_cb
ath10k: remove is_offchan
ath10k: remove freq from skb_cb
ath10k: pack up flags in skb_cb
ath10k: fix tx header parsing
ath10k: replace vdev_id and tid in skb cb
ath10k: store msdu_id instead of txbuf pointers

drivers/net/wireless/ath/ath10k/core.h | 28 +++-----
drivers/net/wireless/ath/ath10k/htt.h | 4 +-
drivers/net/wireless/ath/ath10k/htt_tx.c | 116 +++++++++++++++++++-----------
drivers/net/wireless/ath/ath10k/mac.c | 117 ++++++++++++++++---------------
drivers/net/wireless/ath/ath10k/txrx.c | 15 ++--
drivers/net/wireless/ath/ath10k/wmi.c | 22 ++++--
6 files changed, 173 insertions(+), 129 deletions(-)

--
2.1.4


2015-11-02 14:04:05

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 2/8] ath10k: rename function to adhere to naming convention

All functions should have ath10k_{filename}_
prefixes.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/mac.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 58230cd04174..14a705ca87b2 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3139,8 +3139,10 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
}

static enum ath10k_hw_txrx_mode
-ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, struct sk_buff *skb)
+ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb)
{
const struct ieee80211_hdr *hdr = (void *)skb->data;
__le16 fc = hdr->frame_control;
@@ -3653,7 +3655,8 @@ static void ath10k_tx(struct ieee80211_hw *hw,
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
- ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
+ ATH10K_SKB_CB(skb)->txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta,
+ skb);

switch (ATH10K_SKB_CB(skb)->txmode) {
case ATH10K_HW_TXRX_MGMT:
--
2.1.4


2015-11-23 15:21:42

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v3 0/9] ath10k: clean up ath10k_skb_cb

Michal Kazior <[email protected]> writes:

> The ath10k_skb_cb structure wasn't really space
> efficient. Some stuff is removed or replaced with
> more compact representation.
>
> This cleanup is necessary for future features.
>
> The size of ath10k_skb_cb:
>
> before after
> x86-32 26 12
> x86-64 34 20
>
>
> v3:
> * rebase
>
> v2:
> * fix a bug (patch 7/9 introduced)
>
>
> Michal Kazior (9):
> ath10k: merge is_protected with nohwcrypt
> ath10k: rename function to adhere to naming convention
> ath10k: remove txmode from skb_cb
> ath10k: remove is_offchan
> ath10k: remove freq from skb_cb
> ath10k: pack up flags in skb_cb
> ath10k: fix tx header parsing
> ath10k: replace vdev_id and tid in skb cb
> ath10k: store msdu_id instead of txbuf pointers

Applied, thanks.

--
Kalle Valo

2015-11-18 05:59:39

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v3 7/9] ath10k: fix tx header parsing

Frames are not guaranteed to be 802.11 frames in
ath10k_htt_tx() and the tx completion handler.
In some cases, like TDLS, they can be Ethernet.
Hence checking, e.g. frame_control could yield
bogus results and behavior.

Fortunately this wasn't a real problem so far
because there's no FW/HW combination to encounter
this problem.

However it is good to fix this in advance.

Fixes: 75d85fd9993c ("ath10k: introduce basic tdls functionality")
Fixes: eebc67fef3ee ("ath10k: fix pmf for wmi-tlv on qca6174")
Fixes: 7b7da0a02192 ("ath10k: drop probe responses when too many are queued")
Signed-off-by: Michal Kazior <[email protected]>
---

Notes:
v2:
* introduced

drivers/net/wireless/ath/ath10k/core.h | 1 +
drivers/net/wireless/ath/ath10k/mac.c | 3 +++
drivers/net/wireless/ath/ath10k/txrx.c | 8 ++------
3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 6b9b37329621..6bbd95477325 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -85,6 +85,7 @@ enum ath10k_skb_flags {
ATH10K_SKB_F_NO_HWCRYPT = BIT(0),
ATH10K_SKB_F_DTIM_ZERO = BIT(1),
ATH10K_SKB_F_DELIVER_CAB = BIT(2),
+ ATH10K_SKB_F_MGMT = BIT(3),
};

struct ath10k_skb_cb {
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 38c241596965..fd36200e5396 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3689,6 +3689,9 @@ static void ath10k_tx(struct ieee80211_hw *hw,
if (!ath10k_tx_h_use_hwcrypto(vif, skb))
skb_cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;

+ if (ieee80211_is_mgmt(hdr->frame_control))
+ skb_cb->flags |= ATH10K_SKB_F_MGMT;
+
skb_cb->htt.tid = ath10k_tx_h_get_tid(hdr);
skb_cb->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);

diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 9e14c04ac89f..fbfb608e48ab 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -57,8 +57,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
struct ieee80211_tx_info *info;
struct ath10k_skb_cb *skb_cb;
struct sk_buff *msdu;
- struct ieee80211_hdr *hdr;
- __le16 fc;
bool limit_mgmt_desc = false;

ath10k_dbg(ar, ATH10K_DBG_HTT,
@@ -81,10 +79,9 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
return;
}

- hdr = (struct ieee80211_hdr *)msdu->data;
- fc = hdr->frame_control;
+ skb_cb = ATH10K_SKB_CB(msdu);

- if (unlikely(ieee80211_is_mgmt(fc)) &&
+ if (unlikely(skb_cb->flags & ATH10K_SKB_F_MGMT) &&
ar->hw_params.max_probe_resp_desc_thres)
limit_mgmt_desc = true;

@@ -94,7 +91,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
wake_up(&htt->empty_tx_wq);
spin_unlock_bh(&htt->tx_lock);

- skb_cb = ATH10K_SKB_CB(msdu);
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);

ath10k_report_offchan_tx(htt->ar, msdu);
--
2.1.4


2015-11-03 09:37:46

by Michal Kazior

[permalink] [raw]
Subject: Re: [PATCH 7/8] ath10k: replace vdev_id and tid in skb cb

On 2 November 2015 at 15:03, Michal Kazior <[email protected]> wrote:
> This prepares the driver for future ieee80211_txq
> and wake_tx_queue() support.

I think I've found a regression and bisect blames this patch. Do not
apply this yet, please.


MichaƂ

2015-11-10 13:13:12

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v2 7/9] ath10k: fix tx header parsing

Frames are not guaranteed to be 802.11 frames in
ath10k_htt_tx() and the tx completion handler.
In some cases, like TDLS, they can be Ethernet.
Hence checking, e.g. frame_control could yield
bogus results and behavior.

Fortunately this wasn't a real problem so far
because there's no FW/HW combination to encounter
this problem.

However it is good to fix this in advance.

Fixes: 75d85fd9993c ("ath10k: introduce basic tdls functionality")
Fixes: eebc67fef3ee ("ath10k: fix pmf for wmi-tlv on qca6174")
Fixes: 7b7da0a02192 ("ath10k: drop probe responses when too many are queued")
Signed-off-by: Michal Kazior <[email protected]>
---

Notes:
v2:
* introduced

drivers/net/wireless/ath/ath10k/core.h | 1 +
drivers/net/wireless/ath/ath10k/mac.c | 3 +++
drivers/net/wireless/ath/ath10k/txrx.c | 8 ++------
3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 1e8b5adeac37..b9137b1f76d1 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -85,6 +85,7 @@ enum ath10k_skb_flags {
ATH10K_SKB_F_NO_HWCRYPT = BIT(0),
ATH10K_SKB_F_DTIM_ZERO = BIT(1),
ATH10K_SKB_F_DELIVER_CAB = BIT(2),
+ ATH10K_SKB_F_MGMT = BIT(3),
};

struct ath10k_skb_cb {
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 07b67c9132f6..2f99552acad4 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3685,6 +3685,9 @@ static void ath10k_tx(struct ieee80211_hw *hw,
if (!ath10k_tx_h_use_hwcrypto(vif, skb))
skb_cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;

+ if (ieee80211_is_mgmt(hdr->frame_control))
+ skb_cb->flags |= ATH10K_SKB_F_MGMT;
+
skb_cb->htt.tid = ath10k_tx_h_get_tid(hdr);
skb_cb->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);

diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 655947bef6cc..f3bbe41f3ff7 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -57,8 +57,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
struct ieee80211_tx_info *info;
struct ath10k_skb_cb *skb_cb;
struct sk_buff *msdu;
- struct ieee80211_hdr *hdr;
- __le16 fc;
bool limit_mgmt_desc = false;

ath10k_dbg(ar, ATH10K_DBG_HTT,
@@ -81,10 +79,9 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
return;
}

- hdr = (struct ieee80211_hdr *)msdu->data;
- fc = hdr->frame_control;
+ skb_cb = ATH10K_SKB_CB(msdu);

- if (unlikely(ieee80211_is_mgmt(fc)) &&
+ if (unlikely(skb_cb->flags & ATH10K_SKB_F_MGMT) &&
ar->hw_params.max_probe_resp_desc_thres)
limit_mgmt_desc = true;

@@ -94,7 +91,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
wake_up(&htt->empty_tx_wq);
spin_unlock_bh(&htt->tx_lock);

- skb_cb = ATH10K_SKB_CB(msdu);
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);

ath10k_report_offchan_tx(htt->ar, msdu);
--
2.1.4


2015-11-10 13:13:05

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v2 2/9] ath10k: rename function to adhere to naming convention

All functions should have ath10k_{filename}_
prefixes.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/mac.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 2eb647913a9f..374187e25f2d 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3146,8 +3146,10 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
}

static enum ath10k_hw_txrx_mode
-ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, struct sk_buff *skb)
+ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb)
{
const struct ieee80211_hdr *hdr = (void *)skb->data;
__le16 fc = hdr->frame_control;
@@ -3660,7 +3662,8 @@ static void ath10k_tx(struct ieee80211_hw *hw,
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
- ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
+ ATH10K_SKB_CB(skb)->txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta,
+ skb);

switch (ATH10K_SKB_CB(skb)->txmode) {
case ATH10K_HW_TXRX_MGMT:
--
2.1.4


2015-11-18 05:59:41

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v3 8/9] ath10k: replace vdev_id and tid in skb cb

This prepares the driver for future ieee80211_txq
and wake_tx_queue() support.

Signed-off-by: Michal Kazior <[email protected]>
---

Notes:
v2:
* fix parsing eth frame as 802.11

drivers/net/wireless/ath/ath10k/core.h | 4 ++--
drivers/net/wireless/ath/ath10k/htt_tx.c | 36 +++++++++++++++++++++++++---
drivers/net/wireless/ath/ath10k/mac.c | 40 +++++---------------------------
drivers/net/wireless/ath/ath10k/wmi.c | 10 +++++++-
4 files changed, 50 insertions(+), 40 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 6bbd95477325..75dee79ec206 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -86,16 +86,16 @@ enum ath10k_skb_flags {
ATH10K_SKB_F_DTIM_ZERO = BIT(1),
ATH10K_SKB_F_DELIVER_CAB = BIT(2),
ATH10K_SKB_F_MGMT = BIT(3),
+ ATH10K_SKB_F_QOS = BIT(4),
};

struct ath10k_skb_cb {
dma_addr_t paddr;
u8 flags;
u8 eid;
- u8 vdev_id;
+ struct ieee80211_vif *vif;

struct {
- u8 tid;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
} __packed htt;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index c955c6b6ea9d..23e047b0aca3 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -439,6 +439,35 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
return 0;
}

+static u8 ath10k_htt_tx_get_vdev_id(struct ath10k *ar, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
+ struct ath10k_vif *arvif = (void *)cb->vif->drv_priv;
+
+ if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
+ return ar->scan.vdev_id;
+ else if (cb->vif)
+ return arvif->vdev_id;
+ else if (ar->monitor_started)
+ return ar->monitor_vdev_id;
+ else
+ return 0;
+}
+
+static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth)
+{
+ struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
+
+ if (!is_eth && ieee80211_is_mgmt(hdr->frame_control))
+ return HTT_DATA_TX_EXT_TID_MGMT;
+ else if (cb->flags & ATH10K_SKB_F_QOS)
+ return skb->priority % IEEE80211_QOS_CTL_TID_MASK;
+ else
+ return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
+}
+
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
{
struct ath10k *ar = htt->ar;
@@ -446,7 +475,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
struct sk_buff *txdesc = NULL;
struct htt_cmd *cmd;
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
- u8 vdev_id = skb_cb->vdev_id;
+ u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
int len = 0;
int msdu_id = -1;
int res;
@@ -542,8 +571,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
struct htt_data_tx_desc_frag *frags;
- u8 vdev_id = skb_cb->vdev_id;
- u8 tid = skb_cb->htt.tid;
+ bool is_eth = (txmode == ATH10K_HW_TXRX_ETHERNET);
+ u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
+ u8 tid = ath10k_htt_tx_get_tid(msdu, is_eth);
int prefetch_len;
int res;
u8 flags0 = 0;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index fd36200e5396..cb95314b8058 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3122,32 +3122,6 @@ void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
spin_unlock_bh(&ar->htt.tx_lock);
}

-static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
-{
- if (ieee80211_is_mgmt(hdr->frame_control))
- return HTT_DATA_TX_EXT_TID_MGMT;
-
- if (!ieee80211_is_data_qos(hdr->frame_control))
- return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
-
- if (!is_unicast_ether_addr(ieee80211_get_DA(hdr)))
- return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
-
- return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
-}
-
-static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
-{
- if (vif)
- return ath10k_vif_to_arvif(vif)->vdev_id;
-
- if (ar->monitor_started)
- return ar->monitor_vdev_id;
-
- ath10k_warn(ar, "failed to resolve vdev id\n");
- return 0;
-}
-
static enum ath10k_hw_txrx_mode
ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
struct ieee80211_vif *vif,
@@ -3244,7 +3218,7 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
hdr = (void *)skb->data;
if (ieee80211_is_qos_nullfunc(hdr->frame_control))
- cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
+ cb->flags &= ~ATH10K_SKB_F_QOS;

hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
}
@@ -3413,9 +3387,9 @@ void ath10k_offchan_tx_work(struct work_struct *work)

hdr = (struct ieee80211_hdr *)skb->data;
peer_addr = ieee80211_get_DA(hdr);
- vdev_id = ATH10K_SKB_CB(skb)->vdev_id;

spin_lock_bh(&ar->data_lock);
+ vdev_id = ar->scan.vdev_id;
peer = ath10k_peer_find(ar, vdev_id, peer_addr);
spin_unlock_bh(&ar->data_lock);

@@ -3692,8 +3666,10 @@ static void ath10k_tx(struct ieee80211_hw *hw,
if (ieee80211_is_mgmt(hdr->frame_control))
skb_cb->flags |= ATH10K_SKB_F_MGMT;

- skb_cb->htt.tid = ath10k_tx_h_get_tid(hdr);
- skb_cb->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
+ if (ieee80211_is_data_qos(hdr->frame_control))
+ skb_cb->flags |= ATH10K_SKB_F_QOS;
+
+ skb_cb->vif = vif;

switch (txmode) {
case ATH10K_HW_TXRX_MGMT:
@@ -3714,10 +3690,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
}

if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
- spin_lock_bh(&ar->data_lock);
- ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
- spin_unlock_bh(&ar->data_lock);
-
if (!ath10k_mac_tx_frm_has_freq(ar)) {
ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
skb);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 6028a598c199..2a44d63a03cd 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1814,16 +1814,24 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)
static struct sk_buff *
ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
{
+ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
+ struct ath10k_vif *arvif = (void *)cb->vif->drv_priv;
struct wmi_mgmt_tx_cmd *cmd;
struct ieee80211_hdr *hdr;
struct sk_buff *skb;
int len;
+ u32 vdev_id;
u32 buf_len = msdu->len;
u16 fc;

hdr = (struct ieee80211_hdr *)msdu->data;
fc = le16_to_cpu(hdr->frame_control);

+ if (cb->vif)
+ vdev_id = arvif->vdev_id;
+ else
+ vdev_id = 0;
+
if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
return ERR_PTR(-EINVAL);

@@ -1845,7 +1853,7 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)

cmd = (struct wmi_mgmt_tx_cmd *)skb->data;

- cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(msdu)->vdev_id);
+ cmd->hdr.vdev_id = __cpu_to_le32(vdev_id);
cmd->hdr.tx_rate = 0;
cmd->hdr.tx_power = 0;
cmd->hdr.buf_len = __cpu_to_le32(buf_len);
--
2.1.4


2015-11-02 14:04:08

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 5/8] ath10k: remove freq from skb_cb

It was wasteful to keep it in the struct.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/htt_tx.c | 9 +++++++--
drivers/net/wireless/ath/ath10k/mac.c | 5 +----
3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index f24a5feb2220..64a248f780b9 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -88,7 +88,6 @@ struct ath10k_skb_cb {

struct {
u8 tid;
- u16 freq;
bool nohwcrypt;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index bada9695a4fb..05ce99ad6ca2 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -531,6 +531,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
struct ath10k *ar = htt->ar;
struct device *dev = ar->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
struct htt_data_tx_desc_frag *frags;
@@ -540,6 +541,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
int res;
u8 flags0 = 0;
u16 msdu_id, flags1 = 0;
+ u16 freq = 0;
u32 frags_paddr = 0;
struct htt_msdu_ext_desc *ext_desc = NULL;
bool limit_mgmt_desc = false;
@@ -591,6 +593,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
goto err_free_msdu_id;
}

+ if (unlikely(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN))
+ freq = ar->scan.roc_freq;
+
switch (txmode) {
case ATH10K_HW_TXRX_RAW:
case ATH10K_HW_TXRX_NATIVE_WIFI:
@@ -680,13 +685,13 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
- skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(skb_cb->htt.freq);
+ skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(freq);

trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid);
ath10k_dbg(ar, ATH10K_DBG_HTT,
"htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu freq %hu\n",
flags0, flags1, msdu->len, msdu_id, frags_paddr,
- (u32)skb_cb->paddr, vdev_id, tid, skb_cb->htt.freq);
+ (u32)skb_cb->paddr, vdev_id, tid, freq);
ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ",
msdu->data, msdu->len);
trace_ath10k_tx_hdr(ar, msdu->data, msdu->len);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 9c76934b3bf0..ddf2ad2f3955 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3517,6 +3517,7 @@ void __ath10k_scan_finish(struct ath10k *ar)
case ATH10K_SCAN_STARTING:
ar->scan.state = ATH10K_SCAN_IDLE;
ar->scan_channel = NULL;
+ ar->scan.roc_freq = 0;
ath10k_offchan_tx_purge(ar);
cancel_delayed_work(&ar->scan.timeout);
complete_all(&ar->scan.completed);
@@ -3672,7 +3673,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,

txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);

- ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
@@ -3697,13 +3697,10 @@ static void ath10k_tx(struct ieee80211_hw *hw,

if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
spin_lock_bh(&ar->data_lock);
- ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
spin_unlock_bh(&ar->data_lock);

if (ath10k_mac_need_offchan_tx_work(ar)) {
- ATH10K_SKB_CB(skb)->htt.freq = 0;
-
ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
skb);

--
2.1.4


2015-11-12 19:29:20

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v2 0/9] ath10k: clean up ath10k_skb_cb

Michal Kazior <[email protected]> writes:

> The ath10k_skb_cb structure wasn't really space
> efficient. Some stuff is removed or replaced with
> more compact representation.
>
> This cleanup is necessary for future features.
>
> The size of ath10k_skb_cb:
>
> before after
> x86-32 26 12
> x86-64 34 20
>
>
> v2:
> * fix a bug (patch 7/9 introduced)
>
>
> Michal Kazior (9):
> ath10k: merge is_protected with nohwcrypt
> ath10k: rename function to adhere to naming convention
> ath10k: remove txmode from skb_cb
> ath10k: remove is_offchan
> ath10k: remove freq from skb_cb
> ath10k: pack up flags in skb_cb
> ath10k: fix tx header parsing
> ath10k: replace vdev_id and tid in skb cb
> ath10k: store msdu_id instead of txbuf pointers

I have a conflict which I can't fix myself:

Applying: ath10k: merge is_protected with nohwcrypt
Applying: ath10k: rename function to adhere to naming convention
Applying: ath10k: remove txmode from skb_cb
Applying: ath10k: remove is_offchan
fatal: sha1 information is lacking or useless (drivers/net/wireless/ath/ath10k/mac.c).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0004 ath10k: remove is_offchan

--
Kalle Valo

2015-11-02 14:04:04

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 1/8] ath10k: merge is_protected with nohwcrypt

It was wasteful to have two flags describing
the same thing.

While at it fix code style of
ath10k_tx_h_use_hwcrypto().

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/htt_tx.c | 3 ---
drivers/net/wireless/ath/ath10k/mac.c | 14 ++++++++++----
3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 4a2301589902..64d9a63e6b48 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -86,7 +86,6 @@ struct ath10k_skb_cb {
u8 eid;
u8 vdev_id;
enum ath10k_hw_txrx_mode txmode;
- bool is_protected;

struct {
u8 tid;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 16823970dbfd..eaa9263f6151 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -656,9 +656,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
if (skb_cb->htt.nohwcrypt)
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;

- if (!skb_cb->is_protected)
- flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
-
flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID);
if (msdu->ip_summed == CHECKSUM_PARTIAL &&
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index a7411fe90cc4..58230cd04174 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3190,14 +3190,22 @@ ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
}

static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
- struct sk_buff *skb) {
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct sk_buff *skb)
+{
+ const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ const struct ieee80211_hdr *hdr = (void *)skb->data;
const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
IEEE80211_TX_CTL_INJECTED;
+
+ if (!ieee80211_has_protected(hdr->frame_control))
+ return false;
+
if ((info->flags & mask) == mask)
return false;
+
if (vif)
return !ath10k_vif_to_arvif(vif)->nohwcrypt;
+
return true;
}

@@ -3635,7 +3643,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- __le16 fc = hdr->frame_control;

/* We should disable CCK RATE due to P2P */
if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
@@ -3647,7 +3654,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
- ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);

switch (ATH10K_SKB_CB(skb)->txmode) {
case ATH10K_HW_TXRX_MGMT:
--
2.1.4


2015-11-18 05:59:32

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v3 1/9] ath10k: merge is_protected with nohwcrypt

It was wasteful to have two flags describing
the same thing.

While at it fix code style of
ath10k_tx_h_use_hwcrypto().

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/htt_tx.c | 3 ---
drivers/net/wireless/ath/ath10k/mac.c | 14 ++++++++++----
3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 938431ffed4d..b91f69286a4f 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -86,7 +86,6 @@ struct ath10k_skb_cb {
u8 eid;
u8 vdev_id;
enum ath10k_hw_txrx_mode txmode;
- bool is_protected;

struct {
u8 tid;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 8f76b9d96486..b57335d47c78 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -663,9 +663,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
if (skb_cb->htt.nohwcrypt)
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;

- if (!skb_cb->is_protected)
- flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
-
flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID);
if (msdu->ip_summed == CHECKSUM_PARTIAL &&
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 20e73729c397..ab2e5677f771 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3200,14 +3200,22 @@ ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
}

static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
- struct sk_buff *skb) {
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct sk_buff *skb)
+{
+ const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ const struct ieee80211_hdr *hdr = (void *)skb->data;
const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
IEEE80211_TX_CTL_INJECTED;
+
+ if (!ieee80211_has_protected(hdr->frame_control))
+ return false;
+
if ((info->flags & mask) == mask)
return false;
+
if (vif)
return !ath10k_vif_to_arvif(vif)->nohwcrypt;
+
return true;
}

@@ -3646,7 +3654,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- __le16 fc = hdr->frame_control;

/* We should disable CCK RATE due to P2P */
if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
@@ -3658,7 +3665,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
- ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);

switch (ATH10K_SKB_CB(skb)->txmode) {
case ATH10K_HW_TXRX_MGMT:
--
2.1.4


2015-11-10 13:13:14

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v2 9/9] ath10k: store msdu_id instead of txbuf pointers

Txbuf is no longer a DMA pool and can be easily
tracked with a mere msdu_id. This saves 10 bytes
on 64bit systems and 6 bytes on 32bit systems of
precious sk_buff control buffer.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 6 +---
drivers/net/wireless/ath/ath10k/htt_tx.c | 53 ++++++++++++++++----------------
2 files changed, 27 insertions(+), 32 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 8d17761ad101..15238efc1e4d 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -93,12 +93,8 @@ struct ath10k_skb_cb {
dma_addr_t paddr;
u8 flags;
u8 eid;
+ u16 msdu_id;
struct ieee80211_vif *vif;
-
- struct {
- struct ath10k_htt_txbuf *txbuf;
- u32 txbuf_paddr;
- } __packed htt;
} __packed;

struct ath10k_skb_rxcb {
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index a337fb9328a9..5c440d6c4f11 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -539,8 +539,6 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
memcpy(cmd->mgmt_tx.hdr, msdu->data,
min_t(int, msdu->len, HTT_MGMT_FRM_HDR_DOWNLOAD_LEN));

- skb_cb->htt.txbuf = NULL;
-
res = ath10k_htc_send(&htt->ar->htc, htt->eid, txdesc);
if (res)
goto err_unmap_msdu;
@@ -570,6 +568,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
+ struct ath10k_htt_txbuf *txbuf;
struct htt_data_tx_desc_frag *frags;
bool is_eth = (txmode == ATH10K_HW_TXRX_ETHERNET);
u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
@@ -580,6 +579,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
u16 msdu_id, flags1 = 0;
u16 freq = 0;
u32 frags_paddr = 0;
+ u32 txbuf_paddr;
struct htt_msdu_ext_desc *ext_desc = NULL;
bool limit_mgmt_desc = false;
bool is_probe_resp = false;
@@ -607,9 +607,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
prefetch_len = min(htt->prefetch_len, msdu->len);
prefetch_len = roundup(prefetch_len, 4);

- skb_cb->htt.txbuf = &htt->txbuf.vaddr[msdu_id];
- skb_cb->htt.txbuf_paddr = htt->txbuf.paddr +
- (sizeof(struct ath10k_htt_txbuf) * msdu_id);
+ txbuf = &htt->txbuf.vaddr[msdu_id];
+ txbuf_paddr = htt->txbuf.paddr +
+ (sizeof(struct ath10k_htt_txbuf) * msdu_id);

if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
@@ -653,14 +653,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
frags_paddr = htt->frag_desc.paddr +
(sizeof(struct htt_msdu_ext_desc) * msdu_id);
} else {
- frags = skb_cb->htt.txbuf->frags;
+ frags = txbuf->frags;
frags[0].dword_addr.paddr =
__cpu_to_le32(skb_cb->paddr);
frags[0].dword_addr.len = __cpu_to_le32(msdu->len);
frags[1].dword_addr.paddr = 0;
frags[1].dword_addr.len = 0;

- frags_paddr = skb_cb->htt.txbuf_paddr;
+ frags_paddr = txbuf_paddr;
}
flags0 |= SM(txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
break;
@@ -689,12 +689,11 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
* avoid extra memory allocations, compress data structures and thus
* improve performance. */

- skb_cb->htt.txbuf->htc_hdr.eid = htt->eid;
- skb_cb->htt.txbuf->htc_hdr.len = __cpu_to_le16(
- sizeof(skb_cb->htt.txbuf->cmd_hdr) +
- sizeof(skb_cb->htt.txbuf->cmd_tx) +
- prefetch_len);
- skb_cb->htt.txbuf->htc_hdr.flags = 0;
+ txbuf->htc_hdr.eid = htt->eid;
+ txbuf->htc_hdr.len = __cpu_to_le16(sizeof(txbuf->cmd_hdr) +
+ sizeof(txbuf->cmd_tx) +
+ prefetch_len);
+ txbuf->htc_hdr.flags = 0;

if (skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
@@ -715,14 +714,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
*/
flags1 |= HTT_DATA_TX_DESC_FLAGS1_POSTPONED;

- skb_cb->htt.txbuf->cmd_hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
- skb_cb->htt.txbuf->cmd_tx.flags0 = flags0;
- skb_cb->htt.txbuf->cmd_tx.flags1 = __cpu_to_le16(flags1);
- skb_cb->htt.txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
- skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
- skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
- skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
- skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(freq);
+ txbuf->cmd_hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
+ txbuf->cmd_tx.flags0 = flags0;
+ txbuf->cmd_tx.flags1 = __cpu_to_le16(flags1);
+ txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
+ txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
+ txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
+ txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
+ txbuf->cmd_tx.freq = __cpu_to_le16(freq);

trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid);
ath10k_dbg(ar, ATH10K_DBG_HTT,
@@ -736,12 +735,12 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,

sg_items[0].transfer_id = 0;
sg_items[0].transfer_context = NULL;
- sg_items[0].vaddr = &skb_cb->htt.txbuf->htc_hdr;
- sg_items[0].paddr = skb_cb->htt.txbuf_paddr +
- sizeof(skb_cb->htt.txbuf->frags);
- sg_items[0].len = sizeof(skb_cb->htt.txbuf->htc_hdr) +
- sizeof(skb_cb->htt.txbuf->cmd_hdr) +
- sizeof(skb_cb->htt.txbuf->cmd_tx);
+ sg_items[0].vaddr = &txbuf->htc_hdr;
+ sg_items[0].paddr = txbuf_paddr +
+ sizeof(txbuf->frags);
+ sg_items[0].len = sizeof(txbuf->htc_hdr) +
+ sizeof(txbuf->cmd_hdr) +
+ sizeof(txbuf->cmd_tx);

sg_items[1].transfer_id = 0;
sg_items[1].transfer_context = NULL;
--
2.1.4


2015-11-10 13:13:10

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v2 5/9] ath10k: remove freq from skb_cb

It was wasteful to keep it in the struct.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/htt_tx.c | 9 +++++++--
drivers/net/wireless/ath/ath10k/mac.c | 5 +----
3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 344849dd93c8..3706b0d235ca 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -88,7 +88,6 @@ struct ath10k_skb_cb {

struct {
u8 tid;
- u16 freq;
bool nohwcrypt;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index e9ab0c9075c2..51c40d52bbe9 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -538,6 +538,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
struct ath10k *ar = htt->ar;
struct device *dev = ar->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
struct htt_data_tx_desc_frag *frags;
@@ -547,6 +548,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
int res;
u8 flags0 = 0;
u16 msdu_id, flags1 = 0;
+ u16 freq = 0;
u32 frags_paddr = 0;
struct htt_msdu_ext_desc *ext_desc = NULL;
bool limit_mgmt_desc = false;
@@ -598,6 +600,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
goto err_free_msdu_id;
}

+ if (unlikely(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN))
+ freq = ar->scan.roc_freq;
+
switch (txmode) {
case ATH10K_HW_TXRX_RAW:
case ATH10K_HW_TXRX_NATIVE_WIFI:
@@ -687,13 +692,13 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
- skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(skb_cb->htt.freq);
+ skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(freq);

trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid);
ath10k_dbg(ar, ATH10K_DBG_HTT,
"htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu freq %hu\n",
flags0, flags1, msdu->len, msdu_id, frags_paddr,
- (u32)skb_cb->paddr, vdev_id, tid, skb_cb->htt.freq);
+ (u32)skb_cb->paddr, vdev_id, tid, freq);
ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ",
msdu->data, msdu->len);
trace_ath10k_tx_hdr(ar, msdu->data, msdu->len);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index f7e4fba63b44..3abd684ccd1b 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3524,6 +3524,7 @@ void __ath10k_scan_finish(struct ath10k *ar)
case ATH10K_SCAN_STARTING:
ar->scan.state = ATH10K_SCAN_IDLE;
ar->scan_channel = NULL;
+ ar->scan.roc_freq = 0;
ath10k_offchan_tx_purge(ar);
cancel_delayed_work(&ar->scan.timeout);
complete_all(&ar->scan.completed);
@@ -3679,7 +3680,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,

txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);

- ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
@@ -3704,13 +3704,10 @@ static void ath10k_tx(struct ieee80211_hw *hw,

if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
spin_lock_bh(&ar->data_lock);
- ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
spin_unlock_bh(&ar->data_lock);

if (ath10k_mac_need_offchan_tx_work(ar)) {
- ATH10K_SKB_CB(skb)->htt.freq = 0;
-
ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
skb);

--
2.1.4


2015-11-10 13:13:13

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v2 8/9] ath10k: replace vdev_id and tid in skb cb

This prepares the driver for future ieee80211_txq
and wake_tx_queue() support.

Signed-off-by: Michal Kazior <[email protected]>
---

Notes:
v2:
* fix parsing eth frame as 802.11

drivers/net/wireless/ath/ath10k/core.h | 4 ++--
drivers/net/wireless/ath/ath10k/htt_tx.c | 36 +++++++++++++++++++++++++---
drivers/net/wireless/ath/ath10k/mac.c | 40 +++++---------------------------
drivers/net/wireless/ath/ath10k/wmi.c | 10 +++++++-
4 files changed, 50 insertions(+), 40 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index b9137b1f76d1..8d17761ad101 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -86,16 +86,16 @@ enum ath10k_skb_flags {
ATH10K_SKB_F_DTIM_ZERO = BIT(1),
ATH10K_SKB_F_DELIVER_CAB = BIT(2),
ATH10K_SKB_F_MGMT = BIT(3),
+ ATH10K_SKB_F_QOS = BIT(4),
};

struct ath10k_skb_cb {
dma_addr_t paddr;
u8 flags;
u8 eid;
- u8 vdev_id;
+ struct ieee80211_vif *vif;

struct {
- u8 tid;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
} __packed htt;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 3d1c46a82895..a337fb9328a9 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -439,6 +439,35 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
return 0;
}

+static u8 ath10k_htt_tx_get_vdev_id(struct ath10k *ar, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
+ struct ath10k_vif *arvif = (void *)cb->vif->drv_priv;
+
+ if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
+ return ar->scan.vdev_id;
+ else if (cb->vif)
+ return arvif->vdev_id;
+ else if (ar->monitor_started)
+ return ar->monitor_vdev_id;
+ else
+ return 0;
+}
+
+static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth)
+{
+ struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
+
+ if (!is_eth && ieee80211_is_mgmt(hdr->frame_control))
+ return HTT_DATA_TX_EXT_TID_MGMT;
+ else if (cb->flags & ATH10K_SKB_F_QOS)
+ return skb->priority % IEEE80211_QOS_CTL_TID_MASK;
+ else
+ return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
+}
+
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
{
struct ath10k *ar = htt->ar;
@@ -446,7 +475,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
struct sk_buff *txdesc = NULL;
struct htt_cmd *cmd;
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
- u8 vdev_id = skb_cb->vdev_id;
+ u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
int len = 0;
int msdu_id = -1;
int res;
@@ -542,8 +571,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
struct htt_data_tx_desc_frag *frags;
- u8 vdev_id = skb_cb->vdev_id;
- u8 tid = skb_cb->htt.tid;
+ bool is_eth = (txmode == ATH10K_HW_TXRX_ETHERNET);
+ u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
+ u8 tid = ath10k_htt_tx_get_tid(msdu, is_eth);
int prefetch_len;
int res;
u8 flags0 = 0;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 2f99552acad4..c2387839f25d 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3119,32 +3119,6 @@ void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
spin_unlock_bh(&ar->htt.tx_lock);
}

-static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
-{
- if (ieee80211_is_mgmt(hdr->frame_control))
- return HTT_DATA_TX_EXT_TID_MGMT;
-
- if (!ieee80211_is_data_qos(hdr->frame_control))
- return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
-
- if (!is_unicast_ether_addr(ieee80211_get_DA(hdr)))
- return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
-
- return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
-}
-
-static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
-{
- if (vif)
- return ath10k_vif_to_arvif(vif)->vdev_id;
-
- if (ar->monitor_started)
- return ar->monitor_vdev_id;
-
- ath10k_warn(ar, "failed to resolve vdev id\n");
- return 0;
-}
-
static enum ath10k_hw_txrx_mode
ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
struct ieee80211_vif *vif,
@@ -3241,7 +3215,7 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
hdr = (void *)skb->data;
if (ieee80211_is_qos_nullfunc(hdr->frame_control))
- cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
+ cb->flags &= ~ATH10K_SKB_F_QOS;

hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
}
@@ -3409,9 +3383,9 @@ void ath10k_offchan_tx_work(struct work_struct *work)

hdr = (struct ieee80211_hdr *)skb->data;
peer_addr = ieee80211_get_DA(hdr);
- vdev_id = ATH10K_SKB_CB(skb)->vdev_id;

spin_lock_bh(&ar->data_lock);
+ vdev_id = ar->scan.vdev_id;
peer = ath10k_peer_find(ar, vdev_id, peer_addr);
spin_unlock_bh(&ar->data_lock);

@@ -3688,8 +3662,10 @@ static void ath10k_tx(struct ieee80211_hw *hw,
if (ieee80211_is_mgmt(hdr->frame_control))
skb_cb->flags |= ATH10K_SKB_F_MGMT;

- skb_cb->htt.tid = ath10k_tx_h_get_tid(hdr);
- skb_cb->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
+ if (ieee80211_is_data_qos(hdr->frame_control))
+ skb_cb->flags |= ATH10K_SKB_F_QOS;
+
+ skb_cb->vif = vif;

switch (txmode) {
case ATH10K_HW_TXRX_MGMT:
@@ -3710,10 +3686,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
}

if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
- spin_lock_bh(&ar->data_lock);
- ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
- spin_unlock_bh(&ar->data_lock);
-
if (ath10k_mac_need_offchan_tx_work(ar)) {
ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
skb);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 854136e0d6c8..e4237cd95360 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1814,16 +1814,24 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)
static struct sk_buff *
ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
{
+ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
+ struct ath10k_vif *arvif = (void *)cb->vif->drv_priv;
struct wmi_mgmt_tx_cmd *cmd;
struct ieee80211_hdr *hdr;
struct sk_buff *skb;
int len;
+ u32 vdev_id;
u32 buf_len = msdu->len;
u16 fc;

hdr = (struct ieee80211_hdr *)msdu->data;
fc = le16_to_cpu(hdr->frame_control);

+ if (cb->vif)
+ vdev_id = arvif->vdev_id;
+ else
+ vdev_id = 0;
+
if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
return ERR_PTR(-EINVAL);

@@ -1845,7 +1853,7 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)

cmd = (struct wmi_mgmt_tx_cmd *)skb->data;

- cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(msdu)->vdev_id);
+ cmd->hdr.vdev_id = __cpu_to_le32(vdev_id);
cmd->hdr.tx_rate = 0;
cmd->hdr.tx_power = 0;
cmd->hdr.buf_len = __cpu_to_le32(buf_len);
--
2.1.4


2015-11-13 06:20:08

by Michal Kazior

[permalink] [raw]
Subject: Re: [PATCH v2 0/9] ath10k: clean up ath10k_skb_cb

On 12 November 2015 at 20:29, Kalle Valo <[email protected]> wrote:
> Michal Kazior <[email protected]> writes:
>
>> The ath10k_skb_cb structure wasn't really space
>> efficient. Some stuff is removed or replaced with
>> more compact representation.
>>
>> This cleanup is necessary for future features.
>>
>> The size of ath10k_skb_cb:
>>
>> before after
>> x86-32 26 12
>> x86-64 34 20
>>
>>
>> v2:
>> * fix a bug (patch 7/9 introduced)
>>
>>
>> Michal Kazior (9):
>> ath10k: merge is_protected with nohwcrypt
>> ath10k: rename function to adhere to naming convention
>> ath10k: remove txmode from skb_cb
>> ath10k: remove is_offchan
>> ath10k: remove freq from skb_cb
>> ath10k: pack up flags in skb_cb
>> ath10k: fix tx header parsing
>> ath10k: replace vdev_id and tid in skb cb
>> ath10k: store msdu_id instead of txbuf pointers
>
> I have a conflict which I can't fix myself:
>
> Applying: ath10k: merge is_protected with nohwcrypt
> Applying: ath10k: rename function to adhere to naming convention
> Applying: ath10k: remove txmode from skb_cb
> Applying: ath10k: remove is_offchan
> fatal: sha1 information is lacking or useless (drivers/net/wireless/ath/ath10k/mac.c).
> Repository lacks necessary blobs to fall back on 3-way merge.
> Cannot fall back to three-way merge.
> Patch failed at 0004 ath10k: remove is_offchan

Ah, sorry. I thought I rebased on top of your master branch but it
looks like I didn't. Let me fix that..


MichaƂ

2015-11-10 13:13:07

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v2 4/9] ath10k: remove is_offchan

It was wasteful to keep it in the struct.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/mac.c | 4 +---
drivers/net/wireless/ath/ath10k/mac.h | 1 +
drivers/net/wireless/ath/ath10k/txrx.c | 7 ++++++-
4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 2f48772418ec..344849dd93c8 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -89,7 +89,6 @@ struct ath10k_skb_cb {
struct {
u8 tid;
u16 freq;
- bool is_offchan;
bool nohwcrypt;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index dd4770ec7ecc..f7e4fba63b44 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3297,7 +3297,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
}
}

-static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
+bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
{
/* FIXME: Not really sure since when the behaviour changed. At some
* point new firmware stopped requiring creation of peer entries for
@@ -3679,7 +3679,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,

txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);

- ATH10K_SKB_CB(skb)->htt.is_offchan = false;
ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
@@ -3711,7 +3710,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,

if (ath10k_mac_need_offchan_tx_work(ar)) {
ATH10K_SKB_CB(skb)->htt.freq = 0;
- ATH10K_SKB_CB(skb)->htt.is_offchan = true;

ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
skb);
diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h
index e3cefe4c7cfd..ff09d6986fae 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -58,6 +58,7 @@ bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
u8 keyidx);
int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
struct cfg80211_chan_def *def);
+bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar);

void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb);
void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id);
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 6d1105ab4592..655947bef6cc 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -23,7 +23,12 @@

static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)
{
- if (!ATH10K_SKB_CB(skb)->htt.is_offchan)
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+ if (likely(!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)))
+ return;
+
+ if (!ath10k_mac_need_offchan_tx_work(ar))
return;

/* If the original wait_for_completion() timed out before
--
2.1.4


2015-11-10 13:13:03

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v2 1/9] ath10k: merge is_protected with nohwcrypt

It was wasteful to have two flags describing
the same thing.

While at it fix code style of
ath10k_tx_h_use_hwcrypto().

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/htt_tx.c | 3 ---
drivers/net/wireless/ath/ath10k/mac.c | 14 ++++++++++----
3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index c16f3484dc8a..48db7dd36164 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -86,7 +86,6 @@ struct ath10k_skb_cb {
u8 eid;
u8 vdev_id;
enum ath10k_hw_txrx_mode txmode;
- bool is_protected;

struct {
u8 tid;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index bd8f264ed8cd..31c172848d10 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -663,9 +663,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
if (skb_cb->htt.nohwcrypt)
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;

- if (!skb_cb->is_protected)
- flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
-
flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID);
if (msdu->ip_summed == CHECKSUM_PARTIAL &&
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index a53e213387a2..2eb647913a9f 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3197,14 +3197,22 @@ ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
}

static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
- struct sk_buff *skb) {
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct sk_buff *skb)
+{
+ const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ const struct ieee80211_hdr *hdr = (void *)skb->data;
const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
IEEE80211_TX_CTL_INJECTED;
+
+ if (!ieee80211_has_protected(hdr->frame_control))
+ return false;
+
if ((info->flags & mask) == mask)
return false;
+
if (vif)
return !ath10k_vif_to_arvif(vif)->nohwcrypt;
+
return true;
}

@@ -3642,7 +3650,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- __le16 fc = hdr->frame_control;

/* We should disable CCK RATE due to P2P */
if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
@@ -3654,7 +3661,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
- ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);

switch (ATH10K_SKB_CB(skb)->txmode) {
case ATH10K_HW_TXRX_MGMT:
--
2.1.4


2015-11-02 14:04:12

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 8/8] ath10k: store msdu_id instead of txbuf pointers

Txbuf is no longer a DMA pool and can be easily
tracked with a mere msdu_id. This saves 10 bytes
on 64bit systems and 6 bytes on 32bit systems of
precious sk_buff control buffer.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 6 +---
drivers/net/wireless/ath/ath10k/htt_tx.c | 53 ++++++++++++++++----------------
2 files changed, 27 insertions(+), 32 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 728a5cbe9dfd..f8092a83be2d 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -92,12 +92,8 @@ struct ath10k_skb_cb {
dma_addr_t paddr;
u8 flags;
u8 eid;
+ u16 msdu_id;
struct ieee80211_vif *vif;
-
- struct {
- struct ath10k_htt_txbuf *txbuf;
- u32 txbuf_paddr;
- } __packed htt;
} __packed;

struct ath10k_skb_rxcb {
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index a6fd96a18023..ce81babcc8bd 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -532,8 +532,6 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
memcpy(cmd->mgmt_tx.hdr, msdu->data,
min_t(int, msdu->len, HTT_MGMT_FRM_HDR_DOWNLOAD_LEN));

- skb_cb->htt.txbuf = NULL;
-
res = ath10k_htc_send(&htt->ar->htc, htt->eid, txdesc);
if (res)
goto err_unmap_msdu;
@@ -563,6 +561,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
+ struct ath10k_htt_txbuf *txbuf;
struct htt_data_tx_desc_frag *frags;
u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
u8 tid = ath10k_htt_tx_get_tid(msdu);
@@ -572,6 +571,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
u16 msdu_id, flags1 = 0;
u16 freq = 0;
u32 frags_paddr = 0;
+ u32 txbuf_paddr;
struct htt_msdu_ext_desc *ext_desc = NULL;
bool limit_mgmt_desc = false;
bool is_probe_resp = false;
@@ -599,9 +599,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
prefetch_len = min(htt->prefetch_len, msdu->len);
prefetch_len = roundup(prefetch_len, 4);

- skb_cb->htt.txbuf = &htt->txbuf.vaddr[msdu_id];
- skb_cb->htt.txbuf_paddr = htt->txbuf.paddr +
- (sizeof(struct ath10k_htt_txbuf) * msdu_id);
+ txbuf = &htt->txbuf.vaddr[msdu_id];
+ txbuf_paddr = htt->txbuf.paddr +
+ (sizeof(struct ath10k_htt_txbuf) * msdu_id);

if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
@@ -645,14 +645,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
frags_paddr = htt->frag_desc.paddr +
(sizeof(struct htt_msdu_ext_desc) * msdu_id);
} else {
- frags = skb_cb->htt.txbuf->frags;
+ frags = txbuf->frags;
frags[0].dword_addr.paddr =
__cpu_to_le32(skb_cb->paddr);
frags[0].dword_addr.len = __cpu_to_le32(msdu->len);
frags[1].dword_addr.paddr = 0;
frags[1].dword_addr.len = 0;

- frags_paddr = skb_cb->htt.txbuf_paddr;
+ frags_paddr = txbuf_paddr;
}
flags0 |= SM(txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
break;
@@ -681,12 +681,11 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
* avoid extra memory allocations, compress data structures and thus
* improve performance. */

- skb_cb->htt.txbuf->htc_hdr.eid = htt->eid;
- skb_cb->htt.txbuf->htc_hdr.len = __cpu_to_le16(
- sizeof(skb_cb->htt.txbuf->cmd_hdr) +
- sizeof(skb_cb->htt.txbuf->cmd_tx) +
- prefetch_len);
- skb_cb->htt.txbuf->htc_hdr.flags = 0;
+ txbuf->htc_hdr.eid = htt->eid;
+ txbuf->htc_hdr.len = __cpu_to_le16(sizeof(txbuf->cmd_hdr) +
+ sizeof(txbuf->cmd_tx) +
+ prefetch_len);
+ txbuf->htc_hdr.flags = 0;

if (skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
@@ -707,14 +706,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
*/
flags1 |= HTT_DATA_TX_DESC_FLAGS1_POSTPONED;

- skb_cb->htt.txbuf->cmd_hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
- skb_cb->htt.txbuf->cmd_tx.flags0 = flags0;
- skb_cb->htt.txbuf->cmd_tx.flags1 = __cpu_to_le16(flags1);
- skb_cb->htt.txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
- skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
- skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
- skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
- skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(freq);
+ txbuf->cmd_hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
+ txbuf->cmd_tx.flags0 = flags0;
+ txbuf->cmd_tx.flags1 = __cpu_to_le16(flags1);
+ txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
+ txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
+ txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
+ txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
+ txbuf->cmd_tx.freq = __cpu_to_le16(freq);

trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid);
ath10k_dbg(ar, ATH10K_DBG_HTT,
@@ -728,12 +727,12 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,

sg_items[0].transfer_id = 0;
sg_items[0].transfer_context = NULL;
- sg_items[0].vaddr = &skb_cb->htt.txbuf->htc_hdr;
- sg_items[0].paddr = skb_cb->htt.txbuf_paddr +
- sizeof(skb_cb->htt.txbuf->frags);
- sg_items[0].len = sizeof(skb_cb->htt.txbuf->htc_hdr) +
- sizeof(skb_cb->htt.txbuf->cmd_hdr) +
- sizeof(skb_cb->htt.txbuf->cmd_tx);
+ sg_items[0].vaddr = &txbuf->htc_hdr;
+ sg_items[0].paddr = txbuf_paddr +
+ sizeof(txbuf->frags);
+ sg_items[0].len = sizeof(txbuf->htc_hdr) +
+ sizeof(txbuf->cmd_hdr) +
+ sizeof(txbuf->cmd_tx);

sg_items[1].transfer_id = 0;
sg_items[1].transfer_context = NULL;
--
2.1.4


2015-11-18 05:59:35

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v3 4/9] ath10k: remove is_offchan

It was wasteful to keep it in the struct.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/mac.c | 2 --
drivers/net/wireless/ath/ath10k/txrx.c | 7 ++++++-
3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 0228000ecf50..89a83e3c5cb6 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -89,7 +89,6 @@ struct ath10k_skb_cb {
struct {
u8 tid;
u16 freq;
- bool is_offchan;
bool nohwcrypt;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 4d3b8dc8e5de..164a3e5ae6da 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3683,7 +3683,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,

txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);

- ATH10K_SKB_CB(skb)->htt.is_offchan = false;
ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
@@ -3715,7 +3714,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,

if (!ath10k_mac_tx_frm_has_freq(ar)) {
ATH10K_SKB_CB(skb)->htt.freq = 0;
- ATH10K_SKB_CB(skb)->htt.is_offchan = true;

ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
skb);
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 6d1105ab4592..9e14c04ac89f 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -23,7 +23,12 @@

static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)
{
- if (!ATH10K_SKB_CB(skb)->htt.is_offchan)
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+ if (likely(!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)))
+ return;
+
+ if (ath10k_mac_tx_frm_has_freq(ar))
return;

/* If the original wait_for_completion() timed out before
--
2.1.4


2015-11-02 14:04:06

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 3/8] ath10k: remove txmode from skb_cb

It was wasteful to keep it in the struct because
it can be passed as function argument down the tx
path.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/htt.h | 3 ++-
drivers/net/wireless/ath/ath10k/htt_tx.c | 9 +++----
drivers/net/wireless/ath/ath10k/mac.c | 40 ++++++++++++++++++++++++--------
4 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 64d9a63e6b48..efc34b1412b4 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -85,7 +85,6 @@ struct ath10k_skb_cb {
dma_addr_t paddr;
u8 eid;
u8 vdev_id;
- enum ath10k_hw_txrx_mode txmode;

struct {
u8 tid;
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 2bad50e520b5..9d15924b1f90 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1597,6 +1597,7 @@ void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt, bool limit_mgmt_desc);
int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb);
void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id);
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *);
-int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *);
+int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *msdu);

#endif
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index eaa9263f6151..bada9695a4fb 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -525,7 +525,8 @@ err:
return res;
}

-int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
+int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *msdu)
{
struct ath10k *ar = htt->ar;
struct device *dev = ar->dev;
@@ -577,7 +578,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (!skb_cb->htt.nohwcrypt &&
- skb_cb->txmode == ATH10K_HW_TXRX_RAW &&
+ txmode == ATH10K_HW_TXRX_RAW &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
}
@@ -590,7 +591,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
goto err_free_msdu_id;
}

- switch (skb_cb->txmode) {
+ switch (txmode) {
case ATH10K_HW_TXRX_RAW:
case ATH10K_HW_TXRX_NATIVE_WIFI:
flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
@@ -619,7 +620,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)

frags_paddr = skb_cb->htt.txbuf_paddr;
}
- flags0 |= SM(skb_cb->txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
+ flags0 |= SM(txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
break;
case ATH10K_HW_TXRX_MGMT:
flags0 |= SM(ATH10K_HW_TXRX_MGMT,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 14a705ca87b2..dd24bc970b00 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3324,24 +3324,24 @@ unlock:
return ret;
}

-static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
+static void ath10k_mac_tx(struct ath10k *ar, enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *skb)
{
- struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
struct ath10k_htt *htt = &ar->htt;
int ret = 0;

- switch (cb->txmode) {
+ switch (txmode) {
case ATH10K_HW_TXRX_RAW:
case ATH10K_HW_TXRX_NATIVE_WIFI:
case ATH10K_HW_TXRX_ETHERNET:
- ret = ath10k_htt_tx(htt, skb);
+ ret = ath10k_htt_tx(htt, txmode, skb);
break;
case ATH10K_HW_TXRX_MGMT:
if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
ar->fw_features))
ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
else if (ar->htt.target_version_major >= 3)
- ret = ath10k_htt_tx(htt, skb);
+ ret = ath10k_htt_tx(htt, txmode, skb);
else
ret = ath10k_htt_mgmt_tx(htt, skb);
break;
@@ -3371,9 +3371,13 @@ void ath10k_offchan_tx_work(struct work_struct *work)
{
struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
struct ath10k_peer *peer;
+ struct ath10k_vif *arvif;
struct ieee80211_hdr *hdr;
+ struct ieee80211_vif *vif;
+ struct ieee80211_sta *sta;
struct sk_buff *skb;
const u8 *peer_addr;
+ enum ath10k_hw_txrx_mode txmode;
int vdev_id;
int ret;
unsigned long time_left;
@@ -3423,7 +3427,22 @@ void ath10k_offchan_tx_work(struct work_struct *work)
ar->offchan_tx_skb = skb;
spin_unlock_bh(&ar->data_lock);

- ath10k_mac_tx(ar, skb);
+ /* It's safe to access vif and sta - conf_mutex guarantees that
+ * sta_state() and remove_interface() are locked exclusively
+ * out wrt to this offchannel worker.
+ */
+ arvif = ath10k_get_arvif(ar, vdev_id);
+ if (arvif) {
+ vif = arvif->vif;
+ sta = ieee80211_find_sta(vif, peer_addr);
+ } else {
+ vif = NULL;
+ sta = NULL;
+ }
+
+ txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
+
+ ath10k_mac_tx(ar, txmode, skb);

time_left =
wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
@@ -3645,20 +3664,21 @@ static void ath10k_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ enum ath10k_hw_txrx_mode txmode;

/* We should disable CCK RATE due to P2P */
if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");

+ txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
+
ATH10K_SKB_CB(skb)->htt.is_offchan = false;
ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
- ATH10K_SKB_CB(skb)->txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta,
- skb);

- switch (ATH10K_SKB_CB(skb)->txmode) {
+ switch (txmode) {
case ATH10K_HW_TXRX_MGMT:
case ATH10K_HW_TXRX_NATIVE_WIFI:
ath10k_tx_h_nwifi(hw, skb);
@@ -3695,7 +3715,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
}
}

- ath10k_mac_tx(ar, skb);
+ ath10k_mac_tx(ar, txmode, skb);
}

/* Must not be called with conf_mutex held as workers can use that also. */
--
2.1.4


2015-11-18 05:59:38

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v3 6/9] ath10k: pack up flags in skb_cb

It was wasteful to have all the flags as separate
bools.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 13 +++++++------
drivers/net/wireless/ath/ath10k/htt_tx.c | 4 ++--
drivers/net/wireless/ath/ath10k/mac.c | 10 +++++++---
drivers/net/wireless/ath/ath10k/wmi.c | 12 ++++++++----
4 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 804fd2e5bc38..6b9b37329621 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -81,22 +81,23 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus)
return "unknown";
}

+enum ath10k_skb_flags {
+ ATH10K_SKB_F_NO_HWCRYPT = BIT(0),
+ ATH10K_SKB_F_DTIM_ZERO = BIT(1),
+ ATH10K_SKB_F_DELIVER_CAB = BIT(2),
+};
+
struct ath10k_skb_cb {
dma_addr_t paddr;
+ u8 flags;
u8 eid;
u8 vdev_id;

struct {
u8 tid;
- bool nohwcrypt;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
} __packed htt;
-
- struct {
- bool dtim_zero;
- bool deliver_cab;
- } bcn;
} __packed;

struct ath10k_skb_rxcb {
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index a7d8798b2f37..c955c6b6ea9d 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -586,7 +586,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
- } else if (!skb_cb->htt.nohwcrypt &&
+ } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
txmode == ATH10K_HW_TXRX_RAW &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
@@ -666,7 +666,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
prefetch_len);
skb_cb->htt.txbuf->htc_hdr.flags = 0;

- if (skb_cb->htt.nohwcrypt)
+ if (skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;

flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 0ca5d5bea509..38c241596965 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3672,6 +3672,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
struct ath10k *ar = hw->priv;
+ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
@@ -3684,9 +3685,12 @@ static void ath10k_tx(struct ieee80211_hw *hw,

txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);

- ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
- ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
- ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
+ skb_cb->flags = 0;
+ if (!ath10k_tx_h_use_hwcrypto(vif, skb))
+ skb_cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
+
+ skb_cb->htt.tid = ath10k_tx_h_get_tid(hdr);
+ skb_cb->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);

switch (txmode) {
case ATH10K_HW_TXRX_MGMT:
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 902107934edd..6028a598c199 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1715,6 +1715,8 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
struct ath10k *ar = arvif->ar;
struct ath10k_skb_cb *cb;
struct sk_buff *bcn;
+ bool dtim_zero;
+ bool deliver_cab;
int ret;

spin_lock_bh(&ar->data_lock);
@@ -1734,12 +1736,14 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
arvif->beacon_state = ATH10K_BEACON_SENDING;
spin_unlock_bh(&ar->data_lock);

+ dtim_zero = !!(cb->flags & ATH10K_SKB_F_DTIM_ZERO);
+ deliver_cab = !!(cb->flags & ATH10K_SKB_F_DELIVER_CAB);
ret = ath10k_wmi_beacon_send_ref_nowait(arvif->ar,
arvif->vdev_id,
bcn->data, bcn->len,
cb->paddr,
- cb->bcn.dtim_zero,
- cb->bcn.deliver_cab);
+ dtim_zero,
+ deliver_cab);

spin_lock_bh(&ar->data_lock);

@@ -3157,10 +3161,10 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len);

if (tim->dtim_count == 0) {
- ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true;
+ ATH10K_SKB_CB(bcn)->flags |= ATH10K_SKB_F_DTIM_ZERO;

if (__le32_to_cpu(tim_info->tim_mcast) == 1)
- ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true;
+ ATH10K_SKB_CB(bcn)->flags |= ATH10K_SKB_F_DELIVER_CAB;
}

ath10k_dbg(ar, ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n",
--
2.1.4


2015-11-02 14:04:11

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 7/8] ath10k: replace vdev_id and tid in skb cb

This prepares the driver for future ieee80211_txq
and wake_tx_queue() support.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 4 ++--
drivers/net/wireless/ath/ath10k/htt_tx.c | 35 +++++++++++++++++++++++++---
drivers/net/wireless/ath/ath10k/mac.c | 40 +++++---------------------------
drivers/net/wireless/ath/ath10k/wmi.c | 10 +++++++-
4 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 59ec9a8098d0..728a5cbe9dfd 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -85,16 +85,16 @@ enum ath10k_skb_flags {
ATH10K_SKB_F_NO_HWCRYPT = BIT(0),
ATH10K_SKB_F_DTIM_ZERO = BIT(1),
ATH10K_SKB_F_DELIVER_CAB = BIT(2),
+ ATH10K_SKB_F_QOS = BIT(3),
};

struct ath10k_skb_cb {
dma_addr_t paddr;
u8 flags;
u8 eid;
- u8 vdev_id;
+ struct ieee80211_vif *vif;

struct {
- u8 tid;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
} __packed htt;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index a572576bf6c4..a6fd96a18023 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -439,6 +439,35 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
return 0;
}

+static u8 ath10k_htt_tx_get_vdev_id(struct ath10k *ar, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
+ struct ath10k_vif *arvif = (void *)cb->vif->drv_priv;
+
+ if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
+ return ar->scan.vdev_id;
+ else if (cb->vif)
+ return arvif->vdev_id;
+ else if (ar->monitor_started)
+ return ar->monitor_vdev_id;
+ else
+ return 0;
+}
+
+static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
+
+ if (ieee80211_is_mgmt(hdr->frame_control))
+ return HTT_DATA_TX_EXT_TID_MGMT;
+ else if (cb->flags & ATH10K_SKB_F_QOS)
+ return skb->priority % IEEE80211_QOS_CTL_TID_MASK;
+ else
+ return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
+}
+
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
{
struct ath10k *ar = htt->ar;
@@ -446,7 +475,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
struct sk_buff *txdesc = NULL;
struct htt_cmd *cmd;
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
- u8 vdev_id = skb_cb->vdev_id;
+ u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
int len = 0;
int msdu_id = -1;
int res;
@@ -535,8 +564,8 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
struct htt_data_tx_desc_frag *frags;
- u8 vdev_id = skb_cb->vdev_id;
- u8 tid = skb_cb->htt.tid;
+ u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
+ u8 tid = ath10k_htt_tx_get_tid(msdu);
int prefetch_len;
int res;
u8 flags0 = 0;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 105a2e61c2ae..20b6639b978c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3112,32 +3112,6 @@ void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
spin_unlock_bh(&ar->htt.tx_lock);
}

-static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
-{
- if (ieee80211_is_mgmt(hdr->frame_control))
- return HTT_DATA_TX_EXT_TID_MGMT;
-
- if (!ieee80211_is_data_qos(hdr->frame_control))
- return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
-
- if (!is_unicast_ether_addr(ieee80211_get_DA(hdr)))
- return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
-
- return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
-}
-
-static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
-{
- if (vif)
- return ath10k_vif_to_arvif(vif)->vdev_id;
-
- if (ar->monitor_started)
- return ar->monitor_vdev_id;
-
- ath10k_warn(ar, "failed to resolve vdev id\n");
- return 0;
-}
-
static enum ath10k_hw_txrx_mode
ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
struct ieee80211_vif *vif,
@@ -3234,7 +3208,7 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
hdr = (void *)skb->data;
if (ieee80211_is_qos_nullfunc(hdr->frame_control))
- cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
+ cb->flags &= ~ATH10K_SKB_F_QOS;

hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
}
@@ -3402,9 +3376,9 @@ void ath10k_offchan_tx_work(struct work_struct *work)

hdr = (struct ieee80211_hdr *)skb->data;
peer_addr = ieee80211_get_DA(hdr);
- vdev_id = ATH10K_SKB_CB(skb)->vdev_id;

spin_lock_bh(&ar->data_lock);
+ vdev_id = ar->scan.vdev_id;
peer = ath10k_peer_find(ar, vdev_id, peer_addr);
spin_unlock_bh(&ar->data_lock);

@@ -3678,8 +3652,10 @@ static void ath10k_tx(struct ieee80211_hw *hw,
if (!ath10k_tx_h_use_hwcrypto(vif, skb))
skb_cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;

- skb_cb->htt.tid = ath10k_tx_h_get_tid(hdr);
- skb_cb->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
+ if (ieee80211_is_data_qos(hdr->frame_control))
+ skb_cb->flags |= ATH10K_SKB_F_QOS;
+
+ skb_cb->vif = vif;

switch (txmode) {
case ATH10K_HW_TXRX_MGMT:
@@ -3700,10 +3676,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
}

if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
- spin_lock_bh(&ar->data_lock);
- ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
- spin_unlock_bh(&ar->data_lock);
-
if (ath10k_mac_need_offchan_tx_work(ar)) {
ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
skb);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 022d42d29486..65bce46b39a5 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1759,16 +1759,24 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)
static struct sk_buff *
ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
{
+ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
+ struct ath10k_vif *arvif = (void *)cb->vif->drv_priv;
struct wmi_mgmt_tx_cmd *cmd;
struct ieee80211_hdr *hdr;
struct sk_buff *skb;
int len;
+ u32 vdev_id;
u32 buf_len = msdu->len;
u16 fc;

hdr = (struct ieee80211_hdr *)msdu->data;
fc = le16_to_cpu(hdr->frame_control);

+ if (cb->vif)
+ vdev_id = arvif->vdev_id;
+ else
+ vdev_id = 0;
+
if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
return ERR_PTR(-EINVAL);

@@ -1790,7 +1798,7 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)

cmd = (struct wmi_mgmt_tx_cmd *)skb->data;

- cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(msdu)->vdev_id);
+ cmd->hdr.vdev_id = __cpu_to_le32(vdev_id);
cmd->hdr.tx_rate = 0;
cmd->hdr.tx_power = 0;
cmd->hdr.buf_len = __cpu_to_le32(buf_len);
--
2.1.4


2015-11-18 05:59:34

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v3 3/9] ath10k: remove txmode from skb_cb

It was wasteful to keep it in the struct because
it can be passed as function argument down the tx
path.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/htt.h | 4 +++-
drivers/net/wireless/ath/ath10k/htt_tx.c | 9 +++----
drivers/net/wireless/ath/ath10k/mac.c | 40 ++++++++++++++++++++++++--------
4 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index b91f69286a4f..0228000ecf50 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -85,7 +85,6 @@ struct ath10k_skb_cb {
dma_addr_t paddr;
u8 eid;
u8 vdev_id;
- enum ath10k_hw_txrx_mode txmode;

struct {
u8 tid;
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 2b87ed6458db..47ca048feaf0 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1602,7 +1602,9 @@ void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt, bool limit_mgmt_desc);
int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb);
void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id);
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *);
-int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *);
+int ath10k_htt_tx(struct ath10k_htt *htt,
+ enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *msdu);
void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
struct sk_buff *skb);

diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index b57335d47c78..f6fb4f131542 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -532,7 +532,8 @@ err:
return res;
}

-int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
+int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *msdu)
{
struct ath10k *ar = htt->ar;
struct device *dev = ar->dev;
@@ -584,7 +585,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (!skb_cb->htt.nohwcrypt &&
- skb_cb->txmode == ATH10K_HW_TXRX_RAW &&
+ txmode == ATH10K_HW_TXRX_RAW &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
}
@@ -597,7 +598,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
goto err_free_msdu_id;
}

- switch (skb_cb->txmode) {
+ switch (txmode) {
case ATH10K_HW_TXRX_RAW:
case ATH10K_HW_TXRX_NATIVE_WIFI:
flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
@@ -626,7 +627,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)

frags_paddr = skb_cb->htt.txbuf_paddr;
}
- flags0 |= SM(skb_cb->txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
+ flags0 |= SM(txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
break;
case ATH10K_HW_TXRX_MGMT:
flags0 |= SM(ATH10K_HW_TXRX_MGMT,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index be323ad537ad..4d3b8dc8e5de 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3335,24 +3335,24 @@ unlock:
return ret;
}

-static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
+static void ath10k_mac_tx(struct ath10k *ar, enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *skb)
{
- struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
struct ath10k_htt *htt = &ar->htt;
int ret = 0;

- switch (cb->txmode) {
+ switch (txmode) {
case ATH10K_HW_TXRX_RAW:
case ATH10K_HW_TXRX_NATIVE_WIFI:
case ATH10K_HW_TXRX_ETHERNET:
- ret = ath10k_htt_tx(htt, skb);
+ ret = ath10k_htt_tx(htt, txmode, skb);
break;
case ATH10K_HW_TXRX_MGMT:
if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
ar->fw_features))
ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
else if (ar->htt.target_version_major >= 3)
- ret = ath10k_htt_tx(htt, skb);
+ ret = ath10k_htt_tx(htt, txmode, skb);
else
ret = ath10k_htt_mgmt_tx(htt, skb);
break;
@@ -3382,9 +3382,13 @@ void ath10k_offchan_tx_work(struct work_struct *work)
{
struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
struct ath10k_peer *peer;
+ struct ath10k_vif *arvif;
struct ieee80211_hdr *hdr;
+ struct ieee80211_vif *vif;
+ struct ieee80211_sta *sta;
struct sk_buff *skb;
const u8 *peer_addr;
+ enum ath10k_hw_txrx_mode txmode;
int vdev_id;
int ret;
unsigned long time_left;
@@ -3434,7 +3438,22 @@ void ath10k_offchan_tx_work(struct work_struct *work)
ar->offchan_tx_skb = skb;
spin_unlock_bh(&ar->data_lock);

- ath10k_mac_tx(ar, skb);
+ /* It's safe to access vif and sta - conf_mutex guarantees that
+ * sta_state() and remove_interface() are locked exclusively
+ * out wrt to this offchannel worker.
+ */
+ arvif = ath10k_get_arvif(ar, vdev_id);
+ if (arvif) {
+ vif = arvif->vif;
+ sta = ieee80211_find_sta(vif, peer_addr);
+ } else {
+ vif = NULL;
+ sta = NULL;
+ }
+
+ txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
+
+ ath10k_mac_tx(ar, txmode, skb);

time_left =
wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
@@ -3656,20 +3675,21 @@ static void ath10k_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ enum ath10k_hw_txrx_mode txmode;

/* We should disable CCK RATE due to P2P */
if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");

+ txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
+
ATH10K_SKB_CB(skb)->htt.is_offchan = false;
ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
- ATH10K_SKB_CB(skb)->txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta,
- skb);

- switch (ATH10K_SKB_CB(skb)->txmode) {
+ switch (txmode) {
case ATH10K_HW_TXRX_MGMT:
case ATH10K_HW_TXRX_NATIVE_WIFI:
ath10k_tx_h_nwifi(hw, skb);
@@ -3706,7 +3726,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
}
}

- ath10k_mac_tx(ar, skb);
+ ath10k_mac_tx(ar, txmode, skb);
}

/* Must not be called with conf_mutex held as workers can use that also. */
--
2.1.4


2015-11-10 13:13:03

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v2 0/9] ath10k: clean up ath10k_skb_cb

The ath10k_skb_cb structure wasn't really space
efficient. Some stuff is removed or replaced with
more compact representation.

This cleanup is necessary for future features.

The size of ath10k_skb_cb:

before after
x86-32 26 12
x86-64 34 20


v2:
* fix a bug (patch 7/9 introduced)


Michal Kazior (9):
ath10k: merge is_protected with nohwcrypt
ath10k: rename function to adhere to naming convention
ath10k: remove txmode from skb_cb
ath10k: remove is_offchan
ath10k: remove freq from skb_cb
ath10k: pack up flags in skb_cb
ath10k: fix tx header parsing
ath10k: replace vdev_id and tid in skb cb
ath10k: store msdu_id instead of txbuf pointers

drivers/net/wireless/ath/ath10k/core.h | 28 +++-----
drivers/net/wireless/ath/ath10k/htt.h | 4 +-
drivers/net/wireless/ath/ath10k/htt_tx.c | 112 ++++++++++++++++++-----------
drivers/net/wireless/ath/ath10k/mac.c | 119 ++++++++++++++++---------------
drivers/net/wireless/ath/ath10k/mac.h | 1 +
drivers/net/wireless/ath/ath10k/txrx.c | 15 ++--
drivers/net/wireless/ath/ath10k/wmi.c | 22 ++++--
7 files changed, 173 insertions(+), 128 deletions(-)

--
2.1.4


2015-11-10 13:13:11

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v2 6/9] ath10k: pack up flags in skb_cb

It was wasteful to have all the flags as separate
bools.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 13 +++++++------
drivers/net/wireless/ath/ath10k/htt_tx.c | 4 ++--
drivers/net/wireless/ath/ath10k/mac.c | 10 +++++++---
drivers/net/wireless/ath/ath10k/wmi.c | 12 ++++++++----
4 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 3706b0d235ca..1e8b5adeac37 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -81,22 +81,23 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus)
return "unknown";
}

+enum ath10k_skb_flags {
+ ATH10K_SKB_F_NO_HWCRYPT = BIT(0),
+ ATH10K_SKB_F_DTIM_ZERO = BIT(1),
+ ATH10K_SKB_F_DELIVER_CAB = BIT(2),
+};
+
struct ath10k_skb_cb {
dma_addr_t paddr;
+ u8 flags;
u8 eid;
u8 vdev_id;

struct {
u8 tid;
- bool nohwcrypt;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
} __packed htt;
-
- struct {
- bool dtim_zero;
- bool deliver_cab;
- } bcn;
} __packed;

struct ath10k_skb_rxcb {
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 51c40d52bbe9..3d1c46a82895 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -586,7 +586,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
- } else if (!skb_cb->htt.nohwcrypt &&
+ } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
txmode == ATH10K_HW_TXRX_RAW &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
@@ -666,7 +666,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
prefetch_len);
skb_cb->htt.txbuf->htc_hdr.flags = 0;

- if (skb_cb->htt.nohwcrypt)
+ if (skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;

flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 3abd684ccd1b..07b67c9132f6 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3668,6 +3668,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
struct ath10k *ar = hw->priv;
+ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
@@ -3680,9 +3681,12 @@ static void ath10k_tx(struct ieee80211_hw *hw,

txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);

- ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
- ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
- ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
+ skb_cb->flags = 0;
+ if (!ath10k_tx_h_use_hwcrypto(vif, skb))
+ skb_cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
+
+ skb_cb->htt.tid = ath10k_tx_h_get_tid(hdr);
+ skb_cb->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);

switch (txmode) {
case ATH10K_HW_TXRX_MGMT:
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 56806d94e65e..854136e0d6c8 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1715,6 +1715,8 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
struct ath10k *ar = arvif->ar;
struct ath10k_skb_cb *cb;
struct sk_buff *bcn;
+ bool dtim_zero;
+ bool deliver_cab;
int ret;

spin_lock_bh(&ar->data_lock);
@@ -1734,12 +1736,14 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
arvif->beacon_state = ATH10K_BEACON_SENDING;
spin_unlock_bh(&ar->data_lock);

+ dtim_zero = !!(cb->flags & ATH10K_SKB_F_DTIM_ZERO);
+ deliver_cab = !!(cb->flags & ATH10K_SKB_F_DELIVER_CAB);
ret = ath10k_wmi_beacon_send_ref_nowait(arvif->ar,
arvif->vdev_id,
bcn->data, bcn->len,
cb->paddr,
- cb->bcn.dtim_zero,
- cb->bcn.deliver_cab);
+ dtim_zero,
+ deliver_cab);

spin_lock_bh(&ar->data_lock);

@@ -3157,10 +3161,10 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len);

if (tim->dtim_count == 0) {
- ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true;
+ ATH10K_SKB_CB(bcn)->flags |= ATH10K_SKB_F_DTIM_ZERO;

if (__le32_to_cpu(tim_info->tim_mcast) == 1)
- ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true;
+ ATH10K_SKB_CB(bcn)->flags |= ATH10K_SKB_F_DELIVER_CAB;
}

ath10k_dbg(ar, ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n",
--
2.1.4


2015-11-02 14:04:09

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 6/8] ath10k: pack up flags in skb_cb

It was wasteful to have all the flags as separate
bools.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 13 +++++++------
drivers/net/wireless/ath/ath10k/htt_tx.c | 4 ++--
drivers/net/wireless/ath/ath10k/mac.c | 10 +++++++---
drivers/net/wireless/ath/ath10k/wmi.c | 12 ++++++++----
4 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 64a248f780b9..59ec9a8098d0 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -81,22 +81,23 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus)
return "unknown";
}

+enum ath10k_skb_flags {
+ ATH10K_SKB_F_NO_HWCRYPT = BIT(0),
+ ATH10K_SKB_F_DTIM_ZERO = BIT(1),
+ ATH10K_SKB_F_DELIVER_CAB = BIT(2),
+};
+
struct ath10k_skb_cb {
dma_addr_t paddr;
+ u8 flags;
u8 eid;
u8 vdev_id;

struct {
u8 tid;
- bool nohwcrypt;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
} __packed htt;
-
- struct {
- bool dtim_zero;
- bool deliver_cab;
- } bcn;
} __packed;

struct ath10k_skb_rxcb {
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 05ce99ad6ca2..a572576bf6c4 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -579,7 +579,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
- } else if (!skb_cb->htt.nohwcrypt &&
+ } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
txmode == ATH10K_HW_TXRX_RAW &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
@@ -659,7 +659,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
prefetch_len);
skb_cb->htt.txbuf->htc_hdr.flags = 0;

- if (skb_cb->htt.nohwcrypt)
+ if (skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;

flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index ddf2ad2f3955..105a2e61c2ae 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3661,6 +3661,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
struct ath10k *ar = hw->priv;
+ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
@@ -3673,9 +3674,12 @@ static void ath10k_tx(struct ieee80211_hw *hw,

txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);

- ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
- ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
- ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
+ skb_cb->flags = 0;
+ if (!ath10k_tx_h_use_hwcrypto(vif, skb))
+ skb_cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
+
+ skb_cb->htt.tid = ath10k_tx_h_get_tid(hdr);
+ skb_cb->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);

switch (txmode) {
case ATH10K_HW_TXRX_MGMT:
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 7569db0f69b5..022d42d29486 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1660,6 +1660,8 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
struct ath10k *ar = arvif->ar;
struct ath10k_skb_cb *cb;
struct sk_buff *bcn;
+ bool dtim_zero;
+ bool deliver_cab;
int ret;

spin_lock_bh(&ar->data_lock);
@@ -1679,12 +1681,14 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
arvif->beacon_state = ATH10K_BEACON_SENDING;
spin_unlock_bh(&ar->data_lock);

+ dtim_zero = !!(cb->flags & ATH10K_SKB_F_DTIM_ZERO);
+ deliver_cab = !!(cb->flags & ATH10K_SKB_F_DELIVER_CAB);
ret = ath10k_wmi_beacon_send_ref_nowait(arvif->ar,
arvif->vdev_id,
bcn->data, bcn->len,
cb->paddr,
- cb->bcn.dtim_zero,
- cb->bcn.deliver_cab);
+ dtim_zero,
+ deliver_cab);

spin_lock_bh(&ar->data_lock);

@@ -3115,10 +3119,10 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len);

if (tim->dtim_count == 0) {
- ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true;
+ ATH10K_SKB_CB(bcn)->flags |= ATH10K_SKB_F_DTIM_ZERO;

if (__le32_to_cpu(tim_info->tim_mcast) == 1)
- ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true;
+ ATH10K_SKB_CB(bcn)->flags |= ATH10K_SKB_F_DELIVER_CAB;
}

ath10k_dbg(ar, ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n",
--
2.1.4


2015-11-18 05:59:33

by Michal Kazior

[permalink] [raw]
Subject: [PATCH v3 2/9] ath10k: rename function to adhere to naming convention

All functions should have ath10k_{filename}_
prefixes.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/mac.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index ab2e5677f771..be323ad537ad 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3149,8 +3149,10 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
}

static enum ath10k_hw_txrx_mode
-ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, struct sk_buff *skb)
+ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb)
{
const struct ieee80211_hdr *hdr = (void *)skb->data;
__le16 fc = hdr->frame_control;
@@ -3664,7 +3666,8 @@ static void ath10k_tx(struct ieee80211_hw *hw,
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
- ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
+ ATH10K_SKB_CB(skb)->txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta,
+ skb);

switch (ATH10K_SKB_CB(skb)->txmode) {
case ATH10K_HW_TXRX_MGMT:
--
2.1.4


2015-11-02 14:04:07

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 4/8] ath10k: remove is_offchan

It was wasteful to keep it in the struct.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 -
drivers/net/wireless/ath/ath10k/mac.c | 4 +---
drivers/net/wireless/ath/ath10k/mac.h | 1 +
drivers/net/wireless/ath/ath10k/txrx.c | 7 ++++++-
4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index efc34b1412b4..f24a5feb2220 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -89,7 +89,6 @@ struct ath10k_skb_cb {
struct {
u8 tid;
u16 freq;
- bool is_offchan;
bool nohwcrypt;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index dd24bc970b00..9c76934b3bf0 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3290,7 +3290,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
}
}

-static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
+bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
{
/* FIXME: Not really sure since when the behaviour changed. At some
* point new firmware stopped requiring creation of peer entries for
@@ -3672,7 +3672,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,

txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);

- ATH10K_SKB_CB(skb)->htt.is_offchan = false;
ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
@@ -3704,7 +3703,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,

if (ath10k_mac_need_offchan_tx_work(ar)) {
ATH10K_SKB_CB(skb)->htt.freq = 0;
- ATH10K_SKB_CB(skb)->htt.is_offchan = true;

ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
skb);
diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h
index e3cefe4c7cfd..ff09d6986fae 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -58,6 +58,7 @@ bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
u8 keyidx);
int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
struct cfg80211_chan_def *def);
+bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar);

void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb);
void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id);
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 6d1105ab4592..655947bef6cc 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -23,7 +23,12 @@

static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)
{
- if (!ATH10K_SKB_CB(skb)->htt.is_offchan)
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+ if (likely(!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)))
+ return;
+
+ if (!ath10k_mac_need_offchan_tx_work(ar))
return;

/* If the original wait_for_completion() timed out before
--
2.1.4