diff options
author | jfv <jfv@FreeBSD.org> | 2010-11-01 20:19:25 +0000 |
---|---|---|
committer | jfv <jfv@FreeBSD.org> | 2010-11-01 20:19:25 +0000 |
commit | a4ab528826d1ac9cc9de0ba3fead29d68b978e3e (patch) | |
tree | cbc2856488d5cba69f4f2bc4f0921e4e8502f757 /sys/dev/e1000 | |
parent | e0a2a85d3a72725ab12bf363f472b29193ad6aaa (diff) | |
download | FreeBSD-src-a4ab528826d1ac9cc9de0ba3fead29d68b978e3e.zip FreeBSD-src-a4ab528826d1ac9cc9de0ba3fead29d68b978e3e.tar.gz |
Sync the lem code up with the vlan and other fixes in em.
Delete a unneeded test from the beginning of em_xmit.
CRITICAL: shared code fix for 82574, a mutex might not be
released, this can cause hangs.
Diffstat (limited to 'sys/dev/e1000')
-rw-r--r-- | sys/dev/e1000/e1000_82571.c | 7 | ||||
-rw-r--r-- | sys/dev/e1000/if_em.c | 13 | ||||
-rw-r--r-- | sys/dev/e1000/if_lem.c | 228 | ||||
-rw-r--r-- | sys/dev/e1000/if_lem.h | 18 |
4 files changed, 108 insertions, 158 deletions
diff --git a/sys/dev/e1000/e1000_82571.c b/sys/dev/e1000/e1000_82571.c index 3554dbe..5e12c49 100644 --- a/sys/dev/e1000/e1000_82571.c +++ b/sys/dev/e1000/e1000_82571.c @@ -666,10 +666,15 @@ static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw) **/ static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw) { + s32 ret_val; + DEBUGFUNC("e1000_get_hw_semaphore_82574"); E1000_MUTEX_LOCK(&hw->dev_spec._82571.swflag_mutex); - return e1000_get_hw_semaphore_82573(hw); + ret_val = e1000_get_hw_semaphore_82573(hw); + if (ret_val) + E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex); + return ret_val; } /** diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 1ce3956..c41e144 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1766,19 +1766,6 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp) ip_off = poff = 0; /* - ** When doing checksum offload, it is critical to - ** make sure the first mbuf has more than header, - ** because that routine expects data to be present. - */ - if ((m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) && - (m_head->m_len < ETHER_HDR_LEN + sizeof(struct ip))) { - m_head = m_pullup(m_head, ETHER_HDR_LEN + sizeof(struct ip)); - *m_headp = m_head; - if (m_head == NULL) - return (ENOBUFS); - } - - /* * Intel recommends entire IP/TCP header length reside in a single * buffer. If multiple descriptors are used to describe the IP and * TCP header, each descriptor should describe one or more diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c index 846d6bf..21686e6 100644 --- a/sys/dev/e1000/if_lem.c +++ b/sys/dev/e1000/if_lem.c @@ -51,9 +51,7 @@ #include <sys/sockio.h> #include <sys/sysctl.h> #include <sys/taskqueue.h> -#if __FreeBSD_version >= 700029 #include <sys/eventhandler.h> -#endif #include <machine/bus.h> #include <machine/resource.h> @@ -86,8 +84,7 @@ /********************************************************************* * Legacy Em Driver version: *********************************************************************/ -char lem_driver_version[] = "1.0.2"; - +char lem_driver_version[] = "1.0.3"; /********************************************************************* * PCI Device ID Table @@ -209,11 +206,9 @@ static void lem_disable_promisc(struct adapter *); static void lem_set_multi(struct adapter *); static void lem_update_link_status(struct adapter *); static int lem_get_buf(struct adapter *, int); -#if __FreeBSD_version >= 700029 static void lem_register_vlan(void *, struct ifnet *, u16); static void lem_unregister_vlan(void *, struct ifnet *, u16); static void lem_setup_vlan_hw_support(struct adapter *); -#endif static int lem_xmit(struct adapter *, struct mbuf **); static void lem_smartspeed(struct adapter *); static int lem_82547_fifo_workaround(struct adapter *, int); @@ -231,6 +226,8 @@ static u32 lem_fill_descriptors (bus_addr_t address, u32 length, static int lem_sysctl_int_delay(SYSCTL_HANDLER_ARGS); static void lem_add_int_delay_sysctl(struct adapter *, const char *, const char *, struct em_int_delay_info *, int, int); +static void lem_set_flow_cntrl(struct adapter *, const char *, + const char *, int *, int); /* Management and WOL Support */ static void lem_init_manageability(struct adapter *); static void lem_release_manageability(struct adapter *); @@ -244,11 +241,7 @@ static void lem_led_func(void *, int); #ifdef EM_LEGACY_IRQ static void lem_intr(void *); #else /* FAST IRQ */ -#if __FreeBSD_version < 700000 -static void lem_irq_fast(void *); -#else static int lem_irq_fast(void *); -#endif static void lem_handle_rxtx(void *context, int pending); static void lem_handle_link(void *context, int pending); static void lem_add_rx_process_limit(struct adapter *, const char *, @@ -320,14 +313,6 @@ TUNABLE_INT("hw.em.rx_process_limit", &lem_rx_process_limit); static int lem_fc_setting = e1000_fc_full; TUNABLE_INT("hw.em.fc_setting", &lem_fc_setting); -/* -** Shadow VFTA table, this is needed because -** the real vlan filter table gets cleared during -** a soft reset and the driver needs to be able -** to repopulate it. -*/ -static u32 lem_shadow_vfta[EM_VFTA_SIZE]; - /* Global used in WOL setup with multiport cards */ static int global_quad_port_a = 0; @@ -462,6 +447,11 @@ lem_attach(device_t dev) lem_rx_process_limit); #endif + /* Sysctl for setting the interface flow control */ + lem_set_flow_cntrl(adapter, "flow_control", + "max number of rx packets to process", + &adapter->fc_setting, lem_fc_setting); + /* * Validate number of transmit and receive descriptors. It * must not exceed hardware maximum, and must be multiple @@ -638,13 +628,11 @@ lem_attach(device_t dev) else adapter->pcix_82544 = FALSE; -#if __FreeBSD_version >= 700029 /* Register for VLAN events */ adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, lem_register_vlan, adapter, EVENTHANDLER_PRI_FIRST); adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, lem_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST); -#endif lem_add_hw_stats(adapter); @@ -702,11 +690,7 @@ lem_detach(device_t dev) INIT_DEBUGOUT("em_detach: begin"); /* Make sure VLANS are not using driver */ -#if __FreeBSD_version >= 700000 if (adapter->ifp->if_vlantrunk != NULL) { -#else - if (adapter->ifp->if_nvlans != 0) { -#endif device_printf(dev,"Vlan in use, detach first\n"); return (EBUSY); } @@ -730,13 +714,11 @@ lem_detach(device_t dev) EM_TX_UNLOCK(adapter); EM_CORE_UNLOCK(adapter); -#if __FreeBSD_version >= 700029 /* Unregister VLAN events */ if (adapter->vlan_attach != NULL) EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach); if (adapter->vlan_detach != NULL) EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach); -#endif ether_ifdetach(adapter->ifp); callout_drain(&adapter->timer); @@ -831,6 +813,19 @@ lem_start_locked(struct ifnet *ifp) if (!adapter->link_active) return; + /* + * Force a cleanup if number of TX descriptors + * available hits the threshold + */ + if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) { + lem_txeof(adapter); + /* Now do we at least have a minimal? */ + if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) { + adapter->no_tx_desc_avail1++; + return; + } + } + while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); @@ -1043,9 +1038,7 @@ lem_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING)) lem_init(adapter); -#if __FreeBSD_version >= 700000 VLAN_CAPABILITIES(ifp); -#endif break; } @@ -1135,17 +1128,8 @@ lem_init_locked(struct adapter *adapter) /* Setup VLAN support, basic and offload if available */ E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN); -#if __FreeBSD_version < 700029 - if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) { - u32 ctrl; - ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL); - ctrl |= E1000_CTRL_VME; - E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); - } -#else /* Use real VLAN Filter support */ lem_setup_vlan_hw_support(adapter); -#endif /* Set hardware offload abilities */ ifp->if_hwassist = 0; @@ -1174,6 +1158,19 @@ lem_init_locked(struct adapter *adapter) } lem_initialize_receive_unit(adapter); + /* Use real VLAN Filter support? */ + if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) { + if (ifp->if_capenable & IFCAP_VLAN_HWFILTER) + /* Use real VLAN Filter support */ + lem_setup_vlan_hw_support(adapter); + else { + u32 ctrl; + ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL); + ctrl |= E1000_CTRL_VME; + E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); + } + } + /* Don't lose promiscuous settings */ lem_set_promisc(adapter); @@ -1276,7 +1273,6 @@ lem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) * Legacy Interrupt Service routine * *********************************************************************/ - static void lem_intr(void *arg) { @@ -1311,7 +1307,6 @@ lem_intr(void *arg) } EM_TX_LOCK(adapter); - lem_txeof(adapter); lem_rxeof(adapter, -1, NULL); lem_txeof(adapter); if (ifp->if_drv_flags & IFF_DRV_RUNNING && @@ -1354,8 +1349,7 @@ lem_handle_rxtx(void *context, int pending) if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if (lem_rxeof(adapter, adapter->rx_process_limit, NULL) != 0) - taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); + lem_rxeof(adapter, adapter->rx_process_limit, NULL); EM_TX_LOCK(adapter); lem_txeof(adapter); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) @@ -1363,7 +1357,8 @@ lem_handle_rxtx(void *context, int pending) EM_TX_UNLOCK(adapter); } - lem_enable_intr(adapter); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + lem_enable_intr(adapter); } /********************************************************************* @@ -1371,13 +1366,7 @@ lem_handle_rxtx(void *context, int pending) * Fast Legacy/MSI Combined Interrupt Service routine * *********************************************************************/ -#if __FreeBSD_version < 700000 -#define FILTER_STRAY -#define FILTER_HANDLED -static void -#else static int -#endif lem_irq_fast(void *arg) { struct adapter *adapter = arg; @@ -1550,25 +1539,10 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp) struct mbuf *m_head; u32 txd_upper, txd_lower, txd_used, txd_saved; int error, nsegs, i, j, first, last = 0; -#if __FreeBSD_version < 700000 - struct m_tag *mtag; -#endif + m_head = *m_headp; txd_upper = txd_lower = txd_used = txd_saved = 0; - /* - * Force a cleanup if number of TX descriptors - * available hits the threshold - */ - if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) { - lem_txeof(adapter); - /* Now do we at least have a minimal? */ - if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) { - adapter->no_tx_desc_avail1++; - return (ENOBUFS); - } - } - /* ** When doing checksum offload, it is critical to ** make sure the first mbuf has more than header, @@ -1712,20 +1686,6 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp) else adapter->num_tx_desc_avail -= nsegs; - /* - ** Handle VLAN tag, this is the - ** biggest difference between - ** 6.x and 7 - */ -#if __FreeBSD_version < 700000 - /* Find out if we are in vlan mode. */ - mtag = VLAN_OUTPUT_TAG(ifp, m_head); - if (mtag != NULL) { - ctxd->upper.fields.special = - htole16(VLAN_TAG_VALUE(mtag)); - ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE); - } -#else /* FreeBSD 7 */ if (m_head->m_flags & M_VLANTAG) { /* Set the vlan id. */ ctxd->upper.fields.special = @@ -1733,7 +1693,6 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp) /* Tell hardware to add tag */ ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE); } -#endif tx_buffer->m_head = m_head; tx_buffer_mapped->map = tx_buffer->map; @@ -2249,11 +2208,7 @@ lem_allocate_irq(struct adapter *adapter) #ifdef EM_LEGACY_IRQ /* We do Legacy setup */ if ((error = bus_setup_intr(dev, adapter->res[0], -#if __FreeBSD_version > 700000 INTR_TYPE_NET | INTR_MPSAFE, NULL, lem_intr, adapter, -#else /* 6.X */ - INTR_TYPE_NET | INTR_MPSAFE, lem_intr, adapter, -#endif &adapter->tag[0])) != 0) { device_printf(dev, "Failed to register interrupt handler"); return (error); @@ -2270,13 +2225,8 @@ lem_allocate_irq(struct adapter *adapter) taskqueue_thread_enqueue, &adapter->tq); taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq", device_get_nameunit(adapter->dev)); -#if __FreeBSD_version < 700000 - if ((error = bus_setup_intr(dev, adapter->res[0], - INTR_TYPE_NET | INTR_FAST, lem_irq_fast, adapter, -#else if ((error = bus_setup_intr(dev, adapter->res[0], INTR_TYPE_NET, lem_irq_fast, NULL, adapter, -#endif &adapter->tag[0])) != 0) { device_printf(dev, "Failed to register fast interrupt " "handler: %d\n", error); @@ -2362,7 +2312,7 @@ lem_hardware_init(struct adapter *adapter) adapter->hw.fc.send_xon = TRUE; /* Set Flow control, use the tunable location if sane */ - if ((lem_fc_setting >= 0) || (lem_fc_setting < 4)) + if ((lem_fc_setting >= 0) && (lem_fc_setting < 4)) adapter->hw.fc.requested_mode = lem_fc_setting; else adapter->hw.fc.requested_mode = e1000_fc_none; @@ -2410,14 +2360,8 @@ lem_setup_interface(device_t dev, struct adapter *adapter) ifp->if_capabilities = ifp->if_capenable = 0; if (adapter->hw.mac.type >= e1000_82543) { - int version_cap; -#if __FreeBSD_version < 700000 - version_cap = IFCAP_HWCSUM; -#else - version_cap = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; -#endif - ifp->if_capabilities |= version_cap; - ifp->if_capenable |= version_cap; + ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; + ifp->if_capenable |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; } /* @@ -2427,6 +2371,16 @@ lem_setup_interface(device_t dev, struct adapter *adapter) ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; + /* + ** Dont turn this on by default, if vlans are + ** created on another pseudo device (eg. lagg) + ** then vlan events are not passed thru, breaking + ** operation, but with HW FILTER off it works. If + ** using vlans directly on the em driver you can + ** enable this and get full hardware tag filtering. + */ + ifp->if_capabilities |= IFCAP_VLAN_HWFILTER; + #ifdef DEVICE_POLLING ifp->if_capabilities |= IFCAP_POLLING; #endif @@ -2551,11 +2505,7 @@ lem_dma_malloc(struct adapter *adapter, bus_size_t size, { int error; -#if __FreeBSD_version >= 700000 error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */ -#else - error = bus_dma_tag_create(NULL, /* parent */ -#endif EM_DBA_ALIGN, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -2640,21 +2590,17 @@ lem_allocate_transmit_structures(struct adapter *adapter) /* * Create DMA tags for tx descriptors */ -#if __FreeBSD_version >= 700000 if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ -#else - if ((error = bus_dma_tag_create(NULL, /* parent */ -#endif 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - EM_TSO_SIZE, /* maxsize */ + MCLBYTES * EM_MAX_SCATTER, /* maxsize */ EM_MAX_SCATTER, /* nsegments */ - EM_TSO_SEG_SIZE, /* maxsegsize */ + MCLBYTES, /* maxsegsize */ 0, /* flags */ - NULL, /* lockfunc */ - NULL, /* lockarg */ + NULL, /* lockfunc */ + NULL, /* lockarg */ &adapter->txtag)) != 0) { device_printf(dev, "Unable to allocate TX DMA tag\n"); goto fail; @@ -3072,23 +3018,20 @@ lem_txeof(struct adapter *adapter) BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); adapter->next_tx_to_clean = first; + adapter->num_tx_desc_avail = num_avail; /* * If we have enough room, clear IFF_DRV_OACTIVE to * tell the stack that it is OK to send packets. * If there are no pending descriptors, clear the watchdog. */ - if (num_avail > EM_TX_CLEANUP_THRESHOLD) { + if (adapter->num_tx_desc_avail > EM_TX_CLEANUP_THRESHOLD) { ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if (num_avail == adapter->num_tx_desc) { + if (adapter->num_tx_desc_avail == adapter->num_tx_desc) { adapter->watchdog_check = FALSE; - adapter->num_tx_desc_avail = num_avail; return; } } - - adapter->num_tx_desc_avail = num_avail; - return; } /********************************************************************* @@ -3185,11 +3128,7 @@ lem_allocate_receive_structures(struct adapter *adapter) return (ENOMEM); } -#if __FreeBSD_version >= 700000 error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ -#else - error = bus_dma_tag_create(NULL, /* parent */ -#endif 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -3459,7 +3398,7 @@ lem_rxeof(struct adapter *adapter, int count, int *done) { struct ifnet *ifp = adapter->ifp;; struct mbuf *mp; - u8 status, accept_frame = 0, eop = 0; + u8 status = 0, accept_frame = 0, eop = 0; u16 len, desc_len, prev_len_adj; int i, rx_sent = 0; struct e1000_rx_desc *current_desc; @@ -3477,11 +3416,13 @@ lem_rxeof(struct adapter *adapter, int count, int *done) return (FALSE); } - while ((current_desc->status & E1000_RXD_STAT_DD) && - (count != 0) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) { + while (count != 0 && ifp->if_drv_flags & IFF_DRV_RUNNING) { struct mbuf *m = NULL; + status = current_desc->status; + if ((status & E1000_RXD_STAT_DD) == 0) + break; + mp = adapter->rx_buffer_area[i].m_head; /* * Can't defer bus_dmamap_sync(9) because TBI_ACCEPT @@ -3493,7 +3434,6 @@ lem_rxeof(struct adapter *adapter, int count, int *done) accept_frame = 1; prev_len_adj = 0; desc_len = le16toh(current_desc->length); - status = current_desc->status; if (status & E1000_RXD_STAT_EOP) { count--; eop = 1; @@ -3571,16 +3511,10 @@ lem_rxeof(struct adapter *adapter, int count, int *done) goto skip; #endif if (status & E1000_RXD_STAT_VP) { -#if __FreeBSD_version < 700000 - VLAN_INPUT_TAG_NEW(ifp, adapter->fmp, - (le16toh(current_desc->special) & - E1000_RXD_SPC_VLAN_MASK)); -#else adapter->fmp->m_pkthdr.ether_vtag = (le16toh(current_desc->special) & E1000_RXD_SPC_VLAN_MASK); adapter->fmp->m_flags |= M_VLANTAG; -#endif } #ifndef __NO_STRICT_ALIGNMENT skip: @@ -3636,7 +3570,7 @@ discard: if (done != NULL) *done = rx_sent; EM_RX_UNLOCK(adapter); - return (current_desc->status & E1000_RXD_STAT_DD); + return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE); } #ifndef __NO_STRICT_ALIGNMENT @@ -3728,7 +3662,6 @@ lem_receive_checksum(struct adapter *adapter, } } -#if __FreeBSD_version >= 700029 /* * This routine is run via an vlan * config EVENT @@ -3745,12 +3678,15 @@ lem_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) if ((vtag == 0) || (vtag > 4095)) /* Invalid ID */ return; + EM_CORE_LOCK(adapter); index = (vtag >> 5) & 0x7F; bit = vtag & 0x1F; - lem_shadow_vfta[index] |= (1 << bit); + adapter->shadow_vfta[index] |= (1 << bit); ++adapter->num_vlans; /* Re-init to load the changes */ - lem_init(adapter); + if (ifp->if_capenable & IFCAP_VLAN_HWFILTER) + lem_init_locked(adapter); + EM_CORE_UNLOCK(adapter); } /* @@ -3769,12 +3705,15 @@ lem_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) if ((vtag == 0) || (vtag > 4095)) /* Invalid */ return; + EM_CORE_LOCK(adapter); index = (vtag >> 5) & 0x7F; bit = vtag & 0x1F; - lem_shadow_vfta[index] &= ~(1 << bit); + adapter->shadow_vfta[index] &= ~(1 << bit); --adapter->num_vlans; /* Re-init to load the changes */ - lem_init(adapter); + if (ifp->if_capenable & IFCAP_VLAN_HWFILTER) + lem_init_locked(adapter); + EM_CORE_UNLOCK(adapter); } static void @@ -3797,9 +3736,9 @@ lem_setup_vlan_hw_support(struct adapter *adapter) ** we need to repopulate it now. */ for (int i = 0; i < EM_VFTA_SIZE; i++) - if (lem_shadow_vfta[i] != 0) + if (adapter->shadow_vfta[i] != 0) E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, - i, lem_shadow_vfta[i]); + i, adapter->shadow_vfta[i]); reg = E1000_READ_REG(hw, E1000_CTRL); reg |= E1000_CTRL_VME; @@ -3815,7 +3754,6 @@ lem_setup_vlan_hw_support(struct adapter *adapter) E1000_WRITE_REG(&adapter->hw, E1000_RLPML, adapter->max_frame_size + VLAN_TAG_SIZE); } -#endif static void lem_enable_intr(struct adapter *adapter) @@ -4661,6 +4599,16 @@ lem_add_int_delay_sysctl(struct adapter *adapter, const char *name, info, 0, lem_sysctl_int_delay, "I", description); } +static void +lem_set_flow_cntrl(struct adapter *adapter, const char *name, + const char *description, int *limit, int value) +{ + *limit = value; + SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), + OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); +} + #ifndef EM_LEGACY_IRQ static void lem_add_rx_process_limit(struct adapter *adapter, const char *name, @@ -4672,5 +4620,3 @@ lem_add_rx_process_limit(struct adapter *adapter, const char *name, OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); } #endif - - diff --git a/sys/dev/e1000/if_lem.h b/sys/dev/e1000/if_lem.h index 2f76aa8..e866d07e 100644 --- a/sys/dev/e1000/if_lem.h +++ b/sys/dev/e1000/if_lem.h @@ -328,11 +328,9 @@ struct adapter { struct task tx_task; struct taskqueue *tq; /* private task queue */ -#if __FreeBSD_version >= 700029 eventhandler_tag vlan_attach; eventhandler_tag vlan_detach; u32 num_vlans; -#endif /* Management and WOL features */ u32 wol; @@ -341,11 +339,22 @@ struct adapter { /* Multicast array memory */ u8 *mta; - /* Info about the board itself */ + + /* + ** Shadow VFTA table, this is needed because + ** the real vlan filter table gets cleared during + ** a soft reset and the driver needs to be able + ** to repopulate it. + */ + u32 shadow_vfta[EM_VFTA_SIZE]; + + /* Info about the interface */ uint8_t link_active; uint16_t link_speed; uint16_t link_duplex; uint32_t smartspeed; + uint32_t fc_setting; + struct em_int_delay_info tx_int_delay; struct em_int_delay_info tx_abs_int_delay; struct em_int_delay_info rx_int_delay; @@ -407,6 +416,9 @@ struct adapter { unsigned long no_tx_dma_setup; unsigned long watchdog_events; unsigned long rx_overruns; + unsigned long rx_irq; + unsigned long tx_irq; + unsigned long link_irq; /* 82547 workaround */ uint32_t tx_fifo_size; |