Commit d023a228 authored by Benjamin Berg's avatar Benjamin Berg Committed by Johannes Berg

wifi: iwlwifi: return a new allocation for hdr page space

Instead of returning the pointer to the structure describing the header
page, return the pointer to the newly allocated area. This disentangles
the user from the allocation within the page as it does not need to
advance the position itself.
Signed-off-by: default avatarBenjamin Berg <benjamin.berg@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Link: https://patch.msgid.link/20240703125541.044f2cb373f1.I52a807ac6f311b89530e18deacc7452638a6f5d8@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent f27579ff
...@@ -623,8 +623,8 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans); ...@@ -623,8 +623,8 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq,
int slots_num, bool cmd_queue); int slots_num, bool cmd_queue);
struct iwl_tso_hdr_page *iwl_pcie_get_page_hdr(struct iwl_trans *trans, void *iwl_pcie_get_page_hdr(struct iwl_trans *trans, size_t len,
size_t len, struct sk_buff *skb); struct sk_buff *skb);
void iwl_pcie_free_tso_page(struct iwl_trans *trans, struct sk_buff *skb); void iwl_pcie_free_tso_page(struct iwl_trans *trans, struct sk_buff *skb);
static inline dma_addr_t static inline dma_addr_t
......
...@@ -130,7 +130,6 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans, ...@@ -130,7 +130,6 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans,
unsigned int mss = skb_shinfo(skb)->gso_size; unsigned int mss = skb_shinfo(skb)->gso_size;
u16 length, amsdu_pad; u16 length, amsdu_pad;
u8 *start_hdr; u8 *start_hdr;
struct iwl_tso_hdr_page *hdr_page;
struct tso_t tso; struct tso_t tso;
trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd), trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd),
...@@ -146,12 +145,10 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans, ...@@ -146,12 +145,10 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans,
(3 + snap_ip_tcp_hdrlen + sizeof(struct ethhdr)); (3 + snap_ip_tcp_hdrlen + sizeof(struct ethhdr));
/* Our device supports 9 segments at most, it will fit in 1 page */ /* Our device supports 9 segments at most, it will fit in 1 page */
hdr_page = iwl_pcie_get_page_hdr(trans, hdr_room, skb); start_hdr = iwl_pcie_get_page_hdr(trans, hdr_room, skb);
if (!hdr_page) if (!start_hdr)
return -ENOMEM; return -ENOMEM;
start_hdr = hdr_page->pos;
/* /*
* Pull the ieee80211 header to be able to use TSO core, * Pull the ieee80211 header to be able to use TSO core,
* we will restore it for the tx_status flow. * we will restore it for the tx_status flow.
...@@ -172,32 +169,32 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans, ...@@ -172,32 +169,32 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans,
unsigned int data_left = min_t(unsigned int, mss, total_len); unsigned int data_left = min_t(unsigned int, mss, total_len);
unsigned int tb_len; unsigned int tb_len;
dma_addr_t tb_phys; dma_addr_t tb_phys;
u8 *subf_hdrs_start = hdr_page->pos; u8 *pos_hdr = start_hdr;
total_len -= data_left; total_len -= data_left;
memset(hdr_page->pos, 0, amsdu_pad); memset(pos_hdr, 0, amsdu_pad);
hdr_page->pos += amsdu_pad; pos_hdr += amsdu_pad;
amsdu_pad = (4 - (sizeof(struct ethhdr) + snap_ip_tcp_hdrlen + amsdu_pad = (4 - (sizeof(struct ethhdr) + snap_ip_tcp_hdrlen +
data_left)) & 0x3; data_left)) & 0x3;
ether_addr_copy(hdr_page->pos, ieee80211_get_DA(hdr)); ether_addr_copy(pos_hdr, ieee80211_get_DA(hdr));
hdr_page->pos += ETH_ALEN; pos_hdr += ETH_ALEN;
ether_addr_copy(hdr_page->pos, ieee80211_get_SA(hdr)); ether_addr_copy(pos_hdr, ieee80211_get_SA(hdr));
hdr_page->pos += ETH_ALEN; pos_hdr += ETH_ALEN;
length = snap_ip_tcp_hdrlen + data_left; length = snap_ip_tcp_hdrlen + data_left;
*((__be16 *)hdr_page->pos) = cpu_to_be16(length); *((__be16 *)pos_hdr) = cpu_to_be16(length);
hdr_page->pos += sizeof(length); pos_hdr += sizeof(length);
/* /*
* This will copy the SNAP as well which will be considered * This will copy the SNAP as well which will be considered
* as MAC header. * as MAC header.
*/ */
tso_build_hdr(skb, hdr_page->pos, &tso, data_left, !total_len); tso_build_hdr(skb, pos_hdr, &tso, data_left, !total_len);
hdr_page->pos += snap_ip_tcp_hdrlen; pos_hdr += snap_ip_tcp_hdrlen;
tb_len = hdr_page->pos - start_hdr; tb_len = pos_hdr - start_hdr;
tb_phys = dma_map_single(trans->dev, start_hdr, tb_phys = dma_map_single(trans->dev, start_hdr,
tb_len, DMA_TO_DEVICE); tb_len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(trans->dev, tb_phys))) if (unlikely(dma_mapping_error(trans->dev, tb_phys)))
...@@ -211,10 +208,10 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans, ...@@ -211,10 +208,10 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans,
trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_hdr, trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_hdr,
tb_phys, tb_len); tb_phys, tb_len);
/* add this subframe's headers' length to the tx_cmd */ /* add this subframe's headers' length to the tx_cmd */
le16_add_cpu(&tx_cmd->len, hdr_page->pos - subf_hdrs_start); le16_add_cpu(&tx_cmd->len, tb_len);
/* prepare the start_hdr for the next subframe */ /* prepare the start_hdr for the next subframe */
start_hdr = hdr_page->pos; start_hdr = pos_hdr;
/* put the payload */ /* put the payload */
while (data_left) { while (data_left) {
......
...@@ -1702,12 +1702,13 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -1702,12 +1702,13 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb,
} }
#ifdef CONFIG_INET #ifdef CONFIG_INET
struct iwl_tso_hdr_page *iwl_pcie_get_page_hdr(struct iwl_trans *trans, void *iwl_pcie_get_page_hdr(struct iwl_trans *trans,
size_t len, struct sk_buff *skb) size_t len, struct sk_buff *skb)
{ {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_tso_hdr_page *p = this_cpu_ptr(trans_pcie->txqs.tso_hdr_page); struct iwl_tso_hdr_page *p = this_cpu_ptr(trans_pcie->txqs.tso_hdr_page);
struct page **page_ptr; struct page **page_ptr;
void *ret;
page_ptr = (void *)((u8 *)skb->cb + trans_pcie->txqs.page_offs); page_ptr = (void *)((u8 *)skb->cb + trans_pcie->txqs.page_offs);
...@@ -1744,7 +1745,10 @@ struct iwl_tso_hdr_page *iwl_pcie_get_page_hdr(struct iwl_trans *trans, ...@@ -1744,7 +1745,10 @@ struct iwl_tso_hdr_page *iwl_pcie_get_page_hdr(struct iwl_trans *trans,
out: out:
*page_ptr = p->page; *page_ptr = p->page;
get_page(p->page); get_page(p->page);
return p; ret = p->pos;
p->pos += len;
return ret;
} }
static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
...@@ -1759,8 +1763,7 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -1759,8 +1763,7 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room; unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room;
unsigned int mss = skb_shinfo(skb)->gso_size; unsigned int mss = skb_shinfo(skb)->gso_size;
u16 length, iv_len, amsdu_pad; u16 length, iv_len, amsdu_pad;
u8 *start_hdr; u8 *start_hdr, *pos_hdr;
struct iwl_tso_hdr_page *hdr_page;
struct tso_t tso; struct tso_t tso;
/* if the packet is protected, then it must be CCMP or GCMP */ /* if the packet is protected, then it must be CCMP or GCMP */
...@@ -1783,13 +1786,12 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -1783,13 +1786,12 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
(3 + snap_ip_tcp_hdrlen + sizeof(struct ethhdr)) + iv_len; (3 + snap_ip_tcp_hdrlen + sizeof(struct ethhdr)) + iv_len;
/* Our device supports 9 segments at most, it will fit in 1 page */ /* Our device supports 9 segments at most, it will fit in 1 page */
hdr_page = iwl_pcie_get_page_hdr(trans, hdr_room, skb); pos_hdr = start_hdr = iwl_pcie_get_page_hdr(trans, hdr_room, skb);
if (!hdr_page) if (!start_hdr)
return -ENOMEM; return -ENOMEM;
start_hdr = hdr_page->pos; memcpy(pos_hdr, skb->data + hdr_len, iv_len);
memcpy(hdr_page->pos, skb->data + hdr_len, iv_len); pos_hdr += iv_len;
hdr_page->pos += iv_len;
/* /*
* Pull the ieee80211 header + IV to be able to use TSO core, * Pull the ieee80211 header + IV to be able to use TSO core,
...@@ -1812,32 +1814,32 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -1812,32 +1814,32 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
min_t(unsigned int, mss, total_len); min_t(unsigned int, mss, total_len);
unsigned int hdr_tb_len; unsigned int hdr_tb_len;
dma_addr_t hdr_tb_phys; dma_addr_t hdr_tb_phys;
u8 *subf_hdrs_start = hdr_page->pos; u8 *subf_hdrs_start = pos_hdr;
total_len -= data_left; total_len -= data_left;
memset(hdr_page->pos, 0, amsdu_pad); memset(pos_hdr, 0, amsdu_pad);
hdr_page->pos += amsdu_pad; pos_hdr += amsdu_pad;
amsdu_pad = (4 - (sizeof(struct ethhdr) + snap_ip_tcp_hdrlen + amsdu_pad = (4 - (sizeof(struct ethhdr) + snap_ip_tcp_hdrlen +
data_left)) & 0x3; data_left)) & 0x3;
ether_addr_copy(hdr_page->pos, ieee80211_get_DA(hdr)); ether_addr_copy(pos_hdr, ieee80211_get_DA(hdr));
hdr_page->pos += ETH_ALEN; pos_hdr += ETH_ALEN;
ether_addr_copy(hdr_page->pos, ieee80211_get_SA(hdr)); ether_addr_copy(pos_hdr, ieee80211_get_SA(hdr));
hdr_page->pos += ETH_ALEN; pos_hdr += ETH_ALEN;
length = snap_ip_tcp_hdrlen + data_left; length = snap_ip_tcp_hdrlen + data_left;
*((__be16 *)hdr_page->pos) = cpu_to_be16(length); *((__be16 *)pos_hdr) = cpu_to_be16(length);
hdr_page->pos += sizeof(length); pos_hdr += sizeof(length);
/* /*
* This will copy the SNAP as well which will be considered * This will copy the SNAP as well which will be considered
* as MAC header. * as MAC header.
*/ */
tso_build_hdr(skb, hdr_page->pos, &tso, data_left, !total_len); tso_build_hdr(skb, pos_hdr, &tso, data_left, !total_len);
hdr_page->pos += snap_ip_tcp_hdrlen; pos_hdr += snap_ip_tcp_hdrlen;
hdr_tb_len = hdr_page->pos - start_hdr; hdr_tb_len = pos_hdr - start_hdr;
hdr_tb_phys = dma_map_single(trans->dev, start_hdr, hdr_tb_phys = dma_map_single(trans->dev, start_hdr,
hdr_tb_len, DMA_TO_DEVICE); hdr_tb_len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(trans->dev, hdr_tb_phys))) if (unlikely(dma_mapping_error(trans->dev, hdr_tb_phys)))
...@@ -1847,10 +1849,10 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -1847,10 +1849,10 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_hdr, trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_hdr,
hdr_tb_phys, hdr_tb_len); hdr_tb_phys, hdr_tb_len);
/* add this subframe's headers' length to the tx_cmd */ /* add this subframe's headers' length to the tx_cmd */
le16_add_cpu(&tx_cmd->len, hdr_page->pos - subf_hdrs_start); le16_add_cpu(&tx_cmd->len, pos_hdr - subf_hdrs_start);
/* prepare the start_hdr for the next subframe */ /* prepare the start_hdr for the next subframe */
start_hdr = hdr_page->pos; start_hdr = pos_hdr;
/* put the payload */ /* put the payload */
while (data_left) { while (data_left) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment