1205869Sjfv/******************************************************************************
2205869Sjfv
3294958Smarius  Copyright (c) 2001-2015, Intel Corporation
4205869Sjfv  All rights reserved.
5205869Sjfv
6205869Sjfv  Redistribution and use in source and binary forms, with or without
7205869Sjfv  modification, are permitted provided that the following conditions are met:
8205869Sjfv
9205869Sjfv   1. Redistributions of source code must retain the above copyright notice,
10205869Sjfv      this list of conditions and the following disclaimer.
11205869Sjfv
12205869Sjfv   2. Redistributions in binary form must reproduce the above copyright
13205869Sjfv      notice, this list of conditions and the following disclaimer in the
14205869Sjfv      documentation and/or other materials provided with the distribution.
15205869Sjfv
16205869Sjfv   3. Neither the name of the Intel Corporation nor the names of its
17205869Sjfv      contributors may be used to endorse or promote products derived from
18205869Sjfv      this software without specific prior written permission.
19205869Sjfv
20205869Sjfv  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21205869Sjfv  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22205869Sjfv  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23205869Sjfv  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24205869Sjfv  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25205869Sjfv  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26205869Sjfv  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27205869Sjfv  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28205869Sjfv  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29205869Sjfv  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30205869Sjfv  POSSIBILITY OF SUCH DAMAGE.
31205869Sjfv
32205869Sjfv******************************************************************************/
33205869Sjfv/*$FreeBSD: releng/10.3/sys/dev/e1000/if_lem.c 294958 2016-01-27 22:31:08Z marius $*/
34205869Sjfv
35270252Sluigi/*
36270252Sluigi * Uncomment the following extensions for better performance in a VM,
37270252Sluigi * especially if you have support in the hypervisor.
38270252Sluigi * See http://info.iet.unipi.it/~luigi/netmap/
39270252Sluigi */
40270252Sluigi// #define BATCH_DISPATCH
41270252Sluigi// #define NIC_SEND_COMBINING
42270252Sluigi// #define NIC_PARAVIRT	/* enable virtio-like synchronization */
43270252Sluigi
44253303Sjfv#include "opt_inet.h"
45253303Sjfv#include "opt_inet6.h"
46253303Sjfv
47205869Sjfv#ifdef HAVE_KERNEL_OPTION_HEADERS
48205869Sjfv#include "opt_device_polling.h"
49205869Sjfv#endif
50205869Sjfv
51205869Sjfv#include <sys/param.h>
52205869Sjfv#include <sys/systm.h>
53205869Sjfv#include <sys/bus.h>
54205869Sjfv#include <sys/endian.h>
55205869Sjfv#include <sys/kernel.h>
56205869Sjfv#include <sys/kthread.h>
57205869Sjfv#include <sys/malloc.h>
58205869Sjfv#include <sys/mbuf.h>
59205869Sjfv#include <sys/module.h>
60205869Sjfv#include <sys/rman.h>
61205869Sjfv#include <sys/socket.h>
62205869Sjfv#include <sys/sockio.h>
63205869Sjfv#include <sys/sysctl.h>
64205869Sjfv#include <sys/taskqueue.h>
65205869Sjfv#include <sys/eventhandler.h>
66205869Sjfv#include <machine/bus.h>
67205869Sjfv#include <machine/resource.h>
68205869Sjfv
69205869Sjfv#include <net/bpf.h>
70205869Sjfv#include <net/ethernet.h>
71205869Sjfv#include <net/if.h>
72205869Sjfv#include <net/if_arp.h>
73205869Sjfv#include <net/if_dl.h>
74205869Sjfv#include <net/if_media.h>
75205869Sjfv
76205869Sjfv#include <net/if_types.h>
77205869Sjfv#include <net/if_vlan_var.h>
78205869Sjfv
79205869Sjfv#include <netinet/in_systm.h>
80205869Sjfv#include <netinet/in.h>
81205869Sjfv#include <netinet/if_ether.h>
82205869Sjfv#include <netinet/ip.h>
83205869Sjfv#include <netinet/ip6.h>
84205869Sjfv#include <netinet/tcp.h>
85205869Sjfv#include <netinet/udp.h>
86205869Sjfv
87205869Sjfv#include <machine/in_cksum.h>
88206001Smarius#include <dev/led/led.h>
89205869Sjfv#include <dev/pci/pcivar.h>
90205869Sjfv#include <dev/pci/pcireg.h>
91205869Sjfv
92205869Sjfv#include "e1000_api.h"
93205869Sjfv#include "if_lem.h"
94205869Sjfv
95205869Sjfv/*********************************************************************
96205869Sjfv *  Legacy Em Driver version:
97205869Sjfv *********************************************************************/
98294958Smariuschar lem_driver_version[] = "1.1.0";
99205869Sjfv
100205869Sjfv/*********************************************************************
101205869Sjfv *  PCI Device ID Table
102205869Sjfv *
103205869Sjfv *  Used by probe to select devices to load on
104205869Sjfv *  Last field stores an index into e1000_strings
105205869Sjfv *  Last entry must be all 0s
106205869Sjfv *
107205869Sjfv *  { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
108205869Sjfv *********************************************************************/
109205869Sjfv
110205869Sjfvstatic em_vendor_info_t lem_vendor_info_array[] =
111205869Sjfv{
112205869Sjfv	/* Intel(R) PRO/1000 Network Connection */
113205869Sjfv	{ 0x8086, E1000_DEV_ID_82540EM,		PCI_ANY_ID, PCI_ANY_ID, 0},
114205869Sjfv	{ 0x8086, E1000_DEV_ID_82540EM_LOM,	PCI_ANY_ID, PCI_ANY_ID, 0},
115205869Sjfv	{ 0x8086, E1000_DEV_ID_82540EP,		PCI_ANY_ID, PCI_ANY_ID, 0},
116205869Sjfv	{ 0x8086, E1000_DEV_ID_82540EP_LOM,	PCI_ANY_ID, PCI_ANY_ID, 0},
117205869Sjfv	{ 0x8086, E1000_DEV_ID_82540EP_LP,	PCI_ANY_ID, PCI_ANY_ID, 0},
118205869Sjfv
119205869Sjfv	{ 0x8086, E1000_DEV_ID_82541EI,		PCI_ANY_ID, PCI_ANY_ID, 0},
120205869Sjfv	{ 0x8086, E1000_DEV_ID_82541ER,		PCI_ANY_ID, PCI_ANY_ID, 0},
121205869Sjfv	{ 0x8086, E1000_DEV_ID_82541ER_LOM,	PCI_ANY_ID, PCI_ANY_ID, 0},
122205869Sjfv	{ 0x8086, E1000_DEV_ID_82541EI_MOBILE,	PCI_ANY_ID, PCI_ANY_ID, 0},
123205869Sjfv	{ 0x8086, E1000_DEV_ID_82541GI,		PCI_ANY_ID, PCI_ANY_ID, 0},
124205869Sjfv	{ 0x8086, E1000_DEV_ID_82541GI_LF,	PCI_ANY_ID, PCI_ANY_ID, 0},
125205869Sjfv	{ 0x8086, E1000_DEV_ID_82541GI_MOBILE,	PCI_ANY_ID, PCI_ANY_ID, 0},
126205869Sjfv
127205869Sjfv	{ 0x8086, E1000_DEV_ID_82542,		PCI_ANY_ID, PCI_ANY_ID, 0},
128205869Sjfv
129205869Sjfv	{ 0x8086, E1000_DEV_ID_82543GC_FIBER,	PCI_ANY_ID, PCI_ANY_ID, 0},
130205869Sjfv	{ 0x8086, E1000_DEV_ID_82543GC_COPPER,	PCI_ANY_ID, PCI_ANY_ID, 0},
131205869Sjfv
132205869Sjfv	{ 0x8086, E1000_DEV_ID_82544EI_COPPER,	PCI_ANY_ID, PCI_ANY_ID, 0},
133205869Sjfv	{ 0x8086, E1000_DEV_ID_82544EI_FIBER,	PCI_ANY_ID, PCI_ANY_ID, 0},
134205869Sjfv	{ 0x8086, E1000_DEV_ID_82544GC_COPPER,	PCI_ANY_ID, PCI_ANY_ID, 0},
135205869Sjfv	{ 0x8086, E1000_DEV_ID_82544GC_LOM,	PCI_ANY_ID, PCI_ANY_ID, 0},
136205869Sjfv
137205869Sjfv	{ 0x8086, E1000_DEV_ID_82545EM_COPPER,	PCI_ANY_ID, PCI_ANY_ID, 0},
138205869Sjfv	{ 0x8086, E1000_DEV_ID_82545EM_FIBER,	PCI_ANY_ID, PCI_ANY_ID, 0},
139205869Sjfv	{ 0x8086, E1000_DEV_ID_82545GM_COPPER,	PCI_ANY_ID, PCI_ANY_ID, 0},
140205869Sjfv	{ 0x8086, E1000_DEV_ID_82545GM_FIBER,	PCI_ANY_ID, PCI_ANY_ID, 0},
141205869Sjfv	{ 0x8086, E1000_DEV_ID_82545GM_SERDES,	PCI_ANY_ID, PCI_ANY_ID, 0},
142205869Sjfv
143205869Sjfv	{ 0x8086, E1000_DEV_ID_82546EB_COPPER,	PCI_ANY_ID, PCI_ANY_ID, 0},
144205869Sjfv	{ 0x8086, E1000_DEV_ID_82546EB_FIBER,	PCI_ANY_ID, PCI_ANY_ID, 0},
145205869Sjfv	{ 0x8086, E1000_DEV_ID_82546EB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
146205869Sjfv	{ 0x8086, E1000_DEV_ID_82546GB_COPPER,	PCI_ANY_ID, PCI_ANY_ID, 0},
147205869Sjfv	{ 0x8086, E1000_DEV_ID_82546GB_FIBER,	PCI_ANY_ID, PCI_ANY_ID, 0},
148205869Sjfv	{ 0x8086, E1000_DEV_ID_82546GB_SERDES,	PCI_ANY_ID, PCI_ANY_ID, 0},
149205869Sjfv	{ 0x8086, E1000_DEV_ID_82546GB_PCIE,	PCI_ANY_ID, PCI_ANY_ID, 0},
150205869Sjfv	{ 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
151205869Sjfv	{ 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3,
152205869Sjfv						PCI_ANY_ID, PCI_ANY_ID, 0},
153205869Sjfv
154205869Sjfv	{ 0x8086, E1000_DEV_ID_82547EI,		PCI_ANY_ID, PCI_ANY_ID, 0},
155205869Sjfv	{ 0x8086, E1000_DEV_ID_82547EI_MOBILE,	PCI_ANY_ID, PCI_ANY_ID, 0},
156205869Sjfv	{ 0x8086, E1000_DEV_ID_82547GI,		PCI_ANY_ID, PCI_ANY_ID, 0},
157205869Sjfv	/* required last entry */
158205869Sjfv	{ 0, 0, 0, 0, 0}
159205869Sjfv};
160205869Sjfv
161205869Sjfv/*********************************************************************
162205869Sjfv *  Table of branding strings for all supported NICs.
163205869Sjfv *********************************************************************/
164205869Sjfv
165205869Sjfvstatic char *lem_strings[] = {
166205869Sjfv	"Intel(R) PRO/1000 Legacy Network Connection"
167205869Sjfv};
168205869Sjfv
169205869Sjfv/*********************************************************************
170205869Sjfv *  Function prototypes
171205869Sjfv *********************************************************************/
172205869Sjfvstatic int	lem_probe(device_t);
173205869Sjfvstatic int	lem_attach(device_t);
174205869Sjfvstatic int	lem_detach(device_t);
175205869Sjfvstatic int	lem_shutdown(device_t);
176205869Sjfvstatic int	lem_suspend(device_t);
177205869Sjfvstatic int	lem_resume(device_t);
178205869Sjfvstatic void	lem_start(struct ifnet *);
179205869Sjfvstatic void	lem_start_locked(struct ifnet *ifp);
180205869Sjfvstatic int	lem_ioctl(struct ifnet *, u_long, caddr_t);
181205869Sjfvstatic void	lem_init(void *);
182205869Sjfvstatic void	lem_init_locked(struct adapter *);
183205869Sjfvstatic void	lem_stop(void *);
184205869Sjfvstatic void	lem_media_status(struct ifnet *, struct ifmediareq *);
185205869Sjfvstatic int	lem_media_change(struct ifnet *);
186205869Sjfvstatic void	lem_identify_hardware(struct adapter *);
187205869Sjfvstatic int	lem_allocate_pci_resources(struct adapter *);
188205869Sjfvstatic int	lem_allocate_irq(struct adapter *adapter);
189205869Sjfvstatic void	lem_free_pci_resources(struct adapter *);
190205869Sjfvstatic void	lem_local_timer(void *);
191205869Sjfvstatic int	lem_hardware_init(struct adapter *);
192211907Syongaristatic int	lem_setup_interface(device_t, struct adapter *);
193205869Sjfvstatic void	lem_setup_transmit_structures(struct adapter *);
194205869Sjfvstatic void	lem_initialize_transmit_unit(struct adapter *);
195205869Sjfvstatic int	lem_setup_receive_structures(struct adapter *);
196205869Sjfvstatic void	lem_initialize_receive_unit(struct adapter *);
197205869Sjfvstatic void	lem_enable_intr(struct adapter *);
198205869Sjfvstatic void	lem_disable_intr(struct adapter *);
199205869Sjfvstatic void	lem_free_transmit_structures(struct adapter *);
200205869Sjfvstatic void	lem_free_receive_structures(struct adapter *);
201205869Sjfvstatic void	lem_update_stats_counters(struct adapter *);
202212902Sjhbstatic void	lem_add_hw_stats(struct adapter *adapter);
203205869Sjfvstatic void	lem_txeof(struct adapter *);
204205869Sjfvstatic void	lem_tx_purge(struct adapter *);
205205869Sjfvstatic int	lem_allocate_receive_structures(struct adapter *);
206205869Sjfvstatic int	lem_allocate_transmit_structures(struct adapter *);
207209238Sjfvstatic bool	lem_rxeof(struct adapter *, int, int *);
208205869Sjfv#ifndef __NO_STRICT_ALIGNMENT
209205869Sjfvstatic int	lem_fixup_rx(struct adapter *);
210205869Sjfv#endif
211205869Sjfvstatic void	lem_receive_checksum(struct adapter *, struct e1000_rx_desc *,
212205869Sjfv		    struct mbuf *);
213205869Sjfvstatic void	lem_transmit_checksum_setup(struct adapter *, struct mbuf *,
214205869Sjfv		    u32 *, u32 *);
215205869Sjfvstatic void	lem_set_promisc(struct adapter *);
216205869Sjfvstatic void	lem_disable_promisc(struct adapter *);
217205869Sjfvstatic void	lem_set_multi(struct adapter *);
218205869Sjfvstatic void	lem_update_link_status(struct adapter *);
219205869Sjfvstatic int	lem_get_buf(struct adapter *, int);
220205869Sjfvstatic void	lem_register_vlan(void *, struct ifnet *, u16);
221205869Sjfvstatic void	lem_unregister_vlan(void *, struct ifnet *, u16);
222205869Sjfvstatic void	lem_setup_vlan_hw_support(struct adapter *);
223205869Sjfvstatic int	lem_xmit(struct adapter *, struct mbuf **);
224205869Sjfvstatic void	lem_smartspeed(struct adapter *);
225205869Sjfvstatic int	lem_82547_fifo_workaround(struct adapter *, int);
226205869Sjfvstatic void	lem_82547_update_fifo_head(struct adapter *, int);
227205869Sjfvstatic int	lem_82547_tx_fifo_reset(struct adapter *);
228205869Sjfvstatic void	lem_82547_move_tail(void *);
229205869Sjfvstatic int	lem_dma_malloc(struct adapter *, bus_size_t,
230205869Sjfv		    struct em_dma_alloc *, int);
231205869Sjfvstatic void	lem_dma_free(struct adapter *, struct em_dma_alloc *);
232212902Sjhbstatic int	lem_sysctl_nvm_info(SYSCTL_HANDLER_ARGS);
233205869Sjfvstatic void	lem_print_nvm_info(struct adapter *);
234205869Sjfvstatic int 	lem_is_valid_ether_addr(u8 *);
235205869Sjfvstatic u32	lem_fill_descriptors (bus_addr_t address, u32 length,
236205869Sjfv		    PDESC_ARRAY desc_array);
237205869Sjfvstatic int	lem_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
238205869Sjfvstatic void	lem_add_int_delay_sysctl(struct adapter *, const char *,
239205869Sjfv		    const char *, struct em_int_delay_info *, int, int);
240214646Sjfvstatic void	lem_set_flow_cntrl(struct adapter *, const char *,
241214646Sjfv		    const char *, int *, int);
242205869Sjfv/* Management and WOL Support */
243205869Sjfvstatic void	lem_init_manageability(struct adapter *);
244205869Sjfvstatic void	lem_release_manageability(struct adapter *);
245205869Sjfvstatic void     lem_get_hw_control(struct adapter *);
246205869Sjfvstatic void     lem_release_hw_control(struct adapter *);
247205869Sjfvstatic void	lem_get_wakeup(device_t);
248205869Sjfvstatic void     lem_enable_wakeup(device_t);
249205869Sjfvstatic int	lem_enable_phy_wakeup(struct adapter *);
250206001Smariusstatic void	lem_led_func(void *, int);
251205869Sjfv
252205869Sjfvstatic void	lem_intr(void *);
253205869Sjfvstatic int	lem_irq_fast(void *);
254205869Sjfvstatic void	lem_handle_rxtx(void *context, int pending);
255205869Sjfvstatic void	lem_handle_link(void *context, int pending);
256205869Sjfvstatic void	lem_add_rx_process_limit(struct adapter *, const char *,
257205869Sjfv		    const char *, int *, int);
258205869Sjfv
259205869Sjfv#ifdef DEVICE_POLLING
260205987Sjfvstatic poll_handler_t lem_poll;
261205869Sjfv#endif /* POLLING */
262205869Sjfv
263205869Sjfv/*********************************************************************
264205869Sjfv *  FreeBSD Device Interface Entry Points
265205869Sjfv *********************************************************************/
266205869Sjfv
267205869Sjfvstatic device_method_t lem_methods[] = {
268205869Sjfv	/* Device interface */
269205869Sjfv	DEVMETHOD(device_probe, lem_probe),
270205869Sjfv	DEVMETHOD(device_attach, lem_attach),
271205869Sjfv	DEVMETHOD(device_detach, lem_detach),
272205869Sjfv	DEVMETHOD(device_shutdown, lem_shutdown),
273205869Sjfv	DEVMETHOD(device_suspend, lem_suspend),
274205869Sjfv	DEVMETHOD(device_resume, lem_resume),
275246128Ssbz	DEVMETHOD_END
276205869Sjfv};
277205869Sjfv
278205869Sjfvstatic driver_t lem_driver = {
279205869Sjfv	"em", lem_methods, sizeof(struct adapter),
280205869Sjfv};
281205869Sjfv
282205869Sjfvextern devclass_t em_devclass;
283205869SjfvDRIVER_MODULE(lem, pci, lem_driver, em_devclass, 0, 0);
284205869SjfvMODULE_DEPEND(lem, pci, 1, 1, 1);
285205869SjfvMODULE_DEPEND(lem, ether, 1, 1, 1);
286205869Sjfv
287205869Sjfv/*********************************************************************
288205869Sjfv *  Tunable default values.
289205869Sjfv *********************************************************************/
290205869Sjfv
291205869Sjfv#define EM_TICKS_TO_USECS(ticks)	((1024 * (ticks) + 500) / 1000)
292205869Sjfv#define EM_USECS_TO_TICKS(usecs)	((1000 * (usecs) + 512) / 1024)
293205869Sjfv
294250414Sluigi#define MAX_INTS_PER_SEC	8000
295250414Sluigi#define DEFAULT_ITR		(1000000000/(MAX_INTS_PER_SEC * 256))
296250414Sluigi
297205869Sjfvstatic int lem_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV);
298205869Sjfvstatic int lem_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR);
299205869Sjfvstatic int lem_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV);
300205869Sjfvstatic int lem_rx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_RADV);
301270252Sluigi/*
302270252Sluigi * increase lem_rxd and lem_txd to at least 2048 in netmap mode
303270252Sluigi * for better performance.
304270252Sluigi */
305205869Sjfvstatic int lem_rxd = EM_DEFAULT_RXD;
306205869Sjfvstatic int lem_txd = EM_DEFAULT_TXD;
307205869Sjfvstatic int lem_smart_pwr_down = FALSE;
308205869Sjfv
309205869Sjfv/* Controls whether promiscuous also shows bad packets */
310205869Sjfvstatic int lem_debug_sbp = FALSE;
311205869Sjfv
312205869SjfvTUNABLE_INT("hw.em.tx_int_delay", &lem_tx_int_delay_dflt);
313205869SjfvTUNABLE_INT("hw.em.rx_int_delay", &lem_rx_int_delay_dflt);
314205869SjfvTUNABLE_INT("hw.em.tx_abs_int_delay", &lem_tx_abs_int_delay_dflt);
315205869SjfvTUNABLE_INT("hw.em.rx_abs_int_delay", &lem_rx_abs_int_delay_dflt);
316205869SjfvTUNABLE_INT("hw.em.rxd", &lem_rxd);
317205869SjfvTUNABLE_INT("hw.em.txd", &lem_txd);
318205869SjfvTUNABLE_INT("hw.em.smart_pwr_down", &lem_smart_pwr_down);
319205869SjfvTUNABLE_INT("hw.em.sbp", &lem_debug_sbp);
320205869Sjfv
321238953Sjfv/* Interrupt style - default to fast */
322238953Sjfvstatic int lem_use_legacy_irq = 0;
323238953SjfvTUNABLE_INT("hw.em.use_legacy_irq", &lem_use_legacy_irq);
324238953Sjfv
325205869Sjfv/* How many packets rxeof tries to clean at a time */
326205869Sjfvstatic int lem_rx_process_limit = 100;
327205869SjfvTUNABLE_INT("hw.em.rx_process_limit", &lem_rx_process_limit);
328205869Sjfv
329205869Sjfv/* Flow control setting - default to FULL */
330205869Sjfvstatic int lem_fc_setting = e1000_fc_full;
331205869SjfvTUNABLE_INT("hw.em.fc_setting", &lem_fc_setting);
332205869Sjfv
333205869Sjfv/* Global used in WOL setup with multiport cards */
334205869Sjfvstatic int global_quad_port_a = 0;
335205869Sjfv
336228281Sluigi#ifdef DEV_NETMAP	/* see ixgbe.c for details */
337228281Sluigi#include <dev/netmap/if_lem_netmap.h>
338228281Sluigi#endif /* DEV_NETMAP */
339228281Sluigi
340205869Sjfv/*********************************************************************
341205869Sjfv *  Device identification routine
342205869Sjfv *
343205869Sjfv *  em_probe determines if the driver should be loaded on
344205869Sjfv *  adapter based on PCI vendor/device id of the adapter.
345205869Sjfv *
346205869Sjfv *  return BUS_PROBE_DEFAULT on success, positive on failure
347205869Sjfv *********************************************************************/
348205869Sjfv
349205869Sjfvstatic int
350205869Sjfvlem_probe(device_t dev)
351205869Sjfv{
352205869Sjfv	char		adapter_name[60];
353205869Sjfv	u16		pci_vendor_id = 0;
354205869Sjfv	u16		pci_device_id = 0;
355205869Sjfv	u16		pci_subvendor_id = 0;
356205869Sjfv	u16		pci_subdevice_id = 0;
357205869Sjfv	em_vendor_info_t *ent;
358205869Sjfv
359205869Sjfv	INIT_DEBUGOUT("em_probe: begin");
360205869Sjfv
361205869Sjfv	pci_vendor_id = pci_get_vendor(dev);
362205869Sjfv	if (pci_vendor_id != EM_VENDOR_ID)
363205869Sjfv		return (ENXIO);
364205869Sjfv
365205869Sjfv	pci_device_id = pci_get_device(dev);
366205869Sjfv	pci_subvendor_id = pci_get_subvendor(dev);
367205869Sjfv	pci_subdevice_id = pci_get_subdevice(dev);
368205869Sjfv
369205869Sjfv	ent = lem_vendor_info_array;
370205869Sjfv	while (ent->vendor_id != 0) {
371205869Sjfv		if ((pci_vendor_id == ent->vendor_id) &&
372205869Sjfv		    (pci_device_id == ent->device_id) &&
373205869Sjfv
374205869Sjfv		    ((pci_subvendor_id == ent->subvendor_id) ||
375205869Sjfv		    (ent->subvendor_id == PCI_ANY_ID)) &&
376205869Sjfv
377205869Sjfv		    ((pci_subdevice_id == ent->subdevice_id) ||
378205869Sjfv		    (ent->subdevice_id == PCI_ANY_ID))) {
379205869Sjfv			sprintf(adapter_name, "%s %s",
380205869Sjfv				lem_strings[ent->index],
381205869Sjfv				lem_driver_version);
382205869Sjfv			device_set_desc_copy(dev, adapter_name);
383205869Sjfv			return (BUS_PROBE_DEFAULT);
384205869Sjfv		}
385205869Sjfv		ent++;
386205869Sjfv	}
387205869Sjfv
388205869Sjfv	return (ENXIO);
389205869Sjfv}
390205869Sjfv
391205869Sjfv/*********************************************************************
392205869Sjfv *  Device initialization routine
393205869Sjfv *
394205869Sjfv *  The attach entry point is called when the driver is being loaded.
395205869Sjfv *  This routine identifies the type of hardware, allocates all resources
396205869Sjfv *  and initializes the hardware.
397205869Sjfv *
398205869Sjfv *  return 0 on success, positive on failure
399205869Sjfv *********************************************************************/
400205869Sjfv
401205869Sjfvstatic int
402205869Sjfvlem_attach(device_t dev)
403205869Sjfv{
404205869Sjfv	struct adapter	*adapter;
405205869Sjfv	int		tsize, rsize;
406205869Sjfv	int		error = 0;
407205869Sjfv
408205869Sjfv	INIT_DEBUGOUT("lem_attach: begin");
409205869Sjfv
410205869Sjfv	adapter = device_get_softc(dev);
411205869Sjfv	adapter->dev = adapter->osdep.dev = dev;
412205869Sjfv	EM_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
413205869Sjfv	EM_TX_LOCK_INIT(adapter, device_get_nameunit(dev));
414205869Sjfv	EM_RX_LOCK_INIT(adapter, device_get_nameunit(dev));
415205869Sjfv
416205869Sjfv	/* SYSCTL stuff */
417205869Sjfv	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
418205869Sjfv	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
419212902Sjhb	    OID_AUTO, "nvm", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
420212902Sjhb	    lem_sysctl_nvm_info, "I", "NVM Information");
421205869Sjfv
422205869Sjfv	callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
423205869Sjfv	callout_init_mtx(&adapter->tx_fifo_timer, &adapter->tx_mtx, 0);
424205869Sjfv
425205869Sjfv	/* Determine hardware and mac info */
426205869Sjfv	lem_identify_hardware(adapter);
427205869Sjfv
428205869Sjfv	/* Setup PCI resources */
429205869Sjfv	if (lem_allocate_pci_resources(adapter)) {
430205869Sjfv		device_printf(dev, "Allocation of PCI resources failed\n");
431205869Sjfv		error = ENXIO;
432205869Sjfv		goto err_pci;
433205869Sjfv	}
434205869Sjfv
435205869Sjfv	/* Do Shared Code initialization */
436205869Sjfv	if (e1000_setup_init_funcs(&adapter->hw, TRUE)) {
437205869Sjfv		device_printf(dev, "Setup of Shared code failed\n");
438205869Sjfv		error = ENXIO;
439205869Sjfv		goto err_pci;
440205869Sjfv	}
441205869Sjfv
442205869Sjfv	e1000_get_bus_info(&adapter->hw);
443205869Sjfv
444205869Sjfv	/* Set up some sysctls for the tunable interrupt delays */
445205869Sjfv	lem_add_int_delay_sysctl(adapter, "rx_int_delay",
446205869Sjfv	    "receive interrupt delay in usecs", &adapter->rx_int_delay,
447205869Sjfv	    E1000_REGISTER(&adapter->hw, E1000_RDTR), lem_rx_int_delay_dflt);
448205869Sjfv	lem_add_int_delay_sysctl(adapter, "tx_int_delay",
449205869Sjfv	    "transmit interrupt delay in usecs", &adapter->tx_int_delay,
450205869Sjfv	    E1000_REGISTER(&adapter->hw, E1000_TIDV), lem_tx_int_delay_dflt);
451205869Sjfv	if (adapter->hw.mac.type >= e1000_82540) {
452205869Sjfv		lem_add_int_delay_sysctl(adapter, "rx_abs_int_delay",
453205869Sjfv		    "receive interrupt delay limit in usecs",
454205869Sjfv		    &adapter->rx_abs_int_delay,
455205869Sjfv		    E1000_REGISTER(&adapter->hw, E1000_RADV),
456205869Sjfv		    lem_rx_abs_int_delay_dflt);
457205869Sjfv		lem_add_int_delay_sysctl(adapter, "tx_abs_int_delay",
458205869Sjfv		    "transmit interrupt delay limit in usecs",
459205869Sjfv		    &adapter->tx_abs_int_delay,
460205869Sjfv		    E1000_REGISTER(&adapter->hw, E1000_TADV),
461205869Sjfv		    lem_tx_abs_int_delay_dflt);
462250414Sluigi		lem_add_int_delay_sysctl(adapter, "itr",
463250414Sluigi		    "interrupt delay limit in usecs/4",
464250414Sluigi		    &adapter->tx_itr,
465250414Sluigi		    E1000_REGISTER(&adapter->hw, E1000_ITR),
466250414Sluigi		    DEFAULT_ITR);
467205869Sjfv	}
468205869Sjfv
469205869Sjfv	/* Sysctls for limiting the amount of work done in the taskqueue */
470205869Sjfv	lem_add_rx_process_limit(adapter, "rx_processing_limit",
471205869Sjfv	    "max number of rx packets to process", &adapter->rx_process_limit,
472205869Sjfv	    lem_rx_process_limit);
473205869Sjfv
474270252Sluigi#ifdef NIC_SEND_COMBINING
475270252Sluigi	/* Sysctls to control mitigation */
476270252Sluigi	lem_add_rx_process_limit(adapter, "sc_enable",
477270252Sluigi	    "driver TDT mitigation", &adapter->sc_enable, 0);
478270252Sluigi#endif /* NIC_SEND_COMBINING */
479270252Sluigi#ifdef BATCH_DISPATCH
480270252Sluigi	lem_add_rx_process_limit(adapter, "batch_enable",
481270252Sluigi	    "driver rx batch", &adapter->batch_enable, 0);
482270252Sluigi#endif /* BATCH_DISPATCH */
483270252Sluigi#ifdef NIC_PARAVIRT
484270252Sluigi	lem_add_rx_process_limit(adapter, "rx_retries",
485270252Sluigi	    "driver rx retries", &adapter->rx_retries, 0);
486270252Sluigi#endif /* NIC_PARAVIRT */
487270252Sluigi
488214646Sjfv        /* Sysctl for setting the interface flow control */
489214646Sjfv	lem_set_flow_cntrl(adapter, "flow_control",
490228387Sjfv	    "flow control setting",
491214646Sjfv	    &adapter->fc_setting, lem_fc_setting);
492214646Sjfv
493205869Sjfv	/*
494205869Sjfv	 * Validate number of transmit and receive descriptors. It
495205869Sjfv	 * must not exceed hardware maximum, and must be multiple
496205869Sjfv	 * of E1000_DBA_ALIGN.
497205869Sjfv	 */
498205869Sjfv	if (((lem_txd * sizeof(struct e1000_tx_desc)) % EM_DBA_ALIGN) != 0 ||
499205869Sjfv	    (adapter->hw.mac.type >= e1000_82544 && lem_txd > EM_MAX_TXD) ||
500205869Sjfv	    (adapter->hw.mac.type < e1000_82544 && lem_txd > EM_MAX_TXD_82543) ||
501205869Sjfv	    (lem_txd < EM_MIN_TXD)) {
502205869Sjfv		device_printf(dev, "Using %d TX descriptors instead of %d!\n",
503205869Sjfv		    EM_DEFAULT_TXD, lem_txd);
504205869Sjfv		adapter->num_tx_desc = EM_DEFAULT_TXD;
505205869Sjfv	} else
506205869Sjfv		adapter->num_tx_desc = lem_txd;
507205869Sjfv	if (((lem_rxd * sizeof(struct e1000_rx_desc)) % EM_DBA_ALIGN) != 0 ||
508205869Sjfv	    (adapter->hw.mac.type >= e1000_82544 && lem_rxd > EM_MAX_RXD) ||
509205869Sjfv	    (adapter->hw.mac.type < e1000_82544 && lem_rxd > EM_MAX_RXD_82543) ||
510205869Sjfv	    (lem_rxd < EM_MIN_RXD)) {
511205869Sjfv		device_printf(dev, "Using %d RX descriptors instead of %d!\n",
512205869Sjfv		    EM_DEFAULT_RXD, lem_rxd);
513205869Sjfv		adapter->num_rx_desc = EM_DEFAULT_RXD;
514205869Sjfv	} else
515205869Sjfv		adapter->num_rx_desc = lem_rxd;
516205869Sjfv
517205869Sjfv	adapter->hw.mac.autoneg = DO_AUTO_NEG;
518205869Sjfv	adapter->hw.phy.autoneg_wait_to_complete = FALSE;
519205869Sjfv	adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT;
520205869Sjfv	adapter->rx_buffer_len = 2048;
521205869Sjfv
522205869Sjfv	e1000_init_script_state_82541(&adapter->hw, TRUE);
523205869Sjfv	e1000_set_tbi_compatibility_82543(&adapter->hw, TRUE);
524205869Sjfv
525205869Sjfv	/* Copper options */
526205869Sjfv	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
527205869Sjfv		adapter->hw.phy.mdix = AUTO_ALL_MODES;
528205869Sjfv		adapter->hw.phy.disable_polarity_correction = FALSE;
529205869Sjfv		adapter->hw.phy.ms_type = EM_MASTER_SLAVE;
530205869Sjfv	}
531205869Sjfv
532205869Sjfv	/*
533205869Sjfv	 * Set the frame limits assuming
534205869Sjfv	 * standard ethernet sized frames.
535205869Sjfv	 */
536205869Sjfv	adapter->max_frame_size = ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE;
537205869Sjfv	adapter->min_frame_size = ETH_ZLEN + ETHERNET_FCS_SIZE;
538205869Sjfv
539205869Sjfv	/*
540205869Sjfv	 * This controls when hardware reports transmit completion
541205869Sjfv	 * status.
542205869Sjfv	 */
543205869Sjfv	adapter->hw.mac.report_tx_early = 1;
544205869Sjfv
545270252Sluigi#ifdef NIC_PARAVIRT
546270252Sluigi	device_printf(dev, "driver supports paravirt, subdev 0x%x\n",
547270252Sluigi		adapter->hw.subsystem_device_id);
548270252Sluigi	if (adapter->hw.subsystem_device_id == E1000_PARA_SUBDEV) {
549270252Sluigi		uint64_t bus_addr;
550270252Sluigi
551270252Sluigi		device_printf(dev, "paravirt support on dev %p\n", adapter);
552270252Sluigi		tsize = 4096; // XXX one page for the csb
553270252Sluigi		if (lem_dma_malloc(adapter, tsize, &adapter->csb_mem, BUS_DMA_NOWAIT)) {
554270252Sluigi			device_printf(dev, "Unable to allocate csb memory\n");
555270252Sluigi			error = ENOMEM;
556270252Sluigi			goto err_csb;
557270252Sluigi		}
558270252Sluigi		/* Setup the Base of the CSB */
559270252Sluigi		adapter->csb = (struct paravirt_csb *)adapter->csb_mem.dma_vaddr;
560270252Sluigi		/* force the first kick */
561270252Sluigi		adapter->csb->host_need_txkick = 1; /* txring empty */
562270252Sluigi		adapter->csb->guest_need_rxkick = 1; /* no rx packets */
563270252Sluigi		bus_addr = adapter->csb_mem.dma_paddr;
564270252Sluigi		lem_add_rx_process_limit(adapter, "csb_on",
565270252Sluigi		    "enable paravirt.", &adapter->csb->guest_csb_on, 0);
566270252Sluigi		lem_add_rx_process_limit(adapter, "txc_lim",
567270252Sluigi		    "txc_lim", &adapter->csb->host_txcycles_lim, 1);
568270252Sluigi
569270252Sluigi		/* some stats */
570270252Sluigi#define PA_SC(name, var, val)		\
571270252Sluigi	lem_add_rx_process_limit(adapter, name, name, var, val)
572270252Sluigi		PA_SC("host_need_txkick",&adapter->csb->host_need_txkick, 1);
573270252Sluigi		PA_SC("host_rxkick_at",&adapter->csb->host_rxkick_at, ~0);
574270252Sluigi		PA_SC("guest_need_txkick",&adapter->csb->guest_need_txkick, 0);
575270252Sluigi		PA_SC("guest_need_rxkick",&adapter->csb->guest_need_rxkick, 1);
576270252Sluigi		PA_SC("tdt_reg_count",&adapter->tdt_reg_count, 0);
577270252Sluigi		PA_SC("tdt_csb_count",&adapter->tdt_csb_count, 0);
578270252Sluigi		PA_SC("tdt_int_count",&adapter->tdt_int_count, 0);
579270252Sluigi		PA_SC("guest_need_kick_count",&adapter->guest_need_kick_count, 0);
580270252Sluigi		/* tell the host where the block is */
581270252Sluigi		E1000_WRITE_REG(&adapter->hw, E1000_CSBAH,
582270252Sluigi			(u32)(bus_addr >> 32));
583270252Sluigi		E1000_WRITE_REG(&adapter->hw, E1000_CSBAL,
584270252Sluigi			(u32)bus_addr);
585270252Sluigi	}
586270252Sluigi#endif /* NIC_PARAVIRT */
587270252Sluigi
588205869Sjfv	tsize = roundup2(adapter->num_tx_desc * sizeof(struct e1000_tx_desc),
589205869Sjfv	    EM_DBA_ALIGN);
590205869Sjfv
591205869Sjfv	/* Allocate Transmit Descriptor ring */
592205869Sjfv	if (lem_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
593205869Sjfv		device_printf(dev, "Unable to allocate tx_desc memory\n");
594205869Sjfv		error = ENOMEM;
595205869Sjfv		goto err_tx_desc;
596205869Sjfv	}
597205869Sjfv	adapter->tx_desc_base =
598205869Sjfv	    (struct e1000_tx_desc *)adapter->txdma.dma_vaddr;
599205869Sjfv
600205869Sjfv	rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc),
601205869Sjfv	    EM_DBA_ALIGN);
602205869Sjfv
603205869Sjfv	/* Allocate Receive Descriptor ring */
604205869Sjfv	if (lem_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
605205869Sjfv		device_printf(dev, "Unable to allocate rx_desc memory\n");
606205869Sjfv		error = ENOMEM;
607205869Sjfv		goto err_rx_desc;
608205869Sjfv	}
609205869Sjfv	adapter->rx_desc_base =
610205869Sjfv	    (struct e1000_rx_desc *)adapter->rxdma.dma_vaddr;
611205869Sjfv
612211913Syongari	/* Allocate multicast array memory. */
613211913Syongari	adapter->mta = malloc(sizeof(u8) * ETH_ADDR_LEN *
614211913Syongari	    MAX_NUM_MULTICAST_ADDRESSES, M_DEVBUF, M_NOWAIT);
615211913Syongari	if (adapter->mta == NULL) {
616211913Syongari		device_printf(dev, "Can not allocate multicast setup array\n");
617211913Syongari		error = ENOMEM;
618211913Syongari		goto err_hw_init;
619211913Syongari	}
620211913Syongari
621205869Sjfv	/*
622205869Sjfv	** Start from a known state, this is
623205869Sjfv	** important in reading the nvm and
624205869Sjfv	** mac from that.
625205869Sjfv	*/
626205869Sjfv	e1000_reset_hw(&adapter->hw);
627205869Sjfv
628205869Sjfv	/* Make sure we have a good EEPROM before we read from it */
629205869Sjfv	if (e1000_validate_nvm_checksum(&adapter->hw) < 0) {
630205869Sjfv		/*
631205869Sjfv		** Some PCI-E parts fail the first check due to
632205869Sjfv		** the link being in sleep state, call it again,
633205869Sjfv		** if it fails a second time its a real issue.
634205869Sjfv		*/
635205869Sjfv		if (e1000_validate_nvm_checksum(&adapter->hw) < 0) {
636205869Sjfv			device_printf(dev,
637205869Sjfv			    "The EEPROM Checksum Is Not Valid\n");
638205869Sjfv			error = EIO;
639205869Sjfv			goto err_hw_init;
640205869Sjfv		}
641205869Sjfv	}
642205869Sjfv
643205869Sjfv	/* Copy the permanent MAC address out of the EEPROM */
644205869Sjfv	if (e1000_read_mac_addr(&adapter->hw) < 0) {
645205869Sjfv		device_printf(dev, "EEPROM read error while reading MAC"
646205869Sjfv		    " address\n");
647205869Sjfv		error = EIO;
648205869Sjfv		goto err_hw_init;
649205869Sjfv	}
650205869Sjfv
651205869Sjfv	if (!lem_is_valid_ether_addr(adapter->hw.mac.addr)) {
652205869Sjfv		device_printf(dev, "Invalid MAC address\n");
653205869Sjfv		error = EIO;
654205869Sjfv		goto err_hw_init;
655205869Sjfv	}
656205869Sjfv
657205869Sjfv	/* Initialize the hardware */
658205869Sjfv	if (lem_hardware_init(adapter)) {
659205869Sjfv		device_printf(dev, "Unable to initialize the hardware\n");
660205869Sjfv		error = EIO;
661205869Sjfv		goto err_hw_init;
662205869Sjfv	}
663205869Sjfv
664205869Sjfv	/* Allocate transmit descriptors and buffers */
665205869Sjfv	if (lem_allocate_transmit_structures(adapter)) {
666205869Sjfv		device_printf(dev, "Could not setup transmit structures\n");
667205869Sjfv		error = ENOMEM;
668205869Sjfv		goto err_tx_struct;
669205869Sjfv	}
670205869Sjfv
671205869Sjfv	/* Allocate receive descriptors and buffers */
672205869Sjfv	if (lem_allocate_receive_structures(adapter)) {
673205869Sjfv		device_printf(dev, "Could not setup receive structures\n");
674205869Sjfv		error = ENOMEM;
675205869Sjfv		goto err_rx_struct;
676205869Sjfv	}
677205869Sjfv
678205869Sjfv	/*
679205869Sjfv	**  Do interrupt configuration
680205869Sjfv	*/
681205869Sjfv	error = lem_allocate_irq(adapter);
682205869Sjfv	if (error)
683205869Sjfv		goto err_rx_struct;
684205869Sjfv
685205869Sjfv	/*
686205869Sjfv	 * Get Wake-on-Lan and Management info for later use
687205869Sjfv	 */
688205869Sjfv	lem_get_wakeup(dev);
689205869Sjfv
690205869Sjfv	/* Setup OS specific network interface */
691211907Syongari	if (lem_setup_interface(dev, adapter) != 0)
692211907Syongari		goto err_rx_struct;
693205869Sjfv
694205869Sjfv	/* Initialize statistics */
695205869Sjfv	lem_update_stats_counters(adapter);
696205869Sjfv
697205869Sjfv	adapter->hw.mac.get_link_status = 1;
698205869Sjfv	lem_update_link_status(adapter);
699205869Sjfv
700205869Sjfv	/* Indicate SOL/IDER usage */
701205869Sjfv	if (e1000_check_reset_block(&adapter->hw))
702205869Sjfv		device_printf(dev,
703205869Sjfv		    "PHY reset is blocked due to SOL/IDER session.\n");
704205869Sjfv
705205869Sjfv	/* Do we need workaround for 82544 PCI-X adapter? */
706205869Sjfv	if (adapter->hw.bus.type == e1000_bus_type_pcix &&
707205869Sjfv	    adapter->hw.mac.type == e1000_82544)
708205869Sjfv		adapter->pcix_82544 = TRUE;
709205869Sjfv	else
710205869Sjfv		adapter->pcix_82544 = FALSE;
711205869Sjfv
712205869Sjfv	/* Register for VLAN events */
713205869Sjfv	adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
714205869Sjfv	    lem_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
715205869Sjfv	adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
716205869Sjfv	    lem_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
717205869Sjfv
718212902Sjhb	lem_add_hw_stats(adapter);
719212902Sjhb
720205869Sjfv	/* Non-AMT based hardware can now take control from firmware */
721205869Sjfv	if (adapter->has_manage && !adapter->has_amt)
722205869Sjfv		lem_get_hw_control(adapter);
723205869Sjfv
724205869Sjfv	/* Tell the stack that the interface is not active */
725205869Sjfv	adapter->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
726205869Sjfv
727206001Smarius	adapter->led_dev = led_create(lem_led_func, adapter,
728206001Smarius	    device_get_nameunit(dev));
729206001Smarius
730228281Sluigi#ifdef DEV_NETMAP
731228281Sluigi	lem_netmap_attach(adapter);
732228281Sluigi#endif /* DEV_NETMAP */
733205869Sjfv	INIT_DEBUGOUT("lem_attach: end");
734205869Sjfv
735205869Sjfv	return (0);
736205869Sjfv
737205869Sjfverr_rx_struct:
738205869Sjfv	lem_free_transmit_structures(adapter);
739205869Sjfverr_tx_struct:
740205869Sjfverr_hw_init:
741205869Sjfv	lem_release_hw_control(adapter);
742205869Sjfv	lem_dma_free(adapter, &adapter->rxdma);
743205869Sjfverr_rx_desc:
744205869Sjfv	lem_dma_free(adapter, &adapter->txdma);
745205869Sjfverr_tx_desc:
746270252Sluigi#ifdef NIC_PARAVIRT
747270252Sluigi	lem_dma_free(adapter, &adapter->csb_mem);
748270252Sluigierr_csb:
749270252Sluigi#endif /* NIC_PARAVIRT */
750270252Sluigi
751205869Sjfverr_pci:
752211907Syongari	if (adapter->ifp != NULL)
753211907Syongari		if_free(adapter->ifp);
754205869Sjfv	lem_free_pci_resources(adapter);
755211913Syongari	free(adapter->mta, M_DEVBUF);
756205869Sjfv	EM_TX_LOCK_DESTROY(adapter);
757205869Sjfv	EM_RX_LOCK_DESTROY(adapter);
758205869Sjfv	EM_CORE_LOCK_DESTROY(adapter);
759205869Sjfv
760205869Sjfv	return (error);
761205869Sjfv}
762205869Sjfv
763205869Sjfv/*********************************************************************
764205869Sjfv *  Device removal routine
765205869Sjfv *
766205869Sjfv *  The detach entry point is called when the driver is being removed.
767205869Sjfv *  This routine stops the adapter and deallocates all the resources
768205869Sjfv *  that were allocated for driver operation.
769205869Sjfv *
770205869Sjfv *  return 0 on success, positive on failure
771205869Sjfv *********************************************************************/
772205869Sjfv
773205869Sjfvstatic int
774205869Sjfvlem_detach(device_t dev)
775205869Sjfv{
776205869Sjfv	struct adapter	*adapter = device_get_softc(dev);
777205869Sjfv	struct ifnet	*ifp = adapter->ifp;
778205869Sjfv
779205869Sjfv	INIT_DEBUGOUT("em_detach: begin");
780205869Sjfv
781205869Sjfv	/* Make sure VLANS are not using driver */
782205869Sjfv	if (adapter->ifp->if_vlantrunk != NULL) {
783205869Sjfv		device_printf(dev,"Vlan in use, detach first\n");
784205869Sjfv		return (EBUSY);
785205869Sjfv	}
786205869Sjfv
787205869Sjfv#ifdef DEVICE_POLLING
788205869Sjfv	if (ifp->if_capenable & IFCAP_POLLING)
789205869Sjfv		ether_poll_deregister(ifp);
790205869Sjfv#endif
791205869Sjfv
792206001Smarius	if (adapter->led_dev != NULL)
793206001Smarius		led_destroy(adapter->led_dev);
794206001Smarius
795205869Sjfv	EM_CORE_LOCK(adapter);
796205869Sjfv	EM_TX_LOCK(adapter);
797205869Sjfv	adapter->in_detach = 1;
798205869Sjfv	lem_stop(adapter);
799205869Sjfv	e1000_phy_hw_reset(&adapter->hw);
800205869Sjfv
801205869Sjfv	lem_release_manageability(adapter);
802205869Sjfv
803205869Sjfv	EM_TX_UNLOCK(adapter);
804205869Sjfv	EM_CORE_UNLOCK(adapter);
805205869Sjfv
806205869Sjfv	/* Unregister VLAN events */
807205869Sjfv	if (adapter->vlan_attach != NULL)
808205869Sjfv		EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach);
809205869Sjfv	if (adapter->vlan_detach != NULL)
810205869Sjfv		EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach);
811205869Sjfv
812205869Sjfv	ether_ifdetach(adapter->ifp);
813205869Sjfv	callout_drain(&adapter->timer);
814205869Sjfv	callout_drain(&adapter->tx_fifo_timer);
815205869Sjfv
816228281Sluigi#ifdef DEV_NETMAP
817228281Sluigi	netmap_detach(ifp);
818228281Sluigi#endif /* DEV_NETMAP */
819205869Sjfv	lem_free_pci_resources(adapter);
820205869Sjfv	bus_generic_detach(dev);
821205869Sjfv	if_free(ifp);
822205869Sjfv
823205869Sjfv	lem_free_transmit_structures(adapter);
824205869Sjfv	lem_free_receive_structures(adapter);
825205869Sjfv
826205869Sjfv	/* Free Transmit Descriptor ring */
827205869Sjfv	if (adapter->tx_desc_base) {
828205869Sjfv		lem_dma_free(adapter, &adapter->txdma);
829205869Sjfv		adapter->tx_desc_base = NULL;
830205869Sjfv	}
831205869Sjfv
832205869Sjfv	/* Free Receive Descriptor ring */
833205869Sjfv	if (adapter->rx_desc_base) {
834205869Sjfv		lem_dma_free(adapter, &adapter->rxdma);
835205869Sjfv		adapter->rx_desc_base = NULL;
836205869Sjfv	}
837205869Sjfv
838270252Sluigi#ifdef NIC_PARAVIRT
839270252Sluigi	if (adapter->csb) {
840270252Sluigi		lem_dma_free(adapter, &adapter->csb_mem);
841270252Sluigi		adapter->csb = NULL;
842270252Sluigi	}
843270252Sluigi#endif /* NIC_PARAVIRT */
844205869Sjfv	lem_release_hw_control(adapter);
845211913Syongari	free(adapter->mta, M_DEVBUF);
846205869Sjfv	EM_TX_LOCK_DESTROY(adapter);
847205869Sjfv	EM_RX_LOCK_DESTROY(adapter);
848205869Sjfv	EM_CORE_LOCK_DESTROY(adapter);
849205869Sjfv
850205869Sjfv	return (0);
851205869Sjfv}
852205869Sjfv
853205869Sjfv/*********************************************************************
854205869Sjfv *
855205869Sjfv *  Shutdown entry point
856205869Sjfv *
857205869Sjfv **********************************************************************/
858205869Sjfv
859205869Sjfvstatic int
860205869Sjfvlem_shutdown(device_t dev)
861205869Sjfv{
862205869Sjfv	return lem_suspend(dev);
863205869Sjfv}
864205869Sjfv
865205869Sjfv/*
866205869Sjfv * Suspend/resume device methods.
867205869Sjfv */
868205869Sjfvstatic int
869205869Sjfvlem_suspend(device_t dev)
870205869Sjfv{
871205869Sjfv	struct adapter *adapter = device_get_softc(dev);
872205869Sjfv
873205869Sjfv	EM_CORE_LOCK(adapter);
874205869Sjfv
875205869Sjfv	lem_release_manageability(adapter);
876205869Sjfv	lem_release_hw_control(adapter);
877205869Sjfv	lem_enable_wakeup(dev);
878205869Sjfv
879205869Sjfv	EM_CORE_UNLOCK(adapter);
880205869Sjfv
881205869Sjfv	return bus_generic_suspend(dev);
882205869Sjfv}
883205869Sjfv
884205869Sjfvstatic int
885205869Sjfvlem_resume(device_t dev)
886205869Sjfv{
887205869Sjfv	struct adapter *adapter = device_get_softc(dev);
888205869Sjfv	struct ifnet *ifp = adapter->ifp;
889205869Sjfv
890205869Sjfv	EM_CORE_LOCK(adapter);
891205869Sjfv	lem_init_locked(adapter);
892205869Sjfv	lem_init_manageability(adapter);
893205869Sjfv	EM_CORE_UNLOCK(adapter);
894205869Sjfv	lem_start(ifp);
895205869Sjfv
896205869Sjfv	return bus_generic_resume(dev);
897205869Sjfv}
898205869Sjfv
899205869Sjfv
900205869Sjfvstatic void
901205869Sjfvlem_start_locked(struct ifnet *ifp)
902205869Sjfv{
903205869Sjfv	struct adapter	*adapter = ifp->if_softc;
904205869Sjfv	struct mbuf	*m_head;
905205869Sjfv
906205869Sjfv	EM_TX_LOCK_ASSERT(adapter);
907205869Sjfv
908205869Sjfv	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
909205869Sjfv	    IFF_DRV_RUNNING)
910205869Sjfv		return;
911205869Sjfv	if (!adapter->link_active)
912205869Sjfv		return;
913205869Sjfv
914214646Sjfv        /*
915214646Sjfv         * Force a cleanup if number of TX descriptors
916214646Sjfv         * available hits the threshold
917214646Sjfv         */
918214646Sjfv	if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
919214646Sjfv		lem_txeof(adapter);
920214646Sjfv		/* Now do we at least have a minimal? */
921214646Sjfv		if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) {
922214646Sjfv			adapter->no_tx_desc_avail1++;
923214646Sjfv			return;
924214646Sjfv		}
925214646Sjfv	}
926214646Sjfv
927205869Sjfv	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
928205869Sjfv
929205869Sjfv                IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
930205869Sjfv		if (m_head == NULL)
931205869Sjfv			break;
932205869Sjfv		/*
933205869Sjfv		 *  Encapsulation can modify our pointer, and or make it
934205869Sjfv		 *  NULL on failure.  In that event, we can't requeue.
935205869Sjfv		 */
936205869Sjfv		if (lem_xmit(adapter, &m_head)) {
937205869Sjfv			if (m_head == NULL)
938205869Sjfv				break;
939205869Sjfv			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
940205869Sjfv			IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
941205869Sjfv			break;
942205869Sjfv		}
943205869Sjfv
944205869Sjfv		/* Send a copy of the frame to the BPF listener */
945205869Sjfv		ETHER_BPF_MTAP(ifp, m_head);
946205869Sjfv
947205869Sjfv		/* Set timeout in case hardware has problems transmitting. */
948205869Sjfv		adapter->watchdog_check = TRUE;
949206614Sjfv		adapter->watchdog_time = ticks;
950205869Sjfv	}
951205869Sjfv	if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
952205869Sjfv		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
953270252Sluigi#ifdef NIC_PARAVIRT
954289386Sadrian	if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) && adapter->csb &&
955270252Sluigi	    adapter->csb->guest_csb_on &&
956270252Sluigi	    !(adapter->csb->guest_need_txkick & 1))  {
957270252Sluigi		adapter->csb->guest_need_txkick = 1;
958270252Sluigi		adapter->guest_need_kick_count++;
959270252Sluigi		// XXX memory barrier
960270252Sluigi		lem_txeof(adapter); // XXX possibly clear IFF_DRV_OACTIVE
961270252Sluigi	}
962270252Sluigi#endif /* NIC_PARAVIRT */
963205869Sjfv
964205869Sjfv	return;
965205869Sjfv}
966205869Sjfv
967205869Sjfvstatic void
968205869Sjfvlem_start(struct ifnet *ifp)
969205869Sjfv{
970205869Sjfv	struct adapter *adapter = ifp->if_softc;
971205869Sjfv
972205869Sjfv	EM_TX_LOCK(adapter);
973205869Sjfv	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
974205869Sjfv		lem_start_locked(ifp);
975205869Sjfv	EM_TX_UNLOCK(adapter);
976205869Sjfv}
977205869Sjfv
978205869Sjfv/*********************************************************************
979205869Sjfv *  Ioctl entry point
980205869Sjfv *
981205869Sjfv *  em_ioctl is called when the user wants to configure the
982205869Sjfv *  interface.
983205869Sjfv *
984205869Sjfv *  return 0 on success, positive on failure
985205869Sjfv **********************************************************************/
986205869Sjfv
987205869Sjfvstatic int
988205869Sjfvlem_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
989205869Sjfv{
990205869Sjfv	struct adapter	*adapter = ifp->if_softc;
991228387Sjfv	struct ifreq	*ifr = (struct ifreq *)data;
992228387Sjfv#if defined(INET) || defined(INET6)
993228387Sjfv	struct ifaddr	*ifa = (struct ifaddr *)data;
994205869Sjfv#endif
995228387Sjfv	bool		avoid_reset = FALSE;
996228387Sjfv	int		error = 0;
997205869Sjfv
998205869Sjfv	if (adapter->in_detach)
999205869Sjfv		return (error);
1000205869Sjfv
1001205869Sjfv	switch (command) {
1002205869Sjfv	case SIOCSIFADDR:
1003205869Sjfv#ifdef INET
1004228387Sjfv		if (ifa->ifa_addr->sa_family == AF_INET)
1005228387Sjfv			avoid_reset = TRUE;
1006228387Sjfv#endif
1007228387Sjfv#ifdef INET6
1008228387Sjfv		if (ifa->ifa_addr->sa_family == AF_INET6)
1009228387Sjfv			avoid_reset = TRUE;
1010228387Sjfv#endif
1011228387Sjfv		/*
1012228387Sjfv		** Calling init results in link renegotiation,
1013228387Sjfv		** so we avoid doing it when possible.
1014228387Sjfv		*/
1015228387Sjfv		if (avoid_reset) {
1016205869Sjfv			ifp->if_flags |= IFF_UP;
1017228387Sjfv			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1018228387Sjfv				lem_init(adapter);
1019228387Sjfv#ifdef INET
1020228387Sjfv			if (!(ifp->if_flags & IFF_NOARP))
1021228387Sjfv				arp_ifinit(ifp, ifa);
1022228387Sjfv#endif
1023205869Sjfv		} else
1024205869Sjfv			error = ether_ioctl(ifp, command, data);
1025205869Sjfv		break;
1026205869Sjfv	case SIOCSIFMTU:
1027205869Sjfv	    {
1028205869Sjfv		int max_frame_size;
1029205869Sjfv
1030205869Sjfv		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)");
1031205869Sjfv
1032205869Sjfv		EM_CORE_LOCK(adapter);
1033205869Sjfv		switch (adapter->hw.mac.type) {
1034205869Sjfv		case e1000_82542:
1035205869Sjfv			max_frame_size = ETHER_MAX_LEN;
1036205869Sjfv			break;
1037205869Sjfv		default:
1038205869Sjfv			max_frame_size = MAX_JUMBO_FRAME_SIZE;
1039205869Sjfv		}
1040205869Sjfv		if (ifr->ifr_mtu > max_frame_size - ETHER_HDR_LEN -
1041205869Sjfv		    ETHER_CRC_LEN) {
1042205869Sjfv			EM_CORE_UNLOCK(adapter);
1043205869Sjfv			error = EINVAL;
1044205869Sjfv			break;
1045205869Sjfv		}
1046205869Sjfv
1047205869Sjfv		ifp->if_mtu = ifr->ifr_mtu;
1048205869Sjfv		adapter->max_frame_size =
1049205869Sjfv		    ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
1050205869Sjfv		lem_init_locked(adapter);
1051205869Sjfv		EM_CORE_UNLOCK(adapter);
1052205869Sjfv		break;
1053205869Sjfv	    }
1054205869Sjfv	case SIOCSIFFLAGS:
1055205869Sjfv		IOCTL_DEBUGOUT("ioctl rcv'd:\
1056205869Sjfv		    SIOCSIFFLAGS (Set Interface Flags)");
1057205869Sjfv		EM_CORE_LOCK(adapter);
1058205869Sjfv		if (ifp->if_flags & IFF_UP) {
1059205869Sjfv			if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1060205869Sjfv				if ((ifp->if_flags ^ adapter->if_flags) &
1061205869Sjfv				    (IFF_PROMISC | IFF_ALLMULTI)) {
1062205869Sjfv					lem_disable_promisc(adapter);
1063205869Sjfv					lem_set_promisc(adapter);
1064205869Sjfv				}
1065205869Sjfv			} else
1066205869Sjfv				lem_init_locked(adapter);
1067205869Sjfv		} else
1068205869Sjfv			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1069205869Sjfv				EM_TX_LOCK(adapter);
1070205869Sjfv				lem_stop(adapter);
1071205869Sjfv				EM_TX_UNLOCK(adapter);
1072205869Sjfv			}
1073205869Sjfv		adapter->if_flags = ifp->if_flags;
1074205869Sjfv		EM_CORE_UNLOCK(adapter);
1075205869Sjfv		break;
1076205869Sjfv	case SIOCADDMULTI:
1077205869Sjfv	case SIOCDELMULTI:
1078205869Sjfv		IOCTL_DEBUGOUT("ioctl rcv'd: SIOC(ADD|DEL)MULTI");
1079205869Sjfv		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1080205869Sjfv			EM_CORE_LOCK(adapter);
1081205869Sjfv			lem_disable_intr(adapter);
1082205869Sjfv			lem_set_multi(adapter);
1083205869Sjfv			if (adapter->hw.mac.type == e1000_82542 &&
1084205869Sjfv	    		    adapter->hw.revision_id == E1000_REVISION_2) {
1085205869Sjfv				lem_initialize_receive_unit(adapter);
1086205869Sjfv			}
1087205869Sjfv#ifdef DEVICE_POLLING
1088205869Sjfv			if (!(ifp->if_capenable & IFCAP_POLLING))
1089205869Sjfv#endif
1090205869Sjfv				lem_enable_intr(adapter);
1091205869Sjfv			EM_CORE_UNLOCK(adapter);
1092205869Sjfv		}
1093205869Sjfv		break;
1094205869Sjfv	case SIOCSIFMEDIA:
1095205869Sjfv		/* Check SOL/IDER usage */
1096205869Sjfv		EM_CORE_LOCK(adapter);
1097205869Sjfv		if (e1000_check_reset_block(&adapter->hw)) {
1098205869Sjfv			EM_CORE_UNLOCK(adapter);
1099205869Sjfv			device_printf(adapter->dev, "Media change is"
1100205869Sjfv			    " blocked due to SOL/IDER session.\n");
1101205869Sjfv			break;
1102205869Sjfv		}
1103205869Sjfv		EM_CORE_UNLOCK(adapter);
1104205869Sjfv	case SIOCGIFMEDIA:
1105205869Sjfv		IOCTL_DEBUGOUT("ioctl rcv'd: \
1106205869Sjfv		    SIOCxIFMEDIA (Get/Set Interface Media)");
1107205869Sjfv		error = ifmedia_ioctl(ifp, ifr, &adapter->media, command);
1108205869Sjfv		break;
1109205869Sjfv	case SIOCSIFCAP:
1110205869Sjfv	    {
1111205869Sjfv		int mask, reinit;
1112205869Sjfv
1113205869Sjfv		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)");
1114205869Sjfv		reinit = 0;
1115205869Sjfv		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
1116205869Sjfv#ifdef DEVICE_POLLING
1117205869Sjfv		if (mask & IFCAP_POLLING) {
1118205869Sjfv			if (ifr->ifr_reqcap & IFCAP_POLLING) {
1119205869Sjfv				error = ether_poll_register(lem_poll, ifp);
1120205869Sjfv				if (error)
1121205869Sjfv					return (error);
1122205869Sjfv				EM_CORE_LOCK(adapter);
1123205869Sjfv				lem_disable_intr(adapter);
1124205869Sjfv				ifp->if_capenable |= IFCAP_POLLING;
1125205869Sjfv				EM_CORE_UNLOCK(adapter);
1126205869Sjfv			} else {
1127205869Sjfv				error = ether_poll_deregister(ifp);
1128205869Sjfv				/* Enable interrupt even in error case */
1129205869Sjfv				EM_CORE_LOCK(adapter);
1130205869Sjfv				lem_enable_intr(adapter);
1131205869Sjfv				ifp->if_capenable &= ~IFCAP_POLLING;
1132205869Sjfv				EM_CORE_UNLOCK(adapter);
1133205869Sjfv			}
1134205869Sjfv		}
1135205869Sjfv#endif
1136205869Sjfv		if (mask & IFCAP_HWCSUM) {
1137205869Sjfv			ifp->if_capenable ^= IFCAP_HWCSUM;
1138205869Sjfv			reinit = 1;
1139205869Sjfv		}
1140205869Sjfv		if (mask & IFCAP_VLAN_HWTAGGING) {
1141205869Sjfv			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
1142205869Sjfv			reinit = 1;
1143205869Sjfv		}
1144205869Sjfv		if ((mask & IFCAP_WOL) &&
1145205869Sjfv		    (ifp->if_capabilities & IFCAP_WOL) != 0) {
1146205869Sjfv			if (mask & IFCAP_WOL_MCAST)
1147205869Sjfv				ifp->if_capenable ^= IFCAP_WOL_MCAST;
1148205869Sjfv			if (mask & IFCAP_WOL_MAGIC)
1149205869Sjfv				ifp->if_capenable ^= IFCAP_WOL_MAGIC;
1150205869Sjfv		}
1151205869Sjfv		if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1152205869Sjfv			lem_init(adapter);
1153205869Sjfv		VLAN_CAPABILITIES(ifp);
1154205869Sjfv		break;
1155205869Sjfv	    }
1156205869Sjfv
1157205869Sjfv	default:
1158205869Sjfv		error = ether_ioctl(ifp, command, data);
1159205869Sjfv		break;
1160205869Sjfv	}
1161205869Sjfv
1162205869Sjfv	return (error);
1163205869Sjfv}
1164205869Sjfv
1165205869Sjfv
1166205869Sjfv/*********************************************************************
1167205869Sjfv *  Init entry point
1168205869Sjfv *
1169205869Sjfv *  This routine is used in two ways. It is used by the stack as
1170205869Sjfv *  init entry point in network interface structure. It is also used
1171205869Sjfv *  by the driver as a hw/sw initialization routine to get to a
1172205869Sjfv *  consistent state.
1173205869Sjfv *
1174205869Sjfv *  return 0 on success, positive on failure
1175205869Sjfv **********************************************************************/
1176205869Sjfv
1177205869Sjfvstatic void
1178205869Sjfvlem_init_locked(struct adapter *adapter)
1179205869Sjfv{
1180205869Sjfv	struct ifnet	*ifp = adapter->ifp;
1181205869Sjfv	device_t	dev = adapter->dev;
1182205869Sjfv	u32		pba;
1183205869Sjfv
1184205869Sjfv	INIT_DEBUGOUT("lem_init: begin");
1185205869Sjfv
1186205869Sjfv	EM_CORE_LOCK_ASSERT(adapter);
1187205869Sjfv
1188205869Sjfv	EM_TX_LOCK(adapter);
1189205869Sjfv	lem_stop(adapter);
1190205869Sjfv	EM_TX_UNLOCK(adapter);
1191205869Sjfv
1192205869Sjfv	/*
1193205869Sjfv	 * Packet Buffer Allocation (PBA)
1194205869Sjfv	 * Writing PBA sets the receive portion of the buffer
1195205869Sjfv	 * the remainder is used for the transmit buffer.
1196205869Sjfv	 *
1197205869Sjfv	 * Devices before the 82547 had a Packet Buffer of 64K.
1198205869Sjfv	 *   Default allocation: PBA=48K for Rx, leaving 16K for Tx.
1199205869Sjfv	 * After the 82547 the buffer was reduced to 40K.
1200205869Sjfv	 *   Default allocation: PBA=30K for Rx, leaving 10K for Tx.
1201205869Sjfv	 *   Note: default does not leave enough room for Jumbo Frame >10k.
1202205869Sjfv	 */
1203205869Sjfv	switch (adapter->hw.mac.type) {
1204205869Sjfv	case e1000_82547:
1205205869Sjfv	case e1000_82547_rev_2: /* 82547: Total Packet Buffer is 40K */
1206205869Sjfv		if (adapter->max_frame_size > 8192)
1207205869Sjfv			pba = E1000_PBA_22K; /* 22K for Rx, 18K for Tx */
1208205869Sjfv		else
1209205869Sjfv			pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */
1210205869Sjfv		adapter->tx_fifo_head = 0;
1211205869Sjfv		adapter->tx_head_addr = pba << EM_TX_HEAD_ADDR_SHIFT;
1212205869Sjfv		adapter->tx_fifo_size =
1213205869Sjfv		    (E1000_PBA_40K - pba) << EM_PBA_BYTES_SHIFT;
1214205869Sjfv		break;
1215205869Sjfv	default:
1216205869Sjfv		/* Devices before 82547 had a Packet Buffer of 64K.   */
1217205869Sjfv		if (adapter->max_frame_size > 8192)
1218205869Sjfv			pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */
1219205869Sjfv		else
1220205869Sjfv			pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */
1221205869Sjfv	}
1222205869Sjfv
1223205869Sjfv	INIT_DEBUGOUT1("lem_init: pba=%dK",pba);
1224205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_PBA, pba);
1225205869Sjfv
1226205869Sjfv	/* Get the latest mac address, User can use a LAA */
1227205869Sjfv        bcopy(IF_LLADDR(adapter->ifp), adapter->hw.mac.addr,
1228205869Sjfv              ETHER_ADDR_LEN);
1229205869Sjfv
1230205869Sjfv	/* Put the address into the Receive Address Array */
1231205869Sjfv	e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
1232205869Sjfv
1233205869Sjfv	/* Initialize the hardware */
1234205869Sjfv	if (lem_hardware_init(adapter)) {
1235205869Sjfv		device_printf(dev, "Unable to initialize the hardware\n");
1236205869Sjfv		return;
1237205869Sjfv	}
1238205869Sjfv	lem_update_link_status(adapter);
1239205869Sjfv
1240205869Sjfv	/* Setup VLAN support, basic and offload if available */
1241205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
1242205869Sjfv
1243205869Sjfv	/* Set hardware offload abilities */
1244205869Sjfv	ifp->if_hwassist = 0;
1245205869Sjfv	if (adapter->hw.mac.type >= e1000_82543) {
1246205869Sjfv		if (ifp->if_capenable & IFCAP_TXCSUM)
1247205869Sjfv			ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
1248205869Sjfv	}
1249205869Sjfv
1250205869Sjfv	/* Configure for OS presence */
1251205869Sjfv	lem_init_manageability(adapter);
1252205869Sjfv
1253205869Sjfv	/* Prepare transmit descriptors and buffers */
1254205869Sjfv	lem_setup_transmit_structures(adapter);
1255205869Sjfv	lem_initialize_transmit_unit(adapter);
1256205869Sjfv
1257205869Sjfv	/* Setup Multicast table */
1258205869Sjfv	lem_set_multi(adapter);
1259205869Sjfv
1260205869Sjfv	/* Prepare receive descriptors and buffers */
1261205869Sjfv	if (lem_setup_receive_structures(adapter)) {
1262205869Sjfv		device_printf(dev, "Could not setup receive structures\n");
1263205869Sjfv		EM_TX_LOCK(adapter);
1264205869Sjfv		lem_stop(adapter);
1265205869Sjfv		EM_TX_UNLOCK(adapter);
1266205869Sjfv		return;
1267205869Sjfv	}
1268205869Sjfv	lem_initialize_receive_unit(adapter);
1269205869Sjfv
1270214646Sjfv	/* Use real VLAN Filter support? */
1271214646Sjfv	if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
1272214646Sjfv		if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
1273214646Sjfv			/* Use real VLAN Filter support */
1274214646Sjfv			lem_setup_vlan_hw_support(adapter);
1275214646Sjfv		else {
1276214646Sjfv			u32 ctrl;
1277214646Sjfv			ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
1278214646Sjfv			ctrl |= E1000_CTRL_VME;
1279214646Sjfv			E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
1280214646Sjfv                }
1281214646Sjfv	}
1282214646Sjfv
1283205869Sjfv	/* Don't lose promiscuous settings */
1284205869Sjfv	lem_set_promisc(adapter);
1285205869Sjfv
1286205869Sjfv	ifp->if_drv_flags |= IFF_DRV_RUNNING;
1287205869Sjfv	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1288205869Sjfv
1289205869Sjfv	callout_reset(&adapter->timer, hz, lem_local_timer, adapter);
1290205869Sjfv	e1000_clear_hw_cntrs_base_generic(&adapter->hw);
1291205869Sjfv
1292205869Sjfv#ifdef DEVICE_POLLING
1293205869Sjfv	/*
1294205869Sjfv	 * Only enable interrupts if we are not polling, make sure
1295205869Sjfv	 * they are off otherwise.
1296205869Sjfv	 */
1297205869Sjfv	if (ifp->if_capenable & IFCAP_POLLING)
1298205869Sjfv		lem_disable_intr(adapter);
1299205869Sjfv	else
1300205869Sjfv#endif /* DEVICE_POLLING */
1301205869Sjfv		lem_enable_intr(adapter);
1302205869Sjfv
1303205869Sjfv	/* AMT based hardware can now take control from firmware */
1304205869Sjfv	if (adapter->has_manage && adapter->has_amt)
1305205869Sjfv		lem_get_hw_control(adapter);
1306205869Sjfv}
1307205869Sjfv
1308205869Sjfvstatic void
1309205869Sjfvlem_init(void *arg)
1310205869Sjfv{
1311205869Sjfv	struct adapter *adapter = arg;
1312205869Sjfv
1313205869Sjfv	EM_CORE_LOCK(adapter);
1314205869Sjfv	lem_init_locked(adapter);
1315205869Sjfv	EM_CORE_UNLOCK(adapter);
1316205869Sjfv}
1317205869Sjfv
1318205869Sjfv
1319205869Sjfv#ifdef DEVICE_POLLING
1320205869Sjfv/*********************************************************************
1321205869Sjfv *
1322205869Sjfv *  Legacy polling routine
1323205869Sjfv *
1324205869Sjfv *********************************************************************/
1325205869Sjfvstatic int
1326205869Sjfvlem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
1327205869Sjfv{
1328205869Sjfv	struct adapter *adapter = ifp->if_softc;
1329205869Sjfv	u32		reg_icr, rx_done = 0;
1330205869Sjfv
1331205869Sjfv	EM_CORE_LOCK(adapter);
1332205869Sjfv	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1333205869Sjfv		EM_CORE_UNLOCK(adapter);
1334205869Sjfv		return (rx_done);
1335205869Sjfv	}
1336205869Sjfv
1337205869Sjfv	if (cmd == POLL_AND_CHECK_STATUS) {
1338205869Sjfv		reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
1339205869Sjfv		if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
1340205869Sjfv			callout_stop(&adapter->timer);
1341205869Sjfv			adapter->hw.mac.get_link_status = 1;
1342205869Sjfv			lem_update_link_status(adapter);
1343205869Sjfv			callout_reset(&adapter->timer, hz,
1344205869Sjfv			    lem_local_timer, adapter);
1345205869Sjfv		}
1346205869Sjfv	}
1347205869Sjfv	EM_CORE_UNLOCK(adapter);
1348205869Sjfv
1349209238Sjfv	lem_rxeof(adapter, count, &rx_done);
1350205869Sjfv
1351205869Sjfv	EM_TX_LOCK(adapter);
1352205869Sjfv	lem_txeof(adapter);
1353205869Sjfv	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
1354205869Sjfv		lem_start_locked(ifp);
1355205869Sjfv	EM_TX_UNLOCK(adapter);
1356205869Sjfv	return (rx_done);
1357205869Sjfv}
1358205869Sjfv#endif /* DEVICE_POLLING */
1359205869Sjfv
1360205869Sjfv/*********************************************************************
1361205869Sjfv *
1362205869Sjfv *  Legacy Interrupt Service routine
1363205869Sjfv *
1364205869Sjfv *********************************************************************/
1365205869Sjfvstatic void
1366205869Sjfvlem_intr(void *arg)
1367205869Sjfv{
1368205869Sjfv	struct adapter	*adapter = arg;
1369205869Sjfv	struct ifnet	*ifp = adapter->ifp;
1370205869Sjfv	u32		reg_icr;
1371205869Sjfv
1372205869Sjfv
1373238953Sjfv	if ((ifp->if_capenable & IFCAP_POLLING) ||
1374238953Sjfv	    ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0))
1375205869Sjfv		return;
1376205869Sjfv
1377205869Sjfv	EM_CORE_LOCK(adapter);
1378205869Sjfv	reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
1379205869Sjfv	if (reg_icr & E1000_ICR_RXO)
1380205869Sjfv		adapter->rx_overruns++;
1381205869Sjfv
1382238953Sjfv	if ((reg_icr == 0xffffffff) || (reg_icr == 0)) {
1383238953Sjfv		EM_CORE_UNLOCK(adapter);
1384238953Sjfv		return;
1385238953Sjfv	}
1386205869Sjfv
1387205869Sjfv	if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
1388205869Sjfv		callout_stop(&adapter->timer);
1389205869Sjfv		adapter->hw.mac.get_link_status = 1;
1390205869Sjfv		lem_update_link_status(adapter);
1391205869Sjfv		/* Deal with TX cruft when link lost */
1392205869Sjfv		lem_tx_purge(adapter);
1393205869Sjfv		callout_reset(&adapter->timer, hz,
1394205869Sjfv		    lem_local_timer, adapter);
1395238953Sjfv		EM_CORE_UNLOCK(adapter);
1396238953Sjfv		return;
1397205869Sjfv	}
1398205869Sjfv
1399238953Sjfv	EM_CORE_UNLOCK(adapter);
1400238953Sjfv	lem_rxeof(adapter, -1, NULL);
1401238953Sjfv
1402205869Sjfv	EM_TX_LOCK(adapter);
1403205869Sjfv	lem_txeof(adapter);
1404205869Sjfv	if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
1405205869Sjfv	    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
1406205869Sjfv		lem_start_locked(ifp);
1407205869Sjfv	EM_TX_UNLOCK(adapter);
1408205869Sjfv	return;
1409205869Sjfv}
1410205869Sjfv
1411205869Sjfv
1412205869Sjfvstatic void
1413205869Sjfvlem_handle_link(void *context, int pending)
1414205869Sjfv{
1415205869Sjfv	struct adapter	*adapter = context;
1416205869Sjfv	struct ifnet *ifp = adapter->ifp;
1417205869Sjfv
1418205869Sjfv	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1419205869Sjfv		return;
1420205869Sjfv
1421205869Sjfv	EM_CORE_LOCK(adapter);
1422205869Sjfv	callout_stop(&adapter->timer);
1423205869Sjfv	lem_update_link_status(adapter);
1424205869Sjfv	/* Deal with TX cruft when link lost */
1425205869Sjfv	lem_tx_purge(adapter);
1426205869Sjfv	callout_reset(&adapter->timer, hz, lem_local_timer, adapter);
1427205869Sjfv	EM_CORE_UNLOCK(adapter);
1428205869Sjfv}
1429205869Sjfv
1430205869Sjfv
1431205869Sjfv/* Combined RX/TX handler, used by Legacy and MSI */
1432205869Sjfvstatic void
1433205869Sjfvlem_handle_rxtx(void *context, int pending)
1434205869Sjfv{
1435205869Sjfv	struct adapter	*adapter = context;
1436205869Sjfv	struct ifnet	*ifp = adapter->ifp;
1437205869Sjfv
1438205869Sjfv
1439205869Sjfv	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1440250414Sluigi		bool more = lem_rxeof(adapter, adapter->rx_process_limit, NULL);
1441205869Sjfv		EM_TX_LOCK(adapter);
1442205869Sjfv		lem_txeof(adapter);
1443205869Sjfv		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
1444205869Sjfv			lem_start_locked(ifp);
1445205869Sjfv		EM_TX_UNLOCK(adapter);
1446250414Sluigi		if (more) {
1447250414Sluigi			taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
1448250414Sluigi			return;
1449250414Sluigi		}
1450205869Sjfv	}
1451205869Sjfv
1452214646Sjfv	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1453214646Sjfv		lem_enable_intr(adapter);
1454205869Sjfv}
1455205869Sjfv
1456205869Sjfv/*********************************************************************
1457205869Sjfv *
1458205869Sjfv *  Fast Legacy/MSI Combined Interrupt Service routine
1459205869Sjfv *
1460205869Sjfv *********************************************************************/
1461205869Sjfvstatic int
1462205869Sjfvlem_irq_fast(void *arg)
1463205869Sjfv{
1464205869Sjfv	struct adapter	*adapter = arg;
1465205869Sjfv	struct ifnet	*ifp;
1466205869Sjfv	u32		reg_icr;
1467205869Sjfv
1468205869Sjfv	ifp = adapter->ifp;
1469205869Sjfv
1470205869Sjfv	reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
1471205869Sjfv
1472205869Sjfv	/* Hot eject?  */
1473205869Sjfv	if (reg_icr == 0xffffffff)
1474205869Sjfv		return FILTER_STRAY;
1475205869Sjfv
1476205869Sjfv	/* Definitely not our interrupt.  */
1477205869Sjfv	if (reg_icr == 0x0)
1478205869Sjfv		return FILTER_STRAY;
1479205869Sjfv
1480205869Sjfv	/*
1481205869Sjfv	 * Mask interrupts until the taskqueue is finished running.  This is
1482205869Sjfv	 * cheap, just assume that it is needed.  This also works around the
1483205869Sjfv	 * MSI message reordering errata on certain systems.
1484205869Sjfv	 */
1485205869Sjfv	lem_disable_intr(adapter);
1486205869Sjfv	taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
1487205869Sjfv
1488205869Sjfv	/* Link status change */
1489205869Sjfv	if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
1490205869Sjfv		adapter->hw.mac.get_link_status = 1;
1491205869Sjfv		taskqueue_enqueue(taskqueue_fast, &adapter->link_task);
1492205869Sjfv	}
1493205869Sjfv
1494205869Sjfv	if (reg_icr & E1000_ICR_RXO)
1495205869Sjfv		adapter->rx_overruns++;
1496205869Sjfv	return FILTER_HANDLED;
1497205869Sjfv}
1498205869Sjfv
1499205869Sjfv
1500205869Sjfv/*********************************************************************
1501205869Sjfv *
1502205869Sjfv *  Media Ioctl callback
1503205869Sjfv *
1504205869Sjfv *  This routine is called whenever the user queries the status of
1505205869Sjfv *  the interface using ifconfig.
1506205869Sjfv *
1507205869Sjfv **********************************************************************/
1508205869Sjfvstatic void
1509205869Sjfvlem_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1510205869Sjfv{
1511205869Sjfv	struct adapter *adapter = ifp->if_softc;
1512205869Sjfv	u_char fiber_type = IFM_1000_SX;
1513205869Sjfv
1514205869Sjfv	INIT_DEBUGOUT("lem_media_status: begin");
1515205869Sjfv
1516205869Sjfv	EM_CORE_LOCK(adapter);
1517205869Sjfv	lem_update_link_status(adapter);
1518205869Sjfv
1519205869Sjfv	ifmr->ifm_status = IFM_AVALID;
1520205869Sjfv	ifmr->ifm_active = IFM_ETHER;
1521205869Sjfv
1522205869Sjfv	if (!adapter->link_active) {
1523205869Sjfv		EM_CORE_UNLOCK(adapter);
1524205869Sjfv		return;
1525205869Sjfv	}
1526205869Sjfv
1527205869Sjfv	ifmr->ifm_status |= IFM_ACTIVE;
1528205869Sjfv
1529205869Sjfv	if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
1530205869Sjfv	    (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) {
1531205869Sjfv		if (adapter->hw.mac.type == e1000_82545)
1532205869Sjfv			fiber_type = IFM_1000_LX;
1533205869Sjfv		ifmr->ifm_active |= fiber_type | IFM_FDX;
1534205869Sjfv	} else {
1535205869Sjfv		switch (adapter->link_speed) {
1536205869Sjfv		case 10:
1537205869Sjfv			ifmr->ifm_active |= IFM_10_T;
1538205869Sjfv			break;
1539205869Sjfv		case 100:
1540205869Sjfv			ifmr->ifm_active |= IFM_100_TX;
1541205869Sjfv			break;
1542205869Sjfv		case 1000:
1543205869Sjfv			ifmr->ifm_active |= IFM_1000_T;
1544205869Sjfv			break;
1545205869Sjfv		}
1546205869Sjfv		if (adapter->link_duplex == FULL_DUPLEX)
1547205869Sjfv			ifmr->ifm_active |= IFM_FDX;
1548205869Sjfv		else
1549205869Sjfv			ifmr->ifm_active |= IFM_HDX;
1550205869Sjfv	}
1551205869Sjfv	EM_CORE_UNLOCK(adapter);
1552205869Sjfv}
1553205869Sjfv
1554205869Sjfv/*********************************************************************
1555205869Sjfv *
1556205869Sjfv *  Media Ioctl callback
1557205869Sjfv *
1558205869Sjfv *  This routine is called when the user changes speed/duplex using
1559205869Sjfv *  media/mediopt option with ifconfig.
1560205869Sjfv *
1561205869Sjfv **********************************************************************/
1562205869Sjfvstatic int
1563205869Sjfvlem_media_change(struct ifnet *ifp)
1564205869Sjfv{
1565205869Sjfv	struct adapter *adapter = ifp->if_softc;
1566205869Sjfv	struct ifmedia  *ifm = &adapter->media;
1567205869Sjfv
1568205869Sjfv	INIT_DEBUGOUT("lem_media_change: begin");
1569205869Sjfv
1570205869Sjfv	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
1571205869Sjfv		return (EINVAL);
1572205869Sjfv
1573205869Sjfv	EM_CORE_LOCK(adapter);
1574205869Sjfv	switch (IFM_SUBTYPE(ifm->ifm_media)) {
1575205869Sjfv	case IFM_AUTO:
1576205869Sjfv		adapter->hw.mac.autoneg = DO_AUTO_NEG;
1577205869Sjfv		adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT;
1578205869Sjfv		break;
1579205869Sjfv	case IFM_1000_LX:
1580205869Sjfv	case IFM_1000_SX:
1581205869Sjfv	case IFM_1000_T:
1582205869Sjfv		adapter->hw.mac.autoneg = DO_AUTO_NEG;
1583205869Sjfv		adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL;
1584205869Sjfv		break;
1585205869Sjfv	case IFM_100_TX:
1586205869Sjfv		adapter->hw.mac.autoneg = FALSE;
1587205869Sjfv		adapter->hw.phy.autoneg_advertised = 0;
1588205869Sjfv		if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
1589205869Sjfv			adapter->hw.mac.forced_speed_duplex = ADVERTISE_100_FULL;
1590205869Sjfv		else
1591205869Sjfv			adapter->hw.mac.forced_speed_duplex = ADVERTISE_100_HALF;
1592205869Sjfv		break;
1593205869Sjfv	case IFM_10_T:
1594205869Sjfv		adapter->hw.mac.autoneg = FALSE;
1595205869Sjfv		adapter->hw.phy.autoneg_advertised = 0;
1596205869Sjfv		if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
1597205869Sjfv			adapter->hw.mac.forced_speed_duplex = ADVERTISE_10_FULL;
1598205869Sjfv		else
1599205869Sjfv			adapter->hw.mac.forced_speed_duplex = ADVERTISE_10_HALF;
1600205869Sjfv		break;
1601205869Sjfv	default:
1602205869Sjfv		device_printf(adapter->dev, "Unsupported media type\n");
1603205869Sjfv	}
1604205869Sjfv
1605205869Sjfv	lem_init_locked(adapter);
1606205869Sjfv	EM_CORE_UNLOCK(adapter);
1607205869Sjfv
1608205869Sjfv	return (0);
1609205869Sjfv}
1610205869Sjfv
1611205869Sjfv/*********************************************************************
1612205869Sjfv *
1613205869Sjfv *  This routine maps the mbufs to tx descriptors.
1614205869Sjfv *
1615205869Sjfv *  return 0 on success, positive on failure
1616205869Sjfv **********************************************************************/
1617205869Sjfv
1618205869Sjfvstatic int
1619205869Sjfvlem_xmit(struct adapter *adapter, struct mbuf **m_headp)
1620205869Sjfv{
1621205869Sjfv	bus_dma_segment_t	segs[EM_MAX_SCATTER];
1622205869Sjfv	bus_dmamap_t		map;
1623205869Sjfv	struct em_buffer	*tx_buffer, *tx_buffer_mapped;
1624205869Sjfv	struct e1000_tx_desc	*ctxd = NULL;
1625205869Sjfv	struct mbuf		*m_head;
1626205869Sjfv	u32			txd_upper, txd_lower, txd_used, txd_saved;
1627205869Sjfv	int			error, nsegs, i, j, first, last = 0;
1628214646Sjfv
1629205869Sjfv	m_head = *m_headp;
1630205869Sjfv	txd_upper = txd_lower = txd_used = txd_saved = 0;
1631205869Sjfv
1632205869Sjfv	/*
1633209959Sjfv	** When doing checksum offload, it is critical to
1634209959Sjfv	** make sure the first mbuf has more than header,
1635209959Sjfv	** because that routine expects data to be present.
1636209959Sjfv	*/
1637209959Sjfv	if ((m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) &&
1638209959Sjfv	    (m_head->m_len < ETHER_HDR_LEN + sizeof(struct ip))) {
1639209959Sjfv		m_head = m_pullup(m_head, ETHER_HDR_LEN + sizeof(struct ip));
1640209959Sjfv		*m_headp = m_head;
1641209959Sjfv		if (m_head == NULL)
1642209959Sjfv			return (ENOBUFS);
1643209959Sjfv	}
1644209959Sjfv
1645209959Sjfv	/*
1646205869Sjfv	 * Map the packet for DMA
1647205869Sjfv	 *
1648205869Sjfv	 * Capture the first descriptor index,
1649205869Sjfv	 * this descriptor will have the index
1650205869Sjfv	 * of the EOP which is the only one that
1651205869Sjfv	 * now gets a DONE bit writeback.
1652205869Sjfv	 */
1653205869Sjfv	first = adapter->next_avail_tx_desc;
1654205869Sjfv	tx_buffer = &adapter->tx_buffer_area[first];
1655205869Sjfv	tx_buffer_mapped = tx_buffer;
1656205869Sjfv	map = tx_buffer->map;
1657205869Sjfv
1658205869Sjfv	error = bus_dmamap_load_mbuf_sg(adapter->txtag, map,
1659205869Sjfv	    *m_headp, segs, &nsegs, BUS_DMA_NOWAIT);
1660205869Sjfv
1661205869Sjfv	/*
1662205869Sjfv	 * There are two types of errors we can (try) to handle:
1663205869Sjfv	 * - EFBIG means the mbuf chain was too long and bus_dma ran
1664205869Sjfv	 *   out of segments.  Defragment the mbuf chain and try again.
1665205869Sjfv	 * - ENOMEM means bus_dma could not obtain enough bounce buffers
1666205869Sjfv	 *   at this point in time.  Defer sending and try again later.
1667205869Sjfv	 * All other errors, in particular EINVAL, are fatal and prevent the
1668205869Sjfv	 * mbuf chain from ever going through.  Drop it and report error.
1669205869Sjfv	 */
1670205869Sjfv	if (error == EFBIG) {
1671205869Sjfv		struct mbuf *m;
1672205869Sjfv
1673294958Smarius		m = m_collapse(*m_headp, M_NOWAIT, EM_MAX_SCATTER);
1674205869Sjfv		if (m == NULL) {
1675294958Smarius			adapter->mbuf_defrag_failed++;
1676205869Sjfv			m_freem(*m_headp);
1677205869Sjfv			*m_headp = NULL;
1678205869Sjfv			return (ENOBUFS);
1679205869Sjfv		}
1680205869Sjfv		*m_headp = m;
1681205869Sjfv
1682205869Sjfv		/* Try it again */
1683205869Sjfv		error = bus_dmamap_load_mbuf_sg(adapter->txtag, map,
1684205869Sjfv		    *m_headp, segs, &nsegs, BUS_DMA_NOWAIT);
1685205869Sjfv
1686205869Sjfv		if (error) {
1687205869Sjfv			adapter->no_tx_dma_setup++;
1688205869Sjfv			m_freem(*m_headp);
1689205869Sjfv			*m_headp = NULL;
1690205869Sjfv			return (error);
1691205869Sjfv		}
1692205869Sjfv	} else if (error != 0) {
1693205869Sjfv		adapter->no_tx_dma_setup++;
1694205869Sjfv		return (error);
1695205869Sjfv	}
1696205869Sjfv
1697205869Sjfv        if (nsegs > (adapter->num_tx_desc_avail - 2)) {
1698205869Sjfv                adapter->no_tx_desc_avail2++;
1699205869Sjfv		bus_dmamap_unload(adapter->txtag, map);
1700205869Sjfv		return (ENOBUFS);
1701205869Sjfv        }
1702205869Sjfv	m_head = *m_headp;
1703205869Sjfv
1704205869Sjfv	/* Do hardware assists */
1705205869Sjfv	if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD)
1706205869Sjfv		lem_transmit_checksum_setup(adapter,  m_head,
1707205869Sjfv		    &txd_upper, &txd_lower);
1708205869Sjfv
1709205869Sjfv	i = adapter->next_avail_tx_desc;
1710205869Sjfv	if (adapter->pcix_82544)
1711205869Sjfv		txd_saved = i;
1712205869Sjfv
1713205869Sjfv	/* Set up our transmit descriptors */
1714205869Sjfv	for (j = 0; j < nsegs; j++) {
1715205869Sjfv		bus_size_t seg_len;
1716205869Sjfv		bus_addr_t seg_addr;
1717205869Sjfv		/* If adapter is 82544 and on PCIX bus */
1718205869Sjfv		if(adapter->pcix_82544) {
1719205869Sjfv			DESC_ARRAY	desc_array;
1720205869Sjfv			u32		array_elements, counter;
1721205869Sjfv			/*
1722205869Sjfv			 * Check the Address and Length combination and
1723205869Sjfv			 * split the data accordingly
1724205869Sjfv			 */
1725205869Sjfv			array_elements = lem_fill_descriptors(segs[j].ds_addr,
1726205869Sjfv			    segs[j].ds_len, &desc_array);
1727205869Sjfv			for (counter = 0; counter < array_elements; counter++) {
1728205869Sjfv				if (txd_used == adapter->num_tx_desc_avail) {
1729205869Sjfv					adapter->next_avail_tx_desc = txd_saved;
1730205869Sjfv					adapter->no_tx_desc_avail2++;
1731205869Sjfv					bus_dmamap_unload(adapter->txtag, map);
1732205869Sjfv					return (ENOBUFS);
1733205869Sjfv				}
1734205869Sjfv				tx_buffer = &adapter->tx_buffer_area[i];
1735205869Sjfv				ctxd = &adapter->tx_desc_base[i];
1736205869Sjfv				ctxd->buffer_addr = htole64(
1737205869Sjfv				    desc_array.descriptor[counter].address);
1738205869Sjfv				ctxd->lower.data = htole32(
1739205869Sjfv				    (adapter->txd_cmd | txd_lower | (u16)
1740205869Sjfv				    desc_array.descriptor[counter].length));
1741205869Sjfv				ctxd->upper.data =
1742205869Sjfv				    htole32((txd_upper));
1743205869Sjfv				last = i;
1744205869Sjfv				if (++i == adapter->num_tx_desc)
1745205869Sjfv                                         i = 0;
1746205869Sjfv				tx_buffer->m_head = NULL;
1747205869Sjfv				tx_buffer->next_eop = -1;
1748205869Sjfv				txd_used++;
1749205869Sjfv                        }
1750205869Sjfv		} else {
1751205869Sjfv			tx_buffer = &adapter->tx_buffer_area[i];
1752205869Sjfv			ctxd = &adapter->tx_desc_base[i];
1753205869Sjfv			seg_addr = segs[j].ds_addr;
1754205869Sjfv			seg_len  = segs[j].ds_len;
1755205869Sjfv			ctxd->buffer_addr = htole64(seg_addr);
1756205869Sjfv			ctxd->lower.data = htole32(
1757205869Sjfv			adapter->txd_cmd | txd_lower | seg_len);
1758205869Sjfv			ctxd->upper.data =
1759205869Sjfv			    htole32(txd_upper);
1760205869Sjfv			last = i;
1761205869Sjfv			if (++i == adapter->num_tx_desc)
1762205869Sjfv				i = 0;
1763205869Sjfv			tx_buffer->m_head = NULL;
1764205869Sjfv			tx_buffer->next_eop = -1;
1765205869Sjfv		}
1766205869Sjfv	}
1767205869Sjfv
1768205869Sjfv	adapter->next_avail_tx_desc = i;
1769205869Sjfv
1770205869Sjfv	if (adapter->pcix_82544)
1771205869Sjfv		adapter->num_tx_desc_avail -= txd_used;
1772205869Sjfv	else
1773205869Sjfv		adapter->num_tx_desc_avail -= nsegs;
1774205869Sjfv
1775205869Sjfv	if (m_head->m_flags & M_VLANTAG) {
1776205869Sjfv		/* Set the vlan id. */
1777205869Sjfv		ctxd->upper.fields.special =
1778205869Sjfv		    htole16(m_head->m_pkthdr.ether_vtag);
1779205869Sjfv                /* Tell hardware to add tag */
1780205869Sjfv                ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE);
1781205869Sjfv        }
1782205869Sjfv
1783205869Sjfv        tx_buffer->m_head = m_head;
1784205869Sjfv	tx_buffer_mapped->map = tx_buffer->map;
1785205869Sjfv	tx_buffer->map = map;
1786205869Sjfv        bus_dmamap_sync(adapter->txtag, map, BUS_DMASYNC_PREWRITE);
1787205869Sjfv
1788205869Sjfv        /*
1789205869Sjfv         * Last Descriptor of Packet
1790205869Sjfv	 * needs End Of Packet (EOP)
1791205869Sjfv	 * and Report Status (RS)
1792205869Sjfv         */
1793205869Sjfv        ctxd->lower.data |=
1794205869Sjfv	    htole32(E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS);
1795205869Sjfv	/*
1796205869Sjfv	 * Keep track in the first buffer which
1797205869Sjfv	 * descriptor will be written back
1798205869Sjfv	 */
1799205869Sjfv	tx_buffer = &adapter->tx_buffer_area[first];
1800205869Sjfv	tx_buffer->next_eop = last;
1801213234Sjfv	adapter->watchdog_time = ticks;
1802205869Sjfv
1803205869Sjfv	/*
1804205869Sjfv	 * Advance the Transmit Descriptor Tail (TDT), this tells the E1000
1805205869Sjfv	 * that this frame is available to transmit.
1806205869Sjfv	 */
1807205869Sjfv	bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
1808205869Sjfv	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1809270252Sluigi
1810270252Sluigi#ifdef NIC_PARAVIRT
1811270252Sluigi	if (adapter->csb) {
1812270252Sluigi		adapter->csb->guest_tdt = i;
1813270252Sluigi		/* XXX memory barrier ? */
1814270252Sluigi 		if (adapter->csb->guest_csb_on &&
1815270252Sluigi		    !(adapter->csb->host_need_txkick & 1)) {
1816270252Sluigi			/* XXX maybe useless
1817270252Sluigi			 * clean the ring. maybe do it before ?
1818270252Sluigi			 * maybe a little bit of histeresys ?
1819270252Sluigi			 */
1820270252Sluigi			if (adapter->num_tx_desc_avail <= 64) {// XXX
1821270252Sluigi				lem_txeof(adapter);
1822270252Sluigi			}
1823270252Sluigi			return (0);
1824270252Sluigi		}
1825270252Sluigi	}
1826270252Sluigi#endif /* NIC_PARAVIRT */
1827270252Sluigi
1828270252Sluigi#ifdef NIC_SEND_COMBINING
1829270252Sluigi	if (adapter->sc_enable) {
1830270252Sluigi		if (adapter->shadow_tdt & MIT_PENDING_INT) {
1831270252Sluigi			/* signal intr and data pending */
1832270252Sluigi			adapter->shadow_tdt = MIT_PENDING_TDT | (i & 0xffff);
1833270252Sluigi			return (0);
1834270252Sluigi		} else {
1835270252Sluigi			adapter->shadow_tdt = MIT_PENDING_INT;
1836270252Sluigi		}
1837270252Sluigi	}
1838270252Sluigi#endif /* NIC_SEND_COMBINING */
1839270252Sluigi
1840205869Sjfv	if (adapter->hw.mac.type == e1000_82547 &&
1841205869Sjfv	    adapter->link_duplex == HALF_DUPLEX)
1842205869Sjfv		lem_82547_move_tail(adapter);
1843205869Sjfv	else {
1844205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), i);
1845205869Sjfv		if (adapter->hw.mac.type == e1000_82547)
1846205869Sjfv			lem_82547_update_fifo_head(adapter,
1847205869Sjfv			    m_head->m_pkthdr.len);
1848205869Sjfv	}
1849205869Sjfv
1850205869Sjfv	return (0);
1851205869Sjfv}
1852205869Sjfv
1853205869Sjfv/*********************************************************************
1854205869Sjfv *
1855205869Sjfv * 82547 workaround to avoid controller hang in half-duplex environment.
1856205869Sjfv * The workaround is to avoid queuing a large packet that would span
1857205869Sjfv * the internal Tx FIFO ring boundary. We need to reset the FIFO pointers
1858205869Sjfv * in this case. We do that only when FIFO is quiescent.
1859205869Sjfv *
1860205869Sjfv **********************************************************************/
1861205869Sjfvstatic void
1862205869Sjfvlem_82547_move_tail(void *arg)
1863205869Sjfv{
1864205869Sjfv	struct adapter *adapter = arg;
1865205869Sjfv	struct e1000_tx_desc *tx_desc;
1866205869Sjfv	u16	hw_tdt, sw_tdt, length = 0;
1867205869Sjfv	bool	eop = 0;
1868205869Sjfv
1869205869Sjfv	EM_TX_LOCK_ASSERT(adapter);
1870205869Sjfv
1871205869Sjfv	hw_tdt = E1000_READ_REG(&adapter->hw, E1000_TDT(0));
1872205869Sjfv	sw_tdt = adapter->next_avail_tx_desc;
1873205869Sjfv
1874205869Sjfv	while (hw_tdt != sw_tdt) {
1875205869Sjfv		tx_desc = &adapter->tx_desc_base[hw_tdt];
1876205869Sjfv		length += tx_desc->lower.flags.length;
1877205869Sjfv		eop = tx_desc->lower.data & E1000_TXD_CMD_EOP;
1878205869Sjfv		if (++hw_tdt == adapter->num_tx_desc)
1879205869Sjfv			hw_tdt = 0;
1880205869Sjfv
1881205869Sjfv		if (eop) {
1882205869Sjfv			if (lem_82547_fifo_workaround(adapter, length)) {
1883205869Sjfv				adapter->tx_fifo_wrk_cnt++;
1884205869Sjfv				callout_reset(&adapter->tx_fifo_timer, 1,
1885205869Sjfv					lem_82547_move_tail, adapter);
1886205869Sjfv				break;
1887205869Sjfv			}
1888205869Sjfv			E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), hw_tdt);
1889205869Sjfv			lem_82547_update_fifo_head(adapter, length);
1890205869Sjfv			length = 0;
1891205869Sjfv		}
1892205869Sjfv	}
1893205869Sjfv}
1894205869Sjfv
1895205869Sjfvstatic int
1896205869Sjfvlem_82547_fifo_workaround(struct adapter *adapter, int len)
1897205869Sjfv{
1898205869Sjfv	int fifo_space, fifo_pkt_len;
1899205869Sjfv
1900205869Sjfv	fifo_pkt_len = roundup2(len + EM_FIFO_HDR, EM_FIFO_HDR);
1901205869Sjfv
1902205869Sjfv	if (adapter->link_duplex == HALF_DUPLEX) {
1903205869Sjfv		fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
1904205869Sjfv
1905205869Sjfv		if (fifo_pkt_len >= (EM_82547_PKT_THRESH + fifo_space)) {
1906205869Sjfv			if (lem_82547_tx_fifo_reset(adapter))
1907205869Sjfv				return (0);
1908205869Sjfv			else
1909205869Sjfv				return (1);
1910205869Sjfv		}
1911205869Sjfv	}
1912205869Sjfv
1913205869Sjfv	return (0);
1914205869Sjfv}
1915205869Sjfv
1916205869Sjfvstatic void
1917205869Sjfvlem_82547_update_fifo_head(struct adapter *adapter, int len)
1918205869Sjfv{
1919205869Sjfv	int fifo_pkt_len = roundup2(len + EM_FIFO_HDR, EM_FIFO_HDR);
1920205869Sjfv
1921205869Sjfv	/* tx_fifo_head is always 16 byte aligned */
1922205869Sjfv	adapter->tx_fifo_head += fifo_pkt_len;
1923205869Sjfv	if (adapter->tx_fifo_head >= adapter->tx_fifo_size) {
1924205869Sjfv		adapter->tx_fifo_head -= adapter->tx_fifo_size;
1925205869Sjfv	}
1926205869Sjfv}
1927205869Sjfv
1928205869Sjfv
1929205869Sjfvstatic int
1930205869Sjfvlem_82547_tx_fifo_reset(struct adapter *adapter)
1931205869Sjfv{
1932205869Sjfv	u32 tctl;
1933205869Sjfv
1934205869Sjfv	if ((E1000_READ_REG(&adapter->hw, E1000_TDT(0)) ==
1935205869Sjfv	    E1000_READ_REG(&adapter->hw, E1000_TDH(0))) &&
1936205869Sjfv	    (E1000_READ_REG(&adapter->hw, E1000_TDFT) ==
1937205869Sjfv	    E1000_READ_REG(&adapter->hw, E1000_TDFH)) &&
1938205869Sjfv	    (E1000_READ_REG(&adapter->hw, E1000_TDFTS) ==
1939205869Sjfv	    E1000_READ_REG(&adapter->hw, E1000_TDFHS)) &&
1940205869Sjfv	    (E1000_READ_REG(&adapter->hw, E1000_TDFPC) == 0)) {
1941205869Sjfv		/* Disable TX unit */
1942205869Sjfv		tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL);
1943205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_TCTL,
1944205869Sjfv		    tctl & ~E1000_TCTL_EN);
1945205869Sjfv
1946205869Sjfv		/* Reset FIFO pointers */
1947205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_TDFT,
1948205869Sjfv		    adapter->tx_head_addr);
1949205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_TDFH,
1950205869Sjfv		    adapter->tx_head_addr);
1951205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_TDFTS,
1952205869Sjfv		    adapter->tx_head_addr);
1953205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_TDFHS,
1954205869Sjfv		    adapter->tx_head_addr);
1955205869Sjfv
1956205869Sjfv		/* Re-enable TX unit */
1957205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl);
1958205869Sjfv		E1000_WRITE_FLUSH(&adapter->hw);
1959205869Sjfv
1960205869Sjfv		adapter->tx_fifo_head = 0;
1961205869Sjfv		adapter->tx_fifo_reset_cnt++;
1962205869Sjfv
1963205869Sjfv		return (TRUE);
1964205869Sjfv	}
1965205869Sjfv	else {
1966205869Sjfv		return (FALSE);
1967205869Sjfv	}
1968205869Sjfv}
1969205869Sjfv
1970205869Sjfvstatic void
1971205869Sjfvlem_set_promisc(struct adapter *adapter)
1972205869Sjfv{
1973205869Sjfv	struct ifnet	*ifp = adapter->ifp;
1974205869Sjfv	u32		reg_rctl;
1975205869Sjfv
1976205869Sjfv	reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
1977205869Sjfv
1978205869Sjfv	if (ifp->if_flags & IFF_PROMISC) {
1979205869Sjfv		reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
1980205869Sjfv		/* Turn this on if you want to see bad packets */
1981205869Sjfv		if (lem_debug_sbp)
1982205869Sjfv			reg_rctl |= E1000_RCTL_SBP;
1983205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
1984205869Sjfv	} else if (ifp->if_flags & IFF_ALLMULTI) {
1985205869Sjfv		reg_rctl |= E1000_RCTL_MPE;
1986205869Sjfv		reg_rctl &= ~E1000_RCTL_UPE;
1987205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
1988205869Sjfv	}
1989205869Sjfv}
1990205869Sjfv
1991205869Sjfvstatic void
1992205869Sjfvlem_disable_promisc(struct adapter *adapter)
1993205869Sjfv{
1994249074Sjfv	struct ifnet	*ifp = adapter->ifp;
1995249074Sjfv	u32		reg_rctl;
1996249074Sjfv	int		mcnt = 0;
1997205869Sjfv
1998205869Sjfv	reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
1999205869Sjfv	reg_rctl &=  (~E1000_RCTL_UPE);
2000249074Sjfv	if (ifp->if_flags & IFF_ALLMULTI)
2001249074Sjfv		mcnt = MAX_NUM_MULTICAST_ADDRESSES;
2002249074Sjfv	else {
2003249074Sjfv		struct  ifmultiaddr *ifma;
2004249074Sjfv#if __FreeBSD_version < 800000
2005249074Sjfv		IF_ADDR_LOCK(ifp);
2006249074Sjfv#else
2007249074Sjfv		if_maddr_rlock(ifp);
2008249074Sjfv#endif
2009249074Sjfv		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
2010249074Sjfv			if (ifma->ifma_addr->sa_family != AF_LINK)
2011249074Sjfv				continue;
2012249074Sjfv			if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
2013249074Sjfv				break;
2014249074Sjfv			mcnt++;
2015249074Sjfv		}
2016249074Sjfv#if __FreeBSD_version < 800000
2017249074Sjfv		IF_ADDR_UNLOCK(ifp);
2018249074Sjfv#else
2019249074Sjfv		if_maddr_runlock(ifp);
2020249074Sjfv#endif
2021249074Sjfv	}
2022249074Sjfv	/* Don't disable if in MAX groups */
2023249074Sjfv	if (mcnt < MAX_NUM_MULTICAST_ADDRESSES)
2024249074Sjfv		reg_rctl &=  (~E1000_RCTL_MPE);
2025205869Sjfv	reg_rctl &=  (~E1000_RCTL_SBP);
2026205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
2027205869Sjfv}
2028205869Sjfv
2029205869Sjfv
2030205869Sjfv/*********************************************************************
2031205869Sjfv *  Multicast Update
2032205869Sjfv *
2033205869Sjfv *  This routine is called whenever multicast address list is updated.
2034205869Sjfv *
2035205869Sjfv **********************************************************************/
2036205869Sjfv
2037205869Sjfvstatic void
2038205869Sjfvlem_set_multi(struct adapter *adapter)
2039205869Sjfv{
2040205869Sjfv	struct ifnet	*ifp = adapter->ifp;
2041205869Sjfv	struct ifmultiaddr *ifma;
2042205869Sjfv	u32 reg_rctl = 0;
2043205869Sjfv	u8  *mta; /* Multicast array memory */
2044205869Sjfv	int mcnt = 0;
2045205869Sjfv
2046205869Sjfv	IOCTL_DEBUGOUT("lem_set_multi: begin");
2047205869Sjfv
2048211913Syongari	mta = adapter->mta;
2049211913Syongari	bzero(mta, sizeof(u8) * ETH_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES);
2050211913Syongari
2051205869Sjfv	if (adapter->hw.mac.type == e1000_82542 &&
2052205869Sjfv	    adapter->hw.revision_id == E1000_REVISION_2) {
2053205869Sjfv		reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
2054205869Sjfv		if (adapter->hw.bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
2055205869Sjfv			e1000_pci_clear_mwi(&adapter->hw);
2056205869Sjfv		reg_rctl |= E1000_RCTL_RST;
2057205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
2058205869Sjfv		msec_delay(5);
2059205869Sjfv	}
2060205869Sjfv
2061205869Sjfv#if __FreeBSD_version < 800000
2062205869Sjfv	IF_ADDR_LOCK(ifp);
2063205869Sjfv#else
2064205869Sjfv	if_maddr_rlock(ifp);
2065205869Sjfv#endif
2066205869Sjfv	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
2067205869Sjfv		if (ifma->ifma_addr->sa_family != AF_LINK)
2068205869Sjfv			continue;
2069205869Sjfv
2070205869Sjfv		if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
2071205869Sjfv			break;
2072205869Sjfv
2073205869Sjfv		bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
2074205869Sjfv		    &mta[mcnt * ETH_ADDR_LEN], ETH_ADDR_LEN);
2075205869Sjfv		mcnt++;
2076205869Sjfv	}
2077205869Sjfv#if __FreeBSD_version < 800000
2078205869Sjfv	IF_ADDR_UNLOCK(ifp);
2079205869Sjfv#else
2080205869Sjfv	if_maddr_runlock(ifp);
2081205869Sjfv#endif
2082205869Sjfv	if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) {
2083205869Sjfv		reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
2084205869Sjfv		reg_rctl |= E1000_RCTL_MPE;
2085205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
2086205869Sjfv	} else
2087205869Sjfv		e1000_update_mc_addr_list(&adapter->hw, mta, mcnt);
2088205869Sjfv
2089205869Sjfv	if (adapter->hw.mac.type == e1000_82542 &&
2090205869Sjfv	    adapter->hw.revision_id == E1000_REVISION_2) {
2091205869Sjfv		reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
2092205869Sjfv		reg_rctl &= ~E1000_RCTL_RST;
2093205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
2094205869Sjfv		msec_delay(5);
2095205869Sjfv		if (adapter->hw.bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
2096205869Sjfv			e1000_pci_set_mwi(&adapter->hw);
2097205869Sjfv	}
2098205869Sjfv}
2099205869Sjfv
2100205869Sjfv
2101205869Sjfv/*********************************************************************
2102205869Sjfv *  Timer routine
2103205869Sjfv *
2104205869Sjfv *  This routine checks for link status and updates statistics.
2105205869Sjfv *
2106205869Sjfv **********************************************************************/
2107205869Sjfv
2108205869Sjfvstatic void
2109205869Sjfvlem_local_timer(void *arg)
2110205869Sjfv{
2111205869Sjfv	struct adapter	*adapter = arg;
2112205869Sjfv
2113205869Sjfv	EM_CORE_LOCK_ASSERT(adapter);
2114205869Sjfv
2115205869Sjfv	lem_update_link_status(adapter);
2116205869Sjfv	lem_update_stats_counters(adapter);
2117205869Sjfv
2118205869Sjfv	lem_smartspeed(adapter);
2119205869Sjfv
2120270252Sluigi#ifdef NIC_PARAVIRT
2121270252Sluigi	/* recover space if needed */
2122270252Sluigi	if (adapter->csb && adapter->csb->guest_csb_on &&
2123270252Sluigi	    (adapter->watchdog_check == TRUE) &&
2124270252Sluigi	    (ticks - adapter->watchdog_time > EM_WATCHDOG) &&
2125270252Sluigi	    (adapter->num_tx_desc_avail != adapter->num_tx_desc) ) {
2126270252Sluigi		lem_txeof(adapter);
2127270252Sluigi		/*
2128270252Sluigi		 * lem_txeof() normally (except when space in the queue
2129270252Sluigi		 * runs low XXX) cleans watchdog_check so that
2130270252Sluigi		 * we do not hung.
2131270252Sluigi		 */
2132270252Sluigi	}
2133270252Sluigi#endif /* NIC_PARAVIRT */
2134205869Sjfv	/*
2135205869Sjfv	 * We check the watchdog: the time since
2136205869Sjfv	 * the last TX descriptor was cleaned.
2137205869Sjfv	 * This implies a functional TX engine.
2138205869Sjfv	 */
2139205869Sjfv	if ((adapter->watchdog_check == TRUE) &&
2140205869Sjfv	    (ticks - adapter->watchdog_time > EM_WATCHDOG))
2141205869Sjfv		goto hung;
2142205869Sjfv
2143205869Sjfv	callout_reset(&adapter->timer, hz, lem_local_timer, adapter);
2144205869Sjfv	return;
2145205869Sjfvhung:
2146205869Sjfv	device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
2147205869Sjfv	adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
2148205869Sjfv	adapter->watchdog_events++;
2149205869Sjfv	lem_init_locked(adapter);
2150205869Sjfv}
2151205869Sjfv
2152205869Sjfvstatic void
2153205869Sjfvlem_update_link_status(struct adapter *adapter)
2154205869Sjfv{
2155205869Sjfv	struct e1000_hw *hw = &adapter->hw;
2156205869Sjfv	struct ifnet *ifp = adapter->ifp;
2157205869Sjfv	device_t dev = adapter->dev;
2158205869Sjfv	u32 link_check = 0;
2159205869Sjfv
2160205869Sjfv	/* Get the cached link value or read phy for real */
2161205869Sjfv	switch (hw->phy.media_type) {
2162205869Sjfv	case e1000_media_type_copper:
2163205869Sjfv		if (hw->mac.get_link_status) {
2164205869Sjfv			/* Do the work to read phy */
2165205869Sjfv			e1000_check_for_link(hw);
2166205869Sjfv			link_check = !hw->mac.get_link_status;
2167205869Sjfv			if (link_check) /* ESB2 fix */
2168205869Sjfv				e1000_cfg_on_link_up(hw);
2169205869Sjfv		} else
2170205869Sjfv			link_check = TRUE;
2171205869Sjfv		break;
2172205869Sjfv	case e1000_media_type_fiber:
2173205869Sjfv		e1000_check_for_link(hw);
2174205869Sjfv		link_check = (E1000_READ_REG(hw, E1000_STATUS) &
2175205869Sjfv                                 E1000_STATUS_LU);
2176205869Sjfv		break;
2177205869Sjfv	case e1000_media_type_internal_serdes:
2178205869Sjfv		e1000_check_for_link(hw);
2179205869Sjfv		link_check = adapter->hw.mac.serdes_has_link;
2180205869Sjfv		break;
2181205869Sjfv	default:
2182205869Sjfv	case e1000_media_type_unknown:
2183205869Sjfv		break;
2184205869Sjfv	}
2185205869Sjfv
2186205869Sjfv	/* Now check for a transition */
2187205869Sjfv	if (link_check && (adapter->link_active == 0)) {
2188205869Sjfv		e1000_get_speed_and_duplex(hw, &adapter->link_speed,
2189205869Sjfv		    &adapter->link_duplex);
2190205869Sjfv		if (bootverbose)
2191205869Sjfv			device_printf(dev, "Link is up %d Mbps %s\n",
2192205869Sjfv			    adapter->link_speed,
2193205869Sjfv			    ((adapter->link_duplex == FULL_DUPLEX) ?
2194205869Sjfv			    "Full Duplex" : "Half Duplex"));
2195205869Sjfv		adapter->link_active = 1;
2196205869Sjfv		adapter->smartspeed = 0;
2197205869Sjfv		ifp->if_baudrate = adapter->link_speed * 1000000;
2198205869Sjfv		if_link_state_change(ifp, LINK_STATE_UP);
2199205869Sjfv	} else if (!link_check && (adapter->link_active == 1)) {
2200205869Sjfv		ifp->if_baudrate = adapter->link_speed = 0;
2201205869Sjfv		adapter->link_duplex = 0;
2202205869Sjfv		if (bootverbose)
2203205869Sjfv			device_printf(dev, "Link is Down\n");
2204205869Sjfv		adapter->link_active = 0;
2205205869Sjfv		/* Link down, disable watchdog */
2206205869Sjfv		adapter->watchdog_check = FALSE;
2207205869Sjfv		if_link_state_change(ifp, LINK_STATE_DOWN);
2208205869Sjfv	}
2209205869Sjfv}
2210205869Sjfv
2211205869Sjfv/*********************************************************************
2212205869Sjfv *
2213205869Sjfv *  This routine disables all traffic on the adapter by issuing a
2214205869Sjfv *  global reset on the MAC and deallocates TX/RX buffers.
2215205869Sjfv *
2216205869Sjfv *  This routine should always be called with BOTH the CORE
2217205869Sjfv *  and TX locks.
2218205869Sjfv **********************************************************************/
2219205869Sjfv
2220205869Sjfvstatic void
2221205869Sjfvlem_stop(void *arg)
2222205869Sjfv{
2223205869Sjfv	struct adapter	*adapter = arg;
2224205869Sjfv	struct ifnet	*ifp = adapter->ifp;
2225205869Sjfv
2226205869Sjfv	EM_CORE_LOCK_ASSERT(adapter);
2227205869Sjfv	EM_TX_LOCK_ASSERT(adapter);
2228205869Sjfv
2229205869Sjfv	INIT_DEBUGOUT("lem_stop: begin");
2230205869Sjfv
2231205869Sjfv	lem_disable_intr(adapter);
2232205869Sjfv	callout_stop(&adapter->timer);
2233205869Sjfv	callout_stop(&adapter->tx_fifo_timer);
2234205869Sjfv
2235205869Sjfv	/* Tell the stack that the interface is no longer active */
2236205869Sjfv	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
2237205869Sjfv
2238205869Sjfv	e1000_reset_hw(&adapter->hw);
2239205869Sjfv	if (adapter->hw.mac.type >= e1000_82544)
2240205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0);
2241206001Smarius
2242206001Smarius	e1000_led_off(&adapter->hw);
2243206001Smarius	e1000_cleanup_led(&adapter->hw);
2244205869Sjfv}
2245205869Sjfv
2246205869Sjfv
2247205869Sjfv/*********************************************************************
2248205869Sjfv *
2249205869Sjfv *  Determine hardware revision.
2250205869Sjfv *
2251205869Sjfv **********************************************************************/
2252205869Sjfvstatic void
2253205869Sjfvlem_identify_hardware(struct adapter *adapter)
2254205869Sjfv{
2255205869Sjfv	device_t dev = adapter->dev;
2256205869Sjfv
2257205869Sjfv	/* Make sure our PCI config space has the necessary stuff set */
2258254263Sscottl	pci_enable_busmaster(dev);
2259205869Sjfv	adapter->hw.bus.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
2260205869Sjfv
2261205869Sjfv	/* Save off the information about this board */
2262205869Sjfv	adapter->hw.vendor_id = pci_get_vendor(dev);
2263205869Sjfv	adapter->hw.device_id = pci_get_device(dev);
2264205869Sjfv	adapter->hw.revision_id = pci_read_config(dev, PCIR_REVID, 1);
2265205869Sjfv	adapter->hw.subsystem_vendor_id =
2266205869Sjfv	    pci_read_config(dev, PCIR_SUBVEND_0, 2);
2267205869Sjfv	adapter->hw.subsystem_device_id =
2268205869Sjfv	    pci_read_config(dev, PCIR_SUBDEV_0, 2);
2269205869Sjfv
2270205869Sjfv	/* Do Shared Code Init and Setup */
2271205869Sjfv	if (e1000_set_mac_type(&adapter->hw)) {
2272205869Sjfv		device_printf(dev, "Setup init failure\n");
2273205869Sjfv		return;
2274205869Sjfv	}
2275205869Sjfv}
2276205869Sjfv
2277205869Sjfvstatic int
2278205869Sjfvlem_allocate_pci_resources(struct adapter *adapter)
2279205869Sjfv{
2280205869Sjfv	device_t	dev = adapter->dev;
2281205869Sjfv	int		val, rid, error = E1000_SUCCESS;
2282205869Sjfv
2283205869Sjfv	rid = PCIR_BAR(0);
2284205869Sjfv	adapter->memory = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
2285205869Sjfv	    &rid, RF_ACTIVE);
2286205869Sjfv	if (adapter->memory == NULL) {
2287205869Sjfv		device_printf(dev, "Unable to allocate bus resource: memory\n");
2288205869Sjfv		return (ENXIO);
2289205869Sjfv	}
2290205869Sjfv	adapter->osdep.mem_bus_space_tag =
2291205869Sjfv	    rman_get_bustag(adapter->memory);
2292205869Sjfv	adapter->osdep.mem_bus_space_handle =
2293205869Sjfv	    rman_get_bushandle(adapter->memory);
2294205869Sjfv	adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle;
2295205869Sjfv
2296205869Sjfv	/* Only older adapters use IO mapping */
2297205869Sjfv	if (adapter->hw.mac.type > e1000_82543) {
2298205869Sjfv		/* Figure our where our IO BAR is ? */
2299205869Sjfv		for (rid = PCIR_BAR(0); rid < PCIR_CIS;) {
2300205869Sjfv			val = pci_read_config(dev, rid, 4);
2301205869Sjfv			if (EM_BAR_TYPE(val) == EM_BAR_TYPE_IO) {
2302205869Sjfv				adapter->io_rid = rid;
2303205869Sjfv				break;
2304205869Sjfv			}
2305205869Sjfv			rid += 4;
2306205869Sjfv			/* check for 64bit BAR */
2307205869Sjfv			if (EM_BAR_MEM_TYPE(val) == EM_BAR_MEM_TYPE_64BIT)
2308205869Sjfv				rid += 4;
2309205869Sjfv		}
2310205869Sjfv		if (rid >= PCIR_CIS) {
2311205869Sjfv			device_printf(dev, "Unable to locate IO BAR\n");
2312205869Sjfv			return (ENXIO);
2313205869Sjfv		}
2314205869Sjfv		adapter->ioport = bus_alloc_resource_any(dev,
2315205869Sjfv		    SYS_RES_IOPORT, &adapter->io_rid, RF_ACTIVE);
2316205869Sjfv		if (adapter->ioport == NULL) {
2317205869Sjfv			device_printf(dev, "Unable to allocate bus resource: "
2318205869Sjfv			    "ioport\n");
2319205869Sjfv			return (ENXIO);
2320205869Sjfv		}
2321205869Sjfv		adapter->hw.io_base = 0;
2322205869Sjfv		adapter->osdep.io_bus_space_tag =
2323205869Sjfv		    rman_get_bustag(adapter->ioport);
2324205869Sjfv		adapter->osdep.io_bus_space_handle =
2325205869Sjfv		    rman_get_bushandle(adapter->ioport);
2326205869Sjfv	}
2327205869Sjfv
2328205869Sjfv	adapter->hw.back = &adapter->osdep;
2329205869Sjfv
2330205869Sjfv	return (error);
2331205869Sjfv}
2332205869Sjfv
2333205869Sjfv/*********************************************************************
2334205869Sjfv *
2335205869Sjfv *  Setup the Legacy or MSI Interrupt handler
2336205869Sjfv *
2337205869Sjfv **********************************************************************/
2338205869Sjfvint
2339205869Sjfvlem_allocate_irq(struct adapter *adapter)
2340205869Sjfv{
2341205869Sjfv	device_t dev = adapter->dev;
2342205869Sjfv	int error, rid = 0;
2343205869Sjfv
2344205869Sjfv	/* Manually turn off all interrupts */
2345205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
2346205869Sjfv
2347205869Sjfv	/* We allocate a single interrupt resource */
2348205869Sjfv	adapter->res[0] = bus_alloc_resource_any(dev,
2349205869Sjfv	    SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
2350205869Sjfv	if (adapter->res[0] == NULL) {
2351205869Sjfv		device_printf(dev, "Unable to allocate bus resource: "
2352205869Sjfv		    "interrupt\n");
2353205869Sjfv		return (ENXIO);
2354205869Sjfv	}
2355205869Sjfv
2356238953Sjfv	/* Do Legacy setup? */
2357238953Sjfv	if (lem_use_legacy_irq) {
2358238953Sjfv		if ((error = bus_setup_intr(dev, adapter->res[0],
2359238953Sjfv	    	    INTR_TYPE_NET | INTR_MPSAFE, NULL, lem_intr, adapter,
2360238953Sjfv	    	    &adapter->tag[0])) != 0) {
2361238953Sjfv			device_printf(dev,
2362238953Sjfv			    "Failed to register interrupt handler");
2363238953Sjfv			return (error);
2364238953Sjfv		}
2365238953Sjfv		return (0);
2366205869Sjfv	}
2367205869Sjfv
2368205869Sjfv	/*
2369238953Sjfv	 * Use a Fast interrupt and the associated
2370238953Sjfv	 * deferred processing contexts.
2371205869Sjfv	 */
2372205869Sjfv	TASK_INIT(&adapter->rxtx_task, 0, lem_handle_rxtx, adapter);
2373205869Sjfv	TASK_INIT(&adapter->link_task, 0, lem_handle_link, adapter);
2374205869Sjfv	adapter->tq = taskqueue_create_fast("lem_taskq", M_NOWAIT,
2375205869Sjfv	    taskqueue_thread_enqueue, &adapter->tq);
2376205869Sjfv	taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq",
2377205869Sjfv	    device_get_nameunit(adapter->dev));
2378205869Sjfv	if ((error = bus_setup_intr(dev, adapter->res[0],
2379205869Sjfv	    INTR_TYPE_NET, lem_irq_fast, NULL, adapter,
2380205869Sjfv	    &adapter->tag[0])) != 0) {
2381205869Sjfv		device_printf(dev, "Failed to register fast interrupt "
2382205869Sjfv			    "handler: %d\n", error);
2383205869Sjfv		taskqueue_free(adapter->tq);
2384205869Sjfv		adapter->tq = NULL;
2385205869Sjfv		return (error);
2386205869Sjfv	}
2387205869Sjfv
2388205869Sjfv	return (0);
2389205869Sjfv}
2390205869Sjfv
2391205869Sjfv
2392205869Sjfvstatic void
2393205869Sjfvlem_free_pci_resources(struct adapter *adapter)
2394205869Sjfv{
2395205869Sjfv	device_t dev = adapter->dev;
2396205869Sjfv
2397205869Sjfv
2398205869Sjfv	if (adapter->tag[0] != NULL) {
2399205869Sjfv		bus_teardown_intr(dev, adapter->res[0],
2400205869Sjfv		    adapter->tag[0]);
2401205869Sjfv		adapter->tag[0] = NULL;
2402205869Sjfv	}
2403205869Sjfv
2404205869Sjfv	if (adapter->res[0] != NULL) {
2405205869Sjfv		bus_release_resource(dev, SYS_RES_IRQ,
2406205869Sjfv		    0, adapter->res[0]);
2407205869Sjfv	}
2408205869Sjfv
2409205869Sjfv	if (adapter->memory != NULL)
2410205869Sjfv		bus_release_resource(dev, SYS_RES_MEMORY,
2411205869Sjfv		    PCIR_BAR(0), adapter->memory);
2412205869Sjfv
2413205869Sjfv	if (adapter->ioport != NULL)
2414205869Sjfv		bus_release_resource(dev, SYS_RES_IOPORT,
2415205869Sjfv		    adapter->io_rid, adapter->ioport);
2416205869Sjfv}
2417205869Sjfv
2418205869Sjfv
2419205869Sjfv/*********************************************************************
2420205869Sjfv *
2421205869Sjfv *  Initialize the hardware to a configuration
2422205869Sjfv *  as specified by the adapter structure.
2423205869Sjfv *
2424205869Sjfv **********************************************************************/
2425205869Sjfvstatic int
2426205869Sjfvlem_hardware_init(struct adapter *adapter)
2427205869Sjfv{
2428205869Sjfv	device_t dev = adapter->dev;
2429205869Sjfv	u16 	rx_buffer_size;
2430205869Sjfv
2431205869Sjfv	INIT_DEBUGOUT("lem_hardware_init: begin");
2432205869Sjfv
2433205869Sjfv	/* Issue a global reset */
2434205869Sjfv	e1000_reset_hw(&adapter->hw);
2435205869Sjfv
2436205869Sjfv	/* When hardware is reset, fifo_head is also reset */
2437205869Sjfv	adapter->tx_fifo_head = 0;
2438205869Sjfv
2439205869Sjfv	/*
2440205869Sjfv	 * These parameters control the automatic generation (Tx) and
2441205869Sjfv	 * response (Rx) to Ethernet PAUSE frames.
2442205869Sjfv	 * - High water mark should allow for at least two frames to be
2443205869Sjfv	 *   received after sending an XOFF.
2444205869Sjfv	 * - Low water mark works best when it is very near the high water mark.
2445205869Sjfv	 *   This allows the receiver to restart by sending XON when it has
2446205869Sjfv	 *   drained a bit. Here we use an arbitary value of 1500 which will
2447205869Sjfv	 *   restart after one full frame is pulled from the buffer. There
2448205869Sjfv	 *   could be several smaller frames in the buffer and if so they will
2449205869Sjfv	 *   not trigger the XON until their total number reduces the buffer
2450205869Sjfv	 *   by 1500.
2451205869Sjfv	 * - The pause time is fairly large at 1000 x 512ns = 512 usec.
2452205869Sjfv	 */
2453205869Sjfv	rx_buffer_size = ((E1000_READ_REG(&adapter->hw, E1000_PBA) &
2454205869Sjfv	    0xffff) << 10 );
2455205869Sjfv
2456205869Sjfv	adapter->hw.fc.high_water = rx_buffer_size -
2457205869Sjfv	    roundup2(adapter->max_frame_size, 1024);
2458205869Sjfv	adapter->hw.fc.low_water = adapter->hw.fc.high_water - 1500;
2459205869Sjfv
2460205869Sjfv	adapter->hw.fc.pause_time = EM_FC_PAUSE_TIME;
2461205869Sjfv	adapter->hw.fc.send_xon = TRUE;
2462205869Sjfv
2463205869Sjfv        /* Set Flow control, use the tunable location if sane */
2464214646Sjfv        if ((lem_fc_setting >= 0) && (lem_fc_setting < 4))
2465205869Sjfv                adapter->hw.fc.requested_mode = lem_fc_setting;
2466205869Sjfv        else
2467205869Sjfv                adapter->hw.fc.requested_mode = e1000_fc_none;
2468205869Sjfv
2469205869Sjfv	if (e1000_init_hw(&adapter->hw) < 0) {
2470205869Sjfv		device_printf(dev, "Hardware Initialization Failed\n");
2471205869Sjfv		return (EIO);
2472205869Sjfv	}
2473205869Sjfv
2474205869Sjfv	e1000_check_for_link(&adapter->hw);
2475205869Sjfv
2476205869Sjfv	return (0);
2477205869Sjfv}
2478205869Sjfv
2479205869Sjfv/*********************************************************************
2480205869Sjfv *
2481205869Sjfv *  Setup networking device structure and register an interface.
2482205869Sjfv *
2483205869Sjfv **********************************************************************/
2484211907Syongaristatic int
2485205869Sjfvlem_setup_interface(device_t dev, struct adapter *adapter)
2486205869Sjfv{
2487205869Sjfv	struct ifnet   *ifp;
2488205869Sjfv
2489205869Sjfv	INIT_DEBUGOUT("lem_setup_interface: begin");
2490205869Sjfv
2491205869Sjfv	ifp = adapter->ifp = if_alloc(IFT_ETHER);
2492211907Syongari	if (ifp == NULL) {
2493211907Syongari		device_printf(dev, "can not allocate ifnet structure\n");
2494211907Syongari		return (-1);
2495211907Syongari	}
2496205869Sjfv	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
2497205869Sjfv	ifp->if_init =  lem_init;
2498205869Sjfv	ifp->if_softc = adapter;
2499205869Sjfv	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
2500205869Sjfv	ifp->if_ioctl = lem_ioctl;
2501205869Sjfv	ifp->if_start = lem_start;
2502205869Sjfv	IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 1);
2503205869Sjfv	ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 1;
2504205869Sjfv	IFQ_SET_READY(&ifp->if_snd);
2505205869Sjfv
2506205869Sjfv	ether_ifattach(ifp, adapter->hw.mac.addr);
2507205869Sjfv
2508205869Sjfv	ifp->if_capabilities = ifp->if_capenable = 0;
2509205869Sjfv
2510205869Sjfv	if (adapter->hw.mac.type >= e1000_82543) {
2511214646Sjfv		ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
2512214646Sjfv		ifp->if_capenable |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
2513205869Sjfv	}
2514205869Sjfv
2515205869Sjfv	/*
2516205869Sjfv	 * Tell the upper layer(s) we support long frames.
2517205869Sjfv	 */
2518205869Sjfv	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
2519205869Sjfv	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
2520205869Sjfv	ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
2521205869Sjfv
2522214646Sjfv	/*
2523214646Sjfv	** Dont turn this on by default, if vlans are
2524214646Sjfv	** created on another pseudo device (eg. lagg)
2525214646Sjfv	** then vlan events are not passed thru, breaking
2526214646Sjfv	** operation, but with HW FILTER off it works. If
2527214646Sjfv	** using vlans directly on the em driver you can
2528214646Sjfv	** enable this and get full hardware tag filtering.
2529214646Sjfv	*/
2530214646Sjfv	ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
2531214646Sjfv
2532205869Sjfv#ifdef DEVICE_POLLING
2533205869Sjfv	ifp->if_capabilities |= IFCAP_POLLING;
2534205869Sjfv#endif
2535205869Sjfv
2536208103Sjfv	/* Enable only WOL MAGIC by default */
2537205869Sjfv	if (adapter->wol) {
2538205869Sjfv		ifp->if_capabilities |= IFCAP_WOL;
2539208103Sjfv		ifp->if_capenable |= IFCAP_WOL_MAGIC;
2540205869Sjfv	}
2541205869Sjfv
2542205869Sjfv	/*
2543205869Sjfv	 * Specify the media types supported by this adapter and register
2544205869Sjfv	 * callbacks to update media and link information
2545205869Sjfv	 */
2546205869Sjfv	ifmedia_init(&adapter->media, IFM_IMASK,
2547205869Sjfv	    lem_media_change, lem_media_status);
2548205869Sjfv	if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
2549205869Sjfv	    (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) {
2550205869Sjfv		u_char fiber_type = IFM_1000_SX;	/* default type */
2551205869Sjfv
2552205869Sjfv		if (adapter->hw.mac.type == e1000_82545)
2553205869Sjfv			fiber_type = IFM_1000_LX;
2554205869Sjfv		ifmedia_add(&adapter->media, IFM_ETHER | fiber_type | IFM_FDX,
2555205869Sjfv			    0, NULL);
2556205869Sjfv		ifmedia_add(&adapter->media, IFM_ETHER | fiber_type, 0, NULL);
2557205869Sjfv	} else {
2558205869Sjfv		ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T, 0, NULL);
2559205869Sjfv		ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T | IFM_FDX,
2560205869Sjfv			    0, NULL);
2561205869Sjfv		ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX,
2562205869Sjfv			    0, NULL);
2563205869Sjfv		ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX | IFM_FDX,
2564205869Sjfv			    0, NULL);
2565205869Sjfv		if (adapter->hw.phy.type != e1000_phy_ife) {
2566205869Sjfv			ifmedia_add(&adapter->media,
2567205869Sjfv				IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
2568205869Sjfv			ifmedia_add(&adapter->media,
2569205869Sjfv				IFM_ETHER | IFM_1000_T, 0, NULL);
2570205869Sjfv		}
2571205869Sjfv	}
2572205869Sjfv	ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
2573205869Sjfv	ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
2574211907Syongari	return (0);
2575205869Sjfv}
2576205869Sjfv
2577205869Sjfv
2578205869Sjfv/*********************************************************************
2579205869Sjfv *
2580205869Sjfv *  Workaround for SmartSpeed on 82541 and 82547 controllers
2581205869Sjfv *
2582205869Sjfv **********************************************************************/
2583205869Sjfvstatic void
2584205869Sjfvlem_smartspeed(struct adapter *adapter)
2585205869Sjfv{
2586205869Sjfv	u16 phy_tmp;
2587205869Sjfv
2588205869Sjfv	if (adapter->link_active || (adapter->hw.phy.type != e1000_phy_igp) ||
2589205869Sjfv	    adapter->hw.mac.autoneg == 0 ||
2590205869Sjfv	    (adapter->hw.phy.autoneg_advertised & ADVERTISE_1000_FULL) == 0)
2591205869Sjfv		return;
2592205869Sjfv
2593205869Sjfv	if (adapter->smartspeed == 0) {
2594205869Sjfv		/* If Master/Slave config fault is asserted twice,
2595205869Sjfv		 * we assume back-to-back */
2596205869Sjfv		e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
2597205869Sjfv		if (!(phy_tmp & SR_1000T_MS_CONFIG_FAULT))
2598205869Sjfv			return;
2599205869Sjfv		e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
2600205869Sjfv		if (phy_tmp & SR_1000T_MS_CONFIG_FAULT) {
2601205869Sjfv			e1000_read_phy_reg(&adapter->hw,
2602205869Sjfv			    PHY_1000T_CTRL, &phy_tmp);
2603205869Sjfv			if(phy_tmp & CR_1000T_MS_ENABLE) {
2604205869Sjfv				phy_tmp &= ~CR_1000T_MS_ENABLE;
2605205869Sjfv				e1000_write_phy_reg(&adapter->hw,
2606205869Sjfv				    PHY_1000T_CTRL, phy_tmp);
2607205869Sjfv				adapter->smartspeed++;
2608205869Sjfv				if(adapter->hw.mac.autoneg &&
2609205869Sjfv				   !e1000_copper_link_autoneg(&adapter->hw) &&
2610205869Sjfv				   !e1000_read_phy_reg(&adapter->hw,
2611205869Sjfv				    PHY_CONTROL, &phy_tmp)) {
2612205869Sjfv					phy_tmp |= (MII_CR_AUTO_NEG_EN |
2613205869Sjfv						    MII_CR_RESTART_AUTO_NEG);
2614205869Sjfv					e1000_write_phy_reg(&adapter->hw,
2615205869Sjfv					    PHY_CONTROL, phy_tmp);
2616205869Sjfv				}
2617205869Sjfv			}
2618205869Sjfv		}
2619205869Sjfv		return;
2620205869Sjfv	} else if(adapter->smartspeed == EM_SMARTSPEED_DOWNSHIFT) {
2621205869Sjfv		/* If still no link, perhaps using 2/3 pair cable */
2622205869Sjfv		e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_tmp);
2623205869Sjfv		phy_tmp |= CR_1000T_MS_ENABLE;
2624205869Sjfv		e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_tmp);
2625205869Sjfv		if(adapter->hw.mac.autoneg &&
2626205869Sjfv		   !e1000_copper_link_autoneg(&adapter->hw) &&
2627205869Sjfv		   !e1000_read_phy_reg(&adapter->hw, PHY_CONTROL, &phy_tmp)) {
2628205869Sjfv			phy_tmp |= (MII_CR_AUTO_NEG_EN |
2629205869Sjfv				    MII_CR_RESTART_AUTO_NEG);
2630205869Sjfv			e1000_write_phy_reg(&adapter->hw, PHY_CONTROL, phy_tmp);
2631205869Sjfv		}
2632205869Sjfv	}
2633205869Sjfv	/* Restart process after EM_SMARTSPEED_MAX iterations */
2634205869Sjfv	if(adapter->smartspeed++ == EM_SMARTSPEED_MAX)
2635205869Sjfv		adapter->smartspeed = 0;
2636205869Sjfv}
2637205869Sjfv
2638205869Sjfv
2639205869Sjfv/*
2640205869Sjfv * Manage DMA'able memory.
2641205869Sjfv */
2642205869Sjfvstatic void
2643205869Sjfvlem_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
2644205869Sjfv{
2645205869Sjfv	if (error)
2646205869Sjfv		return;
2647205869Sjfv	*(bus_addr_t *) arg = segs[0].ds_addr;
2648205869Sjfv}
2649205869Sjfv
2650205869Sjfvstatic int
2651205869Sjfvlem_dma_malloc(struct adapter *adapter, bus_size_t size,
2652205869Sjfv        struct em_dma_alloc *dma, int mapflags)
2653205869Sjfv{
2654205869Sjfv	int error;
2655205869Sjfv
2656205869Sjfv	error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */
2657205869Sjfv				EM_DBA_ALIGN, 0,	/* alignment, bounds */
2658205869Sjfv				BUS_SPACE_MAXADDR,	/* lowaddr */
2659205869Sjfv				BUS_SPACE_MAXADDR,	/* highaddr */
2660205869Sjfv				NULL, NULL,		/* filter, filterarg */
2661205869Sjfv				size,			/* maxsize */
2662205869Sjfv				1,			/* nsegments */
2663205869Sjfv				size,			/* maxsegsize */
2664205869Sjfv				0,			/* flags */
2665205869Sjfv				NULL,			/* lockfunc */
2666205869Sjfv				NULL,			/* lockarg */
2667205869Sjfv				&dma->dma_tag);
2668205869Sjfv	if (error) {
2669205869Sjfv		device_printf(adapter->dev,
2670205869Sjfv		    "%s: bus_dma_tag_create failed: %d\n",
2671205869Sjfv		    __func__, error);
2672205869Sjfv		goto fail_0;
2673205869Sjfv	}
2674205869Sjfv
2675205869Sjfv	error = bus_dmamem_alloc(dma->dma_tag, (void**) &dma->dma_vaddr,
2676205869Sjfv	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dma->dma_map);
2677205869Sjfv	if (error) {
2678205869Sjfv		device_printf(adapter->dev,
2679205869Sjfv		    "%s: bus_dmamem_alloc(%ju) failed: %d\n",
2680205869Sjfv		    __func__, (uintmax_t)size, error);
2681205869Sjfv		goto fail_2;
2682205869Sjfv	}
2683205869Sjfv
2684205869Sjfv	dma->dma_paddr = 0;
2685205869Sjfv	error = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr,
2686205869Sjfv	    size, lem_dmamap_cb, &dma->dma_paddr, mapflags | BUS_DMA_NOWAIT);
2687205869Sjfv	if (error || dma->dma_paddr == 0) {
2688205869Sjfv		device_printf(adapter->dev,
2689205869Sjfv		    "%s: bus_dmamap_load failed: %d\n",
2690205869Sjfv		    __func__, error);
2691205869Sjfv		goto fail_3;
2692205869Sjfv	}
2693205869Sjfv
2694205869Sjfv	return (0);
2695205869Sjfv
2696205869Sjfvfail_3:
2697205869Sjfv	bus_dmamap_unload(dma->dma_tag, dma->dma_map);
2698205869Sjfvfail_2:
2699205869Sjfv	bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
2700205869Sjfv	bus_dma_tag_destroy(dma->dma_tag);
2701205869Sjfvfail_0:
2702205869Sjfv	dma->dma_tag = NULL;
2703205869Sjfv
2704205869Sjfv	return (error);
2705205869Sjfv}
2706205869Sjfv
2707205869Sjfvstatic void
2708205869Sjfvlem_dma_free(struct adapter *adapter, struct em_dma_alloc *dma)
2709205869Sjfv{
2710205869Sjfv	if (dma->dma_tag == NULL)
2711205869Sjfv		return;
2712294958Smarius	if (dma->dma_paddr != 0) {
2713205869Sjfv		bus_dmamap_sync(dma->dma_tag, dma->dma_map,
2714205869Sjfv		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2715205869Sjfv		bus_dmamap_unload(dma->dma_tag, dma->dma_map);
2716294958Smarius		dma->dma_paddr = 0;
2717294958Smarius	}
2718294958Smarius	if (dma->dma_vaddr != NULL) {
2719205869Sjfv		bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
2720294958Smarius		dma->dma_vaddr = NULL;
2721205869Sjfv	}
2722205869Sjfv	bus_dma_tag_destroy(dma->dma_tag);
2723205869Sjfv	dma->dma_tag = NULL;
2724205869Sjfv}
2725205869Sjfv
2726205869Sjfv
2727205869Sjfv/*********************************************************************
2728205869Sjfv *
2729205869Sjfv *  Allocate memory for tx_buffer structures. The tx_buffer stores all
2730205869Sjfv *  the information needed to transmit a packet on the wire.
2731205869Sjfv *
2732205869Sjfv **********************************************************************/
2733205869Sjfvstatic int
2734205869Sjfvlem_allocate_transmit_structures(struct adapter *adapter)
2735205869Sjfv{
2736205869Sjfv	device_t dev = adapter->dev;
2737205869Sjfv	struct em_buffer *tx_buffer;
2738205869Sjfv	int error;
2739205869Sjfv
2740205869Sjfv	/*
2741205869Sjfv	 * Create DMA tags for tx descriptors
2742205869Sjfv	 */
2743205869Sjfv	if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
2744205869Sjfv				1, 0,			/* alignment, bounds */
2745205869Sjfv				BUS_SPACE_MAXADDR,	/* lowaddr */
2746205869Sjfv				BUS_SPACE_MAXADDR,	/* highaddr */
2747205869Sjfv				NULL, NULL,		/* filter, filterarg */
2748214646Sjfv				MCLBYTES * EM_MAX_SCATTER,	/* maxsize */
2749205869Sjfv				EM_MAX_SCATTER,		/* nsegments */
2750214646Sjfv				MCLBYTES,		/* maxsegsize */
2751205869Sjfv				0,			/* flags */
2752214646Sjfv				NULL,			/* lockfunc */
2753214646Sjfv				NULL,			/* lockarg */
2754205869Sjfv				&adapter->txtag)) != 0) {
2755205869Sjfv		device_printf(dev, "Unable to allocate TX DMA tag\n");
2756205869Sjfv		goto fail;
2757205869Sjfv	}
2758205869Sjfv
2759205869Sjfv	adapter->tx_buffer_area = malloc(sizeof(struct em_buffer) *
2760205869Sjfv	    adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO);
2761205869Sjfv	if (adapter->tx_buffer_area == NULL) {
2762205869Sjfv		device_printf(dev, "Unable to allocate tx_buffer memory\n");
2763205869Sjfv		error = ENOMEM;
2764205869Sjfv		goto fail;
2765205869Sjfv	}
2766205869Sjfv
2767205869Sjfv	/* Create the descriptor buffer dma maps */
2768205869Sjfv	for (int i = 0; i < adapter->num_tx_desc; i++) {
2769205869Sjfv		tx_buffer = &adapter->tx_buffer_area[i];
2770205869Sjfv		error = bus_dmamap_create(adapter->txtag, 0, &tx_buffer->map);
2771205869Sjfv		if (error != 0) {
2772205869Sjfv			device_printf(dev, "Unable to create TX DMA map\n");
2773205869Sjfv			goto fail;
2774205869Sjfv		}
2775205869Sjfv		tx_buffer->next_eop = -1;
2776205869Sjfv	}
2777205869Sjfv
2778205869Sjfv	return (0);
2779205869Sjfvfail:
2780205869Sjfv	lem_free_transmit_structures(adapter);
2781205869Sjfv	return (error);
2782205869Sjfv}
2783205869Sjfv
2784205869Sjfv/*********************************************************************
2785205869Sjfv *
2786205869Sjfv *  (Re)Initialize transmit structures.
2787205869Sjfv *
2788205869Sjfv **********************************************************************/
2789205869Sjfvstatic void
2790205869Sjfvlem_setup_transmit_structures(struct adapter *adapter)
2791205869Sjfv{
2792205869Sjfv	struct em_buffer *tx_buffer;
2793228281Sluigi#ifdef DEV_NETMAP
2794228281Sluigi	/* we are already locked */
2795228281Sluigi	struct netmap_adapter *na = NA(adapter->ifp);
2796228281Sluigi	struct netmap_slot *slot = netmap_reset(na, NR_TX, 0, 0);
2797228281Sluigi#endif /* DEV_NETMAP */
2798205869Sjfv
2799205869Sjfv	/* Clear the old ring contents */
2800205869Sjfv	bzero(adapter->tx_desc_base,
2801205869Sjfv	    (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc);
2802205869Sjfv
2803205869Sjfv	/* Free any existing TX buffers */
2804205869Sjfv	for (int i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
2805205869Sjfv		tx_buffer = &adapter->tx_buffer_area[i];
2806205869Sjfv		bus_dmamap_sync(adapter->txtag, tx_buffer->map,
2807205869Sjfv		    BUS_DMASYNC_POSTWRITE);
2808205869Sjfv		bus_dmamap_unload(adapter->txtag, tx_buffer->map);
2809205869Sjfv		m_freem(tx_buffer->m_head);
2810205869Sjfv		tx_buffer->m_head = NULL;
2811228281Sluigi#ifdef DEV_NETMAP
2812228281Sluigi		if (slot) {
2813231796Sluigi			/* the i-th NIC entry goes to slot si */
2814232238Sluigi			int si = netmap_idx_n2k(&na->tx_rings[0], i);
2815229939Sluigi			uint64_t paddr;
2816228281Sluigi			void *addr;
2817228281Sluigi
2818270252Sluigi			addr = PNMB(na, slot + si, &paddr);
2819270235Sluigi			adapter->tx_desc_base[i].buffer_addr = htole64(paddr);
2820228281Sluigi			/* reload the map for netmap mode */
2821270252Sluigi			netmap_load_map(na, adapter->txtag, tx_buffer->map, addr);
2822228281Sluigi		}
2823228281Sluigi#endif /* DEV_NETMAP */
2824205869Sjfv		tx_buffer->next_eop = -1;
2825205869Sjfv	}
2826205869Sjfv
2827205869Sjfv	/* Reset state */
2828225640Srstone	adapter->last_hw_offload = 0;
2829205869Sjfv	adapter->next_avail_tx_desc = 0;
2830205869Sjfv	adapter->next_tx_to_clean = 0;
2831205869Sjfv	adapter->num_tx_desc_avail = adapter->num_tx_desc;
2832205869Sjfv
2833205869Sjfv	bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
2834205869Sjfv	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2835205869Sjfv
2836205869Sjfv	return;
2837205869Sjfv}
2838205869Sjfv
2839205869Sjfv/*********************************************************************
2840205869Sjfv *
2841205869Sjfv *  Enable transmit unit.
2842205869Sjfv *
2843205869Sjfv **********************************************************************/
2844205869Sjfvstatic void
2845205869Sjfvlem_initialize_transmit_unit(struct adapter *adapter)
2846205869Sjfv{
2847205869Sjfv	u32	tctl, tipg = 0;
2848205869Sjfv	u64	bus_addr;
2849205869Sjfv
2850205869Sjfv	 INIT_DEBUGOUT("lem_initialize_transmit_unit: begin");
2851205869Sjfv	/* Setup the Base and Length of the Tx Descriptor Ring */
2852205869Sjfv	bus_addr = adapter->txdma.dma_paddr;
2853205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TDLEN(0),
2854205869Sjfv	    adapter->num_tx_desc * sizeof(struct e1000_tx_desc));
2855205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TDBAH(0),
2856205869Sjfv	    (u32)(bus_addr >> 32));
2857205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TDBAL(0),
2858205869Sjfv	    (u32)bus_addr);
2859205869Sjfv	/* Setup the HW Tx Head and Tail descriptor pointers */
2860205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), 0);
2861205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TDH(0), 0);
2862205869Sjfv
2863205869Sjfv	HW_DEBUGOUT2("Base = %x, Length = %x\n",
2864205869Sjfv	    E1000_READ_REG(&adapter->hw, E1000_TDBAL(0)),
2865205869Sjfv	    E1000_READ_REG(&adapter->hw, E1000_TDLEN(0)));
2866205869Sjfv
2867205869Sjfv	/* Set the default values for the Tx Inter Packet Gap timer */
2868205869Sjfv	switch (adapter->hw.mac.type) {
2869205869Sjfv	case e1000_82542:
2870205869Sjfv		tipg = DEFAULT_82542_TIPG_IPGT;
2871205869Sjfv		tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
2872205869Sjfv		tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
2873205869Sjfv		break;
2874205869Sjfv	default:
2875205869Sjfv		if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
2876205869Sjfv		    (adapter->hw.phy.media_type ==
2877205869Sjfv		    e1000_media_type_internal_serdes))
2878205869Sjfv			tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
2879205869Sjfv		else
2880205869Sjfv			tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
2881205869Sjfv		tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
2882205869Sjfv		tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
2883205869Sjfv	}
2884205869Sjfv
2885205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TIPG, tipg);
2886205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TIDV, adapter->tx_int_delay.value);
2887205869Sjfv	if(adapter->hw.mac.type >= e1000_82540)
2888205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_TADV,
2889205869Sjfv		    adapter->tx_abs_int_delay.value);
2890205869Sjfv
2891205869Sjfv	/* Program the Transmit Control Register */
2892205869Sjfv	tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL);
2893205869Sjfv	tctl &= ~E1000_TCTL_CT;
2894205869Sjfv	tctl |= (E1000_TCTL_PSP | E1000_TCTL_RTLC | E1000_TCTL_EN |
2895205869Sjfv		   (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT));
2896205869Sjfv
2897205869Sjfv	/* This write will effectively turn on the transmit unit. */
2898205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl);
2899205869Sjfv
2900205869Sjfv	/* Setup Transmit Descriptor Base Settings */
2901205869Sjfv	adapter->txd_cmd = E1000_TXD_CMD_IFCS;
2902205869Sjfv
2903205869Sjfv	if (adapter->tx_int_delay.value > 0)
2904205869Sjfv		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
2905205869Sjfv}
2906205869Sjfv
2907205869Sjfv/*********************************************************************
2908205869Sjfv *
2909205869Sjfv *  Free all transmit related data structures.
2910205869Sjfv *
2911205869Sjfv **********************************************************************/
2912205869Sjfvstatic void
2913205869Sjfvlem_free_transmit_structures(struct adapter *adapter)
2914205869Sjfv{
2915205869Sjfv	struct em_buffer *tx_buffer;
2916205869Sjfv
2917205869Sjfv	INIT_DEBUGOUT("free_transmit_structures: begin");
2918205869Sjfv
2919205869Sjfv	if (adapter->tx_buffer_area != NULL) {
2920205869Sjfv		for (int i = 0; i < adapter->num_tx_desc; i++) {
2921205869Sjfv			tx_buffer = &adapter->tx_buffer_area[i];
2922205869Sjfv			if (tx_buffer->m_head != NULL) {
2923205869Sjfv				bus_dmamap_sync(adapter->txtag, tx_buffer->map,
2924205869Sjfv				    BUS_DMASYNC_POSTWRITE);
2925205869Sjfv				bus_dmamap_unload(adapter->txtag,
2926205869Sjfv				    tx_buffer->map);
2927205869Sjfv				m_freem(tx_buffer->m_head);
2928205869Sjfv				tx_buffer->m_head = NULL;
2929205869Sjfv			} else if (tx_buffer->map != NULL)
2930205869Sjfv				bus_dmamap_unload(adapter->txtag,
2931205869Sjfv				    tx_buffer->map);
2932205869Sjfv			if (tx_buffer->map != NULL) {
2933205869Sjfv				bus_dmamap_destroy(adapter->txtag,
2934205869Sjfv				    tx_buffer->map);
2935205869Sjfv				tx_buffer->map = NULL;
2936205869Sjfv			}
2937205869Sjfv		}
2938205869Sjfv	}
2939205869Sjfv	if (adapter->tx_buffer_area != NULL) {
2940205869Sjfv		free(adapter->tx_buffer_area, M_DEVBUF);
2941205869Sjfv		adapter->tx_buffer_area = NULL;
2942205869Sjfv	}
2943205869Sjfv	if (adapter->txtag != NULL) {
2944205869Sjfv		bus_dma_tag_destroy(adapter->txtag);
2945205869Sjfv		adapter->txtag = NULL;
2946205869Sjfv	}
2947205869Sjfv}
2948205869Sjfv
2949205869Sjfv/*********************************************************************
2950205869Sjfv *
2951205869Sjfv *  The offload context needs to be set when we transfer the first
2952205869Sjfv *  packet of a particular protocol (TCP/UDP). This routine has been
2953205869Sjfv *  enhanced to deal with inserted VLAN headers, and IPV6 (not complete)
2954205869Sjfv *
2955205869Sjfv *  Added back the old method of keeping the current context type
2956205869Sjfv *  and not setting if unnecessary, as this is reported to be a
2957205869Sjfv *  big performance win.  -jfv
2958205869Sjfv **********************************************************************/
2959205869Sjfvstatic void
2960205869Sjfvlem_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp,
2961205869Sjfv    u32 *txd_upper, u32 *txd_lower)
2962205869Sjfv{
2963205869Sjfv	struct e1000_context_desc *TXD = NULL;
2964205869Sjfv	struct em_buffer *tx_buffer;
2965205869Sjfv	struct ether_vlan_header *eh;
2966205869Sjfv	struct ip *ip = NULL;
2967205869Sjfv	struct ip6_hdr *ip6;
2968205869Sjfv	int curr_txd, ehdrlen;
2969205869Sjfv	u32 cmd, hdr_len, ip_hlen;
2970205869Sjfv	u16 etype;
2971205869Sjfv	u8 ipproto;
2972205869Sjfv
2973205869Sjfv
2974205869Sjfv	cmd = hdr_len = ipproto = 0;
2975209959Sjfv	*txd_upper = *txd_lower = 0;
2976205869Sjfv	curr_txd = adapter->next_avail_tx_desc;
2977205869Sjfv
2978205869Sjfv	/*
2979205869Sjfv	 * Determine where frame payload starts.
2980205869Sjfv	 * Jump over vlan headers if already present,
2981205869Sjfv	 * helpful for QinQ too.
2982205869Sjfv	 */
2983205869Sjfv	eh = mtod(mp, struct ether_vlan_header *);
2984205869Sjfv	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
2985205869Sjfv		etype = ntohs(eh->evl_proto);
2986205869Sjfv		ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
2987205869Sjfv	} else {
2988205869Sjfv		etype = ntohs(eh->evl_encap_proto);
2989205869Sjfv		ehdrlen = ETHER_HDR_LEN;
2990205869Sjfv	}
2991205869Sjfv
2992205869Sjfv	/*
2993205869Sjfv	 * We only support TCP/UDP for IPv4 and IPv6 for the moment.
2994205869Sjfv	 * TODO: Support SCTP too when it hits the tree.
2995205869Sjfv	 */
2996205869Sjfv	switch (etype) {
2997205869Sjfv	case ETHERTYPE_IP:
2998205869Sjfv		ip = (struct ip *)(mp->m_data + ehdrlen);
2999205869Sjfv		ip_hlen = ip->ip_hl << 2;
3000205869Sjfv
3001205869Sjfv		/* Setup of IP header checksum. */
3002205869Sjfv		if (mp->m_pkthdr.csum_flags & CSUM_IP) {
3003205869Sjfv			/*
3004205869Sjfv			 * Start offset for header checksum calculation.
3005205869Sjfv			 * End offset for header checksum calculation.
3006205869Sjfv			 * Offset of place to put the checksum.
3007205869Sjfv			 */
3008205869Sjfv			TXD = (struct e1000_context_desc *)
3009205869Sjfv			    &adapter->tx_desc_base[curr_txd];
3010205869Sjfv			TXD->lower_setup.ip_fields.ipcss = ehdrlen;
3011205869Sjfv			TXD->lower_setup.ip_fields.ipcse =
3012205869Sjfv			    htole16(ehdrlen + ip_hlen);
3013205869Sjfv			TXD->lower_setup.ip_fields.ipcso =
3014205869Sjfv			    ehdrlen + offsetof(struct ip, ip_sum);
3015205869Sjfv			cmd |= E1000_TXD_CMD_IP;
3016205869Sjfv			*txd_upper |= E1000_TXD_POPTS_IXSM << 8;
3017205869Sjfv		}
3018205869Sjfv
3019205869Sjfv		hdr_len = ehdrlen + ip_hlen;
3020205869Sjfv		ipproto = ip->ip_p;
3021205869Sjfv
3022205869Sjfv		break;
3023205869Sjfv	case ETHERTYPE_IPV6:
3024205869Sjfv		ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
3025205869Sjfv		ip_hlen = sizeof(struct ip6_hdr); /* XXX: No header stacking. */
3026205869Sjfv
3027205869Sjfv		/* IPv6 doesn't have a header checksum. */
3028205869Sjfv
3029205869Sjfv		hdr_len = ehdrlen + ip_hlen;
3030205869Sjfv		ipproto = ip6->ip6_nxt;
3031209959Sjfv		break;
3032205869Sjfv
3033205869Sjfv	default:
3034205869Sjfv		return;
3035205869Sjfv	}
3036205869Sjfv
3037205869Sjfv	switch (ipproto) {
3038205869Sjfv	case IPPROTO_TCP:
3039205869Sjfv		if (mp->m_pkthdr.csum_flags & CSUM_TCP) {
3040205869Sjfv			*txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
3041205869Sjfv			*txd_upper |= E1000_TXD_POPTS_TXSM << 8;
3042205869Sjfv			/* no need for context if already set */
3043205869Sjfv			if (adapter->last_hw_offload == CSUM_TCP)
3044205869Sjfv				return;
3045205869Sjfv			adapter->last_hw_offload = CSUM_TCP;
3046205869Sjfv			/*
3047205869Sjfv			 * Start offset for payload checksum calculation.
3048205869Sjfv			 * End offset for payload checksum calculation.
3049205869Sjfv			 * Offset of place to put the checksum.
3050205869Sjfv			 */
3051205869Sjfv			TXD = (struct e1000_context_desc *)
3052205869Sjfv			    &adapter->tx_desc_base[curr_txd];
3053205869Sjfv			TXD->upper_setup.tcp_fields.tucss = hdr_len;
3054205869Sjfv			TXD->upper_setup.tcp_fields.tucse = htole16(0);
3055205869Sjfv			TXD->upper_setup.tcp_fields.tucso =
3056205869Sjfv			    hdr_len + offsetof(struct tcphdr, th_sum);
3057205869Sjfv			cmd |= E1000_TXD_CMD_TCP;
3058205869Sjfv		}
3059205869Sjfv		break;
3060205869Sjfv	case IPPROTO_UDP:
3061205869Sjfv	{
3062205869Sjfv		if (mp->m_pkthdr.csum_flags & CSUM_UDP) {
3063205869Sjfv			*txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
3064205869Sjfv			*txd_upper |= E1000_TXD_POPTS_TXSM << 8;
3065205869Sjfv			/* no need for context if already set */
3066205869Sjfv			if (adapter->last_hw_offload == CSUM_UDP)
3067205869Sjfv				return;
3068205869Sjfv			adapter->last_hw_offload = CSUM_UDP;
3069205869Sjfv			/*
3070205869Sjfv			 * Start offset for header checksum calculation.
3071205869Sjfv			 * End offset for header checksum calculation.
3072205869Sjfv			 * Offset of place to put the checksum.
3073205869Sjfv			 */
3074205869Sjfv			TXD = (struct e1000_context_desc *)
3075205869Sjfv			    &adapter->tx_desc_base[curr_txd];
3076205869Sjfv			TXD->upper_setup.tcp_fields.tucss = hdr_len;
3077205869Sjfv			TXD->upper_setup.tcp_fields.tucse = htole16(0);
3078205869Sjfv			TXD->upper_setup.tcp_fields.tucso =
3079205869Sjfv			    hdr_len + offsetof(struct udphdr, uh_sum);
3080205869Sjfv		}
3081205869Sjfv		/* Fall Thru */
3082205869Sjfv	}
3083205869Sjfv	default:
3084205869Sjfv		break;
3085205869Sjfv	}
3086205869Sjfv
3087209959Sjfv	if (TXD == NULL)
3088209959Sjfv		return;
3089205869Sjfv	TXD->tcp_seg_setup.data = htole32(0);
3090205869Sjfv	TXD->cmd_and_length =
3091205869Sjfv	    htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT | cmd);
3092205869Sjfv	tx_buffer = &adapter->tx_buffer_area[curr_txd];
3093205869Sjfv	tx_buffer->m_head = NULL;
3094205869Sjfv	tx_buffer->next_eop = -1;
3095205869Sjfv
3096205869Sjfv	if (++curr_txd == adapter->num_tx_desc)
3097205869Sjfv		curr_txd = 0;
3098205869Sjfv
3099205869Sjfv	adapter->num_tx_desc_avail--;
3100205869Sjfv	adapter->next_avail_tx_desc = curr_txd;
3101205869Sjfv}
3102205869Sjfv
3103205869Sjfv
3104205869Sjfv/**********************************************************************
3105205869Sjfv *
3106205869Sjfv *  Examine each tx_buffer in the used queue. If the hardware is done
3107205869Sjfv *  processing the packet then free associated resources. The
3108205869Sjfv *  tx_buffer is put back on the free queue.
3109205869Sjfv *
3110205869Sjfv **********************************************************************/
3111205869Sjfvstatic void
3112205869Sjfvlem_txeof(struct adapter *adapter)
3113205869Sjfv{
3114205869Sjfv        int first, last, done, num_avail;
3115205869Sjfv        struct em_buffer *tx_buffer;
3116205869Sjfv        struct e1000_tx_desc   *tx_desc, *eop_desc;
3117205869Sjfv	struct ifnet   *ifp = adapter->ifp;
3118205869Sjfv
3119205869Sjfv	EM_TX_LOCK_ASSERT(adapter);
3120205869Sjfv
3121228281Sluigi#ifdef DEV_NETMAP
3122262151Sluigi	if (netmap_tx_irq(ifp, 0))
3123228281Sluigi		return;
3124228281Sluigi#endif /* DEV_NETMAP */
3125205869Sjfv        if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
3126205869Sjfv                return;
3127205869Sjfv
3128205869Sjfv        num_avail = adapter->num_tx_desc_avail;
3129205869Sjfv        first = adapter->next_tx_to_clean;
3130205869Sjfv        tx_desc = &adapter->tx_desc_base[first];
3131205869Sjfv        tx_buffer = &adapter->tx_buffer_area[first];
3132205869Sjfv	last = tx_buffer->next_eop;
3133205869Sjfv        eop_desc = &adapter->tx_desc_base[last];
3134205869Sjfv
3135205869Sjfv	/*
3136205869Sjfv	 * What this does is get the index of the
3137205869Sjfv	 * first descriptor AFTER the EOP of the
3138205869Sjfv	 * first packet, that way we can do the
3139205869Sjfv	 * simple comparison on the inner while loop.
3140205869Sjfv	 */
3141205869Sjfv	if (++last == adapter->num_tx_desc)
3142205869Sjfv 		last = 0;
3143205869Sjfv	done = last;
3144205869Sjfv
3145205869Sjfv        bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
3146205869Sjfv            BUS_DMASYNC_POSTREAD);
3147205869Sjfv
3148205869Sjfv        while (eop_desc->upper.fields.status & E1000_TXD_STAT_DD) {
3149205869Sjfv		/* We clean the range of the packet */
3150205869Sjfv		while (first != done) {
3151205869Sjfv                	tx_desc->upper.data = 0;
3152205869Sjfv                	tx_desc->lower.data = 0;
3153205869Sjfv                	tx_desc->buffer_addr = 0;
3154205869Sjfv                	++num_avail;
3155205869Sjfv
3156205869Sjfv			if (tx_buffer->m_head) {
3157205869Sjfv				ifp->if_opackets++;
3158205869Sjfv				bus_dmamap_sync(adapter->txtag,
3159205869Sjfv				    tx_buffer->map,
3160205869Sjfv				    BUS_DMASYNC_POSTWRITE);
3161205869Sjfv				bus_dmamap_unload(adapter->txtag,
3162205869Sjfv				    tx_buffer->map);
3163205869Sjfv
3164205869Sjfv                        	m_freem(tx_buffer->m_head);
3165205869Sjfv                        	tx_buffer->m_head = NULL;
3166205869Sjfv                	}
3167205869Sjfv			tx_buffer->next_eop = -1;
3168205869Sjfv			adapter->watchdog_time = ticks;
3169205869Sjfv
3170205869Sjfv	                if (++first == adapter->num_tx_desc)
3171205869Sjfv				first = 0;
3172205869Sjfv
3173205869Sjfv	                tx_buffer = &adapter->tx_buffer_area[first];
3174205869Sjfv			tx_desc = &adapter->tx_desc_base[first];
3175205869Sjfv		}
3176205869Sjfv		/* See if we can continue to the next packet */
3177205869Sjfv		last = tx_buffer->next_eop;
3178205869Sjfv		if (last != -1) {
3179205869Sjfv        		eop_desc = &adapter->tx_desc_base[last];
3180205869Sjfv			/* Get new done point */
3181205869Sjfv			if (++last == adapter->num_tx_desc) last = 0;
3182205869Sjfv			done = last;
3183205869Sjfv		} else
3184205869Sjfv			break;
3185205869Sjfv        }
3186205869Sjfv        bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
3187205869Sjfv            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3188205869Sjfv
3189205869Sjfv        adapter->next_tx_to_clean = first;
3190214646Sjfv        adapter->num_tx_desc_avail = num_avail;
3191205869Sjfv
3192270252Sluigi#ifdef NIC_SEND_COMBINING
3193270252Sluigi	if ((adapter->shadow_tdt & MIT_PENDING_TDT) == MIT_PENDING_TDT) {
3194270252Sluigi		/* a tdt write is pending, do it */
3195270252Sluigi		E1000_WRITE_REG(&adapter->hw, E1000_TDT(0),
3196270252Sluigi			0xffff & adapter->shadow_tdt);
3197270252Sluigi		adapter->shadow_tdt = MIT_PENDING_INT;
3198270252Sluigi	} else {
3199270252Sluigi		adapter->shadow_tdt = 0; // disable
3200270252Sluigi	}
3201270252Sluigi#endif /* NIC_SEND_COMBINING */
3202205869Sjfv        /*
3203205869Sjfv         * If we have enough room, clear IFF_DRV_OACTIVE to
3204205869Sjfv         * tell the stack that it is OK to send packets.
3205205869Sjfv         * If there are no pending descriptors, clear the watchdog.
3206205869Sjfv         */
3207214646Sjfv        if (adapter->num_tx_desc_avail > EM_TX_CLEANUP_THRESHOLD) {
3208205869Sjfv                ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
3209270252Sluigi#ifdef NIC_PARAVIRT
3210270252Sluigi		if (adapter->csb) { // XXX also csb_on ?
3211270252Sluigi			adapter->csb->guest_need_txkick = 2; /* acked */
3212270252Sluigi			// XXX memory barrier
3213270252Sluigi		}
3214270252Sluigi#endif /* NIC_PARAVIRT */
3215214646Sjfv                if (adapter->num_tx_desc_avail == adapter->num_tx_desc) {
3216205869Sjfv			adapter->watchdog_check = FALSE;
3217205869Sjfv			return;
3218205869Sjfv		}
3219205869Sjfv        }
3220205869Sjfv}
3221205869Sjfv
3222205869Sjfv/*********************************************************************
3223205869Sjfv *
3224205869Sjfv *  When Link is lost sometimes there is work still in the TX ring
3225205869Sjfv *  which may result in a watchdog, rather than allow that we do an
3226205869Sjfv *  attempted cleanup and then reinit here. Note that this has been
3227205869Sjfv *  seens mostly with fiber adapters.
3228205869Sjfv *
3229205869Sjfv **********************************************************************/
3230205869Sjfvstatic void
3231205869Sjfvlem_tx_purge(struct adapter *adapter)
3232205869Sjfv{
3233205869Sjfv	if ((!adapter->link_active) && (adapter->watchdog_check)) {
3234205869Sjfv		EM_TX_LOCK(adapter);
3235205869Sjfv		lem_txeof(adapter);
3236205869Sjfv		EM_TX_UNLOCK(adapter);
3237205869Sjfv		if (adapter->watchdog_check) /* Still outstanding? */
3238205869Sjfv			lem_init_locked(adapter);
3239205869Sjfv	}
3240205869Sjfv}
3241205869Sjfv
3242205869Sjfv/*********************************************************************
3243205869Sjfv *
3244205869Sjfv *  Get a buffer from system mbuf buffer pool.
3245205869Sjfv *
3246205869Sjfv **********************************************************************/
3247205869Sjfvstatic int
3248205869Sjfvlem_get_buf(struct adapter *adapter, int i)
3249205869Sjfv{
3250205869Sjfv	struct mbuf		*m;
3251205869Sjfv	bus_dma_segment_t	segs[1];
3252205869Sjfv	bus_dmamap_t		map;
3253205869Sjfv	struct em_buffer	*rx_buffer;
3254205869Sjfv	int			error, nsegs;
3255205869Sjfv
3256243857Sglebius	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
3257205869Sjfv	if (m == NULL) {
3258205869Sjfv		adapter->mbuf_cluster_failed++;
3259205869Sjfv		return (ENOBUFS);
3260205869Sjfv	}
3261205869Sjfv	m->m_len = m->m_pkthdr.len = MCLBYTES;
3262205869Sjfv
3263205869Sjfv	if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN))
3264205869Sjfv		m_adj(m, ETHER_ALIGN);
3265205869Sjfv
3266205869Sjfv	/*
3267205869Sjfv	 * Using memory from the mbuf cluster pool, invoke the
3268205869Sjfv	 * bus_dma machinery to arrange the memory mapping.
3269205869Sjfv	 */
3270205869Sjfv	error = bus_dmamap_load_mbuf_sg(adapter->rxtag,
3271205869Sjfv	    adapter->rx_sparemap, m, segs, &nsegs, BUS_DMA_NOWAIT);
3272205869Sjfv	if (error != 0) {
3273205869Sjfv		m_free(m);
3274205869Sjfv		return (error);
3275205869Sjfv	}
3276205869Sjfv
3277205869Sjfv	/* If nsegs is wrong then the stack is corrupt. */
3278205869Sjfv	KASSERT(nsegs == 1, ("Too many segments returned!"));
3279205869Sjfv
3280205869Sjfv	rx_buffer = &adapter->rx_buffer_area[i];
3281205869Sjfv	if (rx_buffer->m_head != NULL)
3282205869Sjfv		bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
3283205869Sjfv
3284205869Sjfv	map = rx_buffer->map;
3285205869Sjfv	rx_buffer->map = adapter->rx_sparemap;
3286205869Sjfv	adapter->rx_sparemap = map;
3287205869Sjfv	bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD);
3288205869Sjfv	rx_buffer->m_head = m;
3289205869Sjfv
3290205869Sjfv	adapter->rx_desc_base[i].buffer_addr = htole64(segs[0].ds_addr);
3291205869Sjfv	return (0);
3292205869Sjfv}
3293205869Sjfv
3294205869Sjfv/*********************************************************************
3295205869Sjfv *
3296205869Sjfv *  Allocate memory for rx_buffer structures. Since we use one
3297205869Sjfv *  rx_buffer per received packet, the maximum number of rx_buffer's
3298205869Sjfv *  that we'll need is equal to the number of receive descriptors
3299205869Sjfv *  that we've allocated.
3300205869Sjfv *
3301205869Sjfv **********************************************************************/
3302205869Sjfvstatic int
3303205869Sjfvlem_allocate_receive_structures(struct adapter *adapter)
3304205869Sjfv{
3305205869Sjfv	device_t dev = adapter->dev;
3306205869Sjfv	struct em_buffer *rx_buffer;
3307205869Sjfv	int i, error;
3308205869Sjfv
3309205869Sjfv	adapter->rx_buffer_area = malloc(sizeof(struct em_buffer) *
3310205869Sjfv	    adapter->num_rx_desc, M_DEVBUF, M_NOWAIT | M_ZERO);
3311205869Sjfv	if (adapter->rx_buffer_area == NULL) {
3312205869Sjfv		device_printf(dev, "Unable to allocate rx_buffer memory\n");
3313205869Sjfv		return (ENOMEM);
3314205869Sjfv	}
3315205869Sjfv
3316205869Sjfv	error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
3317205869Sjfv				1, 0,			/* alignment, bounds */
3318205869Sjfv				BUS_SPACE_MAXADDR,	/* lowaddr */
3319205869Sjfv				BUS_SPACE_MAXADDR,	/* highaddr */
3320205869Sjfv				NULL, NULL,		/* filter, filterarg */
3321205869Sjfv				MCLBYTES,		/* maxsize */
3322205869Sjfv				1,			/* nsegments */
3323205869Sjfv				MCLBYTES,		/* maxsegsize */
3324205869Sjfv				0,			/* flags */
3325205869Sjfv				NULL,			/* lockfunc */
3326205869Sjfv				NULL,			/* lockarg */
3327205869Sjfv				&adapter->rxtag);
3328205869Sjfv	if (error) {
3329205869Sjfv		device_printf(dev, "%s: bus_dma_tag_create failed %d\n",
3330205869Sjfv		    __func__, error);
3331205869Sjfv		goto fail;
3332205869Sjfv	}
3333205869Sjfv
3334205869Sjfv	/* Create the spare map (used by getbuf) */
3335259508Skib	error = bus_dmamap_create(adapter->rxtag, 0, &adapter->rx_sparemap);
3336205869Sjfv	if (error) {
3337205869Sjfv		device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
3338205869Sjfv		    __func__, error);
3339205869Sjfv		goto fail;
3340205869Sjfv	}
3341205869Sjfv
3342205869Sjfv	rx_buffer = adapter->rx_buffer_area;
3343205869Sjfv	for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
3344259508Skib		error = bus_dmamap_create(adapter->rxtag, 0, &rx_buffer->map);
3345205869Sjfv		if (error) {
3346205869Sjfv			device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
3347205869Sjfv			    __func__, error);
3348205869Sjfv			goto fail;
3349205869Sjfv		}
3350205869Sjfv	}
3351205869Sjfv
3352205869Sjfv	return (0);
3353205869Sjfv
3354205869Sjfvfail:
3355205869Sjfv	lem_free_receive_structures(adapter);
3356205869Sjfv	return (error);
3357205869Sjfv}
3358205869Sjfv
3359205869Sjfv/*********************************************************************
3360205869Sjfv *
3361205869Sjfv *  (Re)initialize receive structures.
3362205869Sjfv *
3363205869Sjfv **********************************************************************/
3364205869Sjfvstatic int
3365205869Sjfvlem_setup_receive_structures(struct adapter *adapter)
3366205869Sjfv{
3367205869Sjfv	struct em_buffer *rx_buffer;
3368205869Sjfv	int i, error;
3369228281Sluigi#ifdef DEV_NETMAP
3370228281Sluigi	/* we are already under lock */
3371228281Sluigi	struct netmap_adapter *na = NA(adapter->ifp);
3372228281Sluigi	struct netmap_slot *slot = netmap_reset(na, NR_RX, 0, 0);
3373228281Sluigi#endif
3374205869Sjfv
3375205869Sjfv	/* Reset descriptor ring */
3376205869Sjfv	bzero(adapter->rx_desc_base,
3377205869Sjfv	    (sizeof(struct e1000_rx_desc)) * adapter->num_rx_desc);
3378205869Sjfv
3379205869Sjfv	/* Free current RX buffers. */
3380205869Sjfv	rx_buffer = adapter->rx_buffer_area;
3381205869Sjfv	for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
3382205869Sjfv		if (rx_buffer->m_head != NULL) {
3383205869Sjfv			bus_dmamap_sync(adapter->rxtag, rx_buffer->map,
3384205869Sjfv			    BUS_DMASYNC_POSTREAD);
3385205869Sjfv			bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
3386205869Sjfv			m_freem(rx_buffer->m_head);
3387205869Sjfv			rx_buffer->m_head = NULL;
3388205869Sjfv		}
3389205869Sjfv        }
3390205869Sjfv
3391205869Sjfv	/* Allocate new ones. */
3392205869Sjfv	for (i = 0; i < adapter->num_rx_desc; i++) {
3393228281Sluigi#ifdef DEV_NETMAP
3394228281Sluigi		if (slot) {
3395231796Sluigi			/* the i-th NIC entry goes to slot si */
3396232238Sluigi			int si = netmap_idx_n2k(&na->rx_rings[0], i);
3397229939Sluigi			uint64_t paddr;
3398228281Sluigi			void *addr;
3399228281Sluigi
3400270252Sluigi			addr = PNMB(na, slot + si, &paddr);
3401270252Sluigi			netmap_load_map(na, adapter->rxtag, rx_buffer->map, addr);
3402228281Sluigi			/* Update descriptor */
3403229939Sluigi			adapter->rx_desc_base[i].buffer_addr = htole64(paddr);
3404228281Sluigi			continue;
3405228281Sluigi		}
3406228281Sluigi#endif /* DEV_NETMAP */
3407205869Sjfv		error = lem_get_buf(adapter, i);
3408205869Sjfv		if (error)
3409205869Sjfv                        return (error);
3410205869Sjfv	}
3411205869Sjfv
3412205869Sjfv	/* Setup our descriptor pointers */
3413205869Sjfv	adapter->next_rx_desc_to_check = 0;
3414205869Sjfv	bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
3415205869Sjfv	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3416205869Sjfv
3417205869Sjfv	return (0);
3418205869Sjfv}
3419205869Sjfv
3420205869Sjfv/*********************************************************************
3421205869Sjfv *
3422205869Sjfv *  Enable receive unit.
3423205869Sjfv *
3424205869Sjfv **********************************************************************/
3425205869Sjfv
3426205869Sjfvstatic void
3427205869Sjfvlem_initialize_receive_unit(struct adapter *adapter)
3428205869Sjfv{
3429205869Sjfv	struct ifnet	*ifp = adapter->ifp;
3430205869Sjfv	u64	bus_addr;
3431205869Sjfv	u32	rctl, rxcsum;
3432205869Sjfv
3433205869Sjfv	INIT_DEBUGOUT("lem_initialize_receive_unit: begin");
3434205869Sjfv
3435205869Sjfv	/*
3436205869Sjfv	 * Make sure receives are disabled while setting
3437205869Sjfv	 * up the descriptor ring
3438205869Sjfv	 */
3439205869Sjfv	rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
3440205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
3441205869Sjfv
3442205869Sjfv	if (adapter->hw.mac.type >= e1000_82540) {
3443205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RADV,
3444205869Sjfv		    adapter->rx_abs_int_delay.value);
3445205869Sjfv		/*
3446205869Sjfv		 * Set the interrupt throttling rate. Value is calculated
3447205869Sjfv		 * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns)
3448205869Sjfv		 */
3449205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_ITR, DEFAULT_ITR);
3450205869Sjfv	}
3451205869Sjfv
3452205869Sjfv	/* Setup the Base and Length of the Rx Descriptor Ring */
3453205869Sjfv	bus_addr = adapter->rxdma.dma_paddr;
3454205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(0),
3455205869Sjfv	    adapter->num_rx_desc * sizeof(struct e1000_rx_desc));
3456205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RDBAH(0),
3457205869Sjfv	    (u32)(bus_addr >> 32));
3458205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RDBAL(0),
3459205869Sjfv	    (u32)bus_addr);
3460205869Sjfv
3461205869Sjfv	/* Setup the Receive Control Register */
3462205869Sjfv	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
3463205869Sjfv	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
3464205869Sjfv		   E1000_RCTL_RDMTS_HALF |
3465205869Sjfv		   (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
3466205869Sjfv
3467205869Sjfv	/* Make sure VLAN Filters are off */
3468205869Sjfv	rctl &= ~E1000_RCTL_VFE;
3469205869Sjfv
3470205869Sjfv	if (e1000_tbi_sbp_enabled_82543(&adapter->hw))
3471205869Sjfv		rctl |= E1000_RCTL_SBP;
3472205869Sjfv	else
3473205869Sjfv		rctl &= ~E1000_RCTL_SBP;
3474205869Sjfv
3475205869Sjfv	switch (adapter->rx_buffer_len) {
3476205869Sjfv	default:
3477205869Sjfv	case 2048:
3478205869Sjfv		rctl |= E1000_RCTL_SZ_2048;
3479205869Sjfv		break;
3480205869Sjfv	case 4096:
3481205869Sjfv		rctl |= E1000_RCTL_SZ_4096 |
3482205869Sjfv		    E1000_RCTL_BSEX | E1000_RCTL_LPE;
3483205869Sjfv		break;
3484205869Sjfv	case 8192:
3485205869Sjfv		rctl |= E1000_RCTL_SZ_8192 |
3486205869Sjfv		    E1000_RCTL_BSEX | E1000_RCTL_LPE;
3487205869Sjfv		break;
3488205869Sjfv	case 16384:
3489205869Sjfv		rctl |= E1000_RCTL_SZ_16384 |
3490205869Sjfv		    E1000_RCTL_BSEX | E1000_RCTL_LPE;
3491205869Sjfv		break;
3492205869Sjfv	}
3493205869Sjfv
3494205869Sjfv	if (ifp->if_mtu > ETHERMTU)
3495205869Sjfv		rctl |= E1000_RCTL_LPE;
3496205869Sjfv	else
3497205869Sjfv		rctl &= ~E1000_RCTL_LPE;
3498205869Sjfv
3499205869Sjfv	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
3500205869Sjfv	if ((adapter->hw.mac.type >= e1000_82543) &&
3501205869Sjfv	    (ifp->if_capenable & IFCAP_RXCSUM)) {
3502205869Sjfv		rxcsum = E1000_READ_REG(&adapter->hw, E1000_RXCSUM);
3503205869Sjfv		rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL);
3504205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RXCSUM, rxcsum);
3505205869Sjfv	}
3506205869Sjfv
3507205869Sjfv	/* Enable Receives */
3508205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
3509205869Sjfv
3510205869Sjfv	/*
3511205869Sjfv	 * Setup the HW Rx Head and
3512205869Sjfv	 * Tail Descriptor Pointers
3513205869Sjfv	 */
3514205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0);
3515250413Sluigi	rctl = adapter->num_rx_desc - 1; /* default RDT value */
3516228281Sluigi#ifdef DEV_NETMAP
3517228281Sluigi	/* preserve buffers already made available to clients */
3518250413Sluigi	if (ifp->if_capenable & IFCAP_NETMAP)
3519262151Sluigi		rctl -= nm_kr_rxspace(&NA(adapter->ifp)->rx_rings[0]);
3520228281Sluigi#endif /* DEV_NETMAP */
3521250413Sluigi	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), rctl);
3522205869Sjfv
3523205869Sjfv	return;
3524205869Sjfv}
3525205869Sjfv
3526205869Sjfv/*********************************************************************
3527205869Sjfv *
3528205869Sjfv *  Free receive related data structures.
3529205869Sjfv *
3530205869Sjfv **********************************************************************/
3531205869Sjfvstatic void
3532205869Sjfvlem_free_receive_structures(struct adapter *adapter)
3533205869Sjfv{
3534205869Sjfv	struct em_buffer *rx_buffer;
3535205869Sjfv	int i;
3536205869Sjfv
3537205869Sjfv	INIT_DEBUGOUT("free_receive_structures: begin");
3538205869Sjfv
3539205869Sjfv	if (adapter->rx_sparemap) {
3540205869Sjfv		bus_dmamap_destroy(adapter->rxtag, adapter->rx_sparemap);
3541205869Sjfv		adapter->rx_sparemap = NULL;
3542205869Sjfv	}
3543205869Sjfv
3544205869Sjfv	/* Cleanup any existing buffers */
3545205869Sjfv	if (adapter->rx_buffer_area != NULL) {
3546205869Sjfv		rx_buffer = adapter->rx_buffer_area;
3547205869Sjfv		for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
3548205869Sjfv			if (rx_buffer->m_head != NULL) {
3549205869Sjfv				bus_dmamap_sync(adapter->rxtag, rx_buffer->map,
3550205869Sjfv				    BUS_DMASYNC_POSTREAD);
3551205869Sjfv				bus_dmamap_unload(adapter->rxtag,
3552205869Sjfv				    rx_buffer->map);
3553205869Sjfv				m_freem(rx_buffer->m_head);
3554205869Sjfv				rx_buffer->m_head = NULL;
3555205869Sjfv			} else if (rx_buffer->map != NULL)
3556205869Sjfv				bus_dmamap_unload(adapter->rxtag,
3557205869Sjfv				    rx_buffer->map);
3558205869Sjfv			if (rx_buffer->map != NULL) {
3559205869Sjfv				bus_dmamap_destroy(adapter->rxtag,
3560205869Sjfv				    rx_buffer->map);
3561205869Sjfv				rx_buffer->map = NULL;
3562205869Sjfv			}
3563205869Sjfv		}
3564205869Sjfv	}
3565205869Sjfv
3566205869Sjfv	if (adapter->rx_buffer_area != NULL) {
3567205869Sjfv		free(adapter->rx_buffer_area, M_DEVBUF);
3568205869Sjfv		adapter->rx_buffer_area = NULL;
3569205869Sjfv	}
3570205869Sjfv
3571205869Sjfv	if (adapter->rxtag != NULL) {
3572205869Sjfv		bus_dma_tag_destroy(adapter->rxtag);
3573205869Sjfv		adapter->rxtag = NULL;
3574205869Sjfv	}
3575205869Sjfv}
3576205869Sjfv
3577205869Sjfv/*********************************************************************
3578205869Sjfv *
3579205869Sjfv *  This routine executes in interrupt context. It replenishes
3580205869Sjfv *  the mbufs in the descriptor and sends data which has been
3581205869Sjfv *  dma'ed into host memory to upper layer.
3582205869Sjfv *
3583205869Sjfv *  We loop at most count times if count is > 0, or until done if
3584205869Sjfv *  count < 0.
3585205869Sjfv *
3586205869Sjfv *  For polling we also now return the number of cleaned packets
3587205869Sjfv *********************************************************************/
3588209238Sjfvstatic bool
3589209238Sjfvlem_rxeof(struct adapter *adapter, int count, int *done)
3590205869Sjfv{
3591241844Seadler	struct ifnet	*ifp = adapter->ifp;
3592205869Sjfv	struct mbuf	*mp;
3593214646Sjfv	u8		status = 0, accept_frame = 0, eop = 0;
3594205869Sjfv	u16 		len, desc_len, prev_len_adj;
3595205869Sjfv	int		i, rx_sent = 0;
3596205869Sjfv	struct e1000_rx_desc   *current_desc;
3597205869Sjfv
3598270252Sluigi#ifdef BATCH_DISPATCH
3599270252Sluigi	struct mbuf *mh = NULL, *mt = NULL;
3600270252Sluigi#endif /* BATCH_DISPATCH */
3601270252Sluigi#ifdef NIC_PARAVIRT
3602270252Sluigi	int retries = 0;
3603270252Sluigi	struct paravirt_csb* csb = adapter->csb;
3604270252Sluigi	int csb_mode = csb && csb->guest_csb_on;
3605270252Sluigi
3606270252Sluigi	//ND("clear guest_rxkick at %d", adapter->next_rx_desc_to_check);
3607270252Sluigi	if (csb_mode && csb->guest_need_rxkick)
3608270252Sluigi		csb->guest_need_rxkick = 0;
3609270252Sluigi#endif /* NIC_PARAVIRT */
3610205869Sjfv	EM_RX_LOCK(adapter);
3611270252Sluigi
3612270252Sluigi#ifdef BATCH_DISPATCH
3613270252Sluigi    batch_again:
3614270252Sluigi#endif /* BATCH_DISPATCH */
3615205869Sjfv	i = adapter->next_rx_desc_to_check;
3616205869Sjfv	current_desc = &adapter->rx_desc_base[i];
3617205869Sjfv	bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
3618205869Sjfv	    BUS_DMASYNC_POSTREAD);
3619205869Sjfv
3620228281Sluigi#ifdef DEV_NETMAP
3621262151Sluigi	if (netmap_rx_irq(ifp, 0, &rx_sent)) {
3622262151Sluigi		EM_RX_UNLOCK(adapter);
3623250109Sluigi		return (FALSE);
3624262151Sluigi	}
3625228281Sluigi#endif /* DEV_NETMAP */
3626228281Sluigi
3627270252Sluigi#if 1 // XXX optimization ?
3628205869Sjfv	if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
3629209238Sjfv		if (done != NULL)
3630209238Sjfv			*done = rx_sent;
3631205869Sjfv		EM_RX_UNLOCK(adapter);
3632209238Sjfv		return (FALSE);
3633205869Sjfv	}
3634270252Sluigi#endif /* 0 */
3635205869Sjfv
3636214646Sjfv	while (count != 0 && ifp->if_drv_flags & IFF_DRV_RUNNING) {
3637205869Sjfv		struct mbuf *m = NULL;
3638205869Sjfv
3639214646Sjfv		status = current_desc->status;
3640270252Sluigi		if ((status & E1000_RXD_STAT_DD) == 0) {
3641270252Sluigi#ifdef NIC_PARAVIRT
3642270252Sluigi		    if (csb_mode) {
3643270252Sluigi			/* buffer not ready yet. Retry a few times before giving up */
3644270252Sluigi			if (++retries <= adapter->rx_retries) {
3645270252Sluigi				continue;
3646270252Sluigi			}
3647270252Sluigi			if (csb->guest_need_rxkick == 0) {
3648270252Sluigi				// ND("set guest_rxkick at %d", adapter->next_rx_desc_to_check);
3649270252Sluigi				csb->guest_need_rxkick = 1;
3650270252Sluigi				// XXX memory barrier, status volatile ?
3651270252Sluigi				continue; /* double check */
3652270252Sluigi			}
3653270252Sluigi		    }
3654270252Sluigi		    /* no buffer ready, give up */
3655270252Sluigi#endif /* NIC_PARAVIRT */
3656214646Sjfv			break;
3657270252Sluigi		}
3658270252Sluigi#ifdef NIC_PARAVIRT
3659270252Sluigi		if (csb_mode) {
3660270252Sluigi			if (csb->guest_need_rxkick)
3661270252Sluigi				// ND("clear again guest_rxkick at %d", adapter->next_rx_desc_to_check);
3662270252Sluigi			csb->guest_need_rxkick = 0;
3663270252Sluigi			retries = 0;
3664270252Sluigi		}
3665270252Sluigi#endif /* NIC_PARAVIRT */
3666214646Sjfv
3667205869Sjfv		mp = adapter->rx_buffer_area[i].m_head;
3668205869Sjfv		/*
3669205869Sjfv		 * Can't defer bus_dmamap_sync(9) because TBI_ACCEPT
3670205869Sjfv		 * needs to access the last received byte in the mbuf.
3671205869Sjfv		 */
3672205869Sjfv		bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map,
3673205869Sjfv		    BUS_DMASYNC_POSTREAD);
3674205869Sjfv
3675205869Sjfv		accept_frame = 1;
3676205869Sjfv		prev_len_adj = 0;
3677205869Sjfv		desc_len = le16toh(current_desc->length);
3678205869Sjfv		if (status & E1000_RXD_STAT_EOP) {
3679205869Sjfv			count--;
3680205869Sjfv			eop = 1;
3681205869Sjfv			if (desc_len < ETHER_CRC_LEN) {
3682205869Sjfv				len = 0;
3683205869Sjfv				prev_len_adj = ETHER_CRC_LEN - desc_len;
3684205869Sjfv			} else
3685205869Sjfv				len = desc_len - ETHER_CRC_LEN;
3686205869Sjfv		} else {
3687205869Sjfv			eop = 0;
3688205869Sjfv			len = desc_len;
3689205869Sjfv		}
3690205869Sjfv
3691205869Sjfv		if (current_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
3692205869Sjfv			u8	last_byte;
3693205869Sjfv			u32	pkt_len = desc_len;
3694205869Sjfv
3695205869Sjfv			if (adapter->fmp != NULL)
3696205869Sjfv				pkt_len += adapter->fmp->m_pkthdr.len;
3697205869Sjfv
3698205869Sjfv			last_byte = *(mtod(mp, caddr_t) + desc_len - 1);
3699205869Sjfv			if (TBI_ACCEPT(&adapter->hw, status,
3700205869Sjfv			    current_desc->errors, pkt_len, last_byte,
3701205869Sjfv			    adapter->min_frame_size, adapter->max_frame_size)) {
3702205869Sjfv				e1000_tbi_adjust_stats_82543(&adapter->hw,
3703205869Sjfv				    &adapter->stats, pkt_len,
3704205869Sjfv				    adapter->hw.mac.addr,
3705205869Sjfv				    adapter->max_frame_size);
3706205869Sjfv				if (len > 0)
3707205869Sjfv					len--;
3708205869Sjfv			} else
3709205869Sjfv				accept_frame = 0;
3710205869Sjfv		}
3711205869Sjfv
3712205869Sjfv		if (accept_frame) {
3713205869Sjfv			if (lem_get_buf(adapter, i) != 0) {
3714205869Sjfv				ifp->if_iqdrops++;
3715205869Sjfv				goto discard;
3716205869Sjfv			}
3717205869Sjfv
3718205869Sjfv			/* Assign correct length to the current fragment */
3719205869Sjfv			mp->m_len = len;
3720205869Sjfv
3721205869Sjfv			if (adapter->fmp == NULL) {
3722205869Sjfv				mp->m_pkthdr.len = len;
3723205869Sjfv				adapter->fmp = mp; /* Store the first mbuf */
3724205869Sjfv				adapter->lmp = mp;
3725205869Sjfv			} else {
3726205869Sjfv				/* Chain mbuf's together */
3727205869Sjfv				mp->m_flags &= ~M_PKTHDR;
3728205869Sjfv				/*
3729205869Sjfv				 * Adjust length of previous mbuf in chain if
3730205869Sjfv				 * we received less than 4 bytes in the last
3731205869Sjfv				 * descriptor.
3732205869Sjfv				 */
3733205869Sjfv				if (prev_len_adj > 0) {
3734205869Sjfv					adapter->lmp->m_len -= prev_len_adj;
3735205869Sjfv					adapter->fmp->m_pkthdr.len -=
3736205869Sjfv					    prev_len_adj;
3737205869Sjfv				}
3738205869Sjfv				adapter->lmp->m_next = mp;
3739205869Sjfv				adapter->lmp = adapter->lmp->m_next;
3740205869Sjfv				adapter->fmp->m_pkthdr.len += len;
3741205869Sjfv			}
3742205869Sjfv
3743205869Sjfv			if (eop) {
3744205869Sjfv				adapter->fmp->m_pkthdr.rcvif = ifp;
3745205869Sjfv				ifp->if_ipackets++;
3746205869Sjfv				lem_receive_checksum(adapter, current_desc,
3747205869Sjfv				    adapter->fmp);
3748205869Sjfv#ifndef __NO_STRICT_ALIGNMENT
3749205869Sjfv				if (adapter->max_frame_size >
3750205869Sjfv				    (MCLBYTES - ETHER_ALIGN) &&
3751205869Sjfv				    lem_fixup_rx(adapter) != 0)
3752205869Sjfv					goto skip;
3753205869Sjfv#endif
3754205869Sjfv				if (status & E1000_RXD_STAT_VP) {
3755205869Sjfv					adapter->fmp->m_pkthdr.ether_vtag =
3756229606Srwatson					    le16toh(current_desc->special);
3757205869Sjfv					adapter->fmp->m_flags |= M_VLANTAG;
3758205869Sjfv				}
3759205869Sjfv#ifndef __NO_STRICT_ALIGNMENT
3760205869Sjfvskip:
3761205869Sjfv#endif
3762205869Sjfv				m = adapter->fmp;
3763205869Sjfv				adapter->fmp = NULL;
3764205869Sjfv				adapter->lmp = NULL;
3765205869Sjfv			}
3766205869Sjfv		} else {
3767240879Ssbruno			adapter->dropped_pkts++;
3768205869Sjfvdiscard:
3769205869Sjfv			/* Reuse loaded DMA map and just update mbuf chain */
3770205869Sjfv			mp = adapter->rx_buffer_area[i].m_head;
3771205869Sjfv			mp->m_len = mp->m_pkthdr.len = MCLBYTES;
3772205869Sjfv			mp->m_data = mp->m_ext.ext_buf;
3773205869Sjfv			mp->m_next = NULL;
3774205869Sjfv			if (adapter->max_frame_size <=
3775205869Sjfv			    (MCLBYTES - ETHER_ALIGN))
3776205869Sjfv				m_adj(mp, ETHER_ALIGN);
3777205869Sjfv			if (adapter->fmp != NULL) {
3778205869Sjfv				m_freem(adapter->fmp);
3779205869Sjfv				adapter->fmp = NULL;
3780205869Sjfv				adapter->lmp = NULL;
3781205869Sjfv			}
3782205869Sjfv			m = NULL;
3783205869Sjfv		}
3784205869Sjfv
3785205869Sjfv		/* Zero out the receive descriptors status. */
3786205869Sjfv		current_desc->status = 0;
3787205869Sjfv		bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
3788205869Sjfv		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3789205869Sjfv
3790270252Sluigi#ifdef NIC_PARAVIRT
3791270252Sluigi		if (csb_mode) {
3792270252Sluigi			/* the buffer at i has been already replaced by lem_get_buf()
3793270252Sluigi			 * so it is safe to set guest_rdt = i and possibly send a kick.
3794270252Sluigi			 * XXX see if we can optimize it later.
3795270252Sluigi			 */
3796270252Sluigi			csb->guest_rdt = i;
3797270252Sluigi			// XXX memory barrier
3798270252Sluigi			if (i == csb->host_rxkick_at)
3799270252Sluigi				E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
3800270252Sluigi		}
3801270252Sluigi#endif /* NIC_PARAVIRT */
3802205869Sjfv		/* Advance our pointers to the next descriptor. */
3803205869Sjfv		if (++i == adapter->num_rx_desc)
3804205869Sjfv			i = 0;
3805205869Sjfv		/* Call into the stack */
3806205869Sjfv		if (m != NULL) {
3807270252Sluigi#ifdef BATCH_DISPATCH
3808270252Sluigi		    if (adapter->batch_enable) {
3809270252Sluigi			if (mh == NULL)
3810270252Sluigi				mh = mt = m;
3811270252Sluigi			else
3812270252Sluigi				mt->m_nextpkt = m;
3813270252Sluigi			mt = m;
3814270252Sluigi			m->m_nextpkt = NULL;
3815270252Sluigi			rx_sent++;
3816270252Sluigi			current_desc = &adapter->rx_desc_base[i];
3817270252Sluigi			continue;
3818270252Sluigi		    }
3819270252Sluigi#endif /* BATCH_DISPATCH */
3820205869Sjfv			adapter->next_rx_desc_to_check = i;
3821205869Sjfv			EM_RX_UNLOCK(adapter);
3822205869Sjfv			(*ifp->if_input)(ifp, m);
3823205869Sjfv			EM_RX_LOCK(adapter);
3824205869Sjfv			rx_sent++;
3825205869Sjfv			i = adapter->next_rx_desc_to_check;
3826205869Sjfv		}
3827205869Sjfv		current_desc = &adapter->rx_desc_base[i];
3828205869Sjfv	}
3829205869Sjfv	adapter->next_rx_desc_to_check = i;
3830270252Sluigi#ifdef BATCH_DISPATCH
3831270252Sluigi	if (mh) {
3832270252Sluigi		EM_RX_UNLOCK(adapter);
3833270252Sluigi		while ( (mt = mh) != NULL) {
3834270252Sluigi			mh = mh->m_nextpkt;
3835270252Sluigi			mt->m_nextpkt = NULL;
3836270252Sluigi			if_input(ifp, mt);
3837270252Sluigi		}
3838270252Sluigi		EM_RX_LOCK(adapter);
3839270252Sluigi		i = adapter->next_rx_desc_to_check; /* in case of interrupts */
3840270252Sluigi		if (count > 0)
3841270252Sluigi			goto batch_again;
3842270252Sluigi	}
3843270252Sluigi#endif /* BATCH_DISPATCH */
3844205869Sjfv
3845205869Sjfv	/* Advance the E1000's Receive Queue #0  "Tail Pointer". */
3846205869Sjfv	if (--i < 0)
3847205869Sjfv		i = adapter->num_rx_desc - 1;
3848270252Sluigi#ifdef NIC_PARAVIRT
3849270252Sluigi	if (!csb_mode) /* filter out writes */
3850270252Sluigi#endif /* NIC_PARAVIRT */
3851205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
3852209238Sjfv	if (done != NULL)
3853209238Sjfv		*done = rx_sent;
3854205869Sjfv	EM_RX_UNLOCK(adapter);
3855214646Sjfv	return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
3856205869Sjfv}
3857205869Sjfv
3858205869Sjfv#ifndef __NO_STRICT_ALIGNMENT
3859205869Sjfv/*
3860205869Sjfv * When jumbo frames are enabled we should realign entire payload on
3861205869Sjfv * architecures with strict alignment. This is serious design mistake of 8254x
3862205869Sjfv * as it nullifies DMA operations. 8254x just allows RX buffer size to be
3863205869Sjfv * 2048/4096/8192/16384. What we really want is 2048 - ETHER_ALIGN to align its
3864205869Sjfv * payload. On architecures without strict alignment restrictions 8254x still
3865205869Sjfv * performs unaligned memory access which would reduce the performance too.
3866205869Sjfv * To avoid copying over an entire frame to align, we allocate a new mbuf and
3867205869Sjfv * copy ethernet header to the new mbuf. The new mbuf is prepended into the
3868205869Sjfv * existing mbuf chain.
3869205869Sjfv *
3870205869Sjfv * Be aware, best performance of the 8254x is achived only when jumbo frame is
3871205869Sjfv * not used at all on architectures with strict alignment.
3872205869Sjfv */
3873205869Sjfvstatic int
3874205869Sjfvlem_fixup_rx(struct adapter *adapter)
3875205869Sjfv{
3876205869Sjfv	struct mbuf *m, *n;
3877205869Sjfv	int error;
3878205869Sjfv
3879205869Sjfv	error = 0;
3880205869Sjfv	m = adapter->fmp;
3881205869Sjfv	if (m->m_len <= (MCLBYTES - ETHER_HDR_LEN)) {
3882205869Sjfv		bcopy(m->m_data, m->m_data + ETHER_HDR_LEN, m->m_len);
3883205869Sjfv		m->m_data += ETHER_HDR_LEN;
3884205869Sjfv	} else {
3885243857Sglebius		MGETHDR(n, M_NOWAIT, MT_DATA);
3886205869Sjfv		if (n != NULL) {
3887205869Sjfv			bcopy(m->m_data, n->m_data, ETHER_HDR_LEN);
3888205869Sjfv			m->m_data += ETHER_HDR_LEN;
3889205869Sjfv			m->m_len -= ETHER_HDR_LEN;
3890205869Sjfv			n->m_len = ETHER_HDR_LEN;
3891205869Sjfv			M_MOVE_PKTHDR(n, m);
3892205869Sjfv			n->m_next = m;
3893205869Sjfv			adapter->fmp = n;
3894205869Sjfv		} else {
3895205869Sjfv			adapter->dropped_pkts++;
3896205869Sjfv			m_freem(adapter->fmp);
3897205869Sjfv			adapter->fmp = NULL;
3898205869Sjfv			error = ENOMEM;
3899205869Sjfv		}
3900205869Sjfv	}
3901205869Sjfv
3902205869Sjfv	return (error);
3903205869Sjfv}
3904205869Sjfv#endif
3905205869Sjfv
3906205869Sjfv/*********************************************************************
3907205869Sjfv *
3908205869Sjfv *  Verify that the hardware indicated that the checksum is valid.
3909205869Sjfv *  Inform the stack about the status of checksum so that stack
3910205869Sjfv *  doesn't spend time verifying the checksum.
3911205869Sjfv *
3912205869Sjfv *********************************************************************/
3913205869Sjfvstatic void
3914205869Sjfvlem_receive_checksum(struct adapter *adapter,
3915205869Sjfv	    struct e1000_rx_desc *rx_desc, struct mbuf *mp)
3916205869Sjfv{
3917205869Sjfv	/* 82543 or newer only */
3918205869Sjfv	if ((adapter->hw.mac.type < e1000_82543) ||
3919205869Sjfv	    /* Ignore Checksum bit is set */
3920205869Sjfv	    (rx_desc->status & E1000_RXD_STAT_IXSM)) {
3921205869Sjfv		mp->m_pkthdr.csum_flags = 0;
3922205869Sjfv		return;
3923205869Sjfv	}
3924205869Sjfv
3925205869Sjfv	if (rx_desc->status & E1000_RXD_STAT_IPCS) {
3926205869Sjfv		/* Did it pass? */
3927205869Sjfv		if (!(rx_desc->errors & E1000_RXD_ERR_IPE)) {
3928205869Sjfv			/* IP Checksum Good */
3929205869Sjfv			mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
3930205869Sjfv			mp->m_pkthdr.csum_flags |= CSUM_IP_VALID;
3931205869Sjfv
3932205869Sjfv		} else {
3933205869Sjfv			mp->m_pkthdr.csum_flags = 0;
3934205869Sjfv		}
3935205869Sjfv	}
3936205869Sjfv
3937205869Sjfv	if (rx_desc->status & E1000_RXD_STAT_TCPCS) {
3938205869Sjfv		/* Did it pass? */
3939205869Sjfv		if (!(rx_desc->errors & E1000_RXD_ERR_TCPE)) {
3940205869Sjfv			mp->m_pkthdr.csum_flags |=
3941205869Sjfv			(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
3942205869Sjfv			mp->m_pkthdr.csum_data = htons(0xffff);
3943205869Sjfv		}
3944205869Sjfv	}
3945205869Sjfv}
3946205869Sjfv
3947205869Sjfv/*
3948205869Sjfv * This routine is run via an vlan
3949205869Sjfv * config EVENT
3950205869Sjfv */
3951205869Sjfvstatic void
3952205869Sjfvlem_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
3953205869Sjfv{
3954205869Sjfv	struct adapter	*adapter = ifp->if_softc;
3955205869Sjfv	u32		index, bit;
3956205869Sjfv
3957205869Sjfv	if (ifp->if_softc !=  arg)   /* Not our event */
3958205869Sjfv		return;
3959205869Sjfv
3960205869Sjfv	if ((vtag == 0) || (vtag > 4095))       /* Invalid ID */
3961205869Sjfv                return;
3962205869Sjfv
3963214646Sjfv	EM_CORE_LOCK(adapter);
3964205869Sjfv	index = (vtag >> 5) & 0x7F;
3965205869Sjfv	bit = vtag & 0x1F;
3966214646Sjfv	adapter->shadow_vfta[index] |= (1 << bit);
3967205869Sjfv	++adapter->num_vlans;
3968205869Sjfv	/* Re-init to load the changes */
3969214646Sjfv	if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
3970214646Sjfv		lem_init_locked(adapter);
3971214646Sjfv	EM_CORE_UNLOCK(adapter);
3972205869Sjfv}
3973205869Sjfv
3974205869Sjfv/*
3975205869Sjfv * This routine is run via an vlan
3976205869Sjfv * unconfig EVENT
3977205869Sjfv */
3978205869Sjfvstatic void
3979205869Sjfvlem_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
3980205869Sjfv{
3981205869Sjfv	struct adapter	*adapter = ifp->if_softc;
3982205869Sjfv	u32		index, bit;
3983205869Sjfv
3984205869Sjfv	if (ifp->if_softc !=  arg)
3985205869Sjfv		return;
3986205869Sjfv
3987205869Sjfv	if ((vtag == 0) || (vtag > 4095))       /* Invalid */
3988205869Sjfv                return;
3989205869Sjfv
3990214646Sjfv	EM_CORE_LOCK(adapter);
3991205869Sjfv	index = (vtag >> 5) & 0x7F;
3992205869Sjfv	bit = vtag & 0x1F;
3993214646Sjfv	adapter->shadow_vfta[index] &= ~(1 << bit);
3994205869Sjfv	--adapter->num_vlans;
3995205869Sjfv	/* Re-init to load the changes */
3996214646Sjfv	if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
3997214646Sjfv		lem_init_locked(adapter);
3998214646Sjfv	EM_CORE_UNLOCK(adapter);
3999205869Sjfv}
4000205869Sjfv
4001205869Sjfvstatic void
4002205869Sjfvlem_setup_vlan_hw_support(struct adapter *adapter)
4003205869Sjfv{
4004205869Sjfv	struct e1000_hw *hw = &adapter->hw;
4005205869Sjfv	u32             reg;
4006205869Sjfv
4007205869Sjfv	/*
4008205869Sjfv	** We get here thru init_locked, meaning
4009205869Sjfv	** a soft reset, this has already cleared
4010205869Sjfv	** the VFTA and other state, so if there
4011205869Sjfv	** have been no vlan's registered do nothing.
4012205869Sjfv	*/
4013205869Sjfv	if (adapter->num_vlans == 0)
4014205869Sjfv                return;
4015205869Sjfv
4016205869Sjfv	/*
4017205869Sjfv	** A soft reset zero's out the VFTA, so
4018205869Sjfv	** we need to repopulate it now.
4019205869Sjfv	*/
4020205869Sjfv	for (int i = 0; i < EM_VFTA_SIZE; i++)
4021214646Sjfv                if (adapter->shadow_vfta[i] != 0)
4022205869Sjfv			E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
4023214646Sjfv                            i, adapter->shadow_vfta[i]);
4024205869Sjfv
4025205869Sjfv	reg = E1000_READ_REG(hw, E1000_CTRL);
4026205869Sjfv	reg |= E1000_CTRL_VME;
4027205869Sjfv	E1000_WRITE_REG(hw, E1000_CTRL, reg);
4028205869Sjfv
4029205869Sjfv	/* Enable the Filter Table */
4030205869Sjfv	reg = E1000_READ_REG(hw, E1000_RCTL);
4031205869Sjfv	reg &= ~E1000_RCTL_CFIEN;
4032205869Sjfv	reg |= E1000_RCTL_VFE;
4033205869Sjfv	E1000_WRITE_REG(hw, E1000_RCTL, reg);
4034205869Sjfv}
4035205869Sjfv
4036205869Sjfvstatic void
4037205869Sjfvlem_enable_intr(struct adapter *adapter)
4038205869Sjfv{
4039205869Sjfv	struct e1000_hw *hw = &adapter->hw;
4040205869Sjfv	u32 ims_mask = IMS_ENABLE_MASK;
4041205869Sjfv
4042205869Sjfv	E1000_WRITE_REG(hw, E1000_IMS, ims_mask);
4043205869Sjfv}
4044205869Sjfv
4045205869Sjfvstatic void
4046205869Sjfvlem_disable_intr(struct adapter *adapter)
4047205869Sjfv{
4048205869Sjfv	struct e1000_hw *hw = &adapter->hw;
4049205869Sjfv
4050238953Sjfv	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
4051205869Sjfv}
4052205869Sjfv
4053205869Sjfv/*
4054205869Sjfv * Bit of a misnomer, what this really means is
4055205869Sjfv * to enable OS management of the system... aka
4056205869Sjfv * to disable special hardware management features
4057205869Sjfv */
4058205869Sjfvstatic void
4059205869Sjfvlem_init_manageability(struct adapter *adapter)
4060205869Sjfv{
4061205869Sjfv	/* A shared code workaround */
4062205869Sjfv	if (adapter->has_manage) {
4063205869Sjfv		int manc = E1000_READ_REG(&adapter->hw, E1000_MANC);
4064205869Sjfv		/* disable hardware interception of ARP */
4065205869Sjfv		manc &= ~(E1000_MANC_ARP_EN);
4066205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc);
4067205869Sjfv	}
4068205869Sjfv}
4069205869Sjfv
4070205869Sjfv/*
4071205869Sjfv * Give control back to hardware management
4072205869Sjfv * controller if there is one.
4073205869Sjfv */
4074205869Sjfvstatic void
4075205869Sjfvlem_release_manageability(struct adapter *adapter)
4076205869Sjfv{
4077205869Sjfv	if (adapter->has_manage) {
4078205869Sjfv		int manc = E1000_READ_REG(&adapter->hw, E1000_MANC);
4079205869Sjfv
4080205869Sjfv		/* re-enable hardware interception of ARP */
4081205869Sjfv		manc |= E1000_MANC_ARP_EN;
4082205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc);
4083205869Sjfv	}
4084205869Sjfv}
4085205869Sjfv
4086205869Sjfv/*
4087205869Sjfv * lem_get_hw_control sets the {CTRL_EXT|FWSM}:DRV_LOAD bit.
4088205869Sjfv * For ASF and Pass Through versions of f/w this means
4089205869Sjfv * that the driver is loaded. For AMT version type f/w
4090205869Sjfv * this means that the network i/f is open.
4091205869Sjfv */
4092205869Sjfvstatic void
4093205869Sjfvlem_get_hw_control(struct adapter *adapter)
4094205869Sjfv{
4095205869Sjfv	u32 ctrl_ext;
4096205869Sjfv
4097205869Sjfv	ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
4098205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT,
4099205869Sjfv	    ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
4100205869Sjfv	return;
4101205869Sjfv}
4102205869Sjfv
4103205869Sjfv/*
4104205869Sjfv * lem_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
4105205869Sjfv * For ASF and Pass Through versions of f/w this means that
4106205869Sjfv * the driver is no longer loaded. For AMT versions of the
4107205869Sjfv * f/w this means that the network i/f is closed.
4108205869Sjfv */
4109205869Sjfvstatic void
4110205869Sjfvlem_release_hw_control(struct adapter *adapter)
4111205869Sjfv{
4112205869Sjfv	u32 ctrl_ext;
4113205869Sjfv
4114205869Sjfv	if (!adapter->has_manage)
4115205869Sjfv		return;
4116205869Sjfv
4117205869Sjfv	ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
4118205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT,
4119205869Sjfv	    ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
4120205869Sjfv	return;
4121205869Sjfv}
4122205869Sjfv
4123205869Sjfvstatic int
4124205869Sjfvlem_is_valid_ether_addr(u8 *addr)
4125205869Sjfv{
4126205869Sjfv	char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
4127205869Sjfv
4128205869Sjfv	if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) {
4129205869Sjfv		return (FALSE);
4130205869Sjfv	}
4131205869Sjfv
4132205869Sjfv	return (TRUE);
4133205869Sjfv}
4134205869Sjfv
4135205869Sjfv/*
4136205869Sjfv** Parse the interface capabilities with regard
4137205869Sjfv** to both system management and wake-on-lan for
4138205869Sjfv** later use.
4139205869Sjfv*/
4140205869Sjfvstatic void
4141205869Sjfvlem_get_wakeup(device_t dev)
4142205869Sjfv{
4143205869Sjfv	struct adapter	*adapter = device_get_softc(dev);
4144205869Sjfv	u16		eeprom_data = 0, device_id, apme_mask;
4145205869Sjfv
4146205869Sjfv	adapter->has_manage = e1000_enable_mng_pass_thru(&adapter->hw);
4147205869Sjfv	apme_mask = EM_EEPROM_APME;
4148205869Sjfv
4149205869Sjfv	switch (adapter->hw.mac.type) {
4150205869Sjfv	case e1000_82542:
4151205869Sjfv	case e1000_82543:
4152205869Sjfv		break;
4153205869Sjfv	case e1000_82544:
4154205869Sjfv		e1000_read_nvm(&adapter->hw,
4155205869Sjfv		    NVM_INIT_CONTROL2_REG, 1, &eeprom_data);
4156205869Sjfv		apme_mask = EM_82544_APME;
4157205869Sjfv		break;
4158205869Sjfv	case e1000_82546:
4159205869Sjfv	case e1000_82546_rev_3:
4160205869Sjfv		if (adapter->hw.bus.func == 1) {
4161205869Sjfv			e1000_read_nvm(&adapter->hw,
4162205869Sjfv			    NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
4163205869Sjfv			break;
4164205869Sjfv		} else
4165205869Sjfv			e1000_read_nvm(&adapter->hw,
4166205869Sjfv			    NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
4167205869Sjfv		break;
4168205869Sjfv	default:
4169205869Sjfv		e1000_read_nvm(&adapter->hw,
4170205869Sjfv		    NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
4171205869Sjfv		break;
4172205869Sjfv	}
4173205869Sjfv	if (eeprom_data & apme_mask)
4174205869Sjfv		adapter->wol = (E1000_WUFC_MAG | E1000_WUFC_MC);
4175205869Sjfv	/*
4176205869Sjfv         * We have the eeprom settings, now apply the special cases
4177205869Sjfv         * where the eeprom may be wrong or the board won't support
4178205869Sjfv         * wake on lan on a particular port
4179205869Sjfv	 */
4180205869Sjfv	device_id = pci_get_device(dev);
4181205869Sjfv        switch (device_id) {
4182205869Sjfv	case E1000_DEV_ID_82546GB_PCIE:
4183205869Sjfv		adapter->wol = 0;
4184205869Sjfv		break;
4185205869Sjfv	case E1000_DEV_ID_82546EB_FIBER:
4186205869Sjfv	case E1000_DEV_ID_82546GB_FIBER:
4187205869Sjfv		/* Wake events only supported on port A for dual fiber
4188205869Sjfv		 * regardless of eeprom setting */
4189205869Sjfv		if (E1000_READ_REG(&adapter->hw, E1000_STATUS) &
4190205869Sjfv		    E1000_STATUS_FUNC_1)
4191205869Sjfv			adapter->wol = 0;
4192205869Sjfv		break;
4193205869Sjfv	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
4194205869Sjfv                /* if quad port adapter, disable WoL on all but port A */
4195205869Sjfv		if (global_quad_port_a != 0)
4196205869Sjfv			adapter->wol = 0;
4197205869Sjfv		/* Reset for multiple quad port adapters */
4198205869Sjfv		if (++global_quad_port_a == 4)
4199205869Sjfv			global_quad_port_a = 0;
4200205869Sjfv                break;
4201205869Sjfv	}
4202205869Sjfv	return;
4203205869Sjfv}
4204205869Sjfv
4205205869Sjfv
4206205869Sjfv/*
4207205869Sjfv * Enable PCI Wake On Lan capability
4208205869Sjfv */
4209206001Smariusstatic void
4210205869Sjfvlem_enable_wakeup(device_t dev)
4211205869Sjfv{
4212205869Sjfv	struct adapter	*adapter = device_get_softc(dev);
4213205869Sjfv	struct ifnet	*ifp = adapter->ifp;
4214205869Sjfv	u32		pmc, ctrl, ctrl_ext, rctl;
4215205869Sjfv	u16     	status;
4216205869Sjfv
4217219902Sjhb	if ((pci_find_cap(dev, PCIY_PMG, &pmc) != 0))
4218205869Sjfv		return;
4219205869Sjfv
4220205869Sjfv	/* Advertise the wakeup capability */
4221205869Sjfv	ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
4222205869Sjfv	ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
4223205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
4224205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
4225205869Sjfv
4226205869Sjfv	/* Keep the laser running on Fiber adapters */
4227205869Sjfv	if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
4228205869Sjfv	    adapter->hw.phy.media_type == e1000_media_type_internal_serdes) {
4229205869Sjfv		ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
4230205869Sjfv		ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
4231205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext);
4232205869Sjfv	}
4233205869Sjfv
4234205869Sjfv	/*
4235205869Sjfv	** Determine type of Wakeup: note that wol
4236205869Sjfv	** is set with all bits on by default.
4237205869Sjfv	*/
4238205869Sjfv	if ((ifp->if_capenable & IFCAP_WOL_MAGIC) == 0)
4239205869Sjfv		adapter->wol &= ~E1000_WUFC_MAG;
4240205869Sjfv
4241205869Sjfv	if ((ifp->if_capenable & IFCAP_WOL_MCAST) == 0)
4242205869Sjfv		adapter->wol &= ~E1000_WUFC_MC;
4243205869Sjfv	else {
4244205869Sjfv		rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
4245205869Sjfv		rctl |= E1000_RCTL_MPE;
4246205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
4247205869Sjfv	}
4248205869Sjfv
4249205869Sjfv	if (adapter->hw.mac.type == e1000_pchlan) {
4250205869Sjfv		if (lem_enable_phy_wakeup(adapter))
4251205869Sjfv			return;
4252205869Sjfv	} else {
4253205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
4254205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol);
4255205869Sjfv	}
4256205869Sjfv
4257205869Sjfv
4258205869Sjfv        /* Request PME */
4259205869Sjfv        status = pci_read_config(dev, pmc + PCIR_POWER_STATUS, 2);
4260205869Sjfv	status &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
4261205869Sjfv	if (ifp->if_capenable & IFCAP_WOL)
4262205869Sjfv		status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
4263205869Sjfv        pci_write_config(dev, pmc + PCIR_POWER_STATUS, status, 2);
4264205869Sjfv
4265205869Sjfv	return;
4266205869Sjfv}
4267205869Sjfv
4268205869Sjfv/*
4269205869Sjfv** WOL in the newer chipset interfaces (pchlan)
4270205869Sjfv** require thing to be copied into the phy
4271205869Sjfv*/
4272205869Sjfvstatic int
4273205869Sjfvlem_enable_phy_wakeup(struct adapter *adapter)
4274205869Sjfv{
4275205869Sjfv	struct e1000_hw *hw = &adapter->hw;
4276205869Sjfv	u32 mreg, ret = 0;
4277205869Sjfv	u16 preg;
4278205869Sjfv
4279205869Sjfv	/* copy MAC RARs to PHY RARs */
4280205869Sjfv	for (int i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
4281205869Sjfv		mreg = E1000_READ_REG(hw, E1000_RAL(i));
4282205869Sjfv		e1000_write_phy_reg(hw, BM_RAR_L(i), (u16)(mreg & 0xFFFF));
4283205869Sjfv		e1000_write_phy_reg(hw, BM_RAR_M(i),
4284205869Sjfv		    (u16)((mreg >> 16) & 0xFFFF));
4285205869Sjfv		mreg = E1000_READ_REG(hw, E1000_RAH(i));
4286205869Sjfv		e1000_write_phy_reg(hw, BM_RAR_H(i), (u16)(mreg & 0xFFFF));
4287205869Sjfv		e1000_write_phy_reg(hw, BM_RAR_CTRL(i),
4288205869Sjfv		    (u16)((mreg >> 16) & 0xFFFF));
4289205869Sjfv	}
4290205869Sjfv
4291205869Sjfv	/* copy MAC MTA to PHY MTA */
4292205869Sjfv	for (int i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
4293205869Sjfv		mreg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
4294205869Sjfv		e1000_write_phy_reg(hw, BM_MTA(i), (u16)(mreg & 0xFFFF));
4295205869Sjfv		e1000_write_phy_reg(hw, BM_MTA(i) + 1,
4296205869Sjfv		    (u16)((mreg >> 16) & 0xFFFF));
4297205869Sjfv	}
4298205869Sjfv
4299205869Sjfv	/* configure PHY Rx Control register */
4300205869Sjfv	e1000_read_phy_reg(&adapter->hw, BM_RCTL, &preg);
4301205869Sjfv	mreg = E1000_READ_REG(hw, E1000_RCTL);
4302205869Sjfv	if (mreg & E1000_RCTL_UPE)
4303205869Sjfv		preg |= BM_RCTL_UPE;
4304205869Sjfv	if (mreg & E1000_RCTL_MPE)
4305205869Sjfv		preg |= BM_RCTL_MPE;
4306205869Sjfv	preg &= ~(BM_RCTL_MO_MASK);
4307205869Sjfv	if (mreg & E1000_RCTL_MO_3)
4308205869Sjfv		preg |= (((mreg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
4309205869Sjfv				<< BM_RCTL_MO_SHIFT);
4310205869Sjfv	if (mreg & E1000_RCTL_BAM)
4311205869Sjfv		preg |= BM_RCTL_BAM;
4312205869Sjfv	if (mreg & E1000_RCTL_PMCF)
4313205869Sjfv		preg |= BM_RCTL_PMCF;
4314205869Sjfv	mreg = E1000_READ_REG(hw, E1000_CTRL);
4315205869Sjfv	if (mreg & E1000_CTRL_RFCE)
4316205869Sjfv		preg |= BM_RCTL_RFCE;
4317205869Sjfv	e1000_write_phy_reg(&adapter->hw, BM_RCTL, preg);
4318205869Sjfv
4319205869Sjfv	/* enable PHY wakeup in MAC register */
4320205869Sjfv	E1000_WRITE_REG(hw, E1000_WUC,
4321205869Sjfv	    E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
4322205869Sjfv	E1000_WRITE_REG(hw, E1000_WUFC, adapter->wol);
4323205869Sjfv
4324205869Sjfv	/* configure and enable PHY wakeup in PHY registers */
4325205869Sjfv	e1000_write_phy_reg(&adapter->hw, BM_WUFC, adapter->wol);
4326205869Sjfv	e1000_write_phy_reg(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
4327205869Sjfv
4328205869Sjfv	/* activate PHY wakeup */
4329205869Sjfv	ret = hw->phy.ops.acquire(hw);
4330205869Sjfv	if (ret) {
4331205869Sjfv		printf("Could not acquire PHY\n");
4332205869Sjfv		return ret;
4333205869Sjfv	}
4334205869Sjfv	e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
4335205869Sjfv	                         (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
4336205869Sjfv	ret = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &preg);
4337205869Sjfv	if (ret) {
4338205869Sjfv		printf("Could not read PHY page 769\n");
4339205869Sjfv		goto out;
4340205869Sjfv	}
4341205869Sjfv	preg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
4342205869Sjfv	ret = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, preg);
4343205869Sjfv	if (ret)
4344205869Sjfv		printf("Could not set PHY Host Wakeup bit\n");
4345205869Sjfvout:
4346205869Sjfv	hw->phy.ops.release(hw);
4347205869Sjfv
4348205869Sjfv	return ret;
4349205869Sjfv}
4350205869Sjfv
4351206001Smariusstatic void
4352206001Smariuslem_led_func(void *arg, int onoff)
4353206001Smarius{
4354206001Smarius	struct adapter	*adapter = arg;
4355205869Sjfv
4356206001Smarius	EM_CORE_LOCK(adapter);
4357206001Smarius	if (onoff) {
4358206001Smarius		e1000_setup_led(&adapter->hw);
4359206001Smarius		e1000_led_on(&adapter->hw);
4360206001Smarius	} else {
4361206001Smarius		e1000_led_off(&adapter->hw);
4362206001Smarius		e1000_cleanup_led(&adapter->hw);
4363206001Smarius	}
4364206001Smarius	EM_CORE_UNLOCK(adapter);
4365206001Smarius}
4366206001Smarius
4367205869Sjfv/*********************************************************************
4368205869Sjfv* 82544 Coexistence issue workaround.
4369205869Sjfv*    There are 2 issues.
4370205869Sjfv*       1. Transmit Hang issue.
4371205869Sjfv*    To detect this issue, following equation can be used...
4372205869Sjfv*	  SIZE[3:0] + ADDR[2:0] = SUM[3:0].
4373205869Sjfv*	  If SUM[3:0] is in between 1 to 4, we will have this issue.
4374205869Sjfv*
4375205869Sjfv*       2. DAC issue.
4376205869Sjfv*    To detect this issue, following equation can be used...
4377205869Sjfv*	  SIZE[3:0] + ADDR[2:0] = SUM[3:0].
4378205869Sjfv*	  If SUM[3:0] is in between 9 to c, we will have this issue.
4379205869Sjfv*
4380205869Sjfv*
4381205869Sjfv*    WORKAROUND:
4382205869Sjfv*	  Make sure we do not have ending address
4383205869Sjfv*	  as 1,2,3,4(Hang) or 9,a,b,c (DAC)
4384205869Sjfv*
4385205869Sjfv*************************************************************************/
4386205869Sjfvstatic u32
4387205869Sjfvlem_fill_descriptors (bus_addr_t address, u32 length,
4388205869Sjfv		PDESC_ARRAY desc_array)
4389205869Sjfv{
4390205869Sjfv	u32 safe_terminator;
4391205869Sjfv
4392205869Sjfv	/* Since issue is sensitive to length and address.*/
4393205869Sjfv	/* Let us first check the address...*/
4394205869Sjfv	if (length <= 4) {
4395205869Sjfv		desc_array->descriptor[0].address = address;
4396205869Sjfv		desc_array->descriptor[0].length = length;
4397205869Sjfv		desc_array->elements = 1;
4398205869Sjfv		return (desc_array->elements);
4399205869Sjfv	}
4400205869Sjfv	safe_terminator = (u32)((((u32)address & 0x7) +
4401205869Sjfv	    (length & 0xF)) & 0xF);
4402205869Sjfv	/* if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then return */
4403205869Sjfv	if (safe_terminator == 0   ||
4404205869Sjfv	(safe_terminator > 4   &&
4405205869Sjfv	safe_terminator < 9)   ||
4406205869Sjfv	(safe_terminator > 0xC &&
4407205869Sjfv	safe_terminator <= 0xF)) {
4408205869Sjfv		desc_array->descriptor[0].address = address;
4409205869Sjfv		desc_array->descriptor[0].length = length;
4410205869Sjfv		desc_array->elements = 1;
4411205869Sjfv		return (desc_array->elements);
4412205869Sjfv	}
4413205869Sjfv
4414205869Sjfv	desc_array->descriptor[0].address = address;
4415205869Sjfv	desc_array->descriptor[0].length = length - 4;
4416205869Sjfv	desc_array->descriptor[1].address = address + (length - 4);
4417205869Sjfv	desc_array->descriptor[1].length = 4;
4418205869Sjfv	desc_array->elements = 2;
4419205869Sjfv	return (desc_array->elements);
4420205869Sjfv}
4421205869Sjfv
4422205869Sjfv/**********************************************************************
4423205869Sjfv *
4424205869Sjfv *  Update the board statistics counters.
4425205869Sjfv *
4426205869Sjfv **********************************************************************/
4427205869Sjfvstatic void
4428205869Sjfvlem_update_stats_counters(struct adapter *adapter)
4429205869Sjfv{
4430205869Sjfv	struct ifnet   *ifp;
4431205869Sjfv
4432205869Sjfv	if(adapter->hw.phy.media_type == e1000_media_type_copper ||
4433205869Sjfv	   (E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) {
4434205869Sjfv		adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
4435205869Sjfv		adapter->stats.sec += E1000_READ_REG(&adapter->hw, E1000_SEC);
4436205869Sjfv	}
4437205869Sjfv	adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, E1000_CRCERRS);
4438205869Sjfv	adapter->stats.mpc += E1000_READ_REG(&adapter->hw, E1000_MPC);
4439205869Sjfv	adapter->stats.scc += E1000_READ_REG(&adapter->hw, E1000_SCC);
4440205869Sjfv	adapter->stats.ecol += E1000_READ_REG(&adapter->hw, E1000_ECOL);
4441205869Sjfv
4442205869Sjfv	adapter->stats.mcc += E1000_READ_REG(&adapter->hw, E1000_MCC);
4443205869Sjfv	adapter->stats.latecol += E1000_READ_REG(&adapter->hw, E1000_LATECOL);
4444205869Sjfv	adapter->stats.colc += E1000_READ_REG(&adapter->hw, E1000_COLC);
4445205869Sjfv	adapter->stats.dc += E1000_READ_REG(&adapter->hw, E1000_DC);
4446205869Sjfv	adapter->stats.rlec += E1000_READ_REG(&adapter->hw, E1000_RLEC);
4447205869Sjfv	adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, E1000_XONRXC);
4448205869Sjfv	adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, E1000_XONTXC);
4449205869Sjfv	adapter->stats.xoffrxc += E1000_READ_REG(&adapter->hw, E1000_XOFFRXC);
4450205869Sjfv	adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, E1000_XOFFTXC);
4451205869Sjfv	adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, E1000_FCRUC);
4452205869Sjfv	adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, E1000_PRC64);
4453205869Sjfv	adapter->stats.prc127 += E1000_READ_REG(&adapter->hw, E1000_PRC127);
4454205869Sjfv	adapter->stats.prc255 += E1000_READ_REG(&adapter->hw, E1000_PRC255);
4455205869Sjfv	adapter->stats.prc511 += E1000_READ_REG(&adapter->hw, E1000_PRC511);
4456205869Sjfv	adapter->stats.prc1023 += E1000_READ_REG(&adapter->hw, E1000_PRC1023);
4457205869Sjfv	adapter->stats.prc1522 += E1000_READ_REG(&adapter->hw, E1000_PRC1522);
4458205869Sjfv	adapter->stats.gprc += E1000_READ_REG(&adapter->hw, E1000_GPRC);
4459205869Sjfv	adapter->stats.bprc += E1000_READ_REG(&adapter->hw, E1000_BPRC);
4460205869Sjfv	adapter->stats.mprc += E1000_READ_REG(&adapter->hw, E1000_MPRC);
4461205869Sjfv	adapter->stats.gptc += E1000_READ_REG(&adapter->hw, E1000_GPTC);
4462205869Sjfv
4463205869Sjfv	/* For the 64-bit byte counters the low dword must be read first. */
4464205869Sjfv	/* Both registers clear on the read of the high dword */
4465205869Sjfv
4466212902Sjhb	adapter->stats.gorc += E1000_READ_REG(&adapter->hw, E1000_GORCL) +
4467212902Sjhb	    ((u64)E1000_READ_REG(&adapter->hw, E1000_GORCH) << 32);
4468212902Sjhb	adapter->stats.gotc += E1000_READ_REG(&adapter->hw, E1000_GOTCL) +
4469212902Sjhb	    ((u64)E1000_READ_REG(&adapter->hw, E1000_GOTCH) << 32);
4470205869Sjfv
4471205869Sjfv	adapter->stats.rnbc += E1000_READ_REG(&adapter->hw, E1000_RNBC);
4472205869Sjfv	adapter->stats.ruc += E1000_READ_REG(&adapter->hw, E1000_RUC);
4473205869Sjfv	adapter->stats.rfc += E1000_READ_REG(&adapter->hw, E1000_RFC);
4474205869Sjfv	adapter->stats.roc += E1000_READ_REG(&adapter->hw, E1000_ROC);
4475205869Sjfv	adapter->stats.rjc += E1000_READ_REG(&adapter->hw, E1000_RJC);
4476205869Sjfv
4477205869Sjfv	adapter->stats.tor += E1000_READ_REG(&adapter->hw, E1000_TORH);
4478205869Sjfv	adapter->stats.tot += E1000_READ_REG(&adapter->hw, E1000_TOTH);
4479205869Sjfv
4480205869Sjfv	adapter->stats.tpr += E1000_READ_REG(&adapter->hw, E1000_TPR);
4481205869Sjfv	adapter->stats.tpt += E1000_READ_REG(&adapter->hw, E1000_TPT);
4482205869Sjfv	adapter->stats.ptc64 += E1000_READ_REG(&adapter->hw, E1000_PTC64);
4483205869Sjfv	adapter->stats.ptc127 += E1000_READ_REG(&adapter->hw, E1000_PTC127);
4484205869Sjfv	adapter->stats.ptc255 += E1000_READ_REG(&adapter->hw, E1000_PTC255);
4485205869Sjfv	adapter->stats.ptc511 += E1000_READ_REG(&adapter->hw, E1000_PTC511);
4486205869Sjfv	adapter->stats.ptc1023 += E1000_READ_REG(&adapter->hw, E1000_PTC1023);
4487205869Sjfv	adapter->stats.ptc1522 += E1000_READ_REG(&adapter->hw, E1000_PTC1522);
4488205869Sjfv	adapter->stats.mptc += E1000_READ_REG(&adapter->hw, E1000_MPTC);
4489205869Sjfv	adapter->stats.bptc += E1000_READ_REG(&adapter->hw, E1000_BPTC);
4490205869Sjfv
4491205869Sjfv	if (adapter->hw.mac.type >= e1000_82543) {
4492205869Sjfv		adapter->stats.algnerrc +=
4493205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_ALGNERRC);
4494205869Sjfv		adapter->stats.rxerrc +=
4495205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_RXERRC);
4496205869Sjfv		adapter->stats.tncrs +=
4497205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_TNCRS);
4498205869Sjfv		adapter->stats.cexterr +=
4499205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_CEXTERR);
4500205869Sjfv		adapter->stats.tsctc +=
4501205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_TSCTC);
4502205869Sjfv		adapter->stats.tsctfc +=
4503205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_TSCTFC);
4504205869Sjfv	}
4505205869Sjfv	ifp = adapter->ifp;
4506205869Sjfv
4507205869Sjfv	ifp->if_collisions = adapter->stats.colc;
4508205869Sjfv
4509205869Sjfv	/* Rx Errors */
4510205869Sjfv	ifp->if_ierrors = adapter->dropped_pkts + adapter->stats.rxerrc +
4511205869Sjfv	    adapter->stats.crcerrs + adapter->stats.algnerrc +
4512205869Sjfv	    adapter->stats.ruc + adapter->stats.roc +
4513205869Sjfv	    adapter->stats.mpc + adapter->stats.cexterr;
4514205869Sjfv
4515205869Sjfv	/* Tx Errors */
4516205869Sjfv	ifp->if_oerrors = adapter->stats.ecol +
4517205869Sjfv	    adapter->stats.latecol + adapter->watchdog_events;
4518205869Sjfv}
4519205869Sjfv
4520212902Sjhb/* Export a single 32-bit register via a read-only sysctl. */
4521212902Sjhbstatic int
4522212902Sjhblem_sysctl_reg_handler(SYSCTL_HANDLER_ARGS)
4523205869Sjfv{
4524212902Sjhb	struct adapter *adapter;
4525212902Sjhb	u_int val;
4526205869Sjfv
4527212902Sjhb	adapter = oidp->oid_arg1;
4528212902Sjhb	val = E1000_READ_REG(&adapter->hw, oidp->oid_arg2);
4529212902Sjhb	return (sysctl_handle_int(oidp, &val, 0, req));
4530205869Sjfv}
4531205869Sjfv
4532212902Sjhb/*
4533212902Sjhb * Add sysctl variables, one per statistic, to the system.
4534212902Sjhb */
4535205869Sjfvstatic void
4536212902Sjhblem_add_hw_stats(struct adapter *adapter)
4537205869Sjfv{
4538205869Sjfv	device_t dev = adapter->dev;
4539205869Sjfv
4540212902Sjhb	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
4541212902Sjhb	struct sysctl_oid *tree = device_get_sysctl_tree(dev);
4542212902Sjhb	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
4543212902Sjhb	struct e1000_hw_stats *stats = &adapter->stats;
4544212902Sjhb
4545212902Sjhb	struct sysctl_oid *stat_node;
4546212902Sjhb	struct sysctl_oid_list *stat_list;
4547212902Sjhb
4548212902Sjhb	/* Driver Statistics */
4549212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "cluster_alloc_fail",
4550212902Sjhb			 CTLFLAG_RD, &adapter->mbuf_cluster_failed,
4551212902Sjhb			 "Std mbuf cluster failed");
4552294958Smarius	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_defrag_fail",
4553294958Smarius			 CTLFLAG_RD, &adapter->mbuf_defrag_failed,
4554294958Smarius			 "Defragmenting mbuf chain failed");
4555212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped",
4556212902Sjhb			CTLFLAG_RD, &adapter->dropped_pkts,
4557212902Sjhb			"Driver dropped packets");
4558212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_dma_fail",
4559212902Sjhb			CTLFLAG_RD, &adapter->no_tx_dma_setup,
4560212902Sjhb			"Driver tx dma failure in xmit");
4561212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_desc_fail1",
4562212902Sjhb			CTLFLAG_RD, &adapter->no_tx_desc_avail1,
4563212902Sjhb			"Not enough tx descriptors failure in xmit");
4564212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_desc_fail2",
4565212902Sjhb			CTLFLAG_RD, &adapter->no_tx_desc_avail2,
4566212902Sjhb			"Not enough tx descriptors failure in xmit");
4567212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "rx_overruns",
4568212902Sjhb			CTLFLAG_RD, &adapter->rx_overruns,
4569212902Sjhb			"RX overruns");
4570212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "watchdog_timeouts",
4571212902Sjhb			CTLFLAG_RD, &adapter->watchdog_events,
4572212902Sjhb			"Watchdog timeouts");
4573212902Sjhb
4574212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "device_control",
4575217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_CTRL,
4576212902Sjhb			lem_sysctl_reg_handler, "IU",
4577212902Sjhb			"Device Control Register");
4578212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_control",
4579217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RCTL,
4580212902Sjhb			lem_sysctl_reg_handler, "IU",
4581212902Sjhb			"Receiver Control Register");
4582212902Sjhb	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_high_water",
4583212902Sjhb			CTLFLAG_RD, &adapter->hw.fc.high_water, 0,
4584212902Sjhb			"Flow Control High Watermark");
4585212902Sjhb	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_low_water",
4586212902Sjhb			CTLFLAG_RD, &adapter->hw.fc.low_water, 0,
4587212902Sjhb			"Flow Control Low Watermark");
4588217318Smdf	SYSCTL_ADD_UQUAD(ctx, child, OID_AUTO, "fifo_workaround",
4589212902Sjhb			CTLFLAG_RD, &adapter->tx_fifo_wrk_cnt,
4590212902Sjhb			"TX FIFO workaround events");
4591217318Smdf	SYSCTL_ADD_UQUAD(ctx, child, OID_AUTO, "fifo_reset",
4592212902Sjhb			CTLFLAG_RD, &adapter->tx_fifo_reset_cnt,
4593212902Sjhb			"TX FIFO resets");
4594212902Sjhb
4595212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "txd_head",
4596217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_TDH(0),
4597212902Sjhb			lem_sysctl_reg_handler, "IU",
4598212902Sjhb 			"Transmit Descriptor Head");
4599212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "txd_tail",
4600217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_TDT(0),
4601212902Sjhb			lem_sysctl_reg_handler, "IU",
4602212902Sjhb 			"Transmit Descriptor Tail");
4603212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rxd_head",
4604217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RDH(0),
4605212902Sjhb			lem_sysctl_reg_handler, "IU",
4606212902Sjhb			"Receive Descriptor Head");
4607212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rxd_tail",
4608217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RDT(0),
4609212902Sjhb			lem_sysctl_reg_handler, "IU",
4610212902Sjhb			"Receive Descriptor Tail");
4611212902Sjhb
4612212902Sjhb
4613212902Sjhb	/* MAC stats get their own sub node */
4614212902Sjhb
4615212902Sjhb	stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac_stats",
4616212902Sjhb				    CTLFLAG_RD, NULL, "Statistics");
4617212902Sjhb	stat_list = SYSCTL_CHILDREN(stat_node);
4618212902Sjhb
4619217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "excess_coll",
4620212902Sjhb			CTLFLAG_RD, &stats->ecol,
4621212902Sjhb			"Excessive collisions");
4622217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "single_coll",
4623212902Sjhb			CTLFLAG_RD, &stats->scc,
4624212902Sjhb			"Single collisions");
4625217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "multiple_coll",
4626212902Sjhb			CTLFLAG_RD, &stats->mcc,
4627212902Sjhb			"Multiple collisions");
4628217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "late_coll",
4629212902Sjhb			CTLFLAG_RD, &stats->latecol,
4630212902Sjhb			"Late collisions");
4631217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "collision_count",
4632212902Sjhb			CTLFLAG_RD, &stats->colc,
4633212902Sjhb			"Collision Count");
4634217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "symbol_errors",
4635212902Sjhb			CTLFLAG_RD, &adapter->stats.symerrs,
4636212902Sjhb			"Symbol Errors");
4637217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "sequence_errors",
4638212902Sjhb			CTLFLAG_RD, &adapter->stats.sec,
4639212902Sjhb			"Sequence Errors");
4640217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "defer_count",
4641212902Sjhb			CTLFLAG_RD, &adapter->stats.dc,
4642212902Sjhb			"Defer Count");
4643217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "missed_packets",
4644212902Sjhb			CTLFLAG_RD, &adapter->stats.mpc,
4645212902Sjhb			"Missed Packets");
4646217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_no_buff",
4647212902Sjhb			CTLFLAG_RD, &adapter->stats.rnbc,
4648212902Sjhb			"Receive No Buffers");
4649217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_undersize",
4650212902Sjhb			CTLFLAG_RD, &adapter->stats.ruc,
4651212902Sjhb			"Receive Undersize");
4652217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_fragmented",
4653212902Sjhb			CTLFLAG_RD, &adapter->stats.rfc,
4654212902Sjhb			"Fragmented Packets Received ");
4655217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_oversize",
4656212902Sjhb			CTLFLAG_RD, &adapter->stats.roc,
4657212902Sjhb			"Oversized Packets Received");
4658217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_jabber",
4659212902Sjhb			CTLFLAG_RD, &adapter->stats.rjc,
4660212902Sjhb			"Recevied Jabber");
4661217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_errs",
4662212902Sjhb			CTLFLAG_RD, &adapter->stats.rxerrc,
4663212902Sjhb			"Receive Errors");
4664217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "crc_errs",
4665212902Sjhb			CTLFLAG_RD, &adapter->stats.crcerrs,
4666212902Sjhb			"CRC errors");
4667217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "alignment_errs",
4668212902Sjhb			CTLFLAG_RD, &adapter->stats.algnerrc,
4669212902Sjhb			"Alignment Errors");
4670217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "coll_ext_errs",
4671212902Sjhb			CTLFLAG_RD, &adapter->stats.cexterr,
4672212902Sjhb			"Collision/Carrier extension errors");
4673217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xon_recvd",
4674212902Sjhb			CTLFLAG_RD, &adapter->stats.xonrxc,
4675212902Sjhb			"XON Received");
4676217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xon_txd",
4677212902Sjhb			CTLFLAG_RD, &adapter->stats.xontxc,
4678212902Sjhb			"XON Transmitted");
4679217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xoff_recvd",
4680212902Sjhb			CTLFLAG_RD, &adapter->stats.xoffrxc,
4681212902Sjhb			"XOFF Received");
4682217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xoff_txd",
4683212902Sjhb			CTLFLAG_RD, &adapter->stats.xofftxc,
4684212902Sjhb			"XOFF Transmitted");
4685212902Sjhb
4686212902Sjhb	/* Packet Reception Stats */
4687217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_pkts_recvd",
4688212902Sjhb			CTLFLAG_RD, &adapter->stats.tpr,
4689212902Sjhb			"Total Packets Received ");
4690217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_recvd",
4691212902Sjhb			CTLFLAG_RD, &adapter->stats.gprc,
4692212902Sjhb			"Good Packets Received");
4693217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_recvd",
4694212902Sjhb			CTLFLAG_RD, &adapter->stats.bprc,
4695212902Sjhb			"Broadcast Packets Received");
4696217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_recvd",
4697212902Sjhb			CTLFLAG_RD, &adapter->stats.mprc,
4698212902Sjhb			"Multicast Packets Received");
4699217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_64",
4700212902Sjhb			CTLFLAG_RD, &adapter->stats.prc64,
4701212902Sjhb			"64 byte frames received ");
4702217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_65_127",
4703212902Sjhb			CTLFLAG_RD, &adapter->stats.prc127,
4704212902Sjhb			"65-127 byte frames received");
4705217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_128_255",
4706212902Sjhb			CTLFLAG_RD, &adapter->stats.prc255,
4707212902Sjhb			"128-255 byte frames received");
4708217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_256_511",
4709212902Sjhb			CTLFLAG_RD, &adapter->stats.prc511,
4710212902Sjhb			"256-511 byte frames received");
4711217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_512_1023",
4712212902Sjhb			CTLFLAG_RD, &adapter->stats.prc1023,
4713212902Sjhb			"512-1023 byte frames received");
4714217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_1024_1522",
4715212902Sjhb			CTLFLAG_RD, &adapter->stats.prc1522,
4716212902Sjhb			"1023-1522 byte frames received");
4717217318Smdf 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_recvd",
4718212902Sjhb 			CTLFLAG_RD, &adapter->stats.gorc,
4719212902Sjhb 			"Good Octets Received");
4720212902Sjhb
4721212902Sjhb	/* Packet Transmission Stats */
4722217318Smdf 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd",
4723212902Sjhb 			CTLFLAG_RD, &adapter->stats.gotc,
4724212902Sjhb 			"Good Octets Transmitted");
4725217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_pkts_txd",
4726212902Sjhb			CTLFLAG_RD, &adapter->stats.tpt,
4727212902Sjhb			"Total Packets Transmitted");
4728217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd",
4729212902Sjhb			CTLFLAG_RD, &adapter->stats.gptc,
4730212902Sjhb			"Good Packets Transmitted");
4731217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_txd",
4732212902Sjhb			CTLFLAG_RD, &adapter->stats.bptc,
4733212902Sjhb			"Broadcast Packets Transmitted");
4734217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_txd",
4735212902Sjhb			CTLFLAG_RD, &adapter->stats.mptc,
4736212902Sjhb			"Multicast Packets Transmitted");
4737217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_64",
4738212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc64,
4739212902Sjhb			"64 byte frames transmitted ");
4740217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_65_127",
4741212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc127,
4742212902Sjhb			"65-127 byte frames transmitted");
4743217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_128_255",
4744212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc255,
4745212902Sjhb			"128-255 byte frames transmitted");
4746217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_256_511",
4747212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc511,
4748212902Sjhb			"256-511 byte frames transmitted");
4749217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_512_1023",
4750212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc1023,
4751212902Sjhb			"512-1023 byte frames transmitted");
4752217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_1024_1522",
4753212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc1522,
4754212902Sjhb			"1024-1522 byte frames transmitted");
4755217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tso_txd",
4756212902Sjhb			CTLFLAG_RD, &adapter->stats.tsctc,
4757212902Sjhb			"TSO Contexts Transmitted");
4758217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tso_ctx_fail",
4759212902Sjhb			CTLFLAG_RD, &adapter->stats.tsctfc,
4760212902Sjhb			"TSO Contexts Failed");
4761205869Sjfv}
4762205869Sjfv
4763205869Sjfv/**********************************************************************
4764205869Sjfv *
4765205869Sjfv *  This routine provides a way to dump out the adapter eeprom,
4766205869Sjfv *  often a useful debug/service tool. This only dumps the first
4767205869Sjfv *  32 words, stuff that matters is in that extent.
4768205869Sjfv *
4769205869Sjfv **********************************************************************/
4770205869Sjfv
4771205869Sjfvstatic int
4772212902Sjhblem_sysctl_nvm_info(SYSCTL_HANDLER_ARGS)
4773205869Sjfv{
4774205869Sjfv	struct adapter *adapter;
4775205869Sjfv	int error;
4776205869Sjfv	int result;
4777205869Sjfv
4778205869Sjfv	result = -1;
4779205869Sjfv	error = sysctl_handle_int(oidp, &result, 0, req);
4780205869Sjfv
4781205869Sjfv	if (error || !req->newptr)
4782205869Sjfv		return (error);
4783205869Sjfv
4784205869Sjfv	/*
4785205869Sjfv	 * This value will cause a hex dump of the
4786205869Sjfv	 * first 32 16-bit words of the EEPROM to
4787205869Sjfv	 * the screen.
4788205869Sjfv	 */
4789212902Sjhb	if (result == 1) {
4790205869Sjfv		adapter = (struct adapter *)arg1;
4791205869Sjfv		lem_print_nvm_info(adapter);
4792205869Sjfv        }
4793205869Sjfv
4794205869Sjfv	return (error);
4795205869Sjfv}
4796205869Sjfv
4797212902Sjhbstatic void
4798212902Sjhblem_print_nvm_info(struct adapter *adapter)
4799205869Sjfv{
4800212902Sjhb	u16	eeprom_data;
4801212902Sjhb	int	i, j, row = 0;
4802205869Sjfv
4803212902Sjhb	/* Its a bit crude, but it gets the job done */
4804212902Sjhb	printf("\nInterface EEPROM Dump:\n");
4805212902Sjhb	printf("Offset\n0x0000  ");
4806212902Sjhb	for (i = 0, j = 0; i < 32; i++, j++) {
4807212902Sjhb		if (j == 8) { /* Make the offset block */
4808212902Sjhb			j = 0; ++row;
4809212902Sjhb			printf("\n0x00%x0  ",row);
4810212902Sjhb		}
4811212902Sjhb		e1000_read_nvm(&adapter->hw, i, 1, &eeprom_data);
4812212902Sjhb		printf("%04x ", eeprom_data);
4813205869Sjfv	}
4814212902Sjhb	printf("\n");
4815205869Sjfv}
4816205869Sjfv
4817205869Sjfvstatic int
4818205869Sjfvlem_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
4819205869Sjfv{
4820205869Sjfv	struct em_int_delay_info *info;
4821205869Sjfv	struct adapter *adapter;
4822205869Sjfv	u32 regval;
4823205869Sjfv	int error;
4824205869Sjfv	int usecs;
4825205869Sjfv	int ticks;
4826205869Sjfv
4827205869Sjfv	info = (struct em_int_delay_info *)arg1;
4828205869Sjfv	usecs = info->value;
4829205869Sjfv	error = sysctl_handle_int(oidp, &usecs, 0, req);
4830205869Sjfv	if (error != 0 || req->newptr == NULL)
4831205869Sjfv		return (error);
4832205869Sjfv	if (usecs < 0 || usecs > EM_TICKS_TO_USECS(65535))
4833205869Sjfv		return (EINVAL);
4834205869Sjfv	info->value = usecs;
4835205869Sjfv	ticks = EM_USECS_TO_TICKS(usecs);
4836250414Sluigi	if (info->offset == E1000_ITR)	/* units are 256ns here */
4837250414Sluigi		ticks *= 4;
4838205869Sjfv
4839205869Sjfv	adapter = info->adapter;
4840205869Sjfv
4841205869Sjfv	EM_CORE_LOCK(adapter);
4842205869Sjfv	regval = E1000_READ_OFFSET(&adapter->hw, info->offset);
4843205869Sjfv	regval = (regval & ~0xffff) | (ticks & 0xffff);
4844205869Sjfv	/* Handle a few special cases. */
4845205869Sjfv	switch (info->offset) {
4846205869Sjfv	case E1000_RDTR:
4847205869Sjfv		break;
4848205869Sjfv	case E1000_TIDV:
4849205869Sjfv		if (ticks == 0) {
4850205869Sjfv			adapter->txd_cmd &= ~E1000_TXD_CMD_IDE;
4851205869Sjfv			/* Don't write 0 into the TIDV register. */
4852205869Sjfv			regval++;
4853205869Sjfv		} else
4854205869Sjfv			adapter->txd_cmd |= E1000_TXD_CMD_IDE;
4855205869Sjfv		break;
4856205869Sjfv	}
4857205869Sjfv	E1000_WRITE_OFFSET(&adapter->hw, info->offset, regval);
4858205869Sjfv	EM_CORE_UNLOCK(adapter);
4859205869Sjfv	return (0);
4860205869Sjfv}
4861205869Sjfv
4862205869Sjfvstatic void
4863205869Sjfvlem_add_int_delay_sysctl(struct adapter *adapter, const char *name,
4864205869Sjfv	const char *description, struct em_int_delay_info *info,
4865205869Sjfv	int offset, int value)
4866205869Sjfv{
4867205869Sjfv	info->adapter = adapter;
4868205869Sjfv	info->offset = offset;
4869205869Sjfv	info->value = value;
4870205869Sjfv	SYSCTL_ADD_PROC(device_get_sysctl_ctx(adapter->dev),
4871205869Sjfv	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
4872205869Sjfv	    OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW,
4873205869Sjfv	    info, 0, lem_sysctl_int_delay, "I", description);
4874205869Sjfv}
4875205869Sjfv
4876214646Sjfvstatic void
4877214646Sjfvlem_set_flow_cntrl(struct adapter *adapter, const char *name,
4878214646Sjfv        const char *description, int *limit, int value)
4879214646Sjfv{
4880214646Sjfv	*limit = value;
4881214646Sjfv	SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
4882214646Sjfv	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
4883273736Shselasky	    OID_AUTO, name, CTLFLAG_RW, limit, value, description);
4884214646Sjfv}
4885214646Sjfv
4886205869Sjfvstatic void
4887205869Sjfvlem_add_rx_process_limit(struct adapter *adapter, const char *name,
4888205869Sjfv	const char *description, int *limit, int value)
4889205869Sjfv{
4890205869Sjfv	*limit = value;
4891205869Sjfv	SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
4892205869Sjfv	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
4893273736Shselasky	    OID_AUTO, name, CTLFLAG_RW, limit, value, description);
4894205869Sjfv}
4895