Commit 7b02bf61 authored by Johannes Berg's avatar Johannes Berg Committed by Luca Coelho

iwlwifi: pcie: move page tracking into get_page_hdr()

Move the tracking that records the page in the SKB for later
free (refcount decrement) into the get_page_hdr() function
for better code reuse.

While at it, also add an assertion that this doesn't overwrite
any existing page pointer in the skb.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 160bab43
...@@ -1082,7 +1082,8 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans); ...@@ -1082,7 +1082,8 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans);
void iwl_pcie_free_tso_page(struct iwl_trans_pcie *trans_pcie, void iwl_pcie_free_tso_page(struct iwl_trans_pcie *trans_pcie,
struct sk_buff *skb); struct sk_buff *skb);
#ifdef CONFIG_INET #ifdef CONFIG_INET
struct iwl_tso_hdr_page *get_page_hdr(struct iwl_trans *trans, size_t len); struct iwl_tso_hdr_page *get_page_hdr(struct iwl_trans *trans, size_t len,
struct sk_buff *skb);
#endif #endif
/* common functions that are used by gen3 transport */ /* common functions that are used by gen3 transport */
......
...@@ -246,7 +246,6 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans *trans, ...@@ -246,7 +246,6 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans *trans,
u8 hdr_len, struct iwl_device_cmd *dev_cmd) u8 hdr_len, struct iwl_device_cmd *dev_cmd)
{ {
#ifdef CONFIG_INET #ifdef CONFIG_INET
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_tx_cmd_gen2 *tx_cmd = (void *)dev_cmd->payload; struct iwl_tx_cmd_gen2 *tx_cmd = (void *)dev_cmd->payload;
struct ieee80211_hdr *hdr = (void *)skb->data; struct ieee80211_hdr *hdr = (void *)skb->data;
unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room; unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room;
...@@ -254,7 +253,6 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans *trans, ...@@ -254,7 +253,6 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans *trans,
u16 length, amsdu_pad; u16 length, amsdu_pad;
u8 *start_hdr; u8 *start_hdr;
struct iwl_tso_hdr_page *hdr_page; struct iwl_tso_hdr_page *hdr_page;
struct page **page_ptr;
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),
...@@ -270,14 +268,11 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans *trans, ...@@ -270,14 +268,11 @@ static int iwl_pcie_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 = get_page_hdr(trans, hdr_room); hdr_page = get_page_hdr(trans, hdr_room, skb);
if (!hdr_page) if (!hdr_page)
return -ENOMEM; return -ENOMEM;
get_page(hdr_page->page);
start_hdr = hdr_page->pos; start_hdr = hdr_page->pos;
page_ptr = (void *)((u8 *)skb->cb + trans_pcie->page_offs);
*page_ptr = hdr_page->page;
/* /*
* Pull the ieee80211 header to be able to use TSO core, * Pull the ieee80211 header to be able to use TSO core,
......
...@@ -2052,17 +2052,24 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -2052,17 +2052,24 @@ 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 *get_page_hdr(struct iwl_trans *trans, size_t len) struct iwl_tso_hdr_page *get_page_hdr(struct iwl_trans *trans, 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->tso_hdr_page); struct iwl_tso_hdr_page *p = this_cpu_ptr(trans_pcie->tso_hdr_page);
struct page **page_ptr;
page_ptr = (void *)((u8 *)skb->cb + trans_pcie->page_offs);
if (WARN_ON(*page_ptr))
return NULL;
if (!p->page) if (!p->page)
goto alloc; goto alloc;
/* enough room on this page */ /* enough room on this page */
if (p->pos + len < (u8 *)page_address(p->page) + PAGE_SIZE) if (p->pos + len < (u8 *)page_address(p->page) + PAGE_SIZE)
return p; goto out;
/* We don't have enough room on this page, get a new one. */ /* We don't have enough room on this page, get a new one. */
__free_page(p->page); __free_page(p->page);
...@@ -2072,6 +2079,9 @@ struct iwl_tso_hdr_page *get_page_hdr(struct iwl_trans *trans, size_t len) ...@@ -2072,6 +2079,9 @@ struct iwl_tso_hdr_page *get_page_hdr(struct iwl_trans *trans, size_t len)
if (!p->page) if (!p->page)
return NULL; return NULL;
p->pos = page_address(p->page); p->pos = page_address(p->page);
out:
*page_ptr = p->page;
get_page(p->page);
return p; return p;
} }
...@@ -2107,7 +2117,6 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -2107,7 +2117,6 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
u16 length, iv_len, amsdu_pad; u16 length, iv_len, amsdu_pad;
u8 *start_hdr; u8 *start_hdr;
struct iwl_tso_hdr_page *hdr_page; struct iwl_tso_hdr_page *hdr_page;
struct page **page_ptr;
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 */
...@@ -2130,14 +2139,11 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -2130,14 +2139,11 @@ 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 = get_page_hdr(trans, hdr_room); hdr_page = get_page_hdr(trans, hdr_room, skb);
if (!hdr_page) if (!hdr_page)
return -ENOMEM; return -ENOMEM;
get_page(hdr_page->page);
start_hdr = hdr_page->pos; start_hdr = hdr_page->pos;
page_ptr = (void *)((u8 *)skb->cb + trans_pcie->page_offs);
*page_ptr = hdr_page->page;
memcpy(hdr_page->pos, skb->data + hdr_len, iv_len); memcpy(hdr_page->pos, skb->data + hdr_len, iv_len);
hdr_page->pos += iv_len; hdr_page->pos += iv_len;
......
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