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

📄 tg3.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 5 页
字号:
	return 0;}static int tg3_abort_hw(struct tg3 *tp){	int i, err;	tg3_disable_ints(tp);	tp->rx_mode &= ~RX_MODE_ENABLE;	tw32_carefully(MAC_RX_MODE, tp->rx_mode);	err  = tg3_stop_block(tp, RCVBDI_MODE,   RCVBDI_MODE_ENABLE);	err |= tg3_stop_block(tp, RCVLPC_MODE,   RCVLPC_MODE_ENABLE);	err |= tg3_stop_block(tp, RCVLSC_MODE,   RCVLSC_MODE_ENABLE);	err |= tg3_stop_block(tp, RCVDBDI_MODE,  RCVDBDI_MODE_ENABLE);	err |= tg3_stop_block(tp, RCVDCC_MODE,   RCVDCC_MODE_ENABLE);	err |= tg3_stop_block(tp, RCVCC_MODE,    RCVCC_MODE_ENABLE);	err |= tg3_stop_block(tp, SNDBDS_MODE,   SNDBDS_MODE_ENABLE);	err |= tg3_stop_block(tp, SNDBDI_MODE,   SNDBDI_MODE_ENABLE);	err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);	err |= tg3_stop_block(tp, RDMAC_MODE,    RDMAC_MODE_ENABLE);	err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE);	err |= tg3_stop_block(tp, SNDBDC_MODE,   SNDBDC_MODE_ENABLE);	if (err)		goto out;	tp->mac_mode &= ~MAC_MODE_TDE_ENABLE;	tw32_carefully(MAC_MODE, tp->mac_mode);	tp->tx_mode &= ~TX_MODE_ENABLE;	tw32_carefully(MAC_TX_MODE, tp->tx_mode);	for (i = 0; i < MAX_WAIT_CNT; i++) {		udelay(100);		if (!(tr32(MAC_TX_MODE) & TX_MODE_ENABLE))			break;	}	if (i >= MAX_WAIT_CNT) {		printf("tg3_abort_hw timed out TX_MODE_ENABLE will not clear MAC_TX_MODE=%x\n",			tr32(MAC_TX_MODE));		return -ENODEV;	}	err  = tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE);	err |= tg3_stop_block(tp, WDMAC_MODE,  WDMAC_MODE_ENABLE);	err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE);	tw32(FTQ_RESET, 0xffffffff);	tw32(FTQ_RESET, 0x00000000);	err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE);	err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE);	if (err)		goto out;	memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);out:	return err;}static void tg3_chip_reset(struct tg3 *tp){	uint32_t val;	if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {		/* Force NVRAM to settle.		 * This deals with a chip bug which can result in EEPROM		 * corruption.		 */		if (tp->tg3_flags & TG3_FLAG_NVRAM) {			int i;				tw32(NVRAM_SWARB, SWARB_REQ_SET1);			for (i = 0; i < 100000; i++) {				if (tr32(NVRAM_SWARB) & SWARB_GNT1)					break;				udelay(10);			}		}	}	/* In Etherboot we don't need to worry about the 5701	 * REG_WRITE_BUG because we do all register writes indirectly.	 */	/* do the reset */	val = GRC_MISC_CFG_CORECLK_RESET;	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)		val |= GRC_MISC_CFG_KEEP_GPHY_POWER;	tw32(GRC_MISC_CFG, val);	/* Flush PCI posted writes.  The normal MMIO registers	 * are inaccessible at this time so this is the only	 * way to make this reliably.  I tried to use indirect	 * register read/write but this upset some 5701 variants.	 */	pci_read_config_dword(tp->pdev, PCI_COMMAND, &val);	udelay(120);	/* Re-enable indirect register accesses. */	pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,			       tp->misc_host_ctrl);	/* Set MAX PCI retry to zero. */	val = (PCISTATE_ROM_ENABLE | PCISTATE_ROM_RETRY_ENABLE);	if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE))		val |= PCISTATE_RETRY_SAME_DMA;	pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val);	pci_restore_state(tp->pdev, tp->pci_cfg_state);	/* Make sure PCI-X relaxed ordering bit is clear. */	pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val);	val &= ~PCIX_CAPS_RELAXED_ORDERING;	pci_write_config_dword(tp->pdev, TG3PCI_X_CAPS, val);	tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);	if (((tp->nic_sram_data_cfg & NIC_SRAM_DATA_CFG_MINI_PCI) != 0) &&		(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) {		tp->pci_clock_ctrl |=			(CLOCK_CTRL_FORCE_CLKRUN | CLOCK_CTRL_CLKRUN_OENABLE);		tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);	}	tw32(TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);}static void tg3_stop_fw(struct tg3 *tp){	if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {		uint32_t val;		int i;		tg3_write_mem(NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);		val = tr32(GRC_RX_CPU_EVENT);		val |= (1 << 14);		tw32(GRC_RX_CPU_EVENT, val);		/* Wait for RX cpu to ACK the event.  */		for (i = 0; i < 100; i++) {			if (!(tr32(GRC_RX_CPU_EVENT) & (1 << 14)))				break;			udelay(1);		}	}}static int tg3_restart_fw(struct tg3 *tp, uint32_t state){	uint32_t val;	int i;		tg3_write_mem(NIC_SRAM_FIRMWARE_MBOX, 		NIC_SRAM_FIRMWARE_MBOX_MAGIC1);	/* Wait for firmware initialization to complete. */	for (i = 0; i < 100000; i++) {		tg3_read_mem(NIC_SRAM_FIRMWARE_MBOX, &val);		if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)			break;		udelay(10);	}	if (i >= 100000 &&		    !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {		printf("Firmware will not restart magic=%x\n",			val);		return -ENODEV;	}	if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {		state = DRV_STATE_SUSPEND;	}	tg3_write_mem(NIC_SRAM_FW_DRV_STATE_MBOX, state);	return 0;}static int tg3_halt(struct tg3 *tp){	tg3_stop_fw(tp);	tg3_abort_hw(tp);	tg3_chip_reset(tp);	return tg3_restart_fw(tp, DRV_STATE_UNLOAD);}static void __tg3_set_mac_addr(struct tg3 *tp){	uint32_t addr_high, addr_low;	int i;	addr_high = ((tp->nic->node_addr[0] << 8) |		     tp->nic->node_addr[1]);	addr_low = ((tp->nic->node_addr[2] << 24) |		    (tp->nic->node_addr[3] << 16) |		    (tp->nic->node_addr[4] <<  8) |		    (tp->nic->node_addr[5] <<  0));	for (i = 0; i < 4; i++) {		tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);		tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);	}	if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) &&		(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) &&		(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705)) {		for(i = 0; i < 12; i++) {			tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high);			tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low);		}	}	addr_high = (tp->nic->node_addr[0] +		     tp->nic->node_addr[1] +		     tp->nic->node_addr[2] +		     tp->nic->node_addr[3] +		     tp->nic->node_addr[4] +		     tp->nic->node_addr[5]) &		TX_BACKOFF_SEED_MASK;	tw32(MAC_TX_BACKOFF_SEED, addr_high);}static void tg3_set_bdinfo(struct tg3 *tp, uint32_t bdinfo_addr,			   dma_addr_t mapping, uint32_t maxlen_flags,			   uint32_t nic_addr){	tg3_write_mem((bdinfo_addr +		       TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH),		      ((uint64_t) mapping >> 32));	tg3_write_mem((bdinfo_addr +		       TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW),		      ((uint64_t) mapping & 0xffffffff));	tg3_write_mem((bdinfo_addr +		       TG3_BDINFO_MAXLEN_FLAGS),		       maxlen_flags);	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {		tg3_write_mem((bdinfo_addr + TG3_BDINFO_NIC_ADDR), nic_addr);	}}static void tg3_init_rings(struct tg3 *tp){	unsigned i;	/* Zero out the tg3 variables */	memset(&tg3_bss, 0, sizeof(tg3_bss));	tp->rx_std    = &tg3_bss.rx_std[0];	tp->rx_rcb    = &tg3_bss.rx_rcb[0];	tp->tx_ring   = &tg3_bss.tx_ring[0];	tp->hw_status = &tg3_bss.hw_status;	tp->hw_stats  = &tg3_bss.hw_stats;	tp->mac_mode  = 0;	/* Initialize tx/rx rings for packet processing.	 *	 * The chip has been shut down and the driver detached from	 * the networking, so no interrupts or new tx packets will	 * end up in the driver.	 */	/* Initialize invariants of the rings, we only set this	 * stuff once.  This works because the card does not	 * write into the rx buffer posting rings.	 */	for (i = 0; i < TG3_RX_RING_SIZE; i++) {		struct tg3_rx_buffer_desc *rxd;		rxd = &tp->rx_std[i];		rxd->idx_len = (RX_PKT_BUF_SZ - 2 - 64)	<< RXD_LEN_SHIFT;		rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);		rxd->opaque = (RXD_OPAQUE_RING_STD | (i << RXD_OPAQUE_INDEX_SHIFT));		/* Note where the receive buffer for the ring is placed */		rxd->addr_hi = 0;		rxd->addr_lo = virt_to_bus(			&tg3_bss.rx_bufs[i%TG3_DEF_RX_RING_PENDING][2]);	}}#define TG3_WRITE_SETTINGS(TABLE) \do { \	const uint32_t *_table, *_end; \	_table = TABLE; \	_end = _table + sizeof(TABLE)/sizeof(TABLE[0]);  \	for(; _table < _end; _table += 2) { \		tw32(_table[0], _table[1]); \	} \} while(0)/* initialize/reset the tg3 */static int tg3_setup_hw(struct tg3 *tp){	uint32_t val, rdmac_mode;	int i, err, limit;	/* Simply don't support setups with extremly buggy firmware in etherboot */	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {		printf("Error 5701_A0 firmware bug detected\n");		return -EINVAL;	}	tg3_disable_ints(tp);	/* Originally this was all in tg3_init_hw */	/* Force the chip into D0. */	tg3_set_power_state_0(tp);	tg3_switch_clocks(tp);	tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);	/* Originally this was all in tg3_reset_hw */	tg3_stop_fw(tp);	/* No need to call tg3_abort_hw here, it is called before tg3_setup_hw. */	tg3_chip_reset(tp);	tw32(GRC_MODE, tp->grc_mode);  /* Redundant? */	err = tg3_restart_fw(tp, DRV_STATE_START);	if (err)		return err;	if (tp->phy_id == PHY_ID_SERDES) {		tp->mac_mode = MAC_MODE_PORT_MODE_TBI;	}	tw32_carefully(MAC_MODE, tp->mac_mode);	/* This works around an issue with Athlon chipsets on	 * B3 tigon3 silicon.  This bit has no effect on any	 * other revision.	 */	tp->pci_clock_ctrl |= CLOCK_CTRL_DELAY_PCI_GRANT;	tw32_carefully(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);	if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {		val = tr32(TG3PCI_PCISTATE);		val |= PCISTATE_RETRY_SAME_DMA;		tw32(TG3PCI_PCISTATE, val);	}	/* Descriptor ring init may make accesses to the	 * NIC SRAM area to setup the TX descriptors, so we	 * can only do this after the hardware has been	 * successfully reset.	 */	tg3_init_rings(tp);	/* Clear statistics/status block in chip */	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {		for (i = NIC_SRAM_STATS_BLK;		     i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;		     i += sizeof(uint32_t)) {			tg3_write_mem(i, 0);			udelay(40);		}	}	/* This value is determined during the probe time DMA	 * engine test, tg3_setup_dma.	 */	tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);	tp->grc_mode &= ~(GRC_MODE_HOST_SENDBDS |			  GRC_MODE_4X_NIC_SEND_RINGS |			  GRC_MODE_NO_TX_PHDR_CSUM |			  GRC_MODE_NO_RX_PHDR_CSUM);	tp->grc_mode |= GRC_MODE_HOST_SENDBDS;	tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM;	tp->grc_mode |= GRC_MODE_NO_RX_PHDR_CSUM;	tw32(GRC_MODE,		tp->grc_mode | 		(GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP));	/* Setup the timer prescalar register.  Clock is always 66Mhz. */	tw32(GRC_MISC_CFG,	     (65 << GRC_MISC_CFG_PRESCALAR_SHIFT));	/* Initialize MBUF/DESC pool. */	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {		tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE);		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)			tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64);		else			tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96);		tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE);		tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE);	}	if (!(tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE)) {		tw32(BUFMGR_MB_RDMA_LOW_WATER,		     tp->bufmgr_config.mbuf_read_dma_low_water);		tw32(BUFMGR_MB_MACRX_LOW_WATER,		     tp->bufmgr_config.mbuf_mac_rx_low_water);		tw32(BUFMGR_MB_HIGH_WATER,		     tp->bufmgr_config.mbuf_high_water);	} else {		tw32(BUFMGR_MB_RDMA_LOW_WATER,		     tp->bufmgr_config.mbuf_read_dma_low_water_jumbo);		tw32(BUFMGR_MB_MACRX_LOW_WATER,		     tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo);		tw32(BUFMGR_MB_HIGH_WATER,		     tp->bufmgr_config.mbuf_high_water_jumbo);	}	tw32(BUFMGR_DMA_LOW_WATER,	     tp->bufmgr_config.dma_low_water);	tw32(BUFMGR_DMA_HIGH_WATER,	     tp->bufmgr_config.dma_high_water);	tw32(BUFMGR_MODE, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);	for (i = 0; i < 2000; i++) {		if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE)			break;		udelay(10);	}	if (i >= 2000) {		printf("tg3_setup_hw cannot enable BUFMGR\n");		return -ENODEV;	}	tw32(FTQ_RESET, 0xffffffff);	tw32(FTQ_RESET, 0x00000000);	for (i = 0; i < 2000; i++) {		if (tr32(FTQ_RESET) == 0x00000000)			break;		udelay(10);	}	if (i >= 2000) {		printf("tg3_setup_hw cannot reset FTQ\n");		return -ENODEV;	}	/* Initialize TG3_BDINFO's at:	 *  RCVDBDI_STD_BD:	standard eth size rx ring	 *  RCVDBDI_JUMBO_BD:	jumbo frame rx ring	 *  RCVDBDI_MINI_BD:	small frame rx ring (??? does not work)	 *	 * like so:	 *  TG3_BDINFO_HOST_ADDR:	high/low parts of DMA address of ring	 *  TG3_BDINFO_MAXLEN_FLAGS:	(rx max buffer size << 16) |	 *                              ring attribute flags	 *  TG3_BDINFO_NIC_ADDR:	location of descriptors in nic SRAM	 *	 * Standard receive ring @ NIC_SRAM_RX_BUFFER_DESC, 512 entries.	 * Jumbo receive ring @ NIC_SRAM_RX_JUMBO_BUFFER_DESC, 256 entries.	 *	 * ??? No space allocated for mini receive ring? :(	 *	 * The size of each ring is fixed in the firmware, but the location is	 * configurable.	 */	{		static const uint32_t table_all[] = {			/* Setup replenish thresholds. */			RCVBDI_STD_THRESH, TG3_DEF_RX_RING_PENDING / 8,			/* Etherboot lives below 4GB */			RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH, 0,			RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, NIC_SRAM_RX_BUFFER_DESC,		};		static const uint32_t table_not_5705[] = {			/* Buffer maximum length */			RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT,						/* Disable the mini frame rx ring */			RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS,	BDINFO_FLAGS_DISABLED,						/* Disable the jumbo frame rx ring */			RCVBDI_JUMBO_THRESH, 0,			RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED,								};		TG3_WRITE_SETTINGS(table_all);		tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, 

⌨️ 快捷键说明

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