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

📄 e1000_phy.c

📁 DELL755 Intel 网卡驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	phy->ops.release(hw);	ret_val = phy->ops.get_cfg_done(hw);out:	return ret_val;}/** *  e1000_get_cfg_done_generic - Generic configuration done *  @hw: pointer to the HW structure * *  Generic function to wait 10 milli-seconds for configuration to complete *  and return success. **/s32 e1000_get_cfg_done_generic(struct e1000_hw *hw){	DEBUGFUNC("e1000_get_cfg_done_generic");	msec_delay_irq(10);	return E1000_SUCCESS;}/** *  e1000_phy_init_script_igp3 - Inits the IGP3 PHY *  @hw: pointer to the HW structure * *  Initializes a Intel Gigabit PHY3 when an EEPROM is not present. **/s32 e1000_phy_init_script_igp3(struct e1000_hw *hw){	DEBUGOUT("Running IGP 3 PHY init script\n");	/* PHY init IGP 3 */	/* Enable rise/fall, 10-mode work in class-A */	hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018);	/* Remove all caps from Replica path filter */	hw->phy.ops.write_reg(hw, 0x2F52, 0x0000);	/* Bias trimming for ADC, AFE and Driver (Default) */	hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24);	/* Increase Hybrid poly bias */	hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0);	/* Add 4% to Tx amplitude in Gig mode */	hw->phy.ops.write_reg(hw, 0x2010, 0x10B0);	/* Disable trimming (TTT) */	hw->phy.ops.write_reg(hw, 0x2011, 0x0000);	/* Poly DC correction to 94.6% + 2% for all channels */	hw->phy.ops.write_reg(hw, 0x20DD, 0x249A);	/* ABS DC correction to 95.9% */	hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3);	/* BG temp curve trim */	hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE);	/* Increasing ADC OPAMP stage 1 currents to max */	hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4);	/* Force 1000 ( required for enabling PHY regs configuration) */	hw->phy.ops.write_reg(hw, 0x0000, 0x0140);	/* Set upd_freq to 6 */	hw->phy.ops.write_reg(hw, 0x1F30, 0x1606);	/* Disable NPDFE */	hw->phy.ops.write_reg(hw, 0x1F31, 0xB814);	/* Disable adaptive fixed FFE (Default) */	hw->phy.ops.write_reg(hw, 0x1F35, 0x002A);	/* Enable FFE hysteresis */	hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067);	/* Fixed FFE for short cable lengths */	hw->phy.ops.write_reg(hw, 0x1F54, 0x0065);	/* Fixed FFE for medium cable lengths */	hw->phy.ops.write_reg(hw, 0x1F55, 0x002A);	/* Fixed FFE for long cable lengths */	hw->phy.ops.write_reg(hw, 0x1F56, 0x002A);	/* Enable Adaptive Clip Threshold */	hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0);	/* AHT reset limit to 1 */	hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF);	/* Set AHT master delay to 127 msec */	hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC);	/* Set scan bits for AHT */	hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF);	/* Set AHT Preset bits */	hw->phy.ops.write_reg(hw, 0x1F79, 0x0210);	/* Change integ_factor of channel A to 3 */	hw->phy.ops.write_reg(hw, 0x1895, 0x0003);	/* Change prop_factor of channels BCD to 8 */	hw->phy.ops.write_reg(hw, 0x1796, 0x0008);	/* Change cg_icount + enable integbp for channels BCD */	hw->phy.ops.write_reg(hw, 0x1798, 0xD008);	/*	 * Change cg_icount + enable integbp + change prop_factor_master	 * to 8 for channel A	 */	hw->phy.ops.write_reg(hw, 0x1898, 0xD918);	/* Disable AHT in Slave mode on channel A */	hw->phy.ops.write_reg(hw, 0x187A, 0x0800);	/*	 * Enable LPLU and disable AN to 1000 in non-D0a states,	 * Enable SPD+B2B	 */	hw->phy.ops.write_reg(hw, 0x0019, 0x008D);	/* Enable restart AN on an1000_dis change */	hw->phy.ops.write_reg(hw, 0x001B, 0x2080);	/* Enable wh_fifo read clock in 10/100 modes */	hw->phy.ops.write_reg(hw, 0x0014, 0x0045);	/* Restart AN, Speed selection is 1000 */	hw->phy.ops.write_reg(hw, 0x0000, 0x1340);	return E1000_SUCCESS;}/** *  e1000_get_phy_type_from_id - Get PHY type from id *  @phy_id: phy_id read from the phy * *  Returns the phy type from the id. **/e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id){	e1000_phy_type phy_type = e1000_phy_unknown;	switch (phy_id)	{	case M88E1000_I_PHY_ID:	case M88E1000_E_PHY_ID:	case M88E1111_I_PHY_ID:	case M88E1011_I_PHY_ID:		phy_type = e1000_phy_m88;		break;	case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */		phy_type = e1000_phy_igp_2;		break;	case GG82563_E_PHY_ID:		phy_type = e1000_phy_gg82563;		break;	case IGP03E1000_E_PHY_ID:		phy_type = e1000_phy_igp_3;		break;	case IFE_E_PHY_ID:	case IFE_PLUS_E_PHY_ID:	case IFE_C_E_PHY_ID:		phy_type = e1000_phy_ife;		break;	case BME1000_E_PHY_ID:	case BME1000_E_PHY_ID_R2:		phy_type = e1000_phy_bm;		break;	default:		phy_type = e1000_phy_unknown;		break;	}	return phy_type;}/** *  e1000_determine_phy_address - Determines PHY address. *  @hw: pointer to the HW structure * *  This uses a trial and error method to loop through possible PHY *  addresses. It tests each by reading the PHY ID registers and *  checking for a match. **/s32 e1000_determine_phy_address(struct e1000_hw* hw){	s32 ret_val = -E1000_ERR_PHY_TYPE;	u32 phy_addr= 0;	u32 i;	e1000_phy_type phy_type = e1000_phy_unknown;	for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {		hw->phy.addr = phy_addr;		i = 0;		do {			e1000_get_phy_id(hw);			phy_type = e1000_get_phy_type_from_id(hw->phy.id);			/* 		 	 * If phy_type is valid, break - we found our		 	 * PHY address		 	 */			if (phy_type  != e1000_phy_unknown) {				ret_val = E1000_SUCCESS;				goto out;			}			msec_delay(1);			i++;		} while (i < 10);	}out:	return ret_val;}/** *  e1000_get_phy_addr_for_bm_page - Retrieve PHY page address *  @page: page to access * *  Returns the phy address for the page requested. **/static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg){	u32 phy_addr = 2;	if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))		phy_addr = 1;	return phy_addr;}/** *  e1000_write_phy_reg_bm - Write BM PHY register *  @hw: pointer to the HW structure *  @offset: register offset to write to *  @data: data to write at register offset * *  Acquires semaphore, if necessary, then writes the data to PHY register *  at the offset.  Release any acquired semaphores before exiting. **/s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data){	s32 ret_val;	u32 page_select = 0;	u32 page = offset >> IGP_PAGE_SHIFT;	u32 page_shift = 0;	DEBUGFUNC("e1000_write_phy_reg_bm");	/* Page 800 works differently than the rest so it has its own func */	if (page == BM_WUC_PAGE) {		ret_val = e1000_access_phy_wakeup_reg_bm(hw,							offset, &data, false);		goto out;	}	ret_val = hw->phy.ops.acquire(hw);	if (ret_val)		goto out;	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);	if (offset > MAX_PHY_MULTI_PAGE_REG) {		/*		 * Page select is register 31 for phy address 1 and 22 for		 * phy address 2 and 3. Page select is shifted only for		 * phy address 1.		 */		if (hw->phy.addr == 1) {			page_shift = IGP_PAGE_SHIFT;			page_select = IGP01E1000_PHY_PAGE_SELECT;		} else {			page_shift = 0;			page_select = BM_PHY_PAGE_SELECT;		}		/* Page is shifted left, PHY expects (page x 32) */		ret_val = e1000_write_phy_reg_mdic(hw, page_select,		                                   (page << page_shift));		if (ret_val) {			hw->phy.ops.release(hw);			goto out;		}	}	ret_val = e1000_write_phy_reg_mdic(hw,	                                   MAX_PHY_REG_ADDRESS & offset,	                                   data);	hw->phy.ops.release(hw);out:	return ret_val;}/** *  e1000_read_phy_reg_bm - Read BM PHY register *  @hw: pointer to the HW structure *  @offset: register offset to be read *  @data: pointer to the read data * *  Acquires semaphore, if necessary, then reads the PHY register at offset *  and storing the retrieved information in data.  Release any acquired *  semaphores before exiting. **/s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data){	s32 ret_val;	u32 page_select = 0;	u32 page = offset >> IGP_PAGE_SHIFT;	u32 page_shift = 0;	DEBUGFUNC("e1000_read_phy_reg_bm");	/* Page 800 works differently than the rest so it has its own func */	if (page == BM_WUC_PAGE) {		ret_val = e1000_access_phy_wakeup_reg_bm(hw,							offset, data, true);		goto out;	}	ret_val = hw->phy.ops.acquire(hw);	if (ret_val)		goto out;	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);	if (offset > MAX_PHY_MULTI_PAGE_REG) {		/*		 * Page select is register 31 for phy address 1 and 22 for		 * phy address 2 and 3. Page select is shifted only for		 * phy address 1.		 */		if (hw->phy.addr == 1) {			page_shift = IGP_PAGE_SHIFT;			page_select = IGP01E1000_PHY_PAGE_SELECT;		} else {			page_shift = 0;			page_select = BM_PHY_PAGE_SELECT;		}		/* Page is shifted left, PHY expects (page x 32) */		ret_val = e1000_write_phy_reg_mdic(hw, page_select,		                                   (page << page_shift));		if (ret_val) {			hw->phy.ops.release(hw);			goto out;		}	} 	ret_val = e1000_read_phy_reg_mdic(hw, 	                                  MAX_PHY_REG_ADDRESS & offset, 	                                  data);	hw->phy.ops.release(hw);out:	return ret_val;}/** *  e1000_read_phy_reg_bm2 - Read BM PHY register *  @hw: pointer to the HW structure *  @offset: register offset to be read *  @data: pointer to the read data * *  Acquires semaphore, if necessary, then reads the PHY register at offset *  and storing the retrieved information in data.  Release any acquired *  semaphores before exiting. **/s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data){	s32 ret_val;	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);	DEBUGFUNC("e1000_write_phy_reg_bm2");	/* Page 800 works differently than the rest so it has its own func */	if (page == BM_WUC_PAGE) {		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,		                                         true);		goto out;	}	ret_val = hw->phy.ops.acquire(hw);	if (ret_val)		goto out;	hw->phy.addr = 1;	if (offset > MAX_PHY_MULTI_PAGE_REG) {		/* Page is shifted left, PHY expects (page x 32) */		ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,		                                   page);		if (ret_val) {			hw->phy.ops.release(hw);			goto out;		}	} 	ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,	                                  data);	hw->phy.ops.release(hw);out:	return ret_val;}/** *  e1000_write_phy_reg_bm2 - Write BM PHY register *  @hw: pointer to the HW structure *  @offset: register offset to write to *  @data: data to write at register offset * *  Acquires semaphore, if necessary, then writes the data to PHY register *  at the offset.  Release any acquired semaphores before exiting. **/s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data){	s32 ret_val;	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);	DEBUGFUNC("e1000_write_phy_reg_bm2");	/* Page 800 works differently than the rest so it has its own func */	if (page == BM_WUC_PAGE) {		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,		                                         false);		goto out;	}	ret_val = hw->phy.ops.acquire(hw);	if (ret_val)		goto out;	hw->phy.addr = 1;	if (offset > MAX_PHY_MULTI_PAGE_REG) {		/* Page is shifted left, PHY expects (page x 32) */		ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,		                                   page);		if (ret_val) {			hw->phy.ops.release(hw);			goto out;		}	}	ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,	                                   data);	hw->phy.ops.release(hw);out:	return ret_val;}/** *  e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register *  @hw: pointer to the HW structure *  @offset: register offset to be read or written *  @data: pointer to the data to read or write *  @read: determines if operation is read or write * *  Acquires semaphore, if necessary, then reads the PHY register at offset *  and storing the retrieved information in data.  Release any acquired *  semaphores before exiting. Note that procedure to read the wakeup *  registers are different. It works as such: *  1) Set page 769, register 17, bit 2 = 1 *  2) Set page to 800 for host (801 if we were manageability) *  3) Write the address using the address opcode (0x11) *  4) Read or write the data using the data opcode (0x12) *  5) Restore 769_17.2 to its original value **/s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw,                                      u32 offset, u16 *data, bool read){	s32 ret_val;	u16 reg = ((u16)offset);	u16 phy_reg = 0;	u8  phy_acquired = 1;	DEBUGFUNC("e1000_read_phy_wakeup_reg_bm");	ret_val = hw->phy.ops.acquire(hw);	if (ret_val) {		DEBUGOUT("Could not acquire PHY\n");		phy_acquired = 0;		goto out;	}	/* All operations in this function are phy address 1 */	hw->phy.addr = 1;	/* Set page 769 */	e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,	       

⌨️ 快捷键说明

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