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