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

📄 e1000_82543.c

📁 linux系统的网卡驱动包
💻 C
📖 第 1 页 / 共 4 页
字号:
/** *  e1000_init_phy_disabled_82543 - Returns init PHY status *  @hw: pointer to the HW structure * *  Returns the current status of whether PHY initialization is disabled. *  True if PHY initialization is disabled else false. **/static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw){	struct e1000_dev_spec_82543 *dev_spec;	bool ret_val;	DEBUGFUNC("e1000_init_phy_disabled_82543");	if (hw->mac.type != e1000_82543) {		ret_val = FALSE;		goto out;	}	dev_spec = (struct e1000_dev_spec_82543 *)hw->dev_spec;	if (!dev_spec) {		DEBUGOUT("dev_spec pointer is set to NULL.\n");		ret_val = FALSE;		goto out;	}	ret_val = dev_spec->init_phy_disabled;out:	return ret_val;}/** *  e1000_tbi_adjust_stats_82543 - Adjust stats when TBI enabled *  @hw: pointer to the HW structure *  @stats: Struct containing statistic register values *  @frame_len: The length of the frame in question *  @mac_addr: The Ethernet destination address of the frame in question *  @max_frame_size: The maximum frame size * *  Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT **/void e1000_tbi_adjust_stats_82543(struct e1000_hw *hw,                                  struct e1000_hw_stats *stats, u32 frame_len,                                  u8 *mac_addr, u32 max_frame_size){	if (!(e1000_tbi_sbp_enabled_82543(hw)))		goto out;	/* First adjust the frame length. */	frame_len--;	/*	 * We need to adjust the statistics counters, since the hardware	 * counters overcount this packet as a CRC error and undercount	 * the packet as a good packet	 */	/* This packet should not be counted as a CRC error.    */	stats->crcerrs--;	/* This packet does count as a Good Packet Received.    */	stats->gprc++;	/* Adjust the Good Octets received counters             */	stats->gorc += frame_len;	/*	 * Is this a broadcast or multicast?  Check broadcast first,	 * since the test for a multicast frame will test positive on	 * a broadcast frame.	 */	if ((mac_addr[0] == 0xff) && (mac_addr[1] == 0xff))		/* Broadcast packet */		stats->bprc++;	else if (*mac_addr & 0x01)		/* Multicast packet */		stats->mprc++;	/*	 * In this case, the hardware has overcounted the number of	 * oversize frames.	 */	if ((frame_len == max_frame_size) && (stats->roc > 0))		stats->roc--;	/*	 * Adjust the bin counters when the extra byte put the frame in the	 * wrong bin. Remember that the frame_len was adjusted above.	 */	if (frame_len == 64) {		stats->prc64++;		stats->prc127--;	} else if (frame_len == 127) {		stats->prc127++;		stats->prc255--;	} else if (frame_len == 255) {		stats->prc255++;		stats->prc511--;	} else if (frame_len == 511) {		stats->prc511++;		stats->prc1023--;	} else if (frame_len == 1023) {		stats->prc1023++;		stats->prc1522--;	} else if (frame_len == 1522) {		stats->prc1522++;	}out:	return;}/** *  e1000_read_phy_reg_82543 - Read PHY register *  @hw: pointer to the HW structure *  @offset: register offset to be read *  @data: pointer to the read data * *  Reads the PHY at offset and stores the information read to data. **/static s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data){	u32 mdic;	s32 ret_val = E1000_SUCCESS;	DEBUGFUNC("e1000_read_phy_reg_82543");	if (offset > MAX_PHY_REG_ADDRESS) {		DEBUGOUT1("PHY Address %d is out of range\n", offset);		ret_val = -E1000_ERR_PARAM;		goto out;	}	/*	 * We must first send a preamble through the MDIO pin to signal the	 * beginning of an MII instruction.  This is done by sending 32	 * consecutive "1" bits.	 */	e1000_shift_out_mdi_bits_82543(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);	/*	 * Now combine the next few fields that are required for a read	 * operation.  We use this method instead of calling the	 * e1000_shift_out_mdi_bits routine five different times.  The format	 * of an MII read instruction consists of a shift out of 14 bits and	 * is defined as follows:	 * 	<Preamble><SOF><Op Code><Phy Addr><Offset>	 * followed by a shift in of 18 bits.  This first two bits shifted in	 * are TurnAround bits used to avoid contention on the MDIO pin when a	 * READ operation is performed.  These two bits are thrown away	 * followed by a shift in of 16 bits which contains the desired data.	 */	mdic = (offset | (hw->phy.addr << 5) |		(PHY_OP_READ << 10) | (PHY_SOF << 12));	e1000_shift_out_mdi_bits_82543(hw, mdic, 14);	/*	 * Now that we've shifted out the read command to the MII, we need to	 * "shift in" the 16-bit value (18 total bits) of the requested PHY	 * register address.	 */	*data = e1000_shift_in_mdi_bits_82543(hw);out:	return ret_val;}/** *  e1000_write_phy_reg_82543 - Write PHY register *  @hw: pointer to the HW structure *  @offset: register offset to be written *  @data: pointer to the data to be written at offset * *  Writes data to the PHY at offset. **/static s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 data){	u32 mdic;	s32 ret_val = E1000_SUCCESS;	DEBUGFUNC("e1000_write_phy_reg_82543");	if (offset > MAX_PHY_REG_ADDRESS) {		DEBUGOUT1("PHY Address %d is out of range\n", offset);		ret_val = -E1000_ERR_PARAM;		goto out;	}	/*	 * We'll need to use the SW defined pins to shift the write command	 * out to the PHY. We first send a preamble to the PHY to signal the	 * beginning of the MII instruction.  This is done by sending 32	 * consecutive "1" bits.	 */	e1000_shift_out_mdi_bits_82543(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);	/*	 * Now combine the remaining required fields that will indicate a	 * write operation. We use this method instead of calling the	 * e1000_shift_out_mdi_bits routine for each field in the command. The	 * format of a MII write instruction is as follows:	 * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.	 */	mdic = ((PHY_TURNAROUND) | (offset << 2) | (hw->phy.addr << 7) |	        (PHY_OP_WRITE << 12) | (PHY_SOF << 14));	mdic <<= 16;	mdic |= (u32) data;	e1000_shift_out_mdi_bits_82543(hw, mdic, 32);out:	return ret_val;}/** *  e1000_raise_mdi_clk_82543 - Raise Management Data Input clock *  @hw: pointer to the HW structure *  @ctrl: pointer to the control register * *  Raise the management data input clock by setting the MDC bit in the control *  register. **/static void e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl){	/*	 * Raise the clock input to the Management Data Clock (by setting the	 * MDC bit), and then delay a sufficient amount of time.	 */	E1000_WRITE_REG(hw, E1000_CTRL, (*ctrl | E1000_CTRL_MDC));	E1000_WRITE_FLUSH(hw);	usec_delay(10);}/** *  e1000_lower_mdi_clk_82543 - Lower Management Data Input clock *  @hw: pointer to the HW structure *  @ctrl: pointer to the control register * *  Lower the management data input clock by clearing the MDC bit in the *  control register. **/static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl){	/*	 * Lower the clock input to the Management Data Clock (by clearing the	 * MDC bit), and then delay a sufficient amount of time.	 */	E1000_WRITE_REG(hw, E1000_CTRL, (*ctrl & ~E1000_CTRL_MDC));	E1000_WRITE_FLUSH(hw);	usec_delay(10);}/** *  e1000_shift_out_mdi_bits_82543 - Shift data bits our to the PHY *  @hw: pointer to the HW structure *  @data: data to send to the PHY *  @count: number of bits to shift out * *  We need to shift 'count' bits out to the PHY.  So, the value in the *  "data" parameter will be shifted out to the PHY one bit at a time. *  In order to do this, "data" must be broken down into bits. **/static void e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data,                                           u16 count){	u32 ctrl, mask;	/*	 * We need to shift "count" number of bits out to the PHY.  So, the	 * value in the "data" parameter will be shifted out to the PHY one	 * bit at a time.  In order to do this, "data" must be broken down	 * into bits.	 */	mask = 0x01;	mask <<= (count -1);	ctrl = E1000_READ_REG(hw, E1000_CTRL);	/* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */	ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);	while (mask) {		/*		 * A "1" is shifted out to the PHY by setting the MDIO bit to		 * "1" and then raising and lowering the Management Data Clock.		 * A "0" is shifted out to the PHY by setting the MDIO bit to		 * "0" and then raising and lowering the clock.		 */		if (data & mask) ctrl |= E1000_CTRL_MDIO;		else ctrl &= ~E1000_CTRL_MDIO;		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);		E1000_WRITE_FLUSH(hw);		usec_delay(10);		e1000_raise_mdi_clk_82543(hw, &ctrl);		e1000_lower_mdi_clk_82543(hw, &ctrl);		mask >>= 1;	}}/** *  e1000_shift_in_mdi_bits_82543 - Shift data bits in from the PHY *  @hw: pointer to the HW structure * *  In order to read a register from the PHY, we need to shift 18 bits *  in from the PHY.  Bits are "shifted in" by raising the clock input to *  the PHY (setting the MDC bit), and then reading the value of the data out *  MDIO bit. **/static u16 e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw){	u32 ctrl;	u16 data = 0;	u8 i;	/*	 * In order to read a register from the PHY, we need to shift in a	 * total of 18 bits from the PHY.  The first two bit (turnaround)	 * times are used to avoid contention on the MDIO pin when a read	 * operation is performed.  These two bits are ignored by us and	 * thrown away.  Bits are "shifted in" by raising the input to the	 * Management Data Clock (setting the MDC bit) and then reading the	 * value of the MDIO bit.	 */	ctrl = E1000_READ_REG(hw, E1000_CTRL);	/*	 * Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as	 * input.	 */	ctrl &= ~E1000_CTRL_MDIO_DIR;	ctrl &= ~E1000_CTRL_MDIO;	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);	E1000_WRITE_FLUSH(hw);	/*	 * Raise and lower the clock before reading in the data.  This accounts	 * for the turnaround bits.  The first clock occurred when we clocked	 * out the last bit of the Register Address.	 */	e1000_raise_mdi_clk_82543(hw, &ctrl);	e1000_lower_mdi_clk_82543(hw, &ctrl);	for (data = 0, i = 0; i < 16; i++) {		data <<= 1;		e1000_raise_mdi_clk_82543(hw, &ctrl);		ctrl = E1000_READ_REG(hw, E1000_CTRL);		/* Check to see if we shifted in a "1". */		if (ctrl & E1000_CTRL_MDIO)			data |= 1;		e1000_lower_mdi_clk_82543(hw, &ctrl);	}	e1000_raise_mdi_clk_82543(hw, &ctrl);	e1000_lower_mdi_clk_82543(hw, &ctrl);	return data;}/** *  e1000_phy_force_speed_duplex_82543 - Force speed/duplex for PHY *  @hw: pointer to the HW structure * *  Calls the function to force speed and duplex for the m88 PHY, and *  if the PHY is not auto-negotiating and the speed is forced to 10Mbit, *  then call the function for polarity reversal workaround. **/static s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw){	s32 ret_val;	DEBUGFUNC("e1000_phy_force_speed_duplex_82543");	ret_val = e1000_phy_force_speed_duplex_m88(hw);	if (ret_val)		goto out;	if (!hw->mac.autoneg &&	    (hw->mac.forced_speed_duplex & E1000_ALL_10_SPEED))		ret_val = e1000_polarity_reversal_workaround_82543(hw);out:	return ret_val;}/** *  e1000_polarity_reversal_workaround_82543 - Workaround polarity reversal *  @hw: pointer to the HW structure * *  When forcing link to 10 Full or 10 Half, the PHY can reverse the polarity *  inadvertantly.  To workaround the issue, we disable the transmitter on *  the PHY until we have established the link partner's link parameters. **/static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw){	s32 ret_val;	u16 mii_status_reg;	u16 i;	bool link;	/* Polarity reversal workaround for forced 10F/10H links. */	/* Disable the transmitter on the PHY */	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);	if (ret_val)		goto out;	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);	if (ret_val)

⌨️ 快捷键说明

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