* [net-next-2.6 13/21] ixgbe: DCB, missed translation from 8021Qaz TSA to CEE link strict
From: Jeff Kirsher @ 2011-03-12 12:20 UTC (permalink / raw)
To: davem; +Cc: John Fastabend, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299932428-3114-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: John Fastabend <john.r.fastabend@intel.com>
The patch below allowed IEEE 802.1Qaz and CEE DCB hardware
configurations to use common hardware set routines,
commit 88eb696cc6a7af8f9272266965b1a4dd7d6a931b
Author: John Fastabend <john.r.fastabend@intel.com>
Date: Thu Feb 10 03:02:11 2011 -0800
ixgbe: DCB, abstract out dcb_config from DCB hardware configuration
However the case when CEE link strict and group strict
are set was missed and are currently being mapped
incorrectly in some configurations.
This patch resolves this.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_dcb.c | 24 +-----------------------
drivers/net/ixgbe/ixgbe_dcb_nl.c | 24 ++++++++++++++++++++++--
2 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c
index c2ee6fc..e2e7a29 100644
--- a/drivers/net/ixgbe/ixgbe_dcb.c
+++ b/drivers/net/ixgbe/ixgbe_dcb.c
@@ -292,30 +292,8 @@ s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en)
}
s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw,
- u16 *refill, u16 *max, u8 *bwg_id, u8 *tsa)
+ u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type)
{
- int i;
- u8 prio_type[IEEE_8021QAZ_MAX_TCS];
-
- /* Map TSA onto CEE prio type */
- for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
- switch (tsa[i]) {
- case IEEE_8021QAZ_TSA_STRICT:
- prio_type[i] = 2;
- break;
- case IEEE_8021QAZ_TSA_ETS:
- prio_type[i] = 0;
- break;
- default:
- /* Hardware only supports priority strict or
- * ETS transmission selection algorithms if
- * we receive some other value from dcbnl
- * throw an error
- */
- return -EINVAL;
- }
- }
-
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max,
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index 91ff51c..8abef8d 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -642,8 +642,9 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
__u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS];
+ __u8 prio_type[IEEE_8021QAZ_MAX_TCS];
int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
- int err;
+ int i, err;
/* naively give each TC a bwg to map onto CEE hardware */
__u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7};
@@ -659,9 +660,28 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets));
+ /* Map TSA onto CEE prio type */
+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+ switch (ets->tc_tsa[i]) {
+ case IEEE_8021QAZ_TSA_STRICT:
+ prio_type[i] = 2;
+ break;
+ case IEEE_8021QAZ_TSA_ETS:
+ prio_type[i] = 0;
+ break;
+ default:
+ /* Hardware only supports priority strict or
+ * ETS transmission selection algorithms if
+ * we receive some other value from dcbnl
+ * throw an error
+ */
+ return -EINVAL;
+ }
+ }
+
ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame);
err = ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max,
- bwg_id, ets->tc_tsa);
+ bwg_id, prio_type);
return err;
}
--
1.7.4
^ permalink raw reply related
* [net-next-2.6 19/21] ixgbe: DCB, set minimum bandwidth per traffic class
From: Jeff Kirsher @ 2011-03-12 12:20 UTC (permalink / raw)
To: davem; +Cc: John Fastabend, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299932428-3114-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: John Fastabend <john.r.fastabend@intel.com>
DCB provides a guaranteed bandwidth in the case with 0%
bandwidth then no bandwidth is guaranteed. However the
traffic class should still be able to transmit traffic.
For this to work the traffic class must be given the
minimum credits required to send a frame.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_dcb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c
index e7b551a..41c529f 100644
--- a/drivers/net/ixgbe/ixgbe_dcb.c
+++ b/drivers/net/ixgbe/ixgbe_dcb.c
@@ -64,7 +64,7 @@ s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill, __u16 *max, int max_frame)
val = min_credit;
refill[i] = val;
- max[i] = (bw[i] * MAX_CREDIT)/100;
+ max[i] = bw[i] ? (bw[i] * MAX_CREDIT)/100 : min_credit;
}
return 0;
}
--
1.7.4
^ permalink raw reply related
* [net-next-2.6 12/21] ixgbe: DCB: enable RSS to be used with DCB
From: Jeff Kirsher @ 2011-03-12 12:20 UTC (permalink / raw)
To: davem; +Cc: John Fastabend, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299932428-3114-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: John Fastabend <john.r.fastabend@intel.com>
RSS had previously been disabled when DCB was enabled because
DCB was single queued per traffic class. Now that DCB implements
multiple Tx/Rx rings per traffic class enable RSS.
Here RSS hashes across the queues in the traffic class.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Tested-by: Ross Brattain <ross.b.brattain.@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_dcb_nl.c | 2 --
drivers/net/ixgbe/ixgbe_main.c | 32 +++++++++++++++++++++++++-------
2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index b7b6db3..91ff51c 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -129,7 +129,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
netdev->netdev_ops->ndo_stop(netdev);
ixgbe_clear_interrupt_scheme(adapter);
- adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
switch (adapter->hw.mac.type) {
case ixgbe_mac_82598EB:
adapter->last_lfc_mode = adapter->hw.fc.current_mode;
@@ -162,7 +161,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
adapter->temp_dcb_cfg.pfc_mode_enable = false;
adapter->dcb_cfg.pfc_mode_enable = false;
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
- adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 3ce0f4f..be2e145 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -2892,17 +2892,20 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
);
switch (mask) {
+#ifdef CONFIG_IXGBE_DCB
+ case (IXGBE_FLAG_DCB_ENABLED | IXGBE_FLAG_RSS_ENABLED):
+ mrqc = IXGBE_MRQC_RTRSS8TCEN;
+ break;
+ case (IXGBE_FLAG_DCB_ENABLED):
+ mrqc = IXGBE_MRQC_RT8TCEN;
+ break;
+#endif /* CONFIG_IXGBE_DCB */
case (IXGBE_FLAG_RSS_ENABLED):
mrqc = IXGBE_MRQC_RSSEN;
break;
case (IXGBE_FLAG_SRIOV_ENABLED):
mrqc = IXGBE_MRQC_VMDQEN;
break;
-#ifdef CONFIG_IXGBE_DCB
- case (IXGBE_FLAG_DCB_ENABLED):
- mrqc = IXGBE_MRQC_RT8TCEN;
- break;
-#endif /* CONFIG_IXGBE_DCB */
default:
break;
}
@@ -3672,6 +3675,23 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
/* reconfigure the hardware */
ixgbe_dcb_hw_config(hw, &adapter->dcb_cfg);
+
+ /* Enable RSS Hash per TC */
+ if (hw->mac.type != ixgbe_mac_82598EB) {
+ int i;
+ u32 reg = 0;
+
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ u8 msb = 0;
+ u8 cnt = adapter->netdev->tc_to_txq[i].count;
+
+ while (cnt >>= 1)
+ msb++;
+
+ reg |= msb << IXGBE_RQTC_SHIFT_TC(i);
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_RQTC, reg);
+ }
}
#endif
@@ -7343,8 +7363,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
adapter->flags &= ~(IXGBE_FLAG_RSS_ENABLED |
IXGBE_FLAG_DCB_ENABLED);
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
- adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
#ifdef CONFIG_IXGBE_DCB
netdev->dcbnl_ops = &dcbnl_ops;
--
1.7.4
^ permalink raw reply related
* [net-next-2.6 17/21] ixgbe: update PHY code to support 100Mbps as well as 1G/10G
From: Jeff Kirsher @ 2011-03-12 12:20 UTC (permalink / raw)
To: davem; +Cc: Emil Tantilov, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299932428-3114-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Emil Tantilov <emil.s.tantilov@intel.com>
This change updates the PHY setup code to support 100Mbps capable PHYs
as well as 10G and 1Gbps.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_82598.c | 1 +
drivers/net/ixgbe/ixgbe_phy.c | 335 +++++++++++++++++++++++++++------------
drivers/net/ixgbe/ixgbe_phy.h | 1 +
drivers/net/ixgbe/ixgbe_type.h | 7 +
4 files changed, 245 insertions(+), 99 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index ff23907..845c679 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -158,6 +158,7 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
switch (hw->phy.type) {
case ixgbe_phy_tn:
+ phy->ops.setup_link = &ixgbe_setup_phy_link_tnx;
phy->ops.check_link = &ixgbe_check_phy_link_tnx;
phy->ops.get_firmware_version =
&ixgbe_get_phy_firmware_version_tnx;
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 9190a8f..f72f705 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -402,49 +402,89 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
**/
s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
{
- s32 status = IXGBE_NOT_IMPLEMENTED;
+ s32 status = 0;
u32 time_out;
u32 max_time_out = 10;
- u16 autoneg_reg;
+ u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
+ bool autoneg = false;
+ ixgbe_link_speed speed;
- /*
- * Set advertisement settings in PHY based on autoneg_advertised
- * settings. If autoneg_advertised = 0, then advertise default values
- * tnx devices cannot be "forced" to a autoneg 10G and fail. But can
- * for a 1G.
- */
- hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg);
+ ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
+
+ if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
+ /* Set or unset auto-negotiation 10G advertisement */
+ hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL,
+ MDIO_MMD_AN,
+ &autoneg_reg);
- if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL)
autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
- else
- autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
+ if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
+ autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
- hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg);
+ hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL,
+ MDIO_MMD_AN,
+ autoneg_reg);
+ }
+
+ if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
+ /* Set or unset auto-negotiation 1G advertisement */
+ hw->phy.ops.read_reg(hw,
+ IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+ MDIO_MMD_AN,
+ &autoneg_reg);
+
+ autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE;
+ if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
+ autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE;
+
+ hw->phy.ops.write_reg(hw,
+ IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+ MDIO_MMD_AN,
+ autoneg_reg);
+ }
+
+ if (speed & IXGBE_LINK_SPEED_100_FULL) {
+ /* Set or unset auto-negotiation 100M advertisement */
+ hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE,
+ MDIO_MMD_AN,
+ &autoneg_reg);
+
+ autoneg_reg &= ~ADVERTISE_100FULL;
+ if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
+ autoneg_reg |= ADVERTISE_100FULL;
+
+ hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
+ MDIO_MMD_AN,
+ autoneg_reg);
+ }
/* Restart PHY autonegotiation and wait for completion */
- hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, &autoneg_reg);
+ hw->phy.ops.read_reg(hw, MDIO_CTRL1,
+ MDIO_MMD_AN, &autoneg_reg);
autoneg_reg |= MDIO_AN_CTRL1_RESTART;
- hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, autoneg_reg);
+ hw->phy.ops.write_reg(hw, MDIO_CTRL1,
+ MDIO_MMD_AN, autoneg_reg);
/* Wait for autonegotiation to finish */
for (time_out = 0; time_out < max_time_out; time_out++) {
udelay(10);
/* Restart PHY autonegotiation and wait for completion */
- status = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN,
- &autoneg_reg);
+ status = hw->phy.ops.read_reg(hw, MDIO_STAT1,
+ MDIO_MMD_AN,
+ &autoneg_reg);
autoneg_reg &= MDIO_AN_STAT1_COMPLETE;
if (autoneg_reg == MDIO_AN_STAT1_COMPLETE) {
- status = 0;
break;
}
}
- if (time_out == max_time_out)
+ if (time_out == max_time_out) {
status = IXGBE_ERR_LINK_SETUP;
+ hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out");
+ }
return status;
}
@@ -473,6 +513,9 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
+ if (speed & IXGBE_LINK_SPEED_100_FULL)
+ hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
+
/* Setup link based on the new speed settings */
hw->phy.ops.setup_link(hw);
@@ -513,6 +556,180 @@ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
}
/**
+ * ixgbe_check_phy_link_tnx - Determine link and speed status
+ * @hw: pointer to hardware structure
+ *
+ * Reads the VS1 register to determine if link is up and the current speed for
+ * the PHY.
+ **/
+s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
+ bool *link_up)
+{
+ s32 status = 0;
+ u32 time_out;
+ u32 max_time_out = 10;
+ u16 phy_link = 0;
+ u16 phy_speed = 0;
+ u16 phy_data = 0;
+
+ /* Initialize speed and link to default case */
+ *link_up = false;
+ *speed = IXGBE_LINK_SPEED_10GB_FULL;
+
+ /*
+ * Check current speed and link status of the PHY register.
+ * This is a vendor specific register and may have to
+ * be changed for other copper PHYs.
+ */
+ for (time_out = 0; time_out < max_time_out; time_out++) {
+ udelay(10);
+ status = hw->phy.ops.read_reg(hw,
+ MDIO_STAT1,
+ MDIO_MMD_VEND1,
+ &phy_data);
+ phy_link = phy_data &
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
+ phy_speed = phy_data &
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
+ if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
+ *link_up = true;
+ if (phy_speed ==
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
+ *speed = IXGBE_LINK_SPEED_1GB_FULL;
+ break;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_phy_link_tnx - Set and restart autoneg
+ * @hw: pointer to hardware structure
+ *
+ * Restart autonegotiation and PHY and waits for completion.
+ **/
+s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
+{
+ s32 status = 0;
+ u32 time_out;
+ u32 max_time_out = 10;
+ u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
+ bool autoneg = false;
+ ixgbe_link_speed speed;
+
+ ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
+
+ if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
+ /* Set or unset auto-negotiation 10G advertisement */
+ hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL,
+ MDIO_MMD_AN,
+ &autoneg_reg);
+
+ autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
+ if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
+ autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
+
+ hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL,
+ MDIO_MMD_AN,
+ autoneg_reg);
+ }
+
+ if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
+ /* Set or unset auto-negotiation 1G advertisement */
+ hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
+ MDIO_MMD_AN,
+ &autoneg_reg);
+
+ autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
+ if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
+ autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
+
+ hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
+ MDIO_MMD_AN,
+ autoneg_reg);
+ }
+
+ if (speed & IXGBE_LINK_SPEED_100_FULL) {
+ /* Set or unset auto-negotiation 100M advertisement */
+ hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE,
+ MDIO_MMD_AN,
+ &autoneg_reg);
+
+ autoneg_reg &= ~ADVERTISE_100FULL;
+ if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
+ autoneg_reg |= ADVERTISE_100FULL;
+
+ hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
+ MDIO_MMD_AN,
+ autoneg_reg);
+ }
+
+ /* Restart PHY autonegotiation and wait for completion */
+ hw->phy.ops.read_reg(hw, MDIO_CTRL1,
+ MDIO_MMD_AN, &autoneg_reg);
+
+ autoneg_reg |= MDIO_AN_CTRL1_RESTART;
+
+ hw->phy.ops.write_reg(hw, MDIO_CTRL1,
+ MDIO_MMD_AN, autoneg_reg);
+
+ /* Wait for autonegotiation to finish */
+ for (time_out = 0; time_out < max_time_out; time_out++) {
+ udelay(10);
+ /* Restart PHY autonegotiation and wait for completion */
+ status = hw->phy.ops.read_reg(hw, MDIO_STAT1,
+ MDIO_MMD_AN,
+ &autoneg_reg);
+
+ autoneg_reg &= MDIO_AN_STAT1_COMPLETE;
+ if (autoneg_reg == MDIO_AN_STAT1_COMPLETE)
+ break;
+ }
+
+ if (time_out == max_time_out) {
+ status = IXGBE_ERR_LINK_SETUP;
+ hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out");
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version
+ * @hw: pointer to hardware structure
+ * @firmware_version: pointer to the PHY Firmware Version
+ **/
+s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
+ u16 *firmware_version)
+{
+ s32 status = 0;
+
+ status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
+ MDIO_MMD_VEND1,
+ firmware_version);
+
+ return status;
+}
+
+/**
+ * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version
+ * @hw: pointer to hardware structure
+ * @firmware_version: pointer to the PHY Firmware Version
+ **/
+s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
+ u16 *firmware_version)
+{
+ s32 status = 0;
+
+ status = hw->phy.ops.read_reg(hw, AQ_FW_REV,
+ MDIO_MMD_VEND1,
+ firmware_version);
+
+ return status;
+}
+
+/**
* ixgbe_reset_phy_nl - Performs a PHY reset
* @hw: pointer to hardware structure
**/
@@ -1477,86 +1694,6 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
}
/**
- * ixgbe_check_phy_link_tnx - Determine link and speed status
- * @hw: pointer to hardware structure
- *
- * Reads the VS1 register to determine if link is up and the current speed for
- * the PHY.
- **/
-s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
- bool *link_up)
-{
- s32 status = 0;
- u32 time_out;
- u32 max_time_out = 10;
- u16 phy_link = 0;
- u16 phy_speed = 0;
- u16 phy_data = 0;
-
- /* Initialize speed and link to default case */
- *link_up = false;
- *speed = IXGBE_LINK_SPEED_10GB_FULL;
-
- /*
- * Check current speed and link status of the PHY register.
- * This is a vendor specific register and may have to
- * be changed for other copper PHYs.
- */
- for (time_out = 0; time_out < max_time_out; time_out++) {
- udelay(10);
- status = hw->phy.ops.read_reg(hw,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
- MDIO_MMD_VEND1,
- &phy_data);
- phy_link = phy_data &
- IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
- phy_speed = phy_data &
- IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
- if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
- *link_up = true;
- if (phy_speed ==
- IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
- break;
- }
- }
-
- return status;
-}
-
-/**
- * ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version
- * @hw: pointer to hardware structure
- * @firmware_version: pointer to the PHY Firmware Version
- **/
-s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
- u16 *firmware_version)
-{
- s32 status = 0;
-
- status = hw->phy.ops.read_reg(hw, TNX_FW_REV, MDIO_MMD_VEND1,
- firmware_version);
-
- return status;
-}
-
-/**
- * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version
- * @hw: pointer to hardware structure
- * @firmware_version: pointer to the PHY Firmware Version
-**/
-s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
- u16 *firmware_version)
-{
- s32 status = 0;
-
- status = hw->phy.ops.read_reg(hw, AQ_FW_REV, MDIO_MMD_VEND1,
- firmware_version);
-
- return status;
-}
-
-/**
* ixgbe_tn_check_overtemp - Checks if an overtemp occured.
* @hw: pointer to hardware structure
*
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index 9bf2783..197bdd1 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -108,6 +108,7 @@ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw,
ixgbe_link_speed *speed,
bool *link_up);
+s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw);
s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
u16 *firmware_version);
s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index f190a4a..63d862d 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1009,6 +1009,13 @@
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */
+/* MII clause 22/28 definitions */
+#define IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG 0xC400 /* 1G Provisioning 1 */
+#define IXGBE_MII_AUTONEG_XNP_TX_REG 0x17 /* 1G XNP Transmit */
+#define IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX 0x4000 /* full duplex, bit:14*/
+#define IXGBE_MII_1GBASE_T_ADVERTISE 0x8000 /* full duplex, bit:15*/
+#define IXGBE_MII_AUTONEG_REG 0x0
+
#define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0
#define IXGBE_MAX_PHY_ADDR 32
--
1.7.4
^ permalink raw reply related
* [net-next-2.6 18/21] ixgbe: correct typo in define name
From: Jeff Kirsher @ 2011-03-12 12:20 UTC (permalink / raw)
To: davem; +Cc: Emil Tantilov, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299932428-3114-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Emil Tantilov <emil.s.tantilov@intel.com>
VF Free Running Timer register name missing an F.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Evan Swanson <evan.swanson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbevf/ethtool.c | 4 ++--
drivers/net/ixgbevf/regs.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c
index fa29b3c..0563ab2 100644
--- a/drivers/net/ixgbevf/ethtool.c
+++ b/drivers/net/ixgbevf/ethtool.c
@@ -172,7 +172,7 @@ static char *ixgbevf_reg_names[] = {
"IXGBE_VFSTATUS",
"IXGBE_VFLINKS",
"IXGBE_VFRXMEMWRAP",
- "IXGBE_VFRTIMER",
+ "IXGBE_VFFRTIMER",
"IXGBE_VTEICR",
"IXGBE_VTEICS",
"IXGBE_VTEIMS",
@@ -240,7 +240,7 @@ static void ixgbevf_get_regs(struct net_device *netdev,
regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_VFSTATUS);
regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_VFRXMEMWRAP);
- regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFRTIMER);
+ regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFFRTIMER);
/* Interrupt */
/* don't read EICR because it can clear interrupt causes, instead
diff --git a/drivers/net/ixgbevf/regs.h b/drivers/net/ixgbevf/regs.h
index fb80ca1..189200e 100644
--- a/drivers/net/ixgbevf/regs.h
+++ b/drivers/net/ixgbevf/regs.h
@@ -31,7 +31,7 @@
#define IXGBE_VFCTRL 0x00000
#define IXGBE_VFSTATUS 0x00008
#define IXGBE_VFLINKS 0x00010
-#define IXGBE_VFRTIMER 0x00048
+#define IXGBE_VFFRTIMER 0x00048
#define IXGBE_VFRXMEMWRAP 0x03190
#define IXGBE_VTEICR 0x00100
#define IXGBE_VTEICS 0x00104
--
1.7.4
^ permalink raw reply related
* [net-next-2.6 16/21] ixgbe: remove timer reset to 0 on timeout
From: Jeff Kirsher @ 2011-03-12 12:20 UTC (permalink / raw)
To: davem; +Cc: Emil Tantilov, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299932428-3114-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Emil Tantilov <emil.s.tantilov@intel.com>
The VF mailbox polling for acks and messages would reset the timer to zero
on a timeout. Under heavy load a timeout may actually occur without being
the result of an error and when this occurs it is not practical to perform
a full VF driver reset on every message timeout. Instead, just return an
error (which is already done) and the VF driver will have an opportunity
to retry the operation.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_mbx.c | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c
index c7ed82e..1ff0eef 100644
--- a/drivers/net/ixgbe/ixgbe_mbx.c
+++ b/drivers/net/ixgbe/ixgbe_mbx.c
@@ -154,9 +154,6 @@ static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
udelay(mbx->usec_delay);
}
- /* if we failed, all future posted messages fail until reset */
- if (!countdown)
- mbx->timeout = 0;
out:
return countdown ? 0 : IXGBE_ERR_MBX;
}
@@ -183,9 +180,6 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
udelay(mbx->usec_delay);
}
- /* if we failed, all future posted messages fail until reset */
- if (!countdown)
- mbx->timeout = 0;
out:
return countdown ? 0 : IXGBE_ERR_MBX;
}
--
1.7.4
^ permalink raw reply related
* [net-next-2.6 08/21] ixgbe: DCB, implement ieee_setapp dcbnl ops
From: Jeff Kirsher @ 2011-03-12 12:20 UTC (permalink / raw)
To: davem; +Cc: John Fastabend, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299932428-3114-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: John Fastabend <john.r.fastabend@intel.com>
Implement ieee_setapp dcbnl ops in ixgbe. This is required
to setup FCoE which requires dedicated resources. If the
app data is not for FCoE then no action is taken in ixgbe
except to add it to the dcb_app_list.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_dcb_nl.c | 30 ++++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index d7c456f..8d139f7 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -709,6 +709,35 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
return err;
}
+static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
+ struct dcb_app *app)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+
+ if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
+ return -EINVAL;
+#ifdef IXGBE_FCOE
+ if (app->selector == 1 && app->protocol == ETH_P_FCOE) {
+ if (adapter->fcoe.tc == app->priority)
+ goto setapp;
+
+ /* In IEEE mode map up to tc 1:1 */
+ adapter->fcoe.tc = app->priority;
+ adapter->fcoe.up = app->priority;
+
+ /* Force hardware reset required to push FCoE
+ * setup on {tx|rx}_rings
+ */
+ adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
+ ixgbe_dcbnl_set_all(dev);
+ }
+
+setapp:
+#endif
+ dcb_setapp(dev, app);
+ return 0;
+}
+
static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
@@ -759,6 +788,7 @@ const struct dcbnl_rtnl_ops dcbnl_ops = {
.ieee_setets = ixgbe_dcbnl_ieee_setets,
.ieee_getpfc = ixgbe_dcbnl_ieee_getpfc,
.ieee_setpfc = ixgbe_dcbnl_ieee_setpfc,
+ .ieee_setapp = ixgbe_dcbnl_ieee_setapp,
.getstate = ixgbe_dcbnl_get_state,
.setstate = ixgbe_dcbnl_set_state,
.getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr,
--
1.7.4
^ permalink raw reply related
* [net-next-2.6 20/21] ixgbe: add support for VF Transmit rate limit using iproute2
From: Jeff Kirsher @ 2011-03-12 12:20 UTC (permalink / raw)
To: davem; +Cc: Lior Levy, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299932428-3114-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Lior Levy <lior.levy@intel.com>
Implemented ixgbe_ndo_set_vf_bw function which is being used by iproute2
tool. In addition, updated ixgbe_ndo_get_vf_config function to show the
actual rate limit to the user.
The rate limitation can be configured only when the link is up and the
link speed is 10Gb.
The rate limit value can be 0 or ranged between 11 and actual link
speed measured in Mbps. A value of '0' disables the rate limit for
this specific VF.
iproute2 usage will be 'ip link set ethX vf Y rate Z'.
After the command is made, the rate will be changed instantly.
To view the current rate limit, use 'ip link show ethX'.
The rates will be zeroed only upon driver reload or a link speed change.
This feature is being supported by 82599 and X540 devices.
Signed-off-by: Lior Levy <lior.levy@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe.h | 2 +
drivers/net/ixgbe/ixgbe_main.c | 1 +
drivers/net/ixgbe/ixgbe_sriov.c | 85 ++++++++++++++++++++++++++++++++++++++-
drivers/net/ixgbe/ixgbe_sriov.h | 1 +
drivers/net/ixgbe/ixgbe_type.h | 6 +++
5 files changed, 93 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index b7e62d5..8d46802 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -118,6 +118,7 @@ struct vf_data_storage {
bool pf_set_mac;
u16 pf_vlan; /* When set, guest VLAN config not allowed. */
u16 pf_qos;
+ u16 tx_rate;
};
/* wrapper around a pointer to a socket buffer,
@@ -468,6 +469,7 @@ struct ixgbe_adapter {
DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS);
unsigned int num_vfs;
struct vf_data_storage *vfinfo;
+ int vf_rate_link_speed;
};
enum ixbge_state_t {
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 38f9758..f17e4a7 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -6217,6 +6217,7 @@ static void ixgbe_watchdog_task(struct work_struct *work)
(flow_tx ? "TX" : "None"))));
netif_carrier_on(netdev);
+ ixgbe_check_vf_rate_limit(adapter);
} else {
/* Force detection of hung controller */
for (i = 0; i < adapter->num_tx_queues; i++) {
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c
index 58c9b45..6e50d83 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ixgbe/ixgbe_sriov.c
@@ -478,9 +478,90 @@ out:
return err;
}
+static int ixgbe_link_mbps(int internal_link_speed)
+{
+ switch (internal_link_speed) {
+ case IXGBE_LINK_SPEED_100_FULL:
+ return 100;
+ case IXGBE_LINK_SPEED_1GB_FULL:
+ return 1000;
+ case IXGBE_LINK_SPEED_10GB_FULL:
+ return 10000;
+ default:
+ return 0;
+ }
+}
+
+static void ixgbe_set_vf_rate_limit(struct ixgbe_hw *hw, int vf, int tx_rate,
+ int link_speed)
+{
+ int rf_dec, rf_int;
+ u32 bcnrc_val;
+
+ if (tx_rate != 0) {
+ /* Calculate the rate factor values to set */
+ rf_int = link_speed / tx_rate;
+ rf_dec = (link_speed - (rf_int * tx_rate));
+ rf_dec = (rf_dec * (1<<IXGBE_RTTBCNRC_RF_INT_SHIFT)) / tx_rate;
+
+ bcnrc_val = IXGBE_RTTBCNRC_RS_ENA;
+ bcnrc_val |= ((rf_int<<IXGBE_RTTBCNRC_RF_INT_SHIFT) &
+ IXGBE_RTTBCNRC_RF_INT_MASK);
+ bcnrc_val |= (rf_dec & IXGBE_RTTBCNRC_RF_DEC_MASK);
+ } else {
+ bcnrc_val = 0;
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, 2*vf); /* vf Y uses queue 2*Y */
+ IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, bcnrc_val);
+}
+
+void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter)
+{
+ int actual_link_speed, i;
+ bool reset_rate = false;
+
+ /* VF Tx rate limit was not set */
+ if (adapter->vf_rate_link_speed == 0)
+ return;
+
+ actual_link_speed = ixgbe_link_mbps(adapter->link_speed);
+ if (actual_link_speed != adapter->vf_rate_link_speed) {
+ reset_rate = true;
+ adapter->vf_rate_link_speed = 0;
+ dev_info(&adapter->pdev->dev,
+ "Link speed has been changed. VF Transmit rate "
+ "is disabled\n");
+ }
+
+ for (i = 0; i < adapter->num_vfs; i++) {
+ if (reset_rate)
+ adapter->vfinfo[i].tx_rate = 0;
+
+ ixgbe_set_vf_rate_limit(&adapter->hw, i,
+ adapter->vfinfo[i].tx_rate,
+ actual_link_speed);
+ }
+}
+
int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
{
- return -EOPNOTSUPP;
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+ int actual_link_speed;
+
+ actual_link_speed = ixgbe_link_mbps(adapter->link_speed);
+ if ((vf >= adapter->num_vfs) || (!adapter->link_up) ||
+ (tx_rate > actual_link_speed) || (actual_link_speed != 10000) ||
+ ((tx_rate != 0) && (tx_rate <= 10)))
+ /* rate limit cannot be set to 10Mb or less in 10Gb adapters */
+ return -EINVAL;
+
+ adapter->vf_rate_link_speed = actual_link_speed;
+ adapter->vfinfo[vf].tx_rate = (u16)tx_rate;
+ ixgbe_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed);
+
+ return 0;
}
int ixgbe_ndo_get_vf_config(struct net_device *netdev,
@@ -491,7 +572,7 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,
return -EINVAL;
ivi->vf = vf;
memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN);
- ivi->tx_rate = 0;
+ ivi->tx_rate = adapter->vfinfo[vf].tx_rate;
ivi->vlan = adapter->vfinfo[vf].pf_vlan;
ivi->qos = adapter->vfinfo[vf].pf_qos;
return 0;
diff --git a/drivers/net/ixgbe/ixgbe_sriov.h b/drivers/net/ixgbe/ixgbe_sriov.h
index e7dd029..3417556 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ixgbe/ixgbe_sriov.h
@@ -40,6 +40,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate);
int ixgbe_ndo_get_vf_config(struct net_device *netdev,
int vf, struct ifla_vf_info *ivi);
+void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);
#endif /* _IXGBE_SRIOV_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 63d862d..25c1fb7 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -533,6 +533,12 @@
#define IXGBE_RTTDTECC 0x04990
#define IXGBE_RTTDTECC_NO_BCN 0x00000100
#define IXGBE_RTTBCNRC 0x04984
+#define IXGBE_RTTBCNRC_RS_ENA 0x80000000
+#define IXGBE_RTTBCNRC_RF_DEC_MASK 0x00003FFF
+#define IXGBE_RTTBCNRC_RF_INT_SHIFT 14
+#define IXGBE_RTTBCNRC_RF_INT_MASK \
+ (IXGBE_RTTBCNRC_RF_DEC_MASK << IXGBE_RTTBCNRC_RF_INT_SHIFT)
+
/* FCoE registers */
#define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */
--
1.7.4
^ permalink raw reply related
* [net-next-2.6 21/21] ixgbe: DCB, PFC not cleared until reset occurs
From: Jeff Kirsher @ 2011-03-12 12:20 UTC (permalink / raw)
To: davem; +Cc: John Fastabend, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299932428-3114-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: John Fastabend <john.r.fastabend@intel.com>
The PFC configuration is not cleared until the device is reset. This
has not been a problem because setting DCB attributes forced a
hardware reset. Now that we no longer require this reset to occur
PFC remains configured even after being disabled until the
device is reset.
This removes a goto in the PFC hardware set routines for 82598 and
82599 devices that was short circuiting the clear.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_dcb_82598.c | 44 +++++++++++++---------------
drivers/net/ixgbe/ixgbe_dcb_82599.c | 54 +++++++++++++++++------------------
2 files changed, 47 insertions(+), 51 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c
index c97cf91..1bc57e5 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c
@@ -233,21 +233,27 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
u32 reg, rx_pba_size;
u8 i;
- if (!pfc_en)
- goto out;
-
- /* Enable Transmit Priority Flow Control */
- reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
- reg &= ~IXGBE_RMCS_TFCE_802_3X;
- /* correct the reporting of our flow control status */
- reg |= IXGBE_RMCS_TFCE_PRIORITY;
- IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
-
- /* Enable Receive Priority Flow Control */
- reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- reg &= ~IXGBE_FCTRL_RFCE;
- reg |= IXGBE_FCTRL_RPFCE;
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
+ if (pfc_en) {
+ /* Enable Transmit Priority Flow Control */
+ reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
+ reg &= ~IXGBE_RMCS_TFCE_802_3X;
+ /* correct the reporting of our flow control status */
+ reg |= IXGBE_RMCS_TFCE_PRIORITY;
+ IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
+
+ /* Enable Receive Priority Flow Control */
+ reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ reg &= ~IXGBE_FCTRL_RFCE;
+ reg |= IXGBE_FCTRL_RPFCE;
+ IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
+
+ /* Configure pause time */
+ for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++)
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800);
+
+ /* Configure flow control refresh threshold value */
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400);
+ }
/*
* Configure flow control thresholds and enable priority flow control
@@ -273,14 +279,6 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
}
- /* Configure pause time */
- for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++)
- IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800);
-
- /* Configure flow control refresh threshold value */
- IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400);
-
-out:
return 0;
}
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
index 0a482bb..025af8c 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -253,13 +253,6 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en)
{
u32 i, reg, rx_pba_size;
- /* If PFC is disabled globally then fall back to LFC. */
- if (!pfc_en) {
- for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
- hw->mac.ops.fc_enable(hw, i);
- goto out;
- }
-
/* Configure PFC Tx thresholds per TC */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
int enabled = pfc_en & (1 << i);
@@ -278,28 +271,33 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en)
IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
}
- /* Configure pause time (2 TCs per register) */
- reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
- for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
- IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
-
- /* Configure flow control refresh threshold value */
- IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
-
- /* Enable Transmit PFC */
- reg = IXGBE_FCCFG_TFCE_PRIORITY;
- IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg);
+ if (pfc_en) {
+ /* Configure pause time (2 TCs per register) */
+ reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
+ for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
+
+ /* Configure flow control refresh threshold value */
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
+
+
+ reg = IXGBE_FCCFG_TFCE_PRIORITY;
+ IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg);
+ /*
+ * Enable Receive PFC
+ * We will always honor XOFF frames we receive when
+ * we are in PFC mode.
+ */
+ reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ reg &= ~IXGBE_MFLCN_RFCE;
+ reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF;
+ IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
+
+ } else {
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+ hw->mac.ops.fc_enable(hw, i);
+ }
- /*
- * Enable Receive PFC
- * We will always honor XOFF frames we receive when
- * we are in PFC mode.
- */
- reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
- reg &= ~IXGBE_MFLCN_RFCE;
- reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF;
- IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
-out:
return 0;
}
--
1.7.4
^ permalink raw reply related
* [net-next-2.6] Latest GIT pulled into linux-next
From: Sedat Dilek @ 2011-03-12 12:26 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
Hi,
I pulled net-next-2.6 (last commit
70d279a7e2a6e308530822ba2bf4134cc0f5c091 "e1000e: bump version
number") into linux-next (next-20110311).
Unfortunately, I see this breakage:
[ build.log ]
...
In file included from
/home/sd/src/linux-2.6/linux-2.6.38-rc8/debian/build/source_i386_none/drivers/block/cciss.c:351:0:
/home/sd/src/linux-2.6/linux-2.6.38-rc8/debian/build/source_i386_none/drivers/block/cciss_scsi.c:
In function ‘scsi_cmd_stack_setup’:
/home/sd/src/linux-2.6/linux-2.6.38-rc8/debian/build/source_i386_none/drivers/block/cciss_scsi.c:229:48:
error: ‘struct cciss_scsi_cmd_stack_t’ has no member named ‘nelems’
/home/sd/src/linux-2.6/linux-2.6.38-rc8/debian/build/source_i386_none/drivers/block/cciss_scsi.c:
In function ‘scsi_cmd_stack_free’:
/home/sd/src/linux-2.6/linux-2.6.38-rc8/debian/build/source_i386_none/drivers/block/cciss_scsi.c:266:12:
error: incompatible types when assigning to type ‘struct
cciss_scsi_cmd_stack_elem_t *[34]’ from type ‘void *’
Just FYI.
Regards,
- Sedat -
^ permalink raw reply
* Re: [net-next-2.6] Latest GIT pulled into linux-next
From: Sedat Dilek @ 2011-03-12 12:32 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <AANLkTi=hna0mq5QTahDP8bHCq5_6ezs7PFeimpLuUe7S@mail.gmail.com>
Ooops, wrong ML and maintainer (sorry for this, it should be Jens and
linux-2.6-block).
- Sedat -
On Sat, Mar 12, 2011 at 1:26 PM, Sedat Dilek <sedat.dilek@googlemail.com> wrote:
> Hi,
>
> I pulled net-next-2.6 (last commit
> 70d279a7e2a6e308530822ba2bf4134cc0f5c091 "e1000e: bump version
> number") into linux-next (next-20110311).
>
> Unfortunately, I see this breakage:
>
> [ build.log ]
> ...
> In file included from
> /home/sd/src/linux-2.6/linux-2.6.38-rc8/debian/build/source_i386_none/drivers/block/cciss.c:351:0:
> /home/sd/src/linux-2.6/linux-2.6.38-rc8/debian/build/source_i386_none/drivers/block/cciss_scsi.c:
> In function ‘scsi_cmd_stack_setup’:
> /home/sd/src/linux-2.6/linux-2.6.38-rc8/debian/build/source_i386_none/drivers/block/cciss_scsi.c:229:48:
> error: ‘struct cciss_scsi_cmd_stack_t’ has no member named ‘nelems’
> /home/sd/src/linux-2.6/linux-2.6.38-rc8/debian/build/source_i386_none/drivers/block/cciss_scsi.c:
> In function ‘scsi_cmd_stack_free’:
> /home/sd/src/linux-2.6/linux-2.6.38-rc8/debian/build/source_i386_none/drivers/block/cciss_scsi.c:266:12:
> error: incompatible types when assigning to type ‘struct
> cciss_scsi_cmd_stack_elem_t *[34]’ from type ‘void *’
>
> Just FYI.
>
> Regards,
> - Sedat -
>
^ permalink raw reply
* [patch net-next-2.6 0/6] mostly bonding cleanups (partial repost)
From: Jiri Pirko @ 2011-03-12 13:14 UTC (permalink / raw)
To: netdev
Cc: davem, shemminger, kaber, fubar, eric.dumazet, nicolas.2p.debian,
andy, xiaosuo
My original series had 2 more patches. That ones I posponed until I resolve
problems with delivering vlan arps to bond_frame_handler on non-vlan_hw_accel
path.
So for now, there are following patches that are ready to be applied I believe.
Note the dependency on "fcoe: correct checking for bonding" patch that has not
been applied so far on scsi-misc. I believe that maybe this patch could be
applied on net-next instead.
Jiri Pirko (6):
af_packet: use skb->skb_iif instead of orig_dev->ifindex
bonding: register slave pointer for rx_handler
net: get rid of multiple bond-related netdevice->priv_flags
bonding: wrap slave state work
bonding: get rid of IFF_SLAVE_INACTIVE netdev->priv_flag
net: introduce rx_handler results and logic around that
drivers/net/bonding/bond_3ad.c | 2 +-
drivers/net/bonding/bond_main.c | 102 +++++++++++++++++++-------------------
drivers/net/bonding/bond_sysfs.c | 14 +----
drivers/net/bonding/bonding.h | 60 +++++++++++++----------
drivers/net/macvlan.c | 11 ++--
include/linux/if.h | 23 +++-----
include/linux/netdevice.h | 50 ++++++++++++++++++-
include/linux/skbuff.h | 5 +--
net/bridge/br_input.c | 25 ++++++----
net/bridge/br_private.h | 2 +-
net/core/dev.c | 21 +++++---
net/core/skbuff.c | 1 -
net/packet/af_packet.c | 4 +-
13 files changed, 186 insertions(+), 134 deletions(-)
--
1.7.4
^ permalink raw reply
* [patch net-next-2.6 2/6] bonding: register slave pointer for rx_handler
From: Jiri Pirko @ 2011-03-12 13:14 UTC (permalink / raw)
To: netdev
Cc: davem, shemminger, kaber, fubar, eric.dumazet, nicolas.2p.debian,
andy, xiaosuo
In-Reply-To: <1299935679-18135-1-git-send-email-jpirko@redhat.com>
Register slave pointer as rx_handler data. That would eventually prevent
need to loop over slave devices to find the right slave.
Use synchronize_net to ensure that bond_handle_frame does not get slave
structure freed when working with that.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Reviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
---
drivers/net/bonding/bond_main.c | 17 +++++++++++------
drivers/net/bonding/bonding.h | 3 +++
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 68a5ce0..29f69da 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1482,21 +1482,22 @@ static bool bond_should_deliver_exact_match(struct sk_buff *skb,
static struct sk_buff *bond_handle_frame(struct sk_buff *skb)
{
- struct net_device *slave_dev;
+ struct slave *slave;
struct net_device *bond_dev;
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
return NULL;
- slave_dev = skb->dev;
- bond_dev = ACCESS_ONCE(slave_dev->master);
+
+ slave = bond_slave_get_rcu(skb->dev);
+ bond_dev = ACCESS_ONCE(slave->dev->master);
if (unlikely(!bond_dev))
return skb;
if (bond_dev->priv_flags & IFF_MASTER_ARPMON)
- slave_dev->last_rx = jiffies;
+ slave->dev->last_rx = jiffies;
- if (bond_should_deliver_exact_match(skb, slave_dev, bond_dev)) {
+ if (bond_should_deliver_exact_match(skb, slave->dev, bond_dev)) {
skb->deliver_no_wcard = 1;
return skb;
}
@@ -1694,7 +1695,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
pr_debug("Error %d calling netdev_set_bond_master\n", res);
goto err_restore_mac;
}
- res = netdev_rx_handler_register(slave_dev, bond_handle_frame, NULL);
+ res = netdev_rx_handler_register(slave_dev, bond_handle_frame,
+ new_slave);
if (res) {
pr_debug("Error %d calling netdev_rx_handler_register\n", res);
goto err_unset_master;
@@ -1916,6 +1918,7 @@ err_close:
err_unreg_rxhandler:
netdev_rx_handler_unregister(slave_dev);
+ synchronize_net();
err_unset_master:
netdev_set_bond_master(slave_dev, NULL);
@@ -2099,6 +2102,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
}
netdev_rx_handler_unregister(slave_dev);
+ synchronize_net();
netdev_set_bond_master(slave_dev, NULL);
slave_disable_netpoll(slave);
@@ -2213,6 +2217,7 @@ static int bond_release_all(struct net_device *bond_dev)
}
netdev_rx_handler_unregister(slave_dev);
+ synchronize_net();
netdev_set_bond_master(slave_dev, NULL);
slave_disable_netpoll(slave);
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index c4e2343..ff9af31 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -266,6 +266,9 @@ struct bonding {
#endif /* CONFIG_DEBUG_FS */
};
+#define bond_slave_get_rcu(dev) \
+ ((struct slave *) rcu_dereference(dev->rx_handler_data))
+
/**
* Returns NULL if the net_device does not belong to any of the bond's slaves
*
--
1.7.4
^ permalink raw reply related
* [patch net-next-2.6 3/6] net: get rid of multiple bond-related netdevice->priv_flags
From: Jiri Pirko @ 2011-03-12 13:14 UTC (permalink / raw)
To: netdev
Cc: davem, shemminger, kaber, fubar, eric.dumazet, nicolas.2p.debian,
andy, xiaosuo
In-Reply-To: <1299935679-18135-1-git-send-email-jpirko@redhat.com>
Now when bond-related code is moved from net/core/dev.c into bonding
code, multiple priv_flags are not needed anymore. So toss them out.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Reviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
---
drivers/net/bonding/bond_main.c | 33 ++++++++++++++-------------------
drivers/net/bonding/bond_sysfs.c | 8 --------
drivers/net/bonding/bonding.h | 24 +-----------------------
include/linux/if.h | 22 +++++++++-------------
4 files changed, 24 insertions(+), 63 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 29f69da..3c6ac2f 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1458,20 +1458,20 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
* ARP on active-backup slaves with arp_validate enabled.
*/
static bool bond_should_deliver_exact_match(struct sk_buff *skb,
- struct net_device *slave_dev,
- struct net_device *bond_dev)
+ struct slave *slave,
+ struct bonding *bond)
{
- if (slave_dev->priv_flags & IFF_SLAVE_INACTIVE) {
- if (slave_dev->priv_flags & IFF_SLAVE_NEEDARP &&
+ if (slave->dev->priv_flags & IFF_SLAVE_INACTIVE) {
+ if (slave_do_arp_validate(bond, slave) &&
skb->protocol == __cpu_to_be16(ETH_P_ARP))
return false;
- if (bond_dev->priv_flags & IFF_MASTER_ALB &&
+ if (bond->params.mode == BOND_MODE_ALB &&
skb->pkt_type != PACKET_BROADCAST &&
skb->pkt_type != PACKET_MULTICAST)
return false;
- if (bond_dev->priv_flags & IFF_MASTER_8023AD &&
+ if (bond->params.mode == BOND_MODE_8023AD &&
skb->protocol == __cpu_to_be16(ETH_P_SLOW))
return false;
@@ -1484,6 +1484,7 @@ static struct sk_buff *bond_handle_frame(struct sk_buff *skb)
{
struct slave *slave;
struct net_device *bond_dev;
+ struct bonding *bond;
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
@@ -1494,17 +1495,19 @@ static struct sk_buff *bond_handle_frame(struct sk_buff *skb)
if (unlikely(!bond_dev))
return skb;
- if (bond_dev->priv_flags & IFF_MASTER_ARPMON)
+ bond = netdev_priv(bond_dev);
+
+ if (bond->params.arp_interval)
slave->dev->last_rx = jiffies;
- if (bond_should_deliver_exact_match(skb, slave->dev, bond_dev)) {
+ if (bond_should_deliver_exact_match(skb, slave, bond)) {
skb->deliver_no_wcard = 1;
return skb;
}
skb->dev = bond_dev;
- if (bond_dev->priv_flags & IFF_MASTER_ALB &&
+ if (bond->params.mode == BOND_MODE_ALB &&
bond_dev->priv_flags & IFF_BRIDGE_PORT &&
skb->pkt_type == PACKET_HOST) {
@@ -2119,9 +2122,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
dev_set_mtu(slave_dev, slave->original_mtu);
- slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
- IFF_SLAVE_INACTIVE | IFF_BONDING |
- IFF_SLAVE_NEEDARP);
+ slave_dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_BONDING);
kfree(slave);
@@ -2232,8 +2233,7 @@ static int bond_release_all(struct net_device *bond_dev)
dev_set_mac_address(slave_dev, &addr);
}
- slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
- IFF_SLAVE_INACTIVE);
+ slave_dev->priv_flags &= ~IFF_SLAVE_INACTIVE;
kfree(slave);
@@ -4416,11 +4416,9 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
case BOND_MODE_BROADCAST:
break;
case BOND_MODE_8023AD:
- bond_set_master_3ad_flags(bond);
bond_set_xmit_hash_policy(bond);
break;
case BOND_MODE_ALB:
- bond_set_master_alb_flags(bond);
/* FALLTHRU */
case BOND_MODE_TLB:
break;
@@ -4511,9 +4509,6 @@ static void bond_setup(struct net_device *bond_dev)
bond_dev->priv_flags |= IFF_BONDING;
bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
- if (bond->params.arp_interval)
- bond_dev->priv_flags |= IFF_MASTER_ARPMON;
-
/* At first, we block adding VLANs. That's the only way to
* prevent problems that occur when adding VLANs over an
* empty bond. The block will be removed once non-challenged
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 72bb0f6..05e0ae5 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -322,11 +322,6 @@ static ssize_t bonding_store_mode(struct device *d,
ret = -EINVAL;
goto out;
}
- if (bond->params.mode == BOND_MODE_8023AD)
- bond_unset_master_3ad_flags(bond);
-
- if (bond->params.mode == BOND_MODE_ALB)
- bond_unset_master_alb_flags(bond);
bond->params.mode = new_value;
bond_set_mode_ops(bond, bond->params.mode);
@@ -527,8 +522,6 @@ static ssize_t bonding_store_arp_interval(struct device *d,
pr_info("%s: Setting ARP monitoring interval to %d.\n",
bond->dev->name, new_value);
bond->params.arp_interval = new_value;
- if (bond->params.arp_interval)
- bond->dev->priv_flags |= IFF_MASTER_ARPMON;
if (bond->params.miimon) {
pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
bond->dev->name, bond->dev->name);
@@ -1004,7 +997,6 @@ static ssize_t bonding_store_miimon(struct device *d,
pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
bond->dev->name);
bond->params.arp_interval = 0;
- bond->dev->priv_flags &= ~IFF_MASTER_ARPMON;
if (bond->params.arp_validate) {
bond_unregister_arp(bond);
bond->params.arp_validate =
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index ff9af31..049619f 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -356,34 +356,12 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave)
slave->state = BOND_STATE_BACKUP;
if (!bond->params.all_slaves_active)
slave->dev->priv_flags |= IFF_SLAVE_INACTIVE;
- if (slave_do_arp_validate(bond, slave))
- slave->dev->priv_flags |= IFF_SLAVE_NEEDARP;
}
static inline void bond_set_slave_active_flags(struct slave *slave)
{
slave->state = BOND_STATE_ACTIVE;
- slave->dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_SLAVE_NEEDARP);
-}
-
-static inline void bond_set_master_3ad_flags(struct bonding *bond)
-{
- bond->dev->priv_flags |= IFF_MASTER_8023AD;
-}
-
-static inline void bond_unset_master_3ad_flags(struct bonding *bond)
-{
- bond->dev->priv_flags &= ~IFF_MASTER_8023AD;
-}
-
-static inline void bond_set_master_alb_flags(struct bonding *bond)
-{
- bond->dev->priv_flags |= IFF_MASTER_ALB;
-}
-
-static inline void bond_unset_master_alb_flags(struct bonding *bond)
-{
- bond->dev->priv_flags &= ~IFF_MASTER_ALB;
+ slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE;
}
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
diff --git a/include/linux/if.h b/include/linux/if.h
index 3bc63e6..2fdd47a 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -60,21 +60,17 @@
#define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */
#define IFF_EBRIDGE 0x2 /* Ethernet bridging device. */
#define IFF_SLAVE_INACTIVE 0x4 /* bonding slave not the curr. active */
-#define IFF_MASTER_8023AD 0x8 /* bonding master, 802.3ad. */
-#define IFF_MASTER_ALB 0x10 /* bonding master, balance-alb. */
-#define IFF_BONDING 0x20 /* bonding master or slave */
-#define IFF_SLAVE_NEEDARP 0x40 /* need ARPs for validation */
-#define IFF_ISATAP 0x80 /* ISATAP interface (RFC4214) */
-#define IFF_MASTER_ARPMON 0x100 /* bonding master, ARP mon in use */
-#define IFF_WAN_HDLC 0x200 /* WAN HDLC device */
-#define IFF_XMIT_DST_RELEASE 0x400 /* dev_hard_start_xmit() is allowed to
+#define IFF_BONDING 0x8 /* bonding master or slave */
+#define IFF_ISATAP 0x10 /* ISATAP interface (RFC4214) */
+#define IFF_WAN_HDLC 0x20 /* WAN HDLC device */
+#define IFF_XMIT_DST_RELEASE 0x40 /* dev_hard_start_xmit() is allowed to
* release skb->dst
*/
-#define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */
-#define IFF_DISABLE_NETPOLL 0x1000 /* disable netpoll at run-time */
-#define IFF_MACVLAN_PORT 0x2000 /* device used as macvlan port */
-#define IFF_BRIDGE_PORT 0x4000 /* device used as bridge port */
-#define IFF_OVS_DATAPATH 0x8000 /* device used as Open vSwitch
+#define IFF_DONT_BRIDGE 0x80 /* disallow bridging this ether dev */
+#define IFF_DISABLE_NETPOLL 0x100 /* disable netpoll at run-time */
+#define IFF_MACVLAN_PORT 0x200 /* device used as macvlan port */
+#define IFF_BRIDGE_PORT 0x400 /* device used as bridge port */
+#define IFF_OVS_DATAPATH 0x800 /* device used as Open vSwitch
* datapath port */
#define IF_GET_IFACE 0x0001 /* for querying only */
--
1.7.4
^ permalink raw reply related
* [patch net-next-2.6 1/6] af_packet: use skb->skb_iif instead of orig_dev->ifindex
From: Jiri Pirko @ 2011-03-12 13:14 UTC (permalink / raw)
To: netdev
Cc: davem, shemminger, kaber, fubar, eric.dumazet, nicolas.2p.debian,
andy, xiaosuo
In-Reply-To: <1299935679-18135-1-git-send-email-jpirko@redhat.com>
Since skb_iif has the desired value (ifindex of physical device actually
received the traffic) use that instead.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Reviewed-by: Changli Gao <xiaosuo@gmail.com>
Reviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
---
net/packet/af_packet.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index b5362e9..714383c 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -627,7 +627,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
sll->sll_protocol = skb->protocol;
sll->sll_pkttype = skb->pkt_type;
if (unlikely(po->origdev))
- sll->sll_ifindex = orig_dev->ifindex;
+ sll->sll_ifindex = skb->skb_iif;
else
sll->sll_ifindex = dev->ifindex;
@@ -812,7 +812,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
sll->sll_protocol = skb->protocol;
sll->sll_pkttype = skb->pkt_type;
if (unlikely(po->origdev))
- sll->sll_ifindex = orig_dev->ifindex;
+ sll->sll_ifindex = skb->skb_iif;
else
sll->sll_ifindex = dev->ifindex;
--
1.7.4
^ permalink raw reply related
* [patch net-next-2.6 4/6] bonding: wrap slave state work
From: Jiri Pirko @ 2011-03-12 13:14 UTC (permalink / raw)
To: netdev
Cc: davem, shemminger, kaber, fubar, eric.dumazet, nicolas.2p.debian,
andy, xiaosuo
In-Reply-To: <1299935679-18135-1-git-send-email-jpirko@redhat.com>
transfers slave->state into slave->backup (that it's going to transfer
into bitfield. Introduce wrapper inlines to do the work with it.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Reviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
---
drivers/net/bonding/bond_3ad.c | 2 +-
drivers/net/bonding/bond_main.c | 36 ++++++++++++++++++------------------
drivers/net/bonding/bond_sysfs.c | 2 +-
drivers/net/bonding/bonding.h | 31 ++++++++++++++++++++++++++-----
4 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 1024ae1..047af0b 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -246,7 +246,7 @@ static inline void __enable_port(struct port *port)
*/
static inline int __port_is_enabled(struct port *port)
{
- return port->slave->state == BOND_STATE_ACTIVE;
+ return bond_is_active_slave(port->slave);
}
/**
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 3c6ac2f..c5f3a01 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1863,7 +1863,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
break;
case BOND_MODE_TLB:
case BOND_MODE_ALB:
- new_slave->state = BOND_STATE_ACTIVE;
+ bond_set_active_slave(new_slave);
bond_set_slave_inactive_flags(new_slave);
bond_select_active_slave(bond);
break;
@@ -1871,7 +1871,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
pr_debug("This slave is always active in trunk mode\n");
/* always active in trunk mode */
- new_slave->state = BOND_STATE_ACTIVE;
+ bond_set_active_slave(new_slave);
/* In trunking mode there is little meaning to curr_active_slave
* anyway (it holds no special properties of the bond device),
@@ -1909,7 +1909,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
pr_info("%s: enslaving %s as a%s interface with a%s link.\n",
bond_dev->name, slave_dev->name,
- new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",
+ bond_is_active_slave(new_slave) ? "n active" : " backup",
new_slave->link != BOND_LINK_DOWN ? "n up" : " down");
/* enslave is successful */
@@ -2007,7 +2007,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
pr_info("%s: releasing %s interface %s\n",
bond_dev->name,
- (slave->state == BOND_STATE_ACTIVE) ? "active" : "backup",
+ bond_is_active_slave(slave) ? "active" : "backup",
slave_dev->name);
oldcurrent = bond->curr_active_slave;
@@ -2348,7 +2348,7 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
res = 0;
strcpy(info->slave_name, slave->dev->name);
info->link = slave->link;
- info->state = slave->state;
+ info->state = bond_slave_state(slave);
info->link_failure_count = slave->link_failure_count;
break;
}
@@ -2387,7 +2387,7 @@ static int bond_miimon_inspect(struct bonding *bond)
bond->dev->name,
(bond->params.mode ==
BOND_MODE_ACTIVEBACKUP) ?
- ((slave->state == BOND_STATE_ACTIVE) ?
+ (bond_is_active_slave(slave) ?
"active " : "backup ") : "",
slave->dev->name,
bond->params.downdelay * bond->params.miimon);
@@ -2478,13 +2478,13 @@ static void bond_miimon_commit(struct bonding *bond)
if (bond->params.mode == BOND_MODE_8023AD) {
/* prevent it from being the active one */
- slave->state = BOND_STATE_BACKUP;
+ bond_set_backup_slave(slave);
} else if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
/* make it immediately active */
- slave->state = BOND_STATE_ACTIVE;
+ bond_set_active_slave(slave);
} else if (slave != bond->primary_slave) {
/* prevent it from being the active one */
- slave->state = BOND_STATE_BACKUP;
+ bond_set_backup_slave(slave);
}
bond_update_speed_duplex(slave);
@@ -2862,7 +2862,7 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
memcpy(&tip, arp_ptr, 4);
pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n",
- bond->dev->name, slave->dev->name, slave->state,
+ bond->dev->name, slave->dev->name, bond_slave_state(slave),
bond->params.arp_validate, slave_do_arp_validate(bond, slave),
&sip, &tip);
@@ -2874,7 +2874,7 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
* the active, through one switch, the router, then the other
* switch before reaching the backup.
*/
- if (slave->state == BOND_STATE_ACTIVE)
+ if (bond_is_active_slave(slave))
bond_validate_arp(bond, slave, sip, tip);
else
bond_validate_arp(bond, slave, tip, sip);
@@ -2936,7 +2936,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
slave->dev->last_rx + delta_in_ticks)) {
slave->link = BOND_LINK_UP;
- slave->state = BOND_STATE_ACTIVE;
+ bond_set_active_slave(slave);
/* primary_slave has no meaning in round-robin
* mode. the window of a slave being up and
@@ -2969,7 +2969,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
slave->dev->last_rx + 2 * delta_in_ticks)) {
slave->link = BOND_LINK_DOWN;
- slave->state = BOND_STATE_BACKUP;
+ bond_set_backup_slave(slave);
if (slave->link_failure_count < UINT_MAX)
slave->link_failure_count++;
@@ -3063,7 +3063,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
* gives each slave a chance to tx/rx traffic
* before being taken out
*/
- if (slave->state == BOND_STATE_BACKUP &&
+ if (!bond_is_active_slave(slave) &&
!bond->current_arp_slave &&
!time_in_range(jiffies,
slave_last_rx(bond, slave) - delta_in_ticks,
@@ -3080,7 +3080,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
* the bond has an IP address)
*/
trans_start = dev_trans_start(slave->dev);
- if ((slave->state == BOND_STATE_ACTIVE) &&
+ if (bond_is_active_slave(slave) &&
(!time_in_range(jiffies,
trans_start - delta_in_ticks,
trans_start + 2 * delta_in_ticks) ||
@@ -4144,7 +4144,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
bond_for_each_slave_from(bond, slave, i, start_at) {
if (IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP) &&
- (slave->state == BOND_STATE_ACTIVE)) {
+ bond_is_active_slave(slave)) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
break;
}
@@ -4221,7 +4221,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
bond_for_each_slave_from(bond, slave, i, start_at) {
if (IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP) &&
- (slave->state == BOND_STATE_ACTIVE)) {
+ bond_is_active_slave(slave)) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
break;
}
@@ -4262,7 +4262,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
bond_for_each_slave_from(bond, slave, i, start_at) {
if (IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP) &&
- (slave->state == BOND_STATE_ACTIVE)) {
+ bond_is_active_slave(slave)) {
if (tx_dev) {
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
if (!skb2) {
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 05e0ae5..344d23f 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1579,7 +1579,7 @@ static ssize_t bonding_store_slaves_active(struct device *d,
}
bond_for_each_slave(bond, slave, i) {
- if (slave->state == BOND_STATE_BACKUP) {
+ if (!bond_is_active_slave(slave)) {
if (new_value)
slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE;
else
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 049619f..63e9cf7 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -55,7 +55,7 @@
(((slave)->dev->flags & IFF_UP) && \
netif_running((slave)->dev) && \
((slave)->link == BOND_LINK_UP) && \
- ((slave)->state == BOND_STATE_ACTIVE))
+ bond_is_active_slave(slave))
#define USES_PRIMARY(mode) \
@@ -192,7 +192,8 @@ struct slave {
unsigned long last_arp_rx;
s8 link; /* one of BOND_LINK_XXXX */
s8 new_link;
- s8 state; /* one of BOND_STATE_XXXX */
+ u8 backup; /* indicates backup slave. Value corresponds with
+ BOND_STATE_ACTIVE and BOND_STATE_BACKUP */
u32 original_mtu;
u32 link_failure_count;
u8 perm_hwaddr[ETH_ALEN];
@@ -304,6 +305,26 @@ static inline bool bond_is_lb(const struct bonding *bond)
bond->params.mode == BOND_MODE_ALB);
}
+static inline void bond_set_active_slave(struct slave *slave)
+{
+ slave->backup = 0;
+}
+
+static inline void bond_set_backup_slave(struct slave *slave)
+{
+ slave->backup = 1;
+}
+
+static inline int bond_slave_state(struct slave *slave)
+{
+ return slave->backup;
+}
+
+static inline bool bond_is_active_slave(struct slave *slave)
+{
+ return !bond_slave_state(slave);
+}
+
#define BOND_PRI_RESELECT_ALWAYS 0
#define BOND_PRI_RESELECT_BETTER 1
#define BOND_PRI_RESELECT_FAILURE 2
@@ -321,7 +342,7 @@ static inline bool bond_is_lb(const struct bonding *bond)
static inline int slave_do_arp_validate(struct bonding *bond,
struct slave *slave)
{
- return bond->params.arp_validate & (1 << slave->state);
+ return bond->params.arp_validate & (1 << bond_slave_state(slave));
}
static inline unsigned long slave_last_rx(struct bonding *bond,
@@ -353,14 +374,14 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave)
{
struct bonding *bond = netdev_priv(slave->dev->master);
if (!bond_is_lb(bond))
- slave->state = BOND_STATE_BACKUP;
+ bond_set_backup_slave(slave);
if (!bond->params.all_slaves_active)
slave->dev->priv_flags |= IFF_SLAVE_INACTIVE;
}
static inline void bond_set_slave_active_flags(struct slave *slave)
{
- slave->state = BOND_STATE_ACTIVE;
+ bond_set_active_slave(slave);
slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE;
}
--
1.7.4
^ permalink raw reply related
* [patch net-next-2.6 6/6] net: introduce rx_handler results and logic around that
From: Jiri Pirko @ 2011-03-12 13:14 UTC (permalink / raw)
To: netdev
Cc: davem, shemminger, kaber, fubar, eric.dumazet, nicolas.2p.debian,
andy, xiaosuo
In-Reply-To: <1299935679-18135-1-git-send-email-jpirko@redhat.com>
This patch allows rx_handlers to better signalize what to do next to
it's caller. That makes skb->deliver_no_wcard no longer needed.
kernel-doc for rx_handler_result is taken from Nicolas' patch.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
eviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
---
drivers/net/bonding/bond_main.c | 22 +++++++++-------
drivers/net/macvlan.c | 11 ++++----
include/linux/netdevice.h | 50 ++++++++++++++++++++++++++++++++++++++-
include/linux/skbuff.h | 5 +---
net/bridge/br_input.c | 25 +++++++++++-------
net/bridge/br_private.h | 2 +-
net/core/dev.c | 21 +++++++++++-----
net/core/skbuff.c | 1 -
8 files changed, 98 insertions(+), 39 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c3150df..fdba1a1 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1480,20 +1480,23 @@ static bool bond_should_deliver_exact_match(struct sk_buff *skb,
return false;
}
-static struct sk_buff *bond_handle_frame(struct sk_buff *skb)
+static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
{
+ struct sk_buff *skb = *pskb;
struct slave *slave;
struct net_device *bond_dev;
struct bonding *bond;
- skb = skb_share_check(skb, GFP_ATOMIC);
- if (unlikely(!skb))
- return NULL;
-
slave = bond_slave_get_rcu(skb->dev);
bond_dev = ACCESS_ONCE(slave->dev->master);
if (unlikely(!bond_dev))
- return skb;
+ return RX_HANDLER_PASS;
+
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (unlikely(!skb))
+ return RX_HANDLER_CONSUMED;
+
+ *pskb = skb;
bond = netdev_priv(bond_dev);
@@ -1501,8 +1504,7 @@ static struct sk_buff *bond_handle_frame(struct sk_buff *skb)
slave->dev->last_rx = jiffies;
if (bond_should_deliver_exact_match(skb, slave, bond)) {
- skb->deliver_no_wcard = 1;
- return skb;
+ return RX_HANDLER_EXACT;
}
skb->dev = bond_dev;
@@ -1514,12 +1516,12 @@ static struct sk_buff *bond_handle_frame(struct sk_buff *skb)
if (unlikely(skb_cow_head(skb,
skb->data - skb_mac_header(skb)))) {
kfree_skb(skb);
- return NULL;
+ return RX_HANDLER_CONSUMED;
}
memcpy(eth_hdr(skb)->h_dest, bond_dev->dev_addr, ETH_ALEN);
}
- return skb;
+ return RX_HANDLER_ANOTHER;
}
/* enslave device <slave> to bond device <master> */
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 6ed577b..ead9a8f 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -152,9 +152,10 @@ static void macvlan_broadcast(struct sk_buff *skb,
}
/* called under rcu_read_lock() from netif_receive_skb */
-static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
+static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
{
struct macvlan_port *port;
+ struct sk_buff *skb = *pskb;
const struct ethhdr *eth = eth_hdr(skb);
const struct macvlan_dev *vlan;
const struct macvlan_dev *src;
@@ -184,7 +185,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
*/
macvlan_broadcast(skb, port, src->dev,
MACVLAN_MODE_VEPA);
- return skb;
+ return RX_HANDLER_PASS;
}
if (port->passthru)
@@ -192,12 +193,12 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
else
vlan = macvlan_hash_lookup(port, eth->h_dest);
if (vlan == NULL)
- return skb;
+ return RX_HANDLER_PASS;
dev = vlan->dev;
if (unlikely(!(dev->flags & IFF_UP))) {
kfree_skb(skb);
- return NULL;
+ return RX_HANDLER_CONSUMED;
}
len = skb->len + ETH_HLEN;
skb = skb_share_check(skb, GFP_ATOMIC);
@@ -211,7 +212,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
out:
macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, 0);
- return NULL;
+ return RX_HANDLER_CONSUMED;
}
static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 6bd5d46..6275a95 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -390,7 +390,55 @@ enum gro_result {
};
typedef enum gro_result gro_result_t;
-typedef struct sk_buff *rx_handler_func_t(struct sk_buff *skb);
+/*
+ * enum rx_handler_result - Possible return values for rx_handlers.
+ * @RX_HANDLER_CONSUMED: skb was consumed by rx_handler, do not process it
+ * further.
+ * @RX_HANDLER_ANOTHER: Do another round in receive path. This is indicated in
+ * case skb->dev was changed by rx_handler.
+ * @RX_HANDLER_EXACT: Force exact delivery, no wildcard.
+ * @RX_HANDLER_PASS: Do nothing, passe the skb as if no rx_handler was called.
+ *
+ * rx_handlers are functions called from inside __netif_receive_skb(), to do
+ * special processing of the skb, prior to delivery to protocol handlers.
+ *
+ * Currently, a net_device can only have a single rx_handler registered. Trying
+ * to register a second rx_handler will return -EBUSY.
+ *
+ * To register a rx_handler on a net_device, use netdev_rx_handler_register().
+ * To unregister a rx_handler on a net_device, use
+ * netdev_rx_handler_unregister().
+ *
+ * Upon return, rx_handler is expected to tell __netif_receive_skb() what to
+ * do with the skb.
+ *
+ * If the rx_handler consumed to skb in some way, it should return
+ * RX_HANDLER_CONSUMED. This is appropriate when the rx_handler arranged for
+ * the skb to be delivered in some other ways.
+ *
+ * If the rx_handler changed skb->dev, to divert the skb to another
+ * net_device, it should return RX_HANDLER_ANOTHER. The rx_handler for the
+ * new device will be called if it exists.
+ *
+ * If the rx_handler consider the skb should be ignored, it should return
+ * RX_HANDLER_EXACT. The skb will only be delivered to protocol handlers that
+ * are registred on exact device (ptype->dev == skb->dev).
+ *
+ * If the rx_handler didn't changed skb->dev, but want the skb to be normally
+ * delivered, it should return RX_HANDLER_PASS.
+ *
+ * A device without a registered rx_handler will behave as if rx_handler
+ * returned RX_HANDLER_PASS.
+ */
+
+enum rx_handler_result {
+ RX_HANDLER_CONSUMED,
+ RX_HANDLER_ANOTHER,
+ RX_HANDLER_EXACT,
+ RX_HANDLER_PASS,
+};
+typedef enum rx_handler_result rx_handler_result_t;
+typedef rx_handler_result_t rx_handler_func_t(struct sk_buff **pskb);
extern void __napi_schedule(struct napi_struct *n);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 31f02d0..24cfa62 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -388,10 +388,7 @@ struct sk_buff {
kmemcheck_bitfield_begin(flags2);
__u16 queue_mapping:16;
#ifdef CONFIG_IPV6_NDISC_NODETYPE
- __u8 ndisc_nodetype:2,
- deliver_no_wcard:1;
-#else
- __u8 deliver_no_wcard:1;
+ __u8 ndisc_nodetype:2;
#endif
__u8 ooo_okay:1;
kmemcheck_bitfield_end(flags2);
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 88e4aa9..e216079 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -139,21 +139,22 @@ static inline int is_link_local(const unsigned char *dest)
* Return NULL if skb is handled
* note: already called with rcu_read_lock
*/
-struct sk_buff *br_handle_frame(struct sk_buff *skb)
+rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
{
struct net_bridge_port *p;
+ struct sk_buff *skb = *pskb;
const unsigned char *dest = eth_hdr(skb)->h_dest;
br_should_route_hook_t *rhook;
if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
- return skb;
+ return RX_HANDLER_PASS;
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
goto drop;
skb = skb_share_check(skb, GFP_ATOMIC);
if (!skb)
- return NULL;
+ return RX_HANDLER_CONSUMED;
p = br_port_get_rcu(skb->dev);
@@ -167,10 +168,12 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb)
goto forward;
if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
- NULL, br_handle_local_finish))
- return NULL; /* frame consumed by filter */
- else
- return skb; /* continue processing */
+ NULL, br_handle_local_finish)) {
+ return RX_HANDLER_CONSUMED; /* consumed by filter */
+ } else {
+ *pskb = skb;
+ return RX_HANDLER_PASS; /* continue processing */
+ }
}
forward:
@@ -178,8 +181,10 @@ forward:
case BR_STATE_FORWARDING:
rhook = rcu_dereference(br_should_route_hook);
if (rhook) {
- if ((*rhook)(skb))
- return skb;
+ if ((*rhook)(skb)) {
+ *pskb = skb;
+ return RX_HANDLER_PASS;
+ }
dest = eth_hdr(skb)->h_dest;
}
/* fall through */
@@ -194,5 +199,5 @@ forward:
drop:
kfree_skb(skb);
}
- return NULL;
+ return RX_HANDLER_CONSUMED;
}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index f7afc36..19e2f46 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -379,7 +379,7 @@ extern void br_features_recompute(struct net_bridge *br);
/* br_input.c */
extern int br_handle_frame_finish(struct sk_buff *skb);
-extern struct sk_buff *br_handle_frame(struct sk_buff *skb);
+extern rx_handler_result_t br_handle_frame(struct sk_buff **pskb);
/* br_ioctl.c */
extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
diff --git a/net/core/dev.c b/net/core/dev.c
index 9f66de9..329e670 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3062,6 +3062,8 @@ out:
* on a failure.
*
* The caller must hold the rtnl_mutex.
+ *
+ * For a general description of rx_handler, see enum rx_handler_result.
*/
int netdev_rx_handler_register(struct net_device *dev,
rx_handler_func_t *rx_handler,
@@ -3121,6 +3123,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
rx_handler_func_t *rx_handler;
struct net_device *orig_dev;
struct net_device *null_or_dev;
+ bool deliver_exact = false;
int ret = NET_RX_DROP;
__be16 type;
@@ -3173,18 +3176,22 @@ ncls:
rx_handler = rcu_dereference(skb->dev->rx_handler);
if (rx_handler) {
- struct net_device *prev_dev;
-
if (pt_prev) {
ret = deliver_skb(skb, pt_prev, orig_dev);
pt_prev = NULL;
}
- prev_dev = skb->dev;
- skb = rx_handler(skb);
- if (!skb)
+ switch (rx_handler(&skb)) {
+ case RX_HANDLER_CONSUMED:
goto out;
- if (skb->dev != prev_dev)
+ case RX_HANDLER_ANOTHER:
goto another_round;
+ case RX_HANDLER_EXACT:
+ deliver_exact = true;
+ case RX_HANDLER_PASS:
+ break;
+ default:
+ BUG();
+ }
}
if (vlan_tx_tag_present(skb)) {
@@ -3202,7 +3209,7 @@ ncls:
vlan_on_bond_hook(skb);
/* deliver only exact match when indicated */
- null_or_dev = skb->deliver_no_wcard ? skb->dev : NULL;
+ null_or_dev = deliver_exact ? skb->dev : NULL;
type = skb->protocol;
list_for_each_entry_rcu(ptype,
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1eb526a..801dd08 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -523,7 +523,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->ip_summed = old->ip_summed;
skb_copy_queue_mapping(new, old);
new->priority = old->priority;
- new->deliver_no_wcard = old->deliver_no_wcard;
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
new->ipvs_property = old->ipvs_property;
#endif
--
1.7.4
^ permalink raw reply related
* [patch net-next-2.6 5/6] bonding: get rid of IFF_SLAVE_INACTIVE netdev->priv_flag
From: Jiri Pirko @ 2011-03-12 13:14 UTC (permalink / raw)
To: netdev
Cc: davem, shemminger, kaber, fubar, eric.dumazet, nicolas.2p.debian,
andy, xiaosuo
In-Reply-To: <1299935679-18135-1-git-send-email-jpirko@redhat.com>
Since bond-related code was moved from net/core/dev.c into bonding,
IFF_SLAVE_INACTIVE is no longer needed. Replace is with flag "inactive"
stored in slave structure
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Reviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
---
drivers/net/bonding/bond_main.c | 6 ++----
drivers/net/bonding/bond_sysfs.c | 4 ++--
drivers/net/bonding/bonding.h | 14 ++++++++++----
include/linux/if.h | 19 +++++++++----------
4 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c5f3a01..c3150df 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1461,7 +1461,7 @@ static bool bond_should_deliver_exact_match(struct sk_buff *skb,
struct slave *slave,
struct bonding *bond)
{
- if (slave->dev->priv_flags & IFF_SLAVE_INACTIVE) {
+ if (bond_is_slave_inactive(slave)) {
if (slave_do_arp_validate(bond, slave) &&
skb->protocol == __cpu_to_be16(ETH_P_ARP))
return false;
@@ -2122,7 +2122,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
dev_set_mtu(slave_dev, slave->original_mtu);
- slave_dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_BONDING);
+ slave_dev->priv_flags &= ~IFF_BONDING;
kfree(slave);
@@ -2233,8 +2233,6 @@ static int bond_release_all(struct net_device *bond_dev)
dev_set_mac_address(slave_dev, &addr);
}
- slave_dev->priv_flags &= ~IFF_SLAVE_INACTIVE;
-
kfree(slave);
/* re-acquire the lock before getting the next slave */
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 344d23f..5161183 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1581,9 +1581,9 @@ static ssize_t bonding_store_slaves_active(struct device *d,
bond_for_each_slave(bond, slave, i) {
if (!bond_is_active_slave(slave)) {
if (new_value)
- slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE;
+ slave->inactive = 0;
else
- slave->dev->priv_flags |= IFF_SLAVE_INACTIVE;
+ slave->inactive = 1;
}
}
out:
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 63e9cf7..6b26962 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -192,8 +192,9 @@ struct slave {
unsigned long last_arp_rx;
s8 link; /* one of BOND_LINK_XXXX */
s8 new_link;
- u8 backup; /* indicates backup slave. Value corresponds with
- BOND_STATE_ACTIVE and BOND_STATE_BACKUP */
+ u8 backup:1, /* indicates backup slave. Value corresponds with
+ BOND_STATE_ACTIVE and BOND_STATE_BACKUP */
+ inactive:1; /* indicates inactive slave */
u32 original_mtu;
u32 link_failure_count;
u8 perm_hwaddr[ETH_ALEN];
@@ -376,13 +377,18 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave)
if (!bond_is_lb(bond))
bond_set_backup_slave(slave);
if (!bond->params.all_slaves_active)
- slave->dev->priv_flags |= IFF_SLAVE_INACTIVE;
+ slave->inactive = 1;
}
static inline void bond_set_slave_active_flags(struct slave *slave)
{
bond_set_active_slave(slave);
- slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE;
+ slave->inactive = 0;
+}
+
+static inline bool bond_is_slave_inactive(struct slave *slave)
+{
+ return slave->inactive;
}
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
diff --git a/include/linux/if.h b/include/linux/if.h
index 2fdd47a..0da7991 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -59,18 +59,17 @@
/* Private (from user) interface flags (netdevice->priv_flags). */
#define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */
#define IFF_EBRIDGE 0x2 /* Ethernet bridging device. */
-#define IFF_SLAVE_INACTIVE 0x4 /* bonding slave not the curr. active */
-#define IFF_BONDING 0x8 /* bonding master or slave */
-#define IFF_ISATAP 0x10 /* ISATAP interface (RFC4214) */
-#define IFF_WAN_HDLC 0x20 /* WAN HDLC device */
-#define IFF_XMIT_DST_RELEASE 0x40 /* dev_hard_start_xmit() is allowed to
+#define IFF_BONDING 0x4 /* bonding master or slave */
+#define IFF_ISATAP 0x8 /* ISATAP interface (RFC4214) */
+#define IFF_WAN_HDLC 0x10 /* WAN HDLC device */
+#define IFF_XMIT_DST_RELEASE 0x20 /* dev_hard_start_xmit() is allowed to
* release skb->dst
*/
-#define IFF_DONT_BRIDGE 0x80 /* disallow bridging this ether dev */
-#define IFF_DISABLE_NETPOLL 0x100 /* disable netpoll at run-time */
-#define IFF_MACVLAN_PORT 0x200 /* device used as macvlan port */
-#define IFF_BRIDGE_PORT 0x400 /* device used as bridge port */
-#define IFF_OVS_DATAPATH 0x800 /* device used as Open vSwitch
+#define IFF_DONT_BRIDGE 0x40 /* disallow bridging this ether dev */
+#define IFF_DISABLE_NETPOLL 0x80 /* disable netpoll at run-time */
+#define IFF_MACVLAN_PORT 0x100 /* device used as macvlan port */
+#define IFF_BRIDGE_PORT 0x200 /* device used as bridge port */
+#define IFF_OVS_DATAPATH 0x400 /* device used as Open vSwitch
* datapath port */
#define IF_GET_IFACE 0x0001 /* for querying only */
--
1.7.4
^ permalink raw reply related
* Re: [patch net-next-2.6 6/6] net: introduce rx_handler results and logic around that
From: Nicolas de Pesloüan @ 2011-03-12 13:24 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, shemminger, kaber, fubar, eric.dumazet, andy,
xiaosuo
In-Reply-To: <1299935679-18135-7-git-send-email-jpirko@redhat.com>
Le 12/03/2011 14:14, Jiri Pirko a écrit :
> This patch allows rx_handlers to better signalize what to do next to
> it's caller. That makes skb->deliver_no_wcard no longer needed.
>
> kernel-doc for rx_handler_result is taken from Nicolas' patch.
>
> Signed-off-by: Jiri Pirko<jpirko@redhat.com>
> eviewed-by: Nicolas de Pesloüan<nicolas.2p.debian@free.fr>
Typo in [R]eviewed-by and missing space between Pesloüan and <nicolas.
Nicolas.
^ permalink raw reply
* Re: [patch net-next-2.6 6/6] net: introduce rx_handler results and logic around that
From: Nicolas de Pesloüan @ 2011-03-12 13:25 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, shemminger, kaber, fubar, eric.dumazet, andy,
xiaosuo
In-Reply-To: <4D7B7403.6050402@gmail.com>
Le 12/03/2011 14:24, Nicolas de Pesloüan a écrit :
> Le 12/03/2011 14:14, Jiri Pirko a écrit :
>> This patch allows rx_handlers to better signalize what to do next to
>> it's caller. That makes skb->deliver_no_wcard no longer needed.
>>
>> kernel-doc for rx_handler_result is taken from Nicolas' patch.
>>
>> Signed-off-by: Jiri Pirko<jpirko@redhat.com>
>> eviewed-by: Nicolas de Pesloüan<nicolas.2p.debian@free.fr>
>
> Typo in [R]eviewed-by and missing space between Pesloüan and <nicolas.
>
> Nicolas.
Only the missing R in Reviewed-by:. The space was removed by my mail client, sorry.
Nicolas.
^ permalink raw reply
* Re: [patch net-next-2.6 6/6] net: introduce rx_handler results and logic around that
From: Jiri Pirko @ 2011-03-12 13:36 UTC (permalink / raw)
To: Nicolas de Pesloüan; +Cc: netdev, davem
In-Reply-To: <4D7B7453.5040606@gmail.com>
Sat, Mar 12, 2011 at 02:25:39PM CET, nicolas.2p.debian@gmail.com wrote:
>Le 12/03/2011 14:24, Nicolas de Pesloüan a écrit :
>>Le 12/03/2011 14:14, Jiri Pirko a écrit :
>>>This patch allows rx_handlers to better signalize what to do next to
>>>it's caller. That makes skb->deliver_no_wcard no longer needed.
>>>
>>>kernel-doc for rx_handler_result is taken from Nicolas' patch.
>>>
>>>Signed-off-by: Jiri Pirko<jpirko@redhat.com>
>>>eviewed-by: Nicolas de Pesloüan<nicolas.2p.debian@free.fr>
>>
>>Typo in [R]eviewed-by and missing space between Pesloüan and <nicolas.
>>
>>Nicolas.
>
>Only the missing R in Reviewed-by:. The space was removed by my mail client, sorry.
Copypaste err :( Sorry..
Dave would you please add "R" before you apply. Many thanks.
Jirka
>
> Nicolas.
>
^ permalink raw reply
* Re: fcoe: correct checking for bonding
From: David Miller @ 2011-03-12 18:59 UTC (permalink / raw)
To: jpirko
Cc: robert.w.love, James.Bottomley, linux-scsi, devel, netdev, fubar,
joe.eykholt
In-Reply-To: <20110312120109.GA2899@psychotron.redhat.com>
From: Jiri Pirko <jpirko@redhat.com>
Date: Sat, 12 Mar 2011 13:01:10 +0100
> Thu, Mar 03, 2011 at 02:09:18AM CET, robert.w.love@intel.com wrote:
>>On Wed, 2011-03-02 at 01:55 -0800, Jiri Pirko wrote:
>>> Or perhaps this should be applied to net-next?
>>>
>>I think this should go through scsi-misc as all the other
>>libfc/libfcoe/fcoe patches do.
>>
>>> Wed, Mar 02, 2011 at 07:05:35AM CET, jpirko@redhat.com wrote:
>>> >Check for bonding master and refuse to use that.
>>> >
>>> >Signed-off-by: Jiri Pirko <jpirko@redhat.com>
>>> >---
>>> > drivers/scsi/fcoe/fcoe.c | 4 +---
>>> > 1 files changed, 1 insertions(+), 3 deletions(-)
>>> >
>>> >diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
>>> >index 9f9600b..3becc6a 100644
>>> >--- a/drivers/scsi/fcoe/fcoe.c
>>> >+++ b/drivers/scsi/fcoe/fcoe.c
>>> >@@ -285,9 +285,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe,
>>> > }
>>> >
>>> > /* Do not support for bonding device */
>>> >- if ((netdev->priv_flags & IFF_MASTER_ALB) ||
>>> >- (netdev->priv_flags & IFF_SLAVE_INACTIVE) ||
>>> >- (netdev->priv_flags & IFF_MASTER_8023AD)) {
>>> >+ if (netdev->priv_flags & IFF_BONDING && netdev->flags & IFF_MASTER) {
>>> > FCOE_NETDEV_DBG(netdev, "Bonded interfaces not supported\n");
>>> > return -EOPNOTSUPP;
>>> > }
>>> >--
>>> >1.7.3.4
>>> >
>>
>>James, feel free to pick up this patch. I don't have anything in my fcoe
>>tree right now that it would conflict with. I'll also put it in my tree
>>and resend if you don't put it into scsi-misc directly.
>
> What's the status of this? Maybe this should rather go thru net-next
Sure, I can take this. I'll look at it later.
^ permalink raw reply
* Re: [net-next-2.6] Latest GIT pulled into linux-next
From: David Miller @ 2011-03-12 19:00 UTC (permalink / raw)
To: sedat.dilek, sedat.dilek; +Cc: netdev
In-Reply-To: <AANLkTi=hna0mq5QTahDP8bHCq5_6ezs7PFeimpLuUe7S@mail.gmail.com>
There is nothing us networking folks can do about a block
driver build failure.
^ permalink raw reply
* (unknown),
From: Money Gram Transfer @ 2011-03-12 15:26 UTC (permalink / raw)
My working partner in relationship with
HSBC London has concluded that our working
partner has helped us to send you first payment of US$5,000 to you as
instructed by United Nation government and will
keep sending you $5000 twice a week until
the payment of (US$420,000) is completed
within six months and here is the information
MONEY TRANSFER REFERENCE:2116-3297
SENDER'S NAME: Mike Marx
AMOUNT: US$5000
To track your funds forward money gram
Transfer agent Mr Allan Davis
Your Name.__________________________
Phone number __________________________
Contact Allan Davis for the funds clearance
certificate necessary for the transfer of your funds
E-mail:moneygramtransfer01@webadictos.net
D/L: Tel:+44 7024018331
Please direct all enquiring to:
Mr Allan Davis
^ permalink raw reply
* Re: Bad checksums and lost packets with macvlan on dummy
From: Daniel Lezcano @ 2011-03-12 21:59 UTC (permalink / raw)
To: Patrick McHardy
Cc: Andrian Nord, lxc-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Eric Dumazet, Linux Netdev List
In-Reply-To: <4D764030.8020202-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org>
Hi Patrick,
I noticed another problem with the macvlan driver.
In the function dev_forward_skb the test always succeed in the second
condition making the packet to be dropped.
...
if (unlikely(!(dev->flags & IFF_UP) ||
(skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN)))) {
...
When tracing I have the following values:
skb->len = 2962
and
dev->mtu + dev->hard_header_len + VLAN_HLEN = 1518
Do you have any idea where that could be come from ?
Thanks
-- Daniel
On 03/08/2011 03:41 PM, Patrick McHardy wrote:
> Am 02.03.2011 19:33, schrieb Daniel Lezcano:
>> On 03/02/2011 07:03 PM, Patrick McHardy wrote:
>>> Am 02.03.2011 17:03, schrieb Daniel Lezcano:
>>>> On 03/02/2011 12:03 PM, Patrick McHardy wrote:
>>>>> Am 01.03.2011 21:04, schrieb Daniel Lezcano:
>>>>>> On 03/01/2011 05:51 PM, Patrick McHardy wrote:
>>>>>>>> Patrick, do you have any suggestions to fix this ?
>>>>>>> Since the frames are only looped back locally, I suppose the easiest
>>>>>>> fix would be to mark them with CHECKSUM_UNNECESSARY. Alternatively
>>>>>>> we need to complete the checksum manually, similar to what
>>>>>>> dev_hard_start_xmit() does.
>>>>>> That sounds very simple to fix, maybe too much simple :)
>>>>>>
>>>>>> I did the following change:
>>>>>>
>>>>>> --- linux-next.orig/drivers/net/macvlan.c
>>>>>> +++ linux-next/drivers/net/macvlan.c
>>>>>> @@ -222,6 +222,7 @@ static int macvlan_queue_xmit(struct sk_
>>>>>>
>>>>>> if (vlan->mode == MACVLAN_MODE_BRIDGE) {
>>>>>> const struct ethhdr *eth = (void *)skb->data;
>>>>>> + skb->ip_summed = CHECKSUM_UNNECESSARY;
>>>>>>
>>>>>> /* send to other bridge ports directly */
>>>>>> if (is_multicast_ether_addr(eth->h_dest)) {
>>>>>>
>>>>>>
>>>>>> and that fixed the problem. Do you think it is acceptable ?
>>>>> The only problem I see is if the packets are bridged to a
>>>>> different networking device (or redirected using the mirred
>>>>> action), in this case the checksum will not be completed.
>>>>> This would be a very strange setup though and probably wouldn't
>>>>> be using dummy as lower device, so I'm not sure we have to
>>>>> worry about this case.
>>>> I am not sure to get it, do you say the patch is correct ?
>>> Its correct with a short-coming that doesn't seem to matter.
>>>
>>>> If my understanding is correct, the packet will be flagged
>>>> CHECKSUM_UNNECESSARY only for the macvlan devices, right ?
>>> Only for packets bridged between macvlan devices. A setup like
>>> the following would cause problems:
>>>
>>> br0
>>> |
>>> .----------.
>>> | |
>>> macvlan0 macvlan1 eth0
>>> | |
>>> -------.-------
>>> dummy0
>>>
>>> In this case packets sent from macvlan0 will show up on
>>> eth0 with incorrect setups. However this setup doesn't
>>> seem realistic to me, you would simply use eth0 instead
>>> of dummy0.
>> Ok, I understand. thanks for the clarification.
>>
>>>> By the way, this problem occurs for any lower device with offloading
>>>> capabilities with a macvlan port in bridge mode.
>>> True. This doesn't affect outgoing packets since their checksum
>>> will be completed in dev_hard_start_xmit(), but it affects
>>> packets bridged between macvlans.
>> One last question. In the case of broadcast packets with maclvan in
>> bridge mode.
>> We will have the packets going through each macvlan port and also to the
>> lower-device, right ?
>> For the latter, don't we have a problem if the packet is flagged
>> CHECKSUM_UNNECESSARY ?
>>
>> Shouldn't we restore the ip_summed field before sending through
>> dev_queue_xmit ?
> Yes, that seems correct in order to have dev_hard_start_xmit() complete
> the checksum if necessary.
------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox