summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2008-06-23 20:27:52 -0700
committerDavid S. Miller <davem@davemloft.net>2008-06-23 20:27:52 -0700
commitc18487ee24381b40df3b8b4f54dd13ee9367a1ce (patch)
tree0c52df7c30f0789fd7509426c38b2d1551c444b9 /drivers/net
parentea4e040abc72f2dbbfdd8d04e271a18593ba72c7 (diff)
bnx2x: New link code
New Link code: Moving all the link related code (including the calculations, the initialization of the MAC and PHY and the external PHY's code) into a separated file. The changes from the code that used to be part of bnx2x.c (now called bnx2x_main.c) are: - Using separate structures for link inputs and link outputs to clearly identify what was configured and what is the outcome - Adding code to read external PHY FW version and print it as part of ethtool -i - Adding code to upgrade external PHY FW from ethtool -E with special magic number - Changing the link down indication to ERR level - Adding a lock on all PHY access to prevent an interrupt and setting changes to overlap - Adding support for emulation and FPGA (small chunk of code that really helps in the lab) - Adding support for 1G on BCM8706 PHY - Adding clear debug print incase of fan failure (the PHY type is now "failure") Signed-off-by: Yaniv Rosner <yanivr@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/bnx2x.h180
-rw-r--r--drivers/net/bnx2x_init.h7
-rw-r--r--drivers/net/bnx2x_main.c3097
-rw-r--r--drivers/net/bnx2x_reg.h1939
5 files changed, 1826 insertions, 3399 deletions
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 59842a109e9d..87703ffd4c1e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -66,7 +66,7 @@ obj-$(CONFIG_FEALNX) += fealnx.o
obj-$(CONFIG_TIGON3) += tg3.o
obj-$(CONFIG_BNX2) += bnx2.o
obj-$(CONFIG_BNX2X) += bnx2x.o
-bnx2x-objs := bnx2x_main.o
+bnx2x-objs := bnx2x_main.o bnx2x_link.o
spidernet-y += spider_net.o spider_net_ethtool.o
obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 8e68d06510a6..2a13defda8ab 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -90,6 +90,12 @@
#define REG_RD_IND(bp, offset) bnx2x_reg_rd_ind(bp, offset)
#define REG_WR_IND(bp, offset, val) bnx2x_reg_wr_ind(bp, offset, val)
+#define REG_RD_DMAE(bp, offset, valp, len32) \
+ do { \
+ bnx2x_read_dmae(bp, offset, len32);\
+ memcpy(valp, bnx2x_sp(bp, wb_data[0]), len32 * 4); \
+ } while (0)
+
#define REG_WR_DMAE(bp, offset, val, len32) \
do { \
memcpy(bnx2x_sp(bp, wb_data[0]), val, len32 * 4); \
@@ -542,11 +548,8 @@ struct bnx2x {
int pm_cap;
int pcie_cap;
- /* Used to synchronize phy accesses */
- spinlock_t phy_lock;
-
- struct work_struct reset_task;
- struct work_struct sp_task;
+ struct work_struct sp_task;
+ struct work_struct reset_task;
struct timer_list timer;
int timer_interval;
@@ -568,6 +571,8 @@ struct bnx2x {
#define CHIP_REV_FPGA 0x0000f000
#define CHIP_REV_IS_SLOW(bp) ((CHIP_REV(bp) == CHIP_REV_EMUL) || \
(CHIP_REV(bp) == CHIP_REV_FPGA))
+#define CHIP_REV_IS_EMUL(bp) (CHIP_REV(bp) == CHIP_REV_EMUL)
+#define CHIP_REV_IS_FPGA(bp) (CHIP_REV(bp) == CHIP_REV_FPGA)
#define CHIP_METAL(bp) (((bp)->chip_id) & 0x00000ff0)
#define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0x0000000f)
@@ -578,84 +583,29 @@ struct bnx2x {
u32 hw_config;
u32 board;
- u32 serdes_config;
- u32 lane_config;
- u32 ext_phy_config;
-#define XGXS_EXT_PHY_TYPE(bp) (bp->ext_phy_config & \
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
-#define SERDES_EXT_PHY_TYPE(bp) (bp->ext_phy_config & \
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
-
- u32 speed_cap_mask;
- u32 link_config;
-#define SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH
-#define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH
-#define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT
-#define SWITCH_CFG_ONE_TIME_DETECT \
- PORT_FEATURE_CON_SWITCH_ONE_TIME_DETECT
-
- u8 ser_lane;
- u8 rx_lane_swap;
- u8 tx_lane_swap;
-
- u8 link_up;
- u8 phy_link_up;
+
+ struct link_params link_params;
+
+ struct link_vars link_vars;
+
+ u32 link_config;
u32 supported;
/* link settings - missing defines */
#define SUPPORTED_2500baseT_Full (1 << 15)
- u32 phy_flags;
-/*#define PHY_SERDES_FLAG 0x1*/
-#define PHY_BMAC_FLAG 0x2
-#define PHY_EMAC_FLAG 0x4
-#define PHY_XGXS_FLAG 0x8
-#define PHY_SGMII_FLAG 0x10
-#define PHY_INT_MODE_MASK_FLAG 0x300
-#define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100
-#define PHY_INT_MODE_LINK_READY_FLAG 0x200
-
u32 phy_addr;
+
+ /* used to synchronize phy accesses */
+ struct mutex phy_mutex;
+
u32 phy_id;
- u32 autoneg;
-#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
-#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
-#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
-#define AUTONEG_PARALLEL \
- SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
-#define AUTONEG_SGMII_FIBER_AUTODET \
- SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
-#define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
-
- u32 req_autoneg;
-#define AUTONEG_SPEED 0x1
-#define AUTONEG_FLOW_CTRL 0x2
-
- u32 req_line_speed;
-/* link settings - missing defines */
-#define SPEED_12000 12000
-#define SPEED_12500 12500
-#define SPEED_13000 13000
-#define SPEED_15000 15000
-#define SPEED_16000 16000
-
- u32 req_duplex;
- u32 req_flow_ctrl;
-#define FLOW_CTRL_AUTO PORT_FEATURE_FLOW_CONTROL_AUTO
-#define FLOW_CTRL_TX PORT_FEATURE_FLOW_CONTROL_TX
-#define FLOW_CTRL_RX PORT_FEATURE_FLOW_CONTROL_RX
-#define FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH
-#define FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE
u32 advertising;
/* link settings - missing defines */
#define ADVERTISED_2500baseT_Full (1 << 15)
- u32 link_status;
- u32 line_speed;
- u32 duplex;
- u32 flow_ctrl;
u32 bc_ver;
@@ -765,6 +715,11 @@ struct bnx2x {
#define DMAE_LEN32_MAX 0x400
+void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
+void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
+ u32 len32);
+int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode);
+
/* MC hsi */
#define RX_COPY_THRESH 92
@@ -890,91 +845,6 @@ struct bnx2x {
(1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT))
-#define MDIO_AN_CL73_OR_37_COMPLETE \
- (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
- MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
-
-#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
- MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
-#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
- MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
-#define GP_STATUS_SPEED_MASK \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
-#define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
-#define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
-#define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
-#define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
-#define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
-#define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
-#define GP_STATUS_10G_HIG \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
-#define GP_STATUS_10G_CX4 \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
-#define GP_STATUS_12G_HIG \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
-#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
-#define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
-#define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
-#define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
-#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
-#define GP_STATUS_10G_KX4 \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
-
-#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
-#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
-#define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
-#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
-#define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
-#define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
-#define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
-#define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
-#define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
-#define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
-#define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
-#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
-#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
-#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
-#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
-#define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
-#define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
-#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
-#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
-#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
-#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
-#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
-#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
-
-#define NIG_STATUS_XGXS0_LINK10G \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
-#define NIG_STATUS_XGXS0_LINK_STATUS \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
-#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
-#define NIG_STATUS_SERDES0_LINK_STATUS \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
-#define NIG_MASK_MI_INT \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
-#define NIG_MASK_XGXS0_LINK10G \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
-#define NIG_MASK_XGXS0_LINK_STATUS \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
-#define NIG_MASK_SERDES0_LINK_STATUS \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
-
-#define XGXS_RESET_BITS \
- (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
-
-#define SERDES_RESET_BITS \
- (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
-
-
#define BNX2X_MC_ASSERT_BITS \
(GENERAL_ATTEN_OFFSET(TSTORM_FATAL_ASSERT_ATTENTION_BIT) | \
GENERAL_ATTEN_OFFSET(USTORM_FATAL_ASSERT_ATTENTION_BIT) | \
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 370686eef97c..bb0ee2dd2d80 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -87,10 +87,6 @@ union init_op {
#include "bnx2x_init_values.h"
static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
-
-static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
- u32 dst_addr, u32 len32);
-
static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len);
static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
@@ -107,9 +103,6 @@ static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
}
}
-#define INIT_MEM_WR(reg, data, reg_off, len) \
- bnx2x_init_str_wr(bp, reg + reg_off*4, data, len)
-
static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
u16 len)
{
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 70cba64732ca..7b547f03b565 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -61,6 +61,7 @@
#include "bnx2x_reg.h"
#include "bnx2x_fw_defs.h"
#include "bnx2x_hsi.h"
+#include "bnx2x_link.h"
#include "bnx2x.h"
#include "bnx2x_init.h"
@@ -174,7 +175,7 @@ static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae,
REG_WR(bp, dmae_reg_go_c[idx], 1);
}
-static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
+void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
u32 dst_addr, u32 len32)
{
struct dmae_command *dmae = &bp->dmae;
@@ -236,8 +237,7 @@ static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
}
}
-#ifdef BNX2X_DMAE_RD
-static void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
+void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
{
struct dmae_command *dmae = &bp->dmae;
int port = bp->port;
@@ -294,7 +294,6 @@ static void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
*/
}
-#endif
static int bnx2x_mc_assert(struct bnx2x *bp)
{
@@ -1135,67 +1134,19 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
/* end of fast path */
-/* PHY/MAC */
+
+/* Link */
/*
* General service functions
*/
-static void bnx2x_leds_set(struct bnx2x *bp, unsigned int speed)
-{
- int port = bp->port;
-
- NIG_WR(NIG_REG_LED_MODE_P0 + port*4,
- ((bp->hw_config & SHARED_HW_CFG_LED_MODE_MASK) >>
- SHARED_HW_CFG_LED_MODE_SHIFT));
- NIG_WR(NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
-
- /* Set blinking rate to ~15.9Hz */
- NIG_WR(NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
- LED_BLINK_RATE_VAL);
- NIG_WR(NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + port*4, 1);
-
- /* On Ax chip versions for speeds less than 10G
- LED scheme is different */
- if ((CHIP_REV(bp) == CHIP_REV_Ax) && (speed < SPEED_10000)) {
- NIG_WR(NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 1);
- NIG_WR(NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4, 0);
- NIG_WR(NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 + port*4, 1);
- }
-}
-
-static void bnx2x_leds_unset(struct bnx2x *bp)
-{
- int port = bp->port;
-
- NIG_WR(NIG_REG_LED_10G_P0 + port*4, 0);
- NIG_WR(NIG_REG_LED_MODE_P0 + port*4, SHARED_HW_CFG_LED_MAC1);
-}
-
-static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
-{
- u32 val = REG_RD(bp, reg);
-
- val |= bits;
- REG_WR(bp, reg, val);
- return val;
-}
-
-static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
-{
- u32 val = REG_RD(bp, reg);
-
- val &= ~bits;
- REG_WR(bp, reg, val);
- return val;
-}
-
static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
{
- u32 cnt;
u32 lock_status;
u32 resource_bit = (1 << resource);
- u8 func = bp->port;
+ u8 port = bp->port;
+ int cnt;
/* Validating that the resource is within range */
if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
@@ -1206,7 +1157,7 @@ static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
}
/* Validating that the resource is not already taken */
- lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + port*8);
if (lock_status & resource_bit) {
DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
lock_status, resource_bit);
@@ -1216,9 +1167,9 @@ static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
/* Try for 1 second every 5ms */
for (cnt = 0; cnt < 200; cnt++) {
/* Try to acquire the lock */
- REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8 + 4,
+ REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + port*8 + 4,
resource_bit);
- lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + port*8);
if (lock_status & resource_bit)
return 0;
@@ -1232,7 +1183,7 @@ static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource)
{
u32 lock_status;
u32 resource_bit = (1 << resource);
- u8 func = bp->port;
+ u8 port = bp->port;
/* Validating that the resource is within range */
if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
@@ -1243,18 +1194,41 @@ static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource)
}
/* Validating that the resource is currently taken */
- lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + port*8);
if (!(lock_status & resource_bit)) {
DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
lock_status, resource_bit);
return -EFAULT;
}
- REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8, resource_bit);
+ REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + port*8, resource_bit);
return 0;
}
-static int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
+/* HW Lock for shared dual port PHYs */
+static void bnx2x_phy_hw_lock(struct bnx2x *bp)
+{
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+
+ mutex_lock(&bp->phy_mutex);
+
+ if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
+ (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+}
+
+static void bnx2x_phy_hw_unlock(struct bnx2x *bp)
+{
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+
+ if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
+ (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+
+ mutex_unlock(&bp->phy_mutex);
+}
+
+int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
{
/* The GPIO should be swapped if swap register is set and active */
int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
@@ -1353,1281 +1327,45 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
return 0;
}
-static int bnx2x_mdio22_write(struct bnx2x *bp, u32 reg, u32 val)
-{
- int port = bp->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 tmp;
- int i, rc;
-
-/* DP(NETIF_MSG_HW, "phy_addr 0x%x reg 0x%x val 0x%08x\n",
- bp->phy_addr, reg, val); */
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- tmp &= ~EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
- REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
- }
-
- tmp = ((bp->phy_addr << 21) | (reg << 16) |
- (val & EMAC_MDIO_COMM_DATA) |
- EMAC_MDIO_COMM_COMMAND_WRITE_22 |
- EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
- if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
-
- if (tmp & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("write phy register failed\n");
-
- rc = -EBUSY;
- } else {
- rc = 0;
- }
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- tmp |= EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
- }
-
- return rc;
-}
-
-static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val)
-{
- int port = bp->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 val;
- int i, rc;
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- val &= ~EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
- REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
- }
-
- val = ((bp->phy_addr << 21) | (reg << 16) |
- EMAC_MDIO_COMM_COMMAND_READ_22 |
- EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
- if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
- val &= EMAC_MDIO_COMM_DATA;
- break;
- }
- }
-
- if (val & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("read phy register failed\n");
-
- *ret_val = 0x0;
- rc = -EBUSY;
- } else {
- *ret_val = val;
- rc = 0;
- }
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- val |= EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
- }
-
-/* DP(NETIF_MSG_HW, "phy_addr 0x%x reg 0x%x ret_val 0x%08x\n",
- bp->phy_addr, reg, *ret_val); */
-
- return rc;
-}
-
-static int bnx2x_mdio45_ctrl_write(struct bnx2x *bp, u32 mdio_ctrl,
- u32 phy_addr, u32 reg, u32 addr, u32 val)
-{
- u32 tmp;
- int i, rc = 0;
-
- /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
- * (a value of 49==0x31) and make sure that the AUTO poll is off
- */
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- tmp &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
- tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
- (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
- REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
-
- /* address */
- tmp = ((phy_addr << 21) | (reg << 16) | addr |
- EMAC_MDIO_COMM_COMMAND_ADDRESS |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
- if (tmp & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("write phy register failed\n");
-
- rc = -EBUSY;
-
- } else {
- /* data */
- tmp = ((phy_addr << 21) | (reg << 16) | val |
- EMAC_MDIO_COMM_COMMAND_WRITE_45 |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
-
- if (tmp & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("write phy register failed\n");
-
- rc = -EBUSY;
- }
- }
-
- /* unset clause 45 mode, set the MDIO clock to a faster value
- * (0x13 => 6.25Mhz) and restore the AUTO poll if needed
- */
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- tmp &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT);
- tmp |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG)
- tmp |= EMAC_MDIO_MODE_AUTO_POLL;
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
-
- return rc;
-}
-
-static int bnx2x_mdio45_write(struct bnx2x *bp, u32 phy_addr, u32 reg,
- u32 addr, u32 val)
-{
- u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-
- return bnx2x_mdio45_ctrl_write(bp, emac_base, phy_addr,
- reg, addr, val);
-}
-
-static int bnx2x_mdio45_ctrl_read(struct bnx2x *bp, u32 mdio_ctrl,
- u32 phy_addr, u32 reg, u32 addr,
- u32 *ret_val)
-{
- u32 val;
- int i, rc = 0;
-
- /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
- * (a value of 49==0x31) and make sure that the AUTO poll is off
- */
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- val &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
- val |= (EMAC_MDIO_MODE_CLAUSE_45 |
- (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
- REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
-
- /* address */
- val = ((phy_addr << 21) | (reg << 16) | addr |
- EMAC_MDIO_COMM_COMMAND_ADDRESS |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
- if (val & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("read phy register failed\n");
-
- *ret_val = 0;
- rc = -EBUSY;
-
- } else {
- /* data */
- val = ((phy_addr << 21) | (reg << 16) |
- EMAC_MDIO_COMM_COMMAND_READ_45 |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
- val &= EMAC_MDIO_COMM_DATA;
- break;
- }
- }
-
- if (val & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("read phy register failed\n");
-
- val = 0;
- rc = -EBUSY;
- }
-
- *ret_val = val;
- }
-
- /* unset clause 45 mode, set the MDIO clock to a faster value
- * (0x13 => 6.25Mhz) and restore the AUTO poll if needed
- */
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- val &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT);
- val |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG)
- val |= EMAC_MDIO_MODE_AUTO_POLL;
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
-
- return rc;
-}
-
-static int bnx2x_mdio45_read(struct bnx2x *bp, u32 phy_addr, u32 reg,
- u32 addr, u32 *ret_val)
-{
- u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-
- return bnx2x_mdio45_ctrl_read(bp, emac_base, phy_addr,
- reg, addr, ret_val);
-}
-
-static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 phy_addr, u32 reg,
- u32 addr, u32 val)
-{
- int i;
- u32 rd_val;
-
- might_sleep();
- for (i = 0; i < 10; i++) {
- bnx2x_mdio45_write(bp, phy_addr, reg, addr, val);
- msleep(5);
- bnx2x_mdio45_read(bp, phy_addr, reg, addr, &rd_val);
- /* if the read value is not the same as the value we wrote,
- we should write it again */
- if (rd_val == val)
- return 0;
- }
- BNX2X_ERR("MDIO write in CL45 failed\n");
- return -EBUSY;
-}
-
-/*
- * link management
- */
-
-static void bnx2x_pause_resolve(struct bnx2x *bp, u32 pause_result)
-{
- switch (pause_result) { /* ASYM P ASYM P */
- case 0xb: /* 1 0 1 1 */
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case 0xe: /* 1 1 1 0 */
- bp->flow_ctrl = FLOW_CTRL_RX;
- break;
-
- case 0x5: /* 0 1 0 1 */
- case 0x7: /* 0 1 1 1 */
- case 0xd: /* 1 1 0 1 */
- case 0xf: /* 1 1 1 1 */
- bp->flow_ctrl = FLOW_CTRL_BOTH;
- break;
-
- default:
- break;
- }
-}
-
-static u8 bnx2x_ext_phy_resove_fc(struct bnx2x *bp)
-{
- u32 ext_phy_addr;
- u32 ld_pause; /* local */
- u32 lp_pause; /* link partner */
- u32 an_complete; /* AN complete */
- u32 pause_result;
- u8 ret = 0;
-
- ext_phy_addr = ((bp->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- /* read twice */
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_STATUS, &an_complete);
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_STATUS, &an_complete);
-
- if (an_complete & EXT_PHY_KR_AUTO_NEG_COMPLETE) {
- ret = 1;
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_AUTO_NEG_ADVERT, &ld_pause);
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_LP_AUTO_NEG, &lp_pause);
- pause_result = (ld_pause &
- EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 8;
- pause_result |= (lp_pause &
- EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 10;
- DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
- pause_result);
- bnx2x_pause_resolve(bp, pause_result);
- }
- return ret;
-}
-
-static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status)
-{
- u32 ld_pause; /* local driver */
- u32 lp_pause; /* link partner */
- u32 pause_result;
-
- bp->flow_ctrl = 0;
-
- /* resolve from gp_status in case of AN complete and not sgmii */
- if ((bp->req_autoneg & AUTONEG_FLOW_CTRL) &&
- (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
- (!(bp->phy_flags & PHY_SGMII_FLAG)) &&
- (XGXS_EXT_PHY_TYPE(bp) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
- bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
- &ld_pause);
- bnx2x_mdio22_read(bp,
- MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
- &lp_pause);
- pause_result = (ld_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
- pause_result |= (lp_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
- DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
- bnx2x_pause_resolve(bp, pause_result);
- } else if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) ||
- !(bnx2x_ext_phy_resove_fc(bp))) {
- /* forced speed */
- if (bp->req_autoneg & AUTONEG_FLOW_CTRL) {
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- if (bp->dev->mtu <= 4500)
- bp->flow_ctrl = FLOW_CTRL_BOTH;
- else
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case FLOW_CTRL_TX:
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case FLOW_CTRL_RX:
- if (bp->dev->mtu <= 4500)
- bp->flow_ctrl = FLOW_CTRL_RX;
- break;
-
- case FLOW_CTRL_BOTH:
- if (bp->dev->mtu <= 4500)
- bp->flow_ctrl = FLOW_CTRL_BOTH;
- else
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case FLOW_CTRL_NONE:
- default:
- break;
- }
- } else { /* forced mode */
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while"
- " req_autoneg 0x%x\n",
- bp->req_flow_ctrl, bp->req_autoneg);
- break;
-
- case FLOW_CTRL_TX:
- case FLOW_CTRL_RX:
- case FLOW_CTRL_BOTH:
- bp->flow_ctrl = bp->req_flow_ctrl;
- break;
-
- case FLOW_CTRL_NONE:
- default:
- break;
- }
- }
- }
- DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", bp->flow_ctrl);
-}
-
-static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status)
-{
- bp->link_status = 0;
-
- if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
- DP(NETIF_MSG_LINK, "phy link up\n");
-
- bp->phy_link_up = 1;
- bp->link_status |= LINK_STATUS_LINK_UP;
-
- if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
- bp->duplex = DUPLEX_FULL;
- else
- bp->duplex = DUPLEX_HALF;
-
- bnx2x_flow_ctrl_resolve(bp, gp_status);
-
- switch (gp_status & GP_STATUS_SPEED_MASK) {
- case GP_STATUS_10M:
- bp->line_speed = SPEED_10;
- if (bp->duplex == DUPLEX_FULL)
- bp->link_status |= LINK_10TFD;
- else
- bp->link_status |= LINK_10THD;
- break;
-
- case GP_STATUS_100M:
- bp->line_speed = SPEED_100;
- if (bp->duplex == DUPLEX_FULL)
- bp->link_status |= LINK_100TXFD;
- else
- bp->link_status |= LINK_100TXHD;
- break;
-
- case GP_STATUS_1G:
- case GP_STATUS_1G_KX:
- bp->line_speed = SPEED_1000;
- if (bp->duplex == DUPLEX_FULL)
- bp->link_status |= LINK_1000TFD;
- else
- bp->link_status |= LINK_1000THD;
- break;
-
- case GP_STATUS_2_5G:
- bp->line_speed = SPEED_2500;
- if (bp->duplex == DUPLEX_FULL)
- bp->link_status |= LINK_2500TFD;
- else
- bp->link_status |= LINK_2500THD;
- break;
-
- case GP_STATUS_5G:
- case GP_STATUS_6G:
- BNX2X_ERR("link speed unsupported gp_status 0x%x\n",
- gp_status);
- break;
-
- case GP_STATUS_10G_KX4:
- case GP_STATUS_10G_HIG:
- case GP_STATUS_10G_CX4:
- bp->line_speed = SPEED_10000;
- bp->link_status |= LINK_10GTFD;
- break;
-
- case GP_STATUS_12G_HIG:
- bp->line_speed = SPEED_12000;
- bp->link_status |= LINK_12GTFD;
- break;
-
- case GP_STATUS_12_5G:
- bp->line_speed = SPEED_12500;
- bp->link_status |= LINK_12_5GTFD;
- break;
-
- case GP_STATUS_13G:
- bp->line_speed = SPEED_13000;
- bp->link_status |= LINK_13GTFD;
- break;
-
- case GP_STATUS_15G:
- bp->line_speed = SPEED_15000;
- bp->link_status |= LINK_15GTFD;
- break;
-
- case GP_STATUS_16G:
- bp->line_speed = SPEED_16000;
- bp->link_status |= LINK_16GTFD;
- break;
-
- default:
- BNX2X_ERR("link speed unsupported gp_status 0x%x\n",
- gp_status);
- break;
- }
-
- bp->link_status |= LINK_STATUS_SERDES_LINK;
-
- if (bp->req_autoneg & AUTONEG_SPEED) {
- bp->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
-
- if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
- bp->link_status |=
- LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
-
- if (bp->autoneg & AUTONEG_PARALLEL)
- bp->link_status |=
- LINK_STATUS_PARALLEL_DETECTION_USED;
- }
-
- if (bp->flow_ctrl & FLOW_CTRL_TX)
- bp->link_status |= LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
-
- if (bp->flow_ctrl & FLOW_CTRL_RX)
- bp->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
-
- } else { /* link_down */
- DP(NETIF_MSG_LINK, "phy link down\n");
-
- bp->phy_link_up = 0;
-
- bp->line_speed = 0;
- bp->duplex = DUPLEX_FULL;
- bp->flow_ctrl = 0;
- }
-
- DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %d\n"
- DP_LEVEL " line_speed %d duplex %d flow_ctrl 0x%x"
- " link_status 0x%x\n",
- gp_status, bp->phy_link_up, bp->line_speed, bp->duplex,
- bp->flow_ctrl, bp->link_status);
-}
-
-static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g)
-{
- int port = bp->port;
-
- /* first reset all status
- * we assume only one line will be change at a time */
- bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_STATUS_XGXS0_LINK10G |
- NIG_STATUS_XGXS0_LINK_STATUS |
- NIG_STATUS_SERDES0_LINK_STATUS));
- if (bp->phy_link_up) {
- if (is_10g) {
- /* Disable the 10G link interrupt