1205869Sjfv/******************************************************************************
2205869Sjfv
3238953Sjfv  Copyright (c) 2001-2012, 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$*/
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 *********************************************************************/
98249074Sjfvchar lem_driver_version[] = "1.0.6";
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
954270252Sluigi	if (if_getdrvflags(ifp) & 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
1673243857Sglebius		m = m_defrag(*m_headp, M_NOWAIT);
1674205869Sjfv		if (m == NULL) {
1675205869Sjfv			adapter->mbuf_alloc_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_map = NULL;
2703205869Sjfv	dma->dma_tag = NULL;
2704205869Sjfv
2705205869Sjfv	return (error);
2706205869Sjfv}
2707205869Sjfv
2708205869Sjfvstatic void
2709205869Sjfvlem_dma_free(struct adapter *adapter, struct em_dma_alloc *dma)
2710205869Sjfv{
2711205869Sjfv	if (dma->dma_tag == NULL)
2712205869Sjfv		return;
2713205869Sjfv	if (dma->dma_map != NULL) {
2714205869Sjfv		bus_dmamap_sync(dma->dma_tag, dma->dma_map,
2715205869Sjfv		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2716205869Sjfv		bus_dmamap_unload(dma->dma_tag, dma->dma_map);
2717205869Sjfv		bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
2718205869Sjfv		dma->dma_map = NULL;
2719205869Sjfv	}
2720205869Sjfv	bus_dma_tag_destroy(dma->dma_tag);
2721205869Sjfv	dma->dma_tag = NULL;
2722205869Sjfv}
2723205869Sjfv
2724205869Sjfv
2725205869Sjfv/*********************************************************************
2726205869Sjfv *
2727205869Sjfv *  Allocate memory for tx_buffer structures. The tx_buffer stores all
2728205869Sjfv *  the information needed to transmit a packet on the wire.
2729205869Sjfv *
2730205869Sjfv **********************************************************************/
2731205869Sjfvstatic int
2732205869Sjfvlem_allocate_transmit_structures(struct adapter *adapter)
2733205869Sjfv{
2734205869Sjfv	device_t dev = adapter->dev;
2735205869Sjfv	struct em_buffer *tx_buffer;
2736205869Sjfv	int error;
2737205869Sjfv
2738205869Sjfv	/*
2739205869Sjfv	 * Create DMA tags for tx descriptors
2740205869Sjfv	 */
2741205869Sjfv	if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
2742205869Sjfv				1, 0,			/* alignment, bounds */
2743205869Sjfv				BUS_SPACE_MAXADDR,	/* lowaddr */
2744205869Sjfv				BUS_SPACE_MAXADDR,	/* highaddr */
2745205869Sjfv				NULL, NULL,		/* filter, filterarg */
2746214646Sjfv				MCLBYTES * EM_MAX_SCATTER,	/* maxsize */
2747205869Sjfv				EM_MAX_SCATTER,		/* nsegments */
2748214646Sjfv				MCLBYTES,		/* maxsegsize */
2749205869Sjfv				0,			/* flags */
2750214646Sjfv				NULL,			/* lockfunc */
2751214646Sjfv				NULL,			/* lockarg */
2752205869Sjfv				&adapter->txtag)) != 0) {
2753205869Sjfv		device_printf(dev, "Unable to allocate TX DMA tag\n");
2754205869Sjfv		goto fail;
2755205869Sjfv	}
2756205869Sjfv
2757205869Sjfv	adapter->tx_buffer_area = malloc(sizeof(struct em_buffer) *
2758205869Sjfv	    adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO);
2759205869Sjfv	if (adapter->tx_buffer_area == NULL) {
2760205869Sjfv		device_printf(dev, "Unable to allocate tx_buffer memory\n");
2761205869Sjfv		error = ENOMEM;
2762205869Sjfv		goto fail;
2763205869Sjfv	}
2764205869Sjfv
2765205869Sjfv	/* Create the descriptor buffer dma maps */
2766205869Sjfv	for (int i = 0; i < adapter->num_tx_desc; i++) {
2767205869Sjfv		tx_buffer = &adapter->tx_buffer_area[i];
2768205869Sjfv		error = bus_dmamap_create(adapter->txtag, 0, &tx_buffer->map);
2769205869Sjfv		if (error != 0) {
2770205869Sjfv			device_printf(dev, "Unable to create TX DMA map\n");
2771205869Sjfv			goto fail;
2772205869Sjfv		}
2773205869Sjfv		tx_buffer->next_eop = -1;
2774205869Sjfv	}
2775205869Sjfv
2776205869Sjfv	return (0);
2777205869Sjfvfail:
2778205869Sjfv	lem_free_transmit_structures(adapter);
2779205869Sjfv	return (error);
2780205869Sjfv}
2781205869Sjfv
2782205869Sjfv/*********************************************************************
2783205869Sjfv *
2784205869Sjfv *  (Re)Initialize transmit structures.
2785205869Sjfv *
2786205869Sjfv **********************************************************************/
2787205869Sjfvstatic void
2788205869Sjfvlem_setup_transmit_structures(struct adapter *adapter)
2789205869Sjfv{
2790205869Sjfv	struct em_buffer *tx_buffer;
2791228281Sluigi#ifdef DEV_NETMAP
2792228281Sluigi	/* we are already locked */
2793228281Sluigi	struct netmap_adapter *na = NA(adapter->ifp);
2794228281Sluigi	struct netmap_slot *slot = netmap_reset(na, NR_TX, 0, 0);
2795228281Sluigi#endif /* DEV_NETMAP */
2796205869Sjfv
2797205869Sjfv	/* Clear the old ring contents */
2798205869Sjfv	bzero(adapter->tx_desc_base,
2799205869Sjfv	    (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc);
2800205869Sjfv
2801205869Sjfv	/* Free any existing TX buffers */
2802205869Sjfv	for (int i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
2803205869Sjfv		tx_buffer = &adapter->tx_buffer_area[i];
2804205869Sjfv		bus_dmamap_sync(adapter->txtag, tx_buffer->map,
2805205869Sjfv		    BUS_DMASYNC_POSTWRITE);
2806205869Sjfv		bus_dmamap_unload(adapter->txtag, tx_buffer->map);
2807205869Sjfv		m_freem(tx_buffer->m_head);
2808205869Sjfv		tx_buffer->m_head = NULL;
2809228281Sluigi#ifdef DEV_NETMAP
2810228281Sluigi		if (slot) {
2811231796Sluigi			/* the i-th NIC entry goes to slot si */
2812232238Sluigi			int si = netmap_idx_n2k(&na->tx_rings[0], i);
2813229939Sluigi			uint64_t paddr;
2814228281Sluigi			void *addr;
2815228281Sluigi
2816270252Sluigi			addr = PNMB(na, slot + si, &paddr);
2817270235Sluigi			adapter->tx_desc_base[i].buffer_addr = htole64(paddr);
2818228281Sluigi			/* reload the map for netmap mode */
2819270252Sluigi			netmap_load_map(na, adapter->txtag, tx_buffer->map, addr);
2820228281Sluigi		}
2821228281Sluigi#endif /* DEV_NETMAP */
2822205869Sjfv		tx_buffer->next_eop = -1;
2823205869Sjfv	}
2824205869Sjfv
2825205869Sjfv	/* Reset state */
2826225640Srstone	adapter->last_hw_offload = 0;
2827205869Sjfv	adapter->next_avail_tx_desc = 0;
2828205869Sjfv	adapter->next_tx_to_clean = 0;
2829205869Sjfv	adapter->num_tx_desc_avail = adapter->num_tx_desc;
2830205869Sjfv
2831205869Sjfv	bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
2832205869Sjfv	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2833205869Sjfv
2834205869Sjfv	return;
2835205869Sjfv}
2836205869Sjfv
2837205869Sjfv/*********************************************************************
2838205869Sjfv *
2839205869Sjfv *  Enable transmit unit.
2840205869Sjfv *
2841205869Sjfv **********************************************************************/
2842205869Sjfvstatic void
2843205869Sjfvlem_initialize_transmit_unit(struct adapter *adapter)
2844205869Sjfv{
2845205869Sjfv	u32	tctl, tipg = 0;
2846205869Sjfv	u64	bus_addr;
2847205869Sjfv
2848205869Sjfv	 INIT_DEBUGOUT("lem_initialize_transmit_unit: begin");
2849205869Sjfv	/* Setup the Base and Length of the Tx Descriptor Ring */
2850205869Sjfv	bus_addr = adapter->txdma.dma_paddr;
2851205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TDLEN(0),
2852205869Sjfv	    adapter->num_tx_desc * sizeof(struct e1000_tx_desc));
2853205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TDBAH(0),
2854205869Sjfv	    (u32)(bus_addr >> 32));
2855205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TDBAL(0),
2856205869Sjfv	    (u32)bus_addr);
2857205869Sjfv	/* Setup the HW Tx Head and Tail descriptor pointers */
2858205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), 0);
2859205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TDH(0), 0);
2860205869Sjfv
2861205869Sjfv	HW_DEBUGOUT2("Base = %x, Length = %x\n",
2862205869Sjfv	    E1000_READ_REG(&adapter->hw, E1000_TDBAL(0)),
2863205869Sjfv	    E1000_READ_REG(&adapter->hw, E1000_TDLEN(0)));
2864205869Sjfv
2865205869Sjfv	/* Set the default values for the Tx Inter Packet Gap timer */
2866205869Sjfv	switch (adapter->hw.mac.type) {
2867205869Sjfv	case e1000_82542:
2868205869Sjfv		tipg = DEFAULT_82542_TIPG_IPGT;
2869205869Sjfv		tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
2870205869Sjfv		tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
2871205869Sjfv		break;
2872205869Sjfv	default:
2873205869Sjfv		if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
2874205869Sjfv		    (adapter->hw.phy.media_type ==
2875205869Sjfv		    e1000_media_type_internal_serdes))
2876205869Sjfv			tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
2877205869Sjfv		else
2878205869Sjfv			tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
2879205869Sjfv		tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
2880205869Sjfv		tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
2881205869Sjfv	}
2882205869Sjfv
2883205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TIPG, tipg);
2884205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TIDV, adapter->tx_int_delay.value);
2885205869Sjfv	if(adapter->hw.mac.type >= e1000_82540)
2886205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_TADV,
2887205869Sjfv		    adapter->tx_abs_int_delay.value);
2888205869Sjfv
2889205869Sjfv	/* Program the Transmit Control Register */
2890205869Sjfv	tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL);
2891205869Sjfv	tctl &= ~E1000_TCTL_CT;
2892205869Sjfv	tctl |= (E1000_TCTL_PSP | E1000_TCTL_RTLC | E1000_TCTL_EN |
2893205869Sjfv		   (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT));
2894205869Sjfv
2895205869Sjfv	/* This write will effectively turn on the transmit unit. */
2896205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl);
2897205869Sjfv
2898205869Sjfv	/* Setup Transmit Descriptor Base Settings */
2899205869Sjfv	adapter->txd_cmd = E1000_TXD_CMD_IFCS;
2900205869Sjfv
2901205869Sjfv	if (adapter->tx_int_delay.value > 0)
2902205869Sjfv		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
2903205869Sjfv}
2904205869Sjfv
2905205869Sjfv/*********************************************************************
2906205869Sjfv *
2907205869Sjfv *  Free all transmit related data structures.
2908205869Sjfv *
2909205869Sjfv **********************************************************************/
2910205869Sjfvstatic void
2911205869Sjfvlem_free_transmit_structures(struct adapter *adapter)
2912205869Sjfv{
2913205869Sjfv	struct em_buffer *tx_buffer;
2914205869Sjfv
2915205869Sjfv	INIT_DEBUGOUT("free_transmit_structures: begin");
2916205869Sjfv
2917205869Sjfv	if (adapter->tx_buffer_area != NULL) {
2918205869Sjfv		for (int i = 0; i < adapter->num_tx_desc; i++) {
2919205869Sjfv			tx_buffer = &adapter->tx_buffer_area[i];
2920205869Sjfv			if (tx_buffer->m_head != NULL) {
2921205869Sjfv				bus_dmamap_sync(adapter->txtag, tx_buffer->map,
2922205869Sjfv				    BUS_DMASYNC_POSTWRITE);
2923205869Sjfv				bus_dmamap_unload(adapter->txtag,
2924205869Sjfv				    tx_buffer->map);
2925205869Sjfv				m_freem(tx_buffer->m_head);
2926205869Sjfv				tx_buffer->m_head = NULL;
2927205869Sjfv			} else if (tx_buffer->map != NULL)
2928205869Sjfv				bus_dmamap_unload(adapter->txtag,
2929205869Sjfv				    tx_buffer->map);
2930205869Sjfv			if (tx_buffer->map != NULL) {
2931205869Sjfv				bus_dmamap_destroy(adapter->txtag,
2932205869Sjfv				    tx_buffer->map);
2933205869Sjfv				tx_buffer->map = NULL;
2934205869Sjfv			}
2935205869Sjfv		}
2936205869Sjfv	}
2937205869Sjfv	if (adapter->tx_buffer_area != NULL) {
2938205869Sjfv		free(adapter->tx_buffer_area, M_DEVBUF);
2939205869Sjfv		adapter->tx_buffer_area = NULL;
2940205869Sjfv	}
2941205869Sjfv	if (adapter->txtag != NULL) {
2942205869Sjfv		bus_dma_tag_destroy(adapter->txtag);
2943205869Sjfv		adapter->txtag = NULL;
2944205869Sjfv	}
2945205869Sjfv#if __FreeBSD_version >= 800000
2946205869Sjfv	if (adapter->br != NULL)
2947205869Sjfv        	buf_ring_free(adapter->br, M_DEVBUF);
2948205869Sjfv#endif
2949205869Sjfv}
2950205869Sjfv
2951205869Sjfv/*********************************************************************
2952205869Sjfv *
2953205869Sjfv *  The offload context needs to be set when we transfer the first
2954205869Sjfv *  packet of a particular protocol (TCP/UDP). This routine has been
2955205869Sjfv *  enhanced to deal with inserted VLAN headers, and IPV6 (not complete)
2956205869Sjfv *
2957205869Sjfv *  Added back the old method of keeping the current context type
2958205869Sjfv *  and not setting if unnecessary, as this is reported to be a
2959205869Sjfv *  big performance win.  -jfv
2960205869Sjfv **********************************************************************/
2961205869Sjfvstatic void
2962205869Sjfvlem_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp,
2963205869Sjfv    u32 *txd_upper, u32 *txd_lower)
2964205869Sjfv{
2965205869Sjfv	struct e1000_context_desc *TXD = NULL;
2966205869Sjfv	struct em_buffer *tx_buffer;
2967205869Sjfv	struct ether_vlan_header *eh;
2968205869Sjfv	struct ip *ip = NULL;
2969205869Sjfv	struct ip6_hdr *ip6;
2970205869Sjfv	int curr_txd, ehdrlen;
2971205869Sjfv	u32 cmd, hdr_len, ip_hlen;
2972205869Sjfv	u16 etype;
2973205869Sjfv	u8 ipproto;
2974205869Sjfv
2975205869Sjfv
2976205869Sjfv	cmd = hdr_len = ipproto = 0;
2977209959Sjfv	*txd_upper = *txd_lower = 0;
2978205869Sjfv	curr_txd = adapter->next_avail_tx_desc;
2979205869Sjfv
2980205869Sjfv	/*
2981205869Sjfv	 * Determine where frame payload starts.
2982205869Sjfv	 * Jump over vlan headers if already present,
2983205869Sjfv	 * helpful for QinQ too.
2984205869Sjfv	 */
2985205869Sjfv	eh = mtod(mp, struct ether_vlan_header *);
2986205869Sjfv	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
2987205869Sjfv		etype = ntohs(eh->evl_proto);
2988205869Sjfv		ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
2989205869Sjfv	} else {
2990205869Sjfv		etype = ntohs(eh->evl_encap_proto);
2991205869Sjfv		ehdrlen = ETHER_HDR_LEN;
2992205869Sjfv	}
2993205869Sjfv
2994205869Sjfv	/*
2995205869Sjfv	 * We only support TCP/UDP for IPv4 and IPv6 for the moment.
2996205869Sjfv	 * TODO: Support SCTP too when it hits the tree.
2997205869Sjfv	 */
2998205869Sjfv	switch (etype) {
2999205869Sjfv	case ETHERTYPE_IP:
3000205869Sjfv		ip = (struct ip *)(mp->m_data + ehdrlen);
3001205869Sjfv		ip_hlen = ip->ip_hl << 2;
3002205869Sjfv
3003205869Sjfv		/* Setup of IP header checksum. */
3004205869Sjfv		if (mp->m_pkthdr.csum_flags & CSUM_IP) {
3005205869Sjfv			/*
3006205869Sjfv			 * Start offset for header checksum calculation.
3007205869Sjfv			 * End offset for header checksum calculation.
3008205869Sjfv			 * Offset of place to put the checksum.
3009205869Sjfv			 */
3010205869Sjfv			TXD = (struct e1000_context_desc *)
3011205869Sjfv			    &adapter->tx_desc_base[curr_txd];
3012205869Sjfv			TXD->lower_setup.ip_fields.ipcss = ehdrlen;
3013205869Sjfv			TXD->lower_setup.ip_fields.ipcse =
3014205869Sjfv			    htole16(ehdrlen + ip_hlen);
3015205869Sjfv			TXD->lower_setup.ip_fields.ipcso =
3016205869Sjfv			    ehdrlen + offsetof(struct ip, ip_sum);
3017205869Sjfv			cmd |= E1000_TXD_CMD_IP;
3018205869Sjfv			*txd_upper |= E1000_TXD_POPTS_IXSM << 8;
3019205869Sjfv		}
3020205869Sjfv
3021205869Sjfv		hdr_len = ehdrlen + ip_hlen;
3022205869Sjfv		ipproto = ip->ip_p;
3023205869Sjfv
3024205869Sjfv		break;
3025205869Sjfv	case ETHERTYPE_IPV6:
3026205869Sjfv		ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
3027205869Sjfv		ip_hlen = sizeof(struct ip6_hdr); /* XXX: No header stacking. */
3028205869Sjfv
3029205869Sjfv		/* IPv6 doesn't have a header checksum. */
3030205869Sjfv
3031205869Sjfv		hdr_len = ehdrlen + ip_hlen;
3032205869Sjfv		ipproto = ip6->ip6_nxt;
3033209959Sjfv		break;
3034205869Sjfv
3035205869Sjfv	default:
3036205869Sjfv		return;
3037205869Sjfv	}
3038205869Sjfv
3039205869Sjfv	switch (ipproto) {
3040205869Sjfv	case IPPROTO_TCP:
3041205869Sjfv		if (mp->m_pkthdr.csum_flags & CSUM_TCP) {
3042205869Sjfv			*txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
3043205869Sjfv			*txd_upper |= E1000_TXD_POPTS_TXSM << 8;
3044205869Sjfv			/* no need for context if already set */
3045205869Sjfv			if (adapter->last_hw_offload == CSUM_TCP)
3046205869Sjfv				return;
3047205869Sjfv			adapter->last_hw_offload = CSUM_TCP;
3048205869Sjfv			/*
3049205869Sjfv			 * Start offset for payload checksum calculation.
3050205869Sjfv			 * End offset for payload checksum calculation.
3051205869Sjfv			 * Offset of place to put the checksum.
3052205869Sjfv			 */
3053205869Sjfv			TXD = (struct e1000_context_desc *)
3054205869Sjfv			    &adapter->tx_desc_base[curr_txd];
3055205869Sjfv			TXD->upper_setup.tcp_fields.tucss = hdr_len;
3056205869Sjfv			TXD->upper_setup.tcp_fields.tucse = htole16(0);
3057205869Sjfv			TXD->upper_setup.tcp_fields.tucso =
3058205869Sjfv			    hdr_len + offsetof(struct tcphdr, th_sum);
3059205869Sjfv			cmd |= E1000_TXD_CMD_TCP;
3060205869Sjfv		}
3061205869Sjfv		break;
3062205869Sjfv	case IPPROTO_UDP:
3063205869Sjfv	{
3064205869Sjfv		if (mp->m_pkthdr.csum_flags & CSUM_UDP) {
3065205869Sjfv			*txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
3066205869Sjfv			*txd_upper |= E1000_TXD_POPTS_TXSM << 8;
3067205869Sjfv			/* no need for context if already set */
3068205869Sjfv			if (adapter->last_hw_offload == CSUM_UDP)
3069205869Sjfv				return;
3070205869Sjfv			adapter->last_hw_offload = CSUM_UDP;
3071205869Sjfv			/*
3072205869Sjfv			 * Start offset for header checksum calculation.
3073205869Sjfv			 * End offset for header checksum calculation.
3074205869Sjfv			 * Offset of place to put the checksum.
3075205869Sjfv			 */
3076205869Sjfv			TXD = (struct e1000_context_desc *)
3077205869Sjfv			    &adapter->tx_desc_base[curr_txd];
3078205869Sjfv			TXD->upper_setup.tcp_fields.tucss = hdr_len;
3079205869Sjfv			TXD->upper_setup.tcp_fields.tucse = htole16(0);
3080205869Sjfv			TXD->upper_setup.tcp_fields.tucso =
3081205869Sjfv			    hdr_len + offsetof(struct udphdr, uh_sum);
3082205869Sjfv		}
3083205869Sjfv		/* Fall Thru */
3084205869Sjfv	}
3085205869Sjfv	default:
3086205869Sjfv		break;
3087205869Sjfv	}
3088205869Sjfv
3089209959Sjfv	if (TXD == NULL)
3090209959Sjfv		return;
3091205869Sjfv	TXD->tcp_seg_setup.data = htole32(0);
3092205869Sjfv	TXD->cmd_and_length =
3093205869Sjfv	    htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT | cmd);
3094205869Sjfv	tx_buffer = &adapter->tx_buffer_area[curr_txd];
3095205869Sjfv	tx_buffer->m_head = NULL;
3096205869Sjfv	tx_buffer->next_eop = -1;
3097205869Sjfv
3098205869Sjfv	if (++curr_txd == adapter->num_tx_desc)
3099205869Sjfv		curr_txd = 0;
3100205869Sjfv
3101205869Sjfv	adapter->num_tx_desc_avail--;
3102205869Sjfv	adapter->next_avail_tx_desc = curr_txd;
3103205869Sjfv}
3104205869Sjfv
3105205869Sjfv
3106205869Sjfv/**********************************************************************
3107205869Sjfv *
3108205869Sjfv *  Examine each tx_buffer in the used queue. If the hardware is done
3109205869Sjfv *  processing the packet then free associated resources. The
3110205869Sjfv *  tx_buffer is put back on the free queue.
3111205869Sjfv *
3112205869Sjfv **********************************************************************/
3113205869Sjfvstatic void
3114205869Sjfvlem_txeof(struct adapter *adapter)
3115205869Sjfv{
3116205869Sjfv        int first, last, done, num_avail;
3117205869Sjfv        struct em_buffer *tx_buffer;
3118205869Sjfv        struct e1000_tx_desc   *tx_desc, *eop_desc;
3119205869Sjfv	struct ifnet   *ifp = adapter->ifp;
3120205869Sjfv
3121205869Sjfv	EM_TX_LOCK_ASSERT(adapter);
3122205869Sjfv
3123228281Sluigi#ifdef DEV_NETMAP
3124262151Sluigi	if (netmap_tx_irq(ifp, 0))
3125228281Sluigi		return;
3126228281Sluigi#endif /* DEV_NETMAP */
3127205869Sjfv        if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
3128205869Sjfv                return;
3129205869Sjfv
3130205869Sjfv        num_avail = adapter->num_tx_desc_avail;
3131205869Sjfv        first = adapter->next_tx_to_clean;
3132205869Sjfv        tx_desc = &adapter->tx_desc_base[first];
3133205869Sjfv        tx_buffer = &adapter->tx_buffer_area[first];
3134205869Sjfv	last = tx_buffer->next_eop;
3135205869Sjfv        eop_desc = &adapter->tx_desc_base[last];
3136205869Sjfv
3137205869Sjfv	/*
3138205869Sjfv	 * What this does is get the index of the
3139205869Sjfv	 * first descriptor AFTER the EOP of the
3140205869Sjfv	 * first packet, that way we can do the
3141205869Sjfv	 * simple comparison on the inner while loop.
3142205869Sjfv	 */
3143205869Sjfv	if (++last == adapter->num_tx_desc)
3144205869Sjfv 		last = 0;
3145205869Sjfv	done = last;
3146205869Sjfv
3147205869Sjfv        bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
3148205869Sjfv            BUS_DMASYNC_POSTREAD);
3149205869Sjfv
3150205869Sjfv        while (eop_desc->upper.fields.status & E1000_TXD_STAT_DD) {
3151205869Sjfv		/* We clean the range of the packet */
3152205869Sjfv		while (first != done) {
3153205869Sjfv                	tx_desc->upper.data = 0;
3154205869Sjfv                	tx_desc->lower.data = 0;
3155205869Sjfv                	tx_desc->buffer_addr = 0;
3156205869Sjfv                	++num_avail;
3157205869Sjfv
3158205869Sjfv			if (tx_buffer->m_head) {
3159205869Sjfv				ifp->if_opackets++;
3160205869Sjfv				bus_dmamap_sync(adapter->txtag,
3161205869Sjfv				    tx_buffer->map,
3162205869Sjfv				    BUS_DMASYNC_POSTWRITE);
3163205869Sjfv				bus_dmamap_unload(adapter->txtag,
3164205869Sjfv				    tx_buffer->map);
3165205869Sjfv
3166205869Sjfv                        	m_freem(tx_buffer->m_head);
3167205869Sjfv                        	tx_buffer->m_head = NULL;
3168205869Sjfv                	}
3169205869Sjfv			tx_buffer->next_eop = -1;
3170205869Sjfv			adapter->watchdog_time = ticks;
3171205869Sjfv
3172205869Sjfv	                if (++first == adapter->num_tx_desc)
3173205869Sjfv				first = 0;
3174205869Sjfv
3175205869Sjfv	                tx_buffer = &adapter->tx_buffer_area[first];
3176205869Sjfv			tx_desc = &adapter->tx_desc_base[first];
3177205869Sjfv		}
3178205869Sjfv		/* See if we can continue to the next packet */
3179205869Sjfv		last = tx_buffer->next_eop;
3180205869Sjfv		if (last != -1) {
3181205869Sjfv        		eop_desc = &adapter->tx_desc_base[last];
3182205869Sjfv			/* Get new done point */
3183205869Sjfv			if (++last == adapter->num_tx_desc) last = 0;
3184205869Sjfv			done = last;
3185205869Sjfv		} else
3186205869Sjfv			break;
3187205869Sjfv        }
3188205869Sjfv        bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
3189205869Sjfv            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3190205869Sjfv
3191205869Sjfv        adapter->next_tx_to_clean = first;
3192214646Sjfv        adapter->num_tx_desc_avail = num_avail;
3193205869Sjfv
3194270252Sluigi#ifdef NIC_SEND_COMBINING
3195270252Sluigi	if ((adapter->shadow_tdt & MIT_PENDING_TDT) == MIT_PENDING_TDT) {
3196270252Sluigi		/* a tdt write is pending, do it */
3197270252Sluigi		E1000_WRITE_REG(&adapter->hw, E1000_TDT(0),
3198270252Sluigi			0xffff & adapter->shadow_tdt);
3199270252Sluigi		adapter->shadow_tdt = MIT_PENDING_INT;
3200270252Sluigi	} else {
3201270252Sluigi		adapter->shadow_tdt = 0; // disable
3202270252Sluigi	}
3203270252Sluigi#endif /* NIC_SEND_COMBINING */
3204205869Sjfv        /*
3205205869Sjfv         * If we have enough room, clear IFF_DRV_OACTIVE to
3206205869Sjfv         * tell the stack that it is OK to send packets.
3207205869Sjfv         * If there are no pending descriptors, clear the watchdog.
3208205869Sjfv         */
3209214646Sjfv        if (adapter->num_tx_desc_avail > EM_TX_CLEANUP_THRESHOLD) {
3210205869Sjfv                ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
3211270252Sluigi#ifdef NIC_PARAVIRT
3212270252Sluigi		if (adapter->csb) { // XXX also csb_on ?
3213270252Sluigi			adapter->csb->guest_need_txkick = 2; /* acked */
3214270252Sluigi			// XXX memory barrier
3215270252Sluigi		}
3216270252Sluigi#endif /* NIC_PARAVIRT */
3217214646Sjfv                if (adapter->num_tx_desc_avail == adapter->num_tx_desc) {
3218205869Sjfv			adapter->watchdog_check = FALSE;
3219205869Sjfv			return;
3220205869Sjfv		}
3221205869Sjfv        }
3222205869Sjfv}
3223205869Sjfv
3224205869Sjfv/*********************************************************************
3225205869Sjfv *
3226205869Sjfv *  When Link is lost sometimes there is work still in the TX ring
3227205869Sjfv *  which may result in a watchdog, rather than allow that we do an
3228205869Sjfv *  attempted cleanup and then reinit here. Note that this has been
3229205869Sjfv *  seens mostly with fiber adapters.
3230205869Sjfv *
3231205869Sjfv **********************************************************************/
3232205869Sjfvstatic void
3233205869Sjfvlem_tx_purge(struct adapter *adapter)
3234205869Sjfv{
3235205869Sjfv	if ((!adapter->link_active) && (adapter->watchdog_check)) {
3236205869Sjfv		EM_TX_LOCK(adapter);
3237205869Sjfv		lem_txeof(adapter);
3238205869Sjfv		EM_TX_UNLOCK(adapter);
3239205869Sjfv		if (adapter->watchdog_check) /* Still outstanding? */
3240205869Sjfv			lem_init_locked(adapter);
3241205869Sjfv	}
3242205869Sjfv}
3243205869Sjfv
3244205869Sjfv/*********************************************************************
3245205869Sjfv *
3246205869Sjfv *  Get a buffer from system mbuf buffer pool.
3247205869Sjfv *
3248205869Sjfv **********************************************************************/
3249205869Sjfvstatic int
3250205869Sjfvlem_get_buf(struct adapter *adapter, int i)
3251205869Sjfv{
3252205869Sjfv	struct mbuf		*m;
3253205869Sjfv	bus_dma_segment_t	segs[1];
3254205869Sjfv	bus_dmamap_t		map;
3255205869Sjfv	struct em_buffer	*rx_buffer;
3256205869Sjfv	int			error, nsegs;
3257205869Sjfv
3258243857Sglebius	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
3259205869Sjfv	if (m == NULL) {
3260205869Sjfv		adapter->mbuf_cluster_failed++;
3261205869Sjfv		return (ENOBUFS);
3262205869Sjfv	}
3263205869Sjfv	m->m_len = m->m_pkthdr.len = MCLBYTES;
3264205869Sjfv
3265205869Sjfv	if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN))
3266205869Sjfv		m_adj(m, ETHER_ALIGN);
3267205869Sjfv
3268205869Sjfv	/*
3269205869Sjfv	 * Using memory from the mbuf cluster pool, invoke the
3270205869Sjfv	 * bus_dma machinery to arrange the memory mapping.
3271205869Sjfv	 */
3272205869Sjfv	error = bus_dmamap_load_mbuf_sg(adapter->rxtag,
3273205869Sjfv	    adapter->rx_sparemap, m, segs, &nsegs, BUS_DMA_NOWAIT);
3274205869Sjfv	if (error != 0) {
3275205869Sjfv		m_free(m);
3276205869Sjfv		return (error);
3277205869Sjfv	}
3278205869Sjfv
3279205869Sjfv	/* If nsegs is wrong then the stack is corrupt. */
3280205869Sjfv	KASSERT(nsegs == 1, ("Too many segments returned!"));
3281205869Sjfv
3282205869Sjfv	rx_buffer = &adapter->rx_buffer_area[i];
3283205869Sjfv	if (rx_buffer->m_head != NULL)
3284205869Sjfv		bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
3285205869Sjfv
3286205869Sjfv	map = rx_buffer->map;
3287205869Sjfv	rx_buffer->map = adapter->rx_sparemap;
3288205869Sjfv	adapter->rx_sparemap = map;
3289205869Sjfv	bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD);
3290205869Sjfv	rx_buffer->m_head = m;
3291205869Sjfv
3292205869Sjfv	adapter->rx_desc_base[i].buffer_addr = htole64(segs[0].ds_addr);
3293205869Sjfv	return (0);
3294205869Sjfv}
3295205869Sjfv
3296205869Sjfv/*********************************************************************
3297205869Sjfv *
3298205869Sjfv *  Allocate memory for rx_buffer structures. Since we use one
3299205869Sjfv *  rx_buffer per received packet, the maximum number of rx_buffer's
3300205869Sjfv *  that we'll need is equal to the number of receive descriptors
3301205869Sjfv *  that we've allocated.
3302205869Sjfv *
3303205869Sjfv **********************************************************************/
3304205869Sjfvstatic int
3305205869Sjfvlem_allocate_receive_structures(struct adapter *adapter)
3306205869Sjfv{
3307205869Sjfv	device_t dev = adapter->dev;
3308205869Sjfv	struct em_buffer *rx_buffer;
3309205869Sjfv	int i, error;
3310205869Sjfv
3311205869Sjfv	adapter->rx_buffer_area = malloc(sizeof(struct em_buffer) *
3312205869Sjfv	    adapter->num_rx_desc, M_DEVBUF, M_NOWAIT | M_ZERO);
3313205869Sjfv	if (adapter->rx_buffer_area == NULL) {
3314205869Sjfv		device_printf(dev, "Unable to allocate rx_buffer memory\n");
3315205869Sjfv		return (ENOMEM);
3316205869Sjfv	}
3317205869Sjfv
3318205869Sjfv	error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
3319205869Sjfv				1, 0,			/* alignment, bounds */
3320205869Sjfv				BUS_SPACE_MAXADDR,	/* lowaddr */
3321205869Sjfv				BUS_SPACE_MAXADDR,	/* highaddr */
3322205869Sjfv				NULL, NULL,		/* filter, filterarg */
3323205869Sjfv				MCLBYTES,		/* maxsize */
3324205869Sjfv				1,			/* nsegments */
3325205869Sjfv				MCLBYTES,		/* maxsegsize */
3326205869Sjfv				0,			/* flags */
3327205869Sjfv				NULL,			/* lockfunc */
3328205869Sjfv				NULL,			/* lockarg */
3329205869Sjfv				&adapter->rxtag);
3330205869Sjfv	if (error) {
3331205869Sjfv		device_printf(dev, "%s: bus_dma_tag_create failed %d\n",
3332205869Sjfv		    __func__, error);
3333205869Sjfv		goto fail;
3334205869Sjfv	}
3335205869Sjfv
3336205869Sjfv	/* Create the spare map (used by getbuf) */
3337259508Skib	error = bus_dmamap_create(adapter->rxtag, 0, &adapter->rx_sparemap);
3338205869Sjfv	if (error) {
3339205869Sjfv		device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
3340205869Sjfv		    __func__, error);
3341205869Sjfv		goto fail;
3342205869Sjfv	}
3343205869Sjfv
3344205869Sjfv	rx_buffer = adapter->rx_buffer_area;
3345205869Sjfv	for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
3346259508Skib		error = bus_dmamap_create(adapter->rxtag, 0, &rx_buffer->map);
3347205869Sjfv		if (error) {
3348205869Sjfv			device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
3349205869Sjfv			    __func__, error);
3350205869Sjfv			goto fail;
3351205869Sjfv		}
3352205869Sjfv	}
3353205869Sjfv
3354205869Sjfv	return (0);
3355205869Sjfv
3356205869Sjfvfail:
3357205869Sjfv	lem_free_receive_structures(adapter);
3358205869Sjfv	return (error);
3359205869Sjfv}
3360205869Sjfv
3361205869Sjfv/*********************************************************************
3362205869Sjfv *
3363205869Sjfv *  (Re)initialize receive structures.
3364205869Sjfv *
3365205869Sjfv **********************************************************************/
3366205869Sjfvstatic int
3367205869Sjfvlem_setup_receive_structures(struct adapter *adapter)
3368205869Sjfv{
3369205869Sjfv	struct em_buffer *rx_buffer;
3370205869Sjfv	int i, error;
3371228281Sluigi#ifdef DEV_NETMAP
3372228281Sluigi	/* we are already under lock */
3373228281Sluigi	struct netmap_adapter *na = NA(adapter->ifp);
3374228281Sluigi	struct netmap_slot *slot = netmap_reset(na, NR_RX, 0, 0);
3375228281Sluigi#endif
3376205869Sjfv
3377205869Sjfv	/* Reset descriptor ring */
3378205869Sjfv	bzero(adapter->rx_desc_base,
3379205869Sjfv	    (sizeof(struct e1000_rx_desc)) * adapter->num_rx_desc);
3380205869Sjfv
3381205869Sjfv	/* Free current RX buffers. */
3382205869Sjfv	rx_buffer = adapter->rx_buffer_area;
3383205869Sjfv	for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
3384205869Sjfv		if (rx_buffer->m_head != NULL) {
3385205869Sjfv			bus_dmamap_sync(adapter->rxtag, rx_buffer->map,
3386205869Sjfv			    BUS_DMASYNC_POSTREAD);
3387205869Sjfv			bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
3388205869Sjfv			m_freem(rx_buffer->m_head);
3389205869Sjfv			rx_buffer->m_head = NULL;
3390205869Sjfv		}
3391205869Sjfv        }
3392205869Sjfv
3393205869Sjfv	/* Allocate new ones. */
3394205869Sjfv	for (i = 0; i < adapter->num_rx_desc; i++) {
3395228281Sluigi#ifdef DEV_NETMAP
3396228281Sluigi		if (slot) {
3397231796Sluigi			/* the i-th NIC entry goes to slot si */
3398232238Sluigi			int si = netmap_idx_n2k(&na->rx_rings[0], i);
3399229939Sluigi			uint64_t paddr;
3400228281Sluigi			void *addr;
3401228281Sluigi
3402270252Sluigi			addr = PNMB(na, slot + si, &paddr);
3403270252Sluigi			netmap_load_map(na, adapter->rxtag, rx_buffer->map, addr);
3404228281Sluigi			/* Update descriptor */
3405229939Sluigi			adapter->rx_desc_base[i].buffer_addr = htole64(paddr);
3406228281Sluigi			continue;
3407228281Sluigi		}
3408228281Sluigi#endif /* DEV_NETMAP */
3409205869Sjfv		error = lem_get_buf(adapter, i);
3410205869Sjfv		if (error)
3411205869Sjfv                        return (error);
3412205869Sjfv	}
3413205869Sjfv
3414205869Sjfv	/* Setup our descriptor pointers */
3415205869Sjfv	adapter->next_rx_desc_to_check = 0;
3416205869Sjfv	bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
3417205869Sjfv	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3418205869Sjfv
3419205869Sjfv	return (0);
3420205869Sjfv}
3421205869Sjfv
3422205869Sjfv/*********************************************************************
3423205869Sjfv *
3424205869Sjfv *  Enable receive unit.
3425205869Sjfv *
3426205869Sjfv **********************************************************************/
3427205869Sjfv
3428205869Sjfvstatic void
3429205869Sjfvlem_initialize_receive_unit(struct adapter *adapter)
3430205869Sjfv{
3431205869Sjfv	struct ifnet	*ifp = adapter->ifp;
3432205869Sjfv	u64	bus_addr;
3433205869Sjfv	u32	rctl, rxcsum;
3434205869Sjfv
3435205869Sjfv	INIT_DEBUGOUT("lem_initialize_receive_unit: begin");
3436205869Sjfv
3437205869Sjfv	/*
3438205869Sjfv	 * Make sure receives are disabled while setting
3439205869Sjfv	 * up the descriptor ring
3440205869Sjfv	 */
3441205869Sjfv	rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
3442205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
3443205869Sjfv
3444205869Sjfv	if (adapter->hw.mac.type >= e1000_82540) {
3445205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RADV,
3446205869Sjfv		    adapter->rx_abs_int_delay.value);
3447205869Sjfv		/*
3448205869Sjfv		 * Set the interrupt throttling rate. Value is calculated
3449205869Sjfv		 * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns)
3450205869Sjfv		 */
3451205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_ITR, DEFAULT_ITR);
3452205869Sjfv	}
3453205869Sjfv
3454205869Sjfv	/* Setup the Base and Length of the Rx Descriptor Ring */
3455205869Sjfv	bus_addr = adapter->rxdma.dma_paddr;
3456205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(0),
3457205869Sjfv	    adapter->num_rx_desc * sizeof(struct e1000_rx_desc));
3458205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RDBAH(0),
3459205869Sjfv	    (u32)(bus_addr >> 32));
3460205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RDBAL(0),
3461205869Sjfv	    (u32)bus_addr);
3462205869Sjfv
3463205869Sjfv	/* Setup the Receive Control Register */
3464205869Sjfv	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
3465205869Sjfv	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
3466205869Sjfv		   E1000_RCTL_RDMTS_HALF |
3467205869Sjfv		   (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
3468205869Sjfv
3469205869Sjfv	/* Make sure VLAN Filters are off */
3470205869Sjfv	rctl &= ~E1000_RCTL_VFE;
3471205869Sjfv
3472205869Sjfv	if (e1000_tbi_sbp_enabled_82543(&adapter->hw))
3473205869Sjfv		rctl |= E1000_RCTL_SBP;
3474205869Sjfv	else
3475205869Sjfv		rctl &= ~E1000_RCTL_SBP;
3476205869Sjfv
3477205869Sjfv	switch (adapter->rx_buffer_len) {
3478205869Sjfv	default:
3479205869Sjfv	case 2048:
3480205869Sjfv		rctl |= E1000_RCTL_SZ_2048;
3481205869Sjfv		break;
3482205869Sjfv	case 4096:
3483205869Sjfv		rctl |= E1000_RCTL_SZ_4096 |
3484205869Sjfv		    E1000_RCTL_BSEX | E1000_RCTL_LPE;
3485205869Sjfv		break;
3486205869Sjfv	case 8192:
3487205869Sjfv		rctl |= E1000_RCTL_SZ_8192 |
3488205869Sjfv		    E1000_RCTL_BSEX | E1000_RCTL_LPE;
3489205869Sjfv		break;
3490205869Sjfv	case 16384:
3491205869Sjfv		rctl |= E1000_RCTL_SZ_16384 |
3492205869Sjfv		    E1000_RCTL_BSEX | E1000_RCTL_LPE;
3493205869Sjfv		break;
3494205869Sjfv	}
3495205869Sjfv
3496205869Sjfv	if (ifp->if_mtu > ETHERMTU)
3497205869Sjfv		rctl |= E1000_RCTL_LPE;
3498205869Sjfv	else
3499205869Sjfv		rctl &= ~E1000_RCTL_LPE;
3500205869Sjfv
3501205869Sjfv	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
3502205869Sjfv	if ((adapter->hw.mac.type >= e1000_82543) &&
3503205869Sjfv	    (ifp->if_capenable & IFCAP_RXCSUM)) {
3504205869Sjfv		rxcsum = E1000_READ_REG(&adapter->hw, E1000_RXCSUM);
3505205869Sjfv		rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL);
3506205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RXCSUM, rxcsum);
3507205869Sjfv	}
3508205869Sjfv
3509205869Sjfv	/* Enable Receives */
3510205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
3511205869Sjfv
3512205869Sjfv	/*
3513205869Sjfv	 * Setup the HW Rx Head and
3514205869Sjfv	 * Tail Descriptor Pointers
3515205869Sjfv	 */
3516205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0);
3517250413Sluigi	rctl = adapter->num_rx_desc - 1; /* default RDT value */
3518228281Sluigi#ifdef DEV_NETMAP
3519228281Sluigi	/* preserve buffers already made available to clients */
3520250413Sluigi	if (ifp->if_capenable & IFCAP_NETMAP)
3521262151Sluigi		rctl -= nm_kr_rxspace(&NA(adapter->ifp)->rx_rings[0]);
3522228281Sluigi#endif /* DEV_NETMAP */
3523250413Sluigi	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), rctl);
3524205869Sjfv
3525205869Sjfv	return;
3526205869Sjfv}
3527205869Sjfv
3528205869Sjfv/*********************************************************************
3529205869Sjfv *
3530205869Sjfv *  Free receive related data structures.
3531205869Sjfv *
3532205869Sjfv **********************************************************************/
3533205869Sjfvstatic void
3534205869Sjfvlem_free_receive_structures(struct adapter *adapter)
3535205869Sjfv{
3536205869Sjfv	struct em_buffer *rx_buffer;
3537205869Sjfv	int i;
3538205869Sjfv
3539205869Sjfv	INIT_DEBUGOUT("free_receive_structures: begin");
3540205869Sjfv
3541205869Sjfv	if (adapter->rx_sparemap) {
3542205869Sjfv		bus_dmamap_destroy(adapter->rxtag, adapter->rx_sparemap);
3543205869Sjfv		adapter->rx_sparemap = NULL;
3544205869Sjfv	}
3545205869Sjfv
3546205869Sjfv	/* Cleanup any existing buffers */
3547205869Sjfv	if (adapter->rx_buffer_area != NULL) {
3548205869Sjfv		rx_buffer = adapter->rx_buffer_area;
3549205869Sjfv		for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
3550205869Sjfv			if (rx_buffer->m_head != NULL) {
3551205869Sjfv				bus_dmamap_sync(adapter->rxtag, rx_buffer->map,
3552205869Sjfv				    BUS_DMASYNC_POSTREAD);
3553205869Sjfv				bus_dmamap_unload(adapter->rxtag,
3554205869Sjfv				    rx_buffer->map);
3555205869Sjfv				m_freem(rx_buffer->m_head);
3556205869Sjfv				rx_buffer->m_head = NULL;
3557205869Sjfv			} else if (rx_buffer->map != NULL)
3558205869Sjfv				bus_dmamap_unload(adapter->rxtag,
3559205869Sjfv				    rx_buffer->map);
3560205869Sjfv			if (rx_buffer->map != NULL) {
3561205869Sjfv				bus_dmamap_destroy(adapter->rxtag,
3562205869Sjfv				    rx_buffer->map);
3563205869Sjfv				rx_buffer->map = NULL;
3564205869Sjfv			}
3565205869Sjfv		}
3566205869Sjfv	}
3567205869Sjfv
3568205869Sjfv	if (adapter->rx_buffer_area != NULL) {
3569205869Sjfv		free(adapter->rx_buffer_area, M_DEVBUF);
3570205869Sjfv		adapter->rx_buffer_area = NULL;
3571205869Sjfv	}
3572205869Sjfv
3573205869Sjfv	if (adapter->rxtag != NULL) {
3574205869Sjfv		bus_dma_tag_destroy(adapter->rxtag);
3575205869Sjfv		adapter->rxtag = NULL;
3576205869Sjfv	}
3577205869Sjfv}
3578205869Sjfv
3579205869Sjfv/*********************************************************************
3580205869Sjfv *
3581205869Sjfv *  This routine executes in interrupt context. It replenishes
3582205869Sjfv *  the mbufs in the descriptor and sends data which has been
3583205869Sjfv *  dma'ed into host memory to upper layer.
3584205869Sjfv *
3585205869Sjfv *  We loop at most count times if count is > 0, or until done if
3586205869Sjfv *  count < 0.
3587205869Sjfv *
3588205869Sjfv *  For polling we also now return the number of cleaned packets
3589205869Sjfv *********************************************************************/
3590209238Sjfvstatic bool
3591209238Sjfvlem_rxeof(struct adapter *adapter, int count, int *done)
3592205869Sjfv{
3593241844Seadler	struct ifnet	*ifp = adapter->ifp;
3594205869Sjfv	struct mbuf	*mp;
3595214646Sjfv	u8		status = 0, accept_frame = 0, eop = 0;
3596205869Sjfv	u16 		len, desc_len, prev_len_adj;
3597205869Sjfv	int		i, rx_sent = 0;
3598205869Sjfv	struct e1000_rx_desc   *current_desc;
3599205869Sjfv
3600270252Sluigi#ifdef BATCH_DISPATCH
3601270252Sluigi	struct mbuf *mh = NULL, *mt = NULL;
3602270252Sluigi#endif /* BATCH_DISPATCH */
3603270252Sluigi#ifdef NIC_PARAVIRT
3604270252Sluigi	int retries = 0;
3605270252Sluigi	struct paravirt_csb* csb = adapter->csb;
3606270252Sluigi	int csb_mode = csb && csb->guest_csb_on;
3607270252Sluigi
3608270252Sluigi	//ND("clear guest_rxkick at %d", adapter->next_rx_desc_to_check);
3609270252Sluigi	if (csb_mode && csb->guest_need_rxkick)
3610270252Sluigi		csb->guest_need_rxkick = 0;
3611270252Sluigi#endif /* NIC_PARAVIRT */
3612205869Sjfv	EM_RX_LOCK(adapter);
3613270252Sluigi
3614270252Sluigi#ifdef BATCH_DISPATCH
3615270252Sluigi    batch_again:
3616270252Sluigi#endif /* BATCH_DISPATCH */
3617205869Sjfv	i = adapter->next_rx_desc_to_check;
3618205869Sjfv	current_desc = &adapter->rx_desc_base[i];
3619205869Sjfv	bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
3620205869Sjfv	    BUS_DMASYNC_POSTREAD);
3621205869Sjfv
3622228281Sluigi#ifdef DEV_NETMAP
3623262151Sluigi	if (netmap_rx_irq(ifp, 0, &rx_sent)) {
3624262151Sluigi		EM_RX_UNLOCK(adapter);
3625250109Sluigi		return (FALSE);
3626262151Sluigi	}
3627228281Sluigi#endif /* DEV_NETMAP */
3628228281Sluigi
3629270252Sluigi#if 1 // XXX optimization ?
3630205869Sjfv	if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
3631209238Sjfv		if (done != NULL)
3632209238Sjfv			*done = rx_sent;
3633205869Sjfv		EM_RX_UNLOCK(adapter);
3634209238Sjfv		return (FALSE);
3635205869Sjfv	}
3636270252Sluigi#endif /* 0 */
3637205869Sjfv
3638214646Sjfv	while (count != 0 && ifp->if_drv_flags & IFF_DRV_RUNNING) {
3639205869Sjfv		struct mbuf *m = NULL;
3640205869Sjfv
3641214646Sjfv		status = current_desc->status;
3642270252Sluigi		if ((status & E1000_RXD_STAT_DD) == 0) {
3643270252Sluigi#ifdef NIC_PARAVIRT
3644270252Sluigi		    if (csb_mode) {
3645270252Sluigi			/* buffer not ready yet. Retry a few times before giving up */
3646270252Sluigi			if (++retries <= adapter->rx_retries) {
3647270252Sluigi				continue;
3648270252Sluigi			}
3649270252Sluigi			if (csb->guest_need_rxkick == 0) {
3650270252Sluigi				// ND("set guest_rxkick at %d", adapter->next_rx_desc_to_check);
3651270252Sluigi				csb->guest_need_rxkick = 1;
3652270252Sluigi				// XXX memory barrier, status volatile ?
3653270252Sluigi				continue; /* double check */
3654270252Sluigi			}
3655270252Sluigi		    }
3656270252Sluigi		    /* no buffer ready, give up */
3657270252Sluigi#endif /* NIC_PARAVIRT */
3658214646Sjfv			break;
3659270252Sluigi		}
3660270252Sluigi#ifdef NIC_PARAVIRT
3661270252Sluigi		if (csb_mode) {
3662270252Sluigi			if (csb->guest_need_rxkick)
3663270252Sluigi				// ND("clear again guest_rxkick at %d", adapter->next_rx_desc_to_check);
3664270252Sluigi			csb->guest_need_rxkick = 0;
3665270252Sluigi			retries = 0;
3666270252Sluigi		}
3667270252Sluigi#endif /* NIC_PARAVIRT */
3668214646Sjfv
3669205869Sjfv		mp = adapter->rx_buffer_area[i].m_head;
3670205869Sjfv		/*
3671205869Sjfv		 * Can't defer bus_dmamap_sync(9) because TBI_ACCEPT
3672205869Sjfv		 * needs to access the last received byte in the mbuf.
3673205869Sjfv		 */
3674205869Sjfv		bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map,
3675205869Sjfv		    BUS_DMASYNC_POSTREAD);
3676205869Sjfv
3677205869Sjfv		accept_frame = 1;
3678205869Sjfv		prev_len_adj = 0;
3679205869Sjfv		desc_len = le16toh(current_desc->length);
3680205869Sjfv		if (status & E1000_RXD_STAT_EOP) {
3681205869Sjfv			count--;
3682205869Sjfv			eop = 1;
3683205869Sjfv			if (desc_len < ETHER_CRC_LEN) {
3684205869Sjfv				len = 0;
3685205869Sjfv				prev_len_adj = ETHER_CRC_LEN - desc_len;
3686205869Sjfv			} else
3687205869Sjfv				len = desc_len - ETHER_CRC_LEN;
3688205869Sjfv		} else {
3689205869Sjfv			eop = 0;
3690205869Sjfv			len = desc_len;
3691205869Sjfv		}
3692205869Sjfv
3693205869Sjfv		if (current_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
3694205869Sjfv			u8	last_byte;
3695205869Sjfv			u32	pkt_len = desc_len;
3696205869Sjfv
3697205869Sjfv			if (adapter->fmp != NULL)
3698205869Sjfv				pkt_len += adapter->fmp->m_pkthdr.len;
3699205869Sjfv
3700205869Sjfv			last_byte = *(mtod(mp, caddr_t) + desc_len - 1);
3701205869Sjfv			if (TBI_ACCEPT(&adapter->hw, status,
3702205869Sjfv			    current_desc->errors, pkt_len, last_byte,
3703205869Sjfv			    adapter->min_frame_size, adapter->max_frame_size)) {
3704205869Sjfv				e1000_tbi_adjust_stats_82543(&adapter->hw,
3705205869Sjfv				    &adapter->stats, pkt_len,
3706205869Sjfv				    adapter->hw.mac.addr,
3707205869Sjfv				    adapter->max_frame_size);
3708205869Sjfv				if (len > 0)
3709205869Sjfv					len--;
3710205869Sjfv			} else
3711205869Sjfv				accept_frame = 0;
3712205869Sjfv		}
3713205869Sjfv
3714205869Sjfv		if (accept_frame) {
3715205869Sjfv			if (lem_get_buf(adapter, i) != 0) {
3716205869Sjfv				ifp->if_iqdrops++;
3717205869Sjfv				goto discard;
3718205869Sjfv			}
3719205869Sjfv
3720205869Sjfv			/* Assign correct length to the current fragment */
3721205869Sjfv			mp->m_len = len;
3722205869Sjfv
3723205869Sjfv			if (adapter->fmp == NULL) {
3724205869Sjfv				mp->m_pkthdr.len = len;
3725205869Sjfv				adapter->fmp = mp; /* Store the first mbuf */
3726205869Sjfv				adapter->lmp = mp;
3727205869Sjfv			} else {
3728205869Sjfv				/* Chain mbuf's together */
3729205869Sjfv				mp->m_flags &= ~M_PKTHDR;
3730205869Sjfv				/*
3731205869Sjfv				 * Adjust length of previous mbuf in chain if
3732205869Sjfv				 * we received less than 4 bytes in the last
3733205869Sjfv				 * descriptor.
3734205869Sjfv				 */
3735205869Sjfv				if (prev_len_adj > 0) {
3736205869Sjfv					adapter->lmp->m_len -= prev_len_adj;
3737205869Sjfv					adapter->fmp->m_pkthdr.len -=
3738205869Sjfv					    prev_len_adj;
3739205869Sjfv				}
3740205869Sjfv				adapter->lmp->m_next = mp;
3741205869Sjfv				adapter->lmp = adapter->lmp->m_next;
3742205869Sjfv				adapter->fmp->m_pkthdr.len += len;
3743205869Sjfv			}
3744205869Sjfv
3745205869Sjfv			if (eop) {
3746205869Sjfv				adapter->fmp->m_pkthdr.rcvif = ifp;
3747205869Sjfv				ifp->if_ipackets++;
3748205869Sjfv				lem_receive_checksum(adapter, current_desc,
3749205869Sjfv				    adapter->fmp);
3750205869Sjfv#ifndef __NO_STRICT_ALIGNMENT
3751205869Sjfv				if (adapter->max_frame_size >
3752205869Sjfv				    (MCLBYTES - ETHER_ALIGN) &&
3753205869Sjfv				    lem_fixup_rx(adapter) != 0)
3754205869Sjfv					goto skip;
3755205869Sjfv#endif
3756205869Sjfv				if (status & E1000_RXD_STAT_VP) {
3757205869Sjfv					adapter->fmp->m_pkthdr.ether_vtag =
3758229606Srwatson					    le16toh(current_desc->special);
3759205869Sjfv					adapter->fmp->m_flags |= M_VLANTAG;
3760205869Sjfv				}
3761205869Sjfv#ifndef __NO_STRICT_ALIGNMENT
3762205869Sjfvskip:
3763205869Sjfv#endif
3764205869Sjfv				m = adapter->fmp;
3765205869Sjfv				adapter->fmp = NULL;
3766205869Sjfv				adapter->lmp = NULL;
3767205869Sjfv			}
3768205869Sjfv		} else {
3769240879Ssbruno			adapter->dropped_pkts++;
3770205869Sjfvdiscard:
3771205869Sjfv			/* Reuse loaded DMA map and just update mbuf chain */
3772205869Sjfv			mp = adapter->rx_buffer_area[i].m_head;
3773205869Sjfv			mp->m_len = mp->m_pkthdr.len = MCLBYTES;
3774205869Sjfv			mp->m_data = mp->m_ext.ext_buf;
3775205869Sjfv			mp->m_next = NULL;
3776205869Sjfv			if (adapter->max_frame_size <=
3777205869Sjfv			    (MCLBYTES - ETHER_ALIGN))
3778205869Sjfv				m_adj(mp, ETHER_ALIGN);
3779205869Sjfv			if (adapter->fmp != NULL) {
3780205869Sjfv				m_freem(adapter->fmp);
3781205869Sjfv				adapter->fmp = NULL;
3782205869Sjfv				adapter->lmp = NULL;
3783205869Sjfv			}
3784205869Sjfv			m = NULL;
3785205869Sjfv		}
3786205869Sjfv
3787205869Sjfv		/* Zero out the receive descriptors status. */
3788205869Sjfv		current_desc->status = 0;
3789205869Sjfv		bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
3790205869Sjfv		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3791205869Sjfv
3792270252Sluigi#ifdef NIC_PARAVIRT
3793270252Sluigi		if (csb_mode) {
3794270252Sluigi			/* the buffer at i has been already replaced by lem_get_buf()
3795270252Sluigi			 * so it is safe to set guest_rdt = i and possibly send a kick.
3796270252Sluigi			 * XXX see if we can optimize it later.
3797270252Sluigi			 */
3798270252Sluigi			csb->guest_rdt = i;
3799270252Sluigi			// XXX memory barrier
3800270252Sluigi			if (i == csb->host_rxkick_at)
3801270252Sluigi				E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
3802270252Sluigi		}
3803270252Sluigi#endif /* NIC_PARAVIRT */
3804205869Sjfv		/* Advance our pointers to the next descriptor. */
3805205869Sjfv		if (++i == adapter->num_rx_desc)
3806205869Sjfv			i = 0;
3807205869Sjfv		/* Call into the stack */
3808205869Sjfv		if (m != NULL) {
3809270252Sluigi#ifdef BATCH_DISPATCH
3810270252Sluigi		    if (adapter->batch_enable) {
3811270252Sluigi			if (mh == NULL)
3812270252Sluigi				mh = mt = m;
3813270252Sluigi			else
3814270252Sluigi				mt->m_nextpkt = m;
3815270252Sluigi			mt = m;
3816270252Sluigi			m->m_nextpkt = NULL;
3817270252Sluigi			rx_sent++;
3818270252Sluigi			current_desc = &adapter->rx_desc_base[i];
3819270252Sluigi			continue;
3820270252Sluigi		    }
3821270252Sluigi#endif /* BATCH_DISPATCH */
3822205869Sjfv			adapter->next_rx_desc_to_check = i;
3823205869Sjfv			EM_RX_UNLOCK(adapter);
3824205869Sjfv			(*ifp->if_input)(ifp, m);
3825205869Sjfv			EM_RX_LOCK(adapter);
3826205869Sjfv			rx_sent++;
3827205869Sjfv			i = adapter->next_rx_desc_to_check;
3828205869Sjfv		}
3829205869Sjfv		current_desc = &adapter->rx_desc_base[i];
3830205869Sjfv	}
3831205869Sjfv	adapter->next_rx_desc_to_check = i;
3832270252Sluigi#ifdef BATCH_DISPATCH
3833270252Sluigi	if (mh) {
3834270252Sluigi		EM_RX_UNLOCK(adapter);
3835270252Sluigi		while ( (mt = mh) != NULL) {
3836270252Sluigi			mh = mh->m_nextpkt;
3837270252Sluigi			mt->m_nextpkt = NULL;
3838270252Sluigi			if_input(ifp, mt);
3839270252Sluigi		}
3840270252Sluigi		EM_RX_LOCK(adapter);
3841270252Sluigi		i = adapter->next_rx_desc_to_check; /* in case of interrupts */
3842270252Sluigi		if (count > 0)
3843270252Sluigi			goto batch_again;
3844270252Sluigi	}
3845270252Sluigi#endif /* BATCH_DISPATCH */
3846205869Sjfv
3847205869Sjfv	/* Advance the E1000's Receive Queue #0  "Tail Pointer". */
3848205869Sjfv	if (--i < 0)
3849205869Sjfv		i = adapter->num_rx_desc - 1;
3850270252Sluigi#ifdef NIC_PARAVIRT
3851270252Sluigi	if (!csb_mode) /* filter out writes */
3852270252Sluigi#endif /* NIC_PARAVIRT */
3853205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
3854209238Sjfv	if (done != NULL)
3855209238Sjfv		*done = rx_sent;
3856205869Sjfv	EM_RX_UNLOCK(adapter);
3857214646Sjfv	return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
3858205869Sjfv}
3859205869Sjfv
3860205869Sjfv#ifndef __NO_STRICT_ALIGNMENT
3861205869Sjfv/*
3862205869Sjfv * When jumbo frames are enabled we should realign entire payload on
3863205869Sjfv * architecures with strict alignment. This is serious design mistake of 8254x
3864205869Sjfv * as it nullifies DMA operations. 8254x just allows RX buffer size to be
3865205869Sjfv * 2048/4096/8192/16384. What we really want is 2048 - ETHER_ALIGN to align its
3866205869Sjfv * payload. On architecures without strict alignment restrictions 8254x still
3867205869Sjfv * performs unaligned memory access which would reduce the performance too.
3868205869Sjfv * To avoid copying over an entire frame to align, we allocate a new mbuf and
3869205869Sjfv * copy ethernet header to the new mbuf. The new mbuf is prepended into the
3870205869Sjfv * existing mbuf chain.
3871205869Sjfv *
3872205869Sjfv * Be aware, best performance of the 8254x is achived only when jumbo frame is
3873205869Sjfv * not used at all on architectures with strict alignment.
3874205869Sjfv */
3875205869Sjfvstatic int
3876205869Sjfvlem_fixup_rx(struct adapter *adapter)
3877205869Sjfv{
3878205869Sjfv	struct mbuf *m, *n;
3879205869Sjfv	int error;
3880205869Sjfv
3881205869Sjfv	error = 0;
3882205869Sjfv	m = adapter->fmp;
3883205869Sjfv	if (m->m_len <= (MCLBYTES - ETHER_HDR_LEN)) {
3884205869Sjfv		bcopy(m->m_data, m->m_data + ETHER_HDR_LEN, m->m_len);
3885205869Sjfv		m->m_data += ETHER_HDR_LEN;
3886205869Sjfv	} else {
3887243857Sglebius		MGETHDR(n, M_NOWAIT, MT_DATA);
3888205869Sjfv		if (n != NULL) {
3889205869Sjfv			bcopy(m->m_data, n->m_data, ETHER_HDR_LEN);
3890205869Sjfv			m->m_data += ETHER_HDR_LEN;
3891205869Sjfv			m->m_len -= ETHER_HDR_LEN;
3892205869Sjfv			n->m_len = ETHER_HDR_LEN;
3893205869Sjfv			M_MOVE_PKTHDR(n, m);
3894205869Sjfv			n->m_next = m;
3895205869Sjfv			adapter->fmp = n;
3896205869Sjfv		} else {
3897205869Sjfv			adapter->dropped_pkts++;
3898205869Sjfv			m_freem(adapter->fmp);
3899205869Sjfv			adapter->fmp = NULL;
3900205869Sjfv			error = ENOMEM;
3901205869Sjfv		}
3902205869Sjfv	}
3903205869Sjfv
3904205869Sjfv	return (error);
3905205869Sjfv}
3906205869Sjfv#endif
3907205869Sjfv
3908205869Sjfv/*********************************************************************
3909205869Sjfv *
3910205869Sjfv *  Verify that the hardware indicated that the checksum is valid.
3911205869Sjfv *  Inform the stack about the status of checksum so that stack
3912205869Sjfv *  doesn't spend time verifying the checksum.
3913205869Sjfv *
3914205869Sjfv *********************************************************************/
3915205869Sjfvstatic void
3916205869Sjfvlem_receive_checksum(struct adapter *adapter,
3917205869Sjfv	    struct e1000_rx_desc *rx_desc, struct mbuf *mp)
3918205869Sjfv{
3919205869Sjfv	/* 82543 or newer only */
3920205869Sjfv	if ((adapter->hw.mac.type < e1000_82543) ||
3921205869Sjfv	    /* Ignore Checksum bit is set */
3922205869Sjfv	    (rx_desc->status & E1000_RXD_STAT_IXSM)) {
3923205869Sjfv		mp->m_pkthdr.csum_flags = 0;
3924205869Sjfv		return;
3925205869Sjfv	}
3926205869Sjfv
3927205869Sjfv	if (rx_desc->status & E1000_RXD_STAT_IPCS) {
3928205869Sjfv		/* Did it pass? */
3929205869Sjfv		if (!(rx_desc->errors & E1000_RXD_ERR_IPE)) {
3930205869Sjfv			/* IP Checksum Good */
3931205869Sjfv			mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
3932205869Sjfv			mp->m_pkthdr.csum_flags |= CSUM_IP_VALID;
3933205869Sjfv
3934205869Sjfv		} else {
3935205869Sjfv			mp->m_pkthdr.csum_flags = 0;
3936205869Sjfv		}
3937205869Sjfv	}
3938205869Sjfv
3939205869Sjfv	if (rx_desc->status & E1000_RXD_STAT_TCPCS) {
3940205869Sjfv		/* Did it pass? */
3941205869Sjfv		if (!(rx_desc->errors & E1000_RXD_ERR_TCPE)) {
3942205869Sjfv			mp->m_pkthdr.csum_flags |=
3943205869Sjfv			(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
3944205869Sjfv			mp->m_pkthdr.csum_data = htons(0xffff);
3945205869Sjfv		}
3946205869Sjfv	}
3947205869Sjfv}
3948205869Sjfv
3949205869Sjfv/*
3950205869Sjfv * This routine is run via an vlan
3951205869Sjfv * config EVENT
3952205869Sjfv */
3953205869Sjfvstatic void
3954205869Sjfvlem_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
3955205869Sjfv{
3956205869Sjfv	struct adapter	*adapter = ifp->if_softc;
3957205869Sjfv	u32		index, bit;
3958205869Sjfv
3959205869Sjfv	if (ifp->if_softc !=  arg)   /* Not our event */
3960205869Sjfv		return;
3961205869Sjfv
3962205869Sjfv	if ((vtag == 0) || (vtag > 4095))       /* Invalid ID */
3963205869Sjfv                return;
3964205869Sjfv
3965214646Sjfv	EM_CORE_LOCK(adapter);
3966205869Sjfv	index = (vtag >> 5) & 0x7F;
3967205869Sjfv	bit = vtag & 0x1F;
3968214646Sjfv	adapter->shadow_vfta[index] |= (1 << bit);
3969205869Sjfv	++adapter->num_vlans;
3970205869Sjfv	/* Re-init to load the changes */
3971214646Sjfv	if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
3972214646Sjfv		lem_init_locked(adapter);
3973214646Sjfv	EM_CORE_UNLOCK(adapter);
3974205869Sjfv}
3975205869Sjfv
3976205869Sjfv/*
3977205869Sjfv * This routine is run via an vlan
3978205869Sjfv * unconfig EVENT
3979205869Sjfv */
3980205869Sjfvstatic void
3981205869Sjfvlem_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
3982205869Sjfv{
3983205869Sjfv	struct adapter	*adapter = ifp->if_softc;
3984205869Sjfv	u32		index, bit;
3985205869Sjfv
3986205869Sjfv	if (ifp->if_softc !=  arg)
3987205869Sjfv		return;
3988205869Sjfv
3989205869Sjfv	if ((vtag == 0) || (vtag > 4095))       /* Invalid */
3990205869Sjfv                return;
3991205869Sjfv
3992214646Sjfv	EM_CORE_LOCK(adapter);
3993205869Sjfv	index = (vtag >> 5) & 0x7F;
3994205869Sjfv	bit = vtag & 0x1F;
3995214646Sjfv	adapter->shadow_vfta[index] &= ~(1 << bit);
3996205869Sjfv	--adapter->num_vlans;
3997205869Sjfv	/* Re-init to load the changes */
3998214646Sjfv	if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
3999214646Sjfv		lem_init_locked(adapter);
4000214646Sjfv	EM_CORE_UNLOCK(adapter);
4001205869Sjfv}
4002205869Sjfv
4003205869Sjfvstatic void
4004205869Sjfvlem_setup_vlan_hw_support(struct adapter *adapter)
4005205869Sjfv{
4006205869Sjfv	struct e1000_hw *hw = &adapter->hw;
4007205869Sjfv	u32             reg;
4008205869Sjfv
4009205869Sjfv	/*
4010205869Sjfv	** We get here thru init_locked, meaning
4011205869Sjfv	** a soft reset, this has already cleared
4012205869Sjfv	** the VFTA and other state, so if there
4013205869Sjfv	** have been no vlan's registered do nothing.
4014205869Sjfv	*/
4015205869Sjfv	if (adapter->num_vlans == 0)
4016205869Sjfv                return;
4017205869Sjfv
4018205869Sjfv	/*
4019205869Sjfv	** A soft reset zero's out the VFTA, so
4020205869Sjfv	** we need to repopulate it now.
4021205869Sjfv	*/
4022205869Sjfv	for (int i = 0; i < EM_VFTA_SIZE; i++)
4023214646Sjfv                if (adapter->shadow_vfta[i] != 0)
4024205869Sjfv			E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
4025214646Sjfv                            i, adapter->shadow_vfta[i]);
4026205869Sjfv
4027205869Sjfv	reg = E1000_READ_REG(hw, E1000_CTRL);
4028205869Sjfv	reg |= E1000_CTRL_VME;
4029205869Sjfv	E1000_WRITE_REG(hw, E1000_CTRL, reg);
4030205869Sjfv
4031205869Sjfv	/* Enable the Filter Table */
4032205869Sjfv	reg = E1000_READ_REG(hw, E1000_RCTL);
4033205869Sjfv	reg &= ~E1000_RCTL_CFIEN;
4034205869Sjfv	reg |= E1000_RCTL_VFE;
4035205869Sjfv	E1000_WRITE_REG(hw, E1000_RCTL, reg);
4036205869Sjfv}
4037205869Sjfv
4038205869Sjfvstatic void
4039205869Sjfvlem_enable_intr(struct adapter *adapter)
4040205869Sjfv{
4041205869Sjfv	struct e1000_hw *hw = &adapter->hw;
4042205869Sjfv	u32 ims_mask = IMS_ENABLE_MASK;
4043205869Sjfv
4044205869Sjfv	E1000_WRITE_REG(hw, E1000_IMS, ims_mask);
4045205869Sjfv}
4046205869Sjfv
4047205869Sjfvstatic void
4048205869Sjfvlem_disable_intr(struct adapter *adapter)
4049205869Sjfv{
4050205869Sjfv	struct e1000_hw *hw = &adapter->hw;
4051205869Sjfv
4052238953Sjfv	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
4053205869Sjfv}
4054205869Sjfv
4055205869Sjfv/*
4056205869Sjfv * Bit of a misnomer, what this really means is
4057205869Sjfv * to enable OS management of the system... aka
4058205869Sjfv * to disable special hardware management features
4059205869Sjfv */
4060205869Sjfvstatic void
4061205869Sjfvlem_init_manageability(struct adapter *adapter)
4062205869Sjfv{
4063205869Sjfv	/* A shared code workaround */
4064205869Sjfv	if (adapter->has_manage) {
4065205869Sjfv		int manc = E1000_READ_REG(&adapter->hw, E1000_MANC);
4066205869Sjfv		/* disable hardware interception of ARP */
4067205869Sjfv		manc &= ~(E1000_MANC_ARP_EN);
4068205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc);
4069205869Sjfv	}
4070205869Sjfv}
4071205869Sjfv
4072205869Sjfv/*
4073205869Sjfv * Give control back to hardware management
4074205869Sjfv * controller if there is one.
4075205869Sjfv */
4076205869Sjfvstatic void
4077205869Sjfvlem_release_manageability(struct adapter *adapter)
4078205869Sjfv{
4079205869Sjfv	if (adapter->has_manage) {
4080205869Sjfv		int manc = E1000_READ_REG(&adapter->hw, E1000_MANC);
4081205869Sjfv
4082205869Sjfv		/* re-enable hardware interception of ARP */
4083205869Sjfv		manc |= E1000_MANC_ARP_EN;
4084205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc);
4085205869Sjfv	}
4086205869Sjfv}
4087205869Sjfv
4088205869Sjfv/*
4089205869Sjfv * lem_get_hw_control sets the {CTRL_EXT|FWSM}:DRV_LOAD bit.
4090205869Sjfv * For ASF and Pass Through versions of f/w this means
4091205869Sjfv * that the driver is loaded. For AMT version type f/w
4092205869Sjfv * this means that the network i/f is open.
4093205869Sjfv */
4094205869Sjfvstatic void
4095205869Sjfvlem_get_hw_control(struct adapter *adapter)
4096205869Sjfv{
4097205869Sjfv	u32 ctrl_ext;
4098205869Sjfv
4099205869Sjfv	ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
4100205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT,
4101205869Sjfv	    ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
4102205869Sjfv	return;
4103205869Sjfv}
4104205869Sjfv
4105205869Sjfv/*
4106205869Sjfv * lem_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
4107205869Sjfv * For ASF and Pass Through versions of f/w this means that
4108205869Sjfv * the driver is no longer loaded. For AMT versions of the
4109205869Sjfv * f/w this means that the network i/f is closed.
4110205869Sjfv */
4111205869Sjfvstatic void
4112205869Sjfvlem_release_hw_control(struct adapter *adapter)
4113205869Sjfv{
4114205869Sjfv	u32 ctrl_ext;
4115205869Sjfv
4116205869Sjfv	if (!adapter->has_manage)
4117205869Sjfv		return;
4118205869Sjfv
4119205869Sjfv	ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
4120205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT,
4121205869Sjfv	    ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
4122205869Sjfv	return;
4123205869Sjfv}
4124205869Sjfv
4125205869Sjfvstatic int
4126205869Sjfvlem_is_valid_ether_addr(u8 *addr)
4127205869Sjfv{
4128205869Sjfv	char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
4129205869Sjfv
4130205869Sjfv	if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) {
4131205869Sjfv		return (FALSE);
4132205869Sjfv	}
4133205869Sjfv
4134205869Sjfv	return (TRUE);
4135205869Sjfv}
4136205869Sjfv
4137205869Sjfv/*
4138205869Sjfv** Parse the interface capabilities with regard
4139205869Sjfv** to both system management and wake-on-lan for
4140205869Sjfv** later use.
4141205869Sjfv*/
4142205869Sjfvstatic void
4143205869Sjfvlem_get_wakeup(device_t dev)
4144205869Sjfv{
4145205869Sjfv	struct adapter	*adapter = device_get_softc(dev);
4146205869Sjfv	u16		eeprom_data = 0, device_id, apme_mask;
4147205869Sjfv
4148205869Sjfv	adapter->has_manage = e1000_enable_mng_pass_thru(&adapter->hw);
4149205869Sjfv	apme_mask = EM_EEPROM_APME;
4150205869Sjfv
4151205869Sjfv	switch (adapter->hw.mac.type) {
4152205869Sjfv	case e1000_82542:
4153205869Sjfv	case e1000_82543:
4154205869Sjfv		break;
4155205869Sjfv	case e1000_82544:
4156205869Sjfv		e1000_read_nvm(&adapter->hw,
4157205869Sjfv		    NVM_INIT_CONTROL2_REG, 1, &eeprom_data);
4158205869Sjfv		apme_mask = EM_82544_APME;
4159205869Sjfv		break;
4160205869Sjfv	case e1000_82546:
4161205869Sjfv	case e1000_82546_rev_3:
4162205869Sjfv		if (adapter->hw.bus.func == 1) {
4163205869Sjfv			e1000_read_nvm(&adapter->hw,
4164205869Sjfv			    NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
4165205869Sjfv			break;
4166205869Sjfv		} else
4167205869Sjfv			e1000_read_nvm(&adapter->hw,
4168205869Sjfv			    NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
4169205869Sjfv		break;
4170205869Sjfv	default:
4171205869Sjfv		e1000_read_nvm(&adapter->hw,
4172205869Sjfv		    NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
4173205869Sjfv		break;
4174205869Sjfv	}
4175205869Sjfv	if (eeprom_data & apme_mask)
4176205869Sjfv		adapter->wol = (E1000_WUFC_MAG | E1000_WUFC_MC);
4177205869Sjfv	/*
4178205869Sjfv         * We have the eeprom settings, now apply the special cases
4179205869Sjfv         * where the eeprom may be wrong or the board won't support
4180205869Sjfv         * wake on lan on a particular port
4181205869Sjfv	 */
4182205869Sjfv	device_id = pci_get_device(dev);
4183205869Sjfv        switch (device_id) {
4184205869Sjfv	case E1000_DEV_ID_82546GB_PCIE:
4185205869Sjfv		adapter->wol = 0;
4186205869Sjfv		break;
4187205869Sjfv	case E1000_DEV_ID_82546EB_FIBER:
4188205869Sjfv	case E1000_DEV_ID_82546GB_FIBER:
4189205869Sjfv		/* Wake events only supported on port A for dual fiber
4190205869Sjfv		 * regardless of eeprom setting */
4191205869Sjfv		if (E1000_READ_REG(&adapter->hw, E1000_STATUS) &
4192205869Sjfv		    E1000_STATUS_FUNC_1)
4193205869Sjfv			adapter->wol = 0;
4194205869Sjfv		break;
4195205869Sjfv	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
4196205869Sjfv                /* if quad port adapter, disable WoL on all but port A */
4197205869Sjfv		if (global_quad_port_a != 0)
4198205869Sjfv			adapter->wol = 0;
4199205869Sjfv		/* Reset for multiple quad port adapters */
4200205869Sjfv		if (++global_quad_port_a == 4)
4201205869Sjfv			global_quad_port_a = 0;
4202205869Sjfv                break;
4203205869Sjfv	}
4204205869Sjfv	return;
4205205869Sjfv}
4206205869Sjfv
4207205869Sjfv
4208205869Sjfv/*
4209205869Sjfv * Enable PCI Wake On Lan capability
4210205869Sjfv */
4211206001Smariusstatic void
4212205869Sjfvlem_enable_wakeup(device_t dev)
4213205869Sjfv{
4214205869Sjfv	struct adapter	*adapter = device_get_softc(dev);
4215205869Sjfv	struct ifnet	*ifp = adapter->ifp;
4216205869Sjfv	u32		pmc, ctrl, ctrl_ext, rctl;
4217205869Sjfv	u16     	status;
4218205869Sjfv
4219219902Sjhb	if ((pci_find_cap(dev, PCIY_PMG, &pmc) != 0))
4220205869Sjfv		return;
4221205869Sjfv
4222205869Sjfv	/* Advertise the wakeup capability */
4223205869Sjfv	ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
4224205869Sjfv	ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
4225205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
4226205869Sjfv	E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
4227205869Sjfv
4228205869Sjfv	/* Keep the laser running on Fiber adapters */
4229205869Sjfv	if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
4230205869Sjfv	    adapter->hw.phy.media_type == e1000_media_type_internal_serdes) {
4231205869Sjfv		ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
4232205869Sjfv		ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
4233205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext);
4234205869Sjfv	}
4235205869Sjfv
4236205869Sjfv	/*
4237205869Sjfv	** Determine type of Wakeup: note that wol
4238205869Sjfv	** is set with all bits on by default.
4239205869Sjfv	*/
4240205869Sjfv	if ((ifp->if_capenable & IFCAP_WOL_MAGIC) == 0)
4241205869Sjfv		adapter->wol &= ~E1000_WUFC_MAG;
4242205869Sjfv
4243205869Sjfv	if ((ifp->if_capenable & IFCAP_WOL_MCAST) == 0)
4244205869Sjfv		adapter->wol &= ~E1000_WUFC_MC;
4245205869Sjfv	else {
4246205869Sjfv		rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
4247205869Sjfv		rctl |= E1000_RCTL_MPE;
4248205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
4249205869Sjfv	}
4250205869Sjfv
4251205869Sjfv	if (adapter->hw.mac.type == e1000_pchlan) {
4252205869Sjfv		if (lem_enable_phy_wakeup(adapter))
4253205869Sjfv			return;
4254205869Sjfv	} else {
4255205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
4256205869Sjfv		E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol);
4257205869Sjfv	}
4258205869Sjfv
4259205869Sjfv
4260205869Sjfv        /* Request PME */
4261205869Sjfv        status = pci_read_config(dev, pmc + PCIR_POWER_STATUS, 2);
4262205869Sjfv	status &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
4263205869Sjfv	if (ifp->if_capenable & IFCAP_WOL)
4264205869Sjfv		status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
4265205869Sjfv        pci_write_config(dev, pmc + PCIR_POWER_STATUS, status, 2);
4266205869Sjfv
4267205869Sjfv	return;
4268205869Sjfv}
4269205869Sjfv
4270205869Sjfv/*
4271205869Sjfv** WOL in the newer chipset interfaces (pchlan)
4272205869Sjfv** require thing to be copied into the phy
4273205869Sjfv*/
4274205869Sjfvstatic int
4275205869Sjfvlem_enable_phy_wakeup(struct adapter *adapter)
4276205869Sjfv{
4277205869Sjfv	struct e1000_hw *hw = &adapter->hw;
4278205869Sjfv	u32 mreg, ret = 0;
4279205869Sjfv	u16 preg;
4280205869Sjfv
4281205869Sjfv	/* copy MAC RARs to PHY RARs */
4282205869Sjfv	for (int i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
4283205869Sjfv		mreg = E1000_READ_REG(hw, E1000_RAL(i));
4284205869Sjfv		e1000_write_phy_reg(hw, BM_RAR_L(i), (u16)(mreg & 0xFFFF));
4285205869Sjfv		e1000_write_phy_reg(hw, BM_RAR_M(i),
4286205869Sjfv		    (u16)((mreg >> 16) & 0xFFFF));
4287205869Sjfv		mreg = E1000_READ_REG(hw, E1000_RAH(i));
4288205869Sjfv		e1000_write_phy_reg(hw, BM_RAR_H(i), (u16)(mreg & 0xFFFF));
4289205869Sjfv		e1000_write_phy_reg(hw, BM_RAR_CTRL(i),
4290205869Sjfv		    (u16)((mreg >> 16) & 0xFFFF));
4291205869Sjfv	}
4292205869Sjfv
4293205869Sjfv	/* copy MAC MTA to PHY MTA */
4294205869Sjfv	for (int i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
4295205869Sjfv		mreg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
4296205869Sjfv		e1000_write_phy_reg(hw, BM_MTA(i), (u16)(mreg & 0xFFFF));
4297205869Sjfv		e1000_write_phy_reg(hw, BM_MTA(i) + 1,
4298205869Sjfv		    (u16)((mreg >> 16) & 0xFFFF));
4299205869Sjfv	}
4300205869Sjfv
4301205869Sjfv	/* configure PHY Rx Control register */
4302205869Sjfv	e1000_read_phy_reg(&adapter->hw, BM_RCTL, &preg);
4303205869Sjfv	mreg = E1000_READ_REG(hw, E1000_RCTL);
4304205869Sjfv	if (mreg & E1000_RCTL_UPE)
4305205869Sjfv		preg |= BM_RCTL_UPE;
4306205869Sjfv	if (mreg & E1000_RCTL_MPE)
4307205869Sjfv		preg |= BM_RCTL_MPE;
4308205869Sjfv	preg &= ~(BM_RCTL_MO_MASK);
4309205869Sjfv	if (mreg & E1000_RCTL_MO_3)
4310205869Sjfv		preg |= (((mreg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
4311205869Sjfv				<< BM_RCTL_MO_SHIFT);
4312205869Sjfv	if (mreg & E1000_RCTL_BAM)
4313205869Sjfv		preg |= BM_RCTL_BAM;
4314205869Sjfv	if (mreg & E1000_RCTL_PMCF)
4315205869Sjfv		preg |= BM_RCTL_PMCF;
4316205869Sjfv	mreg = E1000_READ_REG(hw, E1000_CTRL);
4317205869Sjfv	if (mreg & E1000_CTRL_RFCE)
4318205869Sjfv		preg |= BM_RCTL_RFCE;
4319205869Sjfv	e1000_write_phy_reg(&adapter->hw, BM_RCTL, preg);
4320205869Sjfv
4321205869Sjfv	/* enable PHY wakeup in MAC register */
4322205869Sjfv	E1000_WRITE_REG(hw, E1000_WUC,
4323205869Sjfv	    E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
4324205869Sjfv	E1000_WRITE_REG(hw, E1000_WUFC, adapter->wol);
4325205869Sjfv
4326205869Sjfv	/* configure and enable PHY wakeup in PHY registers */
4327205869Sjfv	e1000_write_phy_reg(&adapter->hw, BM_WUFC, adapter->wol);
4328205869Sjfv	e1000_write_phy_reg(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
4329205869Sjfv
4330205869Sjfv	/* activate PHY wakeup */
4331205869Sjfv	ret = hw->phy.ops.acquire(hw);
4332205869Sjfv	if (ret) {
4333205869Sjfv		printf("Could not acquire PHY\n");
4334205869Sjfv		return ret;
4335205869Sjfv	}
4336205869Sjfv	e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
4337205869Sjfv	                         (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
4338205869Sjfv	ret = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &preg);
4339205869Sjfv	if (ret) {
4340205869Sjfv		printf("Could not read PHY page 769\n");
4341205869Sjfv		goto out;
4342205869Sjfv	}
4343205869Sjfv	preg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
4344205869Sjfv	ret = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, preg);
4345205869Sjfv	if (ret)
4346205869Sjfv		printf("Could not set PHY Host Wakeup bit\n");
4347205869Sjfvout:
4348205869Sjfv	hw->phy.ops.release(hw);
4349205869Sjfv
4350205869Sjfv	return ret;
4351205869Sjfv}
4352205869Sjfv
4353206001Smariusstatic void
4354206001Smariuslem_led_func(void *arg, int onoff)
4355206001Smarius{
4356206001Smarius	struct adapter	*adapter = arg;
4357205869Sjfv
4358206001Smarius	EM_CORE_LOCK(adapter);
4359206001Smarius	if (onoff) {
4360206001Smarius		e1000_setup_led(&adapter->hw);
4361206001Smarius		e1000_led_on(&adapter->hw);
4362206001Smarius	} else {
4363206001Smarius		e1000_led_off(&adapter->hw);
4364206001Smarius		e1000_cleanup_led(&adapter->hw);
4365206001Smarius	}
4366206001Smarius	EM_CORE_UNLOCK(adapter);
4367206001Smarius}
4368206001Smarius
4369205869Sjfv/*********************************************************************
4370205869Sjfv* 82544 Coexistence issue workaround.
4371205869Sjfv*    There are 2 issues.
4372205869Sjfv*       1. Transmit Hang issue.
4373205869Sjfv*    To detect this issue, following equation can be used...
4374205869Sjfv*	  SIZE[3:0] + ADDR[2:0] = SUM[3:0].
4375205869Sjfv*	  If SUM[3:0] is in between 1 to 4, we will have this issue.
4376205869Sjfv*
4377205869Sjfv*       2. DAC issue.
4378205869Sjfv*    To detect this issue, following equation can be used...
4379205869Sjfv*	  SIZE[3:0] + ADDR[2:0] = SUM[3:0].
4380205869Sjfv*	  If SUM[3:0] is in between 9 to c, we will have this issue.
4381205869Sjfv*
4382205869Sjfv*
4383205869Sjfv*    WORKAROUND:
4384205869Sjfv*	  Make sure we do not have ending address
4385205869Sjfv*	  as 1,2,3,4(Hang) or 9,a,b,c (DAC)
4386205869Sjfv*
4387205869Sjfv*************************************************************************/
4388205869Sjfvstatic u32
4389205869Sjfvlem_fill_descriptors (bus_addr_t address, u32 length,
4390205869Sjfv		PDESC_ARRAY desc_array)
4391205869Sjfv{
4392205869Sjfv	u32 safe_terminator;
4393205869Sjfv
4394205869Sjfv	/* Since issue is sensitive to length and address.*/
4395205869Sjfv	/* Let us first check the address...*/
4396205869Sjfv	if (length <= 4) {
4397205869Sjfv		desc_array->descriptor[0].address = address;
4398205869Sjfv		desc_array->descriptor[0].length = length;
4399205869Sjfv		desc_array->elements = 1;
4400205869Sjfv		return (desc_array->elements);
4401205869Sjfv	}
4402205869Sjfv	safe_terminator = (u32)((((u32)address & 0x7) +
4403205869Sjfv	    (length & 0xF)) & 0xF);
4404205869Sjfv	/* if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then return */
4405205869Sjfv	if (safe_terminator == 0   ||
4406205869Sjfv	(safe_terminator > 4   &&
4407205869Sjfv	safe_terminator < 9)   ||
4408205869Sjfv	(safe_terminator > 0xC &&
4409205869Sjfv	safe_terminator <= 0xF)) {
4410205869Sjfv		desc_array->descriptor[0].address = address;
4411205869Sjfv		desc_array->descriptor[0].length = length;
4412205869Sjfv		desc_array->elements = 1;
4413205869Sjfv		return (desc_array->elements);
4414205869Sjfv	}
4415205869Sjfv
4416205869Sjfv	desc_array->descriptor[0].address = address;
4417205869Sjfv	desc_array->descriptor[0].length = length - 4;
4418205869Sjfv	desc_array->descriptor[1].address = address + (length - 4);
4419205869Sjfv	desc_array->descriptor[1].length = 4;
4420205869Sjfv	desc_array->elements = 2;
4421205869Sjfv	return (desc_array->elements);
4422205869Sjfv}
4423205869Sjfv
4424205869Sjfv/**********************************************************************
4425205869Sjfv *
4426205869Sjfv *  Update the board statistics counters.
4427205869Sjfv *
4428205869Sjfv **********************************************************************/
4429205869Sjfvstatic void
4430205869Sjfvlem_update_stats_counters(struct adapter *adapter)
4431205869Sjfv{
4432205869Sjfv	struct ifnet   *ifp;
4433205869Sjfv
4434205869Sjfv	if(adapter->hw.phy.media_type == e1000_media_type_copper ||
4435205869Sjfv	   (E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) {
4436205869Sjfv		adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
4437205869Sjfv		adapter->stats.sec += E1000_READ_REG(&adapter->hw, E1000_SEC);
4438205869Sjfv	}
4439205869Sjfv	adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, E1000_CRCERRS);
4440205869Sjfv	adapter->stats.mpc += E1000_READ_REG(&adapter->hw, E1000_MPC);
4441205869Sjfv	adapter->stats.scc += E1000_READ_REG(&adapter->hw, E1000_SCC);
4442205869Sjfv	adapter->stats.ecol += E1000_READ_REG(&adapter->hw, E1000_ECOL);
4443205869Sjfv
4444205869Sjfv	adapter->stats.mcc += E1000_READ_REG(&adapter->hw, E1000_MCC);
4445205869Sjfv	adapter->stats.latecol += E1000_READ_REG(&adapter->hw, E1000_LATECOL);
4446205869Sjfv	adapter->stats.colc += E1000_READ_REG(&adapter->hw, E1000_COLC);
4447205869Sjfv	adapter->stats.dc += E1000_READ_REG(&adapter->hw, E1000_DC);
4448205869Sjfv	adapter->stats.rlec += E1000_READ_REG(&adapter->hw, E1000_RLEC);
4449205869Sjfv	adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, E1000_XONRXC);
4450205869Sjfv	adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, E1000_XONTXC);
4451205869Sjfv	adapter->stats.xoffrxc += E1000_READ_REG(&adapter->hw, E1000_XOFFRXC);
4452205869Sjfv	adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, E1000_XOFFTXC);
4453205869Sjfv	adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, E1000_FCRUC);
4454205869Sjfv	adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, E1000_PRC64);
4455205869Sjfv	adapter->stats.prc127 += E1000_READ_REG(&adapter->hw, E1000_PRC127);
4456205869Sjfv	adapter->stats.prc255 += E1000_READ_REG(&adapter->hw, E1000_PRC255);
4457205869Sjfv	adapter->stats.prc511 += E1000_READ_REG(&adapter->hw, E1000_PRC511);
4458205869Sjfv	adapter->stats.prc1023 += E1000_READ_REG(&adapter->hw, E1000_PRC1023);
4459205869Sjfv	adapter->stats.prc1522 += E1000_READ_REG(&adapter->hw, E1000_PRC1522);
4460205869Sjfv	adapter->stats.gprc += E1000_READ_REG(&adapter->hw, E1000_GPRC);
4461205869Sjfv	adapter->stats.bprc += E1000_READ_REG(&adapter->hw, E1000_BPRC);
4462205869Sjfv	adapter->stats.mprc += E1000_READ_REG(&adapter->hw, E1000_MPRC);
4463205869Sjfv	adapter->stats.gptc += E1000_READ_REG(&adapter->hw, E1000_GPTC);
4464205869Sjfv
4465205869Sjfv	/* For the 64-bit byte counters the low dword must be read first. */
4466205869Sjfv	/* Both registers clear on the read of the high dword */
4467205869Sjfv
4468212902Sjhb	adapter->stats.gorc += E1000_READ_REG(&adapter->hw, E1000_GORCL) +
4469212902Sjhb	    ((u64)E1000_READ_REG(&adapter->hw, E1000_GORCH) << 32);
4470212902Sjhb	adapter->stats.gotc += E1000_READ_REG(&adapter->hw, E1000_GOTCL) +
4471212902Sjhb	    ((u64)E1000_READ_REG(&adapter->hw, E1000_GOTCH) << 32);
4472205869Sjfv
4473205869Sjfv	adapter->stats.rnbc += E1000_READ_REG(&adapter->hw, E1000_RNBC);
4474205869Sjfv	adapter->stats.ruc += E1000_READ_REG(&adapter->hw, E1000_RUC);
4475205869Sjfv	adapter->stats.rfc += E1000_READ_REG(&adapter->hw, E1000_RFC);
4476205869Sjfv	adapter->stats.roc += E1000_READ_REG(&adapter->hw, E1000_ROC);
4477205869Sjfv	adapter->stats.rjc += E1000_READ_REG(&adapter->hw, E1000_RJC);
4478205869Sjfv
4479205869Sjfv	adapter->stats.tor += E1000_READ_REG(&adapter->hw, E1000_TORH);
4480205869Sjfv	adapter->stats.tot += E1000_READ_REG(&adapter->hw, E1000_TOTH);
4481205869Sjfv
4482205869Sjfv	adapter->stats.tpr += E1000_READ_REG(&adapter->hw, E1000_TPR);
4483205869Sjfv	adapter->stats.tpt += E1000_READ_REG(&adapter->hw, E1000_TPT);
4484205869Sjfv	adapter->stats.ptc64 += E1000_READ_REG(&adapter->hw, E1000_PTC64);
4485205869Sjfv	adapter->stats.ptc127 += E1000_READ_REG(&adapter->hw, E1000_PTC127);
4486205869Sjfv	adapter->stats.ptc255 += E1000_READ_REG(&adapter->hw, E1000_PTC255);
4487205869Sjfv	adapter->stats.ptc511 += E1000_READ_REG(&adapter->hw, E1000_PTC511);
4488205869Sjfv	adapter->stats.ptc1023 += E1000_READ_REG(&adapter->hw, E1000_PTC1023);
4489205869Sjfv	adapter->stats.ptc1522 += E1000_READ_REG(&adapter->hw, E1000_PTC1522);
4490205869Sjfv	adapter->stats.mptc += E1000_READ_REG(&adapter->hw, E1000_MPTC);
4491205869Sjfv	adapter->stats.bptc += E1000_READ_REG(&adapter->hw, E1000_BPTC);
4492205869Sjfv
4493205869Sjfv	if (adapter->hw.mac.type >= e1000_82543) {
4494205869Sjfv		adapter->stats.algnerrc +=
4495205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_ALGNERRC);
4496205869Sjfv		adapter->stats.rxerrc +=
4497205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_RXERRC);
4498205869Sjfv		adapter->stats.tncrs +=
4499205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_TNCRS);
4500205869Sjfv		adapter->stats.cexterr +=
4501205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_CEXTERR);
4502205869Sjfv		adapter->stats.tsctc +=
4503205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_TSCTC);
4504205869Sjfv		adapter->stats.tsctfc +=
4505205869Sjfv		E1000_READ_REG(&adapter->hw, E1000_TSCTFC);
4506205869Sjfv	}
4507205869Sjfv	ifp = adapter->ifp;
4508205869Sjfv
4509205869Sjfv	ifp->if_collisions = adapter->stats.colc;
4510205869Sjfv
4511205869Sjfv	/* Rx Errors */
4512205869Sjfv	ifp->if_ierrors = adapter->dropped_pkts + adapter->stats.rxerrc +
4513205869Sjfv	    adapter->stats.crcerrs + adapter->stats.algnerrc +
4514205869Sjfv	    adapter->stats.ruc + adapter->stats.roc +
4515205869Sjfv	    adapter->stats.mpc + adapter->stats.cexterr;
4516205869Sjfv
4517205869Sjfv	/* Tx Errors */
4518205869Sjfv	ifp->if_oerrors = adapter->stats.ecol +
4519205869Sjfv	    adapter->stats.latecol + adapter->watchdog_events;
4520205869Sjfv}
4521205869Sjfv
4522212902Sjhb/* Export a single 32-bit register via a read-only sysctl. */
4523212902Sjhbstatic int
4524212902Sjhblem_sysctl_reg_handler(SYSCTL_HANDLER_ARGS)
4525205869Sjfv{
4526212902Sjhb	struct adapter *adapter;
4527212902Sjhb	u_int val;
4528205869Sjfv
4529212902Sjhb	adapter = oidp->oid_arg1;
4530212902Sjhb	val = E1000_READ_REG(&adapter->hw, oidp->oid_arg2);
4531212902Sjhb	return (sysctl_handle_int(oidp, &val, 0, req));
4532205869Sjfv}
4533205869Sjfv
4534212902Sjhb/*
4535212902Sjhb * Add sysctl variables, one per statistic, to the system.
4536212902Sjhb */
4537205869Sjfvstatic void
4538212902Sjhblem_add_hw_stats(struct adapter *adapter)
4539205869Sjfv{
4540205869Sjfv	device_t dev = adapter->dev;
4541205869Sjfv
4542212902Sjhb	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
4543212902Sjhb	struct sysctl_oid *tree = device_get_sysctl_tree(dev);
4544212902Sjhb	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
4545212902Sjhb	struct e1000_hw_stats *stats = &adapter->stats;
4546212902Sjhb
4547212902Sjhb	struct sysctl_oid *stat_node;
4548212902Sjhb	struct sysctl_oid_list *stat_list;
4549212902Sjhb
4550212902Sjhb	/* Driver Statistics */
4551212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_alloc_fail",
4552212902Sjhb			 CTLFLAG_RD, &adapter->mbuf_alloc_failed,
4553212902Sjhb			 "Std mbuf failed");
4554212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "cluster_alloc_fail",
4555212902Sjhb			 CTLFLAG_RD, &adapter->mbuf_cluster_failed,
4556212902Sjhb			 "Std mbuf cluster failed");
4557212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped",
4558212902Sjhb			CTLFLAG_RD, &adapter->dropped_pkts,
4559212902Sjhb			"Driver dropped packets");
4560212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_dma_fail",
4561212902Sjhb			CTLFLAG_RD, &adapter->no_tx_dma_setup,
4562212902Sjhb			"Driver tx dma failure in xmit");
4563212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_desc_fail1",
4564212902Sjhb			CTLFLAG_RD, &adapter->no_tx_desc_avail1,
4565212902Sjhb			"Not enough tx descriptors failure in xmit");
4566212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_desc_fail2",
4567212902Sjhb			CTLFLAG_RD, &adapter->no_tx_desc_avail2,
4568212902Sjhb			"Not enough tx descriptors failure in xmit");
4569212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "rx_overruns",
4570212902Sjhb			CTLFLAG_RD, &adapter->rx_overruns,
4571212902Sjhb			"RX overruns");
4572212902Sjhb	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "watchdog_timeouts",
4573212902Sjhb			CTLFLAG_RD, &adapter->watchdog_events,
4574212902Sjhb			"Watchdog timeouts");
4575212902Sjhb
4576212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "device_control",
4577217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_CTRL,
4578212902Sjhb			lem_sysctl_reg_handler, "IU",
4579212902Sjhb			"Device Control Register");
4580212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_control",
4581217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RCTL,
4582212902Sjhb			lem_sysctl_reg_handler, "IU",
4583212902Sjhb			"Receiver Control Register");
4584212902Sjhb	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_high_water",
4585212902Sjhb			CTLFLAG_RD, &adapter->hw.fc.high_water, 0,
4586212902Sjhb			"Flow Control High Watermark");
4587212902Sjhb	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_low_water",
4588212902Sjhb			CTLFLAG_RD, &adapter->hw.fc.low_water, 0,
4589212902Sjhb			"Flow Control Low Watermark");
4590217318Smdf	SYSCTL_ADD_UQUAD(ctx, child, OID_AUTO, "fifo_workaround",
4591212902Sjhb			CTLFLAG_RD, &adapter->tx_fifo_wrk_cnt,
4592212902Sjhb			"TX FIFO workaround events");
4593217318Smdf	SYSCTL_ADD_UQUAD(ctx, child, OID_AUTO, "fifo_reset",
4594212902Sjhb			CTLFLAG_RD, &adapter->tx_fifo_reset_cnt,
4595212902Sjhb			"TX FIFO resets");
4596212902Sjhb
4597212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "txd_head",
4598217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_TDH(0),
4599212902Sjhb			lem_sysctl_reg_handler, "IU",
4600212902Sjhb 			"Transmit Descriptor Head");
4601212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "txd_tail",
4602217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_TDT(0),
4603212902Sjhb			lem_sysctl_reg_handler, "IU",
4604212902Sjhb 			"Transmit Descriptor Tail");
4605212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rxd_head",
4606217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RDH(0),
4607212902Sjhb			lem_sysctl_reg_handler, "IU",
4608212902Sjhb			"Receive Descriptor Head");
4609212902Sjhb	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rxd_tail",
4610217556Smdf			CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RDT(0),
4611212902Sjhb			lem_sysctl_reg_handler, "IU",
4612212902Sjhb			"Receive Descriptor Tail");
4613212902Sjhb
4614212902Sjhb
4615212902Sjhb	/* MAC stats get their own sub node */
4616212902Sjhb
4617212902Sjhb	stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac_stats",
4618212902Sjhb				    CTLFLAG_RD, NULL, "Statistics");
4619212902Sjhb	stat_list = SYSCTL_CHILDREN(stat_node);
4620212902Sjhb
4621217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "excess_coll",
4622212902Sjhb			CTLFLAG_RD, &stats->ecol,
4623212902Sjhb			"Excessive collisions");
4624217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "single_coll",
4625212902Sjhb			CTLFLAG_RD, &stats->scc,
4626212902Sjhb			"Single collisions");
4627217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "multiple_coll",
4628212902Sjhb			CTLFLAG_RD, &stats->mcc,
4629212902Sjhb			"Multiple collisions");
4630217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "late_coll",
4631212902Sjhb			CTLFLAG_RD, &stats->latecol,
4632212902Sjhb			"Late collisions");
4633217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "collision_count",
4634212902Sjhb			CTLFLAG_RD, &stats->colc,
4635212902Sjhb			"Collision Count");
4636217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "symbol_errors",
4637212902Sjhb			CTLFLAG_RD, &adapter->stats.symerrs,
4638212902Sjhb			"Symbol Errors");
4639217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "sequence_errors",
4640212902Sjhb			CTLFLAG_RD, &adapter->stats.sec,
4641212902Sjhb			"Sequence Errors");
4642217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "defer_count",
4643212902Sjhb			CTLFLAG_RD, &adapter->stats.dc,
4644212902Sjhb			"Defer Count");
4645217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "missed_packets",
4646212902Sjhb			CTLFLAG_RD, &adapter->stats.mpc,
4647212902Sjhb			"Missed Packets");
4648217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_no_buff",
4649212902Sjhb			CTLFLAG_RD, &adapter->stats.rnbc,
4650212902Sjhb			"Receive No Buffers");
4651217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_undersize",
4652212902Sjhb			CTLFLAG_RD, &adapter->stats.ruc,
4653212902Sjhb			"Receive Undersize");
4654217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_fragmented",
4655212902Sjhb			CTLFLAG_RD, &adapter->stats.rfc,
4656212902Sjhb			"Fragmented Packets Received ");
4657217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_oversize",
4658212902Sjhb			CTLFLAG_RD, &adapter->stats.roc,
4659212902Sjhb			"Oversized Packets Received");
4660217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_jabber",
4661212902Sjhb			CTLFLAG_RD, &adapter->stats.rjc,
4662212902Sjhb			"Recevied Jabber");
4663217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_errs",
4664212902Sjhb			CTLFLAG_RD, &adapter->stats.rxerrc,
4665212902Sjhb			"Receive Errors");
4666217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "crc_errs",
4667212902Sjhb			CTLFLAG_RD, &adapter->stats.crcerrs,
4668212902Sjhb			"CRC errors");
4669217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "alignment_errs",
4670212902Sjhb			CTLFLAG_RD, &adapter->stats.algnerrc,
4671212902Sjhb			"Alignment Errors");
4672217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "coll_ext_errs",
4673212902Sjhb			CTLFLAG_RD, &adapter->stats.cexterr,
4674212902Sjhb			"Collision/Carrier extension errors");
4675217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xon_recvd",
4676212902Sjhb			CTLFLAG_RD, &adapter->stats.xonrxc,
4677212902Sjhb			"XON Received");
4678217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xon_txd",
4679212902Sjhb			CTLFLAG_RD, &adapter->stats.xontxc,
4680212902Sjhb			"XON Transmitted");
4681217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xoff_recvd",
4682212902Sjhb			CTLFLAG_RD, &adapter->stats.xoffrxc,
4683212902Sjhb			"XOFF Received");
4684217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xoff_txd",
4685212902Sjhb			CTLFLAG_RD, &adapter->stats.xofftxc,
4686212902Sjhb			"XOFF Transmitted");
4687212902Sjhb
4688212902Sjhb	/* Packet Reception Stats */
4689217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_pkts_recvd",
4690212902Sjhb			CTLFLAG_RD, &adapter->stats.tpr,
4691212902Sjhb			"Total Packets Received ");
4692217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_recvd",
4693212902Sjhb			CTLFLAG_RD, &adapter->stats.gprc,
4694212902Sjhb			"Good Packets Received");
4695217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_recvd",
4696212902Sjhb			CTLFLAG_RD, &adapter->stats.bprc,
4697212902Sjhb			"Broadcast Packets Received");
4698217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_recvd",
4699212902Sjhb			CTLFLAG_RD, &adapter->stats.mprc,
4700212902Sjhb			"Multicast Packets Received");
4701217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_64",
4702212902Sjhb			CTLFLAG_RD, &adapter->stats.prc64,
4703212902Sjhb			"64 byte frames received ");
4704217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_65_127",
4705212902Sjhb			CTLFLAG_RD, &adapter->stats.prc127,
4706212902Sjhb			"65-127 byte frames received");
4707217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_128_255",
4708212902Sjhb			CTLFLAG_RD, &adapter->stats.prc255,
4709212902Sjhb			"128-255 byte frames received");
4710217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_256_511",
4711212902Sjhb			CTLFLAG_RD, &adapter->stats.prc511,
4712212902Sjhb			"256-511 byte frames received");
4713217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_512_1023",
4714212902Sjhb			CTLFLAG_RD, &adapter->stats.prc1023,
4715212902Sjhb			"512-1023 byte frames received");
4716217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_1024_1522",
4717212902Sjhb			CTLFLAG_RD, &adapter->stats.prc1522,
4718212902Sjhb			"1023-1522 byte frames received");
4719217318Smdf 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_recvd",
4720212902Sjhb 			CTLFLAG_RD, &adapter->stats.gorc,
4721212902Sjhb 			"Good Octets Received");
4722212902Sjhb
4723212902Sjhb	/* Packet Transmission Stats */
4724217318Smdf 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd",
4725212902Sjhb 			CTLFLAG_RD, &adapter->stats.gotc,
4726212902Sjhb 			"Good Octets Transmitted");
4727217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_pkts_txd",
4728212902Sjhb			CTLFLAG_RD, &adapter->stats.tpt,
4729212902Sjhb			"Total Packets Transmitted");
4730217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd",
4731212902Sjhb			CTLFLAG_RD, &adapter->stats.gptc,
4732212902Sjhb			"Good Packets Transmitted");
4733217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_txd",
4734212902Sjhb			CTLFLAG_RD, &adapter->stats.bptc,
4735212902Sjhb			"Broadcast Packets Transmitted");
4736217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_txd",
4737212902Sjhb			CTLFLAG_RD, &adapter->stats.mptc,
4738212902Sjhb			"Multicast Packets Transmitted");
4739217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_64",
4740212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc64,
4741212902Sjhb			"64 byte frames transmitted ");
4742217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_65_127",
4743212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc127,
4744212902Sjhb			"65-127 byte frames transmitted");
4745217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_128_255",
4746212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc255,
4747212902Sjhb			"128-255 byte frames transmitted");
4748217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_256_511",
4749212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc511,
4750212902Sjhb			"256-511 byte frames transmitted");
4751217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_512_1023",
4752212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc1023,
4753212902Sjhb			"512-1023 byte frames transmitted");
4754217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_1024_1522",
4755212902Sjhb			CTLFLAG_RD, &adapter->stats.ptc1522,
4756212902Sjhb			"1024-1522 byte frames transmitted");
4757217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tso_txd",
4758212902Sjhb			CTLFLAG_RD, &adapter->stats.tsctc,
4759212902Sjhb			"TSO Contexts Transmitted");
4760217318Smdf	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tso_ctx_fail",
4761212902Sjhb			CTLFLAG_RD, &adapter->stats.tsctfc,
4762212902Sjhb			"TSO Contexts Failed");
4763205869Sjfv}
4764205869Sjfv
4765205869Sjfv/**********************************************************************
4766205869Sjfv *
4767205869Sjfv *  This routine provides a way to dump out the adapter eeprom,
4768205869Sjfv *  often a useful debug/service tool. This only dumps the first
4769205869Sjfv *  32 words, stuff that matters is in that extent.
4770205869Sjfv *
4771205869Sjfv **********************************************************************/
4772205869Sjfv
4773205869Sjfvstatic int
4774212902Sjhblem_sysctl_nvm_info(SYSCTL_HANDLER_ARGS)
4775205869Sjfv{
4776205869Sjfv	struct adapter *adapter;
4777205869Sjfv	int error;
4778205869Sjfv	int result;
4779205869Sjfv
4780205869Sjfv	result = -1;
4781205869Sjfv	error = sysctl_handle_int(oidp, &result, 0, req);
4782205869Sjfv
4783205869Sjfv	if (error || !req->newptr)
4784205869Sjfv		return (error);
4785205869Sjfv
4786205869Sjfv	/*
4787205869Sjfv	 * This value will cause a hex dump of the
4788205869Sjfv	 * first 32 16-bit words of the EEPROM to
4789205869Sjfv	 * the screen.
4790205869Sjfv	 */
4791212902Sjhb	if (result == 1) {
4792205869Sjfv		adapter = (struct adapter *)arg1;
4793205869Sjfv		lem_print_nvm_info(adapter);
4794205869Sjfv        }
4795205869Sjfv
4796205869Sjfv	return (error);
4797205869Sjfv}
4798205869Sjfv
4799212902Sjhbstatic void
4800212902Sjhblem_print_nvm_info(struct adapter *adapter)
4801205869Sjfv{
4802212902Sjhb	u16	eeprom_data;
4803212902Sjhb	int	i, j, row = 0;
4804205869Sjfv
4805212902Sjhb	/* Its a bit crude, but it gets the job done */
4806212902Sjhb	printf("\nInterface EEPROM Dump:\n");
4807212902Sjhb	printf("Offset\n0x0000  ");
4808212902Sjhb	for (i = 0, j = 0; i < 32; i++, j++) {
4809212902Sjhb		if (j == 8) { /* Make the offset block */
4810212902Sjhb			j = 0; ++row;
4811212902Sjhb			printf("\n0x00%x0  ",row);
4812212902Sjhb		}
4813212902Sjhb		e1000_read_nvm(&adapter->hw, i, 1, &eeprom_data);
4814212902Sjhb		printf("%04x ", eeprom_data);
4815205869Sjfv	}
4816212902Sjhb	printf("\n");
4817205869Sjfv}
4818205869Sjfv
4819205869Sjfvstatic int
4820205869Sjfvlem_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
4821205869Sjfv{
4822205869Sjfv	struct em_int_delay_info *info;
4823205869Sjfv	struct adapter *adapter;
4824205869Sjfv	u32 regval;
4825205869Sjfv	int error;
4826205869Sjfv	int usecs;
4827205869Sjfv	int ticks;
4828205869Sjfv
4829205869Sjfv	info = (struct em_int_delay_info *)arg1;
4830205869Sjfv	usecs = info->value;
4831205869Sjfv	error = sysctl_handle_int(oidp, &usecs, 0, req);
4832205869Sjfv	if (error != 0 || req->newptr == NULL)
4833205869Sjfv		return (error);
4834205869Sjfv	if (usecs < 0 || usecs > EM_TICKS_TO_USECS(65535))
4835205869Sjfv		return (EINVAL);
4836205869Sjfv	info->value = usecs;
4837205869Sjfv	ticks = EM_USECS_TO_TICKS(usecs);
4838250414Sluigi	if (info->offset == E1000_ITR)	/* units are 256ns here */
4839250414Sluigi		ticks *= 4;
4840205869Sjfv
4841205869Sjfv	adapter = info->adapter;
4842205869Sjfv
4843205869Sjfv	EM_CORE_LOCK(adapter);
4844205869Sjfv	regval = E1000_READ_OFFSET(&adapter->hw, info->offset);
4845205869Sjfv	regval = (regval & ~0xffff) | (ticks & 0xffff);
4846205869Sjfv	/* Handle a few special cases. */
4847205869Sjfv	switch (info->offset) {
4848205869Sjfv	case E1000_RDTR:
4849205869Sjfv		break;
4850205869Sjfv	case E1000_TIDV:
4851205869Sjfv		if (ticks == 0) {
4852205869Sjfv			adapter->txd_cmd &= ~E1000_TXD_CMD_IDE;
4853205869Sjfv			/* Don't write 0 into the TIDV register. */
4854205869Sjfv			regval++;
4855205869Sjfv		} else
4856205869Sjfv			adapter->txd_cmd |= E1000_TXD_CMD_IDE;
4857205869Sjfv		break;
4858205869Sjfv	}
4859205869Sjfv	E1000_WRITE_OFFSET(&adapter->hw, info->offset, regval);
4860205869Sjfv	EM_CORE_UNLOCK(adapter);
4861205869Sjfv	return (0);
4862205869Sjfv}
4863205869Sjfv
4864205869Sjfvstatic void
4865205869Sjfvlem_add_int_delay_sysctl(struct adapter *adapter, const char *name,
4866205869Sjfv	const char *description, struct em_int_delay_info *info,
4867205869Sjfv	int offset, int value)
4868205869Sjfv{
4869205869Sjfv	info->adapter = adapter;
4870205869Sjfv	info->offset = offset;
4871205869Sjfv	info->value = value;
4872205869Sjfv	SYSCTL_ADD_PROC(device_get_sysctl_ctx(adapter->dev),
4873205869Sjfv	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
4874205869Sjfv	    OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW,
4875205869Sjfv	    info, 0, lem_sysctl_int_delay, "I", description);
4876205869Sjfv}
4877205869Sjfv
4878214646Sjfvstatic void
4879214646Sjfvlem_set_flow_cntrl(struct adapter *adapter, const char *name,
4880214646Sjfv        const char *description, int *limit, int value)
4881214646Sjfv{
4882214646Sjfv	*limit = value;
4883214646Sjfv	SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
4884214646Sjfv	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
4885214646Sjfv	    OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
4886214646Sjfv}
4887214646Sjfv
4888205869Sjfvstatic void
4889205869Sjfvlem_add_rx_process_limit(struct adapter *adapter, const char *name,
4890205869Sjfv	const char *description, int *limit, int value)
4891205869Sjfv{
4892205869Sjfv	*limit = value;
4893205869Sjfv	SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
4894205869Sjfv	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
4895205869Sjfv	    OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
4896205869Sjfv}
4897