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

📄 e1000_mac.c

📁 Intel 82546系列lan driver源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Get the SW semaphore */	while (i < timeout) {		swsm = er32(SWSM);		if (!(swsm & E1000_SWSM_SMBI))			break;		udelay(50);		i++;	}	if (i == timeout) {		e_dbg("Driver can't access device - SMBI bit is set.\n");		ret_val = -E1000_ERR_NVM;		goto out;	}	/* Get the FW semaphore. */	for (i = 0; i < timeout; i++) {		swsm = er32(SWSM);		ew32(SWSM, swsm | E1000_SWSM_SWESMBI);		/* Semaphore acquired if bit latched */		if (er32(SWSM) & E1000_SWSM_SWESMBI)			break;		udelay(50);	}	if (i == timeout) {		/* Release semaphores */		e1000e_put_hw_semaphore(hw);		e_dbg("Driver can't access the NVM\n");		ret_val = -E1000_ERR_NVM;		goto out;	}out:	return ret_val;}/** *  e1000e_put_hw_semaphore - Release hardware semaphore *  @hw: pointer to the HW structure * *  Release hardware semaphore used to access the PHY or NVM **/void e1000e_put_hw_semaphore(struct e1000_hw *hw){	u32 swsm;	swsm = er32(SWSM);	swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);	ew32(SWSM, swsm);}/** *  e1000e_get_auto_rd_done - Check for auto read completion *  @hw: pointer to the HW structure * *  Check EEPROM for Auto Read done bit. **/s32 e1000e_get_auto_rd_done(struct e1000_hw *hw){	s32 i = 0;	s32 ret_val = E1000_SUCCESS;	while (i < AUTO_READ_DONE_TIMEOUT) {		if (er32(EECD) & E1000_EECD_AUTO_RD)			break;		msleep(1);		i++;	}	if (i == AUTO_READ_DONE_TIMEOUT) {		e_dbg("Auto read by HW from NVM has not completed.\n");		ret_val = -E1000_ERR_RESET;		goto out;	}out:	return ret_val;}/** *  e1000e_valid_led_default - Verify a valid default LED config *  @hw: pointer to the HW structure *  @data: pointer to the NVM (EEPROM) * *  Read the EEPROM for the current default LED configuration.  If the *  LED configuration is not valid, set to a valid LED configuration. **/s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data){	s32 ret_val;	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);	if (ret_val) {		e_dbg("NVM Read Error\n");		goto out;	}	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)		*data = ID_LED_DEFAULT;out:	return ret_val;}/** *  e1000e_id_led_init - *  @hw: pointer to the HW structure * **/s32 e1000e_id_led_init(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	s32 ret_val;	const u32 ledctl_mask = 0x000000FF;	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;	u16 data, i, temp;	const u16 led_mask = 0x0F;	ret_val = hw->nvm.ops.valid_led_default(hw, &data);	if (ret_val)		goto out;	mac->ledctl_default = er32(LEDCTL);	mac->ledctl_mode1 = mac->ledctl_default;	mac->ledctl_mode2 = mac->ledctl_default;	for (i = 0; i < 4; i++) {		temp = (data >> (i << 2)) & led_mask;		switch (temp) {		case ID_LED_ON1_DEF2:		case ID_LED_ON1_ON2:		case ID_LED_ON1_OFF2:			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));			mac->ledctl_mode1 |= ledctl_on << (i << 3);			break;		case ID_LED_OFF1_DEF2:		case ID_LED_OFF1_ON2:		case ID_LED_OFF1_OFF2:			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));			mac->ledctl_mode1 |= ledctl_off << (i << 3);			break;		default:			/* Do nothing */			break;		}		switch (temp) {		case ID_LED_DEF1_ON2:		case ID_LED_ON1_ON2:		case ID_LED_OFF1_ON2:			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));			mac->ledctl_mode2 |= ledctl_on << (i << 3);			break;		case ID_LED_DEF1_OFF2:		case ID_LED_ON1_OFF2:		case ID_LED_OFF1_OFF2:			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));			mac->ledctl_mode2 |= ledctl_off << (i << 3);			break;		default:			/* Do nothing */			break;		}	}out:	return ret_val;}/** *  e1000_setup_led_generic - Configures SW controllable LED *  @hw: pointer to the HW structure * *  This prepares the SW controllable LED for use and saves the current state *  of the LED so it can be later restored. **/s32 e1000_setup_led_generic(struct e1000_hw *hw){	u32 ledctl;	s32 ret_val = E1000_SUCCESS;	if (hw->mac.ops.setup_led != e1000_setup_led_generic) {		ret_val = -E1000_ERR_CONFIG;		goto out;	}	if (hw->phy.media_type == e1000_media_type_fiber) {		ledctl = er32(LEDCTL);		hw->mac.ledctl_default = ledctl;		/* Turn off LED0 */		ledctl &= ~(E1000_LEDCTL_LED0_IVRT |		            E1000_LEDCTL_LED0_BLINK |		            E1000_LEDCTL_LED0_MODE_MASK);		ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<		           E1000_LEDCTL_LED0_MODE_SHIFT);		ew32(LEDCTL, ledctl);	} else if (hw->phy.media_type == e1000_media_type_copper) {		ew32(LEDCTL, hw->mac.ledctl_mode1);	}out:	return ret_val;}/** *  e1000e_cleanup_led_generic - Set LED config to default operation *  @hw: pointer to the HW structure * *  Remove the current LED configuration and set the LED configuration *  to the default value, saved from the EEPROM. **/s32 e1000e_cleanup_led_generic(struct e1000_hw *hw){	s32 ret_val = E1000_SUCCESS;	if (hw->mac.ops.cleanup_led != e1000e_cleanup_led_generic) {		ret_val = -E1000_ERR_CONFIG;		goto out;	}	ew32(LEDCTL, hw->mac.ledctl_default);out:	return ret_val;}/** *  e1000e_blink_led - Blink LED *  @hw: pointer to the HW structure * *  Blink the LEDs which are set to be on. **/s32 e1000e_blink_led(struct e1000_hw *hw){	u32 ledctl_blink = 0;	u32 i;	if (hw->phy.media_type == e1000_media_type_fiber) {		/* always blink LED0 for PCI-E fiber */		ledctl_blink = E1000_LEDCTL_LED0_BLINK |		     (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);	} else {		/*		 * set the blink bit for each LED that's "on" (0x0E)		 * in ledctl_mode2		 */		ledctl_blink = hw->mac.ledctl_mode2;		for (i = 0; i < 4; i++)			if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==			    E1000_LEDCTL_MODE_LED_ON)				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<				                 (i * 8));	}	ew32(LEDCTL, ledctl_blink);	return E1000_SUCCESS;}/** *  e1000e_led_on_generic - Turn LED on *  @hw: pointer to the HW structure * *  Turn LED on. **/s32 e1000e_led_on_generic(struct e1000_hw *hw){	u32 ctrl;	switch (hw->phy.media_type) {	case e1000_media_type_fiber:		ctrl = er32(CTRL);		ctrl &= ~E1000_CTRL_SWDPIN0;		ctrl |= E1000_CTRL_SWDPIO0;		ew32(CTRL, ctrl);		break;	case e1000_media_type_copper:		ew32(LEDCTL, hw->mac.ledctl_mode2);		break;	default:		break;	}	return E1000_SUCCESS;}/** *  e1000e_led_off_generic - Turn LED off *  @hw: pointer to the HW structure * *  Turn LED off. **/s32 e1000e_led_off_generic(struct e1000_hw *hw){	u32 ctrl;	switch (hw->phy.media_type) {	case e1000_media_type_fiber:		ctrl = er32(CTRL);		ctrl |= E1000_CTRL_SWDPIN0;		ctrl |= E1000_CTRL_SWDPIO0;		ew32(CTRL, ctrl);		break;	case e1000_media_type_copper:		ew32(LEDCTL, hw->mac.ledctl_mode1);		break;	default:		break;	}	return E1000_SUCCESS;}/** *  e1000e_set_pcie_no_snoop - Set PCI-express capabilities *  @hw: pointer to the HW structure *  @no_snoop: bitmap of snoop events * *  Set the PCI-express register to snoop for events enabled in 'no_snoop'. **/void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop){	u32 gcr;	if (hw->bus.type != e1000_bus_type_pci_express)		goto out;	if (no_snoop) {		gcr = er32(GCR);		gcr &= ~(PCIE_NO_SNOOP_ALL);		gcr |= no_snoop;		ew32(GCR, gcr);	}out:	return;}/** *  e1000e_disable_pcie_master - Disables PCI-express master access *  @hw: pointer to the HW structure * *  Returns 0 (E1000_SUCCESS) if successful, else returns -10 *  (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused *  the master requests to be disabled. * *  Disables PCI-Express master access and verifies there are no pending *  requests. **/s32 e1000e_disable_pcie_master(struct e1000_hw *hw){	u32 ctrl;	s32 timeout = MASTER_DISABLE_TIMEOUT;	s32 ret_val = E1000_SUCCESS;	if (hw->bus.type != e1000_bus_type_pci_express)		goto out;	ctrl = er32(CTRL);	ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;	ew32(CTRL, ctrl);	while (timeout) {		if (!(er32(STATUS) &		      E1000_STATUS_GIO_MASTER_ENABLE))			break;		udelay(100);		timeout--;	}	if (!timeout) {		e_dbg("Master requests are pending.\n");		ret_val = -E1000_ERR_MASTER_REQUESTS_PENDING;		goto out;	}out:	return ret_val;}/** *  e1000e_reset_adaptive - Reset Adaptive Interframe Spacing *  @hw: pointer to the HW structure * *  Reset the Adaptive Interframe Spacing throttle to default values. **/void e1000e_reset_adaptive(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	if (!mac->adaptive_ifs) {		e_dbg("Not in Adaptive IFS mode!\n");		goto out;	}	mac->current_ifs_val = 0;	mac->ifs_min_val = IFS_MIN;	mac->ifs_max_val = IFS_MAX;	mac->ifs_step_size = IFS_STEP;	mac->ifs_ratio = IFS_RATIO;	mac->in_ifs_mode = false;	ew32(AIT, 0);out:	return;}/** *  e1000e_update_adaptive - Update Adaptive Interframe Spacing *  @hw: pointer to the HW structure * *  Update the Adaptive Interframe Spacing Throttle value based on the *  time between transmitted packets and time between collisions. **/void e1000e_update_adaptive(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	if (!mac->adaptive_ifs) {		e_dbg("Not in Adaptive IFS mode!\n");		goto out;	}	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {		if (mac->tx_packet_delta > MIN_NUM_XMITS) {			mac->in_ifs_mode = true;			if (mac->current_ifs_val < mac->ifs_max_val) {				if (!mac->current_ifs_val)					mac->current_ifs_val = mac->ifs_min_val;				else					mac->current_ifs_val +=						mac->ifs_step_size;				ew32(AIT, mac->current_ifs_val);			}		}	} else {		if (mac->in_ifs_mode &&		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {			mac->current_ifs_val = 0;			mac->in_ifs_mode = false;			ew32(AIT, 0);		}	}out:	return;}/** *  e1000_validate_mdi_setting_generic - Verify MDI/MDIx settings *  @hw: pointer to the HW structure * *  Verify that when not using auto-negotiation that MDI/MDIx is correctly *  set, which is forced to MDI mode only. **/s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw){	s32 ret_val = E1000_SUCCESS;	if (!hw->mac.autoneg && (hw->phy.mdix == 0 || hw->phy.mdix == 3)) {		e_dbg("Invalid MDI setting detected\n");		hw->phy.mdix = 1;		ret_val = -E1000_ERR_CONFIG;		goto out;	}out:	return ret_val;}

⌨️ 快捷键说明

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