igb: fix max RX packet size and support dual VLAN
authorIntel <intel.com>
Mon, 3 Jun 2013 00:00:00 +0000 (00:00 +0000)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Tue, 17 Sep 2013 12:16:07 +0000 (14:16 +0200)
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
lib/librte_pmd_e1000/igb_rxtx.c

index 735c968..f9b03eb 100644 (file)
@@ -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
index 3dd5156..dd24788 100644 (file)
@@ -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;
                        }