if_em.c revision 118314
150128Swpaul/**************************************************************************
250128Swpaul
350128SwpaulCopyright (c) 2001-2003, Intel Corporation
450128SwpaulAll rights reserved.
550128Swpaul
650128SwpaulRedistribution and use in source and binary forms, with or without
750128Swpaulmodification, are permitted provided that the following conditions are met:
850128Swpaul
950128Swpaul 1. Redistributions of source code must retain the above copyright notice,
1050128Swpaul    this list of conditions and the following disclaimer.
1150128Swpaul
1250128Swpaul 2. Redistributions in binary form must reproduce the above copyright
1350128Swpaul    notice, this list of conditions and the following disclaimer in the
1450128Swpaul    documentation and/or other materials provided with the distribution.
1550128Swpaul
1650128Swpaul 3. Neither the name of the Intel Corporation nor the names of its
1750128Swpaul    contributors may be used to endorse or promote products derived from
1850128Swpaul    this software without specific prior written permission.
1950128Swpaul
2050128SwpaulTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2150128SwpaulAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2250128SwpaulIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2350128SwpaulARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2450128SwpaulLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2550128SwpaulCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2650128SwpaulSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2750128SwpaulINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2850128SwpaulCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2950128SwpaulARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3050128SwpaulPOSSIBILITY OF SUCH DAMAGE.
3150128Swpaul
3250477Speter***************************************************************************/
3350128Swpaul
3450128Swpaul/*$FreeBSD: head/sys/dev/em/if_em.c 118314 2003-08-01 17:33:59Z jdp $*/
3550128Swpaul
3650128Swpaul#include <dev/em/if_em.h>
3750128Swpaul
3850128Swpaul/*********************************************************************
3950128Swpaul *  Set this to one to display debug statistics
4050128Swpaul *********************************************************************/
4150128Swpaulint             em_display_debug_stats = 0;
4250128Swpaul
4350128Swpaul/*********************************************************************
4450128Swpaul *  Linked list of board private structures for all NICs found
4550128Swpaul *********************************************************************/
4650128Swpaul
4750128Swpaulstruct adapter *em_adapter_list = NULL;
48101493Sambrisko
4950128Swpaul
5050128Swpaul/*********************************************************************
5150128Swpaul *  Driver version
5250128Swpaul *********************************************************************/
5350128Swpaul
5450128Swpaulchar em_driver_version[] = "1.6.6";
5550128Swpaul
5650128Swpaul
5750128Swpaul/*********************************************************************
5850128Swpaul *  PCI Device ID Table
5950128Swpaul *
6050128Swpaul *  Used by probe to select devices to load on
6150128Swpaul *  Last field stores an index into em_strings
6250128Swpaul *  Last entry must be all 0s
6350128Swpaul *
6450128Swpaul *  { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
6550128Swpaul *********************************************************************/
6650128Swpaul
6751089Speterstatic em_vendor_info_t em_vendor_info_array[] =
6850128Swpaul{
6950128Swpaul        /* Intel(R) PRO/1000 Network Connection */
7050128Swpaul        { 0x8086, 0x1000, PCI_ANY_ID, PCI_ANY_ID, 0},
7150128Swpaul        { 0x8086, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0},
7250128Swpaul        { 0x8086, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0},
7350128Swpaul        { 0x8086, 0x1008, PCI_ANY_ID, PCI_ANY_ID, 0},
7459758Speter        { 0x8086, 0x1009, PCI_ANY_ID, PCI_ANY_ID, 0},
7559758Speter        { 0x8086, 0x100C, PCI_ANY_ID, PCI_ANY_ID, 0},
7650128Swpaul        { 0x8086, 0x100D, PCI_ANY_ID, PCI_ANY_ID, 0},
7750128Swpaul        { 0x8086, 0x100E, PCI_ANY_ID, PCI_ANY_ID, 0},
7850477Speter        { 0x8086, 0x100F, PCI_ANY_ID, PCI_ANY_ID, 0},
7950128Swpaul        { 0x8086, 0x1010, PCI_ANY_ID, PCI_ANY_ID, 0},
8050128Swpaul        { 0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0},
8150128Swpaul        { 0x8086, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0},
8250128Swpaul        { 0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0},
8350128Swpaul        { 0x8086, 0x1014, PCI_ANY_ID, PCI_ANY_ID, 0},
8450128Swpaul        { 0x8086, 0x1015, PCI_ANY_ID, PCI_ANY_ID, 0},
8550128Swpaul        { 0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0},
8650128Swpaul        { 0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0},
8750128Swpaul        { 0x8086, 0x1018, PCI_ANY_ID, PCI_ANY_ID, 0},
8850128Swpaul        { 0x8086, 0x1019, PCI_ANY_ID, PCI_ANY_ID, 0},
8950128Swpaul        { 0x8086, 0x101A, PCI_ANY_ID, PCI_ANY_ID, 0},
9092739Salfred	{ 0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0},
9192739Salfred	{ 0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0},
9292739Salfred        /* required last entry */
9392739Salfred        { 0, 0, 0, 0, 0}
9492739Salfred};
9592739Salfred
9692739Salfred/*********************************************************************
9792739Salfred *  Table of branding strings for all supported NICs.
9892739Salfred *********************************************************************/
9992739Salfred
10092739Salfredstatic char *em_strings[] = {
10192739Salfred	"Intel(R) PRO/1000 Network Connection"
10292739Salfred};
10392739Salfred
10492739Salfred/*********************************************************************
10592739Salfred *  Function prototypes
10692739Salfred *********************************************************************/
10792739Salfredstatic int  em_probe(device_t);
10850128Swpaulstatic int  em_attach(device_t);
10992739Salfredstatic int  em_detach(device_t);
11092739Salfredstatic int  em_shutdown(device_t);
11192739Salfredstatic void em_intr(void *);
11250128Swpaulstatic void em_start(struct ifnet *);
11392739Salfredstatic int  em_ioctl(struct ifnet *, u_long, caddr_t);
11492739Salfredstatic void em_watchdog(struct ifnet *);
11592739Salfredstatic void em_init(void *);
11692739Salfredstatic void em_stop(void *);
11792739Salfredstatic void em_media_status(struct ifnet *, struct ifmediareq *);
11892739Salfredstatic int  em_media_change(struct ifnet *);
11992739Salfredstatic void em_identify_hardware(struct adapter *);
12050128Swpaulstatic int  em_allocate_pci_resources(struct adapter *);
12192739Salfredstatic void em_free_pci_resources(struct adapter *);
12292739Salfredstatic void em_local_timer(void *);
12392739Salfredstatic int  em_hardware_init(struct adapter *);
12492739Salfredstatic void em_setup_interface(device_t, struct adapter *);
12592739Salfredstatic int  em_setup_transmit_structures(struct adapter *);
12692739Salfredstatic void em_initialize_transmit_unit(struct adapter *);
12792739Salfredstatic int  em_setup_receive_structures(struct adapter *);
12850128Swpaulstatic void em_initialize_receive_unit(struct adapter *);
12950128Swpaulstatic void em_enable_intr(struct adapter *);
13050128Swpaulstatic void em_disable_intr(struct adapter *);
13150128Swpaulstatic void em_free_transmit_structures(struct adapter *);
13250128Swpaulstatic void em_free_receive_structures(struct adapter *);
13350128Swpaulstatic void em_update_stats_counters(struct adapter *);
13450128Swpaulstatic void em_clean_transmit_interrupts(struct adapter *);
13550128Swpaulstatic int  em_allocate_receive_structures(struct adapter *);
13650128Swpaulstatic int  em_allocate_transmit_structures(struct adapter *);
13750128Swpaulstatic void em_process_receive_interrupts(struct adapter *, int);
13850128Swpaulstatic void em_receive_checksum(struct adapter *,
13950128Swpaul				struct em_rx_desc *,
14050128Swpaul				struct mbuf *);
14150128Swpaulstatic void em_transmit_checksum_setup(struct adapter *,
14250128Swpaul				       struct mbuf *,
14350128Swpaul				       u_int32_t *,
14450128Swpaul				       u_int32_t *);
14550128Swpaulstatic void em_set_promisc(struct adapter *);
14650128Swpaulstatic void em_disable_promisc(struct adapter *);
14750128Swpaulstatic void em_set_multi(struct adapter *);
14850128Swpaulstatic void em_print_hw_stats(struct adapter *);
14950128Swpaulstatic void em_print_link_status(struct adapter *);
15050128Swpaulstatic int  em_get_buf(int i, struct adapter *,
15150128Swpaul		       struct mbuf *);
15250128Swpaulstatic void em_enable_vlans(struct adapter *);
15350128Swpaulstatic int  em_encap(struct adapter *, struct mbuf *);
15450128Swpaulstatic void em_smartspeed(struct adapter *);
15550128Swpaulstatic int  em_82547_fifo_workaround(struct adapter *, int);
15650128Swpaulstatic void em_82547_update_fifo_head(struct adapter *, int);
15751455Swpaulstatic int  em_82547_tx_fifo_reset(struct adapter *);
15850128Swpaulstatic void em_82547_move_tail(void *arg);
15950128Swpaulstatic int  em_dma_malloc(struct adapter *, bus_size_t,
16050128Swpaul			  struct em_dma_alloc *, int);
16150128Swpaulstatic void em_dma_free(struct adapter *, struct em_dma_alloc *);
16250128Swpaulstatic void em_print_debug_info(struct adapter *);
16350128Swpaulstatic int  em_is_valid_ether_addr(u_int8_t *);
16451533Swpaulstatic int  em_sysctl_stats(SYSCTL_HANDLER_ARGS);
16551473Swpaulstatic int  em_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
16650128Swpaulstatic int  em_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
16750128Swpaulstatic void em_add_int_delay_sysctl(struct adapter *, const char *,
16850128Swpaul				    const char *, struct em_int_delay_info *,
16950128Swpaul				    int, int);
17050128Swpaul
17150128Swpaul/*********************************************************************
17250128Swpaul *  FreeBSD Device Interface Entry Points
17350128Swpaul *********************************************************************/
17450128Swpaul
17550128Swpaulstatic device_method_t em_methods[] = {
17650128Swpaul	/* Device interface */
17750128Swpaul	DEVMETHOD(device_probe, em_probe),
17850128Swpaul	DEVMETHOD(device_attach, em_attach),
17950128Swpaul	DEVMETHOD(device_detach, em_detach),
18050128Swpaul	DEVMETHOD(device_shutdown, em_shutdown),
18150128Swpaul	{0, 0}
18250128Swpaul};
18350128Swpaul
18450128Swpaulstatic driver_t em_driver = {
18550128Swpaul	"em", em_methods, sizeof(struct adapter ),
18650128Swpaul};
18750128Swpaul
18850128Swpaulstatic devclass_t em_devclass;
18950128SwpaulDRIVER_MODULE(em, pci, em_driver, em_devclass, 0, 0);
19050128SwpaulMODULE_DEPEND(em, pci, 1, 1, 1);
19150128SwpaulMODULE_DEPEND(em, ether, 1, 1, 1);
19250128Swpaul
19350128Swpaul/*********************************************************************
19450128Swpaul *  Tunable default values.
19550128Swpaul *********************************************************************/
19650128Swpaul
19750128Swpaul#define E1000_TICKS_TO_USECS(ticks)	((1024 * (ticks) + 500) / 1000)
19850128Swpaul#define E1000_USECS_TO_TICKS(usecs)	((1000 * (usecs) + 512) / 1024)
19950128Swpaul
20050128Swpaulstatic int em_tx_int_delay_dflt = E1000_TICKS_TO_USECS(EM_TIDV);
20150128Swpaulstatic int em_rx_int_delay_dflt = E1000_TICKS_TO_USECS(EM_RDTR);
20250128Swpaulstatic int em_tx_abs_int_delay_dflt = E1000_TICKS_TO_USECS(EM_TADV);
20350128Swpaulstatic int em_rx_abs_int_delay_dflt = E1000_TICKS_TO_USECS(EM_RADV);
20450128Swpaul
20550128SwpaulTUNABLE_INT("hw.em.tx_int_delay", &em_tx_int_delay_dflt);
20650128SwpaulTUNABLE_INT("hw.em.rx_int_delay", &em_rx_int_delay_dflt);
20750128SwpaulTUNABLE_INT("hw.em.tx_abs_int_delay", &em_tx_abs_int_delay_dflt);
20850128SwpaulTUNABLE_INT("hw.em.rx_abs_int_delay", &em_rx_abs_int_delay_dflt);
20950128Swpaul
21050128Swpaul/*********************************************************************
21150128Swpaul *  Device identification routine
21250128Swpaul *
21350128Swpaul *  em_probe determines if the driver should be loaded on
21450128Swpaul *  adapter based on PCI vendor/device id of the adapter.
21550128Swpaul *
21650128Swpaul *  return 0 on success, positive on failure
21750128Swpaul *********************************************************************/
21850128Swpaul
21950128Swpaulstatic int
22050128Swpaulem_probe(device_t dev)
22150128Swpaul{
22250128Swpaul	em_vendor_info_t *ent;
22350128Swpaul
22450128Swpaul	u_int16_t       pci_vendor_id = 0;
22550128Swpaul	u_int16_t       pci_device_id = 0;
22650128Swpaul	u_int16_t       pci_subvendor_id = 0;
22750128Swpaul	u_int16_t       pci_subdevice_id = 0;
22850128Swpaul	char            adapter_name[60];
22950128Swpaul
23050128Swpaul	INIT_DEBUGOUT("em_probe: begin");
23150128Swpaul
23250128Swpaul	pci_vendor_id = pci_get_vendor(dev);
23350128Swpaul	if (pci_vendor_id != EM_VENDOR_ID)
23450128Swpaul		return(ENXIO);
23550128Swpaul
23650128Swpaul	pci_device_id = pci_get_device(dev);
23750128Swpaul	pci_subvendor_id = pci_get_subvendor(dev);
23850128Swpaul	pci_subdevice_id = pci_get_subdevice(dev);
23950128Swpaul
24050128Swpaul	ent = em_vendor_info_array;
24150128Swpaul	while (ent->vendor_id != 0) {
24267089Swpaul		if ((pci_vendor_id == ent->vendor_id) &&
24350128Swpaul		    (pci_device_id == ent->device_id) &&
24467089Swpaul
24550128Swpaul		    ((pci_subvendor_id == ent->subvendor_id) ||
24650128Swpaul		     (ent->subvendor_id == PCI_ANY_ID)) &&
24750128Swpaul
24850128Swpaul		    ((pci_subdevice_id == ent->subdevice_id) ||
24950128Swpaul		     (ent->subdevice_id == PCI_ANY_ID))) {
25050128Swpaul			sprintf(adapter_name, "%s, Version - %s",
25150128Swpaul				em_strings[ent->index],
25250128Swpaul				em_driver_version);
25350128Swpaul			device_set_desc_copy(dev, adapter_name);
25450128Swpaul			return(0);
25550128Swpaul		}
25650128Swpaul		ent++;
25750128Swpaul	}
25850128Swpaul
25950128Swpaul	return(ENXIO);
26050128Swpaul}
26150128Swpaul
26250128Swpaul/*********************************************************************
26350128Swpaul *  Device initialization routine
26450128Swpaul *
26550128Swpaul *  The attach entry point is called when the driver is being loaded.
26650128Swpaul *  This routine identifies the type of hardware, allocates all resources
26750128Swpaul *  and initializes the hardware.
26850128Swpaul *
26950128Swpaul *  return 0 on success, positive on failure
27050128Swpaul *********************************************************************/
27150128Swpaul
27250128Swpaulstatic int
27350128Swpaulem_attach(device_t dev)
27450128Swpaul{
27550128Swpaul	struct adapter * adapter;
27650128Swpaul	int             s;
27750128Swpaul	int             tsize, rsize;
27850128Swpaul	int		error = 0;
27950128Swpaul
28050128Swpaul	INIT_DEBUGOUT("em_attach: begin");
28150128Swpaul	s = splimp();
28250128Swpaul
28350128Swpaul	/* Allocate, clear, and link in our adapter structure */
28450128Swpaul	if (!(adapter = device_get_softc(dev))) {
28550128Swpaul		printf("em: adapter structure allocation failed\n");
28650128Swpaul		splx(s);
28750128Swpaul		return(ENOMEM);
28850128Swpaul	}
28950128Swpaul	bzero(adapter, sizeof(struct adapter ));
29050128Swpaul	adapter->dev = dev;
29150128Swpaul	adapter->osdep.dev = dev;
29250128Swpaul	adapter->unit = device_get_unit(dev);
29350128Swpaul
29450128Swpaul	if (em_adapter_list != NULL)
29550128Swpaul		em_adapter_list->prev = adapter;
29650128Swpaul	adapter->next = em_adapter_list;
29750128Swpaul	em_adapter_list = adapter;
29850128Swpaul
29950128Swpaul	/* SYSCTL stuff */
30050128Swpaul        sysctl_ctx_init(&adapter->sysctl_ctx);
30150128Swpaul        adapter->sysctl_tree = SYSCTL_ADD_NODE(&adapter->sysctl_ctx,
30250128Swpaul                                               SYSCTL_STATIC_CHILDREN(_hw),
30350128Swpaul                                               OID_AUTO,
30450128Swpaul                                               device_get_nameunit(dev),
30550128Swpaul                                               CTLFLAG_RD,
30650128Swpaul                                               0, "");
30750128Swpaul        if (adapter->sysctl_tree == NULL) {
30850128Swpaul                error = EIO;
30950128Swpaul                goto err_sysctl;
31050128Swpaul        }
31150128Swpaul
31250128Swpaul        SYSCTL_ADD_PROC(&adapter->sysctl_ctx,
31350128Swpaul                        SYSCTL_CHILDREN(adapter->sysctl_tree),
31450128Swpaul                        OID_AUTO, "debug_info", CTLTYPE_INT|CTLFLAG_RW,
31550128Swpaul                        (void *)adapter, 0,
31650128Swpaul                        em_sysctl_debug_info, "I", "Debug Information");
31750128Swpaul
31850128Swpaul        SYSCTL_ADD_PROC(&adapter->sysctl_ctx,
31967089Swpaul                        SYSCTL_CHILDREN(adapter->sysctl_tree),
32050128Swpaul                        OID_AUTO, "stats", CTLTYPE_INT|CTLFLAG_RW,
32150128Swpaul                        (void *)adapter, 0,
32250128Swpaul                        em_sysctl_stats, "I", "Statistics");
32350128Swpaul
32450128Swpaul	callout_handle_init(&adapter->timer_handle);
32550128Swpaul	callout_handle_init(&adapter->tx_fifo_timer_handle);
32650128Swpaul
32750128Swpaul	/* Determine hardware revision */
32850128Swpaul	em_identify_hardware(adapter);
32950128Swpaul
33050128Swpaul	/* Set up some sysctls for the tunable interrupt delays */
33150128Swpaul	em_add_int_delay_sysctl(adapter, "rx_int_delay",
33250128Swpaul	    "receive interrupt delay in usecs", &adapter->rx_int_delay,
33350128Swpaul	    E1000_REG_OFFSET(&adapter->hw, RDTR), em_rx_int_delay_dflt);
33467089Swpaul	em_add_int_delay_sysctl(adapter, "tx_int_delay",
33550128Swpaul	    "transmit interrupt delay in usecs", &adapter->tx_int_delay,
33650128Swpaul	    E1000_REG_OFFSET(&adapter->hw, TIDV), em_tx_int_delay_dflt);
33750128Swpaul	if (adapter->hw.mac_type >= em_82540) {
33850128Swpaul		em_add_int_delay_sysctl(adapter, "rx_abs_int_delay",
33950128Swpaul		    "receive interrupt delay limit in usecs",
34050128Swpaul		    &adapter->rx_abs_int_delay,
34150128Swpaul		    E1000_REG_OFFSET(&adapter->hw, RADV),
34250128Swpaul		    em_rx_abs_int_delay_dflt);
34350128Swpaul		em_add_int_delay_sysctl(adapter, "tx_abs_int_delay",
34450128Swpaul		    "transmit interrupt delay limit in usecs",
34550128Swpaul		    &adapter->tx_abs_int_delay,
34650128Swpaul		    E1000_REG_OFFSET(&adapter->hw, TADV),
34750128Swpaul		    em_tx_abs_int_delay_dflt);
34850128Swpaul	}
34950128Swpaul
35050128Swpaul	/* Parameters (to be read from user) */
35150128Swpaul        adapter->num_tx_desc = EM_MAX_TXD;
35250128Swpaul        adapter->num_rx_desc = EM_MAX_RXD;
35350128Swpaul        adapter->hw.autoneg = DO_AUTO_NEG;
35450128Swpaul        adapter->hw.wait_autoneg_complete = WAIT_FOR_AUTO_NEG_DEFAULT;
35550128Swpaul        adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT;
35650128Swpaul        adapter->hw.tbi_compatibility_en = TRUE;
35750128Swpaul        adapter->rx_buffer_len = EM_RXBUFFER_2048;
35850128Swpaul
35950128Swpaul	/*
36050128Swpaul         * These parameters control the automatic generation(Tx) and
36150128Swpaul         * response(Rx) to Ethernet PAUSE frames.
36250128Swpaul         */
36350128Swpaul        adapter->hw.fc_high_water = FC_DEFAULT_HI_THRESH;
36450128Swpaul        adapter->hw.fc_low_water  = FC_DEFAULT_LO_THRESH;
36550128Swpaul        adapter->hw.fc_pause_time = FC_DEFAULT_TX_TIMER;
36650128Swpaul        adapter->hw.fc_send_xon   = TRUE;
36750128Swpaul        adapter->hw.fc = em_fc_full;
36850128Swpaul
36967089Swpaul	adapter->hw.phy_init_script = 1;
37050128Swpaul
37150128Swpaul	/*
37250128Swpaul	 * Set the max frame size assuming standard ethernet
37350128Swpaul	 * sized frames
37450128Swpaul	 */
37550128Swpaul	adapter->hw.max_frame_size =
37650128Swpaul		ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN;
37750128Swpaul
37850128Swpaul	adapter->hw.min_frame_size =
37950128Swpaul		MINIMUM_ETHERNET_PACKET_SIZE + ETHER_CRC_LEN;
38050128Swpaul
38150128Swpaul	/*
38250128Swpaul	 * This controls when hardware reports transmit completion
383102000Sambrisko	 * status.
384102000Sambrisko	 */
385102000Sambrisko	adapter->hw.report_tx_early = 1;
386102000Sambrisko
387102000Sambrisko
38850128Swpaul	if (em_allocate_pci_resources(adapter)) {
38950128Swpaul		printf("em%d: Allocation of PCI resources failed\n",
39050128Swpaul		       adapter->unit);
39150128Swpaul                error = ENXIO;
39250128Swpaul                goto err_pci;
39350128Swpaul	}
39450128Swpaul
39550128Swpaul
39650128Swpaul	/* Initialize eeprom parameters */
39750128Swpaul        em_init_eeprom_params(&adapter->hw);
39850128Swpaul
39950128Swpaul	tsize = EM_ROUNDUP(adapter->num_tx_desc *
40050128Swpaul			   sizeof(struct em_tx_desc), 4096);
40150128Swpaul
40250128Swpaul	/* Allocate Transmit Descriptor ring */
40350128Swpaul        if (em_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
40450128Swpaul                printf("em%d: Unable to allocate tx_desc memory\n",
40550128Swpaul                       adapter->unit);
40650128Swpaul		error = ENOMEM;
40750128Swpaul                goto err_tx_desc;
40850128Swpaul        }
40950128Swpaul        adapter->tx_desc_base = (struct em_tx_desc *) adapter->txdma.dma_vaddr;
41050128Swpaul
41150128Swpaul	rsize = EM_ROUNDUP(adapter->num_rx_desc *
41250128Swpaul			   sizeof(struct em_rx_desc), 4096);
41350128Swpaul
41450128Swpaul	/* Allocate Receive Descriptor ring */
41550128Swpaul        if (em_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
41650128Swpaul                printf("em%d: Unable to allocate rx_desc memory\n",
41750128Swpaul                        adapter->unit);
41850128Swpaul		error = ENOMEM;
41950128Swpaul                goto err_rx_desc;
42050128Swpaul        }
42150128Swpaul        adapter->rx_desc_base = (struct em_rx_desc *) adapter->rxdma.dma_vaddr;
42250128Swpaul
42367089Swpaul	/* Initialize the hardware */
42450128Swpaul	if (em_hardware_init(adapter)) {
42550128Swpaul		printf("em%d: Unable to initialize the hardware\n",
42650128Swpaul		       adapter->unit);
42750128Swpaul		error = EIO;
42850128Swpaul                goto err_hw_init;
42950128Swpaul	}
43050128Swpaul
43167089Swpaul	/* Copy the permanent MAC address out of the EEPROM */
43250128Swpaul	if (em_read_mac_addr(&adapter->hw) < 0) {
43350128Swpaul		printf("em%d: EEPROM read error while reading mac address\n",
43450128Swpaul		       adapter->unit);
43550128Swpaul		error = EIO;
43650128Swpaul                goto err_mac_addr;
43750128Swpaul	}
43850128Swpaul
43950128Swpaul	if (!em_is_valid_ether_addr(adapter->hw.mac_addr)) {
44050128Swpaul                printf("em%d: Invalid mac address\n", adapter->unit);
44150128Swpaul                error = EIO;
44250128Swpaul                goto err_mac_addr;
44350128Swpaul        }
44454268Swpaul
44554268Swpaul	bcopy(adapter->hw.mac_addr, adapter->interface_data.ac_enaddr,
44654268Swpaul	      ETHER_ADDR_LEN);
44772012Sphk
44854268Swpaul	/* Setup OS specific network interface */
44954268Swpaul	em_setup_interface(dev, adapter);
45050128Swpaul
45150128Swpaul	/* Initialize statistics */
45250128Swpaul	em_clear_hw_cntrs(&adapter->hw);
45350128Swpaul	em_update_stats_counters(adapter);
45450128Swpaul	adapter->hw.get_link_status = 1;
45550128Swpaul	em_check_for_link(&adapter->hw);
45650128Swpaul
45750128Swpaul	/* Print the link status */
45850128Swpaul	if (adapter->link_active == 1) {
45950128Swpaul		em_get_speed_and_duplex(&adapter->hw, &adapter->link_speed,
46050128Swpaul					&adapter->link_duplex);
46150128Swpaul		printf("em%d:  Speed:%d Mbps  Duplex:%s\n",
46250128Swpaul		       adapter->unit,
46350128Swpaul		       adapter->link_speed,
46450128Swpaul		       adapter->link_duplex == FULL_DUPLEX ? "Full" : "Half");
46550128Swpaul	} else
46650128Swpaul		printf("em%d:  Speed:N/A  Duplex:N/A\n", adapter->unit);
46750128Swpaul
46850128Swpaul	INIT_DEBUGOUT("em_attach: end");
46950128Swpaul	splx(s);
47050128Swpaul	return(0);
47150128Swpaul
47250128Swpaulerr_mac_addr:
47350128Swpaulerr_hw_init:
47450128Swpaul        em_dma_free(adapter, &adapter->rxdma);
47550128Swpaulerr_rx_desc:
47650128Swpaul        em_dma_free(adapter, &adapter->txdma);
47750128Swpaulerr_tx_desc:
47850128Swpaulerr_pci:
47950128Swpaul        em_free_pci_resources(adapter);
48050128Swpaul        sysctl_ctx_free(&adapter->sysctl_ctx);
48150128Swpaulerr_sysctl:
48250128Swpaul        splx(s);
48350128Swpaul        return(error);
48450128Swpaul
48550128Swpaul}
48650128Swpaul
48750128Swpaul/*********************************************************************
48850128Swpaul *  Device removal routine
48950128Swpaul *
49050128Swpaul *  The detach entry point is called when the driver is being removed.
49150128Swpaul *  This routine stops the adapter and deallocates all the resources
49250128Swpaul *  that were allocated for driver operation.
49350128Swpaul *
49450128Swpaul *  return 0 on success, positive on failure
49550128Swpaul *********************************************************************/
49650128Swpaul
49750128Swpaulstatic int
49850128Swpaulem_detach(device_t dev)
49950128Swpaul{
50050128Swpaul	struct adapter * adapter = device_get_softc(dev);
50150128Swpaul	struct ifnet   *ifp = &adapter->interface_data.ac_if;
50250128Swpaul	int             s;
50350128Swpaul
50450128Swpaul	INIT_DEBUGOUT("em_detach: begin");
50550128Swpaul	s = splimp();
50650128Swpaul
50750128Swpaul	em_stop(adapter);
50850128Swpaul	em_phy_hw_reset(&adapter->hw);
50950128Swpaul#if __FreeBSD_version < 500000
51050128Swpaul        ether_ifdetach(&adapter->interface_data.ac_if, ETHER_BPF_SUPPORTED);
51150128Swpaul#else
51250128Swpaul        ether_ifdetach(&adapter->interface_data.ac_if);
51350128Swpaul#endif
51450128Swpaul	em_free_pci_resources(adapter);
51550128Swpaul
51650128Swpaul	/* Free Transmit Descriptor ring */
51750128Swpaul        if (adapter->tx_desc_base) {
51850128Swpaul                em_dma_free(adapter, &adapter->txdma);
51950128Swpaul                adapter->tx_desc_base = NULL;
52050128Swpaul        }
52150128Swpaul
52250128Swpaul        /* Free Receive Descriptor ring */
52350128Swpaul        if (adapter->rx_desc_base) {
52450128Swpaul                em_dma_free(adapter, &adapter->rxdma);
52550128Swpaul                adapter->rx_desc_base = NULL;
52650128Swpaul        }
52750128Swpaul
52850128Swpaul	/* Remove from the adapter list */
52950128Swpaul	if (em_adapter_list == adapter)
53050128Swpaul		em_adapter_list = adapter->next;
53150128Swpaul	if (adapter->next != NULL)
53250128Swpaul		adapter->next->prev = adapter->prev;
53350128Swpaul	if (adapter->prev != NULL)
53450128Swpaul		adapter->prev->next = adapter->next;
53550128Swpaul
53650128Swpaul	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
53750128Swpaul	ifp->if_timer = 0;
53850128Swpaul
53950128Swpaul	splx(s);
54050128Swpaul	return(0);
54150128Swpaul}
54250128Swpaul
54350128Swpaul/*********************************************************************
54450128Swpaul *
54550128Swpaul *  Shutdown entry point
54650128Swpaul *
54750128Swpaul **********************************************************************/
54850128Swpaul
54950128Swpaulstatic int
55050128Swpaulem_shutdown(device_t dev)
55150128Swpaul{
55250128Swpaul	struct adapter *adapter = device_get_softc(dev);
55350128Swpaul	em_stop(adapter);
55450128Swpaul	return(0);
55550128Swpaul}
55650128Swpaul
55750128Swpaul
55850128Swpaul/*********************************************************************
55950128Swpaul *  Transmit entry point
56050128Swpaul *
56150128Swpaul *  em_start is called by the stack to initiate a transmit.
56250128Swpaul *  The driver will remain in this routine as long as there are
56350128Swpaul *  packets to transmit and transmit resources are available.
56450128Swpaul *  In case resources are not available stack is notified and
56550128Swpaul *  the packet is requeued.
56650128Swpaul **********************************************************************/
56750128Swpaul
56850128Swpaulstatic void
56950128Swpaulem_start(struct ifnet *ifp)
57050128Swpaul{
57150128Swpaul        int             s;
57250128Swpaul        struct mbuf    *m_head;
57350128Swpaul        struct adapter *adapter = ifp->if_softc;
57450128Swpaul
57550128Swpaul        if (!adapter->link_active)
57650128Swpaul                return;
57750128Swpaul
57850128Swpaul        s = splimp();
57950128Swpaul        while (ifp->if_snd.ifq_head != NULL) {
58050128Swpaul
58150128Swpaul                IF_DEQUEUE(&ifp->if_snd, m_head);
58250128Swpaul
58350128Swpaul                if (m_head == NULL) break;
58450128Swpaul
58550128Swpaul		if (em_encap(adapter, m_head)) {
58650128Swpaul			ifp->if_flags |= IFF_OACTIVE;
58750128Swpaul			IF_PREPEND(&ifp->if_snd, m_head);
58850128Swpaul			break;
58982214Swpaul                }
59082214Swpaul
59182214Swpaul		/* Send a copy of the frame to the BPF listener */
59282214Swpaul#if __FreeBSD_version < 500000
59350128Swpaul                if (ifp->if_bpf)
59450128Swpaul                        bpf_mtap(ifp, m_head);
59572084Sphk#else
59650128Swpaul		BPF_MTAP(ifp, m_head);
59750128Swpaul#endif
59850128Swpaul
59950128Swpaul                /* Set timeout in case hardware has problems transmitting */
60050128Swpaul                ifp->if_timer = EM_TX_TIMEOUT;
60150128Swpaul
60250128Swpaul        }
60350128Swpaul        splx(s);
60450128Swpaul        return;
60582214Swpaul}
60682214Swpaul
60782214Swpaul/*********************************************************************
60882214Swpaul *  Ioctl entry point
60950128Swpaul *
61050128Swpaul *  em_ioctl is called when the user wants to configure the
61150128Swpaul *  interface.
61250128Swpaul *
61350128Swpaul *  return 0 on success, positive on failure
61450128Swpaul **********************************************************************/
61550128Swpaul
61650128Swpaulstatic int
61750128Swpaulem_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
61850128Swpaul{
61950128Swpaul	int             s, mask, error = 0;
62050128Swpaul	struct ifreq   *ifr = (struct ifreq *) data;
62150128Swpaul	struct adapter * adapter = ifp->if_softc;
62250128Swpaul
62367089Swpaul	s = splimp();
62450128Swpaul	switch (command) {
62550128Swpaul	case SIOCSIFADDR:
62650128Swpaul	case SIOCGIFADDR:
62767089Swpaul		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFADDR (Get/Set Interface Addr)");
62867089Swpaul		ether_ioctl(ifp, command, data);
62950128Swpaul		break;
63067089Swpaul	case SIOCSIFMTU:
63150128Swpaul		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)");
63250128Swpaul		if (ifr->ifr_mtu > MAX_JUMBO_FRAME_SIZE - ETHER_HDR_LEN) {
63350128Swpaul			error = EINVAL;
63450128Swpaul		} else {
63550128Swpaul			ifp->if_mtu = ifr->ifr_mtu;
63650128Swpaul			adapter->hw.max_frame_size =
63750128Swpaul			ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
63850128Swpaul			em_init(adapter);
63950128Swpaul		}
64050128Swpaul		break;
64150128Swpaul	case SIOCSIFFLAGS:
64250128Swpaul		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)");
64350128Swpaul		if (ifp->if_flags & IFF_UP) {
64450128Swpaul			if (!(ifp->if_flags & IFF_RUNNING))
64550128Swpaul				em_init(adapter);
64650128Swpaul
64750128Swpaul			em_disable_promisc(adapter);
64850128Swpaul			em_set_promisc(adapter);
64950128Swpaul		} else {
65050128Swpaul			if (ifp->if_flags & IFF_RUNNING) {
65150128Swpaul				em_stop(adapter);
652101493Sambrisko			}
653101493Sambrisko		}
654101493Sambrisko		break;
655101493Sambrisko	case SIOCADDMULTI:
65650128Swpaul	case SIOCDELMULTI:
65750128Swpaul		IOCTL_DEBUGOUT("ioctl rcv'd: SIOC(ADD|DEL)MULTI");
65850128Swpaul		if (ifp->if_flags & IFF_RUNNING) {
65950128Swpaul			em_disable_intr(adapter);
66050128Swpaul			em_set_multi(adapter);
66150128Swpaul			if (adapter->hw.mac_type == em_82542_rev2_0) {
66250128Swpaul				em_initialize_receive_unit(adapter);
66350128Swpaul			}
66450128Swpaul#ifdef DEVICE_POLLING
66550128Swpaul                        if (!(ifp->if_ipending & IFF_POLLING))
66650128Swpaul#endif
66750128Swpaul				em_enable_intr(adapter);
66867089Swpaul		}
66967089Swpaul		break;
67050128Swpaul	case SIOCSIFMEDIA:
67150128Swpaul	case SIOCGIFMEDIA:
67250128Swpaul		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFMEDIA (Get/Set Interface Media)");
67350128Swpaul		error = ifmedia_ioctl(ifp, ifr, &adapter->media, command);
67450128Swpaul		break;
67550128Swpaul	case SIOCSIFCAP:
67650128Swpaul		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)");
67750128Swpaul		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
67850128Swpaul		if (mask & IFCAP_HWCSUM) {
67950128Swpaul			if (IFCAP_HWCSUM & ifp->if_capenable)
68050128Swpaul				ifp->if_capenable &= ~IFCAP_HWCSUM;
68150128Swpaul			else
68250128Swpaul				ifp->if_capenable |= IFCAP_HWCSUM;
68350128Swpaul			if (ifp->if_flags & IFF_RUNNING)
684101493Sambrisko				em_init(adapter);
68550128Swpaul		}
68650128Swpaul		break;
68750128Swpaul	default:
68850128Swpaul		IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%d)\n", (int)command);
689101493Sambrisko		error = EINVAL;
690101493Sambrisko	}
691101493Sambrisko
692101493Sambrisko	splx(s);
693101493Sambrisko	return(error);
69450128Swpaul}
69550128Swpaul
69650128Swpaul/*********************************************************************
69750128Swpaul *  Watchdog entry point
69850128Swpaul *
69950128Swpaul *  This routine is called whenever hardware quits transmitting.
70050128Swpaul *
70150128Swpaul **********************************************************************/
70250128Swpaul
70350128Swpaulstatic void
70450128Swpaulem_watchdog(struct ifnet *ifp)
70550128Swpaul{
70650128Swpaul	struct adapter * adapter;
70750128Swpaul	adapter = ifp->if_softc;
70850128Swpaul
70950128Swpaul	/* If we are in this routine because of pause frames, then
71050128Swpaul	 * don't reset the hardware.
71150128Swpaul	 */
71250128Swpaul	if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF) {
71350128Swpaul		ifp->if_timer = EM_TX_TIMEOUT;
71450128Swpaul		return;
71550128Swpaul	}
71650128Swpaul
71750128Swpaul	printf("em%d: watchdog timeout -- resetting\n", adapter->unit);
71850128Swpaul
71950128Swpaul	ifp->if_flags &= ~IFF_RUNNING;
72050128Swpaul
72150128Swpaul	em_stop(adapter);
72250128Swpaul	em_init(adapter);
72350128Swpaul
72450128Swpaul	ifp->if_oerrors++;
72550128Swpaul	return;
72650128Swpaul}
72750128Swpaul
72850128Swpaul/*********************************************************************
72950128Swpaul *  Init entry point
73050128Swpaul *
73150128Swpaul *  This routine is used in two ways. It is used by the stack as
73250128Swpaul *  init entry point in network interface structure. It is also used
73350128Swpaul *  by the driver as a hw/sw initialization routine to get to a
73450128Swpaul *  consistent state.
73550128Swpaul *
73650128Swpaul *  return 0 on success, positive on failure
73750128Swpaul **********************************************************************/
73850128Swpaul
73950128Swpaulstatic void
74050128Swpaulem_init(void *arg)
74150128Swpaul{
74250128Swpaul	int             s;
74350128Swpaul	struct ifnet   *ifp;
74450128Swpaul	struct adapter * adapter = arg;
74550128Swpaul
74650128Swpaul	INIT_DEBUGOUT("em_init: begin");
74750128Swpaul
74850128Swpaul	s = splimp();
749101493Sambrisko
750101493Sambrisko	em_stop(adapter);
75150128Swpaul
75250128Swpaul	/* Initialize the hardware */
75350128Swpaul	if (em_hardware_init(adapter)) {
75450128Swpaul		printf("em%d: Unable to initialize the hardware\n",
75550128Swpaul		       adapter->unit);
75650128Swpaul		splx(s);
75750128Swpaul		return;
75850128Swpaul	}
75950128Swpaul
76050128Swpaul	em_enable_vlans(adapter);
76150128Swpaul
76250128Swpaul	/* Prepare transmit descriptors and buffers */
76350128Swpaul	if (em_setup_transmit_structures(adapter)) {
76450128Swpaul		printf("em%d: Could not setup transmit structures\n",
76550128Swpaul		       adapter->unit);
76650128Swpaul		em_stop(adapter);
76750128Swpaul		splx(s);
76850128Swpaul		return;
76950128Swpaul	}
77050128Swpaul	em_initialize_transmit_unit(adapter);
77150128Swpaul
77250128Swpaul	/* Setup Multicast table */
77354268Swpaul	em_set_multi(adapter);
77454268Swpaul
77554268Swpaul	/* Prepare receive descriptors and buffers */
77650128Swpaul	if (em_setup_receive_structures(adapter)) {
77750128Swpaul		printf("em%d: Could not setup receive structures\n",
77850128Swpaul		       adapter->unit);
77950128Swpaul		em_stop(adapter);
78050128Swpaul		splx(s);
78150128Swpaul		return;
78250128Swpaul	}
78350128Swpaul	em_initialize_receive_unit(adapter);
78450128Swpaul
78550128Swpaul	ifp = &adapter->interface_data.ac_if;
78650128Swpaul	ifp->if_flags |= IFF_RUNNING;
78750392Swpaul	ifp->if_flags &= ~IFF_OACTIVE;
78850128Swpaul
78950128Swpaul	if (adapter->hw.mac_type >= em_82543) {
79050128Swpaul		if (ifp->if_capenable & IFCAP_TXCSUM)
79150128Swpaul			ifp->if_hwassist = EM_CHECKSUM_FEATURES;
79250128Swpaul		else
79350128Swpaul			ifp->if_hwassist = 0;
79450128Swpaul	}
79550128Swpaul
79650128Swpaul	adapter->timer_handle = timeout(em_local_timer, adapter, 2*hz);
79754268Swpaul	em_clear_hw_cntrs(&adapter->hw);
79850128Swpaul#ifdef DEVICE_POLLING
79954268Swpaul        /*
80050128Swpaul         * Only enable interrupts if we are not polling, make sure
80150128Swpaul         * they are off otherwise.
80250128Swpaul         */
80354268Swpaul        if (ifp->if_ipending & IFF_POLLING)
80454268Swpaul                em_disable_intr(adapter);
80554268Swpaul        else
80650128Swpaul#endif /* DEVICE_POLLING */
80750128Swpaul		em_enable_intr(adapter);
80850128Swpaul
80950128Swpaul	splx(s);
81054268Swpaul	return;
81154268Swpaul}
81254268Swpaul
81354268Swpaul
81454268Swpaul#ifdef DEVICE_POLLING
81550128Swpaulstatic poll_handler_t em_poll;
81650128Swpaul
81754268Swpaulstatic void
81854268Swpaulem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
81954268Swpaul{
82050128Swpaul        struct adapter *adapter = ifp->if_softc;
82150128Swpaul        u_int32_t reg_icr;
82254268Swpaul
82354268Swpaul        if (cmd == POLL_DEREGISTER) {       /* final call, enable interrupts */
82454268Swpaul                em_enable_intr(adapter);
82550128Swpaul                return;
82650128Swpaul        }
82750128Swpaul        if (cmd == POLL_AND_CHECK_STATUS) {
82850128Swpaul                reg_icr = E1000_READ_REG(&adapter->hw, ICR);
82950128Swpaul                if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
83050128Swpaul                        untimeout(em_local_timer, adapter, adapter->timer_handle);
83150128Swpaul                        adapter->hw.get_link_status = 1;
83250128Swpaul                        em_check_for_link(&adapter->hw);
83350128Swpaul                        em_print_link_status(adapter);
83450128Swpaul                        adapter->timer_handle = timeout(em_local_timer, adapter, 2*hz);
83550128Swpaul                }
83650128Swpaul        }
83767089Swpaul        if (ifp->if_flags & IFF_RUNNING) {
83867089Swpaul                em_process_receive_interrupts(adapter, count);
83950128Swpaul                em_clean_transmit_interrupts(adapter);
84050128Swpaul        }
84150128Swpaul
84250128Swpaul        if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL)
843101493Sambrisko                em_start(ifp);
844101493Sambrisko}
845101493Sambrisko#endif /* DEVICE_POLLING */
84650128Swpaul
847101493Sambrisko/*********************************************************************
848101493Sambrisko *
849101493Sambrisko *  Interrupt Service routine
850101493Sambrisko *
851101493Sambrisko **********************************************************************/
852101493Sambriskostatic void
853101493Sambriskoem_intr(void *arg)
854101493Sambrisko{
855101493Sambrisko        u_int32_t       loop_cnt = EM_MAX_INTR;
856101493Sambrisko        u_int32_t       reg_icr;
857101493Sambrisko        struct ifnet    *ifp;
858101493Sambrisko        struct adapter  *adapter = arg;
859101493Sambrisko
86050128Swpaul        ifp = &adapter->interface_data.ac_if;
86150128Swpaul
86250128Swpaul#ifdef DEVICE_POLLING
86367089Swpaul        if (ifp->if_ipending & IFF_POLLING)
86450128Swpaul                return;
86550128Swpaul
86650128Swpaul        if (ether_poll_register(em_poll, ifp)) {
86750128Swpaul                em_disable_intr(adapter);
86850128Swpaul                em_poll(ifp, 0, 1);
86950128Swpaul                return;
87050128Swpaul        }
87150128Swpaul#endif /* DEVICE_POLLING */
87250128Swpaul
87350128Swpaul	reg_icr = E1000_READ_REG(&adapter->hw, ICR);
87450128Swpaul        if (!reg_icr) {
87550128Swpaul                return;
87650128Swpaul        }
87750128Swpaul
87850128Swpaul        /* Link status change */
87950128Swpaul        if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
88050128Swpaul                untimeout(em_local_timer, adapter,
88150128Swpaul                          adapter->timer_handle);
88250128Swpaul                adapter->hw.get_link_status = 1;
88350128Swpaul                em_check_for_link(&adapter->hw);
88450128Swpaul                em_print_link_status(adapter);
88550128Swpaul                adapter->timer_handle =
88650128Swpaul                timeout(em_local_timer, adapter, 2*hz);
88750128Swpaul        }
88850128Swpaul
88950128Swpaul        while (loop_cnt > 0) {
89050128Swpaul                if (ifp->if_flags & IFF_RUNNING) {
89150128Swpaul                        em_process_receive_interrupts(adapter, -1);
89250128Swpaul                        em_clean_transmit_interrupts(adapter);
89350128Swpaul                }
89450128Swpaul                loop_cnt--;
89550128Swpaul        }
89650128Swpaul
89750128Swpaul        if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL)
89850128Swpaul                em_start(ifp);
89950128Swpaul
90050128Swpaul        return;
90150128Swpaul}
90250128Swpaul
90350128Swpaul
90450128Swpaul
90550128Swpaul/*********************************************************************
90650128Swpaul *
907101493Sambrisko *  Media Ioctl callback
90850128Swpaul *
90993818Sjhb *  This routine is called whenever the user queries the status of
91093818Sjhb *  the interface using ifconfig.
91169583Swpaul *
91269583Swpaul **********************************************************************/
91350128Swpaulstatic void
91450128Swpaulem_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
91550128Swpaul{
91672813Swpaul	struct adapter * adapter = ifp->if_softc;
91772813Swpaul
91850128Swpaul	INIT_DEBUGOUT("em_media_status: begin");
91972813Swpaul
92072813Swpaul	em_check_for_link(&adapter->hw);
92172813Swpaul	if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU) {
92272813Swpaul		if (adapter->link_active == 0) {
92350128Swpaul			em_get_speed_and_duplex(&adapter->hw,
92472813Swpaul						&adapter->link_speed,
92572813Swpaul						&adapter->link_duplex);
92672813Swpaul			adapter->link_active = 1;
92772813Swpaul		}
92872813Swpaul	} else {
92950128Swpaul		if (adapter->link_active == 1) {
93072813Swpaul			adapter->link_speed = 0;
93172813Swpaul			adapter->link_duplex = 0;
93272813Swpaul			adapter->link_active = 0;
93372813Swpaul		}
93450128Swpaul	}
93550128Swpaul
93650128Swpaul	ifmr->ifm_status = IFM_AVALID;
93750128Swpaul	ifmr->ifm_active = IFM_ETHER;
93850128Swpaul
93972813Swpaul	if (!adapter->link_active)
94079472Swpaul		return;
94179472Swpaul
94261041Speter	ifmr->ifm_status |= IFM_ACTIVE;
94350128Swpaul
94450128Swpaul	if (adapter->hw.media_type == em_media_type_fiber) {
94550128Swpaul		ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
94650128Swpaul	} else {
94750128Swpaul		switch (adapter->link_speed) {
94850128Swpaul		case 10:
94950128Swpaul			ifmr->ifm_active |= IFM_10_T;
95050128Swpaul			break;
95150128Swpaul		case 100:
95250128Swpaul			ifmr->ifm_active |= IFM_100_TX;
95350128Swpaul			break;
95450128Swpaul		case 1000:
95550128Swpaul#if __FreeBSD_version < 500000
95650128Swpaul			ifmr->ifm_active |= IFM_1000_TX;
95750128Swpaul#else
95850128Swpaul			ifmr->ifm_active |= IFM_1000_T;
95950128Swpaul#endif
96050128Swpaul			break;
96150128Swpaul		}
96250128Swpaul		if (adapter->link_duplex == FULL_DUPLEX)
96350128Swpaul			ifmr->ifm_active |= IFM_FDX;
96450128Swpaul		else
96550128Swpaul			ifmr->ifm_active |= IFM_HDX;
96650128Swpaul	}
96750128Swpaul	return;
96850128Swpaul}
96950128Swpaul
97050128Swpaul/*********************************************************************
97150128Swpaul *
97250128Swpaul *  Media Ioctl callback
97350128Swpaul *
97450128Swpaul *  This routine is called when the user changes speed/duplex using
97550128Swpaul *  media/mediopt option with ifconfig.
97650128Swpaul *
97750128Swpaul **********************************************************************/
97850128Swpaulstatic int
97950128Swpaulem_media_change(struct ifnet *ifp)
98050128Swpaul{
98150128Swpaul	struct adapter * adapter = ifp->if_softc;
98250128Swpaul	struct ifmedia  *ifm = &adapter->media;
98350128Swpaul
98450128Swpaul	INIT_DEBUGOUT("em_media_change: begin");
98550128Swpaul
98650128Swpaul	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
98750128Swpaul		return(EINVAL);
98850128Swpaul
98950128Swpaul	switch (IFM_SUBTYPE(ifm->ifm_media)) {
99050128Swpaul	case IFM_AUTO:
99150128Swpaul		adapter->hw.autoneg = DO_AUTO_NEG;
99250128Swpaul		adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT;
99350128Swpaul		break;
99450128Swpaul	case IFM_1000_SX:
99550128Swpaul#if __FreeBSD_version < 500000
99650128Swpaul	case IFM_1000_TX:
99750128Swpaul#else
99850128Swpaul	case IFM_1000_T:
99950128Swpaul#endif
100050128Swpaul		adapter->hw.autoneg = DO_AUTO_NEG;
100150128Swpaul		adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
100250128Swpaul		break;
100350684Swpaul	case IFM_100_TX:
100450684Swpaul		adapter->hw.autoneg = FALSE;
100550684Swpaul		adapter->hw.autoneg_advertised = 0;
100650684Swpaul		if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
100750128Swpaul			adapter->hw.forced_speed_duplex = em_100_full;
100850128Swpaul		else
100950128Swpaul			adapter->hw.forced_speed_duplex	= em_100_half;
101050128Swpaul		break;
101150128Swpaul	case IFM_10_T:
101250128Swpaul		adapter->hw.autoneg = FALSE;
101350128Swpaul		adapter->hw.autoneg_advertised = 0;
101450128Swpaul		if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
101550128Swpaul			adapter->hw.forced_speed_duplex = em_10_full;
101650128Swpaul		else
101750128Swpaul			adapter->hw.forced_speed_duplex	= em_10_half;
101850128Swpaul		break;
101950128Swpaul	default:
102050548Sbde		printf("em%d: Unsupported media type\n", adapter->unit);
102150128Swpaul	}
102250128Swpaul
102350128Swpaul	em_init(adapter);
102450684Swpaul
102550684Swpaul	return(0);
102650684Swpaul}
102750684Swpaul
102850128Swpaulstatic void
102950128Swpaulem_tx_cb(void *arg, bus_dma_segment_t *seg, int nsegs, bus_size_t mapsize, int error)
103050128Swpaul{
103150128Swpaul        struct em_q *q = arg;
103250128Swpaul
103350128Swpaul        if (error)
103450128Swpaul                return;
103550128Swpaul        KASSERT(nsegs <= EM_MAX_SCATTER,
103650128Swpaul                ("Too many DMA segments returned when mapping tx packet"));
103750128Swpaul        q->nsegs = nsegs;
103850128Swpaul        bcopy(seg, q->segs, nsegs * sizeof(seg[0]));
103950128Swpaul}
104054268Swpaul
104154268Swpaul#define EM_FIFO_HDR              0x10
104250128Swpaul#define EM_82547_PKT_THRESH      0x3e0
104350128Swpaul#define EM_82547_TX_FIFO_SIZE    0x2800
104450128Swpaul#define EM_82547_TX_FIFO_BEGIN   0xf00
104550128Swpaul/*********************************************************************
104650128Swpaul *
104750128Swpaul *  This routine maps the mbufs to tx descriptors.
104850128Swpaul *
104950128Swpaul *  return 0 on success, positive on failure
105050128Swpaul **********************************************************************/
105150128Swpaulstatic int
105250128Swpaulem_encap(struct adapter *adapter, struct mbuf *m_head)
105350128Swpaul{
105450128Swpaul        u_int32_t       txd_upper;
105550128Swpaul        u_int32_t       txd_lower;
105650128Swpaul        int             i, j, error;
105750128Swpaul
105850128Swpaul#if __FreeBSD_version < 500000
105950128Swpaul        struct ifvlan *ifv = NULL;
1060101493Sambrisko#else
1061101493Sambrisko        struct m_tag    *mtag;
106250128Swpaul#endif
106363090Sarchie        struct em_q      q;
106450128Swpaul        struct em_buffer   *tx_buffer = NULL;
106563090Sarchie        struct em_tx_desc *current_tx_desc = NULL;
1066101493Sambrisko        struct ifnet   *ifp = &adapter->interface_data.ac_if;
1067101493Sambrisko
1068101493Sambrisko        /*
1069101493Sambrisko         * Force a cleanup if number of TX descriptors
1070101493Sambrisko         * available hits the threshold
1071101493Sambrisko         */
107267089Swpaul        if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
107367089Swpaul                em_clean_transmit_interrupts(adapter);
107450128Swpaul                if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
107550128Swpaul                        adapter->no_tx_desc_avail1++;
107667089Swpaul                        return(ENOBUFS);
107767089Swpaul                }
107850128Swpaul        }
107950128Swpaul
108050128Swpaul        /*
108150128Swpaul         * Map the packet for DMA.
108250128Swpaul         */
108350128Swpaul        if (bus_dmamap_create(adapter->txtag, BUS_DMA_NOWAIT, &q.map)) {
108450128Swpaul                adapter->no_tx_map_avail++;
108550128Swpaul                return (ENOMEM);
108650128Swpaul        }
108750128Swpaul        error = bus_dmamap_load_mbuf(adapter->txtag, q.map,
108867089Swpaul                                     m_head, em_tx_cb, &q, BUS_DMA_NOWAIT);
108950128Swpaul        if (error != 0) {
109050128Swpaul                adapter->no_tx_dma_setup++;
109150128Swpaul                bus_dmamap_destroy(adapter->txtag, q.map);
109263090Sarchie                return (error);
109350128Swpaul        }
109450128Swpaul        KASSERT(q.nsegs != 0, ("em_encap: empty packet"));
109550128Swpaul
109650128Swpaul        if (q.nsegs > adapter->num_tx_desc_avail) {
109750128Swpaul                adapter->no_tx_desc_avail2++;
109850128Swpaul                bus_dmamap_destroy(adapter->txtag, q.map);
109950128Swpaul                return (ENOBUFS);
110050128Swpaul        }
110154268Swpaul
110250128Swpaul
110367089Swpaul        if (ifp->if_hwassist > 0) {
110467089Swpaul                em_transmit_checksum_setup(adapter,  m_head,
110550128Swpaul                                           &txd_upper, &txd_lower);
110650128Swpaul        } else
110750128Swpaul                txd_upper = txd_lower = 0;
110850128Swpaul
110950128Swpaul
111050128Swpaul        /* Find out if we are in vlan mode */
111150128Swpaul#if __FreeBSD_version < 500000
111250128Swpaul        if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
111350128Swpaul            m_head->m_pkthdr.rcvif != NULL &&
111450128Swpaul            m_head->m_pkthdr.rcvif->if_type == IFT_L2VLAN)
111550128Swpaul                ifv = m_head->m_pkthdr.rcvif->if_softc;
111650128Swpaul#else
111750128Swpaul        mtag = VLAN_OUTPUT_TAG(ifp, m_head);
111887846Sluigi#endif
111950128Swpaul
112050128Swpaul        i = adapter->next_avail_tx_desc;
112150128Swpaul        for (j = 0; j < q.nsegs; j++) {
112250128Swpaul                tx_buffer = &adapter->tx_buffer_area[i];
112350128Swpaul                current_tx_desc = &adapter->tx_desc_base[i];
112450128Swpaul
112550128Swpaul                current_tx_desc->buffer_addr = htole64(q.segs[j].ds_addr);
112650128Swpaul                current_tx_desc->lower.data = htole32(
112750128Swpaul                        adapter->txd_cmd | txd_lower | q.segs[j].ds_len);
112850128Swpaul                current_tx_desc->upper.data = htole32(txd_upper);
112950128Swpaul
113050128Swpaul                if (++i == adapter->num_tx_desc)
113150128Swpaul                        i = 0;
113250128Swpaul
113350128Swpaul                tx_buffer->m_head = NULL;
113450128Swpaul        }
113550128Swpaul
113650128Swpaul        adapter->num_tx_desc_avail -= q.nsegs;
1137101493Sambrisko        adapter->next_avail_tx_desc = i;
113850128Swpaul
113950128Swpaul#if __FreeBSD_version < 500000
114050128Swpaul        if (ifv != NULL) {
114150128Swpaul                /* Set the vlan id */
114250128Swpaul                current_tx_desc->upper.fields.special = htole16(ifv->ifv_tag);
114350128Swpaul#else
114450128Swpaul        if (mtag != NULL) {
114550128Swpaul                /* Set the vlan id */
114650128Swpaul                current_tx_desc->upper.fields.special = htole16(VLAN_TAG_VALUE(mtag));
114750128Swpaul#endif
114850128Swpaul
114950128Swpaul                /* Tell hardware to add tag */
115050128Swpaul                current_tx_desc->lower.data |= htole32(E1000_TXD_CMD_VLE);
115150128Swpaul        }
115250128Swpaul
115350128Swpaul        tx_buffer->m_head = m_head;
115450128Swpaul        tx_buffer->map = q.map;
115550128Swpaul        bus_dmamap_sync(adapter->txtag, q.map, BUS_DMASYNC_PREWRITE);
115650128Swpaul
115750128Swpaul        /*
115850128Swpaul         * Last Descriptor of Packet needs End Of Packet (EOP)
115950128Swpaul         */
116050128Swpaul        current_tx_desc->lower.data |= htole32(E1000_TXD_CMD_EOP);
116150128Swpaul
116250128Swpaul        /*
116350128Swpaul         * Advance the Transmit Descriptor Tail (Tdt), this tells the E1000
116450128Swpaul         * that this frame is available to transmit.
116550128Swpaul         */
116650128Swpaul        if (adapter->hw.mac_type == em_82547 &&
1167101493Sambrisko            adapter->link_duplex == HALF_DUPLEX) {
116850128Swpaul                em_82547_move_tail(adapter);
116950128Swpaul        } else {
117050128Swpaul                E1000_WRITE_REG(&adapter->hw, TDT, i);
117150128Swpaul                if (adapter->hw.mac_type == em_82547) {
117250128Swpaul                        em_82547_update_fifo_head(adapter, m_head->m_pkthdr.len);
117350128Swpaul                }
117450128Swpaul        }
117550128Swpaul
117650128Swpaul        return(0);
117750128Swpaul}
117850128Swpaul
117950128Swpaul/*********************************************************************
118050128Swpaul *
118150128Swpaul * 82547 workaround to avoid controller hang in half-duplex environment.
118250128Swpaul * The workaround is to avoid queuing a large packet that would span
118350128Swpaul * the internal Tx FIFO ring boundary. We need to reset the FIFO pointers
118450128Swpaul * in this case. We do that only when FIFO is queiced.
118550128Swpaul *
1186101493Sambrisko **********************************************************************/
1187101493Sambriskostatic void
118854268Swpaulem_82547_move_tail(void *arg)
118950128Swpaul{
119054268Swpaul	int s;
119154268Swpaul	struct adapter *adapter = arg;
119250128Swpaul	uint16_t hw_tdt;
119350128Swpaul	uint16_t sw_tdt;
119450128Swpaul	struct em_tx_desc *tx_desc;
119554268Swpaul	uint16_t length = 0;
119654268Swpaul	boolean_t eop = 0;
119754268Swpaul
119854268Swpaul	s = splimp();
119954268Swpaul	hw_tdt = E1000_READ_REG(&adapter->hw, TDT);
120054268Swpaul	sw_tdt = adapter->next_avail_tx_desc;
120150128Swpaul
120250128Swpaul	while (hw_tdt != sw_tdt) {
120354268Swpaul		tx_desc = &adapter->tx_desc_base[hw_tdt];
120454268Swpaul		length += tx_desc->lower.flags.length;
120554268Swpaul		eop = tx_desc->lower.data & E1000_TXD_CMD_EOP;
120654268Swpaul		if(++hw_tdt == adapter->num_tx_desc)
120750128Swpaul			hw_tdt = 0;
120850128Swpaul
120950128Swpaul		if(eop) {
121050128Swpaul			if (em_82547_fifo_workaround(adapter, length)) {
121150128Swpaul				adapter->tx_fifo_wrk++;
121250128Swpaul				adapter->tx_fifo_timer_handle =
121350128Swpaul					timeout(em_82547_move_tail,
121467089Swpaul						adapter, 1);
121550128Swpaul				splx(s);
121650128Swpaul				return;
121750128Swpaul			}
121850128Swpaul			else {
121967089Swpaul				E1000_WRITE_REG(&adapter->hw, TDT, hw_tdt);
122050128Swpaul				em_82547_update_fifo_head(adapter, length);
122150128Swpaul				length = 0;
122250128Swpaul			}
122350128Swpaul		}
122450128Swpaul	}
122550128Swpaul	splx(s);
122650128Swpaul	return;
122750128Swpaul}
122850128Swpaul
122950128Swpaulstatic int
123050128Swpaulem_82547_fifo_workaround(struct adapter *adapter, int len)
123150128Swpaul{
123250128Swpaul	int fifo_space, fifo_pkt_len;
123350128Swpaul
123450128Swpaul	fifo_pkt_len = EM_ROUNDUP(len + EM_FIFO_HDR, EM_FIFO_HDR);
123567089Swpaul
123650128Swpaul	if (adapter->link_duplex == HALF_DUPLEX) {
123750128Swpaul		fifo_space = EM_82547_TX_FIFO_SIZE - adapter->tx_fifo_head;
123850128Swpaul
1239101493Sambrisko		if (fifo_pkt_len >= (EM_82547_PKT_THRESH + fifo_space)) {
1240101493Sambrisko			if (em_82547_tx_fifo_reset(adapter)) {
1241101493Sambrisko				return(0);
124250128Swpaul			}
124350128Swpaul			else {
124450128Swpaul				return(1);
124550128Swpaul			}
124650128Swpaul		}
124750128Swpaul	}
124850128Swpaul
124950128Swpaul	return(0);
125050128Swpaul}
125150128Swpaul
125250128Swpaulstatic void
125350128Swpaulem_82547_update_fifo_head(struct adapter *adapter, int len)
125450128Swpaul{
125550128Swpaul	int fifo_pkt_len = EM_ROUNDUP(len + EM_FIFO_HDR, EM_FIFO_HDR);
125650128Swpaul
125750128Swpaul	/* tx_fifo_head is always 16 byte aligned */
125850128Swpaul	adapter->tx_fifo_head += fifo_pkt_len;
125950128Swpaul	if (adapter->tx_fifo_head >= EM_82547_TX_FIFO_SIZE) {
126050128Swpaul		adapter->tx_fifo_head -= EM_82547_TX_FIFO_SIZE;
126150128Swpaul	}
126250128Swpaul
126350128Swpaul	return;
126450128Swpaul}
126550128Swpaul
126650128Swpaul
126750128Swpaulstatic int
126850128Swpaulem_82547_tx_fifo_reset(struct adapter *adapter)
126950128Swpaul{
127050128Swpaul	uint32_t tctl;
127150128Swpaul
127250128Swpaul	if ( (E1000_READ_REG(&adapter->hw, TDT) ==
127350128Swpaul	      E1000_READ_REG(&adapter->hw, TDH)) &&
127450128Swpaul	     (E1000_READ_REG(&adapter->hw, TDFT) ==
127550128Swpaul	      E1000_READ_REG(&adapter->hw, TDFH)) &&
127650128Swpaul	     (E1000_READ_REG(&adapter->hw, TDFTS) ==
127750128Swpaul	      E1000_READ_REG(&adapter->hw, TDFHS)) &&
127850128Swpaul	     (E1000_READ_REG(&adapter->hw, TDFPC) == 0)) {
127950128Swpaul
128050128Swpaul		/* Disable TX unit */
1281101493Sambrisko		tctl = E1000_READ_REG(&adapter->hw, TCTL);
1282101493Sambrisko		E1000_WRITE_REG(&adapter->hw, TCTL, tctl & ~E1000_TCTL_EN);
128354268Swpaul
128454268Swpaul		/* Reset FIFO pointers */
128554268Swpaul		E1000_WRITE_REG(&adapter->hw, TDFT, EM_82547_TX_FIFO_BEGIN);
128654268Swpaul		E1000_WRITE_REG(&adapter->hw, TDFH, EM_82547_TX_FIFO_BEGIN);
1287101493Sambrisko		E1000_WRITE_REG(&adapter->hw, TDFTS, EM_82547_TX_FIFO_BEGIN);
128854268Swpaul		E1000_WRITE_REG(&adapter->hw, TDFHS, EM_82547_TX_FIFO_BEGIN);
128954268Swpaul
129054268Swpaul		/* Re-enable TX unit */
1291101493Sambrisko		E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
129254268Swpaul		E1000_WRITE_FLUSH(&adapter->hw);
129350128Swpaul
129450128Swpaul		adapter->tx_fifo_head = 0;
1295101493Sambrisko		adapter->tx_fifo_reset++;
129650128Swpaul
129750128Swpaul		return(TRUE);
129850128Swpaul	}
129950128Swpaul	else {
130050128Swpaul		return(FALSE);
130150128Swpaul	}
130250128Swpaul}
130350128Swpaul
130450128Swpaulstatic void
130550128Swpaulem_set_promisc(struct adapter * adapter)
1306101493Sambrisko{
1307101493Sambrisko
1308101493Sambrisko	u_int32_t       reg_rctl;
130954268Swpaul	struct ifnet   *ifp = &adapter->interface_data.ac_if;
131050128Swpaul
131150128Swpaul	reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
131250128Swpaul
131350128Swpaul	if (ifp->if_flags & IFF_PROMISC) {
131450128Swpaul		reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
131567089Swpaul		E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
131650128Swpaul	} else if (ifp->if_flags & IFF_ALLMULTI) {
131750128Swpaul		reg_rctl |= E1000_RCTL_MPE;
131850128Swpaul		reg_rctl &= ~E1000_RCTL_UPE;
131950128Swpaul		E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
132050128Swpaul	}
132150128Swpaul
132250128Swpaul	return;
132350128Swpaul}
132450128Swpaul
132550128Swpaulstatic void
132667089Swpaulem_disable_promisc(struct adapter * adapter)
132750128Swpaul{
132850128Swpaul	u_int32_t       reg_rctl;
132950128Swpaul
133050128Swpaul	reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
133150128Swpaul
133250128Swpaul	reg_rctl &=  (~E1000_RCTL_UPE);
133350128Swpaul	reg_rctl &=  (~E1000_RCTL_MPE);
133450128Swpaul	E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
133550128Swpaul
133650128Swpaul	return;
133750128Swpaul}
1338101493Sambrisko
1339101493Sambrisko
1340101493Sambrisko/*********************************************************************
1341101493Sambrisko *  Multicast Update
1342101493Sambrisko *
134350128Swpaul *  This routine is called whenever multicast address list is updated.
134454268Swpaul *
134554268Swpaul **********************************************************************/
134650128Swpaul
134750128Swpaulstatic void
134850128Swpaulem_set_multi(struct adapter * adapter)
134950128Swpaul{
135050128Swpaul        u_int32_t reg_rctl = 0;
135150128Swpaul        u_int8_t  mta[MAX_NUM_MULTICAST_ADDRESSES * ETH_LENGTH_OF_ADDRESS];
135250128Swpaul        struct ifmultiaddr  *ifma;
135350128Swpaul        int mcnt = 0;
135450128Swpaul        struct ifnet   *ifp = &adapter->interface_data.ac_if;
135550128Swpaul
135650128Swpaul        IOCTL_DEBUGOUT("em_set_multi: begin");
135750128Swpaul
135850128Swpaul        if (adapter->hw.mac_type == em_82542_rev2_0) {
135950128Swpaul                reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
1360101493Sambrisko                if (adapter->hw.pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
1361101493Sambrisko                        em_pci_clear_mwi(&adapter->hw);
136250128Swpaul                }
136367089Swpaul                reg_rctl |= E1000_RCTL_RST;
136450128Swpaul                E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
136550128Swpaul                msec_delay(5);
136650128Swpaul        }
136750128Swpaul
136850128Swpaul#if __FreeBSD_version < 500000
136950128Swpaul        LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
137050128Swpaul#else
137150128Swpaul        TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
137250128Swpaul#endif
137350128Swpaul                if (ifma->ifma_addr->sa_family != AF_LINK)
137450128Swpaul                        continue;
137550128Swpaul
137650128Swpaul		if (mcnt == MAX_NUM_MULTICAST_ADDRESSES) break;
137750128Swpaul
137850128Swpaul                bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
137950128Swpaul                      &mta[mcnt*ETH_LENGTH_OF_ADDRESS], ETH_LENGTH_OF_ADDRESS);
138050128Swpaul                mcnt++;
138150128Swpaul        }
138250128Swpaul
138350128Swpaul        if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) {
138450128Swpaul                reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
138550128Swpaul                reg_rctl |= E1000_RCTL_MPE;
138650128Swpaul                E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
138750128Swpaul        } else
138850128Swpaul                em_mc_addr_list_update(&adapter->hw, mta, mcnt, 0);
138950128Swpaul
139050128Swpaul        if (adapter->hw.mac_type == em_82542_rev2_0) {
139150128Swpaul                reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
139250128Swpaul                reg_rctl &= ~E1000_RCTL_RST;
139350128Swpaul                E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
139450128Swpaul                msec_delay(5);
139550128Swpaul                if (adapter->hw.pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
139650128Swpaul                        em_pci_set_mwi(&adapter->hw);
139750128Swpaul                }
139850128Swpaul        }
139950128Swpaul
140050128Swpaul        return;
140167089Swpaul}
140250128Swpaul
140350128Swpaul
140467089Swpaul/*********************************************************************
140550128Swpaul *  Timer routine
140650128Swpaul *
140750128Swpaul *  This routine checks for link status and updates statistics.
140850128Swpaul *
140950128Swpaul **********************************************************************/
141050128Swpaul
141150128Swpaulstatic void
141250128Swpaulem_local_timer(void *arg)
141350128Swpaul{
141450128Swpaul	int s;
141554268Swpaul	struct ifnet   *ifp;
141654268Swpaul	struct adapter * adapter = arg;
141754268Swpaul	ifp = &adapter->interface_data.ac_if;
141854268Swpaul
141954268Swpaul	s = splimp();
142054268Swpaul
142154268Swpaul	em_check_for_link(&adapter->hw);
142254268Swpaul	em_print_link_status(adapter);
142354268Swpaul	em_update_stats_counters(adapter);
142454268Swpaul	if (em_display_debug_stats && ifp->if_flags & IFF_RUNNING) {
1425101493Sambrisko		em_print_hw_stats(adapter);
1426101493Sambrisko	}
1427101493Sambrisko	em_smartspeed(adapter);
1428101493Sambrisko
142954268Swpaul	adapter->timer_handle = timeout(em_local_timer, adapter, 2*hz);
143054268Swpaul
143150128Swpaul	splx(s);
143250128Swpaul	return;
143350128Swpaul}
143450128Swpaul
143554268Swpaulstatic void
143650128Swpaulem_print_link_status(struct adapter * adapter)
143750128Swpaul{
143850128Swpaul	if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU) {
143950128Swpaul		if (adapter->link_active == 0) {
144050128Swpaul			em_get_speed_and_duplex(&adapter->hw,
144150128Swpaul						&adapter->link_speed,
144250128Swpaul						&adapter->link_duplex);
144350128Swpaul			printf("em%d: Link is up %d Mbps %s\n",
144450128Swpaul			       adapter->unit,
144550128Swpaul			       adapter->link_speed,
144650128Swpaul			       ((adapter->link_duplex == FULL_DUPLEX) ?
144750128Swpaul				"Full Duplex" : "Half Duplex"));
144850128Swpaul			adapter->link_active = 1;
144950128Swpaul			adapter->smartspeed = 0;
145050128Swpaul		}
145150128Swpaul	} else {
145250128Swpaul		if (adapter->link_active == 1) {
145367089Swpaul			adapter->link_speed = 0;
145450128Swpaul			adapter->link_duplex = 0;
145550128Swpaul			printf("em%d: Link is Down\n", adapter->unit);
145650128Swpaul			adapter->link_active = 0;
145750128Swpaul		}
145850128Swpaul	}
145950128Swpaul
146050128Swpaul	return;
146150128Swpaul}
146250128Swpaul
146350128Swpaul/*********************************************************************
146450128Swpaul *
146550128Swpaul *  This routine disables all traffic on the adapter by issuing a
146654268Swpaul *  global reset on the MAC and deallocates TX/RX buffers.
146754268Swpaul *
146850128Swpaul **********************************************************************/
146954268Swpaul
147054268Swpaulstatic void
147150128Swpaulem_stop(void *arg)
147250128Swpaul{
147350128Swpaul	struct ifnet   *ifp;
147450128Swpaul	struct adapter * adapter = arg;
147550128Swpaul	ifp = &adapter->interface_data.ac_if;
147650128Swpaul
1477101493Sambrisko	INIT_DEBUGOUT("em_stop: begin\n");
147850128Swpaul	em_disable_intr(adapter);
147950128Swpaul	em_reset_hw(&adapter->hw);
148050128Swpaul	untimeout(em_local_timer, adapter, adapter->timer_handle);
148150128Swpaul	untimeout(em_82547_move_tail, adapter,
148250128Swpaul		  adapter->tx_fifo_timer_handle);
148350128Swpaul	em_free_transmit_structures(adapter);
148450128Swpaul	em_free_receive_structures(adapter);
1485101493Sambrisko
1486101493Sambrisko
148750128Swpaul	/* Tell the stack that the interface is no longer active */
148850128Swpaul	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
148950128Swpaul
149050128Swpaul	return;
149150128Swpaul}
149250128Swpaul
149350128Swpaul
149450128Swpaul/*********************************************************************
149550128Swpaul *
1496101493Sambrisko *  Determine hardware revision.
149754268Swpaul *
149850128Swpaul **********************************************************************/
149950128Swpaulstatic void
150067089Swpaulem_identify_hardware(struct adapter * adapter)
150150128Swpaul{
150267089Swpaul	device_t dev = adapter->dev;
150367089Swpaul
150450128Swpaul	/* Make sure our PCI config space has the necessary stuff set */
150567089Swpaul	adapter->hw.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
150650128Swpaul	if (!((adapter->hw.pci_cmd_word & PCIM_CMD_BUSMASTEREN) &&
150767089Swpaul	      (adapter->hw.pci_cmd_word & PCIM_CMD_MEMEN))) {
150867089Swpaul		printf("em%d: Memory Access and/or Bus Master bits were not set!\n",
150954268Swpaul		       adapter->unit);
151067089Swpaul		adapter->hw.pci_cmd_word |=
151150128Swpaul		(PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
151254268Swpaul		pci_write_config(dev, PCIR_COMMAND, adapter->hw.pci_cmd_word, 2);
151354268Swpaul	}
151454268Swpaul
151554268Swpaul	/* Save off the information about this board */
151654268Swpaul	adapter->hw.vendor_id = pci_get_vendor(dev);
151754268Swpaul	adapter->hw.device_id = pci_get_device(dev);
151854268Swpaul	adapter->hw.revision_id = pci_read_config(dev, PCIR_REVID, 1);
151954268Swpaul	adapter->hw.subsystem_vendor_id = pci_read_config(dev, PCIR_SUBVEND_0, 2);
152054268Swpaul	adapter->hw.subsystem_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
152150128Swpaul
152250128Swpaul	/* Identify the MAC */
152350128Swpaul        if (em_set_mac_type(&adapter->hw))
152450128Swpaul                printf("em%d: Unknown MAC Type\n", adapter->unit);
152554268Swpaul
152650128Swpaul        return;
152750128Swpaul}
152850128Swpaul
1529101493Sambriskostatic int
153050128Swpaulem_allocate_pci_resources(struct adapter * adapter)
1531101493Sambrisko{
1532101493Sambrisko	int             i, val, rid;
1533101493Sambrisko	device_t        dev = adapter->dev;
1534101493Sambrisko
1535101493Sambrisko	rid = EM_MMBA;
1536101493Sambrisko	adapter->res_memory = bus_alloc_resource(dev, SYS_RES_MEMORY,
1537101493Sambrisko						 &rid, 0, ~0, 1,
1538101493Sambrisko						 RF_ACTIVE);
1539101493Sambrisko	if (!(adapter->res_memory)) {
1540101493Sambrisko		printf("em%d: Unable to allocate bus resource: memory\n",
1541101493Sambrisko		       adapter->unit);
1542101493Sambrisko		return(ENXIO);
1543101493Sambrisko	}
1544101493Sambrisko	adapter->osdep.mem_bus_space_tag =
1545101493Sambrisko	rman_get_bustag(adapter->res_memory);
1546101493Sambrisko	adapter->osdep.mem_bus_space_handle =
1547101493Sambrisko	rman_get_bushandle(adapter->res_memory);
1548101493Sambrisko	adapter->hw.hw_addr = (uint8_t *)&adapter->osdep.mem_bus_space_handle;
1549101493Sambrisko
1550101493Sambrisko
1551101493Sambrisko	if (adapter->hw.mac_type > em_82543) {
1552101493Sambrisko		/* Figure our where our IO BAR is ? */
1553101493Sambrisko		rid = EM_MMBA;
1554101493Sambrisko		for (i = 0; i < 5; i++) {
1555101493Sambrisko			val = pci_read_config(dev, rid, 4);
155650128Swpaul			if (val & 0x00000001) {
155754268Swpaul				adapter->io_rid = rid;
155850128Swpaul				break;
155950128Swpaul			}
156050128Swpaul			rid += 4;
156150128Swpaul		}
156254268Swpaul
156354268Swpaul		adapter->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
156454268Swpaul							 &adapter->io_rid, 0, ~0, 1,
1565101493Sambrisko							 RF_ACTIVE);
1566101493Sambrisko		if (!(adapter->res_ioport)) {
156750128Swpaul			printf("em%d: Unable to allocate bus resource: ioport\n",
156850128Swpaul			       adapter->unit);
156967089Swpaul			return(ENXIO);
157050128Swpaul		}
157150128Swpaul
157250128Swpaul		adapter->hw.io_base =
157350128Swpaul		rman_get_start(adapter->res_ioport);
157450128Swpaul	}
157550128Swpaul
157650128Swpaul	rid = 0x0;
157750128Swpaul	adapter->res_interrupt = bus_alloc_resource(dev, SYS_RES_IRQ,
157850128Swpaul						    &rid, 0, ~0, 1,
157950128Swpaul						    RF_SHAREABLE | RF_ACTIVE);
158067089Swpaul	if (!(adapter->res_interrupt)) {
158150128Swpaul		printf("em%d: Unable to allocate bus resource: interrupt\n",
158250128Swpaul		       adapter->unit);
158350128Swpaul		return(ENXIO);
158450128Swpaul	}
158550128Swpaul	if (bus_setup_intr(dev, adapter->res_interrupt, INTR_TYPE_NET,
158650128Swpaul			   (void (*)(void *)) em_intr, adapter,
158750128Swpaul			   &adapter->int_handler_tag)) {
158850128Swpaul		printf("em%d: Error registering interrupt handler!\n",
158950128Swpaul		       adapter->unit);
159050128Swpaul		return(ENXIO);
159150128Swpaul	}
159250128Swpaul
159367089Swpaul	adapter->hw.back = &adapter->osdep;
159450128Swpaul
159550128Swpaul	return(0);
159650128Swpaul}
159750128Swpaul
159850128Swpaulstatic void
159950128Swpaulem_free_pci_resources(struct adapter * adapter)
160050128Swpaul{
160150128Swpaul	device_t dev = adapter->dev;
160250128Swpaul
160350128Swpaul	if (adapter->res_interrupt != NULL) {
160450128Swpaul		bus_teardown_intr(dev, adapter->res_interrupt,
160550128Swpaul				  adapter->int_handler_tag);
160650128Swpaul		bus_release_resource(dev, SYS_RES_IRQ, 0,
160750128Swpaul				     adapter->res_interrupt);
160850128Swpaul	}
1609	if (adapter->res_memory != NULL) {
1610		bus_release_resource(dev, SYS_RES_MEMORY, EM_MMBA,
1611				     adapter->res_memory);
1612	}
1613
1614	if (adapter->res_ioport != NULL) {
1615		bus_release_resource(dev, SYS_RES_IOPORT, adapter->io_rid,
1616				     adapter->res_ioport);
1617	}
1618	return;
1619}
1620
1621/*********************************************************************
1622 *
1623 *  Initialize the hardware to a configuration as specified by the
1624 *  adapter structure. The controller is reset, the EEPROM is
1625 *  verified, the MAC address is set, then the shared initialization
1626 *  routines are called.
1627 *
1628 **********************************************************************/
1629static int
1630em_hardware_init(struct adapter * adapter)
1631{
1632	/* Issue a global reset */
1633	em_reset_hw(&adapter->hw);
1634
1635	/* When hardware is reset, fifo_head is also reset */
1636	adapter->tx_fifo_head = 0;
1637
1638	/* Make sure we have a good EEPROM before we read from it */
1639	if (em_validate_eeprom_checksum(&adapter->hw) < 0) {
1640		printf("em%d: The EEPROM Checksum Is Not Valid\n",
1641		       adapter->unit);
1642		return(EIO);
1643	}
1644
1645	if (em_read_part_num(&adapter->hw, &(adapter->part_num)) < 0) {
1646		printf("em%d: EEPROM read error while reading part number\n",
1647		       adapter->unit);
1648		return(EIO);
1649	}
1650
1651	if (em_init_hw(&adapter->hw) < 0) {
1652		printf("em%d: Hardware Initialization Failed",
1653		       adapter->unit);
1654		return(EIO);
1655	}
1656
1657	em_check_for_link(&adapter->hw);
1658	if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)
1659		adapter->link_active = 1;
1660	else
1661		adapter->link_active = 0;
1662
1663	if (adapter->link_active) {
1664		em_get_speed_and_duplex(&adapter->hw,
1665					&adapter->link_speed,
1666					&adapter->link_duplex);
1667	} else {
1668		adapter->link_speed = 0;
1669		adapter->link_duplex = 0;
1670	}
1671
1672	return(0);
1673}
1674
1675/*********************************************************************
1676 *
1677 *  Setup networking device structure and register an interface.
1678 *
1679 **********************************************************************/
1680static void
1681em_setup_interface(device_t dev, struct adapter * adapter)
1682{
1683	struct ifnet   *ifp;
1684	INIT_DEBUGOUT("em_setup_interface: begin");
1685
1686	ifp = &adapter->interface_data.ac_if;
1687	ifp->if_unit = adapter->unit;
1688	ifp->if_name = "em";
1689	ifp->if_mtu = ETHERMTU;
1690	ifp->if_output = ether_output;
1691	ifp->if_baudrate = 1000000000;
1692	ifp->if_init =  em_init;
1693	ifp->if_softc = adapter;
1694	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1695	ifp->if_ioctl = em_ioctl;
1696	ifp->if_start = em_start;
1697	ifp->if_watchdog = em_watchdog;
1698	ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 1;
1699
1700#if __FreeBSD_version < 500000
1701        ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
1702#else
1703        ether_ifattach(ifp, adapter->interface_data.ac_enaddr);
1704#endif
1705
1706	if (adapter->hw.mac_type >= em_82543) {
1707		ifp->if_capabilities = IFCAP_HWCSUM;
1708		ifp->if_capenable = ifp->if_capabilities;
1709	}
1710
1711	/*
1712	 * Tell the upper layer(s) we support long frames.
1713	 */
1714	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
1715#if __FreeBSD_version >= 500000
1716        ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
1717#endif
1718
1719
1720	/*
1721	 * Specify the media types supported by this adapter and register
1722	 * callbacks to update media and link information
1723	 */
1724	ifmedia_init(&adapter->media, IFM_IMASK, em_media_change,
1725		     em_media_status);
1726	if (adapter->hw.media_type == em_media_type_fiber) {
1727		ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX | IFM_FDX,
1728			    0, NULL);
1729		ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX,
1730			    0, NULL);
1731	} else {
1732		ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T, 0, NULL);
1733		ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T | IFM_FDX,
1734			    0, NULL);
1735		ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX,
1736			    0, NULL);
1737		ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX | IFM_FDX,
1738			    0, NULL);
1739#if __FreeBSD_version < 500000
1740		ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_TX | IFM_FDX,
1741			    0, NULL);
1742		ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_TX, 0, NULL);
1743#else
1744		ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T | IFM_FDX,
1745			    0, NULL);
1746		ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T, 0, NULL);
1747#endif
1748	}
1749	ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
1750	ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
1751
1752	return;
1753}
1754
1755
1756/*********************************************************************
1757 *
1758 *  Workaround for SmartSpeed on 82541 and 82547 controllers
1759 *
1760 **********************************************************************/
1761static void
1762em_smartspeed(struct adapter *adapter)
1763{
1764        uint16_t phy_tmp;
1765
1766	if(adapter->link_active || (adapter->hw.phy_type != em_phy_igp) ||
1767	   !adapter->hw.autoneg || !(adapter->hw.autoneg_advertised & ADVERTISE_1000_FULL))
1768		return;
1769
1770        if(adapter->smartspeed == 0) {
1771                /* If Master/Slave config fault is asserted twice,
1772                 * we assume back-to-back */
1773                em_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
1774                if(!(phy_tmp & SR_1000T_MS_CONFIG_FAULT)) return;
1775                em_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
1776                if(phy_tmp & SR_1000T_MS_CONFIG_FAULT) {
1777                        em_read_phy_reg(&adapter->hw, PHY_1000T_CTRL,
1778					&phy_tmp);
1779                        if(phy_tmp & CR_1000T_MS_ENABLE) {
1780                                phy_tmp &= ~CR_1000T_MS_ENABLE;
1781                                em_write_phy_reg(&adapter->hw,
1782                                                    PHY_1000T_CTRL, phy_tmp);
1783                                adapter->smartspeed++;
1784                                if(adapter->hw.autoneg &&
1785                                   !em_phy_setup_autoneg(&adapter->hw) &&
1786				   !em_read_phy_reg(&adapter->hw, PHY_CTRL,
1787                                                       &phy_tmp)) {
1788                                        phy_tmp |= (MII_CR_AUTO_NEG_EN |
1789                                                    MII_CR_RESTART_AUTO_NEG);
1790                                        em_write_phy_reg(&adapter->hw,
1791							 PHY_CTRL, phy_tmp);
1792                                }
1793                        }
1794                }
1795                return;
1796        } else if(adapter->smartspeed == EM_SMARTSPEED_DOWNSHIFT) {
1797                /* If still no link, perhaps using 2/3 pair cable */
1798                em_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_tmp);
1799                phy_tmp |= CR_1000T_MS_ENABLE;
1800                em_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_tmp);
1801                if(adapter->hw.autoneg &&
1802                   !em_phy_setup_autoneg(&adapter->hw) &&
1803                   !em_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_tmp)) {
1804                        phy_tmp |= (MII_CR_AUTO_NEG_EN |
1805                                    MII_CR_RESTART_AUTO_NEG);
1806                        em_write_phy_reg(&adapter->hw, PHY_CTRL, phy_tmp);
1807                }
1808        }
1809        /* Restart process after EM_SMARTSPEED_MAX iterations */
1810        if(adapter->smartspeed++ == EM_SMARTSPEED_MAX)
1811                adapter->smartspeed = 0;
1812
1813	return;
1814}
1815
1816
1817/*
1818 * Manage DMA'able memory.
1819 */
1820static void
1821em_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1822{
1823        if (error)
1824                return;
1825        *(bus_addr_t*) arg = segs->ds_addr;
1826        return;
1827}
1828
1829static int
1830em_dma_malloc(struct adapter *adapter, bus_size_t size,
1831        struct em_dma_alloc *dma, int mapflags)
1832{
1833        int r;
1834
1835        r = bus_dma_tag_create(NULL,                    /* parent */
1836                               PAGE_SIZE, 0,            /* alignment, bounds */
1837                               BUS_SPACE_MAXADDR,       /* lowaddr */
1838                               BUS_SPACE_MAXADDR,       /* highaddr */
1839                               NULL, NULL,              /* filter, filterarg */
1840                               size,                    /* maxsize */
1841                               1,                       /* nsegments */
1842                               size,                    /* maxsegsize */
1843                               BUS_DMA_ALLOCNOW,        /* flags */
1844			       NULL,			/* lockfunc */
1845			       NULL,			/* lockarg */
1846                               &dma->dma_tag);
1847        if (r != 0) {
1848                printf("em%d: em_dma_malloc: bus_dma_tag_create failed; "
1849                        "error %u\n", adapter->unit, r);
1850                goto fail_0;
1851        }
1852
1853        r = bus_dmamap_create(dma->dma_tag, BUS_DMA_NOWAIT, &dma->dma_map);
1854        if (r != 0) {
1855                printf("em%d: em_dma_malloc: bus_dmamap_create failed; "
1856                        "error %u\n", adapter->unit, r);
1857                goto fail_1;
1858        }
1859
1860        r = bus_dmamem_alloc(dma->dma_tag, (void**) &dma->dma_vaddr,
1861                             BUS_DMA_NOWAIT, &dma->dma_map);
1862        if (r != 0) {
1863                printf("em%d: em_dma_malloc: bus_dmammem_alloc failed; "
1864                        "size %ju, error %d\n", adapter->unit,
1865			(uintmax_t)size, r);
1866                goto fail_2;
1867        }
1868
1869        r = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr,
1870                            size,
1871                            em_dmamap_cb,
1872                            &dma->dma_paddr,
1873                            mapflags | BUS_DMA_NOWAIT);
1874        if (r != 0) {
1875                printf("em%d: em_dma_malloc: bus_dmamap_load failed; "
1876                        "error %u\n", adapter->unit, r);
1877                goto fail_3;
1878        }
1879
1880        dma->dma_size = size;
1881        return (0);
1882
1883fail_3:
1884        bus_dmamap_unload(dma->dma_tag, dma->dma_map);
1885fail_2:
1886        bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
1887fail_1:
1888        bus_dmamap_destroy(dma->dma_tag, dma->dma_map);
1889        bus_dma_tag_destroy(dma->dma_tag);
1890fail_0:
1891        dma->dma_map = NULL;
1892        dma->dma_tag = NULL;
1893        return (r);
1894}
1895
1896static void
1897em_dma_free(struct adapter *adapter, struct em_dma_alloc *dma)
1898{
1899        bus_dmamap_unload(dma->dma_tag, dma->dma_map);
1900        bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
1901        bus_dmamap_destroy(dma->dma_tag, dma->dma_map);
1902        bus_dma_tag_destroy(dma->dma_tag);
1903}
1904
1905
1906/*********************************************************************
1907 *
1908 *  Allocate memory for tx_buffer structures. The tx_buffer stores all
1909 *  the information needed to transmit a packet on the wire.
1910 *
1911 **********************************************************************/
1912static int
1913em_allocate_transmit_structures(struct adapter * adapter)
1914{
1915	if (!(adapter->tx_buffer_area =
1916	      (struct em_buffer *) malloc(sizeof(struct em_buffer) *
1917					     adapter->num_tx_desc, M_DEVBUF,
1918					     M_NOWAIT))) {
1919		printf("em%d: Unable to allocate tx_buffer memory\n",
1920		       adapter->unit);
1921		return ENOMEM;
1922	}
1923
1924	bzero(adapter->tx_buffer_area,
1925	      sizeof(struct em_buffer) * adapter->num_tx_desc);
1926
1927	return 0;
1928}
1929
1930/*********************************************************************
1931 *
1932 *  Allocate and initialize transmit structures.
1933 *
1934 **********************************************************************/
1935static int
1936em_setup_transmit_structures(struct adapter * adapter)
1937{
1938        /*
1939         * Setup DMA descriptor areas.
1940         */
1941        if (bus_dma_tag_create(NULL,                    /* parent */
1942                               PAGE_SIZE, 0,            /* alignment, bounds */
1943                               BUS_SPACE_MAXADDR,       /* lowaddr */
1944                               BUS_SPACE_MAXADDR,       /* highaddr */
1945                               NULL, NULL,              /* filter, filterarg */
1946                               MCLBYTES * 8,            /* maxsize */
1947                               EM_MAX_SCATTER,          /* nsegments */
1948                               MCLBYTES * 8,            /* maxsegsize */
1949                               BUS_DMA_ALLOCNOW,        /* flags */
1950			       NULL,			/* lockfunc */
1951			       NULL,			/* lockarg */
1952                               &adapter->txtag)) {
1953                printf("em%d: Unable to allocate TX DMA tag\n", adapter->unit);
1954                return (ENOMEM);
1955        }
1956
1957        if (em_allocate_transmit_structures(adapter))
1958                return (ENOMEM);
1959
1960        bzero((void *) adapter->tx_desc_base,
1961              (sizeof(struct em_tx_desc)) * adapter->num_tx_desc);
1962
1963        adapter->next_avail_tx_desc = 0;
1964        adapter->oldest_used_tx_desc = 0;
1965
1966        /* Set number of descriptors available */
1967        adapter->num_tx_desc_avail = adapter->num_tx_desc;
1968
1969        /* Set checksum context */
1970        adapter->active_checksum_context = OFFLOAD_NONE;
1971
1972        return (0);
1973}
1974
1975/*********************************************************************
1976 *
1977 *  Enable transmit unit.
1978 *
1979 **********************************************************************/
1980static void
1981em_initialize_transmit_unit(struct adapter * adapter)
1982{
1983	u_int32_t       reg_tctl;
1984	u_int32_t       reg_tipg = 0;
1985	u_int64_t	bus_addr;
1986
1987	/* Setup the Base and Length of the Tx Descriptor Ring */
1988	bus_addr = adapter->txdma.dma_paddr;
1989	E1000_WRITE_REG(&adapter->hw, TDBAL, (u_int32_t)bus_addr);
1990	E1000_WRITE_REG(&adapter->hw, TDBAH, (u_int32_t)(bus_addr >> 32));
1991	E1000_WRITE_REG(&adapter->hw, TDLEN,
1992			adapter->num_tx_desc *
1993			sizeof(struct em_tx_desc));
1994
1995	/* Setup the HW Tx Head and Tail descriptor pointers */
1996	E1000_WRITE_REG(&adapter->hw, TDH, 0);
1997	E1000_WRITE_REG(&adapter->hw, TDT, 0);
1998
1999
2000	HW_DEBUGOUT2("Base = %x, Length = %x\n",
2001		     E1000_READ_REG(&adapter->hw, TDBAL),
2002		     E1000_READ_REG(&adapter->hw, TDLEN));
2003
2004	/* Set the default values for the Tx Inter Packet Gap timer */
2005	switch (adapter->hw.mac_type) {
2006	case em_82542_rev2_0:
2007        case em_82542_rev2_1:
2008                reg_tipg = DEFAULT_82542_TIPG_IPGT;
2009                reg_tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
2010                reg_tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
2011                break;
2012        default:
2013                if (adapter->hw.media_type == em_media_type_fiber)
2014                        reg_tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
2015                else
2016                        reg_tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
2017                reg_tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
2018                reg_tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
2019        }
2020
2021	E1000_WRITE_REG(&adapter->hw, TIPG, reg_tipg);
2022	E1000_WRITE_REG(&adapter->hw, TIDV, adapter->tx_int_delay.value);
2023	if(adapter->hw.mac_type >= em_82540)
2024		E1000_WRITE_REG(&adapter->hw, TADV,
2025		    adapter->tx_abs_int_delay.value);
2026
2027	/* Program the Transmit Control Register */
2028	reg_tctl = E1000_TCTL_PSP | E1000_TCTL_EN |
2029		   (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
2030	if (adapter->link_duplex == 1) {
2031		reg_tctl |= E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT;
2032	} else {
2033		reg_tctl |= E1000_HDX_COLLISION_DISTANCE << E1000_COLD_SHIFT;
2034	}
2035	E1000_WRITE_REG(&adapter->hw, TCTL, reg_tctl);
2036
2037	/* Setup Transmit Descriptor Settings for this adapter */
2038	adapter->txd_cmd = E1000_TXD_CMD_IFCS | E1000_TXD_CMD_RS;
2039
2040	if (adapter->tx_int_delay.value > 0)
2041		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
2042
2043	return;
2044}
2045
2046/*********************************************************************
2047 *
2048 *  Free all transmit related data structures.
2049 *
2050 **********************************************************************/
2051static void
2052em_free_transmit_structures(struct adapter * adapter)
2053{
2054        struct em_buffer   *tx_buffer;
2055        int             i;
2056
2057        INIT_DEBUGOUT("free_transmit_structures: begin");
2058
2059        if (adapter->tx_buffer_area != NULL) {
2060                tx_buffer = adapter->tx_buffer_area;
2061                for (i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
2062                        if (tx_buffer->m_head != NULL) {
2063                                bus_dmamap_unload(adapter->txtag, tx_buffer->map);
2064                                bus_dmamap_destroy(adapter->txtag, tx_buffer->map);
2065                                m_freem(tx_buffer->m_head);
2066                        }
2067                        tx_buffer->m_head = NULL;
2068                }
2069        }
2070        if (adapter->tx_buffer_area != NULL) {
2071                free(adapter->tx_buffer_area, M_DEVBUF);
2072                adapter->tx_buffer_area = NULL;
2073        }
2074        if (adapter->txtag != NULL) {
2075                bus_dma_tag_destroy(adapter->txtag);
2076                adapter->txtag = NULL;
2077        }
2078        return;
2079}
2080
2081/*********************************************************************
2082 *
2083 *  The offload context needs to be set when we transfer the first
2084 *  packet of a particular protocol (TCP/UDP). We change the
2085 *  context only if the protocol type changes.
2086 *
2087 **********************************************************************/
2088static void
2089em_transmit_checksum_setup(struct adapter * adapter,
2090			   struct mbuf *mp,
2091			   u_int32_t *txd_upper,
2092			   u_int32_t *txd_lower)
2093{
2094	struct em_context_desc *TXD;
2095	struct em_buffer *tx_buffer;
2096	int curr_txd;
2097
2098	if (mp->m_pkthdr.csum_flags) {
2099
2100		if (mp->m_pkthdr.csum_flags & CSUM_TCP) {
2101			*txd_upper = E1000_TXD_POPTS_TXSM << 8;
2102			*txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
2103			if (adapter->active_checksum_context == OFFLOAD_TCP_IP)
2104				return;
2105			else
2106				adapter->active_checksum_context = OFFLOAD_TCP_IP;
2107
2108		} else if (mp->m_pkthdr.csum_flags & CSUM_UDP) {
2109			*txd_upper = E1000_TXD_POPTS_TXSM << 8;
2110			*txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
2111			if (adapter->active_checksum_context == OFFLOAD_UDP_IP)
2112				return;
2113			else
2114				adapter->active_checksum_context = OFFLOAD_UDP_IP;
2115		} else {
2116			*txd_upper = 0;
2117			*txd_lower = 0;
2118			return;
2119		}
2120	} else {
2121		*txd_upper = 0;
2122		*txd_lower = 0;
2123		return;
2124	}
2125
2126	/* If we reach this point, the checksum offload context
2127	 * needs to be reset.
2128	 */
2129	curr_txd = adapter->next_avail_tx_desc;
2130	tx_buffer = &adapter->tx_buffer_area[curr_txd];
2131	TXD = (struct em_context_desc *) &adapter->tx_desc_base[curr_txd];
2132
2133	TXD->lower_setup.ip_fields.ipcss = ETHER_HDR_LEN;
2134	TXD->lower_setup.ip_fields.ipcso =
2135		ETHER_HDR_LEN + offsetof(struct ip, ip_sum);
2136	TXD->lower_setup.ip_fields.ipcse =
2137		htole16(ETHER_HDR_LEN + sizeof(struct ip) - 1);
2138
2139	TXD->upper_setup.tcp_fields.tucss =
2140		ETHER_HDR_LEN + sizeof(struct ip);
2141	TXD->upper_setup.tcp_fields.tucse = htole16(0);
2142
2143	if (adapter->active_checksum_context == OFFLOAD_TCP_IP) {
2144		TXD->upper_setup.tcp_fields.tucso =
2145			ETHER_HDR_LEN + sizeof(struct ip) +
2146			offsetof(struct tcphdr, th_sum);
2147	} else if (adapter->active_checksum_context == OFFLOAD_UDP_IP) {
2148		TXD->upper_setup.tcp_fields.tucso =
2149			ETHER_HDR_LEN + sizeof(struct ip) +
2150			offsetof(struct udphdr, uh_sum);
2151	}
2152
2153	TXD->tcp_seg_setup.data = htole32(0);
2154	TXD->cmd_and_length = htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT);
2155
2156	tx_buffer->m_head = NULL;
2157
2158	if (++curr_txd == adapter->num_tx_desc)
2159		curr_txd = 0;
2160
2161	adapter->num_tx_desc_avail--;
2162	adapter->next_avail_tx_desc = curr_txd;
2163
2164	return;
2165}
2166
2167/**********************************************************************
2168 *
2169 *  Examine each tx_buffer in the used queue. If the hardware is done
2170 *  processing the packet then free associated resources. The
2171 *  tx_buffer is put back on the free queue.
2172 *
2173 **********************************************************************/
2174static void
2175em_clean_transmit_interrupts(struct adapter * adapter)
2176{
2177        int s;
2178        int i, num_avail;
2179        struct em_buffer *tx_buffer;
2180        struct em_tx_desc   *tx_desc;
2181	struct ifnet   *ifp = &adapter->interface_data.ac_if;
2182
2183        if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
2184                return;
2185
2186        s = splimp();
2187#ifdef DBG_STATS
2188        adapter->clean_tx_interrupts++;
2189#endif
2190        num_avail = adapter->num_tx_desc_avail;
2191        i = adapter->oldest_used_tx_desc;
2192
2193        tx_buffer = &adapter->tx_buffer_area[i];
2194        tx_desc = &adapter->tx_desc_base[i];
2195
2196        while (tx_desc->upper.fields.status & E1000_TXD_STAT_DD) {
2197
2198                tx_desc->upper.data = 0;
2199                num_avail++;
2200
2201                if (tx_buffer->m_head) {
2202			ifp->if_opackets++;
2203                        bus_dmamap_sync(adapter->txtag, tx_buffer->map,
2204                                        BUS_DMASYNC_POSTWRITE);
2205                        bus_dmamap_unload(adapter->txtag, tx_buffer->map);
2206                        bus_dmamap_destroy(adapter->txtag, tx_buffer->map);
2207
2208                        m_freem(tx_buffer->m_head);
2209                        tx_buffer->m_head = NULL;
2210                }
2211
2212                if (++i == adapter->num_tx_desc)
2213                        i = 0;
2214
2215                tx_buffer = &adapter->tx_buffer_area[i];
2216                tx_desc = &adapter->tx_desc_base[i];
2217        }
2218
2219        adapter->oldest_used_tx_desc = i;
2220
2221        /*
2222         * If we have enough room, clear IFF_OACTIVE to tell the stack
2223         * that it is OK to send packets.
2224         * If there are no pending descriptors, clear the timeout. Otherwise,
2225         * if some descriptors have been freed, restart the timeout.
2226         */
2227        if (num_avail > EM_TX_CLEANUP_THRESHOLD) {
2228                ifp->if_flags &= ~IFF_OACTIVE;
2229                if (num_avail == adapter->num_tx_desc)
2230                        ifp->if_timer = 0;
2231                else if (num_avail == adapter->num_tx_desc_avail)
2232                        ifp->if_timer = EM_TX_TIMEOUT;
2233        }
2234        adapter->num_tx_desc_avail = num_avail;
2235        splx(s);
2236        return;
2237}
2238
2239/*********************************************************************
2240 *
2241 *  Get a buffer from system mbuf buffer pool.
2242 *
2243 **********************************************************************/
2244static int
2245em_get_buf(int i, struct adapter *adapter,
2246           struct mbuf *nmp)
2247{
2248        register struct mbuf    *mp = nmp;
2249        struct em_buffer *rx_buffer;
2250        struct ifnet   *ifp;
2251        bus_addr_t paddr;
2252        int error;
2253
2254        ifp = &adapter->interface_data.ac_if;
2255
2256        if (mp == NULL) {
2257                mp = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
2258                if (mp == NULL) {
2259                        adapter->mbuf_cluster_failed++;
2260                        return(ENOBUFS);
2261                }
2262                mp->m_len = mp->m_pkthdr.len = MCLBYTES;
2263        } else {
2264                mp->m_len = mp->m_pkthdr.len = MCLBYTES;
2265                mp->m_data = mp->m_ext.ext_buf;
2266                mp->m_next = NULL;
2267        }
2268
2269        if (ifp->if_mtu <= ETHERMTU) {
2270                m_adj(mp, ETHER_ALIGN);
2271        }
2272
2273        rx_buffer = &adapter->rx_buffer_area[i];
2274
2275        /*
2276         * Using memory from the mbuf cluster pool, invoke the
2277         * bus_dma machinery to arrange the memory mapping.
2278         */
2279        error = bus_dmamap_load(adapter->rxtag, rx_buffer->map,
2280                                mtod(mp, void *), mp->m_len,
2281                                em_dmamap_cb, &paddr, 0);
2282        if (error) {
2283                m_free(mp);
2284                return(error);
2285        }
2286        rx_buffer->m_head = mp;
2287        adapter->rx_desc_base[i].buffer_addr = htole64(paddr);
2288        bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD);
2289
2290        return(0);
2291}
2292
2293/*********************************************************************
2294 *
2295 *  Allocate memory for rx_buffer structures. Since we use one
2296 *  rx_buffer per received packet, the maximum number of rx_buffer's
2297 *  that we'll need is equal to the number of receive descriptors
2298 *  that we've allocated.
2299 *
2300 **********************************************************************/
2301static int
2302em_allocate_receive_structures(struct adapter * adapter)
2303{
2304        int             i, error;
2305        struct em_buffer *rx_buffer;
2306
2307        if (!(adapter->rx_buffer_area =
2308              (struct em_buffer *) malloc(sizeof(struct em_buffer) *
2309                                          adapter->num_rx_desc, M_DEVBUF,
2310                                          M_NOWAIT))) {
2311                printf("em%d: Unable to allocate rx_buffer memory\n",
2312                       adapter->unit);
2313                return(ENOMEM);
2314        }
2315
2316        bzero(adapter->rx_buffer_area,
2317              sizeof(struct em_buffer) * adapter->num_rx_desc);
2318
2319        error = bus_dma_tag_create(NULL,                /* parent */
2320                               PAGE_SIZE, 0,            /* alignment, bounds */
2321                               BUS_SPACE_MAXADDR,       /* lowaddr */
2322                               BUS_SPACE_MAXADDR,       /* highaddr */
2323                               NULL, NULL,              /* filter, filterarg */
2324                               MCLBYTES,                /* maxsize */
2325                               1,                       /* nsegments */
2326                               MCLBYTES,                /* maxsegsize */
2327                               BUS_DMA_ALLOCNOW,        /* flags */
2328			       NULL,			/* lockfunc */
2329			       NULL,			/* lockarg */
2330                               &adapter->rxtag);
2331        if (error != 0) {
2332                printf("em%d: em_allocate_receive_structures: "
2333                        "bus_dma_tag_create failed; error %u\n",
2334                       adapter->unit, error);
2335                goto fail_0;
2336        }
2337
2338        rx_buffer = adapter->rx_buffer_area;
2339        for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
2340                error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
2341                                          &rx_buffer->map);
2342                if (error != 0) {
2343                        printf("em%d: em_allocate_receive_structures: "
2344                                "bus_dmamap_create failed; error %u\n",
2345                                adapter->unit, error);
2346                        goto fail_1;
2347                }
2348        }
2349
2350        for (i = 0; i < adapter->num_rx_desc; i++) {
2351                error = em_get_buf(i, adapter, NULL);
2352                if (error != 0) {
2353                        adapter->rx_buffer_area[i].m_head = NULL;
2354                        adapter->rx_desc_base[i].buffer_addr = 0;
2355                        return(error);
2356                }
2357        }
2358
2359        return(0);
2360
2361fail_1:
2362        bus_dma_tag_destroy(adapter->rxtag);
2363fail_0:
2364        adapter->rxtag = NULL;
2365        free(adapter->rx_buffer_area, M_DEVBUF);
2366        adapter->rx_buffer_area = NULL;
2367        return (error);
2368}
2369
2370/*********************************************************************
2371 *
2372 *  Allocate and initialize receive structures.
2373 *
2374 **********************************************************************/
2375static int
2376em_setup_receive_structures(struct adapter * adapter)
2377{
2378	bzero((void *) adapter->rx_desc_base,
2379              (sizeof(struct em_rx_desc)) * adapter->num_rx_desc);
2380
2381	if (em_allocate_receive_structures(adapter))
2382		return ENOMEM;
2383
2384	/* Setup our descriptor pointers */
2385        adapter->next_rx_desc_to_check = 0;
2386	return(0);
2387}
2388
2389/*********************************************************************
2390 *
2391 *  Enable receive unit.
2392 *
2393 **********************************************************************/
2394static void
2395em_initialize_receive_unit(struct adapter * adapter)
2396{
2397	u_int32_t       reg_rctl;
2398	u_int32_t       reg_rxcsum;
2399	struct ifnet    *ifp;
2400	u_int64_t	bus_addr;
2401
2402	ifp = &adapter->interface_data.ac_if;
2403
2404	/* Make sure receives are disabled while setting up the descriptor ring */
2405	E1000_WRITE_REG(&adapter->hw, RCTL, 0);
2406
2407	/* Set the Receive Delay Timer Register */
2408	E1000_WRITE_REG(&adapter->hw, RDTR,
2409			adapter->rx_int_delay.value | E1000_RDT_FPDB);
2410
2411	if(adapter->hw.mac_type >= em_82540) {
2412		E1000_WRITE_REG(&adapter->hw, RADV,
2413		    adapter->rx_abs_int_delay.value);
2414
2415                /* Set the interrupt throttling rate.  Value is calculated
2416                 * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */
2417#define MAX_INTS_PER_SEC        8000
2418#define DEFAULT_ITR             1000000000/(MAX_INTS_PER_SEC * 256)
2419                E1000_WRITE_REG(&adapter->hw, ITR, DEFAULT_ITR);
2420        }
2421
2422	/* Setup the Base and Length of the Rx Descriptor Ring */
2423	bus_addr = adapter->rxdma.dma_paddr;
2424	E1000_WRITE_REG(&adapter->hw, RDBAL, (u_int32_t)bus_addr);
2425	E1000_WRITE_REG(&adapter->hw, RDBAH, (u_int32_t)(bus_addr >> 32));
2426	E1000_WRITE_REG(&adapter->hw, RDLEN, adapter->num_rx_desc *
2427			sizeof(struct em_rx_desc));
2428
2429	/* Setup the HW Rx Head and Tail Descriptor Pointers */
2430	E1000_WRITE_REG(&adapter->hw, RDH, 0);
2431	E1000_WRITE_REG(&adapter->hw, RDT, adapter->num_rx_desc - 1);
2432
2433	/* Setup the Receive Control Register */
2434	reg_rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
2435		   E1000_RCTL_RDMTS_HALF |
2436		   (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
2437
2438	if (adapter->hw.tbi_compatibility_on == TRUE)
2439		reg_rctl |= E1000_RCTL_SBP;
2440
2441
2442	switch (adapter->rx_buffer_len) {
2443	default:
2444	case EM_RXBUFFER_2048:
2445		reg_rctl |= E1000_RCTL_SZ_2048;
2446		break;
2447	case EM_RXBUFFER_4096:
2448		reg_rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
2449		break;
2450	case EM_RXBUFFER_8192:
2451		reg_rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
2452		break;
2453	case EM_RXBUFFER_16384:
2454		reg_rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
2455		break;
2456	}
2457
2458	if (ifp->if_mtu > ETHERMTU)
2459		reg_rctl |= E1000_RCTL_LPE;
2460
2461	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
2462	if ((adapter->hw.mac_type >= em_82543) &&
2463	    (ifp->if_capenable & IFCAP_RXCSUM)) {
2464		reg_rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM);
2465		reg_rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL);
2466		E1000_WRITE_REG(&adapter->hw, RXCSUM, reg_rxcsum);
2467	}
2468
2469	/* Enable Receives */
2470	E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
2471
2472	return;
2473}
2474
2475/*********************************************************************
2476 *
2477 *  Free receive related data structures.
2478 *
2479 **********************************************************************/
2480static void
2481em_free_receive_structures(struct adapter *adapter)
2482{
2483        struct em_buffer   *rx_buffer;
2484        int             i;
2485
2486        INIT_DEBUGOUT("free_receive_structures: begin");
2487
2488        if (adapter->rx_buffer_area != NULL) {
2489                rx_buffer = adapter->rx_buffer_area;
2490                for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
2491                        if (rx_buffer->map != NULL) {
2492                                bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
2493                                bus_dmamap_destroy(adapter->rxtag, rx_buffer->map);
2494                        }
2495                        if (rx_buffer->m_head != NULL)
2496                                m_freem(rx_buffer->m_head);
2497                        rx_buffer->m_head = NULL;
2498                }
2499        }
2500        if (adapter->rx_buffer_area != NULL) {
2501                free(adapter->rx_buffer_area, M_DEVBUF);
2502                adapter->rx_buffer_area = NULL;
2503        }
2504        if (adapter->rxtag != NULL) {
2505                bus_dma_tag_destroy(adapter->rxtag);
2506                adapter->rxtag = NULL;
2507        }
2508        return;
2509}
2510
2511/*********************************************************************
2512 *
2513 *  This routine executes in interrupt context. It replenishes
2514 *  the mbufs in the descriptor and sends data which has been
2515 *  dma'ed into host memory to upper layer.
2516 *
2517 *  We loop at most count times if count is > 0, or until done if
2518 *  count < 0.
2519 *
2520 *********************************************************************/
2521static void
2522em_process_receive_interrupts(struct adapter * adapter, int count)
2523{
2524	struct ifnet        *ifp;
2525	struct mbuf         *mp;
2526#if __FreeBSD_version < 500000
2527        struct ether_header *eh;
2528#endif
2529	u_int8_t            accept_frame = 0;
2530 	u_int8_t            eop = 0;
2531        u_int16_t           len, desc_len;
2532	int                 i;
2533
2534	/* Pointer to the receive descriptor being examined. */
2535	struct em_rx_desc   *current_desc;
2536
2537	ifp = &adapter->interface_data.ac_if;
2538	i = adapter->next_rx_desc_to_check;
2539        current_desc = &adapter->rx_desc_base[i];
2540
2541	if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
2542#ifdef DBG_STATS
2543		adapter->no_pkts_avail++;
2544#endif
2545		return;
2546	}
2547
2548	while ((current_desc->status & E1000_RXD_STAT_DD) && (count != 0)) {
2549
2550		mp = adapter->rx_buffer_area[i].m_head;
2551		bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map,
2552				BUS_DMASYNC_POSTREAD);
2553
2554		accept_frame = 1;
2555                desc_len = le16toh(current_desc->length);
2556		if (current_desc->status & E1000_RXD_STAT_EOP) {
2557			count--;
2558			eop = 1;
2559			len = desc_len - ETHER_CRC_LEN;
2560		} else {
2561			eop = 0;
2562			len = desc_len;
2563		}
2564
2565		if (current_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
2566			u_int8_t            last_byte;
2567			u_int32_t           pkt_len = desc_len;
2568
2569			if (adapter->fmp != NULL)
2570				pkt_len += adapter->fmp->m_pkthdr.len;
2571
2572			last_byte = *(mtod(mp, caddr_t) + desc_len - 1);
2573
2574			if (TBI_ACCEPT(&adapter->hw, current_desc->status,
2575				       current_desc->errors,
2576				       pkt_len, last_byte)) {
2577				em_tbi_adjust_stats(&adapter->hw,
2578						    &adapter->stats,
2579						    pkt_len,
2580						    adapter->hw.mac_addr);
2581				len--;
2582			}
2583			else {
2584				accept_frame = 0;
2585			}
2586		}
2587
2588		if (accept_frame) {
2589
2590			if (em_get_buf(i, adapter, NULL) == ENOBUFS) {
2591				adapter->dropped_pkts++;
2592				em_get_buf(i, adapter, mp);
2593				if (adapter->fmp != NULL)
2594					m_freem(adapter->fmp);
2595				adapter->fmp = NULL;
2596				adapter->lmp = NULL;
2597				break;
2598			}
2599
2600			/* Assign correct length to the current fragment */
2601			mp->m_len = len;
2602
2603			if (adapter->fmp == NULL) {
2604				mp->m_pkthdr.len = len;
2605				adapter->fmp = mp;	 /* Store the first mbuf */
2606				adapter->lmp = mp;
2607			} else {
2608				/* Chain mbuf's together */
2609				mp->m_flags &= ~M_PKTHDR;
2610				adapter->lmp->m_next = mp;
2611				adapter->lmp = adapter->lmp->m_next;
2612				adapter->fmp->m_pkthdr.len += len;
2613			}
2614
2615                        if (eop) {
2616                                adapter->fmp->m_pkthdr.rcvif = ifp;
2617                                 ifp->if_ipackets++;
2618
2619#if __FreeBSD_version < 500000
2620                                eh = mtod(adapter->fmp, struct ether_header *);
2621                                /* Remove ethernet header from mbuf */
2622                                m_adj(adapter->fmp, sizeof(struct ether_header));
2623                                em_receive_checksum(adapter, current_desc,
2624                                                    adapter->fmp);
2625                                if (current_desc->status & E1000_RXD_STAT_VP)
2626                                        VLAN_INPUT_TAG(eh, adapter->fmp,
2627                                                       (current_desc->special &
2628							E1000_RXD_SPC_VLAN_MASK));
2629                                else
2630                                        ether_input(ifp, eh, adapter->fmp);
2631#else
2632
2633                                em_receive_checksum(adapter, current_desc,
2634                                                    adapter->fmp);
2635                                if (current_desc->status & E1000_RXD_STAT_VP)
2636                                        VLAN_INPUT_TAG(ifp, adapter->fmp,
2637                                                       (current_desc->special &
2638							E1000_RXD_SPC_VLAN_MASK),
2639						       adapter->fmp = NULL);
2640
2641                                if (adapter->fmp != NULL)
2642                                        (*ifp->if_input)(ifp, adapter->fmp);
2643#endif
2644                                adapter->fmp = NULL;
2645                                adapter->lmp = NULL;
2646                        }
2647		} else {
2648			adapter->dropped_pkts++;
2649			em_get_buf(i, adapter, mp);
2650			if (adapter->fmp != NULL)
2651				m_freem(adapter->fmp);
2652			adapter->fmp = NULL;
2653			adapter->lmp = NULL;
2654		}
2655
2656		/* Zero out the receive descriptors status  */
2657		current_desc->status = 0;
2658
2659		/* Advance the E1000's Receive Queue #0  "Tail Pointer". */
2660                E1000_WRITE_REG(&adapter->hw, RDT, i);
2661
2662                /* Advance our pointers to the next descriptor */
2663                if (++i == adapter->num_rx_desc) {
2664                        i = 0;
2665                        current_desc = adapter->rx_desc_base;
2666                } else
2667			current_desc++;
2668	}
2669	adapter->next_rx_desc_to_check = i;
2670	return;
2671}
2672
2673/*********************************************************************
2674 *
2675 *  Verify that the hardware indicated that the checksum is valid.
2676 *  Inform the stack about the status of checksum so that stack
2677 *  doesn't spend time verifying the checksum.
2678 *
2679 *********************************************************************/
2680static void
2681em_receive_checksum(struct adapter *adapter,
2682		    struct em_rx_desc *rx_desc,
2683		    struct mbuf *mp)
2684{
2685	/* 82543 or newer only */
2686	if ((adapter->hw.mac_type < em_82543) ||
2687	    /* Ignore Checksum bit is set */
2688	    (rx_desc->status & E1000_RXD_STAT_IXSM)) {
2689		mp->m_pkthdr.csum_flags = 0;
2690		return;
2691	}
2692
2693	if (rx_desc->status & E1000_RXD_STAT_IPCS) {
2694		/* Did it pass? */
2695		if (!(rx_desc->errors & E1000_RXD_ERR_IPE)) {
2696			/* IP Checksum Good */
2697			mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
2698			mp->m_pkthdr.csum_flags |= CSUM_IP_VALID;
2699
2700		} else {
2701			mp->m_pkthdr.csum_flags = 0;
2702		}
2703	}
2704
2705	if (rx_desc->status & E1000_RXD_STAT_TCPCS) {
2706		/* Did it pass? */
2707		if (!(rx_desc->errors & E1000_RXD_ERR_TCPE)) {
2708			mp->m_pkthdr.csum_flags |=
2709			(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
2710			mp->m_pkthdr.csum_data = htons(0xffff);
2711		}
2712	}
2713
2714	return;
2715}
2716
2717
2718static void
2719em_enable_vlans(struct adapter *adapter)
2720{
2721	uint32_t ctrl;
2722
2723	E1000_WRITE_REG(&adapter->hw, VET, ETHERTYPE_VLAN);
2724
2725	ctrl = E1000_READ_REG(&adapter->hw, CTRL);
2726	ctrl |= E1000_CTRL_VME;
2727	E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
2728
2729	return;
2730}
2731
2732static void
2733em_enable_intr(struct adapter * adapter)
2734{
2735	E1000_WRITE_REG(&adapter->hw, IMS, (IMS_ENABLE_MASK));
2736	return;
2737}
2738
2739static void
2740em_disable_intr(struct adapter *adapter)
2741{
2742	E1000_WRITE_REG(&adapter->hw, IMC,
2743			(0xffffffff & ~E1000_IMC_RXSEQ));
2744	return;
2745}
2746
2747static int
2748em_is_valid_ether_addr(u_int8_t *addr)
2749{
2750        char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
2751
2752        if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) {
2753                return (FALSE);
2754        }
2755
2756        return(TRUE);
2757}
2758
2759void
2760em_write_pci_cfg(struct em_hw *hw,
2761		      uint32_t reg,
2762		      uint16_t *value)
2763{
2764	pci_write_config(((struct em_osdep *)hw->back)->dev, reg,
2765			 *value, 2);
2766}
2767
2768void
2769em_read_pci_cfg(struct em_hw *hw, uint32_t reg,
2770		     uint16_t *value)
2771{
2772	*value = pci_read_config(((struct em_osdep *)hw->back)->dev,
2773				 reg, 2);
2774	return;
2775}
2776
2777void
2778em_pci_set_mwi(struct em_hw *hw)
2779{
2780        pci_write_config(((struct em_osdep *)hw->back)->dev,
2781                         PCIR_COMMAND,
2782                         (hw->pci_cmd_word | CMD_MEM_WRT_INVALIDATE), 2);
2783        return;
2784}
2785
2786void
2787em_pci_clear_mwi(struct em_hw *hw)
2788{
2789        pci_write_config(((struct em_osdep *)hw->back)->dev,
2790                         PCIR_COMMAND,
2791                         (hw->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE), 2);
2792        return;
2793}
2794
2795uint32_t
2796em_io_read(struct em_hw *hw, uint32_t port)
2797{
2798	return(inl(port));
2799}
2800
2801void
2802em_io_write(struct em_hw *hw, uint32_t port, uint32_t value)
2803{
2804	outl(port, value);
2805	return;
2806}
2807
2808/**********************************************************************
2809 *
2810 *  Update the board statistics counters.
2811 *
2812 **********************************************************************/
2813static void
2814em_update_stats_counters(struct adapter *adapter)
2815{
2816	struct ifnet   *ifp;
2817
2818	adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, CRCERRS);
2819	adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, SYMERRS);
2820	adapter->stats.mpc += E1000_READ_REG(&adapter->hw, MPC);
2821	adapter->stats.scc += E1000_READ_REG(&adapter->hw, SCC);
2822	adapter->stats.ecol += E1000_READ_REG(&adapter->hw, ECOL);
2823
2824	adapter->stats.mcc += E1000_READ_REG(&adapter->hw, MCC);
2825	adapter->stats.latecol += E1000_READ_REG(&adapter->hw, LATECOL);
2826	adapter->stats.colc += E1000_READ_REG(&adapter->hw, COLC);
2827	adapter->stats.dc += E1000_READ_REG(&adapter->hw, DC);
2828	adapter->stats.sec += E1000_READ_REG(&adapter->hw, SEC);
2829	adapter->stats.rlec += E1000_READ_REG(&adapter->hw, RLEC);
2830	adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, XONRXC);
2831	adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, XONTXC);
2832	adapter->stats.xoffrxc += E1000_READ_REG(&adapter->hw, XOFFRXC);
2833	adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, XOFFTXC);
2834	adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, FCRUC);
2835	adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, PRC64);
2836	adapter->stats.prc127 += E1000_READ_REG(&adapter->hw, PRC127);
2837	adapter->stats.prc255 += E1000_READ_REG(&adapter->hw, PRC255);
2838	adapter->stats.prc511 += E1000_READ_REG(&adapter->hw, PRC511);
2839	adapter->stats.prc1023 += E1000_READ_REG(&adapter->hw, PRC1023);
2840	adapter->stats.prc1522 += E1000_READ_REG(&adapter->hw, PRC1522);
2841	adapter->stats.gprc += E1000_READ_REG(&adapter->hw, GPRC);
2842	adapter->stats.bprc += E1000_READ_REG(&adapter->hw, BPRC);
2843	adapter->stats.mprc += E1000_READ_REG(&adapter->hw, MPRC);
2844	adapter->stats.gptc += E1000_READ_REG(&adapter->hw, GPTC);
2845
2846	/* For the 64-bit byte counters the low dword must be read first. */
2847	/* Both registers clear on the read of the high dword */
2848
2849	adapter->stats.gorcl += E1000_READ_REG(&adapter->hw, GORCL);
2850	adapter->stats.gorch += E1000_READ_REG(&adapter->hw, GORCH);
2851	adapter->stats.gotcl += E1000_READ_REG(&adapter->hw, GOTCL);
2852	adapter->stats.gotch += E1000_READ_REG(&adapter->hw, GOTCH);
2853
2854	adapter->stats.rnbc += E1000_READ_REG(&adapter->hw, RNBC);
2855	adapter->stats.ruc += E1000_READ_REG(&adapter->hw, RUC);
2856	adapter->stats.rfc += E1000_READ_REG(&adapter->hw, RFC);
2857	adapter->stats.roc += E1000_READ_REG(&adapter->hw, ROC);
2858	adapter->stats.rjc += E1000_READ_REG(&adapter->hw, RJC);
2859
2860	adapter->stats.torl += E1000_READ_REG(&adapter->hw, TORL);
2861	adapter->stats.torh += E1000_READ_REG(&adapter->hw, TORH);
2862	adapter->stats.totl += E1000_READ_REG(&adapter->hw, TOTL);
2863	adapter->stats.toth += E1000_READ_REG(&adapter->hw, TOTH);
2864
2865	adapter->stats.tpr += E1000_READ_REG(&adapter->hw, TPR);
2866	adapter->stats.tpt += E1000_READ_REG(&adapter->hw, TPT);
2867	adapter->stats.ptc64 += E1000_READ_REG(&adapter->hw, PTC64);
2868	adapter->stats.ptc127 += E1000_READ_REG(&adapter->hw, PTC127);
2869	adapter->stats.ptc255 += E1000_READ_REG(&adapter->hw, PTC255);
2870	adapter->stats.ptc511 += E1000_READ_REG(&adapter->hw, PTC511);
2871	adapter->stats.ptc1023 += E1000_READ_REG(&adapter->hw, PTC1023);
2872	adapter->stats.ptc1522 += E1000_READ_REG(&adapter->hw, PTC1522);
2873	adapter->stats.mptc += E1000_READ_REG(&adapter->hw, MPTC);
2874	adapter->stats.bptc += E1000_READ_REG(&adapter->hw, BPTC);
2875
2876	if (adapter->hw.mac_type >= em_82543) {
2877		adapter->stats.algnerrc +=
2878		E1000_READ_REG(&adapter->hw, ALGNERRC);
2879		adapter->stats.rxerrc +=
2880		E1000_READ_REG(&adapter->hw, RXERRC);
2881		adapter->stats.tncrs +=
2882		E1000_READ_REG(&adapter->hw, TNCRS);
2883		adapter->stats.cexterr +=
2884		E1000_READ_REG(&adapter->hw, CEXTERR);
2885		adapter->stats.tsctc +=
2886		E1000_READ_REG(&adapter->hw, TSCTC);
2887		adapter->stats.tsctfc +=
2888		E1000_READ_REG(&adapter->hw, TSCTFC);
2889	}
2890	ifp = &adapter->interface_data.ac_if;
2891
2892	/* Fill out the OS statistics structure */
2893	ifp->if_ibytes = adapter->stats.gorcl;
2894	ifp->if_obytes = adapter->stats.gotcl;
2895	ifp->if_imcasts = adapter->stats.mprc;
2896	ifp->if_collisions = adapter->stats.colc;
2897
2898	/* Rx Errors */
2899	ifp->if_ierrors =
2900	adapter->dropped_pkts +
2901	adapter->stats.rxerrc +
2902	adapter->stats.crcerrs +
2903	adapter->stats.algnerrc +
2904	adapter->stats.rlec + adapter->stats.rnbc +
2905	adapter->stats.mpc + adapter->stats.cexterr;
2906
2907	/* Tx Errors */
2908	ifp->if_oerrors = adapter->stats.ecol + adapter->stats.latecol;
2909
2910}
2911
2912
2913/**********************************************************************
2914 *
2915 *  This routine is called only when em_display_debug_stats is enabled.
2916 *  This routine provides a way to take a look at important statistics
2917 *  maintained by the driver and hardware.
2918 *
2919 **********************************************************************/
2920static void
2921em_print_debug_info(struct adapter *adapter)
2922{
2923        int unit = adapter->unit;
2924
2925#ifdef DBG_STATS
2926        printf("em%d: Packets not Avail = %ld\n", unit,
2927               adapter->no_pkts_avail);
2928        printf("em%d: CleanTxInterrupts = %ld\n", unit,
2929               adapter->clean_tx_interrupts);
2930#endif
2931        printf("em%d: fifo workaround = %lld, fifo_reset = %lld\n", unit,
2932               (long long)adapter->tx_fifo_wrk,
2933               (long long)adapter->tx_fifo_reset);
2934        printf("em%d: hw tdh = %d, hw tdt = %d\n", unit,
2935               E1000_READ_REG(&adapter->hw, TDH),
2936               E1000_READ_REG(&adapter->hw, TDT));
2937        printf("em%d: Num Tx descriptors avail = %d\n", unit,
2938               adapter->num_tx_desc_avail);
2939        printf("em%d: Tx Descriptors not avail1 = %ld\n", unit,
2940               adapter->no_tx_desc_avail1);
2941        printf("em%d: Tx Descriptors not avail2 = %ld\n", unit,
2942               adapter->no_tx_desc_avail2);
2943        printf("em%d: Std mbuf failed = %ld\n", unit,
2944               adapter->mbuf_alloc_failed);
2945        printf("em%d: Std mbuf cluster failed = %ld\n", unit,
2946               adapter->mbuf_cluster_failed);
2947        printf("em%d: Driver dropped packets = %ld\n", unit,
2948               adapter->dropped_pkts);
2949
2950        return;
2951}
2952
2953static void
2954em_print_hw_stats(struct adapter *adapter)
2955{
2956        int unit = adapter->unit;
2957
2958        printf("em%d: Excessive collisions = %lld\n", unit,
2959               (long long)adapter->stats.ecol);
2960        printf("em%d: Symbol errors = %lld\n", unit,
2961               (long long)adapter->stats.symerrs);
2962        printf("em%d: Sequence errors = %lld\n", unit,
2963               (long long)adapter->stats.sec);
2964        printf("em%d: Defer count = %lld\n", unit,
2965               (long long)adapter->stats.dc);
2966
2967        printf("em%d: Missed Packets = %lld\n", unit,
2968               (long long)adapter->stats.mpc);
2969        printf("em%d: Receive No Buffers = %lld\n", unit,
2970               (long long)adapter->stats.rnbc);
2971        printf("em%d: Receive length errors = %lld\n", unit,
2972               (long long)adapter->stats.rlec);
2973        printf("em%d: Receive errors = %lld\n", unit,
2974               (long long)adapter->stats.rxerrc);
2975        printf("em%d: Crc errors = %lld\n", unit,
2976               (long long)adapter->stats.crcerrs);
2977        printf("em%d: Alignment errors = %lld\n", unit,
2978               (long long)adapter->stats.algnerrc);
2979        printf("em%d: Carrier extension errors = %lld\n", unit,
2980               (long long)adapter->stats.cexterr);
2981
2982        printf("em%d: XON Rcvd = %lld\n", unit,
2983               (long long)adapter->stats.xonrxc);
2984        printf("em%d: XON Xmtd = %lld\n", unit,
2985               (long long)adapter->stats.xontxc);
2986        printf("em%d: XOFF Rcvd = %lld\n", unit,
2987               (long long)adapter->stats.xoffrxc);
2988        printf("em%d: XOFF Xmtd = %lld\n", unit,
2989               (long long)adapter->stats.xofftxc);
2990
2991        printf("em%d: Good Packets Rcvd = %lld\n", unit,
2992               (long long)adapter->stats.gprc);
2993        printf("em%d: Good Packets Xmtd = %lld\n", unit,
2994               (long long)adapter->stats.gptc);
2995
2996        return;
2997}
2998
2999static int
3000em_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
3001{
3002        int error;
3003        int result;
3004        struct adapter *adapter;
3005
3006        result = -1;
3007        error = sysctl_handle_int(oidp, &result, 0, req);
3008
3009        if (error || !req->newptr)
3010                return (error);
3011
3012        if (result == 1) {
3013                adapter = (struct adapter *)arg1;
3014                em_print_debug_info(adapter);
3015        }
3016
3017        return error;
3018}
3019
3020
3021static int
3022em_sysctl_stats(SYSCTL_HANDLER_ARGS)
3023{
3024        int error;
3025        int result;
3026        struct adapter *adapter;
3027
3028        result = -1;
3029        error = sysctl_handle_int(oidp, &result, 0, req);
3030
3031        if (error || !req->newptr)
3032                return (error);
3033
3034        if (result == 1) {
3035                adapter = (struct adapter *)arg1;
3036                em_print_hw_stats(adapter);
3037        }
3038
3039        return error;
3040}
3041
3042static int
3043em_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
3044{
3045	struct em_int_delay_info *info;
3046	struct adapter *adapter;
3047	u_int32_t regval;
3048	int error;
3049	int usecs;
3050	int ticks;
3051	int s;
3052
3053	info = (struct em_int_delay_info *)arg1;
3054	adapter = info->adapter;
3055	usecs = info->value;
3056	error = sysctl_handle_int(oidp, &usecs, 0, req);
3057	if (error != 0 || req->newptr == NULL)
3058		return error;
3059	if (usecs < 0 || usecs > E1000_TICKS_TO_USECS(65535))
3060		return EINVAL;
3061	info->value = usecs;
3062	ticks = E1000_USECS_TO_TICKS(usecs);
3063
3064	s = splimp();
3065	regval = E1000_READ_OFFSET(&adapter->hw, info->offset);
3066	regval = (regval & ~0xffff) | (ticks & 0xffff);
3067	/* Handle a few special cases. */
3068	switch (info->offset) {
3069	case E1000_RDTR:
3070	case E1000_82542_RDTR:
3071		regval |= E1000_RDT_FPDB;
3072		break;
3073	case E1000_TIDV:
3074	case E1000_82542_TIDV:
3075		if (ticks == 0) {
3076			adapter->txd_cmd &= ~E1000_TXD_CMD_IDE;
3077			/* Don't write 0 into the TIDV register. */
3078			regval++;
3079		} else
3080			adapter->txd_cmd |= E1000_TXD_CMD_IDE;
3081		break;
3082	}
3083	E1000_WRITE_OFFSET(&adapter->hw, info->offset, regval);
3084	splx(s);
3085	return 0;
3086}
3087
3088static void
3089em_add_int_delay_sysctl(struct adapter *adapter, const char *name,
3090    const char *description, struct em_int_delay_info *info,
3091    int offset, int value)
3092{
3093	info->adapter = adapter;
3094	info->offset = offset;
3095	info->value = value;
3096	SYSCTL_ADD_PROC(&adapter->sysctl_ctx,
3097	    SYSCTL_CHILDREN(adapter->sysctl_tree),
3098	    OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW,
3099	    info, 0, em_sysctl_int_delay, "I", description);
3100}
3101