Commit 8d018621 authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller

[TG3]: Separate requested and actual flow control parameters

This patch removes the TX and RX flow control flags from tg3_flags and
adds two new flow control variables, flowctrl and active_flowctrl.
Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a43d8994
...@@ -1602,17 +1602,19 @@ static void tg3_link_report(struct tg3 *tp) ...@@ -1602,17 +1602,19 @@ static void tg3_link_report(struct tg3 *tp)
(tp->link_config.active_duplex == DUPLEX_FULL ? (tp->link_config.active_duplex == DUPLEX_FULL ?
"full" : "half")); "full" : "half"));
printk(KERN_INFO PFX "%s: Flow control is %s for TX and " printk(KERN_INFO PFX
"%s for RX.\n", "%s: Flow control is %s for TX and %s for RX.\n",
tp->dev->name, tp->dev->name,
(tp->tg3_flags & TG3_FLAG_TX_PAUSE) ? "on" : "off", (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX) ?
(tp->tg3_flags & TG3_FLAG_RX_PAUSE) ? "on" : "off"); "on" : "off",
(tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ?
"on" : "off");
} }
} }
static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv) static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv)
{ {
u32 new_tg3_flags = 0; u8 new_tg3_flags = 0;
u32 old_rx_mode = tp->rx_mode; u32 old_rx_mode = tp->rx_mode;
u32 old_tx_mode = tp->tx_mode; u32 old_tx_mode = tp->tx_mode;
...@@ -1639,31 +1641,27 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv ...@@ -1639,31 +1641,27 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv
if (local_adv & ADVERTISE_PAUSE_CAP) { if (local_adv & ADVERTISE_PAUSE_CAP) {
if (local_adv & ADVERTISE_PAUSE_ASYM) { if (local_adv & ADVERTISE_PAUSE_ASYM) {
if (remote_adv & LPA_PAUSE_CAP) if (remote_adv & LPA_PAUSE_CAP)
new_tg3_flags |= new_tg3_flags = TG3_FLOW_CTRL_RX |
(TG3_FLAG_RX_PAUSE | TG3_FLOW_CTRL_TX;
TG3_FLAG_TX_PAUSE);
else if (remote_adv & LPA_PAUSE_ASYM) else if (remote_adv & LPA_PAUSE_ASYM)
new_tg3_flags |= new_tg3_flags = TG3_FLOW_CTRL_RX;
(TG3_FLAG_RX_PAUSE);
} else { } else {
if (remote_adv & LPA_PAUSE_CAP) if (remote_adv & LPA_PAUSE_CAP)
new_tg3_flags |= new_tg3_flags = TG3_FLOW_CTRL_RX |
(TG3_FLAG_RX_PAUSE | TG3_FLOW_CTRL_TX;
TG3_FLAG_TX_PAUSE);
} }
} else if (local_adv & ADVERTISE_PAUSE_ASYM) { } else if (local_adv & ADVERTISE_PAUSE_ASYM) {
if ((remote_adv & LPA_PAUSE_CAP) && if ((remote_adv & LPA_PAUSE_CAP) &&
(remote_adv & LPA_PAUSE_ASYM)) (remote_adv & LPA_PAUSE_ASYM))
new_tg3_flags |= TG3_FLAG_TX_PAUSE; new_tg3_flags = TG3_FLOW_CTRL_TX;
} }
tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE);
tp->tg3_flags |= new_tg3_flags;
} else { } else {
new_tg3_flags = tp->tg3_flags; new_tg3_flags = tp->link_config.flowctrl;
} }
if (new_tg3_flags & TG3_FLAG_RX_PAUSE) tp->link_config.active_flowctrl = new_tg3_flags;
if (new_tg3_flags & TG3_FLOW_CTRL_RX)
tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE; tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
else else
tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE; tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
...@@ -1672,7 +1670,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv ...@@ -1672,7 +1670,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv
tw32_f(MAC_RX_MODE, tp->rx_mode); tw32_f(MAC_RX_MODE, tp->rx_mode);
} }
if (new_tg3_flags & TG3_FLAG_TX_PAUSE) if (new_tg3_flags & TG3_FLOW_CTRL_TX)
tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE; tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
else else
tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE; tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
...@@ -2812,9 +2810,7 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset) ...@@ -2812,9 +2810,7 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
int current_link_up; int current_link_up;
int i; int i;
orig_pause_cfg = orig_pause_cfg = tp->link_config.active_flowctrl;
(tp->tg3_flags & (TG3_FLAG_RX_PAUSE |
TG3_FLAG_TX_PAUSE));
orig_active_speed = tp->link_config.active_speed; orig_active_speed = tp->link_config.active_speed;
orig_active_duplex = tp->link_config.active_duplex; orig_active_duplex = tp->link_config.active_duplex;
...@@ -2903,9 +2899,7 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset) ...@@ -2903,9 +2899,7 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
netif_carrier_off(tp->dev); netif_carrier_off(tp->dev);
tg3_link_report(tp); tg3_link_report(tp);
} else { } else {
u32 now_pause_cfg = u32 now_pause_cfg = tp->link_config.active_flowctrl;
tp->tg3_flags & (TG3_FLAG_RX_PAUSE |
TG3_FLAG_TX_PAUSE);
if (orig_pause_cfg != now_pause_cfg || if (orig_pause_cfg != now_pause_cfg ||
orig_active_speed != tp->link_config.active_speed || orig_active_speed != tp->link_config.active_speed ||
orig_active_duplex != tp->link_config.active_duplex) orig_active_duplex != tp->link_config.active_duplex)
...@@ -8569,8 +8563,16 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam ...@@ -8569,8 +8563,16 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
struct tg3 *tp = netdev_priv(dev); struct tg3 *tp = netdev_priv(dev);
epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0; epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0;
epause->rx_pause = (tp->tg3_flags & TG3_FLAG_RX_PAUSE) != 0;
epause->tx_pause = (tp->tg3_flags & TG3_FLAG_TX_PAUSE) != 0; if (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX)
epause->rx_pause = 1;
else
epause->rx_pause = 0;
if (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX)
epause->tx_pause = 1;
else
epause->tx_pause = 0;
} }
static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
...@@ -8590,13 +8592,13 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam ...@@ -8590,13 +8592,13 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
else else
tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG; tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
if (epause->rx_pause) if (epause->rx_pause)
tp->tg3_flags |= TG3_FLAG_RX_PAUSE; tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
else else
tp->tg3_flags &= ~TG3_FLAG_RX_PAUSE; tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
if (epause->tx_pause) if (epause->tx_pause)
tp->tg3_flags |= TG3_FLAG_TX_PAUSE; tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
else else
tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
if (netif_running(dev)) { if (netif_running(dev)) {
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
...@@ -12631,6 +12633,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, ...@@ -12631,6 +12633,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
/* flow control autonegotiation is default behavior */ /* flow control autonegotiation is default behavior */
tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
tp->link_config.flowctrl = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
tg3_init_coal(tp); tg3_init_coal(tp);
......
...@@ -2103,13 +2103,18 @@ struct tg3_link_config { ...@@ -2103,13 +2103,18 @@ struct tg3_link_config {
u16 speed; u16 speed;
u8 duplex; u8 duplex;
u8 autoneg; u8 autoneg;
u8 flowctrl;
#define TG3_FLOW_CTRL_TX 0x01
#define TG3_FLOW_CTRL_RX 0x02
/* Describes what we actually have. */ /* Describes what we actually have. */
u16 active_speed; u8 active_flowctrl;
u8 active_duplex; u8 active_duplex;
#define SPEED_INVALID 0xffff #define SPEED_INVALID 0xffff
#define DUPLEX_INVALID 0xff #define DUPLEX_INVALID 0xff
#define AUTONEG_INVALID 0xff #define AUTONEG_INVALID 0xff
u16 active_speed;
/* When we go in and out of low power mode we need /* When we go in and out of low power mode we need
* to swap with this state. * to swap with this state.
...@@ -2337,8 +2342,6 @@ struct tg3 { ...@@ -2337,8 +2342,6 @@ struct tg3 {
#define TG3_FLAG_EEPROM_WRITE_PROT 0x00001000 #define TG3_FLAG_EEPROM_WRITE_PROT 0x00001000
#define TG3_FLAG_NVRAM 0x00002000 #define TG3_FLAG_NVRAM 0x00002000
#define TG3_FLAG_NVRAM_BUFFERED 0x00004000 #define TG3_FLAG_NVRAM_BUFFERED 0x00004000
#define TG3_FLAG_RX_PAUSE 0x00008000
#define TG3_FLAG_TX_PAUSE 0x00010000
#define TG3_FLAG_PCIX_MODE 0x00020000 #define TG3_FLAG_PCIX_MODE 0x00020000
#define TG3_FLAG_PCI_HIGH_SPEED 0x00040000 #define TG3_FLAG_PCI_HIGH_SPEED 0x00040000
#define TG3_FLAG_PCI_32BIT 0x00080000 #define TG3_FLAG_PCI_32BIT 0x00080000
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment