From: Jose Abreu <Jose.Abreu@synopsys.com>
To: netdev@vger.kernel.org
Cc: Joao Pinto <Joao.Pinto@synopsys.com>,
Jose Abreu <Jose.Abreu@synopsys.com>,
Giuseppe Cavallaro <peppe.cavallaro@st.com>,
Alexandre Torgue <alexandre.torgue@st.com>,
"David S. Miller" <davem@davemloft.net>,
Maxime Coquelin <mcoquelin.stm32@gmail.com>,
linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: [PATCH net-next 15/26] net: stmmac: Prepare to add Split Header support
Date: Mon, 5 Aug 2019 18:44:42 +0200 [thread overview]
Message-ID: <b46739b2adc5372d710686e5c47c2f8021837916.1565022597.git.joabreu@synopsys.com> (raw)
In-Reply-To: <cover.1565022597.git.joabreu@synopsys.com>
In-Reply-To: <cover.1565022597.git.joabreu@synopsys.com>
In order to add Split Header support, stmmac_rx() needs to take into
account that packet may be split accross multiple descriptors.
Refactor the logic of this function in order to support this scenario.
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
---
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Jose Abreu <joabreu@synopsys.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: netdev@vger.kernel.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 +
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 149 +++++++++++++---------
2 files changed, 95 insertions(+), 60 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 4179559b11ad..be9ee3d7ec35 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -74,6 +74,12 @@ struct stmmac_rx_queue {
u32 rx_zeroc_thresh;
dma_addr_t dma_rx_phy;
u32 rx_tail_addr;
+ unsigned int state_saved;
+ struct {
+ struct sk_buff *skb;
+ unsigned int len;
+ unsigned int error;
+ } state;
};
struct stmmac_channel {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 075de483ce7b..e1ef8de952cc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3359,9 +3359,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
{
struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
struct stmmac_channel *ch = &priv->channel[queue];
+ unsigned int count = 0, error = 0, len = 0;
+ int status = 0, coe = priv->hw->rx_csum;
unsigned int next_entry = rx_q->cur_rx;
- int coe = priv->hw->rx_csum;
- unsigned int count = 0;
+ struct sk_buff *skb = NULL;
if (netif_msg_rx_status(priv)) {
void *rx_head;
@@ -3375,9 +3376,27 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
stmmac_display_ring(priv, rx_head, DMA_RX_SIZE, true);
}
while (count < limit) {
+ enum pkt_hash_types hash_type;
struct stmmac_rx_buffer *buf;
+ unsigned int prev_len = 0;
struct dma_desc *np, *p;
- int entry, status;
+ int entry;
+ u32 hash;
+
+ if (!count && rx_q->state_saved) {
+ skb = rx_q->state.skb;
+ error = rx_q->state.error;
+ len = rx_q->state.len;
+ } else {
+ rx_q->state_saved = false;
+ skb = NULL;
+ error = 0;
+ len = 0;
+ }
+
+read_again:
+ if (count >= limit)
+ break;
entry = next_entry;
buf = &rx_q->buf_pool[entry];
@@ -3413,28 +3432,24 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
page_pool_recycle_direct(rx_q->page_pool, buf->page);
priv->dev->stats.rx_errors++;
buf->page = NULL;
+ error = 1;
+ }
+
+ if (unlikely(error & (status & rx_not_ls)))
+ goto read_again;
+ if (unlikely(error)) {
+ if (skb)
+ dev_kfree_skb(skb);
+ continue;
+ }
+
+ /* Buffer is good. Go on. */
+
+ if (likely(status & rx_not_ls)) {
+ len += priv->dma_buf_sz;
} else {
- enum pkt_hash_types hash_type;
- struct sk_buff *skb;
- unsigned int des;
- int frame_len;
- u32 hash;
-
- stmmac_get_desc_addr(priv, p, &des);
- frame_len = stmmac_get_rx_frame_len(priv, p, coe);
-
- /* If frame length is greater than skb buffer size
- * (preallocated during init) then the packet is
- * ignored
- */
- if (frame_len > priv->dma_buf_sz) {
- if (net_ratelimit())
- netdev_err(priv->dev,
- "len %d larger than size (%d)\n",
- frame_len, priv->dma_buf_sz);
- priv->dev->stats.rx_length_errors++;
- continue;
- }
+ prev_len = len;
+ len = stmmac_get_rx_frame_len(priv, p, coe);
/* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
* Type frames (LLC/LLC-SNAP)
@@ -3445,57 +3460,71 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
*/
if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00) ||
unlikely(status != llc_snap))
- frame_len -= ETH_FCS_LEN;
-
- if (netif_msg_rx_status(priv)) {
- netdev_dbg(priv->dev, "\tdesc: %p [entry %d] buff=0x%x\n",
- p, entry, des);
- netdev_dbg(priv->dev, "frame size %d, COE: %d\n",
- frame_len, status);
- }
+ len -= ETH_FCS_LEN;
+ }
- skb = netdev_alloc_skb_ip_align(priv->dev, frame_len);
- if (unlikely(!skb)) {
+ if (!skb) {
+ skb = netdev_alloc_skb_ip_align(priv->dev, len);
+ if (!skb) {
priv->dev->stats.rx_dropped++;
continue;
}
- dma_sync_single_for_cpu(priv->device, buf->addr,
- frame_len, DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(priv->device, buf->addr, len,
+ DMA_FROM_DEVICE);
skb_copy_to_linear_data(skb, page_address(buf->page),
- frame_len);
- skb_put(skb, frame_len);
+ len);
+ skb_put(skb, len);
- if (netif_msg_pktdata(priv)) {
- netdev_dbg(priv->dev, "frame received (%dbytes)",
- frame_len);
- print_pkt(skb->data, frame_len);
- }
+ /* Data payload copied into SKB, page ready for recycle */
+ page_pool_recycle_direct(rx_q->page_pool, buf->page);
+ buf->page = NULL;
+ } else {
+ unsigned int buf_len = len - prev_len;
- stmmac_get_rx_hwtstamp(priv, p, np, skb);
+ if (likely(status & rx_not_ls))
+ buf_len = priv->dma_buf_sz;
- stmmac_rx_vlan(priv->dev, skb);
+ dma_sync_single_for_cpu(priv->device, buf->addr,
+ buf_len, DMA_FROM_DEVICE);
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+ buf->page, 0, buf_len,
+ priv->dma_buf_sz);
- skb->protocol = eth_type_trans(skb, priv->dev);
+ /* Data payload appended into SKB */
+ page_pool_release_page(rx_q->page_pool, buf->page);
+ buf->page = NULL;
+ }
- if (unlikely(!coe))
- skb_checksum_none_assert(skb);
- else
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ if (likely(status & rx_not_ls))
+ goto read_again;
- if (!stmmac_get_rx_hash(priv, p, &hash, &hash_type))
- skb_set_hash(skb, hash, hash_type);
+ /* Got entire packet into SKB. Finish it. */
- skb_record_rx_queue(skb, queue);
- napi_gro_receive(&ch->rx_napi, skb);
+ stmmac_get_rx_hwtstamp(priv, p, np, skb);
+ stmmac_rx_vlan(priv->dev, skb);
+ skb->protocol = eth_type_trans(skb, priv->dev);
- /* Data payload copied into SKB, page ready for recycle */
- page_pool_recycle_direct(rx_q->page_pool, buf->page);
- buf->page = NULL;
+ if (unlikely(!coe))
+ skb_checksum_none_assert(skb);
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
- priv->dev->stats.rx_packets++;
- priv->dev->stats.rx_bytes += frame_len;
- }
+ if (!stmmac_get_rx_hash(priv, p, &hash, &hash_type))
+ skb_set_hash(skb, hash, hash_type);
+
+ skb_record_rx_queue(skb, queue);
+ napi_gro_receive(&ch->rx_napi, skb);
+
+ priv->dev->stats.rx_packets++;
+ priv->dev->stats.rx_bytes += len;
+ }
+
+ if (status & rx_not_ls) {
+ rx_q->state_saved = true;
+ rx_q->state.skb = skb;
+ rx_q->state.error = error;
+ rx_q->state.len = len;
}
stmmac_rx_refill(priv, queue);
--
2.7.4
next prev parent reply other threads:[~2019-08-05 16:45 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-05 16:44 [PATCH net-next 00/26] net: stmmac: Misc improvements for XGMAC Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 01/26] net: stmmac: xgmac: Fix XGMAC selftests Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 02/26] net: stmmac: xgmac: Implement MMC counters Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 03/26] net: stmmac: Fix issues when number of Queues >= 4 Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 04/26] net: stmmac: xgmac: Implement set_mtl_tx_queue_weight() Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 05/26] net: stmmac: xgmac: Implement tx_queue_prio() Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 06/26] net: stmmac: Implement RSS and enable it in XGMAC core Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 07/26] net: stmmac: selftests: Add RSS test Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 08/26] net: stmmac: Implement VLAN Hash Filtering in XGMAC Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 09/26] net: stmmac: selftests: Add test for VLAN and Double VLAN Filtering Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 10/26] net: stmmac: Implement Safety Features in XGMAC core Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 11/26] net: stmmac: Add Flexible RX Parser support in XGMAC Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 12/26] net: stmmac: tc: Do not return a fragment entry Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 13/26] net: stmmac: selftests: Add a selftest for Flexible RX Parser Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 14/26] net: stmmac: Get correct timestamp values from XGMAC Jose Abreu
2019-08-05 16:44 ` Jose Abreu [this message]
2019-08-05 16:44 ` [PATCH net-next 16/26] net: stmmac: xgmac: Correctly return that RX descriptor is not last one Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 17/26] net: stmmac: Add Split Header support and enable it in XGMAC cores Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 18/26] net: stmmac: dwxgmac: Add Flexible PPS support Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 19/26] net: stmmac: Add ethtool register dump for XGMAC cores Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 20/26] net: stmmac: Add a counter for Split Header packets Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 21/26] net: stmmac: Add support for SA Insertion/Replacement in XGMAC cores Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 22/26] net: stmmac: selftests: Add tests for SA Insertion/Replacement Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 23/26] net: stmmac: xgmac: Add EEE support Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 24/26] net: stmmac: Add support for VLAN Insertion Offload Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 25/26] net: stmmac: selftests: Add selftest for VLAN TX Offload Jose Abreu
2019-08-05 16:44 ` [PATCH net-next 26/26] net: stmmac: selftests: Return proper error code to userspace Jose Abreu
2019-08-05 17:47 ` [PATCH net-next 00/26] net: stmmac: Misc improvements for XGMAC David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b46739b2adc5372d710686e5c47c2f8021837916.1565022597.git.joabreu@synopsys.com \
--to=jose.abreu@synopsys.com \
--cc=Joao.Pinto@synopsys.com \
--cc=alexandre.torgue@st.com \
--cc=davem@davemloft.net \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=mcoquelin.stm32@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=peppe.cavallaro@st.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).