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

📄 tg3.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 5 页
字号:
			return err;		goto out;	}	err = tg3_bmcr_reset(tp);	if (err)		return err; out:	tg3_phy_set_wirespeed(tp);	return 0;}static void tg3_set_power_state_0(struct tg3 *tp){	uint16_t power_control;	int pm = tp->pm_cap;	/* Make sure register accesses (indirect or otherwise)	 * will function correctly.	 */	pci_write_config_dword(tp->pdev,  TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);	pci_read_config_word(tp->pdev, pm + PCI_PM_CTRL, &power_control);	power_control |= PCI_PM_CTRL_PME_STATUS;	power_control &= ~(PCI_PM_CTRL_STATE_MASK);	power_control |= 0;	pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);	tw32_carefully(GRC_LOCAL_CTRL, tp->grc_local_ctrl);	return;}#if SUPPORT_LINK_REPORTstatic void tg3_link_report(struct tg3 *tp){	if (!tp->carrier_ok) {		printf("Link is down.\n");	} else {		printf("Link is up at %d Mbps, %s duplex. %s %s %s\n",			(tp->link_config.active_speed == SPEED_1000 ?			       1000 :			(tp->link_config.active_speed == SPEED_100 ?				100 : 10)),			(tp->link_config.active_duplex == DUPLEX_FULL ?  				"full" : "half"),			(tp->tg3_flags & TG3_FLAG_TX_PAUSE) ? "TX" : "",			(tp->tg3_flags & TG3_FLAG_RX_PAUSE) ? "RX" : "",			(tp->tg3_flags & (TG3_FLAG_TX_PAUSE |TG3_FLAG_RX_PAUSE)) ? "flow control" : "");	}}#else#define tg3_link_report(tp)#endifstatic void tg3_setup_flow_control(struct tg3 *tp, uint32_t local_adv, uint32_t remote_adv){	uint32_t new_tg3_flags = 0;	if (local_adv & ADVERTISE_PAUSE_CAP) {		if (local_adv & ADVERTISE_PAUSE_ASYM) {			if (remote_adv & LPA_PAUSE_CAP)				new_tg3_flags |=					(TG3_FLAG_RX_PAUSE |					 TG3_FLAG_TX_PAUSE);			else if (remote_adv & LPA_PAUSE_ASYM)				new_tg3_flags |=					(TG3_FLAG_RX_PAUSE);		} else {			if (remote_adv & LPA_PAUSE_CAP)				new_tg3_flags |=					(TG3_FLAG_RX_PAUSE |					 TG3_FLAG_TX_PAUSE);		}	} else if (local_adv & ADVERTISE_PAUSE_ASYM) {		if ((remote_adv & LPA_PAUSE_CAP) &&		    (remote_adv & LPA_PAUSE_ASYM))			new_tg3_flags |= TG3_FLAG_TX_PAUSE;	}	tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE);	tp->tg3_flags |= new_tg3_flags;	if (new_tg3_flags & TG3_FLAG_RX_PAUSE)		tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;	else		tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;	if (new_tg3_flags & TG3_FLAG_TX_PAUSE)		tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;	else		tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;}#if SUPPORT_COPPER_PHYstatic void tg3_aux_stat_to_speed_duplex(	struct tg3 *tp __unused, uint32_t val, uint8_t *speed, uint8_t *duplex){	static const uint8_t map[] = {		[0] = (SPEED_INVALID << 2) | DUPLEX_INVALID,		[MII_TG3_AUX_STAT_10HALF >> 8]   = (SPEED_10 << 2) | DUPLEX_HALF,		[MII_TG3_AUX_STAT_10FULL >> 8]   = (SPEED_10 << 2) | DUPLEX_FULL,		[MII_TG3_AUX_STAT_100HALF >> 8]  = (SPEED_100 << 2) | DUPLEX_HALF,		[MII_TG3_AUX_STAT_100_4 >> 8] = (SPEED_INVALID << 2) | DUPLEX_INVALID,		[MII_TG3_AUX_STAT_100FULL >> 8]  = (SPEED_100 << 2) | DUPLEX_FULL,		[MII_TG3_AUX_STAT_1000HALF >> 8] = (SPEED_1000 << 2) | DUPLEX_HALF,		[MII_TG3_AUX_STAT_1000FULL >> 8] = (SPEED_1000 << 2) | DUPLEX_FULL,	};	uint8_t result;	result = map[(val & MII_TG3_AUX_STAT_SPDMASK) >> 8];	*speed = result >> 2;	*duplex = result & 3;}static int tg3_phy_copper_begin(struct tg3 *tp){	uint32_t new_adv;	tp->link_config.advertising =		(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |			ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |			ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full |			ADVERTISED_Autoneg | ADVERTISED_MII);		if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) {		tp->link_config.advertising &=			~(ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full);	}		new_adv = (ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);	if (tp->link_config.advertising & ADVERTISED_10baseT_Half) {		new_adv |= ADVERTISE_10HALF;	}	if (tp->link_config.advertising & ADVERTISED_10baseT_Full) {		new_adv |= ADVERTISE_10FULL;	}	if (tp->link_config.advertising & ADVERTISED_100baseT_Half) {		new_adv |= ADVERTISE_100HALF;	}	if (tp->link_config.advertising & ADVERTISED_100baseT_Full) {		new_adv |= ADVERTISE_100FULL;	}	tg3_writephy(tp, MII_ADVERTISE, new_adv);		if (tp->link_config.advertising &		(ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full)) {		new_adv = 0;		if (tp->link_config.advertising & ADVERTISED_1000baseT_Half) {			new_adv |= MII_TG3_CTRL_ADV_1000_HALF;		}		if (tp->link_config.advertising & ADVERTISED_1000baseT_Full) {			new_adv |= MII_TG3_CTRL_ADV_1000_FULL;		}		if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY) &&			(tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||				tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)) {			new_adv |= (MII_TG3_CTRL_AS_MASTER |				MII_TG3_CTRL_ENABLE_AS_MASTER);		}		tg3_writephy(tp, MII_TG3_CTRL, new_adv);	} else {		tg3_writephy(tp, MII_TG3_CTRL, 0);	}	tg3_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);	return 0;}static int tg3_init_5401phy_dsp(struct tg3 *tp){	int err;	/* Turn off tap power management. */	err  = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c20);		err |= tg3_writedsp(tp, 0x0012, 0x1804);	err |= tg3_writedsp(tp, 0x0013, 0x1204);	err |= tg3_writedsp(tp, 0x8006, 0x0132);	err |= tg3_writedsp(tp, 0x8006, 0x0232);	err |= tg3_writedsp(tp, 0x201f, 0x0a20);	udelay(40);	return err;}static int tg3_setup_copper_phy(struct tg3 *tp){	int current_link_up;	uint32_t bmsr, dummy;	int i, err;	tw32_carefully(MAC_STATUS,		(MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED));	tp->mi_mode = MAC_MI_MODE_BASE;	tw32_carefully(MAC_MI_MODE, tp->mi_mode);	tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);	/* Some third-party PHYs need to be reset on link going	 * down.	 */	if (	(	(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||			(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||			(tp->pci_chip_rev_id == CHIPREV_ID_5705_A0)) &&		(tp->carrier_ok)) {		tg3_readphy(tp, MII_BMSR, &bmsr);		tg3_readphy(tp, MII_BMSR, &bmsr);		if (!(bmsr & BMSR_LSTATUS))			tg3_phy_reset(tp);	}	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {		tg3_readphy(tp, MII_BMSR, &bmsr);		tg3_readphy(tp, MII_BMSR, &bmsr);		if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE))			bmsr = 0;		if (!(bmsr & BMSR_LSTATUS)) {			err = tg3_init_5401phy_dsp(tp);			if (err)				return err;			tg3_readphy(tp, MII_BMSR, &bmsr);			for (i = 0; i < 1000; i++) {				udelay(10);				tg3_readphy(tp, MII_BMSR, &bmsr);				if (bmsr & BMSR_LSTATUS) {					udelay(40);					break;				}			}			if ((tp->phy_id & PHY_ID_REV_MASK) == PHY_REV_BCM5401_B0 &&			    !(bmsr & BMSR_LSTATUS) &&			    tp->link_config.active_speed == SPEED_1000) {				err = tg3_phy_reset(tp);				if (!err)					err = tg3_init_5401phy_dsp(tp);				if (err)					return err;			}		}	} else if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||		   tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {		/* 5701 {A0,B0} CRC bug workaround */		tg3_writephy(tp, 0x15, 0x0a75);		tg3_writephy(tp, 0x1c, 0x8c68);		tg3_writephy(tp, 0x1c, 0x8d68);		tg3_writephy(tp, 0x1c, 0x8c68);	}	/* Clear pending interrupts... */	tg3_readphy(tp, MII_TG3_ISTAT, &dummy);	tg3_readphy(tp, MII_TG3_ISTAT, &dummy);	tg3_writephy(tp, MII_TG3_IMASK, ~0);	if (tp->led_mode == led_mode_three_link)		tg3_writephy(tp, MII_TG3_EXT_CTRL,			     MII_TG3_EXT_CTRL_LNK3_LED_MODE);	else		tg3_writephy(tp, MII_TG3_EXT_CTRL, 0);	current_link_up = 0;	tg3_readphy(tp, MII_BMSR, &bmsr);	tg3_readphy(tp, MII_BMSR, &bmsr);	if (bmsr & BMSR_LSTATUS) {		uint32_t aux_stat, bmcr;		tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);		for (i = 0; i < 2000; i++) {			udelay(10);			tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);			if (aux_stat)				break;		}		tg3_aux_stat_to_speed_duplex(tp, aux_stat,			&tp->link_config.active_speed,			&tp->link_config.active_duplex);		tg3_readphy(tp, MII_BMCR, &bmcr);		tg3_readphy(tp, MII_BMCR, &bmcr);		if (bmcr & BMCR_ANENABLE) {			uint32_t gig_ctrl;						current_link_up = 1;						/* Force autoneg restart if we are exiting			 * low power mode.			 */			tg3_readphy(tp, MII_TG3_CTRL, &gig_ctrl);			if (!(gig_ctrl & (MII_TG3_CTRL_ADV_1000_HALF |				      MII_TG3_CTRL_ADV_1000_FULL))) {				current_link_up = 0;			}		} else {			current_link_up = 0;		}	}	if (current_link_up == 1 &&		(tp->link_config.active_duplex == DUPLEX_FULL)) {		uint32_t local_adv, remote_adv;		tg3_readphy(tp, MII_ADVERTISE, &local_adv);		local_adv &= (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);		tg3_readphy(tp, MII_LPA, &remote_adv);		remote_adv &= (LPA_PAUSE_CAP | LPA_PAUSE_ASYM);		/* If we are not advertising full pause capability,		 * something is wrong.  Bring the link down and reconfigure.		 */		if (local_adv != ADVERTISE_PAUSE_CAP) {			current_link_up = 0;		} else {			tg3_setup_flow_control(tp, local_adv, remote_adv);		}	}	if (current_link_up == 0) {		uint32_t tmp;		tg3_phy_copper_begin(tp);		tg3_readphy(tp, MII_BMSR, &tmp);		tg3_readphy(tp, MII_BMSR, &tmp);		if (tmp & BMSR_LSTATUS)			current_link_up = 1;	}	tp->mac_mode &= ~MAC_MODE_PORT_MODE_MASK;	if (current_link_up == 1) {		if (tp->link_config.active_speed == SPEED_100 ||		    tp->link_config.active_speed == SPEED_10)			tp->mac_mode |= MAC_MODE_PORT_MODE_MII;		else			tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;	} else		tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;	tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;	if (tp->link_config.active_duplex == DUPLEX_HALF)		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;	tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {		if ((tp->led_mode == led_mode_link10) ||		    (current_link_up == 1 &&		     tp->link_config.active_speed == SPEED_10))			tp->mac_mode |= MAC_MODE_LINK_POLARITY;	} else {		if (current_link_up == 1)			tp->mac_mode |= MAC_MODE_LINK_POLARITY;		tw32(MAC_LED_CTRL, LED_CTRL_PHY_MODE_1);	}	/* ??? Without this setting Netgear GA302T PHY does not	 * ??? send/receive packets...	 * With this other PHYs cannot bring up the link	 */	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411 &&		tp->pci_chip_rev_id == CHIPREV_ID_5700_ALTIMA) {		tp->mi_mode |= MAC_MI_MODE_AUTO_POLL;		tw32_carefully(MAC_MI_MODE, tp->mi_mode);	}	tw32_carefully(MAC_MODE, tp->mac_mode);	/* Link change polled. */	tw32_carefully(MAC_EVENT, 0);	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 &&	    current_link_up == 1 &&	    tp->link_config.active_speed == SPEED_1000 &&	    ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ||	     (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED))) {		udelay(120);		tw32_carefully(MAC_STATUS,			(MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED));		tg3_write_mem(			      NIC_SRAM_FIRMWARE_MBOX,			      NIC_SRAM_FIRMWARE_MBOX_MAGIC2);	}	if (current_link_up != tp->carrier_ok) {		tp->carrier_ok = current_link_up;		tg3_link_report(tp);	}	return 0;}#else#define tg3_setup_copper_phy(TP) (-EINVAL)#endif /* SUPPORT_COPPER_PHY */#if SUPPORT_FIBER_PHYstruct tg3_fiber_aneginfo {	int state;#define ANEG_STATE_UNKNOWN		0#define ANEG_STATE_AN_ENABLE		1#define ANEG_STATE_RESTART_INIT		2#define ANEG_STATE_RESTART		3#define ANEG_STATE_DISABLE_LINK_OK	4#define ANEG_STATE_ABILITY_DETECT_INIT	5#define ANEG_STATE_ABILITY_DETECT	6#define ANEG_STATE_ACK_DETECT_INIT	7#define ANEG_STATE_ACK_DETECT		8#define ANEG_STATE_COMPLETE_ACK_INIT	9#define ANEG_STATE_COMPLETE_ACK		10#define ANEG_STATE_IDLE_DETECT_INIT	11#define ANEG_STATE_IDLE_DETECT		12#define ANEG_STATE_LINK_OK		13#define ANEG_STATE_NEXT_PAGE_WAIT_INIT	14#define ANEG_STATE_NEXT_PAGE_WAIT	15	uint32_t flags;#define MR_AN_ENABLE		0x00000001#define MR_RESTART_AN		0x00000002#define MR_AN_COMPLETE		0x00000004#define MR_PAGE_RX		0x00000008#define MR_NP_LOADED		0x00000010#define MR_TOGGLE_TX		0x00000020#define MR_LP_ADV_FULL_DUPLEX	0x00000040#define MR_LP_ADV_HALF_DUPLEX	0x00000080#define MR_LP_ADV_SYM_PAUSE	0x00000100#define MR_LP_ADV_ASYM_PAUSE	0x00000200#define MR_LP_ADV_REMOTE_FAULT1	0x00000400#define MR_LP_ADV_REMOTE_FAULT2	0x00000800#define MR_LP_ADV_NEXT_PAGE	0x00001000#define MR_TOGGLE_RX		0x00002000#define MR_NP_RX		0x00004000#define MR_LINK_OK		0x80000000	unsigned long link_time, cur_time;	uint32_t ability_match_cfg;	int ability_match_count;	char ability_match, idle_match, ack_match;	uint32_t txconfig, rxconfig;#define ANEG_CFG_NP		0x00000080#define ANEG_CFG_ACK		0x00000040#define ANEG_CFG_RF2		0x00000020#define ANEG_CFG_RF1		0x00000010#define ANEG_CFG_PS2		0x00000001#define ANEG_CFG_PS1		0x00008000#define ANEG_CFG_HD		0x00004000#define ANEG_CFG_FD		0x00002000#define ANEG_CFG_INVAL		0x00001f06};#define ANEG_OK		0#define ANEG_DONE	1#define ANEG_TIMER_ENAB	2#define ANEG_FAILED	-1#define ANEG_STATE_SETTLE_TIME	10000static int tg3_fiber_aneg_smachine(struct tg3 *tp,				   struct tg3_fiber_aneginfo *ap){	unsigned long delta;	uint32_t rx_cfg_reg;	int ret;	if (ap->state == ANEG_STATE_UNKNOWN) {		ap->rxconfig = 0;		ap->link_time = 0;		ap->cur_time = 0;		ap->ability_match_cfg = 0;		ap->ability_match_count = 0;		ap->ability_match = 0;		ap->idle_match = 0;

⌨️ 快捷键说明

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