summaryrefslogtreecommitdiff
path: root/drivers/net/ixgbe/ixgbe_dcb_nl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_dcb_nl.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c119
1 files changed, 85 insertions, 34 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index bd0a0c276952..d56890f5c9d5 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -28,15 +28,22 @@
#include "ixgbe.h"
#include <linux/dcbnl.h>
+#include "ixgbe_dcb_82598.h"
+#include "ixgbe_dcb_82599.h"
/* Callbacks for DCB netlink in the kernel */
#define BIT_DCB_MODE 0x01
#define BIT_PFC 0x02
#define BIT_PG_RX 0x04
#define BIT_PG_TX 0x08
-#define BIT_BCN 0x10
+#define BIT_RESETLINK 0x40
#define BIT_LINKSPEED 0x80
+/* Responses for the DCB_C_SET_ALL command */
+#define DCB_HW_CHG_RST 0 /* DCB configuration changed with reset */
+#define DCB_NO_HW_CHG 1 /* DCB configuration did not change */
+#define DCB_HW_CHG 2 /* DCB configuration changed, no reset */
+
int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
struct ixgbe_dcb_config *dst_dcb_cfg, int tc_max)
{
@@ -124,15 +131,12 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
- ixgbe_reset_interrupt_capability(adapter);
- ixgbe_napi_del_all(adapter);
- INIT_LIST_HEAD(&netdev->napi_list);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
- adapter->tx_ring = NULL;
- adapter->rx_ring = NULL;
+ ixgbe_clear_interrupt_scheme(adapter);
- adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ adapter->last_lfc_mode = adapter->hw.fc.current_mode;
+ adapter->hw.fc.requested_mode = ixgbe_fc_none;
+ }
adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
ixgbe_init_interrupt_scheme(adapter);
@@ -141,17 +145,13 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
} else {
/* Turn off DCB */
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- adapter->hw.fc.requested_mode = ixgbe_fc_default;
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
- ixgbe_reset_interrupt_capability(adapter);
- ixgbe_napi_del_all(adapter);
- INIT_LIST_HEAD(&netdev->napi_list);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
- adapter->tx_ring = NULL;
- adapter->rx_ring = NULL;
+ ixgbe_clear_interrupt_scheme(adapter);
+ adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
+ 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;
ixgbe_init_interrupt_scheme(adapter);
@@ -167,10 +167,15 @@ static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
u8 *perm_addr)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- int i;
+ int i, j;
for (i = 0; i < netdev->addr_len; i++)
perm_addr[i] = adapter->hw.mac.perm_addr[i];
+
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ for (j = 0; j < netdev->addr_len; j++, i++)
+ perm_addr[i] = adapter->hw.mac.san_addr[j];
+ }
}
static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
@@ -197,8 +202,10 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
(adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent !=
adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) ||
(adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap !=
- adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap))
+ adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) {
adapter->dcb_set_bitmap |= BIT_PG_TX;
+ adapter->dcb_set_bitmap |= BIT_RESETLINK;
+ }
}
static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
@@ -209,8 +216,10 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct;
if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] !=
- adapter->dcb_cfg.bw_percentage[0][bwg_id])
+ adapter->dcb_cfg.bw_percentage[0][bwg_id]) {
adapter->dcb_set_bitmap |= BIT_PG_RX;
+ adapter->dcb_set_bitmap |= BIT_RESETLINK;
+ }
}
static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
@@ -237,8 +246,10 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
(adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent !=
adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) ||
(adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap !=
- adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap))
+ adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) {
adapter->dcb_set_bitmap |= BIT_PG_RX;
+ adapter->dcb_set_bitmap |= BIT_RESETLINK;
+ }
}
static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
@@ -249,8 +260,10 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct;
if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] !=
- adapter->dcb_cfg.bw_percentage[1][bwg_id])
+ adapter->dcb_cfg.bw_percentage[1][bwg_id]) {
adapter->dcb_set_bitmap |= BIT_PG_RX;
+ adapter->dcb_set_bitmap |= BIT_RESETLINK;
+ }
}
static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc,
@@ -319,28 +332,60 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
struct ixgbe_adapter *adapter = netdev_priv(netdev);
int ret;
- adapter->dcb_set_bitmap &= ~BIT_BCN; /* no set for BCN */
if (!adapter->dcb_set_bitmap)
- return 1;
+ return DCB_NO_HW_CHG;
- while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
- msleep(1);
+ /*
+ * Only take down the adapter if the configuration change
+ * requires a reset.
+ */
+ if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
+ while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
+ msleep(1);
- if (netif_running(netdev))
- ixgbe_down(adapter);
+ if (netif_running(netdev))
+ ixgbe_down(adapter);
+ }
ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
adapter->ring_feature[RING_F_DCB].indices);
if (ret) {
- clear_bit(__IXGBE_RESETTING, &adapter->state);
- return ret;
+ if (adapter->dcb_set_bitmap & BIT_RESETLINK)
+ clear_bit(__IXGBE_RESETTING, &adapter->state);
+ return DCB_NO_HW_CHG;
+ }
+
+ if (adapter->dcb_cfg.pfc_mode_enable) {
+ if ((adapter->hw.mac.type != ixgbe_mac_82598EB) &&
+ (adapter->hw.fc.current_mode != ixgbe_fc_pfc))
+ adapter->last_lfc_mode = adapter->hw.fc.current_mode;
+ adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
+ } else {
+ if (adapter->hw.mac.type != ixgbe_mac_82598EB)
+ adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
+ else
+ adapter->hw.fc.requested_mode = ixgbe_fc_none;
}
- if (netif_running(netdev))
- ixgbe_up(adapter);
+ if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
+ if (netif_running(netdev))
+ ixgbe_up(adapter);
+ ret = DCB_HW_CHG_RST;
+ } else if (adapter->dcb_set_bitmap & BIT_PFC) {
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ ixgbe_dcb_config_pfc_82598(&adapter->hw,
+ &adapter->dcb_cfg);
+ else if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ ixgbe_dcb_config_pfc_82599(&adapter->hw,
+ &adapter->dcb_cfg);
+ ret = DCB_HW_CHG;
+ }
+ if (adapter->dcb_cfg.pfc_mode_enable)
+ adapter->hw.fc.current_mode = ixgbe_fc_pfc;
+ if (adapter->dcb_set_bitmap & BIT_RESETLINK)
+ clear_bit(__IXGBE_RESETTING, &adapter->state);
adapter->dcb_set_bitmap = 0x00;
- clear_bit(__IXGBE_RESETTING, &adapter->state);
return ret;
}
@@ -416,11 +461,17 @@ static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
+ return adapter->dcb_cfg.pfc_mode_enable;
}
static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ adapter->temp_dcb_cfg.pfc_mode_enable = state;
+ if (adapter->temp_dcb_cfg.pfc_mode_enable !=
+ adapter->dcb_cfg.pfc_mode_enable)
+ adapter->dcb_set_bitmap |= BIT_PFC;
return;
}