📄 e1000_main.c
字号:
* Author: IntelCorporation** Born on Date: 7/12/99** Arguments: * device_t dev - the device stucture to return stats on** Returns:* the address of the net_device_stats stucture for the device** Modification log:* Date Who Description* -------- --- -------------------------------------------------------- *****************************************************************************/static struct net_device_stats *e1000_get_stats(device_t * dev){ bd_config_t *bdp = dev->priv; /* Statistics are updated from the watchdog - so just return them now */ return (&bdp->net_stats);}/* this routine is to change the MTU size for jumbo frames *//***************************************************************************** Name: e1000_change_mtu** Description: This routine is called when the OS would like the driver to* change the MTU size. This is used for jumbo frame support.** Author: IntelCorporation** Born on Date: 7/12/98** Arguments: * device_t pointer - pointer to the device* int - the new MTU size ** Returns:* ???? ** Modification log:* Date Who Description* -------- --- -------------------------------------------------------- *****************************************************************************/static inte1000_change_mtu(device_t * dev, int new_mtu){ bd_config_t *bdp; PADAPTER_STRUCT Adapter; bdp = (bd_config_t *) dev->priv; Adapter = bdp->bddp; if ((new_mtu < MINIMUM_ETHERNET_PACKET_SIZE - ENET_HEADER_SIZE) || (new_mtu > MAX_JUMBO_FRAME_SIZE - ENET_HEADER_SIZE)) return -EINVAL; if (new_mtu <= MAXIMUM_ETHERNET_PACKET_SIZE - ENET_HEADER_SIZE) { /* 802.x legal frame sizes */ Adapter->LongPacket = FALSE; if (Adapter->RxBufferLen != E1000_RXBUFFER_2048) { Adapter->RxBufferLen = E1000_RXBUFFER_2048; if (dev->flags & IFF_UP) { e1000_close(dev); e1000_open(dev); } } } else if (Adapter->MacType < MAC_LIVENGOOD) { /* Jumbo frames not supported on 82542 hardware */ printk("e1000: Jumbo frames not supported on 82542\n"); return -EINVAL; } else if (Jumbo[Adapter->bd_number] != 1) { printk("e1000: Jumbo frames disabled\n"); return -EINVAL; } else if (new_mtu <= (4096 - 256) - ENET_HEADER_SIZE) { /* 4k buffers */ Adapter->LongPacket = TRUE; if (Adapter->RxBufferLen != E1000_RXBUFFER_4096) { Adapter->RxBufferLen = E1000_RXBUFFER_4096; if (dev->flags & IFF_UP) { e1000_close(dev); e1000_open(dev); } } } else if (new_mtu <= (8192 - 256) - ENET_HEADER_SIZE) { /* 8k buffers */ Adapter->LongPacket = TRUE; if (Adapter->RxBufferLen != E1000_RXBUFFER_8192) { Adapter->RxBufferLen = E1000_RXBUFFER_8192; if (dev->flags & IFF_UP) { e1000_close(dev); e1000_open(dev); } } } else { /* 16k buffers */ Adapter->LongPacket = TRUE; if (Adapter->RxBufferLen != E1000_RXBUFFER_16384) { Adapter->RxBufferLen = E1000_RXBUFFER_16384; if (dev->flags & IFF_UP) { e1000_close(dev); e1000_open(dev); } } } dev->mtu = new_mtu; return 0;}/***************************************************************************** Name: e1000_init** Description: This routine is called when this driver is loaded. This is* the initialization routine which allocates memory, starts the* watchdog, & configures the adapter, determines the system* resources.** Author: IntelCorporation** Born on Date: 1/18/98** Arguments: * NONE** Returns:* NONE ** Modification log:* Date Who Description* -------- --- -------------------------------------------------------- *****************************************************************************/static inte1000_init(bd_config_t * bdp){ PADAPTER_STRUCT Adapter; device_t *dev; uint16_t LineSpeed, FullDuplex; if (e1000_debug_level >= 1) printk("e1000_init()\n"); dev = bdp->device; Adapter = (PADAPTER_STRUCT) bdp->bddp; /* * Disable interrupts on the E1000 card */ e1000DisableInterrupt(Adapter); /**** Reset and Initialize the E1000 *******/ AdapterStop(Adapter); Adapter->AdapterStopped = FALSE; /* Validate the EEPROM */ if (!ValidateEepromChecksum(Adapter)) { printk("e1000: The EEPROM checksum is not valid \n"); return (1); } /* read the ethernet address from the eprom */ ReadNodeAddress(Adapter, &Adapter->perm_node_address[0]); if (e1000_debug_level >= 2) { printk("Node addr is: "); printk("%x:", Adapter->perm_node_address[0]); printk("%x:", Adapter->perm_node_address[1]); printk("%x:", Adapter->perm_node_address[2]); printk("%x:", Adapter->perm_node_address[3]); printk("%x:", Adapter->perm_node_address[4]); printk("%x\n ", Adapter->perm_node_address[5]); } /* save off the perm node addr in the bdp */ memcpy(bdp->eaddr.bytes, &Adapter->perm_node_address[0], DL_MAC_ADDR_LEN); /* tell the system what the address is... */ memcpy(&dev->dev_addr[0], &Adapter->perm_node_address[0], DL_MAC_ADDR_LEN); /* Scan the chipset and determine whether to set the RS bit or * the RPS bit during transmits. On some systems with a fast chipset * (450NX), setting the RS bit may cause data corruption. Check the * space.c paratemer to see if the user has forced this setting or * has let the software do the detection. */ if ((e1000_ReportTxEarly == 0) || (e1000_ReportTxEarly == 1)) Adapter->ReportTxEarly = e1000_ReportTxEarly; /* User setting */ else { /* let the software setect the chipset */ if(Adapter->MacType < MAC_LIVENGOOD) { if (DetectKnownChipset(Adapter) == B_TRUE) Adapter->ReportTxEarly = 1; /* Set the RS bit */ else Adapter->ReportTxEarly = 0; /* Set the RPS bit */ } else Adapter->ReportTxEarly = 1; } Adapter->FlowControl = e1000_flow_ctrl; Adapter->RxPciPriority = e1000_rxpci_priority; /* Do the adapter initialization */ if (!InitializeHardware(Adapter)) { printk("InitializeHardware Failed\n"); return (1); } /* all initialization done, mark board as present */ bdp->flags = BOARD_PRESENT; CheckForLink(Adapter); if(E1000_READ_REG(Status) & E1000_STATUS_LU) { Adapter->LinkIsActive = TRUE; GetSpeedAndDuplex(Adapter, &LineSpeed, &FullDuplex); Adapter->cur_line_speed = (uint32_t) LineSpeed; Adapter->FullDuplex = (uint32_t) FullDuplex;#ifdef IANS Adapter->ans_link = IANS_STATUS_LINK_OK; Adapter->ans_speed = (uint32_t) LineSpeed; Adapter->ans_duplex = FullDuplex == FULL_DUPLEX ? BD_ANS_DUPLEX_FULL : BD_ANS_DUPLEX_HALF;#endif } else { Adapter->LinkIsActive = FALSE; Adapter->cur_line_speed = 0; Adapter->FullDuplex = 0;#ifdef IANS Adapter->ans_link = IANS_STATUS_LINK_FAIL; Adapter->ans_speed = 0; Adapter->ans_duplex = 0;#endif } if (e1000_debug_level >= 1) printk("e1000_init: end\n"); return (0);}static inte1000_runtime_init(bd_config_t * bdp){ PADAPTER_STRUCT Adapter; device_t *dev; if (e1000_debug_level >= 1) printk("e1000_init()\n"); dev = bdp->device; Adapter = (PADAPTER_STRUCT) bdp->bddp; /* Setup Shared Memory Structures */ /* Make sure RxBufferLen is set to something */ if (Adapter->RxBufferLen == 0) { Adapter->RxBufferLen = E1000_RXBUFFER_2048; Adapter->LongPacket = FALSE; } if (!e1000_sw_init(bdp)) { /* Board is disabled because all memory structures * could not be allocated */ printk ("%s - Could not allocate the software mem structures\n", e1000_driver); bdp->flags = BOARD_DISABLED; return (1); } /* Setup and initialize the transmit structures. */ SetupTransmitStructures(Adapter, B_TRUE); /* Setup and initialize the receive structures -- we can receive packets * off of the wire */ SetupReceiveStructures(bdp, TRUE, TRUE); return 0;}/***************************************************************************** Name: e1000_set_mac** Description: This routine sets the ethernet address of the board** Author: IntelCorporation** Born on Date: 07/11/99** Arguments: * bdp - Ptr to this card's bd_config_t structure* eaddrp - Ptr to the new ethernet address** Returns:* 1 - If successful* 0 - If not successful** Modification log:* Date Who Description* -------- --- -------------------------------------------------------- *****************************************************************************/static inte1000_set_mac(device_t * dev, void *p){ bd_config_t *bdp; uint32_t HwLowAddress = 0; uint32_t HwHighAddress = 0; uint32_t RctlRegValue; uint16_t PciCommandWord; PADAPTER_STRUCT Adapter; uint32_t IntMask; struct sockaddr *addr = p; if (e1000_debug_level >= 1) printk("set_eaddr()\n"); bdp = dev->priv; Adapter = bdp->bddp; RctlRegValue = E1000_READ_REG(Rctl); /* * setup the MAC address by writing to RAR0 */ if (Adapter->MacType == MAC_WISEMAN_2_0) { /* if MWI was enabled then dis able it before issueing the receive * reset to the hardware. */ if (Adapter->PciCommandWord && CMD_MEM_WRT_INVALIDATE) { PciCommandWord = Adapter->PciCommandWord & ~CMD_MEM_WRT_INVALIDATE; WritePciConfigWord(PCI_COMMAND_REGISTER, &PciCommandWord); } /* reset receiver */ E1000_WRITE_REG(Rctl, E1000_RCTL_RST); DelayInMilliseconds(5); /* Allow receiver time to go in to reset */ } memcpy(Adapter->CurrentNetAddress, addr->sa_data, DL_MAC_ADDR_LEN); /****************************************************************** ** Setup the receive address (individual/node/network address). ******************************************************************/ if (e1000_debug_level >= 2) printk("Programming IA into RAR[0]\n"); HwLowAddress = (Adapter->CurrentNetAddress[0] | (Adapter->CurrentNetAddress[1] << 8) | (Adapter->CurrentNetAddress[2] << 16) | (Adapter->CurrentNetAddress[3] << 24)); HwHighAddress = (Adapter->CurrentNetAddress[4] | (Adapter->CurrentNetAddress[5] << 8) | E1000_RAH_AV); E1000_WRITE_REG(Rar[0].Low, HwLowAddress); E1000_WRITE_REG(Rar[0].High, HwHighAddress); memcpy(bdp->eaddr.bytes, addr->sa_data, DL_MAC_ADDR_LEN); memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); if (Adapter->MacType == MAC_WISEMAN_2_0) { /****************************************************************** ** Take the receiver out of reset. ******************************************************************/ E1000_WRITE_REG(Rctl, 0); DelayInMilliseconds(1); /* if MWI was enabled then reenable it after issueing the global * or receive reset to the hardware. */ if (Adapter->PciCommandWord && CMD_MEM_WRT_INVALIDATE) { WritePciConfigWord(PCI_COMMAND_REGISTER, &Adapter->PciCommandWord); } IntMask = E1000_READ_REG(Ims); e1000DisableInterrupt(Adapter); /* Enable receiver */ SetupReceiveStructures(bdp, FALSE, FALSE); E1000_WRITE_REG(Ims, IntMask); /* e1000EnableInterrupt( Adapter ); */ } return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -