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

📄 e1000_idiag.c

📁 COPE the first practical network coding scheme which is developped on click
💻 C
📖 第 1 页 / 共 3 页
字号:
	memset(txdr->buffer_info, 0, size);	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);	E1000_ROUNDUP(txdr->size, 4096);	if(!(txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma)))		goto err_nomem;	memset(txdr->desc, 0, txdr->size);	txdr->next_to_use = txdr->next_to_clean = 0;	E1000_WRITE_REG(&adapter->hw, TDBAL,			((uint64_t) txdr->dma & 0x00000000FFFFFFFF));	E1000_WRITE_REG(&adapter->hw, TDBAH, ((uint64_t) txdr->dma >> 32));	E1000_WRITE_REG(&adapter->hw, TDLEN,			txdr->count * sizeof(struct e1000_tx_desc));	E1000_WRITE_REG(&adapter->hw, TDH, 0);	E1000_WRITE_REG(&adapter->hw, TDT, 0);	E1000_WRITE_REG(&adapter->hw, TCTL,			E1000_TCTL_PSP | E1000_TCTL_EN |			E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |			E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT);	for(i = 0; i < txdr->count; i++) {		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*txdr, i);		struct sk_buff *skb;		unsigned int size = 1024;		if(!(skb = alloc_skb(size, GFP_KERNEL)))			goto err_nomem;		skb_put(skb, size);		txdr->buffer_info[i].skb = skb;		txdr->buffer_info[i].length = skb->len;		txdr->buffer_info[i].dma =			pci_map_single(pdev, skb->data, skb->len,				       PCI_DMA_TODEVICE);		tx_desc->buffer_addr = cpu_to_le64(txdr->buffer_info[i].dma);		tx_desc->lower.data = cpu_to_le32(skb->len);		tx_desc->lower.data |= E1000_TXD_CMD_EOP;		tx_desc->lower.data |= E1000_TXD_CMD_IFCS;		tx_desc->lower.data |= E1000_TXD_CMD_RPS;		tx_desc->upper.data = 0;	}	/* Setup Rx descriptor ring and Rx buffers */	rxdr->count = 80;	size = rxdr->count * sizeof(struct e1000_buffer);#if 0	if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL)))		goto err_nomem;#endif	memset(rxdr->buffer_info, 0, size);	rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc);	if(!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma)))		goto err_nomem;	memset(rxdr->desc, 0, rxdr->size);	rxdr->next_to_use = rxdr->next_to_clean = 0;	rctl = E1000_READ_REG(&adapter->hw, RCTL);	E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN);	E1000_WRITE_REG(&adapter->hw, RDBAL,			((uint64_t) rxdr->dma & 0xFFFFFFFF));	E1000_WRITE_REG(&adapter->hw, RDBAH, ((uint64_t) rxdr->dma >> 32));	E1000_WRITE_REG(&adapter->hw, RDLEN, rxdr->size);	E1000_WRITE_REG(&adapter->hw, RDH, 0);	E1000_WRITE_REG(&adapter->hw, RDT, 0);	rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 |		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | 		(adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);	for(i = 0; i < rxdr->count; i++) {		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);		struct sk_buff *skb;		if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + 2, GFP_KERNEL)))			goto err_nomem;		skb_reserve(skb, 2);		rxdr->buffer_info[i].skb = skb;		rxdr->buffer_info[i].length = E1000_RXBUFFER_2048;		rxdr->buffer_info[i].dma =			pci_map_single(pdev, skb->data, E1000_RXBUFFER_2048,				       PCI_DMA_FROMDEVICE);		rx_desc->buffer_addr = cpu_to_le64(rxdr->buffer_info[i].dma);		memset(skb->data, 0x00, skb->len);	}	return 0;      err_nomem:	e1000_free_desc_rings(adapter);	return -ENOMEM;}/** * e1000_phy_disable_receiver - This routine disables the receiver * during loopback testing to insure that if, in the middle of a * loopback test, a link partner is connected, it won't change the * speed or link status and thus cause a failure. * * @adapter: board private structure **/static voide1000_phy_disable_receiver(struct e1000_adapter *adapter){	/* Write out to PHY registers 29 and 30 to disable the Receiver. */	e1000_write_phy_reg(&adapter->hw, 29, 0x001F);	e1000_write_phy_reg(&adapter->hw, 30, 0x8FFC);	e1000_write_phy_reg(&adapter->hw, 29, 0x001A);	e1000_write_phy_reg(&adapter->hw, 30, 0x8FF0);	return;}/** * e1000_phy_reset_clk_and_crs - This routine resets the TX_CLK and * TX_CRS registers on the non-integrated PHY. * * @adapter: board private structure **/static voide1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter){	uint16_t phy_reg;	/* Because we reset the PHY above, we need to re-force TX_CLK in the	 * Extended PHY Specific Control Register to 25MHz clock.  This	 * value defaults back to a 2.5MHz clock when the PHY is reset.	 */	e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);	phy_reg |= M88E1000_EPSCR_TX_CLK_25;	e1000_write_phy_reg(&adapter->hw, 		M88E1000_EXT_PHY_SPEC_CTRL, phy_reg);	/* In addition, because of the s/w reset above, we need to enable	 * CRS on TX.  This must be set for both full and half duplex	 * operation.	 */	e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);	phy_reg |= M88E1000_PSCR_ASSERT_CRS_ON_TX;	e1000_write_phy_reg(&adapter->hw, 		M88E1000_PHY_SPEC_CTRL, phy_reg);}/** * e1000_nonintegrated_phy_loopback - This routine enables the PHY  * loopback circuit to work on the non-integrated PHY, under *any* link * condition. * * @adapter: board private structure * * Returns 0 on success, 1 on failure **/static inte1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter){	uint32_t ctrl_reg;	uint16_t phy_reg;	int status = 1;	/* Setup the Device Control Register for PHY loopback test. */	ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);	ctrl_reg |= (E1000_CTRL_ILOS |		/* Invert Loss-Of-Signal */		     E1000_CTRL_FRCSPD |	/* Set the Force Speed Bit */		     E1000_CTRL_FRCDPX |	/* Set the Force Duplex Bit */		     E1000_CTRL_SPD_1000 |	/* Force Speed to 1000 */		     E1000_CTRL_FD);		/* Force Duplex to FULL */	E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg);	/* Read the PHY Specific Control Register (0x10) */	e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);	/* Clear Auto-Crossover bits in PHY Specific Control Register	 * (bits 6:5).	 */	phy_reg &= ~M88E1000_PSCR_AUTO_X_MODE;	e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, phy_reg);	/* Perform software reset on the PHY */	e1000_phy_reset(&adapter->hw);	/* Have to setup TX_CLK and TX_CRS after software reset */	e1000_phy_reset_clk_and_crs(adapter);	e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100);	/* Wait for reset to complete. */	usec_delay(500);	/* Have to setup TX_CLK and TX_CRS after software reset */	e1000_phy_reset_clk_and_crs(adapter);	/* Write out to PHY registers 29 and 30 to disable the Receiver. */	e1000_phy_disable_receiver(adapter);	/* Set the loopback bit in the PHY control register. */	e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);	phy_reg |= MII_CR_LOOPBACK;	e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);	/* Setup TX_CLK and TX_CRS one more time. */	e1000_phy_reset_clk_and_crs(adapter);	status = 0;	/* Check Phy Configuration */	e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);	if(phy_reg != 0x4100) {		status = 1;	}	e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);	if(phy_reg != 0x0070) {		status = 1;	}	e1000_read_phy_reg(&adapter->hw, 29, &phy_reg);	if(phy_reg != 0x001A) {		status = 1;	}	return status;}/** * e1000_integrated_phy_loopback - This routine is used by diagnostic * software to put the 82544, 82540, 82545, and 82546 MAC based network * cards into loopback mode. * * @adapter: board private structure * @speed: speed *                *  Current procedure is to: *    1) Disable auto-MDI/MDIX *    2) Perform SW phy reset (bit 15 of PHY_CTRL) *    3) Disable autoneg and reset *    4) For the specified speed, set the loopback *       mode for that speed.  Also force the MAC *       to the correct speed and duplex for the *       specified operation. *    5) If this is an 82543, setup the TX_CLK and *       TX_CRS again. *    6) Disable the receiver so a cable disconnect *       and reconnect will not cause autoneg to *       begin. * * Returns 0 on success, 1 on failure **/static inte1000_integrated_phy_loopback(struct e1000_adapter *adapter,			      uint16_t speed){	uint32_t ctrl_reg = 0;	uint32_t stat_reg = 0;	boolean_t loopback_mode_set = FALSE;	adapter->hw.autoneg = FALSE;	/* Set up desired loopback speed and duplex depending on input	 * into this function.	 */	switch (speed) {	case SPEED_1000:		/* Set up the MII control reg to the desired loopback speed. */		/* Auto-MDI/MDIX Off */		e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL,				    0x0808);		/* reset to update Auto-MDI/MDIX */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140);		/* autoneg off */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140);		/* force 1000, set loopback */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140);		/* Now set up the MAC to the same speed/duplex as the PHY. */		ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);		ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */		ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */			     E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */			     E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */			     E1000_CTRL_FD);	 /* Force Duplex to FULL */		if(adapter->hw.media_type == e1000_media_type_copper) {			ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */		} else {			/* Set the ILOS bit on the fiber Nic is half			 * duplex link is detected. */			stat_reg = E1000_READ_REG(&adapter->hw, STATUS);			if((stat_reg & E1000_STATUS_FD) == 0)				ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);		}		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg);		loopback_mode_set = TRUE;		break;	case SPEED_100:		/* Set up the MII control reg to the desired loopback speed. */		/* Auto-MDI/MDIX Off */		e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL,				    0x0808);		/* reset to update Auto-MDI/MDIX */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140);		/* autoneg off */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140);		/* reset to update autoneg */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100);		/* MAC interface speed to 100Mbps */		e1000_write_phy_reg(&adapter->hw,				    M88E1000_EXT_PHY_SPEC_CTRL, 0x0c14);		/* reset to update MAC interface speed */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0xe100);		/* force 100, set loopback */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x6100);		/* Now set up the MAC to the same speed/duplex as the PHY. */		ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);		ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */		ctrl_reg |= (E1000_CTRL_ILOS |	 /* Invert Loss-Of-Signal */			     E1000_CTRL_SLU |    /* Set the Force Link Bit */			     E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */			     E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */			     E1000_CTRL_SPD_100 |/* Force Speed to 100 */			     E1000_CTRL_FD);	 /* Force Duplex to FULL */		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg);		loopback_mode_set = TRUE;		break;	case SPEED_10:		/* Set up the MII control reg to the desired loopback speed. */		/* Auto-MDI/MDIX Off */		e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL,				    0x0808);		/* reset to update Auto-MDI/MDIX */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140);		/* autoneg off */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140);		/* reset to update autoneg */		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100);		/* MAC interface speed to 10Mbps */		e1000_write_phy_reg(&adapter->hw,

⌨️ 快捷键说明

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