/drivers/e1000-2.x/e1000_main.c
C | 4185 lines | 2319 code | 577 blank | 1289 comment | 491 complexity | c752713a14b002fc5251b0bcf6b65467 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- /*****************************************************************************
- *****************************************************************************
- Copyright (c) 1999 - 2000, Intel Corporation
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- 3. Neither the name of Intel Corporation nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************
- ****************************************************************************/
- /**********************************************************************
- * *
- * INTEL CORPORATION *
- * *
- * This software is supplied under the terms of the license included *
- * above. All use of this driver must be in accordance with the terms *
- * of that license. *
- * *
- * Module Name: e1000.c *
- * *
- * Abstract: Functions for the driver entry points like load, *
- * unload, open and close. All board specific calls made *
- * by the network interface section of the driver. *
- * *
- * Environment: This file is intended to be specific to the Linux *
- * operating system. *
- * *
- **********************************************************************/
-
- /* This first section contains the setable parametes for configuring the
- * driver into the kernel.
- */
- #define E1000_DEBUG_DEFAULT 0
- static int e1000_debug_level = E1000_DEBUG_DEFAULT;
- /* global defines */
- #define MAX_TCB 256 /* number of transmit descriptors */
- #define MAX_RFD 256 /* number of receive descriptors */
- /* includes */
- #ifdef MODULE
- #ifdef MODVERSIONS
- #include <linux/modversions.h>
- #endif
- #include <linux/module.h>
- #endif
- #define E1000_MAIN_STATIC
- #ifdef IANS
- #define _IANS_MAIN_MODULE_C_
- #endif
- #include "e1000.h"
- #include "e1000_vendor_info.h"
- #include "e1000_proc.h"
- /* Global Data structures and variables */
- static const char *version =
- "Intel(R) PRO/1000 Gigabit Ethernet Adapter - Loadable driver, ver. 2.5.11\n";
- static char e1000_copyright[] = " Copyright (c) 1999-2000 Intel Corporation\n";
- static char e1000id_string[128] = "Intel(R) PRO/1000 Gigabit Server Adapter";
- static char e1000_driver[] = "e1000";
- static char e1000_version[] = "2.5.11";
- static bd_config_t *e1000first = NULL;
- static int e1000boards = 0;
- static int e1000_rxfree_cnt = 0;
- /* Driver performance tuning variables */
- static uint_t e1000_pcimlt_override = 0;
- static uint_t e1000_pcimwi_enable = 1;
- static uint_t e1000_txint_delay = 128;
- #if 1
- static uint_t e1000_rxint_delay = 128; /* RTM turn on rcv intr coalescing? microseconds? */
- #else
- static uint_t e1000_rxint_delay = 0;
- #endif
- #if 1
- static int e1000_flow_ctrl = 0; /* RTM turn off flow control */
- #else
- static int e1000_flow_ctrl = 3;
- #endif
- static int e1000_rxpci_priority = 0;
- static uint_t e1000_maxdpc_count = 5;
- static int TxDescriptors[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
- static int RxDescriptors[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
- /* Feature enable/disable */
- static int Jumbo[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
- static int WaitForLink[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
- static int SBP[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- /* Speed and Duplex Settings */
- static int AutoNeg[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
- static int Speed[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
- static int ForceDuplex[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
- /* This parameter determines whether the driver sets the RS bit or the
- * RPS bit in a transmit packet. These are the possible values for this
- * parameter:
- * e1000_ReportTxEarly = 0 ==> set the RPS bit
- * = 1 ==> set the RS bit
- * = 2 ==> (default) let the driver auto-detect
- *
- * If the RS bit is set in a packet, an interrupts is generated as soon
- * as the packet is DMAed from host memory to the FIFO. If the RPS bit
- * is set, an interrupt is generated after the packet has been transmitted
- * on the wire.
- */
- static uchar_t e1000_ReportTxEarly = 2; /* let the driver auto-detect */
- /* these next ones are for Linux specific things */
- static int probed = 0;
- static int e1000_tx_queue(struct device *dev, struct sk_buff *skb);
- static int e1000_tx_start(struct device *dev);
- static int e1000_rx_refill(struct device *dev, struct sk_buff **);
- static int e1000_tx_eob(struct device *dev);
- static struct sk_buff *e1000_tx_clean(struct device *dev);
- static struct sk_buff *e1000_rx_poll(struct device *dev, int *want);
- static int e1000_poll_on(struct device *dev);
- static int e1000_poll_off(struct device *dev);
- /* The system interface routines */
- /****************************************************************************
- * Name: e1000_probe
- *
- * Description: This routine is called when the dynamic driver module
- * "e1000" is loaded using the command "insmod".
- *
- * This is a Linux required routine.
- *
- * Author: IntelCorporation
- *
- * Born on Date: 07/11/99
- *
- * Arguments:
- * NONE
- *
- * Returns:
- *
- * Modification log:
- * Date Who Description
- * -------- --- --------------------------------------------------------
- *
- ****************************************************************************/
- int
- e1000_probe()
- {
- device_t *dev;
- bd_config_t *bdp;
- PADAPTER_STRUCT Adapter;
- pci_dev_t *pcid = NULL;
- int num_boards = 0;
- int first_time = 0, loop_cnt = 0;
- if (e1000_debug_level >= 1)
- printk("e1000_probe()\n");
- /* Has the probe routine been called before? The driver can be probed only
- * once.
- */
- if (probed)
- return (0);
- else
- probed++;
- /* does the system support pci? */
- if ((!CONFIG_PCI) || (!pci_present()))
- return (0);
- #ifdef CONFIG_PROC_FS
- {
- int len;
- /* first check if e1000_proc_dir already exists */
- len = strlen(ADAPTERS_PROC_DIR);
- for (e1000_proc_dir=proc_net->subdir;e1000_proc_dir;
- e1000_proc_dir=e1000_proc_dir->next) {
- if ((e1000_proc_dir->namelen == len) &&
- (!memcmp(e1000_proc_dir->name, ADAPTERS_PROC_DIR, len)))
- break;
- }
- if (!e1000_proc_dir)
- e1000_proc_dir =
- create_proc_entry(ADAPTERS_PROC_DIR, S_IFDIR, proc_net);
- if (!e1000_proc_dir) return -ENODEV;
- }
- #endif
-
- /* loop through all of the ethernet PCI devices looking for ours */
- while ((pcid = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pcid))) {
- dev = NULL;
- if (e1000_debug_level >= 2)
- printk("e1000_probe: vendor = 0x%x, device = 0x%x \n",
- pcid->vendor, pcid->device);
-
- /* is the device ours? */
- if ((pcid->vendor != E1000_VENDOR_ID) ||
- !((pcid->device == WISEMAN_DEVICE_ID) ||
- (pcid->device == LIVENGOOD_FIBER_DEVICE_ID) ||
- (pcid->device == LIVENGOOD_COPPER_DEVICE_ID))) continue; /* No, continue */
- if (!first_time) {
- /* only display the version message one time */
- first_time = 1;
- /* print out the version */
- printk("%s", version);
- printk("%s\n", e1000_copyright);
- }
- /* register the net device, but don't allocate a private structure yet */
- dev = init_etherdev(dev, 0);
- if (dev == NULL) {
- printk(KERN_ERR "Not able to alloc etherdev struct\n");
- break;
- }
- /* Allocate all the memory that the driver will need */
- if (!(bdp = e1000_alloc_space())) {
- printk("%s - Failed to allocate memory\n", e1000_driver);
- e1000_dealloc_space(bdp);
- return 0;
- }
- bdp->device = dev;
- #ifdef CONFIG_PROC_FS
- if (e1000_create_proc_dev(bdp) < 0) {
- e1000_remove_proc_dev(dev);
- e1000_dealloc_space(bdp);
- continue; /*return e100nics;*/
- }
- #endif
- /* init the timer */
- bdp->timer_val = -1;
- /* point the Adapter to the bddp */
- Adapter = (PADAPTER_STRUCT) bdp->bddp;
- #ifdef IANS
- bdp->iANSdata = kmalloc(sizeof(iANSsupport_t), GFP_KERNEL);
- memset((PVOID) bdp->iANSdata, 0, sizeof(iANSsupport_t));
- bd_ans_drv_InitANS(bdp, bdp->iANSdata);
- #endif
- /*
- * Obtain the PCI specific information about the driver.
- */
- if (e1000_find_pci_device(pcid, Adapter) == 0) {
- printk("%s - Failed to find PCI device\n", e1000_driver);
- return (0);
- }
- /* range check the command line parameters for this board */
- if(!e1000_GetBrandingMesg(Adapter->DeviceId, Adapter->SubVendorId, Adapter->SubSystemId)) {
- continue;
- }
- printk("%s\n", e1000id_string);
- e1000_check_options(loop_cnt);
- switch (Speed[loop_cnt]) {
- case SPEED_10:
- switch(ForceDuplex[loop_cnt]) {
- case HALF_DUPLEX:
- Adapter->AutoNeg = 0;
- Adapter->ForcedSpeedDuplex = HALF_10;
- break;
- case FULL_DUPLEX:
- Adapter->AutoNeg = 0;
- Adapter->ForcedSpeedDuplex = FULL_10;
- break;
- default:
- Adapter->AutoNeg = 1;
- Adapter->AutoNegAdvertised =
- ADVERTISE_10_HALF | ADVERTISE_10_FULL;
- }
- break;
- case SPEED_100:
- switch(ForceDuplex[loop_cnt]) {
- case HALF_DUPLEX:
- Adapter->AutoNeg = 0;
- Adapter->ForcedSpeedDuplex = HALF_100;
- break;
- case FULL_DUPLEX:
- Adapter->AutoNeg = 0;
- Adapter->ForcedSpeedDuplex = FULL_100;
- break;
- default:
- Adapter->AutoNeg = 1;
- Adapter->AutoNegAdvertised =
- ADVERTISE_100_HALF | ADVERTISE_100_FULL;
- }
- break;
- case SPEED_1000:
- Adapter->AutoNeg = 1;
- Adapter->AutoNegAdvertised = ADVERTISE_1000_FULL;
- break;
- default:
- Adapter->AutoNeg = 1;
- switch(ForceDuplex[loop_cnt]) {
- case HALF_DUPLEX:
- Adapter->AutoNegAdvertised =
- ADVERTISE_10_HALF | ADVERTISE_100_HALF;
- break;
- case FULL_DUPLEX:
- Adapter->AutoNegAdvertised =
- ADVERTISE_10_FULL | ADVERTISE_100_FULL | ADVERTISE_1000_FULL;
- break;
- default:
- Adapter->AutoNegAdvertised = AutoNeg[loop_cnt];
- }
- }
- Adapter->WaitAutoNegComplete = WaitForLink[loop_cnt];
- /* Set Adapter->MacType */
- switch (pcid->device) {
- case WISEMAN_DEVICE_ID:
- if (Adapter->RevID == WISEMAN_2_0_REV_ID)
- Adapter->MacType = MAC_WISEMAN_2_0;
- else {
- if (Adapter->RevID == WISEMAN_2_1_REV_ID)
- Adapter->MacType = MAC_WISEMAN_2_1;
- else {
- Adapter->MacType = MAC_WISEMAN_2_0;
- printk(KERN_ERR
- "Could not identify hardware revision\n");
- }
- }
- break;
- case LIVENGOOD_FIBER_DEVICE_ID:
- case LIVENGOOD_COPPER_DEVICE_ID:
- Adapter->MacType = MAC_LIVENGOOD;
- break;
- default:
- Adapter->MacType = MAC_WISEMAN_2_0;
- printk(KERN_ERR "Could not identify hardware revision\n");
- break;
- }
- /* save off the needed information */
- bdp->device = dev;
- dev->priv = bdp;
- Adapter = bdp->bddp;
- /* save off the pci device structure pointer */
- Adapter->pci_dev = pcid;
- bdp->vendor = pcid->vendor;
- /* set the irq into the dev and bdp structures */
- dev->irq = pcid->irq;
- bdp->irq_level = pcid->irq;
- /* point to all of our entry point to let the system know where we are */
- dev->open = &e1000_open;
- dev->hard_start_xmit = &e1000_xmit_frame;
- dev->stop = &e1000_close;
- dev->get_stats = &e1000_get_stats;
- dev->set_multicast_list = &e1000_set_multi;
- dev->set_mac_address = &e1000_set_mac;
- dev->change_mtu = &e1000_change_mtu;
- #ifdef IANS
- dev->do_ioctl = &bd_ans_os_Ioctl;
- #endif
- /* set memory base addr */
- dev->base_addr = pci_resource_start(pcid, 0);
- #ifdef CLICK_POLLING
- /* Click - polling extensions */
- dev->polling = 0;
- dev->rx_poll = e1000_rx_poll;
- dev->rx_refill = e1000_rx_refill;
- dev->tx_eob = e1000_tx_eob;
- dev->tx_clean = e1000_tx_clean;
- dev->tx_queue = e1000_tx_queue;
- dev->tx_start = e1000_tx_start;
- dev->poll_off = e1000_poll_off;
- dev->poll_on = e1000_poll_on;
- #endif
- /* now map the phys addr into system space... */
- /*
- * Map the PCI memory base address to a virtual address that can be used
- * for access by the driver. The amount of memory to be mapped will be
- * the E1000 register area.
- */
- Adapter->HardwareVirtualAddress =
- (PE1000_REGISTERS) ioremap(pci_resource_start(pcid, 0),
- sizeof(E1000_REGISTERS));
- if (Adapter->HardwareVirtualAddress == NULL) {
- /*
- * If the hardware register space can not be allocated, the driver
- * must fail to load.
- */
- printk("e1000_probe ioremap failed\n");
- /* this is a problem, if the first one inits OK but a secondary one
- * fails, what should you return? Now it will say the load was OK
- * but one or more boards may have failed to come up
- */
- break;
- }
- bdp->mem_start = pci_resource_start(pcid, 0);
- if (e1000_debug_level >= 2)
- printk("memstart = 0x%p, virt_addr = 0x%p\n",
- (void *) bdp->mem_start,
- (void *) Adapter->HardwareVirtualAddress);
- e1000_init(bdp);
- /* Printout the board configuration */
- e1000_print_brd_conf(bdp);
- /* init the basic stats stuff */
- ClearHwStatsCounters(Adapter);
- /* Update the statistics needed by the upper */
- UpdateStatsCounters(bdp);
- /* up the loop count( it's also the number of our boards found) */
- loop_cnt++;
- if (e1000_debug_level >= 2) {
- printk("dev = 0x%p ", dev);
- printk(" priv = 0x%p\n", dev->priv);
- printk(" irq = 0x%x ", dev->irq);
- printk(" next = 0x%p ", dev->next);
- printk(" flags = 0x%x\n", dev->flags);
- printk(" bdp = 0x%p\n", bdp);
- printk(" irq_level = 0x%x\n", bdp->irq_level);
- }
- } /* end of pci_find_class while loop */
- e1000boards = num_boards = loop_cnt;
- if (num_boards)
- return (0);
- else
- return (-ENODEV);
- }
- /* register e1000_probe as our initilization routine */
- module_init(e1000_probe);
- /* set some of the modules specific things here */
- #ifdef MODULE
- MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
- MODULE_DESCRIPTION("Intel(R) PRO/1000 Gigabit Ethernet driver");
- MODULE_PARM(TxDescriptors, "1-8i");
- MODULE_PARM(RxDescriptors, "1-8i");
- MODULE_PARM(Jumbo, "1-8i");
- MODULE_PARM(WaitForLink, "1-8i");
- MODULE_PARM(AutoNeg, "1-8i");
- MODULE_PARM(Speed, "1-8i");
- MODULE_PARM(ForceDuplex, "1-8i");
- MODULE_PARM(SBP, "1-8i");
- #endif
- /****************************************************************************
- * Name: cleanup_module
- *
- * Description: This routine is an entry point into the driver.
- *
- * This is a Linux required routine.
- *
- * Author: IntelCorporation
- *
- * Born on Date: 07/11/99
- *
- * Arguments:
- * NONE
- *
- * Returns:
- * It returns 0 and can not fail
- *
- * Modification log:
- * Date Who Description
- * -------- --- --------------------------------------------------------
- *
- ****************************************************************************/
- int
- cleanup_module(void)
- {
- bd_config_t *bdp, *next_bdp;
- PADAPTER_STRUCT Adapter;
- device_t *dev, *next_dev;
- /* start looking at the first device */
- if (e1000first)
- dev = e1000first->device;
- else
- return 0;
- if (e1000_debug_level >= 1)
- printk("cleanup_module: SOR, dev = 0x%p \n\n\n", dev);
- while (dev) {
- #ifdef CONFIG_PROC_FS
- e1000_remove_proc_dev(dev);
- #endif
- bdp = (bd_config_t *) dev->priv;
- next_bdp = bdp->bd_next;
- if (next_bdp)
- next_dev = next_bdp->device;
- else
- next_dev = NULL;
- Adapter = bdp->bddp;
- /* unregister this instance of the module */
- if (e1000_debug_level >= 2)
- printk("--Cleanup, unreg_netdev\n");
- unregister_netdev(dev);
- /*
- * Free the memory mapped area that is allocated to the E1000 hardware
- * registers
- */
- if (e1000_debug_level >= 2)
- printk("--Cleanup, iounmap\n");
- iounmap(Adapter->HardwareVirtualAddress);
- /* free the irq back to the system */
- #ifdef IANS
- kfree(bdp->iANSdata);
- #endif
- /* free up any memory here */
- if (e1000_debug_level >= 2)
- printk("--Cleanup, e1000_dealloc_space\n");
- e1000_dealloc_space(bdp);
- dev = next_dev;
- }
- #ifdef CONFIG_PROC_FS
- {
- struct proc_dir_entry *de;
- /* check if the subdir list is empty before removing e1000_proc_dir */
- for (de = e1000_proc_dir->subdir; de; de = de->next) {
- /* ignore . and .. */
- if (*(de->name) == '.') continue;
- break;
- }
- if (de) return 0;
- remove_proc_entry(ADAPTERS_PROC_DIR, proc_net);
- }
- #endif
-
- return (0);
- }
- /****************************************************************************
- * Name: e1000_check_options
- *
- * Description: This routine does range checking on command line options.
- *
- * Author: IntelCorporation
- *
- * Born on Date: 03/28/2000
- *
- * Arguments:
- * int board - board number to check values for
- *
- * Returns:
- * None
- *
- ****************************************************************************/
- static void
- e1000_check_options(int board)
- {
- /* Transmit Descriptor Count */
- if (TxDescriptors[board] == -1) {
- TxDescriptors[board] = MAX_TCB;
- } else if ((TxDescriptors[board] > E1000_MAX_TXD) ||
- (TxDescriptors[board] < E1000_MIN_TXD)) {
- printk("Invalid TxDescriptor count specified (%i),"
- " using default of %i\n", TxDescriptors[board], MAX_TCB);
- TxDescriptors[board] = MAX_TCB;
- } else {
- printk("Using specified value of %i TxDescriptors\n",
- TxDescriptors[board]);
- }
- /* Receive Descriptor Count */
- if (RxDescriptors[board] == -1) {
- RxDescriptors[board] = MAX_RFD;
- } else if ((RxDescriptors[board] > E1000_MAX_RXD) ||
- (RxDescriptors[board] < E1000_MIN_RXD)) {
- printk("Invalid RxDescriptor count specified (%i),"
- " using default of %i\n", RxDescriptors[board], MAX_RFD);
- RxDescriptors[board] = MAX_RFD;
- } else {
- printk("Using specified value of %i RxDescriptors\n",
- RxDescriptors[board]);
- }
- /* Jumbo Frame Enable */
- if (Jumbo[board] == -1) {
- Jumbo[board] = 1;
- } else if ((Jumbo[board] > 1) || (Jumbo[board] < 0)) {
- printk("Invalid Jumbo specified (%i), using default of %i\n",
- Jumbo[board], 1);
- Jumbo[board] = 1;
- } else {
- printk("Jumbo Frames %s\n",
- Jumbo[board] == 1 ? "Enabled" : "Disabled");
- }
- /* Wait for link at driver load */
- if (WaitForLink[board] == -1) {
- WaitForLink[board] = 1;
- } else if ((WaitForLink[board] > 1) || (WaitForLink[board] < 0)) {
- printk("Invalid WaitForLink specified (%i), using default of %i\n",
- WaitForLink[board], 1);
- WaitForLink[board] = 1;
- } else {
- printk("WaitForLink %s\n",
- WaitForLink[board] == 1 ? "Enabled" : "Disabled");
- }
- /* Forced Speed and Duplex */
- switch (Speed[board]) {
- case -1:
- Speed[board] = 0;
- switch (ForceDuplex[board]) {
- case -1:
- ForceDuplex[board] = 0;
- break;
- case 0:
- printk("Speed and Duplex Autonegotiation Enabled\n");
- break;
- case 1:
- printk("Warning: Half Duplex specified without Speed\n");
- printk("Using Autonegotiation at Half Duplex only\n");
- break;
- case 2:
- printk("Warning: Full Duplex specified without Speed\n");
- printk("Using Autonegotiation at Full Duplex only\n");
- break;
- default:
- printk("Invalid Duplex Specified (%i), Parameter Ignored\n",
- ForceDuplex[board]);
- ForceDuplex[board] = 0;
- printk("Speed and Duplex Autonegotiation Enabled\n");
- }
- break;
- case 0:
- switch (ForceDuplex[board]) {
- case -1:
- case 0:
- printk("Speed and Duplex Autonegotiation Enabled\n");
- ForceDuplex[board] = 0;
- break;
- case 1:
- printk("Warning: Half Duplex specified without Speed\n");
- printk("Using Autonegotiation at Half Duplex only\n");
- break;
- case 2:
- printk("Warning: Full Duplex specified without Speed\n");
- printk("Using Autonegotiation at Full Duplex only\n");
- break;
- default:
- printk("Invalid Duplex Specified (%i), Parameter Ignored\n",
- ForceDuplex[board]);
- ForceDuplex[board] = 0;
- printk("Speed and Duplex Autonegotiation Enabled\n");
- }
- break;
- case 10:
- case 100:
- switch (ForceDuplex[board]) {
- case -1:
- case 0:
- printk("Warning: %i Mbps Speed specified without Duplex\n",
- Speed[board]);
- printk("Using Autonegotiation at %i Mbps only\n", Speed[board]);
- ForceDuplex[board] = 0;
- break;
- case 1:
- printk("Forcing to %i Mbps Half Duplex\n", Speed[board]);
- break;
- case 2:
- printk("Forcing to %i Mbps Full Duplex\n", Speed[board]);
- break;
- default:
- printk("Invalid Duplex Specified (%i), Parameter Ignored\n",
- ForceDuplex[board]);
- ForceDuplex[board] = 0;
- printk("Warning: %i Mbps Speed specified without Duplex\n",
- Speed[board]);
- printk("Using Autonegotiation at %i Mbps only\n", Speed[board]);
- }
- break;
- case 1000:
- switch (ForceDuplex[board]) {
- case -1:
- case 0:
- printk("Warning: 1000 Mbps Speed specified without Duplex\n");
- printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n");
- ForceDuplex[board] = 0;
- break;
- case 1:
- printk("Warning: Half Duplex is not supported at 1000 Mbps\n");
- printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n");
- break;
- case 2:
- printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n");
- break;
- default:
- printk("Invalid Duplex Specified (%i), Parameter Ignored\n",
- ForceDuplex[board]);
- ForceDuplex[board] = 0;
- printk("Warning: 1000 Mbps Speed specified without Duplex\n");
- printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n");
- }
- break;
- default:
- printk("Invalid Speed Specified (%i), Parameter Ignored\n",
- Speed[board]);
- Speed[board] = 0;
- switch (ForceDuplex[board]) {
- case -1:
- case 0:
- printk("Speed and Duplex Autonegotiation Enabled\n");
- ForceDuplex[board] = 0;
- break;
- case 1:
- printk("Warning: Half Duplex specified without Speed\n");
- printk("Using Autonegotiation at Half Duplex only\n");
- break;
- case 2:
- printk("Warning: Full Duplex specified without Speed\n");
- printk("Using Autonegotiation at Full Duplex only\n");
- break;
- default:
- printk("Invalid Duplex Specified (%i), Parameter Ignored\n",
- ForceDuplex[board]);
- ForceDuplex[board] = 0;
- printk("Speed and Duplex Autonegotiation Enabled\n");
- }
- }
- if (AutoNeg[board] == -1) {
- AutoNeg[board] = 0x2F;
- } else {
- if (AutoNeg[board] & ~0x2F) {
- printk("Invalid AutoNeg Specified (0x%X)\n", AutoNeg[board]);
- AutoNeg[board] = 0x2F;
- }
- printk("AutoNeg Advertising ");
- if(AutoNeg[board] & 0x20) {
- printk("1000/FD");
- if(AutoNeg[board] & 0x0F)
- printk(", ");
- }
- if(AutoNeg[board] & 0x08) {
- printk("100/FD");
- if(AutoNeg[board] & 0x07)
- printk(", ");
- }
- if(AutoNeg[board] & 0x04) {
- printk("100/HD");
- if(AutoNeg[board] & 0x03)
- printk(", ");
- }
- if(AutoNeg[board] & 0x02) {
- printk("10/FD");
- if(AutoNeg[board] & 0x01)
- printk(", ");
- }
- if(AutoNeg[board] & 0x01)
- printk("10/HD");
- printk("\n");
- }
- }
- /****************************************************************************
- * Name: e1000_open
- *
- * Description: This routine is the open call for the interface.
- *
- * This is a Linux required routine.
- *
- * Author: IntelCorporation
- *
- * Born on Date: 07/11/99
- *
- * Arguments:
- * NONE
- *
- * Returns:
- * It returns 0 on success
- * -EAGAIN on failure
- *
- * Modification log:
- * Date Who Description
- * -------- --- --------------------------------------------------------
- *
- ****************************************************************************/
- static int
- e1000_open(device_t * dev)
- {
- bd_config_t *bdp;
- PADAPTER_STRUCT Adapter = 0;
- int ret_val;
- printk("v0 e1000 Alignment: %p %p\n",
- &(Adapter->FirstTxDescriptor), &(Adapter->NumRxDescriptors));
- bdp = dev->priv;
- Adapter = bdp->bddp;
- if (e1000_debug_level >= 1)
- printk("open: SOR, bdp = 0x%p\n", bdp);
- /* make sure we have not already opened this interface */
- if(bdp->flags & BOARD_OPEN)
- return -EBUSY;
-
- if (e1000_init(bdp)) {
- return -ENOMEM;
- }
- if (e1000_runtime_init(bdp)) {
- return -ENOMEM;
- }
- Adapter->AdapterStopped = FALSE;
-
- #ifdef IANS_BASE_VLAN_TAGGING
- /* on a close a global reset is issued to the hardware,
- * so VLAN settings are lost and need to be re-set on open */
- if((IANS_BD_TAGGING_MODE)ANS_PRIVATE_DATA_FIELD(bdp)->tag_mode != IANS_BD_TAGGING_NONE)
- bd_ans_hw_EnableVLAN(bdp);
- #endif
-
- if (request_irq(dev->irq, &e1000_intr, SA_SHIRQ, "e1000", dev)) {
- if (e1000_debug_level >= 1)
- printk("open: request_irq failed");
- return (-EAGAIN);
- }
- /* Check to see if promiscuous mode needs to be turned on */
- if (dev->flags & IFF_PROMISC) {
- /* turn promisc mode on */
- ret_val = e1000_set_promisc(bdp, B_TRUE);
- bdp->flags |= PROMISCUOUS;
- } else {
- /* turn promisc mode off */
- ret_val = e1000_set_promisc(bdp, B_FALSE);
- bdp->flags &= ~PROMISCUOUS;
- }
- #ifdef MODULE
- /* up the mod use count used by the system */
- MOD_INC_USE_COUNT;
- #endif
- /* setup and start the watchdog timer */
- init_timer(&bdp->timer_id);
- /* set the timer value for 2 sec( i.e. 200 10msec tics )
- * jiffies are mesured in tics and is equiv. to LBOLTS in Unix
- */
- bdp->timer_id.expires = bdp->timer_val = jiffies + 200;
- bdp->timer_id.data = (ulong_t) dev;
- bdp->timer_id.function = (void *) &e1000_watchdog;
- /* start the timer */
- add_timer(&bdp->timer_id);
- /* set the device flags */
- netif_start_queue(dev);
- /* enable interrupts */
- e1000EnableInterrupt(Adapter);
- /* init the basic stats stuff */
- ClearHwStatsCounters(Adapter);
- bdp->flags |= BOARD_OPEN;
- return (0);
- }
- /****************************************************************************
- * Name: e1000_close
- *
- * Description: This routine is an entry point into the driver.
- *
- * This is a Linux required routine.
- *
- * Author: IntelCorporation
- *
- * Born on Date: 07/11/99
- *
- * Arguments:
- * device_t pointer
- *
- * Returns:
- * It returns 0 and can not fail.
- *
- * Modification log:
- * Date Who Description
- * -------- --- --------------------------------------------------------
- *
- ****************************************************************************/
- static int
- e1000_close(device_t * dev)
- {
- bd_config_t *bdp;
- PADAPTER_STRUCT Adapter;
- ushort_t status;
- int j;
- bdp = dev->priv;
- Adapter = bdp->bddp;
- /* set the device to not started */
- netif_stop_queue(dev);
- /* stop the hardware */
- /* Disable all possible interrupts */
- E1000_WRITE_REG(Imc, (0xffffffff));
- status = E1000_READ_REG(Icr);
- /* Reset the chip */
- AdapterStop(Adapter);
- /* kill the timer */
- del_timer(&bdp->timer_id);
- /* free the irq back to the system */
- if (e1000_debug_level >= 1)
- printk("E1000: close: free_irq\n");
- free_irq(dev->irq, dev);
- /*
- * Free up the transmit descriptor area
- */
- if (e1000_debug_level >= 2)
- printk("--Cleanup, free tx descriptor area\n");
- free_contig(bdp->base_tx_tbds);
- bdp->base_tx_tbds = NULL;
- if(Adapter->TxSkBuffs)
- free_contig(Adapter->TxSkBuffs);
- /*
- * Free up the RX_SW_PACKET area also free any allocated
- * receive buffers
- */
- if (e1000_debug_level >= 2)
- printk("--Cleanup, free rx packet area + skbuffs\n");
- if(Adapter->RxSkBuffs){
- for (j = 0; j < Adapter->NumRxDescriptors; j++) {
- if (Adapter->RxSkBuffs[j]){
- if (e1000_debug_level >= 2)
- printk(" -- kfree_skb\n");
- dev_kfree_skb(Adapter->RxSkBuffs[j]);
- Adapter->RxSkBuffs[j] = 0;
- }
- }
- free_contig(Adapter->RxSkBuffs);
- }
- /*
- * Free the receive descriptor area
- */
- if (e1000_debug_level >= 2)
- printk("--Cleanup, free rx descriptor area\n");
- /* free_contig( Adapter->e1000_rbd_data ); */
- free_contig(bdp->base_rx_rbds);
- bdp->base_rx_rbds = NULL;
-
- bdp->flags &= ~BOARD_OPEN;
- #ifdef MODULE
- /* adjust the mod use count */
- MOD_DEC_USE_COUNT;
- #endif
- return (0);
- }
- /*
- * the send a packet, may poke at e1000 to force it to start tx
- */
-
- static int
- e1000_xmit_frame_aux(struct sk_buff *skb, device_t * dev, int poke)
- {
- bd_config_t *bdp;
- PADAPTER_STRUCT Adapter;
- int lock_flag;
- int ret;
- bdp = dev->priv;
- Adapter = (PADAPTER_STRUCT) bdp->bddp;
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- return 1;
- }
- if (e1000_debug_level >= 3)
- printk("e1000_tx_frame\n");
- /* call the transmit routine */
- #ifdef CLICK_POLLING
- if(SendBuffer(skb, bdp, poke, dev->polling)){
- #else
- if(SendBuffer(skb, bdp, poke, 0)){
- #endif
- ret = 0;
- } else {
- #ifdef IANS
- if(bdp->iANSdata->iANS_status == IANS_COMMUNICATION_UP) {
- ans_notify(dev, IANS_IND_XMIT_QUEUE_FULL);
- }
- #endif
- ret = 1;
- }
- if(bdp->tx_out_res == 0)
- clear_bit(0, (void*)&dev->tbusy);
- return (ret);
- }
- /****************************************************************************
- * Name: e1000_xmit_frame
- *
- * Description: This routine is called to transmit a frame.
- *
- *
- * Author: IntelCorporation
- *
- * Born on Date: 07/11/99
- *
- * Arguments:
- * sb_buff pointer
- * device_t pointer
- *
- * Returns:
- * It returns B_FALSE on success
- * B_TRUE on failure
- *
- * Modification log:
- * Date Who Description
- * -------- --- --------------------------------------------------------
- *
- ****************************************************************************/
- static int
- e1000_xmit_frame(struct sk_buff *skb, device_t * dev)
- {
- return e1000_xmit_frame_aux(skb, dev, 1);
- }
- /****************************************************************************
- * Name: SendBuffer
- *
- * Description: This routine physically sends the packet to the nic controller.
- *
- *
- * Author: IntelCorporation
- *
- * Born on Date: 07/11/99
- *
- * Arguments:
- * TX_SW_PACKET pointer
- * bd_config_t pointer
- *
- * Returns:
- * It returns B_TRUE always and can not fail.
- *
- * Modification log:
- * Date Who Description
- * -------- --- --------------------------------------------------------
- *
- ****************************************************************************/
- static UINT
- SendBuffer(struct sk_buff *skb, bd_config_t * bdp, int poke, int polling)
- {
- PADAPTER_STRUCT Adapter;
- PE1000_TRANSMIT_DESCRIPTOR CurrentTxDescriptor, nxt;
- // net_device_stats_t *stats;
- int di;
- Adapter = bdp->bddp;
- // stats = &bdp->net_stats;
- CurrentTxDescriptor = Adapter->NextAvailTxDescriptor;
- /* Don't use the last descriptor! */
- if (CurrentTxDescriptor == Adapter->LastTxDescriptor)
- nxt = Adapter->FirstTxDescriptor;
- else
- nxt = CurrentTxDescriptor + 1;
- if(nxt == Adapter->OldestUsedTxDescriptor){
- printk("e1000: out of descs in Sendbuffer\n");
- return(0);
- }
- di = CurrentTxDescriptor - Adapter->FirstTxDescriptor;
- if(Adapter->TxSkBuffs[di])
- printk("e1000 oops di %d TxSkBuffs[di] %x\n",
- di,
- (di >= 0 && di < 80) ? Adapter->TxSkBuffs[di] : 0);
- Adapter->TxSkBuffs[di] = skb;
- CurrentTxDescriptor->BufferAddress = virt_to_bus(skb->data);
-
- CurrentTxDescriptor->Lower.DwordData = skb->len;
- /* zero out the status field in the descriptor. */
- CurrentTxDescriptor->Upper.DwordData = 0;
- #ifdef IANS
- if(bdp->iANSdata->iANS_status == IANS_COMMUNICATION_UP) {
- if(bd_ans_os_Transmit(bdp, CurrentTxDescriptor, &skb)==BD_ANS_FAILURE) {
- dev_kfree_skb(skb);
- return B_FALSE;
- }
- }
- #endif
- Adapter->NextAvailTxDescriptor = nxt;
- CurrentTxDescriptor->Lower.DwordData |=
- (E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS);
- #if 1
- /*
- * If there is a valid value for the transmit interrupt delay, set up the
- * delay in the descriptor field
- */
- if (Adapter->TxIntDelay)
- CurrentTxDescriptor->Lower.DwordData |= E1000_TXD_CMD_IDE;
- #else
- /*
- * Ask for a transmit complete interrupt every 60 packets. RTM
- * This seems to be broken -- sometimes the tx complete
- * interrupts never happen -- sending waits until a receive
- * packet arrives. RTM Dec 22 2000.
- */
- if(polling==0 && Adapter->TxIntDelay){
- static int dctr;
- if(dctr++ > 60){
- dctr = 0;
- /* Don't delay for this packet! */
- } else {
- /* Delay tx complete interrupt for most packets. */
- CurrentTxDescriptor->Lower.DwordData |= E1000_TXD_CMD_IDE;
- }
- }
- #endif
- /* Set the RS or the RPS bit by looking at the ReportTxEarly setting */
- if (Adapter->ReportTxEarly == 1)
- CurrentTxDescriptor->Lower.DwordData |= E1000_TXD_CMD_RS;
- else
- CurrentTxDescriptor->Lower.DwordData |= E1000_TXD_CMD_RPS;
- if (poke)
- /* Advance the Transmit Descriptor Tail (Tdt), this tells the
- * E1000 that this frame is available to transmit.
- */
- E1000_WRITE_REG(Tdt, (((unsigned long) Adapter->NextAvailTxDescriptor -
- (unsigned long) Adapter->FirstTxDescriptor) >> 4));
- /* Could we queue another packet? */
- if (Adapter->NextAvailTxDescriptor == Adapter->LastTxDescriptor)
- nxt = Adapter->FirstTxDescriptor;
- else
- nxt = Adapter->NextAvailTxDescriptor + 1;
- if(nxt == Adapter->OldestUsedTxDescriptor)
- bdp->tx_out_res = 1;
- return(1);
- }
- /****************************************************************************
- * Name: e1000_get_stats
- *
- * Description: This routine is called when the OS wants the nic stats returned
- *
- * 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 int
- e1000_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 int
- e1000_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 int
- e1000_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 int
- e1000_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.
- ************************************…
Large files files are truncated, but you can click here to view the full file