[BNX2X]: Correct Link management

Properly protect PHY access between two devices on the same board with
a HW lock.

Use GPIO to clear all previous configurations before changing link
parameters.

Shut down the external PHY in case of fan failure.

Reducing the MDC/MDIO clock to 2.5MHz due to problems with some
devices.

Resolve the flow control response according to autoneg with external
PHY.

Unmasking all PHY interrupts in single write to prevent a race in the
interrupts order.

LASI indication fixes to work with peculiarities of PHYs.

Disable MAC RX to avoid a HW bug when closing the MAC under traffic.

Disable parallel detection on HiGig due to HW limitation.

Updating the shared memory structure to work with the current
bootcode.

Signed-off-by: Eliezer Tamir <eliezert@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c
index 7786716..5cd7850 100644
--- a/drivers/net/bnx2x.c
+++ b/drivers/net/bnx2x.c
@@ -1,6 +1,6 @@
 /* bnx2x.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -65,7 +65,7 @@
 
 #define DRV_MODULE_VERSION      "0.40.15"
 #define DRV_MODULE_RELDATE      "$DateTime: 2007/11/15 07:28:37 $"
-#define BNX2X_BC_VER    	0x040009
+#define BNX2X_BC_VER    	0x040200
 
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT      	(5*HZ)
@@ -78,7 +78,7 @@
 MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
-MODULE_INFO(cvs_version, "$Revision: #356 $");
+MODULE_INFO(cvs_version, "$Revision: #404 $");
 
 static int use_inta;
 static int poll;
@@ -1181,12 +1181,175 @@
 	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;
+
+	/* Validating that the resource is within range */
+	if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
+		DP(NETIF_MSG_HW,
+		   "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
+		   resource, HW_LOCK_MAX_RESOURCE_VALUE);
+		return -EINVAL;
+	}
+
+	/* Validating that the resource is not already taken */
+	lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+	if (lock_status & resource_bit) {
+		DP(NETIF_MSG_HW, "lock_status 0x%x  resource_bit 0x%x\n",
+		   lock_status, resource_bit);
+		return -EEXIST;
+	}
+
+	/* 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,
+		       resource_bit);
+		lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+		if (lock_status & resource_bit)
+			return 0;
+
+		msleep(5);
+	}
+	DP(NETIF_MSG_HW, "Timeout\n");
+	return -EAGAIN;
+}
+
+static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource)
+{
+	u32 lock_status;
+	u32 resource_bit = (1 << resource);
+	u8 func = bp->port;
+
+	/* Validating that the resource is within range */
+	if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
+		DP(NETIF_MSG_HW,
+		   "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
+		   resource, HW_LOCK_MAX_RESOURCE_VALUE);
+		return -EINVAL;
+	}
+
+	/* Validating that the resource is currently taken */
+	lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*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);
+	return 0;
+}
+
+static 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) &&
+			 REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ bp->port;
+	int gpio_shift = gpio_num +
+			(gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+	u32 gpio_mask = (1 << gpio_shift);
+	u32 gpio_reg;
+
+	if (gpio_num > MISC_REGISTERS_GPIO_3) {
+		BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+		return -EINVAL;
+	}
+
+	bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+	/* read GPIO and mask except the float bits */
+	gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT);
+
+	switch (mode) {
+	case MISC_REGISTERS_GPIO_OUTPUT_LOW:
+		DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n",
+		   gpio_num, gpio_shift);
+		/* clear FLOAT and set CLR */
+		gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+		gpio_reg |=  (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS);
+		break;
+
+	case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
+		DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n",
+		   gpio_num, gpio_shift);
+		/* clear FLOAT and set SET */
+		gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+		gpio_reg |=  (gpio_mask << MISC_REGISTERS_GPIO_SET_POS);
+		break;
+
+	case MISC_REGISTERS_GPIO_INPUT_HI_Z :
+		DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n",
+		   gpio_num, gpio_shift);
+		/* set FLOAT */
+		gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+		break;
+
+	default:
+		break;
+	}
+
+	REG_WR(bp, MISC_REG_GPIO, gpio_reg);
+	bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_GPIO);
+
+	return 0;
+}
+
+static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
+{
+	u32 spio_mask = (1 << spio_num);
+	u32 spio_reg;
+
+	if ((spio_num < MISC_REGISTERS_SPIO_4) ||
+	    (spio_num > MISC_REGISTERS_SPIO_7)) {
+		BNX2X_ERR("Invalid SPIO %d\n", spio_num);
+		return -EINVAL;
+	}
+
+	bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_SPIO);
+	/* read SPIO and mask except the float bits */
+	spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT);
+
+	switch (mode) {
+	case MISC_REGISTERS_SPIO_OUTPUT_LOW :
+		DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num);
+		/* clear FLOAT and set CLR */
+		spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+		spio_reg |=  (spio_mask << MISC_REGISTERS_SPIO_CLR_POS);
+		break;
+
+	case MISC_REGISTERS_SPIO_OUTPUT_HIGH :
+		DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num);
+		/* clear FLOAT and set SET */
+		spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+		spio_reg |=  (spio_mask << MISC_REGISTERS_SPIO_SET_POS);
+		break;
+
+	case MISC_REGISTERS_SPIO_INPUT_HI_Z:
+		DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num);
+		/* set FLOAT */
+		spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+		break;
+
+	default:
+		break;
+	}
+
+	REG_WR(bp, MISC_REG_SPIO, spio_reg);
+	bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_SPIO);
+
+	return 0;
+}
+
 static int bnx2x_mdio22_write(struct bnx2x *bp, u32 reg, u32 val)
 {
-	int rc;
-	u32 tmp, i;
 	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); */
@@ -1238,8 +1401,8 @@
 {
 	int port = bp->port;
 	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-	u32 val, i;
-	int rc;
+	u32 val;
+	int i, rc;
 
 	if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
 
@@ -1288,58 +1451,54 @@
 	return rc;
 }
 
-static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
+static int bnx2x_mdio45_ctrl_write(struct bnx2x *bp, u32 mdio_ctrl,
+				   u32 phy_addr, u32 reg, u32 addr, u32 val)
 {
-	int rc = 0;
-	u32 tmp, i;
-	int port = bp->port;
-	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+	u32 tmp;
+	int i, 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);
-		REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-		udelay(40);
-	}
-
-	/* set clause 45 mode */
-	tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-	tmp |= EMAC_MDIO_MODE_CLAUSE_45;
-	EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
+	/* 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 = ((bp->phy_addr << 21) | (reg << 16) | addr |
+	tmp = ((phy_addr << 21) | (reg << 16) | addr |
 	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
 	       EMAC_MDIO_COMM_START_BUSY);
-	EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+	REG_WR(bp, mdio_ctrl + 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);
+		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 = ((bp->phy_addr << 21) | (reg << 16) | val |
+		tmp = ((phy_addr << 21) | (reg << 16) | val |
 		       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
 		       EMAC_MDIO_COMM_START_BUSY);
-		EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+		REG_WR(bp, mdio_ctrl + 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);
+			tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
 			if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
 				udelay(5);
 				break;
@@ -1353,75 +1512,78 @@
 		}
 	}
 
-	/* unset clause 45 mode */
-	tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-	tmp &= ~EMAC_MDIO_MODE_CLAUSE_45;
-	EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
-
-	if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
-		tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+	/* 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;
-		EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
-	}
+	REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
 
 	return rc;
 }
 
-static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr,
-			     u32 *ret_val)
+static int bnx2x_mdio45_write(struct bnx2x *bp, u32 phy_addr, u32 reg,
+			      u32 addr, u32 val)
 {
-	int port = bp->port;
-	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-	u32 val, i;
-	int rc = 0;
+	u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 
-	if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+	return bnx2x_mdio45_ctrl_write(bp, emac_base, phy_addr,
+				       reg, addr, val);
+}
 
-		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);
-	}
+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 */
-	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-	val |= EMAC_MDIO_MODE_CLAUSE_45;
-	EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
+	/* 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 = ((bp->phy_addr << 21) | (reg << 16) | addr |
+	val = ((phy_addr << 21) | (reg << 16) | addr |
 	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
 	       EMAC_MDIO_COMM_START_BUSY);
-	EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+	REG_WR(bp, mdio_ctrl + 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);
+		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 = ((bp->phy_addr << 21) | (reg << 16) |
+		val = ((phy_addr << 21) | (reg << 16) |
 		       EMAC_MDIO_COMM_COMMAND_READ_45 |
 		       EMAC_MDIO_COMM_START_BUSY);
-		EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+		REG_WR(bp, mdio_ctrl + 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);
+			val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
 			if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
 				val &= EMAC_MDIO_COMM_DATA;
 				break;
@@ -1438,31 +1600,39 @@
 		*ret_val = val;
 	}
 
-	/* unset clause 45 mode */
-	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-	val &= ~EMAC_MDIO_MODE_CLAUSE_45;
-	EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
-
-	if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
-		val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+	/* 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;
-		EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
-	}
+	REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
 
 	return rc;
 }
 
-static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
+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, reg, addr, val);
+		bnx2x_mdio45_write(bp, phy_addr, reg, addr, val);
 		msleep(5);
-		bnx2x_mdio45_read(bp, reg, addr, &rd_val);
+		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)
@@ -1476,10 +1646,73 @@
  * 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 ld_pause;	/* local driver */
+	u32 lp_pause;	/* link partner */
 	u32 pause_result;
 
 	bp->flow_ctrl = 0;
@@ -1501,45 +1734,57 @@
 		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;
 
-		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;
-		}
-
-	} else { /* forced mode */
-		switch (bp->req_flow_ctrl) {
-		case FLOW_CTRL_AUTO:
-			if (bp->dev->mtu <= 4500)
-				bp->flow_ctrl = FLOW_CTRL_BOTH;
-			else
+			case FLOW_CTRL_TX:
 				bp->flow_ctrl = FLOW_CTRL_TX;
-			break;
+				break;
 
-		case FLOW_CTRL_TX:
-		case FLOW_CTRL_RX:
-		case FLOW_CTRL_BOTH:
-			bp->flow_ctrl = bp->req_flow_ctrl;
-			break;
+			case FLOW_CTRL_RX:
+				if (bp->dev->mtu <= 4500)
+					bp->flow_ctrl = FLOW_CTRL_RX;
+				break;
 
-		case FLOW_CTRL_NONE:
-		default:
-			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);
@@ -1550,9 +1795,9 @@
 	bp->link_status = 0;
 
 	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
-		DP(NETIF_MSG_LINK, "link up\n");
+		DP(NETIF_MSG_LINK, "phy link up\n");
 
-		bp->link_up = 1;
+		bp->phy_link_up = 1;
 		bp->link_status |= LINK_STATUS_LINK_UP;
 
 		if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
@@ -1661,20 +1906,20 @@
 		       bp->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
 
 	} else { /* link_down */
-		DP(NETIF_MSG_LINK, "link down\n");
+		DP(NETIF_MSG_LINK, "phy link down\n");
 
-		bp->link_up = 0;
+		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  link_up %d\n"
+	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->link_up, bp->line_speed, bp->duplex, bp->flow_ctrl,
-	   bp->link_status);
+	   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)
@@ -1684,38 +1929,38 @@
 	/* 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_XGXS0_LINK_STATUS |
-			NIG_SERDES0_LINK_STATUS |
-			NIG_STATUS_INTERRUPT_XGXS0_LINK10G));
-	if (bp->link_up) {
+		       (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
 			 * by writing 1 to the status register
 			 */
-			DP(NETIF_MSG_LINK, "10G XGXS link up\n");
+			DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
 			bnx2x_bits_en(bp,
 				      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
-				      NIG_STATUS_INTERRUPT_XGXS0_LINK10G);
+				      NIG_STATUS_XGXS0_LINK10G);
 
 		} else if (bp->phy_flags & PHY_XGXS_FLAG) {
 			/* Disable the link interrupt
 			 * by writing 1 to the relevant lane
 			 * in the status register
 			 */
-			DP(NETIF_MSG_LINK, "1G XGXS link up\n");
+			DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
 			bnx2x_bits_en(bp,
 				      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
 				      ((1 << bp->ser_lane) <<
-				       NIG_XGXS0_LINK_STATUS_SIZE));
+				       NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
 
 		} else { /* SerDes */
-			DP(NETIF_MSG_LINK, "SerDes link up\n");
+			DP(NETIF_MSG_LINK, "SerDes phy link up\n");
 			/* Disable the link interrupt
 			 * by writing 1 to the status register
 			 */
 			bnx2x_bits_en(bp,
 				      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
-				      NIG_SERDES0_LINK_STATUS);
+				      NIG_STATUS_SERDES0_LINK_STATUS);
 		}
 
 	} else { /* link_down */
@@ -1726,91 +1971,182 @@
 {
 	u32 ext_phy_type;
 	u32 ext_phy_addr;
-	u32 local_phy;
-	u32 val = 0;
+	u32 val1 = 0, val2;
 	u32 rx_sd, pcs_status;
 
 	if (bp->phy_flags & PHY_XGXS_FLAG) {
-		local_phy = bp->phy_addr;
 		ext_phy_addr = ((bp->ext_phy_config &
 				 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-		bp->phy_addr = (u8)ext_phy_addr;
 
 		ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
 		switch (ext_phy_type) {
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
 			DP(NETIF_MSG_LINK, "XGXS Direct\n");
-			val = 1;
+			val1 = 1;
 			break;
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
 			DP(NETIF_MSG_LINK, "XGXS 8705\n");
-			bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD,
-					  EXT_PHY_OPT_LASI_STATUS, &val);
-			DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val);
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_WIS_DEVAD,
+					  EXT_PHY_OPT_LASI_STATUS, &val1);
+			DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
 
-			bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD,
-					  EXT_PHY_OPT_LASI_STATUS, &val);
-			DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val);
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_WIS_DEVAD,
+					  EXT_PHY_OPT_LASI_STATUS, &val1);
+			DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
 
-			bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_PMA_PMD_DEVAD,
 					  EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
-			val = (rx_sd & 0x1);
+			DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
+			val1 = (rx_sd & 0x1);
 			break;
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
 			DP(NETIF_MSG_LINK, "XGXS 8706\n");
-			bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
-					  EXT_PHY_OPT_LASI_STATUS, &val);
-			DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val);
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_PMA_PMD_DEVAD,
+					  EXT_PHY_OPT_LASI_STATUS, &val1);
+			DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
 
-			bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
-					  EXT_PHY_OPT_LASI_STATUS, &val);
-			DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val);
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_PMA_PMD_DEVAD,
+					  EXT_PHY_OPT_LASI_STATUS, &val1);
+			DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
 
-			bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_PMA_PMD_DEVAD,
 					  EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
-			bnx2x_mdio45_read(bp, EXT_PHY_OPT_PCS_DEVAD,
-					 EXT_PHY_OPT_PCS_STATUS, &pcs_status);
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_PCS_DEVAD,
+					  EXT_PHY_OPT_PCS_STATUS, &pcs_status);
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_AUTO_NEG_DEVAD,
+					  EXT_PHY_OPT_AN_LINK_STATUS, &val2);
+
 			DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
-			   "  pcs_status 0x%x\n", rx_sd, pcs_status);
-			/* link is up if both bit 0 of pmd_rx and
-			 * bit 0 of pcs_status are set
+			   "  pcs_status 0x%x 1Gbps link_status 0x%x 0x%x\n",
+			   rx_sd, pcs_status, val2, (val2 & (1<<1)));
+			/* link is up if both bit 0 of pmd_rx_sd and
+			 * bit 0 of pcs_status are set, or if the autoneg bit
+			   1 is set
 			 */
-			val = (rx_sd & pcs_status);
+			val1 = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+			bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+
+			/* clear the interrupt LASI status register */
+			bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+					       ext_phy_addr,
+					       EXT_PHY_KR_PCS_DEVAD,
+					       EXT_PHY_KR_LASI_STATUS, &val2);
+			bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+					       ext_phy_addr,
+					       EXT_PHY_KR_PCS_DEVAD,
+					       EXT_PHY_KR_LASI_STATUS, &val1);
+			DP(NETIF_MSG_LINK, "KR LASI status 0x%x->0x%x\n",
+			   val2, val1);
+			/* Check the LASI */
+			bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+					       ext_phy_addr,
+					       EXT_PHY_KR_PMA_PMD_DEVAD,
+					       0x9003, &val2);
+			bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+					       ext_phy_addr,
+					       EXT_PHY_KR_PMA_PMD_DEVAD,
+					       0x9003, &val1);
+			DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
+			   val2, val1);
+			/* Check the link status */
+			bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+					       ext_phy_addr,
+					       EXT_PHY_KR_PCS_DEVAD,
+					       EXT_PHY_KR_PCS_STATUS, &val2);
+			DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
+			/* Check the link status on 1.1.2 */
+			bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+					  ext_phy_addr,
+					  EXT_PHY_OPT_PMA_PMD_DEVAD,
+					  EXT_PHY_KR_STATUS, &val2);
+			bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+					  ext_phy_addr,
+					  EXT_PHY_OPT_PMA_PMD_DEVAD,
+					  EXT_PHY_KR_STATUS, &val1);
+			DP(NETIF_MSG_LINK,
+			   "KR PMA status 0x%x->0x%x\n", val2, val1);
+			val1 = ((val1 & 4) == 4);
+			/* If 1G was requested assume the link is up */
+			if (!(bp->req_autoneg & AUTONEG_SPEED) &&
+			    (bp->req_line_speed == SPEED_1000))
+				val1 = 1;
+			bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_PMA_PMD_DEVAD,
+					  EXT_PHY_OPT_LASI_STATUS, &val2);
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_PMA_PMD_DEVAD,
+					  EXT_PHY_OPT_LASI_STATUS, &val1);
+			DP(NETIF_MSG_LINK,
+			   "10G-base-T LASI status 0x%x->0x%x\n", val2, val1);
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_PMA_PMD_DEVAD,
+					  EXT_PHY_KR_STATUS, &val2);
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_OPT_PMA_PMD_DEVAD,
+					  EXT_PHY_KR_STATUS, &val1);
+			DP(NETIF_MSG_LINK,
+			   "10G-base-T PMA status 0x%x->0x%x\n", val2, val1);
+			val1 = ((val1 & 4) == 4);
+			/* if link is up
+			 * print the AN outcome of the SFX7101 PHY
+			 */
+			if (val1) {
+				bnx2x_mdio45_read(bp, ext_phy_addr,
+						  EXT_PHY_KR_AUTO_NEG_DEVAD,
+						  0x21, &val2);
+				DP(NETIF_MSG_LINK,
+				   "SFX7101 AN status 0x%x->%s\n", val2,
+				   (val2 & (1<<14)) ? "Master" : "Slave");
+			}
 			break;
 
 		default:
 			DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
 			   bp->ext_phy_config);
-			val = 0;
+			val1 = 0;
 			break;
 		}
-		bp->phy_addr = local_phy;
 
 	} else { /* SerDes */
 		ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
 		switch (ext_phy_type) {
 		case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
 			DP(NETIF_MSG_LINK, "SerDes Direct\n");
-			val = 1;
+			val1 = 1;
 			break;
 
 		case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
 			DP(NETIF_MSG_LINK, "SerDes 5482\n");
-			val = 1;
+			val1 = 1;
 			break;
 
 		default:
 			DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
 			   bp->ext_phy_config);
-			val = 0;
+			val1 = 0;
 			break;
 		}
 	}
 
-	return val;
+	return val1;
 }
 
 static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
@@ -1935,6 +2271,35 @@
 	bp->stats_state = STATS_STATE_ENABLE;
 }
 
+static void bnx2x_bmac_rx_disable(struct bnx2x *bp)
+{
+	int port = bp->port;
+	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
+			       NIG_REG_INGRESS_BMAC0_MEM;
+	u32 wb_write[2];
+
+	/* Only if the bmac is out of reset */
+	if (REG_RD(bp, MISC_REG_RESET_REG_2) &
+			(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)) {
+		/* Clear Rx Enable bit in BMAC_CONTROL register */
+#ifdef BNX2X_DMAE_RD
+		bnx2x_read_dmae(bp, bmac_addr +
+				BIGMAC_REGISTER_BMAC_CONTROL, 2);
+		wb_write[0] = *bnx2x_sp(bp, wb_data[0]);
+		wb_write[1] = *bnx2x_sp(bp, wb_data[1]);
+#else
+		wb_write[0] = REG_RD(bp,
+				bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL);
+		wb_write[1] = REG_RD(bp,
+				bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL + 4);
+#endif
+		wb_write[0] &= ~BMAC_CONTROL_RX_ENABLE;
+		REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
+			    wb_write, 2);
+		msleep(1);
+	}
+}
+
 static void bnx2x_emac_enable(struct bnx2x *bp)
 {
 	int port = bp->port;
@@ -2233,7 +2598,7 @@
 static void bnx2x_update_mng(struct bnx2x *bp)
 {
 	if (!nomcp)
-		SHMEM_WR(bp, drv_fw_mb[bp->port].link_status,
+		SHMEM_WR(bp, port_mb[bp->port].link_status,
 			 bp->link_status);
 }
 
@@ -2295,20 +2660,20 @@
 		DP(BNX2X_MSG_STATS, "stats_state - STOP\n");
 	}
 
-	/* indicate link down */
+	/* indicate no mac active */
 	bp->phy_flags &= ~(PHY_BMAC_FLAG | PHY_EMAC_FLAG);
 
-	/* reset BigMac */
-	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
-	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
-	/* ignore drain flag interrupt */
-	/* activate nig drain */
-	NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
-
 	/* update shared memory */
 	bnx2x_update_mng(bp);
 
+	/* activate nig drain */
+	NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+
+	/* reset BigMac */
+	bnx2x_bmac_rx_disable(bp);
+	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+
 	/* indicate link down */
 	bnx2x_link_report(bp);
 }
@@ -2318,14 +2683,15 @@
 /* This function is called upon link interrupt */
 static void bnx2x_link_update(struct bnx2x *bp)
 {
-	u32 gp_status;
 	int port = bp->port;
 	int i;
+	u32 gp_status;
 	int link_10g;
 
-	DP(NETIF_MSG_LINK, "port %x, is xgxs %x, stat_mask 0x%x,"
+	DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x,"
 	   " int_mask 0x%x, saved_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
-	   " 10G %x, XGXS_LINK %x\n", port, (bp->phy_flags & PHY_XGXS_FLAG),
+	   " 10G %x, XGXS_LINK %x\n", port,
+	   (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
 	   REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
 	   REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), bp->nig_mask,
 	   REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
@@ -2337,7 +2703,7 @@
 	might_sleep();
 	MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_GP_STATUS);
 	/* avoid fast toggling */
-	for (i = 0 ; i < 10 ; i++) {
+	for (i = 0; i < 10; i++) {
 		msleep(10);
 		bnx2x_mdio22_read(bp, MDIO_GP_STATUS_TOP_AN_STATUS1,
 				  &gp_status);
@@ -2352,7 +2718,8 @@
 	bnx2x_link_int_ack(bp, link_10g);
 
 	/* link is up only if both local phy and external phy are up */
-	if (bp->link_up && bnx2x_ext_phy_is_link_up(bp)) {
+	bp->link_up = (bp->phy_link_up && bnx2x_ext_phy_is_link_up(bp));
+	if (bp->link_up) {
 		if (link_10g) {
 			bnx2x_bmac_enable(bp, 0);
 			bnx2x_leds_set(bp, SPEED_10000);
@@ -2428,7 +2795,9 @@
 		}
 	}
 
-	BNX2X_ERR("BUG! unicore is still in reset!\n");
+	BNX2X_ERR("BUG! %s (0x%x) is still in reset!\n",
+		  (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
+		  bp->phy_addr);
 }
 
 static void bnx2x_set_swap_lanes(struct bnx2x *bp)
@@ -2476,12 +2845,12 @@
 		MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_10G_PARALLEL_DETECT);
 
 		bnx2x_mdio22_write(bp,
-				   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
+				MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
 			       MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
 
 		bnx2x_mdio22_read(bp,
-				 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
-				  &control2);
+				MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+				&control2);
 
 		if (bp->autoneg & AUTONEG_PARALLEL) {
 			control2 |=
@@ -2491,8 +2860,14 @@
 		   ~MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
 		}
 		bnx2x_mdio22_write(bp,
-				 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
-				   control2);
+				MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+				control2);
+
+		/* Disable parallel detection of HiG */
+		MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2);
+		bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
+				MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
+				MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
 	}
 }
 
@@ -2626,7 +3001,7 @@
 	MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G);
 
 	/* set extended capabilities */
-	if (bp->advertising & ADVERTISED_2500baseT_Full)
+	if (bp->advertising & ADVERTISED_2500baseX_Full)
 		val |= MDIO_OVER_1G_UP1_2_5G;
 	if (bp->advertising & ADVERTISED_10000baseT_Full)
 		val |= MDIO_OVER_1G_UP1_10G;
@@ -2642,20 +3017,91 @@
 	/* for AN, we are always publishing full duplex */
 	an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
 
-	/* set pause */
-	switch (bp->pause_mode) {
-	case PAUSE_SYMMETRIC:
-		an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
-		break;
-	case PAUSE_ASYMMETRIC:
-		an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
-		break;
-	case PAUSE_BOTH:
-		an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
-		break;
-	case PAUSE_NONE:
-		an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
-		break;
+	/* resolve pause mode and advertisement
+	 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
+	if (bp->req_autoneg & AUTONEG_FLOW_CTRL) {
+		switch (bp->req_flow_ctrl) {
+		case FLOW_CTRL_AUTO:
+			if (bp->dev->mtu <= 4500) {
+				an_adv |=
+				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+				bp->advertising |= (ADVERTISED_Pause |
+						    ADVERTISED_Asym_Pause);
+			} else {
+				an_adv |=
+			       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+				bp->advertising |= ADVERTISED_Asym_Pause;
+			}
+			break;
+
+		case FLOW_CTRL_TX:
+			an_adv |=
+			       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+			bp->advertising |= ADVERTISED_Asym_Pause;
+			break;
+
+		case FLOW_CTRL_RX:
+			if (bp->dev->mtu <= 4500) {
+				an_adv |=
+				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+				bp->advertising |= (ADVERTISED_Pause |
+						    ADVERTISED_Asym_Pause);
+			} else {
+				an_adv |=
+				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+				bp->advertising &= ~(ADVERTISED_Pause |
+						     ADVERTISED_Asym_Pause);
+			}
+			break;
+
+		case FLOW_CTRL_BOTH:
+			if (bp->dev->mtu <= 4500) {
+				an_adv |=
+				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+				bp->advertising |= (ADVERTISED_Pause |
+						    ADVERTISED_Asym_Pause);
+			} else {
+				an_adv |=
+			       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+				bp->advertising |= ADVERTISED_Asym_Pause;
+			}
+			break;
+
+		case FLOW_CTRL_NONE:
+		default:
+			an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+			bp->advertising &= ~(ADVERTISED_Pause |
+					     ADVERTISED_Asym_Pause);
+			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:
+			an_adv |=
+			       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+			bp->advertising |= ADVERTISED_Asym_Pause;
+			break;
+
+		case FLOW_CTRL_RX:
+		case FLOW_CTRL_BOTH:
+			an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+			bp->advertising |= (ADVERTISED_Pause |
+					    ADVERTISED_Asym_Pause);
+			break;
+
+		case FLOW_CTRL_NONE:
+		default:
+			an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+			bp->advertising &= ~(ADVERTISED_Pause |
+					     ADVERTISED_Asym_Pause);
+			break;
+		}
 	}
 
 	MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
@@ -2753,47 +3199,162 @@
 static void bnx2x_link_int_enable(struct bnx2x *bp)
 {
 	int port = bp->port;
+	u32 ext_phy_type;
+	u32 mask;
 
 	/* setting the status to report on link up
 	   for either XGXS or SerDes */
 	bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
-		       (NIG_XGXS0_LINK_STATUS |
-			NIG_STATUS_INTERRUPT_XGXS0_LINK10G |
-			NIG_SERDES0_LINK_STATUS));
+		       (NIG_STATUS_XGXS0_LINK10G |
+			NIG_STATUS_XGXS0_LINK_STATUS |
+			NIG_STATUS_SERDES0_LINK_STATUS));
 
 	if (bp->phy_flags & PHY_XGXS_FLAG) {
-		/* TBD -
-		 * in force mode (not AN) we can enable just the relevant
-		 * interrupt
-		 * Even in AN we might enable only one according to the AN
-		 * speed mask
-		 */
-		bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
-			      (NIG_MASK_XGXS0_LINK_STATUS |
-			       NIG_MASK_XGXS0_LINK10G));
-		DP(NETIF_MSG_LINK, "enable XGXS interrupt\n");
+		mask = (NIG_MASK_XGXS0_LINK10G |
+			NIG_MASK_XGXS0_LINK_STATUS);
+		DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
+		ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+		if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+		    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+		    (ext_phy_type !=
+				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
+			mask |= NIG_MASK_MI_INT;
+			DP(NETIF_MSG_LINK, "enabled external phy int\n");
+		}
 
 	} else { /* SerDes */
-		bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
-			      NIG_MASK_SERDES0_LINK_STATUS);
-		DP(NETIF_MSG_LINK, "enable SerDes interrupt\n");
+		mask = NIG_MASK_SERDES0_LINK_STATUS;
+		DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
+		ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
+		if ((ext_phy_type !=
+				PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
+		    (ext_phy_type !=
+				PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
+			mask |= NIG_MASK_MI_INT;
+			DP(NETIF_MSG_LINK, "enabled external phy int\n");
+		}
 	}
+	bnx2x_bits_en(bp,
+		      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+		      mask);
+	DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x,"
+	   " int_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
+	   " 10G %x, XGXS_LINK %x\n", port,
+	   (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
+	   REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
+	   REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+	   REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
+	   REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c),
+	   REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+	   REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)
+	);
+}
+
+static void bnx2x_bcm8072_external_rom_boot(struct bnx2x *bp)
+{
+	u32 ext_phy_addr = ((bp->ext_phy_config &
+			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u32 fw_ver1, fw_ver2;
+
+	/* Need to wait 200ms after reset */
+	msleep(200);
+	/* Boot port from external ROM
+	 * Set ser_boot_ctl bit in the MISC_CTRL1 register
+	 */
+	bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+				EXT_PHY_KR_PMA_PMD_DEVAD,
+				EXT_PHY_KR_MISC_CTRL1, 0x0001);
+
+	/* Reset internal microprocessor */
+	bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+				EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+				EXT_PHY_KR_ROM_RESET_INTERNAL_MP);
+	/* set micro reset = 0 */
+	bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+				EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+				EXT_PHY_KR_ROM_MICRO_RESET);
+	/* Reset internal microprocessor */
+	bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+				EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+				EXT_PHY_KR_ROM_RESET_INTERNAL_MP);
+	/* wait for 100ms for code download via SPI port */
+	msleep(100);
+
+	/* Clear ser_boot_ctl bit */
+	bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+				EXT_PHY_KR_PMA_PMD_DEVAD,
+				EXT_PHY_KR_MISC_CTRL1, 0x0000);
+	/* Wait 100ms */
+	msleep(100);
+
+	/* Print the PHY FW version */
+	bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr,
+			       EXT_PHY_KR_PMA_PMD_DEVAD,
+			       0xca19, &fw_ver1);
+	bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr,
+			       EXT_PHY_KR_PMA_PMD_DEVAD,
+			       0xca1a, &fw_ver2);
+	DP(NETIF_MSG_LINK,
+	   "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+}
+
+static void bnx2x_bcm8072_force_10G(struct bnx2x *bp)
+{
+	u32 ext_phy_addr = ((bp->ext_phy_config &
+			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+	/* Force KR or KX */
+	bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+				EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL,
+				0x2040);
+	bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+				EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL2,
+				0x000b);
+	bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+				EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_PMD_CTRL,
+				0x0000);
+	bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+				EXT_PHY_KR_AUTO_NEG_DEVAD, EXT_PHY_KR_CTRL,
+				0x0000);
 }
 
 static void bnx2x_ext_phy_init(struct bnx2x *bp)
 {
-	int port = bp->port;
 	u32 ext_phy_type;
 	u32 ext_phy_addr;
-	u32 local_phy;
+	u32 cnt;
+	u32 ctrl;
+	u32 val = 0;
 
 	if (bp->phy_flags & PHY_XGXS_FLAG) {
-		local_phy = bp->phy_addr;
 		ext_phy_addr = ((bp->ext_phy_config &
 				 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
 
 		ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+		/* Make sure that the soft reset is off (expect for the 8072:
+		 * due to the lock, it will be done inside the specific
+		 * handling)
+		 */
+		if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+		    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+		   (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
+		    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)) {
+			/* Wait for soft reset to get cleared upto 1 sec */
+			for (cnt = 0; cnt < 1000; cnt++) {
+				bnx2x_mdio45_read(bp, ext_phy_addr,
+						  EXT_PHY_OPT_PMA_PMD_DEVAD,
+						  EXT_PHY_OPT_CNTL, &ctrl);
+				if (!(ctrl & (1<<15)))
+					break;
+				msleep(1);
+			}
+			DP(NETIF_MSG_LINK,
+			   "control reg 0x%x (after %d ms)\n", ctrl, cnt);
+		}
+
 		switch (ext_phy_type) {
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
 			DP(NETIF_MSG_LINK, "XGXS Direct\n");
@@ -2801,49 +3362,235 @@
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
 			DP(NETIF_MSG_LINK, "XGXS 8705\n");
-			bnx2x_bits_en(bp,
-				      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
-				      NIG_MASK_MI_INT);
-			DP(NETIF_MSG_LINK, "enabled external phy int\n");
 
-			bp->phy_addr = ext_phy_type;
-			bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+			bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+					    EXT_PHY_OPT_PMA_PMD_DEVAD,
 					    EXT_PHY_OPT_PMD_MISC_CNTL,
 					    0x8288);
-			bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+			bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+					    EXT_PHY_OPT_PMA_PMD_DEVAD,
 					    EXT_PHY_OPT_PHY_IDENTIFIER,
 					    0x7fbf);
-			bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+			bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+					    EXT_PHY_OPT_PMA_PMD_DEVAD,
 					    EXT_PHY_OPT_CMU_PLL_BYPASS,
 					    0x0100);
-			bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_WIS_DEVAD,
+			bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+					    EXT_PHY_OPT_WIS_DEVAD,
 					    EXT_PHY_OPT_LASI_CNTL, 0x1);
 			break;
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
 			DP(NETIF_MSG_LINK, "XGXS 8706\n");
-			bnx2x_bits_en(bp,
-				      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
-				      NIG_MASK_MI_INT);
-			DP(NETIF_MSG_LINK, "enabled external phy int\n");
 
-			bp->phy_addr = ext_phy_type;
-			bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
-					    EXT_PHY_OPT_PMD_DIGITAL_CNT,
-					    0x400);
-			bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+			if (!(bp->req_autoneg & AUTONEG_SPEED)) {
+				/* Force speed */
+				if (bp->req_line_speed == SPEED_10000) {
+					DP(NETIF_MSG_LINK,
+					   "XGXS 8706 force 10Gbps\n");
+					bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+						EXT_PHY_OPT_PMA_PMD_DEVAD,
+						EXT_PHY_OPT_PMD_DIGITAL_CNT,
+						0x400);
+				} else {
+					/* Force 1Gbps */
+					DP(NETIF_MSG_LINK,
+					   "XGXS 8706 force 1Gbps\n");
+
+					bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+						EXT_PHY_OPT_PMA_PMD_DEVAD,
+						EXT_PHY_OPT_CNTL,
+						0x0040);
+
+					bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+						EXT_PHY_OPT_PMA_PMD_DEVAD,
+						EXT_PHY_OPT_CNTL2,
+						0x000D);
+				}
+
+				/* Enable LASI */
+				bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+						    EXT_PHY_OPT_PMA_PMD_DEVAD,
+						    EXT_PHY_OPT_LASI_CNTL,
+						    0x1);
+			} else {
+				/* AUTONEG */
+				/* Allow CL37 through CL73 */
+				DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
+				bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+						    EXT_PHY_AUTO_NEG_DEVAD,
+						    EXT_PHY_OPT_AN_CL37_CL73,
+						    0x040c);
+
+				/* Enable Full-Duplex advertisment on CL37 */
+				bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+						    EXT_PHY_AUTO_NEG_DEVAD,
+						    EXT_PHY_OPT_AN_CL37_FD,
+						    0x0020);
+				/* Enable CL37 AN */
+				bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+						    EXT_PHY_AUTO_NEG_DEVAD,
+						    EXT_PHY_OPT_AN_CL37_AN,
+						    0x1000);
+				/* Advertise 10G/1G support */
+				if (bp->advertising &
+				    ADVERTISED_1000baseT_Full)
+					val = (1<<5);
+				if (bp->advertising &
+				    ADVERTISED_10000baseT_Full)
+					val |= (1<<7);
+
+				bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+						    EXT_PHY_AUTO_NEG_DEVAD,
+						    EXT_PHY_OPT_AN_ADV, val);
+				/* Enable LASI */
+				bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+						    EXT_PHY_OPT_PMA_PMD_DEVAD,
+						    EXT_PHY_OPT_LASI_CNTL,
+						    0x1);
+
+				/* Enable clause 73 AN */
+				bnx2x_mdio45_write(bp, ext_phy_addr,
+						   EXT_PHY_AUTO_NEG_DEVAD,
+						   EXT_PHY_OPT_CNTL,
+						   0x1200);
+			}
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+			bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+			/* Wait for soft reset to get cleared upto 1 sec */
+			for (cnt = 0; cnt < 1000; cnt++) {
+				bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+						ext_phy_addr,
+						EXT_PHY_OPT_PMA_PMD_DEVAD,
+						EXT_PHY_OPT_CNTL, &ctrl);
+				if (!(ctrl & (1<<15)))
+					break;
+				msleep(1);
+			}
+			DP(NETIF_MSG_LINK,
+			   "8072 control reg 0x%x (after %d ms)\n",
+			   ctrl, cnt);
+
+			bnx2x_bcm8072_external_rom_boot(bp);
+			DP(NETIF_MSG_LINK, "Finshed loading 8072 KR ROM\n");
+
+			/* enable LASI */
+			bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+						ext_phy_addr,
+						EXT_PHY_KR_PMA_PMD_DEVAD,
+						0x9000, 0x0400);
+			bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+						ext_phy_addr,
+						EXT_PHY_KR_PMA_PMD_DEVAD,
+						EXT_PHY_KR_LASI_CNTL, 0x0004);
+
+			/* If this is forced speed, set to KR or KX
+			 * (all other are not supported)
+			 */
+			if (!(bp->req_autoneg & AUTONEG_SPEED)) {
+				if (bp->req_line_speed == SPEED_10000) {
+					bnx2x_bcm8072_force_10G(bp);
+					DP(NETIF_MSG_LINK,
+					   "Forced speed 10G on 8072\n");
+					/* unlock */
+					bnx2x_hw_unlock(bp,
+						HW_LOCK_RESOURCE_8072_MDIO);
+					break;
+				} else
+					val = (1<<5);
+			} else {
+
+				/* Advertise 10G/1G support */
+				if (bp->advertising &
+						ADVERTISED_1000baseT_Full)
+					val = (1<<5);
+				if (bp->advertising &
+						ADVERTISED_10000baseT_Full)
+					val |= (1<<7);
+			}
+			bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+					ext_phy_addr,
+					EXT_PHY_KR_AUTO_NEG_DEVAD,
+					0x11, val);
+			/* Add support for CL37 ( passive mode ) I */
+			bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+						ext_phy_addr,
+						EXT_PHY_KR_AUTO_NEG_DEVAD,
+						0x8370, 0x040c);
+			/* Add support for CL37 ( passive mode ) II */
+			bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+						ext_phy_addr,
+						EXT_PHY_KR_AUTO_NEG_DEVAD,
+						0xffe4, 0x20);
+			/* Add support for CL37 ( passive mode ) III */
+			bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+						ext_phy_addr,
+						EXT_PHY_KR_AUTO_NEG_DEVAD,
+						0xffe0, 0x1000);
+			/* Restart autoneg */
+			msleep(500);
+			bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+					ext_phy_addr,
+					EXT_PHY_KR_AUTO_NEG_DEVAD,
+					EXT_PHY_KR_CTRL, 0x1200);
+			DP(NETIF_MSG_LINK, "8072 Autoneg Restart: "
+			   "1G %ssupported  10G %ssupported\n",
+			   (val & (1<<5)) ? "" : "not ",
+			   (val & (1<<7)) ? "" : "not ");
+
+			/* unlock */
+			bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+			DP(NETIF_MSG_LINK,
+			   "Setting the SFX7101 LASI indication\n");
+			bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+					    EXT_PHY_OPT_PMA_PMD_DEVAD,
 					    EXT_PHY_OPT_LASI_CNTL, 0x1);
+			DP(NETIF_MSG_LINK,
+			   "Setting the SFX7101 LED to blink on traffic\n");
+			bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+					    EXT_PHY_OPT_PMA_PMD_DEVAD,
+					    0xC007, (1<<3));
+
+			/* read modify write pause advertizing */
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_KR_AUTO_NEG_DEVAD,
+					  EXT_PHY_KR_AUTO_NEG_ADVERT, &val);
+			val &= ~EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH;
+			/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+			if (bp->advertising & ADVERTISED_Pause)
+				val |= EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE;
+
+			if (bp->advertising & ADVERTISED_Asym_Pause) {
+				val |=
+				 EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC;
+			}
+			DP(NETIF_MSG_LINK, "SFX7101 AN advertize 0x%x\n", val);
+			bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+					    EXT_PHY_KR_AUTO_NEG_DEVAD,
+					    EXT_PHY_KR_AUTO_NEG_ADVERT, val);
+			/* Restart autoneg */
+			bnx2x_mdio45_read(bp, ext_phy_addr,
+					  EXT_PHY_KR_AUTO_NEG_DEVAD,
+					  EXT_PHY_KR_CTRL, &val);
+			val |= 0x200;
+			bnx2x_mdio45_write(bp, ext_phy_addr,
+					    EXT_PHY_KR_AUTO_NEG_DEVAD,
+					    EXT_PHY_KR_CTRL, val);
 			break;
 
 		default:
-			DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
-			   bp->ext_phy_config);
+			BNX2X_ERR("BAD XGXS ext_phy_config 0x%x\n",
+				  bp->ext_phy_config);
 			break;
 		}
-		bp->phy_addr = local_phy;
 
 	} else { /* SerDes */
-/*      	ext_phy_addr = ((bp->ext_phy_config &
+/*		ext_phy_addr = ((bp->ext_phy_config &
 				 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >>
 				PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT);
 */
@@ -2855,10 +3602,6 @@
 
 		case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
 			DP(NETIF_MSG_LINK, "SerDes 5482\n");
-			bnx2x_bits_en(bp,
-				      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
-				      NIG_MASK_MI_INT);
-			DP(NETIF_MSG_LINK, "enabled external phy int\n");
 			break;
 
 		default:
@@ -2872,8 +3615,22 @@
 static void bnx2x_ext_phy_reset(struct bnx2x *bp)
 {
 	u32 ext_phy_type;
-	u32 ext_phy_addr;
-	u32 local_phy;
+	u32 ext_phy_addr = ((bp->ext_phy_config &
+			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK);
+
+	/* The PHY reset is controled by GPIO 1
+	 * Give it 1ms of reset pulse
+	 */
+	if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) &&
+	    (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) {
+		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+			       MISC_REGISTERS_GPIO_OUTPUT_LOW);
+		msleep(1);
+		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+			       MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+	}
 
 	if (bp->phy_flags & PHY_XGXS_FLAG) {
 		ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
@@ -2884,15 +3641,24 @@
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-			DP(NETIF_MSG_LINK, "XGXS 8705/6\n");
-			local_phy = bp->phy_addr;
-			ext_phy_addr = ((bp->ext_phy_config &
-					PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-					PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-			bp->phy_addr = (u8)ext_phy_addr;
-			bnx2x_mdio45_write(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+			DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
+			bnx2x_mdio45_write(bp, ext_phy_addr,
+					   EXT_PHY_OPT_PMA_PMD_DEVAD,
 					   EXT_PHY_OPT_CNTL, 0xa040);
-			bp->phy_addr = local_phy;
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+			DP(NETIF_MSG_LINK, "XGXS 8072\n");
+			bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+			bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+						ext_phy_addr,
+						EXT_PHY_KR_PMA_PMD_DEVAD,
+						0, 1<<15);
+			bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+			DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
 			break;
 
 		default:
@@ -2931,6 +3697,7 @@
 			NIG_MASK_SERDES0_LINK_STATUS |
 			NIG_MASK_MI_INT));
 
+	/* Activate the external PHY */
 	bnx2x_ext_phy_reset(bp);
 
 	bnx2x_set_aer_mmd(bp);
@@ -3011,11 +3778,11 @@
 		bnx2x_initialize_sgmii_process(bp);
 	}
 
-	/* enable the interrupt */
-	bnx2x_link_int_enable(bp);
-
 	/* init ext phy and enable link state int */
 	bnx2x_ext_phy_init(bp);
+
+	/* enable the interrupt */
+	bnx2x_link_int_enable(bp);
 }
 
 static void bnx2x_phy_deassert(struct bnx2x *bp)
@@ -3074,6 +3841,11 @@
 static void bnx2x_link_reset(struct bnx2x *bp)
 {
 	int port = bp->port;
+	u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK);
+
+	/* update shared memory */
+	bp->link_status = 0;
+	bnx2x_update_mng(bp);
 
 	/* disable attentions */
 	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
@@ -3082,21 +3854,45 @@
 			NIG_MASK_SERDES0_LINK_STATUS |
 			NIG_MASK_MI_INT));
 
-	bnx2x_ext_phy_reset(bp);
+	/* activate nig drain */
+	NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+
+	/* disable nig egress interface */
+	NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0);
+	NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
+
+	/* Stop BigMac rx */
+	bnx2x_bmac_rx_disable(bp);
+
+	/* disable emac */
+	NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+	msleep(10);
+
+	/* The PHY reset is controled by GPIO 1
+	 * Hold it as output low
+	 */
+	if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) &&
+	    (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) {
+		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+			       MISC_REGISTERS_GPIO_OUTPUT_LOW);
+		DP(NETIF_MSG_LINK, "reset external PHY\n");
+	}
 
 	/* reset the SerDes/XGXS */
 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
 	       (0x1ff << (port*16)));
 
-	/* reset EMAC / BMAC and disable NIG interfaces */
+	/* reset BigMac */
+	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+
+	/* disable nig ingress interface */
 	NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0);
-	NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0);
-
-	NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0);
 	NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0);
-	NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
 
-	NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+	/* set link down */
+	bp->link_up = 0;
 }
 
 #ifdef BNX2X_XGXS_LB
@@ -3177,6 +3973,7 @@
 		bnx2x_panic();
 		return -EBUSY;
 	}
+
 	/* CID needs port number to be encoded int it */
 	bp->spq_prod_bd->hdr.conn_and_cmd_data =
 			cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
@@ -4335,7 +5132,7 @@
 		return;
 
 	if (atomic_read(&bp->intr_sem) != 0)
-		goto bnx2x_restart_timer;
+		goto timer_restart;
 
 	if (poll) {
 		struct bnx2x_fastpath *fp = &bp->fp[0];
@@ -4345,7 +5142,7 @@
 		rc = bnx2x_rx_int(fp, 1000);
 	}
 
-	if (!nomcp && (bp->bc_ver >= 0x040003)) {
+	if (!nomcp) {
 		int port = bp->port;
 		u32 drv_pulse;
 		u32 mcp_pulse;
@@ -4354,9 +5151,9 @@
 		bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK;
 		/* TBD - add SYSTEM_TIME */
 		drv_pulse = bp->fw_drv_pulse_wr_seq;
-		SHMEM_WR(bp, drv_fw_mb[port].drv_pulse_mb, drv_pulse);
+		SHMEM_WR(bp, func_mb[port].drv_pulse_mb, drv_pulse);
 
-		mcp_pulse = (SHMEM_RD(bp, drv_fw_mb[port].mcp_pulse_mb) &
+		mcp_pulse = (SHMEM_RD(bp, func_mb[port].mcp_pulse_mb) &
 			     MCP_PULSE_SEQ_MASK);
 		/* The delta between driver pulse and mcp response
 		 * should be 1 (before mcp response) or 0 (after mcp response)
@@ -4370,11 +5167,11 @@
 	}
 
 	if (bp->stats_state == STATS_STATE_DISABLE)
-		goto bnx2x_restart_timer;
+		goto timer_restart;
 
 	bnx2x_update_stats(bp);
 
-bnx2x_restart_timer:
+timer_restart:
 	mod_timer(&bp->timer, jiffies + bp->current_interval);
 }
 
@@ -5266,8 +6063,10 @@
 	if (mode & 0x1) {       /* init common */
 		DP(BNX2X_MSG_MCP, "starting common init  func %d  mode %x\n",
 		   func, mode);
-		REG_WR(bp, MISC_REG_RESET_REG_1, 0xffffffff);
-		REG_WR(bp, MISC_REG_RESET_REG_2, 0xfffc);
+		REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+		       0xffffffff);
+		REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+		       0xfffc);
 		bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
 
 		REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100);
@@ -5487,6 +6286,28 @@
 		enable_blocks_attention(bp);
 		/* enable_blocks_parity(bp); */
 
+		switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+		case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+			/* Fan failure is indicated by SPIO 5 */
+			bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
+				       MISC_REGISTERS_SPIO_INPUT_HI_Z);
+
+			/* set to active low mode */
+			val = REG_RD(bp, MISC_REG_SPIO_INT);
+			val |= ((1 << MISC_REGISTERS_SPIO_5) <<
+					MISC_REGISTERS_SPIO_INT_OLD_SET_POS);
+			REG_WR(bp, MISC_REG_SPIO_INT, val);
+
+			/* enable interrupt to signal the IGU */
+			val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN);
+			val |= (1 << MISC_REGISTERS_SPIO_5);
+			REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val);
+			break;
+
+		default:
+			break;
+		}
+
 	} /* end of common init */
 
 	/* per port init */
@@ -5646,6 +6467,18 @@
 	/* Port MCP comes here */
 	/* Port DMAE comes here */
 
+	switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+	case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+		/* add SPIO 5 to group 0 */
+		val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+		val |= AEU_INPUTS_ATTN_BITS_SPIO5;
+		REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val);
+		break;
+
+	default:
+		break;
+	}
+
 	bnx2x_link_reset(bp);
 
 	/* Reset PCIE errors for debug */
@@ -5670,9 +6503,9 @@
 		port = bp->port;
 
 		bp->fw_drv_pulse_wr_seq =
-				(SHMEM_RD(bp, drv_fw_mb[port].drv_pulse_mb) &
+				(SHMEM_RD(bp, func_mb[port].drv_pulse_mb) &
 				 DRV_PULSE_SEQ_MASK);
-		bp->fw_mb = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_param);
+		bp->fw_mb = SHMEM_RD(bp, func_mb[port].fw_mb_param);
 		DP(BNX2X_MSG_MCP, "drv_pulse 0x%x  fw_mb 0x%x\n",
 		   bp->fw_drv_pulse_wr_seq, bp->fw_mb);
 	} else {
@@ -5685,12 +6518,12 @@
 /* send the MCP a request, block until there is a reply */
 static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
 {
-	u32 rc = 0;
-	u32 seq = ++bp->fw_seq;
 	int port = bp->port;
+	u32 seq = ++bp->fw_seq;
+	u32 rc = 0;
 
-	SHMEM_WR(bp, drv_fw_mb[port].drv_mb_header, command|seq);
-	DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", command|seq);
+	SHMEM_WR(bp, func_mb[port].drv_mb_header, (command | seq));
+	DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
 
 	/* let the FW do it's magic ... */
 	msleep(100); /* TBD */
@@ -5698,19 +6531,20 @@
 	if (CHIP_REV_IS_SLOW(bp))
 		msleep(900);
 
-	rc = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_header);
-
+	rc = SHMEM_RD(bp, func_mb[port].fw_mb_header);
 	DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq);
 
 	/* is this a reply to our command? */
 	if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
 		rc &= FW_MSG_CODE_MASK;
+
 	} else {
 		/* FW BUG! */
 		BNX2X_ERR("FW failed to respond!\n");
 		bnx2x_fw_dump(bp);
 		rc = 0;
 	}
+
 	return rc;
 }
 
@@ -6559,7 +7393,7 @@
 					  SUPPORTED_100baseT_Half |
 					  SUPPORTED_100baseT_Full |
 					  SUPPORTED_1000baseT_Full |
-					  SUPPORTED_2500baseT_Full |
+					  SUPPORTED_2500baseX_Full |
 					  SUPPORTED_TP | SUPPORTED_FIBRE |
 					  SUPPORTED_Autoneg |
 					  SUPPORTED_Pause |
@@ -6572,10 +7406,10 @@
 
 			bp->phy_flags |= PHY_SGMII_FLAG;
 
-			bp->supported |= (/* SUPPORTED_10baseT_Half |
-					     SUPPORTED_10baseT_Full |
-					     SUPPORTED_100baseT_Half |
-					     SUPPORTED_100baseT_Full |*/
+			bp->supported |= (SUPPORTED_10baseT_Half |
+					  SUPPORTED_10baseT_Full |
+					  SUPPORTED_100baseT_Half |
+					  SUPPORTED_100baseT_Full |
 					  SUPPORTED_1000baseT_Full |
 					  SUPPORTED_TP | SUPPORTED_FIBRE |
 					  SUPPORTED_Autoneg |
@@ -6611,7 +7445,7 @@
 					  SUPPORTED_100baseT_Half |
 					  SUPPORTED_100baseT_Full |
 					  SUPPORTED_1000baseT_Full |
-					  SUPPORTED_2500baseT_Full |
+					  SUPPORTED_2500baseX_Full |
 					  SUPPORTED_10000baseT_Full |
 					  SUPPORTED_TP | SUPPORTED_FIBRE |
 					  SUPPORTED_Autoneg |
@@ -6620,9 +7454,8 @@
 			break;
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
-		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-			BNX2X_DEV_INFO("ext_phy_type 0x%x (8705/6)\n",
-				       ext_phy_type);
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
+					ext_phy_type);
 
 			bp->supported |= (SUPPORTED_10000baseT_Full |
 					  SUPPORTED_FIBRE |
@@ -6630,6 +7463,41 @@
 					  SUPPORTED_Asym_Pause);
 			break;
 
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
+				       ext_phy_type);
+
+			bp->supported |= (SUPPORTED_10000baseT_Full |
+					  SUPPORTED_1000baseT_Full |
+					  SUPPORTED_Autoneg |
+					  SUPPORTED_FIBRE |
+					  SUPPORTED_Pause |
+					  SUPPORTED_Asym_Pause);
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
+				       ext_phy_type);
+
+			bp->supported |= (SUPPORTED_10000baseT_Full |
+					  SUPPORTED_1000baseT_Full |
+					  SUPPORTED_FIBRE |
+					  SUPPORTED_Autoneg |
+					  SUPPORTED_Pause |
+					  SUPPORTED_Asym_Pause);
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
+				       ext_phy_type);
+
+			bp->supported |= (SUPPORTED_10000baseT_Full |
+					  SUPPORTED_TP |
+					  SUPPORTED_Autoneg |
+					  SUPPORTED_Pause |
+					  SUPPORTED_Asym_Pause);
+			break;
+
 		default:
 			BNX2X_ERR("NVRAM config error. "
 				  "BAD XGXS ext_phy_config 0x%x\n",
@@ -6682,7 +7550,7 @@
 				   SUPPORTED_1000baseT_Full);
 
 	if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
-		bp->supported &= ~SUPPORTED_2500baseT_Full;
+		bp->supported &= ~SUPPORTED_2500baseX_Full;
 
 	if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
 		bp->supported &= ~SUPPORTED_10000baseT_Full;
@@ -6702,13 +7570,8 @@
 			bp->req_line_speed = 0;
 			bp->advertising = bp->supported;
 		} else {
-			u32 ext_phy_type;
-
-			ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
-			if ((ext_phy_type ==
-				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
-			    (ext_phy_type ==
-				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) {
+			if (XGXS_EXT_PHY_TYPE(bp) ==
+				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) {
 				/* force 10G, no AN */
 				bp->req_line_speed = SPEED_10000;
 				bp->advertising =
@@ -6725,8 +7588,7 @@
 		break;
 
 	case PORT_FEATURE_LINK_SPEED_10M_FULL:
-		if (bp->speed_cap_mask &
-		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) {
+		if (bp->supported & SUPPORTED_10baseT_Full) {
 			bp->req_line_speed = SPEED_10;
 			bp->advertising = (ADVERTISED_10baseT_Full |
 					   ADVERTISED_TP);
@@ -6740,8 +7602,7 @@
 		break;
 
 	case PORT_FEATURE_LINK_SPEED_10M_HALF:
-		if (bp->speed_cap_mask &
-		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
+		if (bp->supported & SUPPORTED_10baseT_Half) {
 			bp->req_line_speed = SPEED_10;
 			bp->req_duplex = DUPLEX_HALF;
 			bp->advertising = (ADVERTISED_10baseT_Half |
@@ -6756,8 +7617,7 @@
 		break;
 
 	case PORT_FEATURE_LINK_SPEED_100M_FULL:
-		if (bp->speed_cap_mask &
-		    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
+		if (bp->supported & SUPPORTED_100baseT_Full) {
 			bp->req_line_speed = SPEED_100;
 			bp->advertising = (ADVERTISED_100baseT_Full |
 					   ADVERTISED_TP);
@@ -6771,8 +7631,7 @@
 		break;
 
 	case PORT_FEATURE_LINK_SPEED_100M_HALF:
-		if (bp->speed_cap_mask &
-		    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
+		if (bp->supported & SUPPORTED_100baseT_Half) {
 			bp->req_line_speed = SPEED_100;
 			bp->req_duplex = DUPLEX_HALF;
 			bp->advertising = (ADVERTISED_100baseT_Half |
@@ -6787,8 +7646,7 @@
 		break;
 
 	case PORT_FEATURE_LINK_SPEED_1G:
-		if (bp->speed_cap_mask &
-		    PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
+		if (bp->supported & SUPPORTED_1000baseT_Full) {
 			bp->req_line_speed = SPEED_1000;
 			bp->advertising = (ADVERTISED_1000baseT_Full |
 					   ADVERTISED_TP);
@@ -6802,10 +7660,9 @@
 		break;
 
 	case PORT_FEATURE_LINK_SPEED_2_5G:
-		if (bp->speed_cap_mask &
-		    PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) {
+		if (bp->supported & SUPPORTED_2500baseX_Full) {
 			bp->req_line_speed = SPEED_2500;
-			bp->advertising = (ADVERTISED_2500baseT_Full |
+			bp->advertising = (ADVERTISED_2500baseX_Full |
 					   ADVERTISED_TP);
 		} else {
 			BNX2X_ERR("NVRAM config error. "
@@ -6819,15 +7676,7 @@
 	case PORT_FEATURE_LINK_SPEED_10G_CX4:
 	case PORT_FEATURE_LINK_SPEED_10G_KX4:
 	case PORT_FEATURE_LINK_SPEED_10G_KR:
-		if (!(bp->phy_flags & PHY_XGXS_FLAG)) {
-			BNX2X_ERR("NVRAM config error. "
-				  "Invalid link_config 0x%x"
-				  "  phy_flags 0x%x\n",
-				  bp->link_config, bp->phy_flags);
-			return;
-		}
-		if (bp->speed_cap_mask &
-		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
+		if (bp->supported & SUPPORTED_10000baseT_Full) {
 			bp->req_line_speed = SPEED_10000;
 			bp->advertising = (ADVERTISED_10000baseT_Full |
 					   ADVERTISED_FIBRE);
@@ -6854,43 +7703,13 @@
 
 	bp->req_flow_ctrl = (bp->link_config &
 			     PORT_FEATURE_FLOW_CONTROL_MASK);
-	/* Please refer to Table 28B-3 of the 802.3ab-1999 spec */
-	switch (bp->req_flow_ctrl) {
-	case FLOW_CTRL_AUTO:
+	if ((bp->req_flow_ctrl == FLOW_CTRL_AUTO) &&
+	    (bp->supported & SUPPORTED_Autoneg))
 		bp->req_autoneg |= AUTONEG_FLOW_CTRL;
-		if (bp->dev->mtu <= 4500) {
-			bp->pause_mode = PAUSE_BOTH;
-			bp->advertising |= (ADVERTISED_Pause |
-					    ADVERTISED_Asym_Pause);
-		} else {
-			bp->pause_mode = PAUSE_ASYMMETRIC;
-			bp->advertising |= ADVERTISED_Asym_Pause;
-		}
-		break;
 
-	case FLOW_CTRL_TX:
-		bp->pause_mode = PAUSE_ASYMMETRIC;
-		bp->advertising |= ADVERTISED_Asym_Pause;
-		break;
-
-	case FLOW_CTRL_RX:
-	case FLOW_CTRL_BOTH:
-		bp->pause_mode = PAUSE_BOTH;
-		bp->advertising |= (ADVERTISED_Pause |
-				    ADVERTISED_Asym_Pause);
-		break;
-
-	case FLOW_CTRL_NONE:
-	default:
-		bp->pause_mode = PAUSE_NONE;
-		bp->advertising &= ~(ADVERTISED_Pause |
-				     ADVERTISED_Asym_Pause);
-		break;
-	}
-	BNX2X_DEV_INFO("req_autoneg 0x%x  req_flow_ctrl 0x%x\n"
-	     KERN_INFO "  pause_mode %d  advertising 0x%x\n",
-		       bp->req_autoneg, bp->req_flow_ctrl,
-		       bp->pause_mode, bp->advertising);
+	BNX2X_DEV_INFO("req_autoneg 0x%x  req_flow_ctrl 0x%x"
+		       "  advertising 0x%x\n",
+		       bp->req_autoneg, bp->req_flow_ctrl, bp->advertising);
 }
 
 static void bnx2x_get_hwinfo(struct bnx2x *bp)
@@ -6923,16 +7742,16 @@
 
 	val = SHMEM_RD(bp, validity_map[port]);
 	if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
-	    != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
-		BNX2X_ERR("MCP validity signature bad\n");
+		!= (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
+		BNX2X_ERR("BAD MCP validity signature\n");
 
-	bp->fw_seq = (SHMEM_RD(bp, drv_fw_mb[port].drv_mb_header) &
+	bp->fw_seq = (SHMEM_RD(bp, func_mb[port].drv_mb_header) &
 		      DRV_MSG_SEQ_NUMBER_MASK);
 
 	bp->hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
-
+	bp->board = SHMEM_RD(bp, dev_info.shared_hw_config.board);
 	bp->serdes_config =
-		SHMEM_RD(bp, dev_info.port_hw_config[bp->port].serdes_config);
+		SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config);
 	bp->lane_config =
 		SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
 	bp->ext_phy_config =
@@ -6945,13 +7764,13 @@
 	bp->link_config =
 		SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
 
-	BNX2X_DEV_INFO("hw_config (%08x)  serdes_config (%08x)\n"
+	BNX2X_DEV_INFO("hw_config (%08x) board (%08x)  serdes_config (%08x)\n"
 	     KERN_INFO "  lane_config (%08x)  ext_phy_config (%08x)\n"
 	     KERN_INFO "  speed_cap_mask (%08x)  link_config (%08x)"
 		       "  fw_seq (%08x)\n",
-		       bp->hw_config, bp->serdes_config, bp->lane_config,
-		       bp->ext_phy_config, bp->speed_cap_mask,
-		       bp->link_config, bp->fw_seq);
+		       bp->hw_config, bp->board, bp->serdes_config,
+		       bp->lane_config, bp->ext_phy_config,
+		       bp->speed_cap_mask, bp->link_config, bp->fw_seq);
 
 	switch_cfg = (bp->link_config & PORT_FEATURE_CONNECTED_SWITCH_MASK);
 	bnx2x_link_settings_supported(bp, switch_cfg);
@@ -7005,14 +7824,8 @@
 	return;
 
 set_mac: /* only supposed to happen on emulation/FPGA */
-	BNX2X_ERR("warning constant MAC workaround active\n");
-	bp->dev->dev_addr[0] = 0;
-	bp->dev->dev_addr[1] = 0x50;
-	bp->dev->dev_addr[2] = 0xc2;
-	bp->dev->dev_addr[3] = 0x2c;
-	bp->dev->dev_addr[4] = 0x71;
-	bp->dev->dev_addr[5] = port ? 0x0d : 0x0e;
-
+	BNX2X_ERR("warning rendom MAC workaround active\n");
+	random_ether_addr(bp->dev->dev_addr);
 	memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6);
 
 }
@@ -7039,19 +7852,34 @@
 	}
 
 	if (bp->phy_flags & PHY_XGXS_FLAG) {
-		cmd->port = PORT_FIBRE;
-	} else {
+		u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+
+		switch (ext_phy_type) {
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+			cmd->port = PORT_FIBRE;
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+			cmd->port = PORT_TP;
+			break;
+
+		default:
+			DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+			   bp->ext_phy_config);
+		}
+	} else
 		cmd->port = PORT_TP;
-	}
 
 	cmd->phy_address = bp->phy_addr;
 	cmd->transceiver = XCVR_INTERNAL;
 
-	if (bp->req_autoneg & AUTONEG_SPEED) {
+	if (bp->req_autoneg & AUTONEG_SPEED)
 		cmd->autoneg = AUTONEG_ENABLE;
-	} else {
+	else
 		cmd->autoneg = AUTONEG_DISABLE;
-	}
 
 	cmd->maxtxpkt = 0;
 	cmd->maxrxpkt = 0;
@@ -7082,8 +7910,10 @@
 
 	switch (cmd->port) {
 	case PORT_TP:
-		if (!(bp->supported & SUPPORTED_TP))
+		if (!(bp->supported & SUPPORTED_TP)) {
+			DP(NETIF_MSG_LINK, "TP not supported\n");
 			return -EINVAL;
+		}
 
 		if (bp->phy_flags & PHY_XGXS_FLAG) {
 			bnx2x_link_reset(bp);
@@ -7093,8 +7923,10 @@
 		break;
 
 	case PORT_FIBRE:
-		if (!(bp->supported & SUPPORTED_FIBRE))
+		if (!(bp->supported & SUPPORTED_FIBRE)) {
+			DP(NETIF_MSG_LINK, "FIBRE not supported\n");
 			return -EINVAL;
+		}
 
 		if (!(bp->phy_flags & PHY_XGXS_FLAG)) {
 			bnx2x_link_reset(bp);
@@ -7104,12 +7936,15 @@
 		break;
 
 	default:
+		DP(NETIF_MSG_LINK, "Unknown port type\n");
 		return -EINVAL;
 	}
 
 	if (cmd->autoneg == AUTONEG_ENABLE) {
-		if (!(bp->supported & SUPPORTED_Autoneg))
+		if (!(bp->supported & SUPPORTED_Autoneg)) {
+			DP(NETIF_MSG_LINK, "Aotoneg not supported\n");
 			return -EINVAL;
+		}
 
 		/* advertise the requested speed and duplex if supported */
 		cmd->advertising &= bp->supported;
@@ -7124,14 +7959,22 @@
 		switch (cmd->speed) {
 		case SPEED_10:
 			if (cmd->duplex == DUPLEX_FULL) {
-				if (!(bp->supported & SUPPORTED_10baseT_Full))
+				if (!(bp->supported &
+				      SUPPORTED_10baseT_Full)) {
+					DP(NETIF_MSG_LINK,
+					   "10M full not supported\n");
 					return -EINVAL;
+				}
 
 				advertising = (ADVERTISED_10baseT_Full |
 					       ADVERTISED_TP);
 			} else {
-				if (!(bp->supported & SUPPORTED_10baseT_Half))
+				if (!(bp->supported &
+				      SUPPORTED_10baseT_Half)) {
+					DP(NETIF_MSG_LINK,
+					   "10M half not supported\n");
 					return -EINVAL;
+				}
 
 				advertising = (ADVERTISED_10baseT_Half |
 					       ADVERTISED_TP);
@@ -7141,15 +7984,21 @@
 		case SPEED_100:
 			if (cmd->duplex == DUPLEX_FULL) {
 				if (!(bp->supported &
-						SUPPORTED_100baseT_Full))
+						SUPPORTED_100baseT_Full)) {
+					DP(NETIF_MSG_LINK,
+					   "100M full not supported\n");
 					return -EINVAL;
+				}
 
 				advertising = (ADVERTISED_100baseT_Full |
 					       ADVERTISED_TP);
 			} else {
 				if (!(bp->supported &
-						SUPPORTED_100baseT_Half))
+						SUPPORTED_100baseT_Half)) {
+					DP(NETIF_MSG_LINK,
+					   "100M half not supported\n");
 					return -EINVAL;
+				}
 
 				advertising = (ADVERTISED_100baseT_Half |
 					       ADVERTISED_TP);
@@ -7157,39 +8006,54 @@
 			break;
 
 		case SPEED_1000:
-			if (cmd->duplex != DUPLEX_FULL)
+			if (cmd->duplex != DUPLEX_FULL) {
+				DP(NETIF_MSG_LINK, "1G half not supported\n");
 				return -EINVAL;
+			}
 
-			if (!(bp->supported & SUPPORTED_1000baseT_Full))
+			if (!(bp->supported & SUPPORTED_1000baseT_Full)) {
+				DP(NETIF_MSG_LINK, "1G full not supported\n");
 				return -EINVAL;
+			}
 
 			advertising = (ADVERTISED_1000baseT_Full |
 				       ADVERTISED_TP);
 			break;
 
 		case SPEED_2500:
-			if (cmd->duplex != DUPLEX_FULL)
+			if (cmd->duplex != DUPLEX_FULL) {
+				DP(NETIF_MSG_LINK,
+				   "2.5G half not supported\n");
 				return -EINVAL;
+			}
 
-			if (!(bp->supported & SUPPORTED_2500baseT_Full))
+			if (!(bp->supported & SUPPORTED_2500baseX_Full)) {
+				DP(NETIF_MSG_LINK,
+				   "2.5G full not supported\n");
 				return -EINVAL;
+			}
 
-			advertising = (ADVERTISED_2500baseT_Full |
+			advertising = (ADVERTISED_2500baseX_Full |
 				       ADVERTISED_TP);
 			break;
 
 		case SPEED_10000:
-			if (cmd->duplex != DUPLEX_FULL)
+			if (cmd->duplex != DUPLEX_FULL) {
+				DP(NETIF_MSG_LINK, "10G half not supported\n");
 				return -EINVAL;
+			}
 
-			if (!(bp->supported & SUPPORTED_10000baseT_Full))
+			if (!(bp->supported & SUPPORTED_10000baseT_Full)) {
+				DP(NETIF_MSG_LINK, "10G full not supported\n");
 				return -EINVAL;
+			}
 
 			advertising = (ADVERTISED_10000baseT_Full |
 				       ADVERTISED_FIBRE);
 			break;
 
 		default:
+			DP(NETIF_MSG_LINK, "Unsupported speed\n");
 			return -EINVAL;
 		}
 
@@ -7389,8 +8253,7 @@
 static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
 				  u32 cmd_flags)
 {
-	int rc;
-	int count, i;
+	int count, i, rc;
 	u32 val;
 
 	/* build the command word */
@@ -7510,8 +8373,7 @@
 static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
 				   u32 cmd_flags)
 {
-	int rc;
-	int count, i;
+	int count, i, rc;
 
 	/* build the command word */
 	cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR;
@@ -7548,7 +8410,7 @@
 	return rc;
 }
 
-#define BYTE_OFFSET(offset)     	(8 * (offset & 0x03))
+#define BYTE_OFFSET(offset)		(8 * (offset & 0x03))
 
 static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
 			      int buf_size)
@@ -7779,52 +8641,29 @@
 	   DP_LEVEL "  autoneg %d  rx_pause %d  tx_pause %d\n",
 	   epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
 
-	bp->req_flow_ctrl = FLOW_CTRL_AUTO;
 	if (epause->autoneg) {
-		bp->req_autoneg |= AUTONEG_FLOW_CTRL;
-		if (bp->dev->mtu <= 4500) {
-			bp->pause_mode = PAUSE_BOTH;
-			bp->advertising |= (ADVERTISED_Pause |
-					    ADVERTISED_Asym_Pause);
-		} else {
-			bp->pause_mode = PAUSE_ASYMMETRIC;
-			bp->advertising |= ADVERTISED_Asym_Pause;
+		if (!(bp->supported & SUPPORTED_Autoneg)) {
+			DP(NETIF_MSG_LINK, "Aotoneg not supported\n");
+			return -EINVAL;
 		}
 
-	} else {
+		bp->req_autoneg |= AUTONEG_FLOW_CTRL;
+	} else
 		bp->req_autoneg &= ~AUTONEG_FLOW_CTRL;
 
-		if (epause->rx_pause)
-			bp->req_flow_ctrl |= FLOW_CTRL_RX;
-		if (epause->tx_pause)
-			bp->req_flow_ctrl |= FLOW_CTRL_TX;
+	bp->req_flow_ctrl = FLOW_CTRL_AUTO;
 
-		switch (bp->req_flow_ctrl) {
-		case FLOW_CTRL_AUTO:
-			bp->req_flow_ctrl = FLOW_CTRL_NONE;
-			bp->pause_mode = PAUSE_NONE;
-			bp->advertising &= ~(ADVERTISED_Pause |
-					     ADVERTISED_Asym_Pause);
-			break;
+	if (epause->rx_pause)
+		bp->req_flow_ctrl |= FLOW_CTRL_RX;
+	if (epause->tx_pause)
+		bp->req_flow_ctrl |= FLOW_CTRL_TX;
 
-		case FLOW_CTRL_TX:
-			bp->pause_mode = PAUSE_ASYMMETRIC;
-			bp->advertising |= ADVERTISED_Asym_Pause;
-			break;
+	if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) &&
+	    (bp->req_flow_ctrl == FLOW_CTRL_AUTO))
+		bp->req_flow_ctrl = FLOW_CTRL_NONE;
 
-		case FLOW_CTRL_RX:
-		case FLOW_CTRL_BOTH:
-			bp->pause_mode = PAUSE_BOTH;
-			bp->advertising |= (ADVERTISED_Pause |
-					    ADVERTISED_Asym_Pause);
-			break;
-		}
-	}
-
-	DP(NETIF_MSG_LINK, "req_autoneg 0x%x  req_flow_ctrl 0x%x\n"
-	   DP_LEVEL "  pause_mode %d  advertising 0x%x\n",
-	   bp->req_autoneg, bp->req_flow_ctrl, bp->pause_mode,
-	   bp->advertising);
+	DP(NETIF_MSG_LINK, "req_autoneg 0x%x  req_flow_ctrl 0x%x\n",
+	   bp->req_autoneg, bp->req_flow_ctrl);
 
 	bnx2x_stop_stats(bp);
 	bnx2x_link_initialize(bp);