⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ixgb_hw.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************** * Writes a word to a device over the Management Data Interface (MDI) bus. * This interface is used to manage Physical layer devices. * * hw          - Struct containing variables accessed by hw code * reg_address - Offset of device register being read. * phy_address - Address of device on MDI. * device_type - Also known as the Device ID or DID. * data        - 16-bit value to be written * * Returns:  void. * * The 82597EX has support for several MDI access methods.  This routine * uses the new protocol MDI Single Command and Address Operation. * This requires that first an address cycle command is sent, followed by a * write command. *****************************************************************************/static voidixgb_write_phy_reg(struct ixgb_hw *hw,			uint32_t reg_address,			uint32_t phy_address,			uint32_t device_type,			uint16_t data){	uint32_t i;	uint32_t command = 0;	ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS);	ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS);	ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE);	/* Put the data in the MDIO Read/Write Data register */	IXGB_WRITE_REG(hw, MSRWD, (uint32_t)data);	/* Setup and write the address cycle command */	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  |			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |			   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND));	IXGB_WRITE_REG(hw, MSCA, command);	/**************************************************************	** Check every 10 usec to see if the address cycle completed	** The COMMAND bit will clear when the operation is complete.	** This may take as long as 64 usecs (we'll wait 100 usecs max)	** from the CPU Write to the Ready bit assertion.	**************************************************************/	for(i = 0; i < 10; i++)	{		udelay(10);		command = IXGB_READ_REG(hw, MSCA);		if ((command & IXGB_MSCA_MDI_COMMAND) == 0)			break;	}	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0);	/* Address cycle complete, setup and write the write command */	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  |			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |			   (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND));	IXGB_WRITE_REG(hw, MSCA, command);	/**************************************************************	** Check every 10 usec to see if the read command completed	** The COMMAND bit will clear when the operation is complete.	** The write may take as long as 64 usecs (we'll wait 100 usecs max)	** from the CPU Write to the Ready bit assertion.	**************************************************************/	for(i = 0; i < 10; i++)	{		udelay(10);		command = IXGB_READ_REG(hw, MSCA);		if ((command & IXGB_MSCA_MDI_COMMAND) == 0)			break;	}	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0);	/* Operation is complete, return. */}/****************************************************************************** * Checks to see if the link status of the hardware has changed. * * hw - Struct containing variables accessed by hw code * * Called by any function that needs to check the link status of the adapter. *****************************************************************************/voidixgb_check_for_link(struct ixgb_hw *hw){	uint32_t status_reg;	uint32_t xpcss_reg;	DEBUGFUNC("ixgb_check_for_link");	xpcss_reg = IXGB_READ_REG(hw, XPCSS);	status_reg = IXGB_READ_REG(hw, STATUS);	if ((xpcss_reg & IXGB_XPCSS_ALIGN_STATUS) &&	    (status_reg & IXGB_STATUS_LU)) {		hw->link_up = TRUE;	} else if (!(xpcss_reg & IXGB_XPCSS_ALIGN_STATUS) &&		   (status_reg & IXGB_STATUS_LU)) {		DEBUGOUT("XPCSS Not Aligned while Status:LU is set.\n");		hw->link_up = ixgb_link_reset(hw);	} else {		/*		 * 82597EX errata.  Since the lane deskew problem may prevent		 * link, reset the link before reporting link down.		 */		hw->link_up = ixgb_link_reset(hw);	}	/*  Anything else for 10 Gig?? */}/****************************************************************************** * Check for a bad link condition that may have occured. * The indication is that the RFC / LFC registers may be incrementing * continually.  A full adapter reset is required to recover. * * hw - Struct containing variables accessed by hw code * * Called by any function that needs to check the link status of the adapter. *****************************************************************************/boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw){	uint32_t newLFC, newRFC;	boolean_t bad_link_returncode = FALSE;	if (hw->phy_type == ixgb_phy_type_txn17401) {		newLFC = IXGB_READ_REG(hw, LFC);		newRFC = IXGB_READ_REG(hw, RFC);		if ((hw->lastLFC + 250 < newLFC)		    || (hw->lastRFC + 250 < newRFC)) {			DEBUGOUT			    ("BAD LINK! too many LFC/RFC since last check\n");			bad_link_returncode = TRUE;		}		hw->lastLFC = newLFC;		hw->lastRFC = newRFC;	}	return bad_link_returncode;}/****************************************************************************** * Clears all hardware statistics counters. * * hw - Struct containing variables accessed by shared code *****************************************************************************/static voidixgb_clear_hw_cntrs(struct ixgb_hw *hw){	volatile uint32_t temp_reg;	DEBUGFUNC("ixgb_clear_hw_cntrs");	/* if we are stopped or resetting exit gracefully */	if(hw->adapter_stopped) {		DEBUGOUT("Exiting because the adapter is stopped!!!\n");		return;	}	temp_reg = IXGB_READ_REG(hw, TPRL);	temp_reg = IXGB_READ_REG(hw, TPRH);	temp_reg = IXGB_READ_REG(hw, GPRCL);	temp_reg = IXGB_READ_REG(hw, GPRCH);	temp_reg = IXGB_READ_REG(hw, BPRCL);	temp_reg = IXGB_READ_REG(hw, BPRCH);	temp_reg = IXGB_READ_REG(hw, MPRCL);	temp_reg = IXGB_READ_REG(hw, MPRCH);	temp_reg = IXGB_READ_REG(hw, UPRCL);	temp_reg = IXGB_READ_REG(hw, UPRCH);	temp_reg = IXGB_READ_REG(hw, VPRCL);	temp_reg = IXGB_READ_REG(hw, VPRCH);	temp_reg = IXGB_READ_REG(hw, JPRCL);	temp_reg = IXGB_READ_REG(hw, JPRCH);	temp_reg = IXGB_READ_REG(hw, GORCL);	temp_reg = IXGB_READ_REG(hw, GORCH);	temp_reg = IXGB_READ_REG(hw, TORL);	temp_reg = IXGB_READ_REG(hw, TORH);	temp_reg = IXGB_READ_REG(hw, RNBC);	temp_reg = IXGB_READ_REG(hw, RUC);	temp_reg = IXGB_READ_REG(hw, ROC);	temp_reg = IXGB_READ_REG(hw, RLEC);	temp_reg = IXGB_READ_REG(hw, CRCERRS);	temp_reg = IXGB_READ_REG(hw, ICBC);	temp_reg = IXGB_READ_REG(hw, ECBC);	temp_reg = IXGB_READ_REG(hw, MPC);	temp_reg = IXGB_READ_REG(hw, TPTL);	temp_reg = IXGB_READ_REG(hw, TPTH);	temp_reg = IXGB_READ_REG(hw, GPTCL);	temp_reg = IXGB_READ_REG(hw, GPTCH);	temp_reg = IXGB_READ_REG(hw, BPTCL);	temp_reg = IXGB_READ_REG(hw, BPTCH);	temp_reg = IXGB_READ_REG(hw, MPTCL);	temp_reg = IXGB_READ_REG(hw, MPTCH);	temp_reg = IXGB_READ_REG(hw, UPTCL);	temp_reg = IXGB_READ_REG(hw, UPTCH);	temp_reg = IXGB_READ_REG(hw, VPTCL);	temp_reg = IXGB_READ_REG(hw, VPTCH);	temp_reg = IXGB_READ_REG(hw, JPTCL);	temp_reg = IXGB_READ_REG(hw, JPTCH);	temp_reg = IXGB_READ_REG(hw, GOTCL);	temp_reg = IXGB_READ_REG(hw, GOTCH);	temp_reg = IXGB_READ_REG(hw, TOTL);	temp_reg = IXGB_READ_REG(hw, TOTH);	temp_reg = IXGB_READ_REG(hw, DC);	temp_reg = IXGB_READ_REG(hw, PLT64C);	temp_reg = IXGB_READ_REG(hw, TSCTC);	temp_reg = IXGB_READ_REG(hw, TSCTFC);	temp_reg = IXGB_READ_REG(hw, IBIC);	temp_reg = IXGB_READ_REG(hw, RFC);	temp_reg = IXGB_READ_REG(hw, LFC);	temp_reg = IXGB_READ_REG(hw, PFRC);	temp_reg = IXGB_READ_REG(hw, PFTC);	temp_reg = IXGB_READ_REG(hw, MCFRC);	temp_reg = IXGB_READ_REG(hw, MCFTC);	temp_reg = IXGB_READ_REG(hw, XONRXC);	temp_reg = IXGB_READ_REG(hw, XONTXC);	temp_reg = IXGB_READ_REG(hw, XOFFRXC);	temp_reg = IXGB_READ_REG(hw, XOFFTXC);	temp_reg = IXGB_READ_REG(hw, RJC);	return;}/****************************************************************************** * Turns on the software controllable LED * * hw - Struct containing variables accessed by shared code *****************************************************************************/voidixgb_led_on(struct ixgb_hw *hw){	uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0);	/* To turn on the LED, clear software-definable pin 0 (SDP0). */	ctrl0_reg &= ~IXGB_CTRL0_SDP0;	IXGB_WRITE_REG(hw, CTRL0, ctrl0_reg);	return;}/****************************************************************************** * Turns off the software controllable LED * * hw - Struct containing variables accessed by shared code *****************************************************************************/voidixgb_led_off(struct ixgb_hw *hw){	uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0);	/* To turn off the LED, set software-definable pin 0 (SDP0). */	ctrl0_reg |= IXGB_CTRL0_SDP0;	IXGB_WRITE_REG(hw, CTRL0, ctrl0_reg);	return;}/****************************************************************************** * Gets the current PCI bus type, speed, and width of the hardware * * hw - Struct containing variables accessed by shared code *****************************************************************************/static voidixgb_get_bus_info(struct ixgb_hw *hw){	uint32_t status_reg;	status_reg = IXGB_READ_REG(hw, STATUS);	hw->bus.type = (status_reg & IXGB_STATUS_PCIX_MODE) ?		ixgb_bus_type_pcix : ixgb_bus_type_pci;	if (hw->bus.type == ixgb_bus_type_pci) {		hw->bus.speed = (status_reg & IXGB_STATUS_PCI_SPD) ?			ixgb_bus_speed_66 : ixgb_bus_speed_33;	} else {		switch (status_reg & IXGB_STATUS_PCIX_SPD_MASK) {		case IXGB_STATUS_PCIX_SPD_66:			hw->bus.speed = ixgb_bus_speed_66;			break;		case IXGB_STATUS_PCIX_SPD_100:			hw->bus.speed = ixgb_bus_speed_100;			break;		case IXGB_STATUS_PCIX_SPD_133:			hw->bus.speed = ixgb_bus_speed_133;			break;		default:			hw->bus.speed = ixgb_bus_speed_reserved;			break;		}	}	hw->bus.width = (status_reg & IXGB_STATUS_BUS64) ?		ixgb_bus_width_64 : ixgb_bus_width_32;	return;}/****************************************************************************** * Tests a MAC address to ensure it is a valid Individual Address * * mac_addr - pointer to MAC address. * *****************************************************************************/static boolean_tmac_addr_valid(uint8_t *mac_addr){	boolean_t is_valid = TRUE;	DEBUGFUNC("mac_addr_valid");	/* Make sure it is not a multicast address */	if (IS_MULTICAST(mac_addr)) {		DEBUGOUT("MAC address is multicast\n");		is_valid = FALSE;	}	/* Not a broadcast address */	else if (IS_BROADCAST(mac_addr)) {		DEBUGOUT("MAC address is broadcast\n");		is_valid = FALSE;	}	/* Reject the zero address */	else if (mac_addr[0] == 0 &&			 mac_addr[1] == 0 &&			 mac_addr[2] == 0 &&			 mac_addr[3] == 0 &&			 mac_addr[4] == 0 &&			 mac_addr[5] == 0) {		DEBUGOUT("MAC address is all zeros\n");		is_valid = FALSE;	}	return (is_valid);}/****************************************************************************** * Resets the 10GbE link.  Waits the settle time and returns the state of * the link. * * hw - Struct containing variables accessed by shared code *****************************************************************************/boolean_tixgb_link_reset(struct ixgb_hw *hw){	boolean_t link_status = FALSE;	uint8_t wait_retries = MAX_RESET_ITERATIONS;	uint8_t lrst_retries = MAX_RESET_ITERATIONS;	do {		/* Reset the link */		IXGB_WRITE_REG(hw, CTRL0,			       IXGB_READ_REG(hw, CTRL0) | IXGB_CTRL0_LRST);		/* Wait for link-up and lane re-alignment */		do {			udelay(IXGB_DELAY_USECS_AFTER_LINK_RESET);			link_status =			    ((IXGB_READ_REG(hw, STATUS) & IXGB_STATUS_LU)			     && (IXGB_READ_REG(hw, XPCSS) &				 IXGB_XPCSS_ALIGN_STATUS)) ? TRUE : FALSE;		} while (!link_status && --wait_retries);	} while (!link_status && --lrst_retries);	return link_status;}/****************************************************************************** * Resets the 10GbE optics module. * * hw - Struct containing variables accessed by shared code *****************************************************************************/voidixgb_optics_reset(struct ixgb_hw *hw){	if (hw->phy_type == ixgb_phy_type_txn17401) {		uint16_t mdio_reg;		ixgb_write_phy_reg(hw,					MDIO_PMA_PMD_CR1,					IXGB_PHY_ADDRESS,					MDIO_PMA_PMD_DID,					MDIO_PMA_PMD_CR1_RESET);		mdio_reg = ixgb_read_phy_reg( hw,						MDIO_PMA_PMD_CR1,						IXGB_PHY_ADDRESS,						MDIO_PMA_PMD_DID);	}	return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -