From e51abef393824b73906a80eea5c81f90c7e5dc08 Mon Sep 17 00:00:00 2001 From: Intel Date: Mon, 3 Jun 2013 00:00:00 +0000 Subject: [PATCH] igb: fix max RX packet size and support dual VLAN When in 'normal' mode, hardware is designed to receive up to 1522 bytes. When in 'jumbo' mode, RLPML register must be updated so that hardware accepts a 802.1q vlan header. If dual vlan is enabled, then a second vlan header is expected, so update RLPML register according to dual vlan support. Signed-off-by: Intel --- lib/librte_pmd_e1000/igb_ethdev.c | 20 +++++++++++--------- lib/librte_pmd_e1000/igb_rxtx.c | 17 ++++++++++++----- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c index 735c96850c..f9b03eb227 100644 --- a/lib/librte_pmd_e1000/igb_ethdev.c +++ b/lib/librte_pmd_e1000/igb_ethdev.c @@ -1363,10 +1363,6 @@ igb_vlan_hw_strip_disable(struct rte_eth_dev *dev) reg = E1000_READ_REG(hw, E1000_CTRL); reg &= ~E1000_CTRL_VME; E1000_WRITE_REG(hw, E1000_CTRL, reg); - - /* Update maximum frame size */ - E1000_WRITE_REG(hw, E1000_RLPML, - dev->data->dev_conf.rxmode.max_rx_pkt_len + VLAN_TAG_SIZE); } static void @@ -1380,11 +1376,6 @@ igb_vlan_hw_strip_enable(struct rte_eth_dev *dev) reg = E1000_READ_REG(hw, E1000_CTRL); reg |= E1000_CTRL_VME; E1000_WRITE_REG(hw, E1000_CTRL, reg); - - /* Update maximum frame size */ - E1000_WRITE_REG(hw, E1000_RLPML, - dev->data->dev_conf.rxmode.max_rx_pkt_len); - } static void @@ -1399,6 +1390,11 @@ igb_vlan_hw_extend_disable(struct rte_eth_dev *dev) reg &= ~E1000_CTRL_EXT_EXTEND_VLAN; E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); + /* Update maximum packet length */ + if (dev->data->dev_conf.rxmode.jumbo_frame == 1) + E1000_WRITE_REG(hw, E1000_RLPML, + dev->data->dev_conf.rxmode.max_rx_pkt_len + + VLAN_TAG_SIZE); } static void @@ -1412,6 +1408,12 @@ igb_vlan_hw_extend_enable(struct rte_eth_dev *dev) reg = E1000_READ_REG(hw, E1000_CTRL_EXT); reg |= E1000_CTRL_EXT_EXTEND_VLAN; E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); + + /* Update maximum packet length */ + if (dev->data->dev_conf.rxmode.jumbo_frame == 1) + E1000_WRITE_REG(hw, E1000_RLPML, + dev->data->dev_conf.rxmode.max_rx_pkt_len + + 2 * VLAN_TAG_SIZE); } static void diff --git a/lib/librte_pmd_e1000/igb_rxtx.c b/lib/librte_pmd_e1000/igb_rxtx.c index 3dd5156b16..dd247887f2 100644 --- a/lib/librte_pmd_e1000/igb_rxtx.c +++ b/lib/librte_pmd_e1000/igb_rxtx.c @@ -1608,9 +1608,13 @@ eth_igb_rx_init(struct rte_eth_dev *dev) if (dev->data->dev_conf.rxmode.jumbo_frame == 1) { rctl |= E1000_RCTL_LPE; - /* Set maximum packet length. */ + /* + * Set maximum packet length by default, and might be updated + * together with enabling/disabling dual VLAN. + */ E1000_WRITE_REG(hw, E1000_RLPML, - dev->data->dev_conf.rxmode.max_rx_pkt_len); + dev->data->dev_conf.rxmode.max_rx_pkt_len + + VLAN_TAG_SIZE); } else rctl &= ~E1000_RCTL_LPE; @@ -1667,8 +1671,9 @@ eth_igb_rx_init(struct rte_eth_dev *dev) E1000_SRRCTL_BSIZEPKT_MASK) << E1000_SRRCTL_BSIZEPKT_SHIFT); - if (dev->data->dev_conf.rxmode.max_rx_pkt_len + VLAN_TAG_SIZE - > buf_size){ + /* It adds dual VLAN length for supporting dual VLAN */ + if ((dev->data->dev_conf.rxmode.max_rx_pkt_len + + 2 * VLAN_TAG_SIZE) > buf_size){ dev->rx_pkt_burst = eth_igb_recv_scattered_pkts; dev->data->scattered_rx = 1; } @@ -1912,7 +1917,9 @@ eth_igbvf_rx_init(struct rte_eth_dev *dev) E1000_SRRCTL_BSIZEPKT_MASK) << E1000_SRRCTL_BSIZEPKT_SHIFT); - if (dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size){ + /* It adds dual VLAN length for supporting dual VLAN */ + if ((dev->data->dev_conf.rxmode.max_rx_pkt_len + + 2 * VLAN_TAG_SIZE) > buf_size){ dev->rx_pkt_burst = eth_igb_recv_scattered_pkts; dev->data->scattered_rx = 1; } -- 2.20.1