Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3648b3d authored by Michael Chan's avatar Michael Chan Committed by John W. Linville
Browse files

[PATCH] bnx2: update firmware handshake for 5708



Dynamically determine the shared memory location where eeprom
parameters are stored instead of using a fixed location.

Add speed reporting to management firmware. This allows management
firmware to know the current speed without contending for MII
registers.

Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 37137709
Loading
Loading
Loading
Loading
+79 −15
Original line number Diff line number Diff line
@@ -436,6 +436,62 @@ bnx2_alloc_mem(struct bnx2 *bp)
	return -ENOMEM;
}

static void
bnx2_report_fw_link(struct bnx2 *bp)
{
	u32 fw_link_status = 0;

	if (bp->link_up) {
		u32 bmsr;

		switch (bp->line_speed) {
		case SPEED_10:
			if (bp->duplex == DUPLEX_HALF)
				fw_link_status = BNX2_LINK_STATUS_10HALF;
			else
				fw_link_status = BNX2_LINK_STATUS_10FULL;
			break;
		case SPEED_100:
			if (bp->duplex == DUPLEX_HALF)
				fw_link_status = BNX2_LINK_STATUS_100HALF;
			else
				fw_link_status = BNX2_LINK_STATUS_100FULL;
			break;
		case SPEED_1000:
			if (bp->duplex == DUPLEX_HALF)
				fw_link_status = BNX2_LINK_STATUS_1000HALF;
			else
				fw_link_status = BNX2_LINK_STATUS_1000FULL;
			break;
		case SPEED_2500:
			if (bp->duplex == DUPLEX_HALF)
				fw_link_status = BNX2_LINK_STATUS_2500HALF;
			else
				fw_link_status = BNX2_LINK_STATUS_2500FULL;
			break;
		}

		fw_link_status |= BNX2_LINK_STATUS_LINK_UP;

		if (bp->autoneg) {
			fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED;

			bnx2_read_phy(bp, MII_BMSR, &bmsr);
			bnx2_read_phy(bp, MII_BMSR, &bmsr);

			if (!(bmsr & BMSR_ANEGCOMPLETE) ||
			    bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)
				fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET;
			else
				fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE;
		}
	}
	else
		fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;

	REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
}

static void
bnx2_report_link(struct bnx2 *bp)
{
@@ -467,6 +523,8 @@ bnx2_report_link(struct bnx2 *bp)
		netif_carrier_off(bp->dev);
		printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
	}

	bnx2_report_fw_link(bp);
}

static void
@@ -1123,13 +1181,13 @@ bnx2_init_5708s_phy(struct bnx2 *bp)
		bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
	}

	val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_CONFIG) &
	val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) &
	      BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;

	if (val) {
		u32 is_backplane;

		is_backplane = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
		is_backplane = REG_RD_IND(bp, bp->shmem_base +
					  BNX2_SHARED_HW_CFG_CONFIG);
		if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
			bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
@@ -1280,13 +1338,13 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data)
	bp->fw_wr_seq++;
	msg_data |= bp->fw_wr_seq;

	REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);

	/* wait for an acknowledgement. */
	for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) {
		udelay(5);

		val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_FW_MB);
		val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);

		if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
			break;
@@ -1299,7 +1357,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data)
		msg_data &= ~BNX2_DRV_MSG_CODE;
		msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;

		REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
		REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);

		bp->fw_timed_out = 1;

@@ -2935,7 +2993,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)

	/* Deposit a driver reset signature so the firmware knows that
	 * this is a soft reset. */
	REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_RESET_SIGNATURE,
	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
		   BNX2_DRV_RESET_SIGNATURE_MAGIC);

	bp->fw_timed_out = 0;
@@ -4012,7 +4070,7 @@ bnx2_timer(unsigned long data)
		goto bnx2_restart_timer;

	msg = (u32) ++bp->fw_drv_pulse_wr_seq;
	REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_PULSE_MB, msg);
	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);

	if ((bp->phy_flags & PHY_SERDES_FLAG) &&
	    (CHIP_NUM(bp) == CHIP_NUM_5706)) {
@@ -5483,10 +5541,18 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)

	bnx2_init_nvram(bp);

	reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE);

	if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
	    BNX2_SHM_HDR_SIGNATURE_SIG)
		bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0);
	else
		bp->shmem_base = HOST_VIEW_SHMEM_BASE;

	/* Get the permanent MAC address.  First we need to make sure the
	 * firmware is actually running.
	 */
	reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DEV_INFO_SIGNATURE);
	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE);

	if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
	    BNX2_DEV_INFO_SIGNATURE_MAGIC) {
@@ -5495,14 +5561,13 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
		goto err_out_unmap;
	}

	bp->fw_ver = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
				BNX2_DEV_INFO_BC_REV);
	bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);

	reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_UPPER);
	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
	bp->mac_addr[0] = (u8) (reg >> 8);
	bp->mac_addr[1] = (u8) reg;

	reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_LOWER);
	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER);
	bp->mac_addr[2] = (u8) (reg >> 24);
	bp->mac_addr[3] = (u8) (reg >> 16);
	bp->mac_addr[4] = (u8) (reg >> 8);
@@ -5538,7 +5603,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
		bp->flags |= NO_WOL_FLAG;
		if (CHIP_NUM(bp) == CHIP_NUM_5708) {
			bp->phy_addr = 2;
			reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
			reg = REG_RD_IND(bp, bp->shmem_base +
					 BNX2_SHARED_HW_CFG_CONFIG);
			if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
				bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
@@ -5562,8 +5627,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
	if (bp->phy_flags & PHY_SERDES_FLAG) {
		bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;

		reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
				 BNX2_PORT_HW_CFG_CONFIG);
		reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
		reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
		if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
			bp->autoneg = 0;
+43 −0
Original line number Diff line number Diff line
@@ -3715,6 +3715,15 @@ struct l2_fhdr {
#define BNX2_MCP_ROM					0x00150000
#define BNX2_MCP_SCRATCH				0x00160000

#define BNX2_SHM_HDR_SIGNATURE				BNX2_MCP_SCRATCH
#define BNX2_SHM_HDR_SIGNATURE_SIG_MASK			 0xffff0000
#define BNX2_SHM_HDR_SIGNATURE_SIG			 0x53530000
#define BNX2_SHM_HDR_SIGNATURE_VER_MASK			 0x000000ff
#define BNX2_SHM_HDR_SIGNATURE_VER_ONE			 0x00000001

#define BNX2_SHM_HDR_ADDR_0				BNX2_MCP_SCRATCH + 4
#define BNX2_SHM_HDR_ADDR_1				BNX2_MCP_SCRATCH + 8


#define NUM_MC_HASH_REGISTERS   8

@@ -4052,6 +4061,8 @@ struct bnx2 {

	u8			mac_addr[8];

	u32			shmem_base;

	u32			fw_ver;

	int			pm_cap;
@@ -4191,6 +4202,38 @@ struct fw_info {
#define BNX2_FW_MSG_STATUS_FAILURE		 0x00ff0000

#define BNX2_LINK_STATUS			0x0000000c
#define BNX2_LINK_STATUS_INIT_VALUE		 0xffffffff 
#define BNX2_LINK_STATUS_LINK_UP		 0x1 
#define BNX2_LINK_STATUS_LINK_DOWN		 0x0 
#define BNX2_LINK_STATUS_SPEED_MASK		 0x1e
#define BNX2_LINK_STATUS_AN_INCOMPLETE		 (0<<1) 
#define BNX2_LINK_STATUS_10HALF			 (1<<1) 
#define BNX2_LINK_STATUS_10FULL			 (2<<1) 
#define BNX2_LINK_STATUS_100HALF		 (3<<1) 
#define BNX2_LINK_STATUS_100BASE_T4		 (4<<1) 
#define BNX2_LINK_STATUS_100FULL		 (5<<1) 
#define BNX2_LINK_STATUS_1000HALF		 (6<<1) 
#define BNX2_LINK_STATUS_1000FULL		 (7<<1) 
#define BNX2_LINK_STATUS_2500HALF		 (8<<1) 
#define BNX2_LINK_STATUS_2500FULL		 (9<<1) 
#define BNX2_LINK_STATUS_AN_ENABLED		 (1<<5) 
#define BNX2_LINK_STATUS_AN_COMPLETE		 (1<<6) 
#define BNX2_LINK_STATUS_PARALLEL_DET		 (1<<7) 
#define BNX2_LINK_STATUS_RESERVED		 (1<<8) 
#define BNX2_LINK_STATUS_PARTNER_AD_1000FULL	 (1<<9) 
#define BNX2_LINK_STATUS_PARTNER_AD_1000HALF	 (1<<10) 
#define BNX2_LINK_STATUS_PARTNER_AD_100BT4	 (1<<11) 
#define BNX2_LINK_STATUS_PARTNER_AD_100FULL	 (1<<12) 
#define BNX2_LINK_STATUS_PARTNER_AD_100HALF	 (1<<13) 
#define BNX2_LINK_STATUS_PARTNER_AD_10FULL	 (1<<14) 
#define BNX2_LINK_STATUS_PARTNER_AD_10HALF	 (1<<15) 
#define BNX2_LINK_STATUS_TX_FC_ENABLED		 (1<<16) 
#define BNX2_LINK_STATUS_RX_FC_ENABLED		 (1<<17) 
#define BNX2_LINK_STATUS_PARTNER_SYM_PAUSE_CAP	 (1<<18) 
#define BNX2_LINK_STATUS_PARTNER_ASYM_PAUSE_CAP	 (1<<19) 
#define BNX2_LINK_STATUS_SERDES_LINK		 (1<<20) 
#define BNX2_LINK_STATUS_PARTNER_AD_2500FULL	 (1<<21) 
#define BNX2_LINK_STATUS_PARTNER_AD_2500HALF	 (1<<22) 

#define BNX2_DRV_PULSE_MB			0x00000010
#define BNX2_DRV_PULSE_SEQ_MASK			 0x00007fff