if_ixgb.c revision 211907
1139749Simp/*******************************************************************************
2129794Stackerman
3129794StackermanCopyright (c) 2001-2004, Intel Corporation
4129794StackermanAll rights reserved.
5129794Stackerman
6129794StackermanRedistribution and use in source and binary forms, with or without
7129794Stackermanmodification, are permitted provided that the following conditions are met:
8129794Stackerman
9129794Stackerman 1. Redistributions of source code must retain the above copyright notice,
10129794Stackerman    this list of conditions and the following disclaimer.
11129794Stackerman
12129794Stackerman 2. Redistributions in binary form must reproduce the above copyright
13129794Stackerman    notice, this list of conditions and the following disclaimer in the
14129794Stackerman    documentation and/or other materials provided with the distribution.
15129794Stackerman
16129794Stackerman 3. Neither the name of the Intel Corporation nor the names of its
17129794Stackerman    contributors may be used to endorse or promote products derived from
18129794Stackerman    this software without specific prior written permission.
19129794Stackerman
20129794StackermanTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21129794StackermanAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22129794StackermanIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23129794StackermanARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24129794StackermanLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25129794StackermanCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26129794StackermanSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27129794StackermanINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28129794StackermanCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29129794StackermanARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30129794StackermanPOSSIBILITY OF SUCH DAMAGE.
31129794Stackerman
32129794Stackerman***************************************************************************/
33129794Stackerman
34129794Stackerman/*$FreeBSD: head/sys/dev/ixgb/if_ixgb.c 211907 2010-08-28 00:09:19Z yongari $*/
35129794Stackerman
36150968Sglebius#ifdef HAVE_KERNEL_OPTION_HEADERS
37150968Sglebius#include "opt_device_polling.h"
38150968Sglebius#endif
39150968Sglebius
40129794Stackerman#include <dev/ixgb/if_ixgb.h>
41129794Stackerman
42129794Stackerman/*********************************************************************
43129794Stackerman *  Set this to one to display debug statistics
44129794Stackerman *********************************************************************/
45129794Stackermanint             ixgb_display_debug_stats = 0;
46129794Stackerman
47129794Stackerman/*********************************************************************
48129794Stackerman *  Linked list of board private structures for all NICs found
49129794Stackerman *********************************************************************/
50129794Stackerman
51129794Stackermanstruct adapter *ixgb_adapter_list = NULL;
52129794Stackerman
53129794Stackerman
54129794Stackerman
55129794Stackerman/*********************************************************************
56129794Stackerman *  Driver version
57129794Stackerman *********************************************************************/
58129794Stackerman
59129794Stackermanchar            ixgb_driver_version[] = "1.0.6";
60129794Stackermanchar            ixgb_copyright[] = "Copyright (c) 2001-2004 Intel Corporation.";
61129794Stackerman
62129794Stackerman/*********************************************************************
63129794Stackerman *  PCI Device ID Table
64129794Stackerman *
65129794Stackerman *  Used by probe to select devices to load on
66129794Stackerman *  Last field stores an index into ixgb_strings
67129794Stackerman *  Last entry must be all 0s
68129794Stackerman *
69129794Stackerman *  { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
70129794Stackerman *********************************************************************/
71129794Stackerman
72129794Stackermanstatic ixgb_vendor_info_t ixgb_vendor_info_array[] =
73129794Stackerman{
74129794Stackerman	/* Intel(R) PRO/10000 Network Connection */
75129794Stackerman	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX, PCI_ANY_ID, PCI_ANY_ID, 0},
76129794Stackerman	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_SR, PCI_ANY_ID, PCI_ANY_ID, 0},
77129794Stackerman	/* required last entry */
78129794Stackerman	{0, 0, 0, 0, 0}
79129794Stackerman};
80129794Stackerman
81129794Stackerman/*********************************************************************
82129794Stackerman *  Table of branding strings for all supported NICs.
83129794Stackerman *********************************************************************/
84129794Stackerman
85129794Stackermanstatic char    *ixgb_strings[] = {
86129794Stackerman	"Intel(R) PRO/10GbE Network Driver"
87129794Stackerman};
88129794Stackerman
89129794Stackerman/*********************************************************************
90129794Stackerman *  Function prototypes
91129794Stackerman *********************************************************************/
92129794Stackermanstatic int      ixgb_probe(device_t);
93129794Stackermanstatic int      ixgb_attach(device_t);
94129794Stackermanstatic int      ixgb_detach(device_t);
95129794Stackermanstatic int      ixgb_shutdown(device_t);
96129794Stackermanstatic void     ixgb_intr(void *);
97129794Stackermanstatic void     ixgb_start(struct ifnet *);
98144651Salcstatic void     ixgb_start_locked(struct ifnet *);
99129794Stackermanstatic int      ixgb_ioctl(struct ifnet *, IOCTL_CMD_TYPE, caddr_t);
100199539Sjhbstatic void     ixgb_watchdog(struct adapter *);
101129794Stackermanstatic void     ixgb_init(void *);
102144651Salcstatic void     ixgb_init_locked(struct adapter *);
103129794Stackermanstatic void     ixgb_stop(void *);
104129794Stackermanstatic void     ixgb_media_status(struct ifnet *, struct ifmediareq *);
105129794Stackermanstatic int      ixgb_media_change(struct ifnet *);
106129794Stackermanstatic void     ixgb_identify_hardware(struct adapter *);
107129794Stackermanstatic int      ixgb_allocate_pci_resources(struct adapter *);
108129794Stackermanstatic void     ixgb_free_pci_resources(struct adapter *);
109129794Stackermanstatic void     ixgb_local_timer(void *);
110129794Stackermanstatic int      ixgb_hardware_init(struct adapter *);
111211907Syongaristatic int      ixgb_setup_interface(device_t, struct adapter *);
112129794Stackermanstatic int      ixgb_setup_transmit_structures(struct adapter *);
113129794Stackermanstatic void     ixgb_initialize_transmit_unit(struct adapter *);
114129794Stackermanstatic int      ixgb_setup_receive_structures(struct adapter *);
115129794Stackermanstatic void     ixgb_initialize_receive_unit(struct adapter *);
116129794Stackermanstatic void     ixgb_enable_intr(struct adapter *);
117129794Stackermanstatic void     ixgb_disable_intr(struct adapter *);
118129794Stackermanstatic void     ixgb_free_transmit_structures(struct adapter *);
119129794Stackermanstatic void     ixgb_free_receive_structures(struct adapter *);
120129794Stackermanstatic void     ixgb_update_stats_counters(struct adapter *);
121129794Stackermanstatic void     ixgb_clean_transmit_interrupts(struct adapter *);
122129794Stackermanstatic int      ixgb_allocate_receive_structures(struct adapter *);
123129794Stackermanstatic int      ixgb_allocate_transmit_structures(struct adapter *);
124193096Sattiliostatic int      ixgb_process_receive_interrupts(struct adapter *, int);
125129794Stackermanstatic void
126129794Stackermanixgb_receive_checksum(struct adapter *,
127129794Stackerman		      struct ixgb_rx_desc * rx_desc,
128129794Stackerman		      struct mbuf *);
129129794Stackermanstatic void
130129794Stackermanixgb_transmit_checksum_setup(struct adapter *,
131129794Stackerman			     struct mbuf *,
132129794Stackerman			     u_int8_t *);
133129794Stackermanstatic void     ixgb_set_promisc(struct adapter *);
134129794Stackermanstatic void     ixgb_disable_promisc(struct adapter *);
135129794Stackermanstatic void     ixgb_set_multi(struct adapter *);
136129794Stackermanstatic void     ixgb_print_hw_stats(struct adapter *);
137129794Stackermanstatic void     ixgb_print_link_status(struct adapter *);
138129794Stackermanstatic int
139129794Stackermanixgb_get_buf(int i, struct adapter *,
140129794Stackerman	     struct mbuf *);
141129794Stackermanstatic void     ixgb_enable_vlans(struct adapter * adapter);
142129794Stackermanstatic int      ixgb_encap(struct adapter * adapter, struct mbuf * m_head);
143129794Stackermanstatic int      ixgb_sysctl_stats(SYSCTL_HANDLER_ARGS);
144129794Stackermanstatic int
145129794Stackermanixgb_dma_malloc(struct adapter *, bus_size_t,
146129794Stackerman		struct ixgb_dma_alloc *, int);
147129794Stackermanstatic void     ixgb_dma_free(struct adapter *, struct ixgb_dma_alloc *);
148150789Sglebius#ifdef DEVICE_POLLING
149150789Sglebiusstatic poll_handler_t ixgb_poll;
150150789Sglebius#endif
151129794Stackerman
152129794Stackerman/*********************************************************************
153129794Stackerman *  FreeBSD Device Interface Entry Points
154129794Stackerman *********************************************************************/
155129794Stackerman
156129794Stackermanstatic device_method_t ixgb_methods[] = {
157129794Stackerman	/* Device interface */
158129794Stackerman	DEVMETHOD(device_probe, ixgb_probe),
159129794Stackerman	DEVMETHOD(device_attach, ixgb_attach),
160129794Stackerman	DEVMETHOD(device_detach, ixgb_detach),
161129794Stackerman	DEVMETHOD(device_shutdown, ixgb_shutdown),
162129794Stackerman	{0, 0}
163129794Stackerman};
164129794Stackerman
165129794Stackermanstatic driver_t ixgb_driver = {
166129794Stackerman	"ixgb", ixgb_methods, sizeof(struct adapter),
167129794Stackerman};
168129794Stackerman
169129794Stackermanstatic devclass_t ixgb_devclass;
170192147SimpDRIVER_MODULE(ixgb, pci, ixgb_driver, ixgb_devclass, 0, 0);
171129794Stackerman
172192147SimpMODULE_DEPEND(ixgb, pci, 1, 1, 1);
173192147SimpMODULE_DEPEND(ixgb, ether, 1, 1, 1);
174144183Smux
175129794Stackerman/* some defines for controlling descriptor fetches in h/w */
176129794Stackerman#define RXDCTL_PTHRESH_DEFAULT 128	/* chip considers prefech below this */
177129794Stackerman#define RXDCTL_HTHRESH_DEFAULT 16	/* chip will only prefetch if tail is
178129794Stackerman					 * pushed this many descriptors from
179129794Stackerman					 * head */
180129794Stackerman#define RXDCTL_WTHRESH_DEFAULT 0	/* chip writes back at this many or RXT0 */
181129794Stackerman
182129794Stackerman
183129794Stackerman/*********************************************************************
184129794Stackerman *  Device identification routine
185129794Stackerman *
186129794Stackerman *  ixgb_probe determines if the driver should be loaded on
187129794Stackerman *  adapter based on PCI vendor/device id of the adapter.
188129794Stackerman *
189129794Stackerman *  return 0 on success, positive on failure
190129794Stackerman *********************************************************************/
191129794Stackerman
192129794Stackermanstatic int
193129794Stackermanixgb_probe(device_t dev)
194129794Stackerman{
195129794Stackerman	ixgb_vendor_info_t *ent;
196129794Stackerman
197129794Stackerman	u_int16_t       pci_vendor_id = 0;
198129794Stackerman	u_int16_t       pci_device_id = 0;
199129794Stackerman	u_int16_t       pci_subvendor_id = 0;
200129794Stackerman	u_int16_t       pci_subdevice_id = 0;
201129794Stackerman	char            adapter_name[60];
202129794Stackerman
203129794Stackerman	INIT_DEBUGOUT("ixgb_probe: begin");
204129794Stackerman
205129794Stackerman	pci_vendor_id = pci_get_vendor(dev);
206129794Stackerman	if (pci_vendor_id != IXGB_VENDOR_ID)
207129794Stackerman		return (ENXIO);
208129794Stackerman
209129794Stackerman	pci_device_id = pci_get_device(dev);
210129794Stackerman	pci_subvendor_id = pci_get_subvendor(dev);
211129794Stackerman	pci_subdevice_id = pci_get_subdevice(dev);
212129794Stackerman
213129794Stackerman	ent = ixgb_vendor_info_array;
214129794Stackerman	while (ent->vendor_id != 0) {
215129794Stackerman		if ((pci_vendor_id == ent->vendor_id) &&
216129794Stackerman		    (pci_device_id == ent->device_id) &&
217129794Stackerman
218129794Stackerman		    ((pci_subvendor_id == ent->subvendor_id) ||
219129794Stackerman		     (ent->subvendor_id == PCI_ANY_ID)) &&
220129794Stackerman
221129794Stackerman		    ((pci_subdevice_id == ent->subdevice_id) ||
222129794Stackerman		     (ent->subdevice_id == PCI_ANY_ID))) {
223129794Stackerman			sprintf(adapter_name, "%s, Version - %s",
224129794Stackerman				ixgb_strings[ent->index],
225129794Stackerman				ixgb_driver_version);
226129794Stackerman			device_set_desc_copy(dev, adapter_name);
227143160Simp			return (BUS_PROBE_DEFAULT);
228129794Stackerman		}
229129794Stackerman		ent++;
230129794Stackerman	}
231129794Stackerman
232129794Stackerman	return (ENXIO);
233129794Stackerman}
234129794Stackerman
235129794Stackerman/*********************************************************************
236129794Stackerman *  Device initialization routine
237129794Stackerman *
238129794Stackerman *  The attach entry point is called when the driver is being loaded.
239129794Stackerman *  This routine identifies the type of hardware, allocates all resources
240129794Stackerman *  and initializes the hardware.
241129794Stackerman *
242129794Stackerman *  return 0 on success, positive on failure
243129794Stackerman *********************************************************************/
244129794Stackerman
245129794Stackermanstatic int
246129794Stackermanixgb_attach(device_t dev)
247129794Stackerman{
248129794Stackerman	struct adapter *adapter;
249129794Stackerman	int             tsize, rsize;
250129794Stackerman	int             error = 0;
251129794Stackerman
252198987Sjhb	device_printf(dev, "%s\n", ixgb_copyright);
253129794Stackerman	INIT_DEBUGOUT("ixgb_attach: begin");
254129794Stackerman
255129794Stackerman	/* Allocate, clear, and link in our adapter structure */
256129794Stackerman	if (!(adapter = device_get_softc(dev))) {
257198987Sjhb		device_printf(dev, "adapter structure allocation failed\n");
258129794Stackerman		return (ENOMEM);
259129794Stackerman	}
260129794Stackerman	bzero(adapter, sizeof(struct adapter));
261129794Stackerman	adapter->dev = dev;
262129794Stackerman	adapter->osdep.dev = dev;
263144651Salc	IXGB_LOCK_INIT(adapter, device_get_nameunit(dev));
264129794Stackerman
265129794Stackerman	if (ixgb_adapter_list != NULL)
266129794Stackerman		ixgb_adapter_list->prev = adapter;
267129794Stackerman	adapter->next = ixgb_adapter_list;
268129794Stackerman	ixgb_adapter_list = adapter;
269129794Stackerman
270129794Stackerman	/* SYSCTL APIs */
271144183Smux	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
272144183Smux			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
273129794Stackerman			OID_AUTO, "stats", CTLTYPE_INT | CTLFLAG_RW,
274129794Stackerman			(void *)adapter, 0,
275129794Stackerman			ixgb_sysctl_stats, "I", "Statistics");
276129794Stackerman
277199539Sjhb	callout_init_mtx(&adapter->timer, &adapter->mtx, 0);
278129794Stackerman
279129794Stackerman	/* Determine hardware revision */
280129794Stackerman	ixgb_identify_hardware(adapter);
281129794Stackerman
282129794Stackerman	/* Parameters (to be read from user) */
283129794Stackerman	adapter->num_tx_desc = IXGB_MAX_TXD;
284129794Stackerman	adapter->num_rx_desc = IXGB_MAX_RXD;
285129794Stackerman	adapter->tx_int_delay = TIDV;
286129794Stackerman	adapter->rx_int_delay = RDTR;
287129794Stackerman	adapter->rx_buffer_len = IXGB_RXBUFFER_2048;
288129794Stackerman
289129794Stackerman	adapter->hw.fc.high_water = FCRTH;
290129794Stackerman	adapter->hw.fc.low_water = FCRTL;
291129794Stackerman	adapter->hw.fc.pause_time = FCPAUSE;
292129794Stackerman	adapter->hw.fc.send_xon = TRUE;
293129794Stackerman	adapter->hw.fc.type = FLOW_CONTROL;
294129794Stackerman
295129794Stackerman
296129794Stackerman	/* Set the max frame size assuming standard ethernet sized frames */
297129794Stackerman	adapter->hw.max_frame_size =
298129794Stackerman		ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN;
299129794Stackerman
300129794Stackerman	if (ixgb_allocate_pci_resources(adapter)) {
301198987Sjhb		device_printf(dev, "Allocation of PCI resources failed\n");
302129794Stackerman		error = ENXIO;
303129794Stackerman		goto err_pci;
304129794Stackerman	}
305129794Stackerman	tsize = IXGB_ROUNDUP(adapter->num_tx_desc *
306129794Stackerman			     sizeof(struct ixgb_tx_desc), 4096);
307129794Stackerman
308129794Stackerman	/* Allocate Transmit Descriptor ring */
309129794Stackerman	if (ixgb_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
310198987Sjhb		device_printf(dev, "Unable to allocate TxDescriptor memory\n");
311129794Stackerman		error = ENOMEM;
312129794Stackerman		goto err_tx_desc;
313129794Stackerman	}
314129794Stackerman	adapter->tx_desc_base = (struct ixgb_tx_desc *) adapter->txdma.dma_vaddr;
315129794Stackerman
316129794Stackerman	rsize = IXGB_ROUNDUP(adapter->num_rx_desc *
317129794Stackerman			     sizeof(struct ixgb_rx_desc), 4096);
318129794Stackerman
319129794Stackerman	/* Allocate Receive Descriptor ring */
320129794Stackerman	if (ixgb_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
321198987Sjhb		device_printf(dev, "Unable to allocate rx_desc memory\n");
322129794Stackerman		error = ENOMEM;
323129794Stackerman		goto err_rx_desc;
324129794Stackerman	}
325129794Stackerman	adapter->rx_desc_base = (struct ixgb_rx_desc *) adapter->rxdma.dma_vaddr;
326129794Stackerman
327129794Stackerman	/* Initialize the hardware */
328129794Stackerman	if (ixgb_hardware_init(adapter)) {
329198987Sjhb		device_printf(dev, "Unable to initialize the hardware\n");
330129794Stackerman		error = EIO;
331129794Stackerman		goto err_hw_init;
332129794Stackerman	}
333129794Stackerman	/* Setup OS specific network interface */
334211907Syongari	if (ixgb_setup_interface(dev, adapter) != 0)
335211907Syongari		goto err_hw_init;
336129794Stackerman
337129794Stackerman	/* Initialize statistics */
338129794Stackerman	ixgb_clear_hw_cntrs(&adapter->hw);
339129794Stackerman	ixgb_update_stats_counters(adapter);
340129794Stackerman
341129794Stackerman	INIT_DEBUGOUT("ixgb_attach: end");
342129794Stackerman	return (0);
343129794Stackerman
344129794Stackermanerr_hw_init:
345129794Stackerman	ixgb_dma_free(adapter, &adapter->rxdma);
346129794Stackermanerr_rx_desc:
347129794Stackerman	ixgb_dma_free(adapter, &adapter->txdma);
348129794Stackermanerr_tx_desc:
349129794Stackermanerr_pci:
350211907Syongari	if (adapter->ifp != NULL)
351211907Syongari		if_free(adapter->ifp);
352129794Stackerman	ixgb_free_pci_resources(adapter);
353129794Stackerman	sysctl_ctx_free(&adapter->sysctl_ctx);
354129794Stackerman	return (error);
355129794Stackerman
356129794Stackerman}
357129794Stackerman
358129794Stackerman/*********************************************************************
359129794Stackerman *  Device removal routine
360129794Stackerman *
361129794Stackerman *  The detach entry point is called when the driver is being removed.
362129794Stackerman *  This routine stops the adapter and deallocates all the resources
363129794Stackerman *  that were allocated for driver operation.
364129794Stackerman *
365129794Stackerman *  return 0 on success, positive on failure
366129794Stackerman *********************************************************************/
367129794Stackerman
368129794Stackermanstatic int
369129794Stackermanixgb_detach(device_t dev)
370129794Stackerman{
371129794Stackerman	struct adapter *adapter = device_get_softc(dev);
372147256Sbrooks	struct ifnet   *ifp = adapter->ifp;
373129794Stackerman
374129794Stackerman	INIT_DEBUGOUT("ixgb_detach: begin");
375129794Stackerman
376150789Sglebius#ifdef DEVICE_POLLING
377150789Sglebius	if (ifp->if_capenable & IFCAP_POLLING)
378150789Sglebius		ether_poll_deregister(ifp);
379150789Sglebius#endif
380150789Sglebius
381144651Salc	IXGB_LOCK(adapter);
382129794Stackerman	adapter->in_detach = 1;
383129794Stackerman
384129794Stackerman	ixgb_stop(adapter);
385144651Salc	IXGB_UNLOCK(adapter);
386129794Stackerman
387129794Stackerman#if __FreeBSD_version < 500000
388199539Sjhb	ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
389129794Stackerman#else
390199539Sjhb	ether_ifdetach(ifp);
391150306Simp#endif
392199539Sjhb	callout_drain(&adapter->timer);
393150306Simp	ixgb_free_pci_resources(adapter);
394150306Simp#if __FreeBSD_version >= 500000
395199539Sjhb	if_free(ifp);
396129794Stackerman#endif
397129794Stackerman
398129794Stackerman	/* Free Transmit Descriptor ring */
399129794Stackerman	if (adapter->tx_desc_base) {
400129794Stackerman		ixgb_dma_free(adapter, &adapter->txdma);
401129794Stackerman		adapter->tx_desc_base = NULL;
402129794Stackerman	}
403129794Stackerman	/* Free Receive Descriptor ring */
404129794Stackerman	if (adapter->rx_desc_base) {
405129794Stackerman		ixgb_dma_free(adapter, &adapter->rxdma);
406129794Stackerman		adapter->rx_desc_base = NULL;
407129794Stackerman	}
408129794Stackerman	/* Remove from the adapter list */
409129794Stackerman	if (ixgb_adapter_list == adapter)
410129794Stackerman		ixgb_adapter_list = adapter->next;
411129794Stackerman	if (adapter->next != NULL)
412129794Stackerman		adapter->next->prev = adapter->prev;
413129794Stackerman	if (adapter->prev != NULL)
414129794Stackerman		adapter->prev->next = adapter->next;
415129794Stackerman
416144651Salc	IXGB_LOCK_DESTROY(adapter);
417129794Stackerman	return (0);
418129794Stackerman}
419129794Stackerman
420129794Stackerman/*********************************************************************
421129794Stackerman *
422129794Stackerman *  Shutdown entry point
423129794Stackerman *
424129794Stackerman **********************************************************************/
425129794Stackerman
426129794Stackermanstatic int
427129794Stackermanixgb_shutdown(device_t dev)
428129794Stackerman{
429129794Stackerman	struct adapter *adapter = device_get_softc(dev);
430144651Salc	IXGB_LOCK(adapter);
431129794Stackerman	ixgb_stop(adapter);
432144651Salc	IXGB_UNLOCK(adapter);
433129794Stackerman	return (0);
434129794Stackerman}
435129794Stackerman
436129794Stackerman
437129794Stackerman/*********************************************************************
438129794Stackerman *  Transmit entry point
439129794Stackerman *
440129794Stackerman *  ixgb_start is called by the stack to initiate a transmit.
441129794Stackerman *  The driver will remain in this routine as long as there are
442129794Stackerman *  packets to transmit and transmit resources are available.
443129794Stackerman *  In case resources are not available stack is notified and
444129794Stackerman *  the packet is requeued.
445129794Stackerman **********************************************************************/
446129794Stackerman
447129794Stackermanstatic void
448144651Salcixgb_start_locked(struct ifnet * ifp)
449129794Stackerman{
450129794Stackerman	struct mbuf    *m_head;
451129794Stackerman	struct adapter *adapter = ifp->if_softc;
452129794Stackerman
453144651Salc	IXGB_LOCK_ASSERT(adapter);
454129794Stackerman
455129794Stackerman	if (!adapter->link_active)
456129794Stackerman		return;
457129794Stackerman
458129794Stackerman	while (ifp->if_snd.ifq_head != NULL) {
459129794Stackerman		IF_DEQUEUE(&ifp->if_snd, m_head);
460129794Stackerman
461129794Stackerman		if (m_head == NULL)
462129794Stackerman			break;
463129794Stackerman
464129794Stackerman		if (ixgb_encap(adapter, m_head)) {
465148887Srwatson			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
466129794Stackerman			IF_PREPEND(&ifp->if_snd, m_head);
467129794Stackerman			break;
468129794Stackerman		}
469129794Stackerman		/* Send a copy of the frame to the BPF listener */
470129794Stackerman#if __FreeBSD_version < 500000
471129794Stackerman		if (ifp->if_bpf)
472129794Stackerman			bpf_mtap(ifp, m_head);
473129794Stackerman#else
474167190Scsjp		ETHER_BPF_MTAP(ifp, m_head);
475129794Stackerman#endif
476129794Stackerman		/* Set timeout in case hardware has problems transmitting */
477199539Sjhb		adapter->tx_timer = IXGB_TX_TIMEOUT;
478129794Stackerman
479129794Stackerman	}
480129794Stackerman	return;
481129794Stackerman}
482129794Stackerman
483144651Salcstatic void
484144651Salcixgb_start(struct ifnet *ifp)
485144651Salc{
486144651Salc	struct adapter *adapter = ifp->if_softc;
487144651Salc
488144651Salc	IXGB_LOCK(adapter);
489144651Salc	ixgb_start_locked(ifp);
490144651Salc	IXGB_UNLOCK(adapter);
491144651Salc	return;
492144651Salc}
493144651Salc
494129794Stackerman/*********************************************************************
495129794Stackerman *  Ioctl entry point
496129794Stackerman *
497129794Stackerman *  ixgb_ioctl is called when the user wants to configure the
498129794Stackerman *  interface.
499129794Stackerman *
500129794Stackerman *  return 0 on success, positive on failure
501129794Stackerman **********************************************************************/
502129794Stackerman
503129794Stackermanstatic int
504129794Stackermanixgb_ioctl(struct ifnet * ifp, IOCTL_CMD_TYPE command, caddr_t data)
505129794Stackerman{
506144651Salc	int             mask, error = 0;
507129794Stackerman	struct ifreq   *ifr = (struct ifreq *) data;
508129794Stackerman	struct adapter *adapter = ifp->if_softc;
509129794Stackerman
510129794Stackerman	if (adapter->in_detach)
511129794Stackerman		goto out;
512129794Stackerman
513129794Stackerman	switch (command) {
514129794Stackerman	case SIOCSIFADDR:
515129794Stackerman	case SIOCGIFADDR:
516129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFADDR (Get/Set Interface Addr)");
517129794Stackerman		ether_ioctl(ifp, command, data);
518129794Stackerman		break;
519129794Stackerman	case SIOCSIFMTU:
520129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)");
521129794Stackerman		if (ifr->ifr_mtu > IXGB_MAX_JUMBO_FRAME_SIZE - ETHER_HDR_LEN) {
522129794Stackerman			error = EINVAL;
523129794Stackerman		} else {
524144651Salc			IXGB_LOCK(adapter);
525129794Stackerman			ifp->if_mtu = ifr->ifr_mtu;
526129794Stackerman			adapter->hw.max_frame_size =
527129794Stackerman				ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
528129794Stackerman
529144651Salc			ixgb_init_locked(adapter);
530144651Salc			IXGB_UNLOCK(adapter);
531129794Stackerman		}
532129794Stackerman		break;
533129794Stackerman	case SIOCSIFFLAGS:
534129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)");
535144651Salc		IXGB_LOCK(adapter);
536129794Stackerman		if (ifp->if_flags & IFF_UP) {
537148887Srwatson			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
538144651Salc				ixgb_init_locked(adapter);
539129794Stackerman			}
540129794Stackerman			ixgb_disable_promisc(adapter);
541129794Stackerman			ixgb_set_promisc(adapter);
542129794Stackerman		} else {
543148887Srwatson			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
544129794Stackerman				ixgb_stop(adapter);
545129794Stackerman			}
546129794Stackerman		}
547144651Salc		IXGB_UNLOCK(adapter);
548129794Stackerman		break;
549129794Stackerman	case SIOCADDMULTI:
550129794Stackerman	case SIOCDELMULTI:
551129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOC(ADD|DEL)MULTI");
552148887Srwatson		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
553144651Salc			IXGB_LOCK(adapter);
554129794Stackerman			ixgb_disable_intr(adapter);
555129794Stackerman			ixgb_set_multi(adapter);
556129794Stackerman			ixgb_enable_intr(adapter);
557144651Salc			IXGB_UNLOCK(adapter);
558129794Stackerman		}
559129794Stackerman		break;
560129794Stackerman	case SIOCSIFMEDIA:
561129794Stackerman	case SIOCGIFMEDIA:
562129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFMEDIA (Get/Set Interface Media)");
563129794Stackerman		error = ifmedia_ioctl(ifp, ifr, &adapter->media, command);
564129794Stackerman		break;
565129794Stackerman	case SIOCSIFCAP:
566129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)");
567129794Stackerman		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
568150789Sglebius#ifdef DEVICE_POLLING
569150789Sglebius		if (mask & IFCAP_POLLING) {
570150789Sglebius			if (ifr->ifr_reqcap & IFCAP_POLLING) {
571150789Sglebius				error = ether_poll_register(ixgb_poll, ifp);
572150789Sglebius				if (error)
573150789Sglebius					return(error);
574150789Sglebius				IXGB_LOCK(adapter);
575150789Sglebius				ixgb_disable_intr(adapter);
576150789Sglebius				ifp->if_capenable |= IFCAP_POLLING;
577150789Sglebius				IXGB_UNLOCK(adapter);
578150789Sglebius			} else {
579150789Sglebius				error = ether_poll_deregister(ifp);
580150789Sglebius				/* Enable interrupt even in error case */
581150789Sglebius				IXGB_LOCK(adapter);
582150789Sglebius				ixgb_enable_intr(adapter);
583150789Sglebius				ifp->if_capenable &= ~IFCAP_POLLING;
584150789Sglebius				IXGB_UNLOCK(adapter);
585150789Sglebius			}
586150789Sglebius		}
587150789Sglebius#endif /* DEVICE_POLLING */
588129794Stackerman		if (mask & IFCAP_HWCSUM) {
589129794Stackerman			if (IFCAP_HWCSUM & ifp->if_capenable)
590129794Stackerman				ifp->if_capenable &= ~IFCAP_HWCSUM;
591129794Stackerman			else
592129794Stackerman				ifp->if_capenable |= IFCAP_HWCSUM;
593148887Srwatson			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
594129794Stackerman				ixgb_init(adapter);
595129794Stackerman		}
596129794Stackerman		break;
597129794Stackerman	default:
598129794Stackerman		IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%X)\n", (int)command);
599129794Stackerman		error = EINVAL;
600129794Stackerman	}
601129794Stackerman
602129794Stackermanout:
603129794Stackerman	return (error);
604129794Stackerman}
605129794Stackerman
606129794Stackerman/*********************************************************************
607129794Stackerman *  Watchdog entry point
608129794Stackerman *
609129794Stackerman *  This routine is called whenever hardware quits transmitting.
610129794Stackerman *
611129794Stackerman **********************************************************************/
612129794Stackerman
613129794Stackermanstatic void
614199539Sjhbixgb_watchdog(struct adapter *adapter)
615129794Stackerman{
616199539Sjhb	struct ifnet *ifp;
617129794Stackerman
618199539Sjhb	ifp = adapter->ifp;
619199539Sjhb
620129794Stackerman	/*
621129794Stackerman	 * If we are in this routine because of pause frames, then don't
622129794Stackerman	 * reset the hardware.
623129794Stackerman	 */
624129794Stackerman	if (IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF) {
625199539Sjhb		adapter->tx_timer = IXGB_TX_TIMEOUT;
626129794Stackerman		return;
627129794Stackerman	}
628198987Sjhb	if_printf(ifp, "watchdog timeout -- resetting\n");
629129794Stackerman
630129794Stackerman	ixgb_stop(adapter);
631199539Sjhb	ixgb_init_locked(adapter);
632129794Stackerman
633129794Stackerman
634129794Stackerman	ifp->if_oerrors++;
635129794Stackerman
636129794Stackerman	return;
637129794Stackerman}
638129794Stackerman
639129794Stackerman/*********************************************************************
640129794Stackerman *  Init entry point
641129794Stackerman *
642129794Stackerman *  This routine is used in two ways. It is used by the stack as
643129794Stackerman *  init entry point in network interface structure. It is also used
644129794Stackerman *  by the driver as a hw/sw initialization routine to get to a
645129794Stackerman *  consistent state.
646129794Stackerman *
647129794Stackerman *  return 0 on success, positive on failure
648129794Stackerman **********************************************************************/
649129794Stackerman
650129794Stackermanstatic void
651144651Salcixgb_init_locked(struct adapter *adapter)
652129794Stackerman{
653129794Stackerman	struct ifnet   *ifp;
654129794Stackerman
655129794Stackerman	INIT_DEBUGOUT("ixgb_init: begin");
656129794Stackerman
657144651Salc	IXGB_LOCK_ASSERT(adapter);
658129794Stackerman
659129794Stackerman	ixgb_stop(adapter);
660198987Sjhb	ifp = adapter->ifp;
661129794Stackerman
662129794Stackerman	/* Get the latest mac address, User can use a LAA */
663198987Sjhb	bcopy(IF_LLADDR(ifp), adapter->hw.curr_mac_addr,
664198987Sjhb	    IXGB_ETH_LENGTH_OF_ADDRESS);
665129794Stackerman
666129794Stackerman	/* Initialize the hardware */
667129794Stackerman	if (ixgb_hardware_init(adapter)) {
668198987Sjhb		if_printf(ifp, "Unable to initialize the hardware\n");
669129794Stackerman		return;
670129794Stackerman	}
671129794Stackerman	ixgb_enable_vlans(adapter);
672129794Stackerman
673129794Stackerman	/* Prepare transmit descriptors and buffers */
674129794Stackerman	if (ixgb_setup_transmit_structures(adapter)) {
675198987Sjhb		if_printf(ifp, "Could not setup transmit structures\n");
676129794Stackerman		ixgb_stop(adapter);
677129794Stackerman		return;
678129794Stackerman	}
679129794Stackerman	ixgb_initialize_transmit_unit(adapter);
680129794Stackerman
681129794Stackerman	/* Setup Multicast table */
682129794Stackerman	ixgb_set_multi(adapter);
683129794Stackerman
684129794Stackerman	/* Prepare receive descriptors and buffers */
685129794Stackerman	if (ixgb_setup_receive_structures(adapter)) {
686198987Sjhb		if_printf(ifp, "Could not setup receive structures\n");
687129794Stackerman		ixgb_stop(adapter);
688129794Stackerman		return;
689129794Stackerman	}
690129794Stackerman	ixgb_initialize_receive_unit(adapter);
691129794Stackerman
692160964Syar	/* Don't lose promiscuous settings */
693129794Stackerman	ixgb_set_promisc(adapter);
694129794Stackerman
695147256Sbrooks	ifp = adapter->ifp;
696148887Srwatson	ifp->if_drv_flags |= IFF_DRV_RUNNING;
697148887Srwatson	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
698129794Stackerman
699129794Stackerman
700129794Stackerman	if (ifp->if_capenable & IFCAP_TXCSUM)
701129794Stackerman		ifp->if_hwassist = IXGB_CHECKSUM_FEATURES;
702129794Stackerman	else
703129794Stackerman		ifp->if_hwassist = 0;
704129794Stackerman
705129794Stackerman
706129794Stackerman	/* Enable jumbo frames */
707129794Stackerman	if (ifp->if_mtu > ETHERMTU) {
708129794Stackerman		uint32_t        temp_reg;
709129794Stackerman		IXGB_WRITE_REG(&adapter->hw, MFS,
710129794Stackerman			       adapter->hw.max_frame_size << IXGB_MFS_SHIFT);
711129794Stackerman		temp_reg = IXGB_READ_REG(&adapter->hw, CTRL0);
712129794Stackerman		temp_reg |= IXGB_CTRL0_JFE;
713129794Stackerman		IXGB_WRITE_REG(&adapter->hw, CTRL0, temp_reg);
714129794Stackerman	}
715199539Sjhb	callout_reset(&adapter->timer, hz, ixgb_local_timer, adapter);
716129794Stackerman	ixgb_clear_hw_cntrs(&adapter->hw);
717129794Stackerman#ifdef DEVICE_POLLING
718129794Stackerman	/*
719129794Stackerman	 * Only disable interrupts if we are polling, make sure they are on
720129794Stackerman	 * otherwise.
721129794Stackerman	 */
722150789Sglebius	if (ifp->if_capenable & IFCAP_POLLING)
723129794Stackerman		ixgb_disable_intr(adapter);
724129794Stackerman	else
725150789Sglebius#endif
726129794Stackerman		ixgb_enable_intr(adapter);
727129794Stackerman
728129794Stackerman	return;
729129794Stackerman}
730129794Stackerman
731144651Salcstatic void
732144651Salcixgb_init(void *arg)
733144651Salc{
734144651Salc	struct adapter *adapter = arg;
735129794Stackerman
736144651Salc	IXGB_LOCK(adapter);
737144651Salc	ixgb_init_locked(adapter);
738144651Salc	IXGB_UNLOCK(adapter);
739144651Salc	return;
740144651Salc}
741144651Salc
742129794Stackerman#ifdef DEVICE_POLLING
743193096Sattiliostatic int
744144651Salcixgb_poll_locked(struct ifnet * ifp, enum poll_cmd cmd, int count)
745129794Stackerman{
746129794Stackerman	struct adapter *adapter = ifp->if_softc;
747129794Stackerman	u_int32_t       reg_icr;
748193096Sattilio	int		rx_npkts;
749129794Stackerman
750144651Salc	IXGB_LOCK_ASSERT(adapter);
751144651Salc
752129794Stackerman	if (cmd == POLL_AND_CHECK_STATUS) {
753129794Stackerman		reg_icr = IXGB_READ_REG(&adapter->hw, ICR);
754129794Stackerman		if (reg_icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)) {
755129794Stackerman			ixgb_check_for_link(&adapter->hw);
756129794Stackerman			ixgb_print_link_status(adapter);
757129794Stackerman		}
758129794Stackerman	}
759193096Sattilio	rx_npkts = ixgb_process_receive_interrupts(adapter, count);
760150789Sglebius	ixgb_clean_transmit_interrupts(adapter);
761150789Sglebius
762150789Sglebius	if (ifp->if_snd.ifq_head != NULL)
763144651Salc		ixgb_start_locked(ifp);
764193096Sattilio	return (rx_npkts);
765129794Stackerman}
766144651Salc
767193096Sattiliostatic int
768144651Salcixgb_poll(struct ifnet * ifp, enum poll_cmd cmd, int count)
769144651Salc{
770144651Salc	struct adapter *adapter = ifp->if_softc;
771193096Sattilio	int rx_npkts = 0;
772144651Salc
773144651Salc	IXGB_LOCK(adapter);
774150789Sglebius	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
775193096Sattilio		rx_npkts = ixgb_poll_locked(ifp, cmd, count);
776144651Salc	IXGB_UNLOCK(adapter);
777193096Sattilio	return (rx_npkts);
778144651Salc}
779150789Sglebius#endif /* DEVICE_POLLING */
780129794Stackerman
781129794Stackerman/*********************************************************************
782129794Stackerman *
783129794Stackerman *  Interrupt Service routine
784129794Stackerman *
785129794Stackerman **********************************************************************/
786129794Stackerman
787129794Stackermanstatic void
788129794Stackermanixgb_intr(void *arg)
789129794Stackerman{
790129794Stackerman	u_int32_t       loop_cnt = IXGB_MAX_INTR;
791129794Stackerman	u_int32_t       reg_icr;
792129794Stackerman	struct ifnet   *ifp;
793129794Stackerman	struct adapter *adapter = arg;
794129794Stackerman	boolean_t       rxdmt0 = FALSE;
795129794Stackerman
796144651Salc	IXGB_LOCK(adapter);
797144651Salc
798147256Sbrooks	ifp = adapter->ifp;
799129794Stackerman
800129794Stackerman#ifdef DEVICE_POLLING
801150789Sglebius	if (ifp->if_capenable & IFCAP_POLLING) {
802144651Salc		IXGB_UNLOCK(adapter);
803129794Stackerman		return;
804144651Salc	}
805150789Sglebius#endif
806129794Stackerman
807144651Salc	reg_icr = IXGB_READ_REG(&adapter->hw, ICR);
808144651Salc	if (reg_icr == 0) {
809144651Salc		IXGB_UNLOCK(adapter);
810129794Stackerman		return;
811144651Salc	}
812129794Stackerman
813129794Stackerman	if (reg_icr & IXGB_INT_RXDMT0)
814129794Stackerman		rxdmt0 = TRUE;
815129794Stackerman
816129794Stackerman#ifdef _SV_
817129794Stackerman	if (reg_icr & IXGB_INT_RXDMT0)
818129794Stackerman		adapter->sv_stats.icr_rxdmt0++;
819129794Stackerman	if (reg_icr & IXGB_INT_RXO)
820129794Stackerman		adapter->sv_stats.icr_rxo++;
821129794Stackerman	if (reg_icr & IXGB_INT_RXT0)
822129794Stackerman		adapter->sv_stats.icr_rxt0++;
823129794Stackerman	if (reg_icr & IXGB_INT_TXDW)
824129794Stackerman		adapter->sv_stats.icr_TXDW++;
825129794Stackerman#endif				/* _SV_ */
826129794Stackerman
827129794Stackerman	/* Link status change */
828129794Stackerman	if (reg_icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)) {
829129794Stackerman		ixgb_check_for_link(&adapter->hw);
830129794Stackerman		ixgb_print_link_status(adapter);
831129794Stackerman	}
832129794Stackerman	while (loop_cnt > 0) {
833148887Srwatson		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
834129794Stackerman			ixgb_process_receive_interrupts(adapter, -1);
835129794Stackerman			ixgb_clean_transmit_interrupts(adapter);
836129794Stackerman		}
837129794Stackerman		loop_cnt--;
838129794Stackerman	}
839129794Stackerman
840129794Stackerman	if (rxdmt0 && adapter->raidc) {
841129794Stackerman		IXGB_WRITE_REG(&adapter->hw, IMC, IXGB_INT_RXDMT0);
842129794Stackerman		IXGB_WRITE_REG(&adapter->hw, IMS, IXGB_INT_RXDMT0);
843129794Stackerman	}
844148887Srwatson	if (ifp->if_drv_flags & IFF_DRV_RUNNING && ifp->if_snd.ifq_head != NULL)
845144651Salc		ixgb_start_locked(ifp);
846129794Stackerman
847144651Salc	IXGB_UNLOCK(adapter);
848129794Stackerman	return;
849129794Stackerman}
850129794Stackerman
851129794Stackerman
852129794Stackerman/*********************************************************************
853129794Stackerman *
854129794Stackerman *  Media Ioctl callback
855129794Stackerman *
856129794Stackerman *  This routine is called whenever the user queries the status of
857129794Stackerman *  the interface using ifconfig.
858129794Stackerman *
859129794Stackerman **********************************************************************/
860129794Stackermanstatic void
861129794Stackermanixgb_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
862129794Stackerman{
863129794Stackerman	struct adapter *adapter = ifp->if_softc;
864129794Stackerman
865129794Stackerman	INIT_DEBUGOUT("ixgb_media_status: begin");
866129794Stackerman
867129794Stackerman	ixgb_check_for_link(&adapter->hw);
868129794Stackerman	ixgb_print_link_status(adapter);
869129794Stackerman
870129794Stackerman	ifmr->ifm_status = IFM_AVALID;
871129794Stackerman	ifmr->ifm_active = IFM_ETHER;
872129794Stackerman
873129794Stackerman	if (!adapter->hw.link_up)
874129794Stackerman		return;
875129794Stackerman
876129794Stackerman	ifmr->ifm_status |= IFM_ACTIVE;
877129794Stackerman	ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
878129794Stackerman
879129794Stackerman	return;
880129794Stackerman}
881129794Stackerman
882129794Stackerman/*********************************************************************
883129794Stackerman *
884129794Stackerman *  Media Ioctl callback
885129794Stackerman *
886129794Stackerman *  This routine is called when the user changes speed/duplex using
887129794Stackerman *  media/mediopt option with ifconfig.
888129794Stackerman *
889129794Stackerman **********************************************************************/
890129794Stackermanstatic int
891129794Stackermanixgb_media_change(struct ifnet * ifp)
892129794Stackerman{
893129794Stackerman	struct adapter *adapter = ifp->if_softc;
894129794Stackerman	struct ifmedia *ifm = &adapter->media;
895129794Stackerman
896129794Stackerman	INIT_DEBUGOUT("ixgb_media_change: begin");
897129794Stackerman
898129794Stackerman	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
899129794Stackerman		return (EINVAL);
900129794Stackerman
901129794Stackerman	return (0);
902129794Stackerman}
903129794Stackerman
904129794Stackerman/*********************************************************************
905129794Stackerman *
906129794Stackerman *  This routine maps the mbufs to tx descriptors.
907129794Stackerman *
908129794Stackerman *  return 0 on success, positive on failure
909129794Stackerman **********************************************************************/
910129794Stackerman
911129794Stackermanstatic int
912129794Stackermanixgb_encap(struct adapter * adapter, struct mbuf * m_head)
913129794Stackerman{
914129794Stackerman	u_int8_t        txd_popts;
915146339Salc	int             i, j, error, nsegs;
916129794Stackerman
917129794Stackerman#if __FreeBSD_version < 500000
918129794Stackerman	struct ifvlan  *ifv = NULL;
919129794Stackerman#endif
920146339Salc	bus_dma_segment_t segs[IXGB_MAX_SCATTER];
921146339Salc	bus_dmamap_t	map;
922129794Stackerman	struct ixgb_buffer *tx_buffer = NULL;
923129794Stackerman	struct ixgb_tx_desc *current_tx_desc = NULL;
924147256Sbrooks	struct ifnet   *ifp = adapter->ifp;
925129794Stackerman
926129794Stackerman	/*
927129794Stackerman	 * Force a cleanup if number of TX descriptors available hits the
928129794Stackerman	 * threshold
929129794Stackerman	 */
930129794Stackerman	if (adapter->num_tx_desc_avail <= IXGB_TX_CLEANUP_THRESHOLD) {
931129794Stackerman		ixgb_clean_transmit_interrupts(adapter);
932129794Stackerman	}
933129794Stackerman	if (adapter->num_tx_desc_avail <= IXGB_TX_CLEANUP_THRESHOLD) {
934129794Stackerman		adapter->no_tx_desc_avail1++;
935129794Stackerman		return (ENOBUFS);
936129794Stackerman	}
937129794Stackerman	/*
938129794Stackerman	 * Map the packet for DMA.
939129794Stackerman	 */
940146339Salc	if (bus_dmamap_create(adapter->txtag, BUS_DMA_NOWAIT, &map)) {
941129794Stackerman		adapter->no_tx_map_avail++;
942129794Stackerman		return (ENOMEM);
943129794Stackerman	}
944146339Salc	error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, m_head, segs,
945146339Salc					&nsegs, BUS_DMA_NOWAIT);
946129794Stackerman	if (error != 0) {
947129794Stackerman		adapter->no_tx_dma_setup++;
948198987Sjhb		if_printf(ifp, "ixgb_encap: bus_dmamap_load_mbuf failed; "
949198987Sjhb		       "error %u\n", error);
950146339Salc		bus_dmamap_destroy(adapter->txtag, map);
951129794Stackerman		return (error);
952129794Stackerman	}
953146339Salc	KASSERT(nsegs != 0, ("ixgb_encap: empty packet"));
954129794Stackerman
955146339Salc	if (nsegs > adapter->num_tx_desc_avail) {
956129794Stackerman		adapter->no_tx_desc_avail2++;
957146339Salc		bus_dmamap_destroy(adapter->txtag, map);
958129794Stackerman		return (ENOBUFS);
959129794Stackerman	}
960129794Stackerman	if (ifp->if_hwassist > 0) {
961129794Stackerman		ixgb_transmit_checksum_setup(adapter, m_head,
962129794Stackerman					     &txd_popts);
963129794Stackerman	} else
964129794Stackerman		txd_popts = 0;
965129794Stackerman
966129794Stackerman	/* Find out if we are in vlan mode */
967129794Stackerman#if __FreeBSD_version < 500000
968129794Stackerman	if ((m_head->m_flags & (M_PROTO1 | M_PKTHDR)) == (M_PROTO1 | M_PKTHDR) &&
969129794Stackerman	    m_head->m_pkthdr.rcvif != NULL &&
970129794Stackerman	    m_head->m_pkthdr.rcvif->if_type == IFT_L2VLAN)
971129794Stackerman		ifv = m_head->m_pkthdr.rcvif->if_softc;
972162375Sandre#elseif __FreeBSD_version < 700000
973129794Stackerman	mtag = VLAN_OUTPUT_TAG(ifp, m_head);
974129794Stackerman#endif
975129794Stackerman	i = adapter->next_avail_tx_desc;
976146339Salc	for (j = 0; j < nsegs; j++) {
977129794Stackerman		tx_buffer = &adapter->tx_buffer_area[i];
978129794Stackerman		current_tx_desc = &adapter->tx_desc_base[i];
979129794Stackerman
980146339Salc		current_tx_desc->buff_addr = htole64(segs[j].ds_addr);
981146339Salc		current_tx_desc->cmd_type_len = (adapter->txd_cmd | segs[j].ds_len);
982129794Stackerman		current_tx_desc->popts = txd_popts;
983129794Stackerman		if (++i == adapter->num_tx_desc)
984129794Stackerman			i = 0;
985129794Stackerman
986129794Stackerman		tx_buffer->m_head = NULL;
987129794Stackerman	}
988129794Stackerman
989146339Salc	adapter->num_tx_desc_avail -= nsegs;
990129794Stackerman	adapter->next_avail_tx_desc = i;
991129794Stackerman
992129794Stackerman#if __FreeBSD_version < 500000
993129794Stackerman	if (ifv != NULL) {
994129794Stackerman		/* Set the vlan id */
995129794Stackerman		current_tx_desc->vlan = ifv->ifv_tag;
996162375Sandre#elseif __FreeBSD_version < 700000
997129794Stackerman	if (mtag != NULL) {
998129794Stackerman		/* Set the vlan id */
999129794Stackerman		current_tx_desc->vlan = VLAN_TAG_VALUE(mtag);
1000162375Sandre#else
1001162375Sandre	if (m_head->m_flags & M_VLANTAG) {
1002162375Sandre		current_tx_desc->vlan = m_head->m_pkthdr.ether_vtag;
1003129794Stackerman#endif
1004129794Stackerman
1005129794Stackerman		/* Tell hardware to add tag */
1006129794Stackerman		current_tx_desc->cmd_type_len |= IXGB_TX_DESC_CMD_VLE;
1007129794Stackerman	}
1008129794Stackerman	tx_buffer->m_head = m_head;
1009146339Salc	tx_buffer->map = map;
1010146339Salc	bus_dmamap_sync(adapter->txtag, map, BUS_DMASYNC_PREWRITE);
1011129794Stackerman
1012129794Stackerman	/*
1013129794Stackerman	 * Last Descriptor of Packet needs End Of Packet (EOP)
1014129794Stackerman	 */
1015129794Stackerman	current_tx_desc->cmd_type_len |= (IXGB_TX_DESC_CMD_EOP);
1016129794Stackerman
1017129794Stackerman	/*
1018129794Stackerman	 * Advance the Transmit Descriptor Tail (Tdt), this tells the E1000
1019129794Stackerman	 * that this frame is available to transmit.
1020129794Stackerman	 */
1021129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDT, i);
1022129794Stackerman
1023129794Stackerman	return (0);
1024129794Stackerman}
1025129794Stackerman
1026129794Stackermanstatic void
1027129794Stackermanixgb_set_promisc(struct adapter * adapter)
1028129794Stackerman{
1029129794Stackerman
1030129794Stackerman	u_int32_t       reg_rctl;
1031147256Sbrooks	struct ifnet   *ifp = adapter->ifp;
1032129794Stackerman
1033129794Stackerman	reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL);
1034129794Stackerman
1035129794Stackerman	if (ifp->if_flags & IFF_PROMISC) {
1036129794Stackerman		reg_rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE);
1037129794Stackerman		IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
1038129794Stackerman	} else if (ifp->if_flags & IFF_ALLMULTI) {
1039129794Stackerman		reg_rctl |= IXGB_RCTL_MPE;
1040129794Stackerman		reg_rctl &= ~IXGB_RCTL_UPE;
1041129794Stackerman		IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
1042129794Stackerman	}
1043129794Stackerman	return;
1044129794Stackerman}
1045129794Stackerman
1046129794Stackermanstatic void
1047129794Stackermanixgb_disable_promisc(struct adapter * adapter)
1048129794Stackerman{
1049129794Stackerman	u_int32_t       reg_rctl;
1050129794Stackerman
1051129794Stackerman	reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL);
1052129794Stackerman
1053129794Stackerman	reg_rctl &= (~IXGB_RCTL_UPE);
1054129794Stackerman	reg_rctl &= (~IXGB_RCTL_MPE);
1055129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
1056129794Stackerman
1057129794Stackerman	return;
1058129794Stackerman}
1059129794Stackerman
1060129794Stackerman
1061129794Stackerman/*********************************************************************
1062129794Stackerman *  Multicast Update
1063129794Stackerman *
1064129794Stackerman *  This routine is called whenever multicast address list is updated.
1065129794Stackerman *
1066129794Stackerman **********************************************************************/
1067129794Stackerman
1068129794Stackermanstatic void
1069129794Stackermanixgb_set_multi(struct adapter * adapter)
1070129794Stackerman{
1071129794Stackerman	u_int32_t       reg_rctl = 0;
1072129794Stackerman	u_int8_t        mta[MAX_NUM_MULTICAST_ADDRESSES * IXGB_ETH_LENGTH_OF_ADDRESS];
1073129794Stackerman	struct ifmultiaddr *ifma;
1074129794Stackerman	int             mcnt = 0;
1075147256Sbrooks	struct ifnet   *ifp = adapter->ifp;
1076129794Stackerman
1077129794Stackerman	IOCTL_DEBUGOUT("ixgb_set_multi: begin");
1078129794Stackerman
1079195049Srwatson	if_maddr_rlock(ifp);
1080129794Stackerman#if __FreeBSD_version < 500000
1081129794Stackerman	LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1082129794Stackerman#else
1083129794Stackerman	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1084129794Stackerman#endif
1085129794Stackerman		if (ifma->ifma_addr->sa_family != AF_LINK)
1086129794Stackerman			continue;
1087129794Stackerman
1088129794Stackerman		bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
1089129794Stackerman		      &mta[mcnt * IXGB_ETH_LENGTH_OF_ADDRESS], IXGB_ETH_LENGTH_OF_ADDRESS);
1090129794Stackerman		mcnt++;
1091129794Stackerman	}
1092195049Srwatson	if_maddr_runlock(ifp);
1093129794Stackerman
1094129794Stackerman	if (mcnt > MAX_NUM_MULTICAST_ADDRESSES) {
1095129794Stackerman		reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL);
1096129794Stackerman		reg_rctl |= IXGB_RCTL_MPE;
1097129794Stackerman		IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
1098129794Stackerman	} else
1099129794Stackerman		ixgb_mc_addr_list_update(&adapter->hw, mta, mcnt, 0);
1100129794Stackerman
1101129794Stackerman	return;
1102129794Stackerman}
1103129794Stackerman
1104129794Stackerman
1105129794Stackerman/*********************************************************************
1106129794Stackerman *  Timer routine
1107129794Stackerman *
1108129794Stackerman *  This routine checks for link status and updates statistics.
1109129794Stackerman *
1110129794Stackerman **********************************************************************/
1111129794Stackerman
1112129794Stackermanstatic void
1113129794Stackermanixgb_local_timer(void *arg)
1114129794Stackerman{
1115129794Stackerman	struct ifnet   *ifp;
1116129794Stackerman	struct adapter *adapter = arg;
1117147256Sbrooks	ifp = adapter->ifp;
1118129794Stackerman
1119199539Sjhb	IXGB_LOCK_ASSERT(adapter);
1120129794Stackerman
1121129794Stackerman	ixgb_check_for_link(&adapter->hw);
1122129794Stackerman	ixgb_print_link_status(adapter);
1123129794Stackerman	ixgb_update_stats_counters(adapter);
1124148887Srwatson	if (ixgb_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) {
1125129794Stackerman		ixgb_print_hw_stats(adapter);
1126129794Stackerman	}
1127199539Sjhb	if (adapter->tx_timer != 0 && --adapter->tx_timer == 0)
1128199539Sjhb		ixgb_watchdog(adapter);
1129199539Sjhb	callout_reset(&adapter->timer, hz, ixgb_local_timer, adapter);
1130129794Stackerman}
1131129794Stackerman
1132129794Stackermanstatic void
1133129794Stackermanixgb_print_link_status(struct adapter * adapter)
1134129794Stackerman{
1135129794Stackerman	if (adapter->hw.link_up) {
1136129794Stackerman		if (!adapter->link_active) {
1137198987Sjhb			if_printf(adapter->ifp, "Link is up %d Mbps %s \n",
1138129794Stackerman			       10000,
1139129794Stackerman			       "Full Duplex");
1140129794Stackerman			adapter->link_active = 1;
1141129794Stackerman		}
1142129794Stackerman	} else {
1143129794Stackerman		if (adapter->link_active) {
1144198987Sjhb			if_printf(adapter->ifp, "Link is Down \n");
1145129794Stackerman			adapter->link_active = 0;
1146129794Stackerman		}
1147129794Stackerman	}
1148129794Stackerman
1149129794Stackerman	return;
1150129794Stackerman}
1151129794Stackerman
1152129794Stackerman
1153129794Stackerman
1154129794Stackerman/*********************************************************************
1155129794Stackerman *
1156129794Stackerman *  This routine disables all traffic on the adapter by issuing a
1157129794Stackerman *  global reset on the MAC and deallocates TX/RX buffers.
1158129794Stackerman *
1159129794Stackerman **********************************************************************/
1160129794Stackerman
1161129794Stackermanstatic void
1162129794Stackermanixgb_stop(void *arg)
1163129794Stackerman{
1164129794Stackerman	struct ifnet   *ifp;
1165129794Stackerman	struct adapter *adapter = arg;
1166147256Sbrooks	ifp = adapter->ifp;
1167129794Stackerman
1168144651Salc	IXGB_LOCK_ASSERT(adapter);
1169144651Salc
1170129794Stackerman	INIT_DEBUGOUT("ixgb_stop: begin\n");
1171129794Stackerman	ixgb_disable_intr(adapter);
1172129794Stackerman	adapter->hw.adapter_stopped = FALSE;
1173129794Stackerman	ixgb_adapter_stop(&adapter->hw);
1174144651Salc	callout_stop(&adapter->timer);
1175129794Stackerman	ixgb_free_transmit_structures(adapter);
1176129794Stackerman	ixgb_free_receive_structures(adapter);
1177129794Stackerman
1178129794Stackerman	/* Tell the stack that the interface is no longer active */
1179148887Srwatson	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1180199539Sjhb	adapter->tx_timer = 0;
1181129794Stackerman
1182129794Stackerman	return;
1183129794Stackerman}
1184129794Stackerman
1185129794Stackerman
1186129794Stackerman/*********************************************************************
1187129794Stackerman *
1188129794Stackerman *  Determine hardware revision.
1189129794Stackerman *
1190129794Stackerman **********************************************************************/
1191129794Stackermanstatic void
1192129794Stackermanixgb_identify_hardware(struct adapter * adapter)
1193129794Stackerman{
1194129794Stackerman	device_t        dev = adapter->dev;
1195129794Stackerman
1196129794Stackerman	/* Make sure our PCI config space has the necessary stuff set */
1197129794Stackerman	adapter->hw.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
1198129794Stackerman	if (!((adapter->hw.pci_cmd_word & PCIM_CMD_BUSMASTEREN) &&
1199129794Stackerman	      (adapter->hw.pci_cmd_word & PCIM_CMD_MEMEN))) {
1200198987Sjhb		device_printf(dev,
1201198987Sjhb		    "Memory Access and/or Bus Master bits were not set!\n");
1202129794Stackerman		adapter->hw.pci_cmd_word |=
1203129794Stackerman			(PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
1204129794Stackerman		pci_write_config(dev, PCIR_COMMAND, adapter->hw.pci_cmd_word, 2);
1205129794Stackerman	}
1206129794Stackerman	/* Save off the information about this board */
1207129794Stackerman	adapter->hw.vendor_id = pci_get_vendor(dev);
1208129794Stackerman	adapter->hw.device_id = pci_get_device(dev);
1209129794Stackerman	adapter->hw.revision_id = pci_read_config(dev, PCIR_REVID, 1);
1210129794Stackerman	adapter->hw.subsystem_vendor_id = pci_read_config(dev, PCIR_SUBVEND_0, 2);
1211129794Stackerman	adapter->hw.subsystem_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
1212129794Stackerman
1213129794Stackerman	/* Set MacType, etc. based on this PCI info */
1214129794Stackerman	switch (adapter->hw.device_id) {
1215129794Stackerman	case IXGB_DEVICE_ID_82597EX:
1216129794Stackerman	case IXGB_DEVICE_ID_82597EX_SR:
1217129794Stackerman		adapter->hw.mac_type = ixgb_82597;
1218129794Stackerman		break;
1219129794Stackerman	default:
1220129794Stackerman		INIT_DEBUGOUT1("Unknown device if 0x%x", adapter->hw.device_id);
1221198987Sjhb		device_printf(dev, "unsupported device id 0x%x\n",
1222198987Sjhb		    adapter->hw.device_id);
1223129794Stackerman	}
1224129794Stackerman
1225129794Stackerman	return;
1226129794Stackerman}
1227129794Stackerman
1228129794Stackermanstatic int
1229129794Stackermanixgb_allocate_pci_resources(struct adapter * adapter)
1230129794Stackerman{
1231129794Stackerman	int             rid;
1232129794Stackerman	device_t        dev = adapter->dev;
1233129794Stackerman
1234129794Stackerman	rid = IXGB_MMBA;
1235129794Stackerman	adapter->res_memory = bus_alloc_resource(dev, SYS_RES_MEMORY,
1236129794Stackerman						 &rid, 0, ~0, 1,
1237129794Stackerman						 RF_ACTIVE);
1238129794Stackerman	if (!(adapter->res_memory)) {
1239198987Sjhb		device_printf(dev, "Unable to allocate bus resource: memory\n");
1240129794Stackerman		return (ENXIO);
1241129794Stackerman	}
1242129794Stackerman	adapter->osdep.mem_bus_space_tag =
1243129794Stackerman		rman_get_bustag(adapter->res_memory);
1244129794Stackerman	adapter->osdep.mem_bus_space_handle =
1245129794Stackerman		rman_get_bushandle(adapter->res_memory);
1246129794Stackerman	adapter->hw.hw_addr = (uint8_t *) & adapter->osdep.mem_bus_space_handle;
1247129794Stackerman
1248129794Stackerman	rid = 0x0;
1249129794Stackerman	adapter->res_interrupt = bus_alloc_resource(dev, SYS_RES_IRQ,
1250129794Stackerman						    &rid, 0, ~0, 1,
1251129794Stackerman						  RF_SHAREABLE | RF_ACTIVE);
1252129794Stackerman	if (!(adapter->res_interrupt)) {
1253198987Sjhb		device_printf(dev,
1254198987Sjhb		    "Unable to allocate bus resource: interrupt\n");
1255129794Stackerman		return (ENXIO);
1256129794Stackerman	}
1257144651Salc	if (bus_setup_intr(dev, adapter->res_interrupt,
1258144651Salc			   INTR_TYPE_NET | INTR_MPSAFE,
1259166901Spiso			   NULL, (void (*) (void *))ixgb_intr, adapter,
1260129794Stackerman			   &adapter->int_handler_tag)) {
1261198987Sjhb		device_printf(dev, "Error registering interrupt handler!\n");
1262129794Stackerman		return (ENXIO);
1263129794Stackerman	}
1264129794Stackerman	adapter->hw.back = &adapter->osdep;
1265129794Stackerman
1266129794Stackerman	return (0);
1267129794Stackerman}
1268129794Stackerman
1269129794Stackermanstatic void
1270129794Stackermanixgb_free_pci_resources(struct adapter * adapter)
1271129794Stackerman{
1272129794Stackerman	device_t        dev = adapter->dev;
1273129794Stackerman
1274129794Stackerman	if (adapter->res_interrupt != NULL) {
1275129794Stackerman		bus_teardown_intr(dev, adapter->res_interrupt,
1276129794Stackerman				  adapter->int_handler_tag);
1277129794Stackerman		bus_release_resource(dev, SYS_RES_IRQ, 0,
1278129794Stackerman				     adapter->res_interrupt);
1279129794Stackerman	}
1280129794Stackerman	if (adapter->res_memory != NULL) {
1281129794Stackerman		bus_release_resource(dev, SYS_RES_MEMORY, IXGB_MMBA,
1282129794Stackerman				     adapter->res_memory);
1283129794Stackerman	}
1284129794Stackerman	if (adapter->res_ioport != NULL) {
1285129794Stackerman		bus_release_resource(dev, SYS_RES_IOPORT, adapter->io_rid,
1286129794Stackerman				     adapter->res_ioport);
1287129794Stackerman	}
1288129794Stackerman	return;
1289129794Stackerman}
1290129794Stackerman
1291129794Stackerman/*********************************************************************
1292129794Stackerman *
1293129794Stackerman *  Initialize the hardware to a configuration as specified by the
1294129794Stackerman *  adapter structure. The controller is reset, the EEPROM is
1295129794Stackerman *  verified, the MAC address is set, then the shared initialization
1296129794Stackerman *  routines are called.
1297129794Stackerman *
1298129794Stackerman **********************************************************************/
1299129794Stackermanstatic int
1300129794Stackermanixgb_hardware_init(struct adapter * adapter)
1301129794Stackerman{
1302129794Stackerman	/* Issue a global reset */
1303129794Stackerman	adapter->hw.adapter_stopped = FALSE;
1304129794Stackerman	ixgb_adapter_stop(&adapter->hw);
1305129794Stackerman
1306129794Stackerman	/* Make sure we have a good EEPROM before we read from it */
1307129794Stackerman	if (!ixgb_validate_eeprom_checksum(&adapter->hw)) {
1308198987Sjhb		device_printf(adapter->dev,
1309198987Sjhb		    "The EEPROM Checksum Is Not Valid\n");
1310129794Stackerman		return (EIO);
1311129794Stackerman	}
1312129794Stackerman	if (!ixgb_init_hw(&adapter->hw)) {
1313198987Sjhb		device_printf(adapter->dev, "Hardware Initialization Failed");
1314129794Stackerman		return (EIO);
1315129794Stackerman	}
1316129794Stackerman
1317129794Stackerman	return (0);
1318129794Stackerman}
1319129794Stackerman
1320129794Stackerman/*********************************************************************
1321129794Stackerman *
1322129794Stackerman *  Setup networking device structure and register an interface.
1323129794Stackerman *
1324129794Stackerman **********************************************************************/
1325211907Syongaristatic int
1326129794Stackermanixgb_setup_interface(device_t dev, struct adapter * adapter)
1327129794Stackerman{
1328129794Stackerman	struct ifnet   *ifp;
1329129794Stackerman	INIT_DEBUGOUT("ixgb_setup_interface: begin");
1330129794Stackerman
1331147256Sbrooks	ifp = adapter->ifp = if_alloc(IFT_ETHER);
1332211907Syongari	if (ifp == NULL) {
1333211907Syongari		device_printf(dev, "can not allocate ifnet structure\n");
1334211907Syongari		return (-1);
1335211907Syongari	}
1336129794Stackerman#if __FreeBSD_version >= 502000
1337129794Stackerman	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1338129794Stackerman#else
1339198987Sjhb	ifp->if_unit = device_get_unit(dev);
1340129794Stackerman	ifp->if_name = "ixgb";
1341129794Stackerman#endif
1342129794Stackerman	ifp->if_mtu = ETHERMTU;
1343129794Stackerman	ifp->if_baudrate = 1000000000;
1344129794Stackerman	ifp->if_init = ixgb_init;
1345129794Stackerman	ifp->if_softc = adapter;
1346144651Salc	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1347129794Stackerman	ifp->if_ioctl = ixgb_ioctl;
1348129794Stackerman	ifp->if_start = ixgb_start;
1349129794Stackerman	ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 1;
1350129794Stackerman
1351129794Stackerman#if __FreeBSD_version < 500000
1352129794Stackerman	ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
1353129794Stackerman#else
1354147256Sbrooks	ether_ifattach(ifp, adapter->hw.curr_mac_addr);
1355129794Stackerman#endif
1356129794Stackerman
1357129794Stackerman	ifp->if_capabilities = IFCAP_HWCSUM;
1358129794Stackerman
1359129794Stackerman	/*
1360129794Stackerman	 * Tell the upper layer(s) we support long frames.
1361129794Stackerman	 */
1362129794Stackerman	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
1363129794Stackerman
1364129794Stackerman#if __FreeBSD_version >= 500000
1365129794Stackerman	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
1366129794Stackerman#endif
1367148637Sbrueffer
1368148637Sbrueffer	ifp->if_capenable = ifp->if_capabilities;
1369148637Sbrueffer
1370150789Sglebius#ifdef DEVICE_POLLING
1371150789Sglebius	ifp->if_capabilities |= IFCAP_POLLING;
1372150789Sglebius#endif
1373150789Sglebius
1374129794Stackerman	/*
1375129794Stackerman	 * Specify the media types supported by this adapter and register
1376129794Stackerman	 * callbacks to update media and link information
1377129794Stackerman	 */
1378129794Stackerman	ifmedia_init(&adapter->media, IFM_IMASK, ixgb_media_change,
1379129794Stackerman		     ixgb_media_status);
1380129794Stackerman	ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX | IFM_FDX,
1381129794Stackerman		    0, NULL);
1382129794Stackerman	ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX,
1383129794Stackerman		    0, NULL);
1384129794Stackerman	ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
1385129794Stackerman	ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
1386129794Stackerman
1387211907Syongari	return (0);
1388129794Stackerman}
1389129794Stackerman
1390129794Stackerman/********************************************************************
1391129794Stackerman * Manage DMA'able memory.
1392129794Stackerman *******************************************************************/
1393129794Stackermanstatic void
1394129794Stackermanixgb_dmamap_cb(void *arg, bus_dma_segment_t * segs, int nseg, int error)
1395129794Stackerman{
1396129794Stackerman	if (error)
1397129794Stackerman		return;
1398129794Stackerman	*(bus_addr_t *) arg = segs->ds_addr;
1399129794Stackerman	return;
1400129794Stackerman}
1401129794Stackerman
1402129794Stackermanstatic int
1403129794Stackermanixgb_dma_malloc(struct adapter * adapter, bus_size_t size,
1404129794Stackerman		struct ixgb_dma_alloc * dma, int mapflags)
1405129794Stackerman{
1406198987Sjhb	device_t dev;
1407129794Stackerman	int             r;
1408129794Stackerman
1409198987Sjhb	dev = adapter->dev;
1410129794Stackerman	r = bus_dma_tag_create(NULL,	/* parent */
1411129794Stackerman			       PAGE_SIZE, 0,	/* alignment, bounds */
1412129794Stackerman			       BUS_SPACE_MAXADDR,	/* lowaddr */
1413129794Stackerman			       BUS_SPACE_MAXADDR,	/* highaddr */
1414129794Stackerman			       NULL, NULL,	/* filter, filterarg */
1415129794Stackerman			       size,	/* maxsize */
1416129794Stackerman			       1,	/* nsegments */
1417129794Stackerman			       size,	/* maxsegsize */
1418129794Stackerman			       BUS_DMA_ALLOCNOW,	/* flags */
1419129794Stackerman#if __FreeBSD_version >= 502000
1420129794Stackerman			       NULL,	/* lockfunc */
1421129794Stackerman			       NULL,	/* lockfuncarg */
1422129794Stackerman#endif
1423129794Stackerman			       &dma->dma_tag);
1424129794Stackerman	if (r != 0) {
1425198987Sjhb		device_printf(dev, "ixgb_dma_malloc: bus_dma_tag_create failed; "
1426198987Sjhb		       "error %u\n", r);
1427129794Stackerman		goto fail_0;
1428129794Stackerman	}
1429129794Stackerman	r = bus_dmamem_alloc(dma->dma_tag, (void **)&dma->dma_vaddr,
1430129794Stackerman			     BUS_DMA_NOWAIT, &dma->dma_map);
1431129794Stackerman	if (r != 0) {
1432198987Sjhb		device_printf(dev, "ixgb_dma_malloc: bus_dmamem_alloc failed; "
1433198987Sjhb		       "error %u\n", r);
1434144183Smux		goto fail_1;
1435129794Stackerman	}
1436129794Stackerman	r = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr,
1437129794Stackerman			    size,
1438129794Stackerman			    ixgb_dmamap_cb,
1439129794Stackerman			    &dma->dma_paddr,
1440129794Stackerman			    mapflags | BUS_DMA_NOWAIT);
1441129794Stackerman	if (r != 0) {
1442198987Sjhb		device_printf(dev, "ixgb_dma_malloc: bus_dmamap_load failed; "
1443198987Sjhb		       "error %u\n", r);
1444144183Smux		goto fail_2;
1445129794Stackerman	}
1446129794Stackerman	dma->dma_size = size;
1447129794Stackerman	return (0);
1448129794Stackermanfail_2:
1449129794Stackerman	bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
1450129794Stackermanfail_1:
1451129794Stackerman	bus_dma_tag_destroy(dma->dma_tag);
1452129794Stackermanfail_0:
1453129794Stackerman	dma->dma_map = NULL;
1454129794Stackerman	dma->dma_tag = NULL;
1455129794Stackerman	return (r);
1456129794Stackerman}
1457129794Stackerman
1458129794Stackerman
1459129794Stackerman
1460129794Stackermanstatic void
1461129794Stackermanixgb_dma_free(struct adapter * adapter, struct ixgb_dma_alloc * dma)
1462129794Stackerman{
1463129794Stackerman	bus_dmamap_unload(dma->dma_tag, dma->dma_map);
1464129794Stackerman	bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
1465129794Stackerman	bus_dma_tag_destroy(dma->dma_tag);
1466129794Stackerman}
1467129794Stackerman
1468129794Stackerman/*********************************************************************
1469129794Stackerman *
1470129794Stackerman *  Allocate memory for tx_buffer structures. The tx_buffer stores all
1471129794Stackerman *  the information needed to transmit a packet on the wire.
1472129794Stackerman *
1473129794Stackerman **********************************************************************/
1474129794Stackermanstatic int
1475129794Stackermanixgb_allocate_transmit_structures(struct adapter * adapter)
1476129794Stackerman{
1477129794Stackerman	if (!(adapter->tx_buffer_area =
1478129794Stackerman	      (struct ixgb_buffer *) malloc(sizeof(struct ixgb_buffer) *
1479129794Stackerman					    adapter->num_tx_desc, M_DEVBUF,
1480129794Stackerman					    M_NOWAIT | M_ZERO))) {
1481198987Sjhb		device_printf(adapter->dev,
1482198987Sjhb		    "Unable to allocate tx_buffer memory\n");
1483129794Stackerman		return ENOMEM;
1484129794Stackerman	}
1485129794Stackerman	bzero(adapter->tx_buffer_area,
1486129794Stackerman	      sizeof(struct ixgb_buffer) * adapter->num_tx_desc);
1487129794Stackerman
1488129794Stackerman	return 0;
1489129794Stackerman}
1490129794Stackerman
1491129794Stackerman/*********************************************************************
1492129794Stackerman *
1493129794Stackerman *  Allocate and initialize transmit structures.
1494129794Stackerman *
1495129794Stackerman **********************************************************************/
1496129794Stackermanstatic int
1497129794Stackermanixgb_setup_transmit_structures(struct adapter * adapter)
1498129794Stackerman{
1499129794Stackerman	/*
1500129794Stackerman	 * Setup DMA descriptor areas.
1501129794Stackerman	 */
1502129794Stackerman	if (bus_dma_tag_create(NULL,	/* parent */
1503129794Stackerman			       PAGE_SIZE, 0,	/* alignment, bounds */
1504129794Stackerman			       BUS_SPACE_MAXADDR,	/* lowaddr */
1505129794Stackerman			       BUS_SPACE_MAXADDR,	/* highaddr */
1506129794Stackerman			       NULL, NULL,	/* filter, filterarg */
1507129794Stackerman			       MCLBYTES * IXGB_MAX_SCATTER,	/* maxsize */
1508129794Stackerman			       IXGB_MAX_SCATTER,	/* nsegments */
1509129794Stackerman			       MCLBYTES,	/* maxsegsize */
1510129794Stackerman			       BUS_DMA_ALLOCNOW,	/* flags */
1511129794Stackerman#if __FreeBSD_version >= 502000
1512129794Stackerman			       NULL,	/* lockfunc */
1513129794Stackerman			       NULL,	/* lockfuncarg */
1514129794Stackerman#endif
1515129794Stackerman			       &adapter->txtag)) {
1516198987Sjhb		device_printf(adapter->dev, "Unable to allocate TX DMA tag\n");
1517129794Stackerman		return (ENOMEM);
1518129794Stackerman	}
1519129794Stackerman	if (ixgb_allocate_transmit_structures(adapter))
1520129794Stackerman		return ENOMEM;
1521129794Stackerman
1522129794Stackerman	bzero((void *)adapter->tx_desc_base,
1523129794Stackerman	      (sizeof(struct ixgb_tx_desc)) * adapter->num_tx_desc);
1524129794Stackerman
1525129794Stackerman	adapter->next_avail_tx_desc = 0;
1526129794Stackerman	adapter->oldest_used_tx_desc = 0;
1527129794Stackerman
1528129794Stackerman	/* Set number of descriptors available */
1529129794Stackerman	adapter->num_tx_desc_avail = adapter->num_tx_desc;
1530129794Stackerman
1531129794Stackerman	/* Set checksum context */
1532129794Stackerman	adapter->active_checksum_context = OFFLOAD_NONE;
1533129794Stackerman
1534129794Stackerman	return 0;
1535129794Stackerman}
1536129794Stackerman
1537129794Stackerman/*********************************************************************
1538129794Stackerman *
1539129794Stackerman *  Enable transmit unit.
1540129794Stackerman *
1541129794Stackerman **********************************************************************/
1542129794Stackermanstatic void
1543129794Stackermanixgb_initialize_transmit_unit(struct adapter * adapter)
1544129794Stackerman{
1545129794Stackerman	u_int32_t       reg_tctl;
1546144183Smux	u_int64_t       tdba = adapter->txdma.dma_paddr;
1547129794Stackerman
1548129794Stackerman	/* Setup the Base and Length of the Tx Descriptor Ring */
1549129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDBAL,
1550129794Stackerman		       (tdba & 0x00000000ffffffffULL));
1551129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDBAH, (tdba >> 32));
1552129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDLEN,
1553129794Stackerman		       adapter->num_tx_desc *
1554129794Stackerman		       sizeof(struct ixgb_tx_desc));
1555129794Stackerman
1556129794Stackerman	/* Setup the HW Tx Head and Tail descriptor pointers */
1557129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDH, 0);
1558129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDT, 0);
1559129794Stackerman
1560129794Stackerman
1561129794Stackerman	HW_DEBUGOUT2("Base = %x, Length = %x\n",
1562129794Stackerman		     IXGB_READ_REG(&adapter->hw, TDBAL),
1563129794Stackerman		     IXGB_READ_REG(&adapter->hw, TDLEN));
1564129794Stackerman
1565129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TIDV, adapter->tx_int_delay);
1566129794Stackerman
1567129794Stackerman
1568129794Stackerman	/* Program the Transmit Control Register */
1569129794Stackerman	reg_tctl = IXGB_READ_REG(&adapter->hw, TCTL);
1570129794Stackerman	reg_tctl = IXGB_TCTL_TCE | IXGB_TCTL_TXEN | IXGB_TCTL_TPDE;
1571129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TCTL, reg_tctl);
1572129794Stackerman
1573129794Stackerman	/* Setup Transmit Descriptor Settings for this adapter */
1574129794Stackerman	adapter->txd_cmd = IXGB_TX_DESC_TYPE | IXGB_TX_DESC_CMD_RS;
1575129794Stackerman
1576129794Stackerman	if (adapter->tx_int_delay > 0)
1577129794Stackerman		adapter->txd_cmd |= IXGB_TX_DESC_CMD_IDE;
1578129794Stackerman	return;
1579129794Stackerman}
1580129794Stackerman
1581129794Stackerman/*********************************************************************
1582129794Stackerman *
1583129794Stackerman *  Free all transmit related data structures.
1584129794Stackerman *
1585129794Stackerman **********************************************************************/
1586129794Stackermanstatic void
1587129794Stackermanixgb_free_transmit_structures(struct adapter * adapter)
1588129794Stackerman{
1589129794Stackerman	struct ixgb_buffer *tx_buffer;
1590129794Stackerman	int             i;
1591129794Stackerman
1592129794Stackerman	INIT_DEBUGOUT("free_transmit_structures: begin");
1593129794Stackerman
1594129794Stackerman	if (adapter->tx_buffer_area != NULL) {
1595129794Stackerman		tx_buffer = adapter->tx_buffer_area;
1596129794Stackerman		for (i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
1597129794Stackerman			if (tx_buffer->m_head != NULL) {
1598129794Stackerman				bus_dmamap_unload(adapter->txtag, tx_buffer->map);
1599129794Stackerman				bus_dmamap_destroy(adapter->txtag, tx_buffer->map);
1600129794Stackerman				m_freem(tx_buffer->m_head);
1601129794Stackerman			}
1602129794Stackerman			tx_buffer->m_head = NULL;
1603129794Stackerman		}
1604129794Stackerman	}
1605129794Stackerman	if (adapter->tx_buffer_area != NULL) {
1606129794Stackerman		free(adapter->tx_buffer_area, M_DEVBUF);
1607129794Stackerman		adapter->tx_buffer_area = NULL;
1608129794Stackerman	}
1609129794Stackerman	if (adapter->txtag != NULL) {
1610129794Stackerman		bus_dma_tag_destroy(adapter->txtag);
1611129794Stackerman		adapter->txtag = NULL;
1612129794Stackerman	}
1613129794Stackerman	return;
1614129794Stackerman}
1615129794Stackerman
1616129794Stackerman/*********************************************************************
1617129794Stackerman *
1618129794Stackerman *  The offload context needs to be set when we transfer the first
1619129794Stackerman *  packet of a particular protocol (TCP/UDP). We change the
1620129794Stackerman *  context only if the protocol type changes.
1621129794Stackerman *
1622129794Stackerman **********************************************************************/
1623129794Stackermanstatic void
1624129794Stackermanixgb_transmit_checksum_setup(struct adapter * adapter,
1625129794Stackerman			     struct mbuf * mp,
1626129794Stackerman			     u_int8_t * txd_popts)
1627129794Stackerman{
1628129794Stackerman	struct ixgb_context_desc *TXD;
1629129794Stackerman	struct ixgb_buffer *tx_buffer;
1630129794Stackerman	int             curr_txd;
1631129794Stackerman
1632129794Stackerman	if (mp->m_pkthdr.csum_flags) {
1633129794Stackerman
1634129794Stackerman		if (mp->m_pkthdr.csum_flags & CSUM_TCP) {
1635129794Stackerman			*txd_popts = IXGB_TX_DESC_POPTS_TXSM;
1636129794Stackerman			if (adapter->active_checksum_context == OFFLOAD_TCP_IP)
1637129794Stackerman				return;
1638129794Stackerman			else
1639129794Stackerman				adapter->active_checksum_context = OFFLOAD_TCP_IP;
1640129794Stackerman		} else if (mp->m_pkthdr.csum_flags & CSUM_UDP) {
1641129794Stackerman			*txd_popts = IXGB_TX_DESC_POPTS_TXSM;
1642129794Stackerman			if (adapter->active_checksum_context == OFFLOAD_UDP_IP)
1643129794Stackerman				return;
1644129794Stackerman			else
1645129794Stackerman				adapter->active_checksum_context = OFFLOAD_UDP_IP;
1646129794Stackerman		} else {
1647129794Stackerman			*txd_popts = 0;
1648129794Stackerman			return;
1649129794Stackerman		}
1650129794Stackerman	} else {
1651129794Stackerman		*txd_popts = 0;
1652129794Stackerman		return;
1653129794Stackerman	}
1654129794Stackerman
1655129794Stackerman	/*
1656129794Stackerman	 * If we reach this point, the checksum offload context needs to be
1657129794Stackerman	 * reset.
1658129794Stackerman	 */
1659129794Stackerman	curr_txd = adapter->next_avail_tx_desc;
1660129794Stackerman	tx_buffer = &adapter->tx_buffer_area[curr_txd];
1661129794Stackerman	TXD = (struct ixgb_context_desc *) & adapter->tx_desc_base[curr_txd];
1662129794Stackerman
1663129794Stackerman
1664129794Stackerman	TXD->tucss = ENET_HEADER_SIZE + sizeof(struct ip);
1665129794Stackerman	TXD->tucse = 0;
1666129794Stackerman
1667129794Stackerman	TXD->mss = 0;
1668129794Stackerman
1669129794Stackerman	if (adapter->active_checksum_context == OFFLOAD_TCP_IP) {
1670129794Stackerman		TXD->tucso =
1671129794Stackerman			ENET_HEADER_SIZE + sizeof(struct ip) +
1672129794Stackerman			offsetof(struct tcphdr, th_sum);
1673129794Stackerman	} else if (adapter->active_checksum_context == OFFLOAD_UDP_IP) {
1674129794Stackerman		TXD->tucso =
1675129794Stackerman			ENET_HEADER_SIZE + sizeof(struct ip) +
1676129794Stackerman			offsetof(struct udphdr, uh_sum);
1677129794Stackerman	}
1678129794Stackerman	TXD->cmd_type_len = IXGB_CONTEXT_DESC_CMD_TCP | IXGB_TX_DESC_CMD_RS | IXGB_CONTEXT_DESC_CMD_IDE;
1679129794Stackerman
1680129794Stackerman	tx_buffer->m_head = NULL;
1681129794Stackerman
1682129794Stackerman	if (++curr_txd == adapter->num_tx_desc)
1683129794Stackerman		curr_txd = 0;
1684129794Stackerman
1685129794Stackerman	adapter->num_tx_desc_avail--;
1686129794Stackerman	adapter->next_avail_tx_desc = curr_txd;
1687129794Stackerman	return;
1688129794Stackerman}
1689129794Stackerman
1690129794Stackerman/**********************************************************************
1691129794Stackerman *
1692129794Stackerman *  Examine each tx_buffer in the used queue. If the hardware is done
1693129794Stackerman *  processing the packet then free associated resources. The
1694129794Stackerman *  tx_buffer is put back on the free queue.
1695129794Stackerman *
1696129794Stackerman **********************************************************************/
1697129794Stackermanstatic void
1698129794Stackermanixgb_clean_transmit_interrupts(struct adapter * adapter)
1699129794Stackerman{
1700129794Stackerman	int             i, num_avail;
1701129794Stackerman	struct ixgb_buffer *tx_buffer;
1702129794Stackerman	struct ixgb_tx_desc *tx_desc;
1703129794Stackerman
1704144651Salc	IXGB_LOCK_ASSERT(adapter);
1705129794Stackerman
1706129794Stackerman	if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
1707129794Stackerman		return;
1708129794Stackerman
1709129794Stackerman#ifdef _SV_
1710129794Stackerman	adapter->clean_tx_interrupts++;
1711129794Stackerman#endif
1712129794Stackerman	num_avail = adapter->num_tx_desc_avail;
1713129794Stackerman	i = adapter->oldest_used_tx_desc;
1714129794Stackerman
1715129794Stackerman	tx_buffer = &adapter->tx_buffer_area[i];
1716129794Stackerman	tx_desc = &adapter->tx_desc_base[i];
1717129794Stackerman
1718129794Stackerman	while (tx_desc->status & IXGB_TX_DESC_STATUS_DD) {
1719129794Stackerman
1720129794Stackerman		tx_desc->status = 0;
1721129794Stackerman		num_avail++;
1722129794Stackerman
1723129794Stackerman		if (tx_buffer->m_head) {
1724129794Stackerman			bus_dmamap_sync(adapter->txtag, tx_buffer->map,
1725129794Stackerman					BUS_DMASYNC_POSTWRITE);
1726129794Stackerman			bus_dmamap_unload(adapter->txtag, tx_buffer->map);
1727129794Stackerman			bus_dmamap_destroy(adapter->txtag, tx_buffer->map);
1728129794Stackerman			m_freem(tx_buffer->m_head);
1729129794Stackerman			tx_buffer->m_head = NULL;
1730129794Stackerman		}
1731129794Stackerman		if (++i == adapter->num_tx_desc)
1732129794Stackerman			i = 0;
1733129794Stackerman
1734129794Stackerman		tx_buffer = &adapter->tx_buffer_area[i];
1735129794Stackerman		tx_desc = &adapter->tx_desc_base[i];
1736129794Stackerman	}
1737129794Stackerman
1738129794Stackerman	adapter->oldest_used_tx_desc = i;
1739129794Stackerman
1740129794Stackerman	/*
1741148887Srwatson	 * If we have enough room, clear IFF_DRV_OACTIVE to tell the stack that
1742129794Stackerman	 * it is OK to send packets. If there are no pending descriptors,
1743129794Stackerman	 * clear the timeout. Otherwise, if some descriptors have been freed,
1744129794Stackerman	 * restart the timeout.
1745129794Stackerman	 */
1746129794Stackerman	if (num_avail > IXGB_TX_CLEANUP_THRESHOLD) {
1747147256Sbrooks		struct ifnet   *ifp = adapter->ifp;
1748129794Stackerman
1749148887Srwatson		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1750129794Stackerman		if (num_avail == adapter->num_tx_desc)
1751199539Sjhb			adapter->tx_timer = 0;
1752129794Stackerman		else if (num_avail == adapter->num_tx_desc_avail)
1753199539Sjhb			adapter->tx_timer = IXGB_TX_TIMEOUT;
1754129794Stackerman	}
1755129794Stackerman	adapter->num_tx_desc_avail = num_avail;
1756129794Stackerman	return;
1757129794Stackerman}
1758129794Stackerman
1759129794Stackerman
1760129794Stackerman/*********************************************************************
1761129794Stackerman *
1762129794Stackerman *  Get a buffer from system mbuf buffer pool.
1763129794Stackerman *
1764129794Stackerman **********************************************************************/
1765129794Stackermanstatic int
1766129794Stackermanixgb_get_buf(int i, struct adapter * adapter,
1767129794Stackerman	     struct mbuf * nmp)
1768129794Stackerman{
1769129794Stackerman	register struct mbuf *mp = nmp;
1770129794Stackerman	struct ixgb_buffer *rx_buffer;
1771129794Stackerman	struct ifnet   *ifp;
1772129794Stackerman	bus_addr_t      paddr;
1773129794Stackerman	int             error;
1774129794Stackerman
1775147256Sbrooks	ifp = adapter->ifp;
1776129794Stackerman
1777129794Stackerman	if (mp == NULL) {
1778129794Stackerman
1779129794Stackerman		mp = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
1780129794Stackerman
1781129794Stackerman		if (mp == NULL) {
1782129794Stackerman			adapter->mbuf_alloc_failed++;
1783129794Stackerman			return (ENOBUFS);
1784129794Stackerman		}
1785129794Stackerman		mp->m_len = mp->m_pkthdr.len = MCLBYTES;
1786129794Stackerman	} else {
1787129794Stackerman		mp->m_len = mp->m_pkthdr.len = MCLBYTES;
1788129794Stackerman		mp->m_data = mp->m_ext.ext_buf;
1789129794Stackerman		mp->m_next = NULL;
1790129794Stackerman	}
1791129794Stackerman
1792129794Stackerman	if (ifp->if_mtu <= ETHERMTU) {
1793129794Stackerman		m_adj(mp, ETHER_ALIGN);
1794129794Stackerman	}
1795129794Stackerman	rx_buffer = &adapter->rx_buffer_area[i];
1796129794Stackerman
1797129794Stackerman	/*
1798129794Stackerman	 * Using memory from the mbuf cluster pool, invoke the bus_dma
1799129794Stackerman	 * machinery to arrange the memory mapping.
1800129794Stackerman	 */
1801129794Stackerman	error = bus_dmamap_load(adapter->rxtag, rx_buffer->map,
1802129794Stackerman				mtod(mp, void *), mp->m_len,
1803129794Stackerman				ixgb_dmamap_cb, &paddr, 0);
1804129794Stackerman	if (error) {
1805129794Stackerman		m_free(mp);
1806129794Stackerman		return (error);
1807129794Stackerman	}
1808129794Stackerman	rx_buffer->m_head = mp;
1809129794Stackerman	adapter->rx_desc_base[i].buff_addr = htole64(paddr);
1810129794Stackerman	bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD);
1811129794Stackerman
1812129794Stackerman	return (0);
1813129794Stackerman}
1814129794Stackerman
1815129794Stackerman/*********************************************************************
1816129794Stackerman *
1817129794Stackerman *  Allocate memory for rx_buffer structures. Since we use one
1818129794Stackerman *  rx_buffer per received packet, the maximum number of rx_buffer's
1819129794Stackerman *  that we'll need is equal to the number of receive descriptors
1820129794Stackerman *  that we've allocated.
1821129794Stackerman *
1822129794Stackerman **********************************************************************/
1823129794Stackermanstatic int
1824129794Stackermanixgb_allocate_receive_structures(struct adapter * adapter)
1825129794Stackerman{
1826129794Stackerman	int             i, error;
1827129794Stackerman	struct ixgb_buffer *rx_buffer;
1828129794Stackerman
1829129794Stackerman	if (!(adapter->rx_buffer_area =
1830129794Stackerman	      (struct ixgb_buffer *) malloc(sizeof(struct ixgb_buffer) *
1831129794Stackerman					    adapter->num_rx_desc, M_DEVBUF,
1832129794Stackerman					    M_NOWAIT | M_ZERO))) {
1833198987Sjhb		device_printf(adapter->dev,
1834198987Sjhb		    "Unable to allocate rx_buffer memory\n");
1835129794Stackerman		return (ENOMEM);
1836129794Stackerman	}
1837129794Stackerman	bzero(adapter->rx_buffer_area,
1838129794Stackerman	      sizeof(struct ixgb_buffer) * adapter->num_rx_desc);
1839129794Stackerman
1840129794Stackerman	error = bus_dma_tag_create(NULL,	/* parent */
1841129794Stackerman				   PAGE_SIZE, 0,	/* alignment, bounds */
1842129794Stackerman				   BUS_SPACE_MAXADDR,	/* lowaddr */
1843129794Stackerman				   BUS_SPACE_MAXADDR,	/* highaddr */
1844129794Stackerman				   NULL, NULL,	/* filter, filterarg */
1845129794Stackerman				   MCLBYTES,	/* maxsize */
1846129794Stackerman				   1,	/* nsegments */
1847129794Stackerman				   MCLBYTES,	/* maxsegsize */
1848129794Stackerman				   BUS_DMA_ALLOCNOW,	/* flags */
1849129794Stackerman#if __FreeBSD_version >= 502000
1850129794Stackerman				   NULL,	/* lockfunc */
1851129794Stackerman				   NULL,	/* lockfuncarg */
1852129794Stackerman#endif
1853129794Stackerman				   &adapter->rxtag);
1854129794Stackerman	if (error != 0) {
1855198987Sjhb		device_printf(adapter->dev, "ixgb_allocate_receive_structures: "
1856129794Stackerman		       "bus_dma_tag_create failed; error %u\n",
1857198987Sjhb		       error);
1858129794Stackerman		goto fail_0;
1859129794Stackerman	}
1860129794Stackerman	rx_buffer = adapter->rx_buffer_area;
1861129794Stackerman	for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
1862129794Stackerman		error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
1863129794Stackerman					  &rx_buffer->map);
1864129794Stackerman		if (error != 0) {
1865198987Sjhb			device_printf(adapter->dev,
1866198987Sjhb			       "ixgb_allocate_receive_structures: "
1867129794Stackerman			       "bus_dmamap_create failed; error %u\n",
1868198987Sjhb			       error);
1869129794Stackerman			goto fail_1;
1870129794Stackerman		}
1871129794Stackerman	}
1872129794Stackerman
1873129794Stackerman	for (i = 0; i < adapter->num_rx_desc; i++) {
1874129794Stackerman		if (ixgb_get_buf(i, adapter, NULL) == ENOBUFS) {
1875129794Stackerman			adapter->rx_buffer_area[i].m_head = NULL;
1876129794Stackerman			adapter->rx_desc_base[i].buff_addr = 0;
1877129794Stackerman			return (ENOBUFS);
1878129794Stackerman		}
1879129794Stackerman	}
1880129794Stackerman
1881129794Stackerman	return (0);
1882129794Stackermanfail_1:
1883129794Stackerman	bus_dma_tag_destroy(adapter->rxtag);
1884129794Stackermanfail_0:
1885129794Stackerman	adapter->rxtag = NULL;
1886129794Stackerman	free(adapter->rx_buffer_area, M_DEVBUF);
1887129794Stackerman	adapter->rx_buffer_area = NULL;
1888129794Stackerman	return (error);
1889129794Stackerman}
1890129794Stackerman
1891129794Stackerman/*********************************************************************
1892129794Stackerman *
1893129794Stackerman *  Allocate and initialize receive structures.
1894129794Stackerman *
1895129794Stackerman **********************************************************************/
1896129794Stackermanstatic int
1897129794Stackermanixgb_setup_receive_structures(struct adapter * adapter)
1898129794Stackerman{
1899129794Stackerman	bzero((void *)adapter->rx_desc_base,
1900129794Stackerman	      (sizeof(struct ixgb_rx_desc)) * adapter->num_rx_desc);
1901129794Stackerman
1902129794Stackerman	if (ixgb_allocate_receive_structures(adapter))
1903129794Stackerman		return ENOMEM;
1904129794Stackerman
1905129794Stackerman	/* Setup our descriptor pointers */
1906129794Stackerman	adapter->next_rx_desc_to_check = 0;
1907129794Stackerman	adapter->next_rx_desc_to_use = 0;
1908129794Stackerman	return (0);
1909129794Stackerman}
1910129794Stackerman
1911129794Stackerman/*********************************************************************
1912129794Stackerman *
1913129794Stackerman *  Enable receive unit.
1914129794Stackerman *
1915129794Stackerman **********************************************************************/
1916129794Stackermanstatic void
1917129794Stackermanixgb_initialize_receive_unit(struct adapter * adapter)
1918129794Stackerman{
1919129794Stackerman	u_int32_t       reg_rctl;
1920129794Stackerman	u_int32_t       reg_rxcsum;
1921129794Stackerman	u_int32_t       reg_rxdctl;
1922129794Stackerman	struct ifnet   *ifp;
1923144183Smux	u_int64_t       rdba = adapter->rxdma.dma_paddr;
1924129794Stackerman
1925147256Sbrooks	ifp = adapter->ifp;
1926129794Stackerman
1927129794Stackerman	/*
1928129794Stackerman	 * Make sure receives are disabled while setting up the descriptor
1929129794Stackerman	 * ring
1930129794Stackerman	 */
1931129794Stackerman	reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL);
1932129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl & ~IXGB_RCTL_RXEN);
1933129794Stackerman
1934129794Stackerman	/* Set the Receive Delay Timer Register */
1935129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDTR,
1936129794Stackerman		       adapter->rx_int_delay);
1937129794Stackerman
1938129794Stackerman
1939129794Stackerman	/* Setup the Base and Length of the Rx Descriptor Ring */
1940129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDBAL,
1941129794Stackerman		       (rdba & 0x00000000ffffffffULL));
1942129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDBAH, (rdba >> 32));
1943129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDLEN, adapter->num_rx_desc *
1944129794Stackerman		       sizeof(struct ixgb_rx_desc));
1945129794Stackerman
1946129794Stackerman	/* Setup the HW Rx Head and Tail Descriptor Pointers */
1947129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDH, 0);
1948129794Stackerman
1949129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDT, adapter->num_rx_desc - 1);
1950129794Stackerman
1951129794Stackerman
1952129794Stackerman
1953129794Stackerman	reg_rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT
1954129794Stackerman		| RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT
1955129794Stackerman		| RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
1956129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RXDCTL, reg_rxdctl);
1957129794Stackerman
1958129794Stackerman
1959129794Stackerman	adapter->raidc = 1;
1960129794Stackerman	if (adapter->raidc) {
1961129794Stackerman		uint32_t        raidc;
1962129794Stackerman		uint8_t         poll_threshold;
1963129794Stackerman#define IXGB_RAIDC_POLL_DEFAULT 120
1964129794Stackerman
1965129794Stackerman		poll_threshold = ((adapter->num_rx_desc - 1) >> 3);
1966129794Stackerman		poll_threshold >>= 1;
1967129794Stackerman		poll_threshold &= 0x3F;
1968129794Stackerman		raidc = IXGB_RAIDC_EN | IXGB_RAIDC_RXT_GATE |
1969129794Stackerman			(IXGB_RAIDC_POLL_DEFAULT << IXGB_RAIDC_POLL_SHIFT) |
1970129794Stackerman			(adapter->rx_int_delay << IXGB_RAIDC_DELAY_SHIFT) |
1971129794Stackerman			poll_threshold;
1972129794Stackerman		IXGB_WRITE_REG(&adapter->hw, RAIDC, raidc);
1973129794Stackerman	}
1974129794Stackerman	/* Enable Receive Checksum Offload for TCP and UDP ? */
1975129794Stackerman	if (ifp->if_capenable & IFCAP_RXCSUM) {
1976129794Stackerman		reg_rxcsum = IXGB_READ_REG(&adapter->hw, RXCSUM);
1977129794Stackerman		reg_rxcsum |= IXGB_RXCSUM_TUOFL;
1978129794Stackerman		IXGB_WRITE_REG(&adapter->hw, RXCSUM, reg_rxcsum);
1979129794Stackerman	}
1980129794Stackerman	/* Setup the Receive Control Register */
1981129794Stackerman	reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL);
1982129794Stackerman	reg_rctl &= ~(3 << IXGB_RCTL_MO_SHIFT);
1983129794Stackerman	reg_rctl |= IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 | IXGB_RCTL_SECRC |
1984129794Stackerman		IXGB_RCTL_CFF |
1985129794Stackerman		(adapter->hw.mc_filter_type << IXGB_RCTL_MO_SHIFT);
1986129794Stackerman
1987129794Stackerman	switch (adapter->rx_buffer_len) {
1988129794Stackerman	default:
1989129794Stackerman	case IXGB_RXBUFFER_2048:
1990129794Stackerman		reg_rctl |= IXGB_RCTL_BSIZE_2048;
1991129794Stackerman		break;
1992129794Stackerman	case IXGB_RXBUFFER_4096:
1993129794Stackerman		reg_rctl |= IXGB_RCTL_BSIZE_4096;
1994129794Stackerman		break;
1995129794Stackerman	case IXGB_RXBUFFER_8192:
1996129794Stackerman		reg_rctl |= IXGB_RCTL_BSIZE_8192;
1997129794Stackerman		break;
1998129794Stackerman	case IXGB_RXBUFFER_16384:
1999129794Stackerman		reg_rctl |= IXGB_RCTL_BSIZE_16384;
2000129794Stackerman		break;
2001129794Stackerman	}
2002129794Stackerman
2003129794Stackerman	reg_rctl |= IXGB_RCTL_RXEN;
2004129794Stackerman
2005129794Stackerman
2006129794Stackerman	/* Enable Receives */
2007129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
2008129794Stackerman
2009129794Stackerman	return;
2010129794Stackerman}
2011129794Stackerman
2012129794Stackerman/*********************************************************************
2013129794Stackerman *
2014129794Stackerman *  Free receive related data structures.
2015129794Stackerman *
2016129794Stackerman **********************************************************************/
2017129794Stackermanstatic void
2018129794Stackermanixgb_free_receive_structures(struct adapter * adapter)
2019129794Stackerman{
2020129794Stackerman	struct ixgb_buffer *rx_buffer;
2021129794Stackerman	int             i;
2022129794Stackerman
2023129794Stackerman	INIT_DEBUGOUT("free_receive_structures: begin");
2024129794Stackerman
2025129794Stackerman	if (adapter->rx_buffer_area != NULL) {
2026129794Stackerman		rx_buffer = adapter->rx_buffer_area;
2027129794Stackerman		for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
2028129794Stackerman			if (rx_buffer->map != NULL) {
2029129794Stackerman				bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
2030129794Stackerman				bus_dmamap_destroy(adapter->rxtag, rx_buffer->map);
2031129794Stackerman			}
2032129794Stackerman			if (rx_buffer->m_head != NULL)
2033129794Stackerman				m_freem(rx_buffer->m_head);
2034129794Stackerman			rx_buffer->m_head = NULL;
2035129794Stackerman		}
2036129794Stackerman	}
2037129794Stackerman	if (adapter->rx_buffer_area != NULL) {
2038129794Stackerman		free(adapter->rx_buffer_area, M_DEVBUF);
2039129794Stackerman		adapter->rx_buffer_area = NULL;
2040129794Stackerman	}
2041129794Stackerman	if (adapter->rxtag != NULL) {
2042129794Stackerman		bus_dma_tag_destroy(adapter->rxtag);
2043129794Stackerman		adapter->rxtag = NULL;
2044129794Stackerman	}
2045129794Stackerman	return;
2046129794Stackerman}
2047129794Stackerman
2048129794Stackerman/*********************************************************************
2049129794Stackerman *
2050129794Stackerman *  This routine executes in interrupt context. It replenishes
2051129794Stackerman *  the mbufs in the descriptor and sends data which has been
2052129794Stackerman *  dma'ed into host memory to upper layer.
2053129794Stackerman *
2054129794Stackerman *  We loop at most count times if count is > 0, or until done if
2055129794Stackerman *  count < 0.
2056129794Stackerman *
2057129794Stackerman *********************************************************************/
2058193096Sattiliostatic int
2059129794Stackermanixgb_process_receive_interrupts(struct adapter * adapter, int count)
2060129794Stackerman{
2061129794Stackerman	struct ifnet   *ifp;
2062129794Stackerman	struct mbuf    *mp;
2063129794Stackerman#if __FreeBSD_version < 500000
2064129794Stackerman	struct ether_header *eh;
2065129794Stackerman#endif
2066129794Stackerman	int             eop = 0;
2067129794Stackerman	int             len;
2068129794Stackerman	u_int8_t        accept_frame = 0;
2069129794Stackerman	int             i;
2070129794Stackerman	int             next_to_use = 0;
2071129794Stackerman	int             eop_desc;
2072193096Sattilio	int		rx_npkts = 0;
2073129794Stackerman	/* Pointer to the receive descriptor being examined. */
2074129794Stackerman	struct ixgb_rx_desc *current_desc;
2075129794Stackerman
2076144651Salc	IXGB_LOCK_ASSERT(adapter);
2077144651Salc
2078147256Sbrooks	ifp = adapter->ifp;
2079129794Stackerman	i = adapter->next_rx_desc_to_check;
2080129794Stackerman	next_to_use = adapter->next_rx_desc_to_use;
2081129794Stackerman	eop_desc = adapter->next_rx_desc_to_check;
2082129794Stackerman	current_desc = &adapter->rx_desc_base[i];
2083129794Stackerman
2084129794Stackerman	if (!((current_desc->status) & IXGB_RX_DESC_STATUS_DD)) {
2085129794Stackerman#ifdef _SV_
2086129794Stackerman		adapter->no_pkts_avail++;
2087129794Stackerman#endif
2088193096Sattilio		return (rx_npkts);
2089129794Stackerman	}
2090129794Stackerman	while ((current_desc->status & IXGB_RX_DESC_STATUS_DD) && (count != 0)) {
2091129794Stackerman
2092129794Stackerman		mp = adapter->rx_buffer_area[i].m_head;
2093129794Stackerman		bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map,
2094129794Stackerman				BUS_DMASYNC_POSTREAD);
2095129794Stackerman		accept_frame = 1;
2096129794Stackerman		if (current_desc->status & IXGB_RX_DESC_STATUS_EOP) {
2097129794Stackerman			count--;
2098129794Stackerman			eop = 1;
2099129794Stackerman		} else {
2100129794Stackerman			eop = 0;
2101129794Stackerman		}
2102129794Stackerman		len = current_desc->length;
2103129794Stackerman
2104129794Stackerman		if (current_desc->errors & (IXGB_RX_DESC_ERRORS_CE |
2105129794Stackerman			    IXGB_RX_DESC_ERRORS_SE | IXGB_RX_DESC_ERRORS_P |
2106129794Stackerman					    IXGB_RX_DESC_ERRORS_RXE)) {
2107129794Stackerman			accept_frame = 0;
2108129794Stackerman		}
2109129794Stackerman		if (accept_frame) {
2110129794Stackerman
2111129794Stackerman			/* Assign correct length to the current fragment */
2112129794Stackerman			mp->m_len = len;
2113129794Stackerman
2114129794Stackerman			if (adapter->fmp == NULL) {
2115129794Stackerman				mp->m_pkthdr.len = len;
2116129794Stackerman				adapter->fmp = mp;	/* Store the first mbuf */
2117129794Stackerman				adapter->lmp = mp;
2118129794Stackerman			} else {
2119129794Stackerman				/* Chain mbuf's together */
2120129794Stackerman				mp->m_flags &= ~M_PKTHDR;
2121129794Stackerman				adapter->lmp->m_next = mp;
2122129794Stackerman				adapter->lmp = adapter->lmp->m_next;
2123129794Stackerman				adapter->fmp->m_pkthdr.len += len;
2124129794Stackerman			}
2125129794Stackerman
2126129794Stackerman			if (eop) {
2127129794Stackerman				eop_desc = i;
2128129794Stackerman				adapter->fmp->m_pkthdr.rcvif = ifp;
2129129794Stackerman
2130129794Stackerman#if __FreeBSD_version < 500000
2131129794Stackerman				eh = mtod(adapter->fmp, struct ether_header *);
2132129794Stackerman
2133129794Stackerman				/* Remove ethernet header from mbuf */
2134129794Stackerman				m_adj(adapter->fmp, sizeof(struct ether_header));
2135129794Stackerman				ixgb_receive_checksum(adapter, current_desc,
2136129794Stackerman						      adapter->fmp);
2137129794Stackerman
2138129794Stackerman				if (current_desc->status & IXGB_RX_DESC_STATUS_VP)
2139129794Stackerman					VLAN_INPUT_TAG(eh, adapter->fmp,
2140129794Stackerman						     current_desc->special);
2141129794Stackerman				else
2142129794Stackerman					ether_input(ifp, eh, adapter->fmp);
2143129794Stackerman#else
2144129794Stackerman				ixgb_receive_checksum(adapter, current_desc,
2145129794Stackerman						      adapter->fmp);
2146162375Sandre#if __FreeBSD_version < 700000
2147129794Stackerman				if (current_desc->status & IXGB_RX_DESC_STATUS_VP)
2148129794Stackerman					VLAN_INPUT_TAG(ifp, adapter->fmp,
2149153512Sglebius						       current_desc->special);
2150162375Sandre#else
2151162375Sandre				if (current_desc->status & IXGB_RX_DESC_STATUS_VP) {
2152162375Sandre					adapter->fmp->m_pkthdr.ether_vtag =
2153162375Sandre					    current_desc->special;
2154162375Sandre					adapter->fmp->m_flags |= M_VLANTAG;
2155162375Sandre				}
2156162375Sandre#endif
2157129794Stackerman
2158144651Salc				if (adapter->fmp != NULL) {
2159144651Salc					IXGB_UNLOCK(adapter);
2160129794Stackerman					(*ifp->if_input) (ifp, adapter->fmp);
2161144651Salc					IXGB_LOCK(adapter);
2162193096Sattilio					rx_npkts++;
2163144651Salc				}
2164129794Stackerman#endif
2165129794Stackerman				adapter->fmp = NULL;
2166129794Stackerman				adapter->lmp = NULL;
2167129794Stackerman			}
2168129794Stackerman			adapter->rx_buffer_area[i].m_head = NULL;
2169129794Stackerman		} else {
2170129794Stackerman			adapter->dropped_pkts++;
2171129794Stackerman			if (adapter->fmp != NULL)
2172129794Stackerman				m_freem(adapter->fmp);
2173129794Stackerman			adapter->fmp = NULL;
2174129794Stackerman			adapter->lmp = NULL;
2175129794Stackerman		}
2176129794Stackerman
2177129794Stackerman		/* Zero out the receive descriptors status  */
2178129794Stackerman		current_desc->status = 0;
2179129794Stackerman
2180129794Stackerman		/* Advance our pointers to the next descriptor */
2181129794Stackerman		if (++i == adapter->num_rx_desc) {
2182129794Stackerman			i = 0;
2183129794Stackerman			current_desc = adapter->rx_desc_base;
2184129794Stackerman		} else
2185129794Stackerman			current_desc++;
2186129794Stackerman	}
2187129794Stackerman	adapter->next_rx_desc_to_check = i;
2188129794Stackerman
2189129794Stackerman	if (--i < 0)
2190129794Stackerman		i = (adapter->num_rx_desc - 1);
2191129794Stackerman
2192129794Stackerman	/*
2193129794Stackerman	 * 82597EX: Workaround for redundent write back in receive descriptor ring (causes
2194129794Stackerman 	 * memory corruption). Avoid using and re-submitting the most recently received RX
2195129794Stackerman	 * descriptor back to hardware.
2196129794Stackerman	 *
2197129794Stackerman	 * if(Last written back descriptor == EOP bit set descriptor)
2198129794Stackerman	 * 	then avoid re-submitting the most recently received RX descriptor
2199129794Stackerman	 *	back to hardware.
2200129794Stackerman	 * if(Last written back descriptor != EOP bit set descriptor)
2201129794Stackerman	 *	then avoid re-submitting the most recently received RX descriptors
2202129794Stackerman	 * 	till last EOP bit set descriptor.
2203129794Stackerman	 */
2204129794Stackerman	if (eop_desc != i) {
2205129794Stackerman		if (++eop_desc == adapter->num_rx_desc)
2206129794Stackerman			eop_desc = 0;
2207129794Stackerman		i = eop_desc;
2208129794Stackerman	}
2209129794Stackerman	/* Replenish the descriptors with new mbufs till last EOP bit set descriptor */
2210129794Stackerman	while (next_to_use != i) {
2211129794Stackerman		current_desc = &adapter->rx_desc_base[next_to_use];
2212129794Stackerman		if ((current_desc->errors & (IXGB_RX_DESC_ERRORS_CE |
2213129794Stackerman			    IXGB_RX_DESC_ERRORS_SE | IXGB_RX_DESC_ERRORS_P |
2214129794Stackerman					     IXGB_RX_DESC_ERRORS_RXE))) {
2215129794Stackerman			mp = adapter->rx_buffer_area[next_to_use].m_head;
2216129794Stackerman			ixgb_get_buf(next_to_use, adapter, mp);
2217129794Stackerman		} else {
2218129794Stackerman			if (ixgb_get_buf(next_to_use, adapter, NULL) == ENOBUFS)
2219129794Stackerman				break;
2220129794Stackerman		}
2221129794Stackerman		/* Advance our pointers to the next descriptor */
2222129794Stackerman		if (++next_to_use == adapter->num_rx_desc) {
2223129794Stackerman			next_to_use = 0;
2224129794Stackerman			current_desc = adapter->rx_desc_base;
2225129794Stackerman		} else
2226129794Stackerman			current_desc++;
2227129794Stackerman	}
2228129794Stackerman	adapter->next_rx_desc_to_use = next_to_use;
2229129794Stackerman	if (--next_to_use < 0)
2230129794Stackerman		next_to_use = (adapter->num_rx_desc - 1);
2231129794Stackerman	/* Advance the IXGB's Receive Queue #0  "Tail Pointer" */
2232129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDT, next_to_use);
2233129794Stackerman
2234193096Sattilio	return (rx_npkts);
2235129794Stackerman}
2236129794Stackerman
2237129794Stackerman/*********************************************************************
2238129794Stackerman *
2239129794Stackerman *  Verify that the hardware indicated that the checksum is valid.
2240129794Stackerman *  Inform the stack about the status of checksum so that stack
2241129794Stackerman *  doesn't spend time verifying the checksum.
2242129794Stackerman *
2243129794Stackerman *********************************************************************/
2244129794Stackermanstatic void
2245129794Stackermanixgb_receive_checksum(struct adapter * adapter,
2246129794Stackerman		      struct ixgb_rx_desc * rx_desc,
2247129794Stackerman		      struct mbuf * mp)
2248129794Stackerman{
2249129794Stackerman	if (rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) {
2250129794Stackerman		mp->m_pkthdr.csum_flags = 0;
2251129794Stackerman		return;
2252129794Stackerman	}
2253129794Stackerman	if (rx_desc->status & IXGB_RX_DESC_STATUS_IPCS) {
2254129794Stackerman		/* Did it pass? */
2255129794Stackerman		if (!(rx_desc->errors & IXGB_RX_DESC_ERRORS_IPE)) {
2256129794Stackerman			/* IP Checksum Good */
2257129794Stackerman			mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
2258129794Stackerman			mp->m_pkthdr.csum_flags |= CSUM_IP_VALID;
2259129794Stackerman
2260129794Stackerman		} else {
2261129794Stackerman			mp->m_pkthdr.csum_flags = 0;
2262129794Stackerman		}
2263129794Stackerman	}
2264129794Stackerman	if (rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS) {
2265129794Stackerman		/* Did it pass? */
2266129794Stackerman		if (!(rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE)) {
2267129794Stackerman			mp->m_pkthdr.csum_flags |=
2268129794Stackerman				(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
2269129794Stackerman			mp->m_pkthdr.csum_data = htons(0xffff);
2270129794Stackerman		}
2271129794Stackerman	}
2272129794Stackerman	return;
2273129794Stackerman}
2274129794Stackerman
2275129794Stackerman
2276129794Stackermanstatic void
2277129794Stackermanixgb_enable_vlans(struct adapter * adapter)
2278129794Stackerman{
2279129794Stackerman	uint32_t        ctrl;
2280129794Stackerman
2281129794Stackerman	ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
2282129794Stackerman	ctrl |= IXGB_CTRL0_VME;
2283129794Stackerman	IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
2284129794Stackerman
2285129794Stackerman	return;
2286129794Stackerman}
2287129794Stackerman
2288129794Stackerman
2289129794Stackermanstatic void
2290129794Stackermanixgb_enable_intr(struct adapter * adapter)
2291129794Stackerman{
2292129794Stackerman	IXGB_WRITE_REG(&adapter->hw, IMS, (IXGB_INT_RXT0 | IXGB_INT_TXDW |
2293129794Stackerman			    IXGB_INT_RXDMT0 | IXGB_INT_LSC | IXGB_INT_RXO));
2294129794Stackerman	return;
2295129794Stackerman}
2296129794Stackerman
2297129794Stackermanstatic void
2298129794Stackermanixgb_disable_intr(struct adapter * adapter)
2299129794Stackerman{
2300129794Stackerman	IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
2301129794Stackerman	return;
2302129794Stackerman}
2303129794Stackerman
2304129794Stackermanvoid
2305129794Stackermanixgb_write_pci_cfg(struct ixgb_hw * hw,
2306129794Stackerman		   uint32_t reg,
2307129794Stackerman		   uint16_t * value)
2308129794Stackerman{
2309129794Stackerman	pci_write_config(((struct ixgb_osdep *) hw->back)->dev, reg,
2310129794Stackerman			 *value, 2);
2311129794Stackerman}
2312129794Stackerman
2313129794Stackerman/**********************************************************************
2314129794Stackerman *
2315129794Stackerman *  Update the board statistics counters.
2316129794Stackerman *
2317129794Stackerman **********************************************************************/
2318129794Stackermanstatic void
2319129794Stackermanixgb_update_stats_counters(struct adapter * adapter)
2320129794Stackerman{
2321129794Stackerman	struct ifnet   *ifp;
2322129794Stackerman
2323129794Stackerman	adapter->stats.crcerrs += IXGB_READ_REG(&adapter->hw, CRCERRS);
2324129794Stackerman	adapter->stats.gprcl += IXGB_READ_REG(&adapter->hw, GPRCL);
2325129794Stackerman	adapter->stats.gprch += IXGB_READ_REG(&adapter->hw, GPRCH);
2326129794Stackerman	adapter->stats.gorcl += IXGB_READ_REG(&adapter->hw, GORCL);
2327129794Stackerman	adapter->stats.gorch += IXGB_READ_REG(&adapter->hw, GORCH);
2328129794Stackerman	adapter->stats.bprcl += IXGB_READ_REG(&adapter->hw, BPRCL);
2329129794Stackerman	adapter->stats.bprch += IXGB_READ_REG(&adapter->hw, BPRCH);
2330129794Stackerman	adapter->stats.mprcl += IXGB_READ_REG(&adapter->hw, MPRCL);
2331129794Stackerman	adapter->stats.mprch += IXGB_READ_REG(&adapter->hw, MPRCH);
2332129794Stackerman	adapter->stats.roc += IXGB_READ_REG(&adapter->hw, ROC);
2333129794Stackerman
2334129794Stackerman	adapter->stats.mpc += IXGB_READ_REG(&adapter->hw, MPC);
2335129794Stackerman	adapter->stats.dc += IXGB_READ_REG(&adapter->hw, DC);
2336129794Stackerman	adapter->stats.rlec += IXGB_READ_REG(&adapter->hw, RLEC);
2337129794Stackerman	adapter->stats.xonrxc += IXGB_READ_REG(&adapter->hw, XONRXC);
2338129794Stackerman	adapter->stats.xontxc += IXGB_READ_REG(&adapter->hw, XONTXC);
2339129794Stackerman	adapter->stats.xoffrxc += IXGB_READ_REG(&adapter->hw, XOFFRXC);
2340129794Stackerman	adapter->stats.xofftxc += IXGB_READ_REG(&adapter->hw, XOFFTXC);
2341129794Stackerman	adapter->stats.gptcl += IXGB_READ_REG(&adapter->hw, GPTCL);
2342129794Stackerman	adapter->stats.gptch += IXGB_READ_REG(&adapter->hw, GPTCH);
2343129794Stackerman	adapter->stats.gotcl += IXGB_READ_REG(&adapter->hw, GOTCL);
2344129794Stackerman	adapter->stats.gotch += IXGB_READ_REG(&adapter->hw, GOTCH);
2345129794Stackerman	adapter->stats.ruc += IXGB_READ_REG(&adapter->hw, RUC);
2346129794Stackerman	adapter->stats.rfc += IXGB_READ_REG(&adapter->hw, RFC);
2347129794Stackerman	adapter->stats.rjc += IXGB_READ_REG(&adapter->hw, RJC);
2348129794Stackerman	adapter->stats.torl += IXGB_READ_REG(&adapter->hw, TORL);
2349129794Stackerman	adapter->stats.torh += IXGB_READ_REG(&adapter->hw, TORH);
2350129794Stackerman	adapter->stats.totl += IXGB_READ_REG(&adapter->hw, TOTL);
2351129794Stackerman	adapter->stats.toth += IXGB_READ_REG(&adapter->hw, TOTH);
2352129794Stackerman	adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL);
2353129794Stackerman	adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH);
2354129794Stackerman	adapter->stats.tptl += IXGB_READ_REG(&adapter->hw, TPTL);
2355129794Stackerman	adapter->stats.tpth += IXGB_READ_REG(&adapter->hw, TPTH);
2356129794Stackerman	adapter->stats.plt64c += IXGB_READ_REG(&adapter->hw, PLT64C);
2357129794Stackerman	adapter->stats.mptcl += IXGB_READ_REG(&adapter->hw, MPTCL);
2358129794Stackerman	adapter->stats.mptch += IXGB_READ_REG(&adapter->hw, MPTCH);
2359129794Stackerman	adapter->stats.bptcl += IXGB_READ_REG(&adapter->hw, BPTCL);
2360129794Stackerman	adapter->stats.bptch += IXGB_READ_REG(&adapter->hw, BPTCH);
2361129794Stackerman
2362129794Stackerman	adapter->stats.uprcl += IXGB_READ_REG(&adapter->hw, UPRCL);
2363129794Stackerman	adapter->stats.uprch += IXGB_READ_REG(&adapter->hw, UPRCH);
2364129794Stackerman	adapter->stats.vprcl += IXGB_READ_REG(&adapter->hw, VPRCL);
2365129794Stackerman	adapter->stats.vprch += IXGB_READ_REG(&adapter->hw, VPRCH);
2366129794Stackerman	adapter->stats.jprcl += IXGB_READ_REG(&adapter->hw, JPRCL);
2367129794Stackerman	adapter->stats.jprch += IXGB_READ_REG(&adapter->hw, JPRCH);
2368129794Stackerman	adapter->stats.rnbc += IXGB_READ_REG(&adapter->hw, RNBC);
2369129794Stackerman	adapter->stats.icbc += IXGB_READ_REG(&adapter->hw, ICBC);
2370129794Stackerman	adapter->stats.ecbc += IXGB_READ_REG(&adapter->hw, ECBC);
2371129794Stackerman	adapter->stats.uptcl += IXGB_READ_REG(&adapter->hw, UPTCL);
2372129794Stackerman	adapter->stats.uptch += IXGB_READ_REG(&adapter->hw, UPTCH);
2373129794Stackerman	adapter->stats.vptcl += IXGB_READ_REG(&adapter->hw, VPTCL);
2374129794Stackerman	adapter->stats.vptch += IXGB_READ_REG(&adapter->hw, VPTCH);
2375129794Stackerman	adapter->stats.jptcl += IXGB_READ_REG(&adapter->hw, JPTCL);
2376129794Stackerman	adapter->stats.jptch += IXGB_READ_REG(&adapter->hw, JPTCH);
2377129794Stackerman	adapter->stats.tsctc += IXGB_READ_REG(&adapter->hw, TSCTC);
2378129794Stackerman	adapter->stats.tsctfc += IXGB_READ_REG(&adapter->hw, TSCTFC);
2379129794Stackerman	adapter->stats.ibic += IXGB_READ_REG(&adapter->hw, IBIC);
2380129794Stackerman	adapter->stats.lfc += IXGB_READ_REG(&adapter->hw, LFC);
2381129794Stackerman	adapter->stats.pfrc += IXGB_READ_REG(&adapter->hw, PFRC);
2382129794Stackerman	adapter->stats.pftc += IXGB_READ_REG(&adapter->hw, PFTC);
2383129794Stackerman	adapter->stats.mcfrc += IXGB_READ_REG(&adapter->hw, MCFRC);
2384129794Stackerman
2385147256Sbrooks	ifp = adapter->ifp;
2386129794Stackerman
2387129794Stackerman	/* Fill out the OS statistics structure */
2388129794Stackerman	ifp->if_ipackets = adapter->stats.gprcl;
2389129794Stackerman	ifp->if_opackets = adapter->stats.gptcl;
2390129794Stackerman	ifp->if_ibytes = adapter->stats.gorcl;
2391129794Stackerman	ifp->if_obytes = adapter->stats.gotcl;
2392129794Stackerman	ifp->if_imcasts = adapter->stats.mprcl;
2393129794Stackerman	ifp->if_collisions = 0;
2394129794Stackerman
2395129794Stackerman	/* Rx Errors */
2396129794Stackerman	ifp->if_ierrors =
2397129794Stackerman		adapter->dropped_pkts +
2398129794Stackerman		adapter->stats.crcerrs +
2399129794Stackerman		adapter->stats.rnbc +
2400129794Stackerman		adapter->stats.mpc +
2401129794Stackerman		adapter->stats.rlec;
2402129794Stackerman
2403129794Stackerman
2404129794Stackerman}
2405129794Stackerman
2406129794Stackerman
2407129794Stackerman/**********************************************************************
2408129794Stackerman *
2409129794Stackerman *  This routine is called only when ixgb_display_debug_stats is enabled.
2410129794Stackerman *  This routine provides a way to take a look at important statistics
2411129794Stackerman *  maintained by the driver and hardware.
2412129794Stackerman *
2413129794Stackerman **********************************************************************/
2414129794Stackermanstatic void
2415129794Stackermanixgb_print_hw_stats(struct adapter * adapter)
2416129794Stackerman{
2417129794Stackerman	char            buf_speed[100], buf_type[100];
2418129794Stackerman	ixgb_bus_speed  bus_speed;
2419129794Stackerman	ixgb_bus_type   bus_type;
2420198987Sjhb	device_t dev;
2421129794Stackerman
2422198987Sjhb	dev = adapter->dev;
2423129794Stackerman#ifdef _SV_
2424198987Sjhb	device_printf(dev, "Packets not Avail = %ld\n",
2425129794Stackerman	       adapter->no_pkts_avail);
2426198987Sjhb	device_printf(dev, "CleanTxInterrupts = %ld\n",
2427129794Stackerman	       adapter->clean_tx_interrupts);
2428198987Sjhb	device_printf(dev, "ICR RXDMT0 = %lld\n",
2429129794Stackerman	       (long long)adapter->sv_stats.icr_rxdmt0);
2430198987Sjhb	device_printf(dev, "ICR RXO = %lld\n",
2431129794Stackerman	       (long long)adapter->sv_stats.icr_rxo);
2432198987Sjhb	device_printf(dev, "ICR RXT0 = %lld\n",
2433129794Stackerman	       (long long)adapter->sv_stats.icr_rxt0);
2434198987Sjhb	device_printf(dev, "ICR TXDW = %lld\n",
2435129794Stackerman	       (long long)adapter->sv_stats.icr_TXDW);
2436129794Stackerman#endif				/* _SV_ */
2437129794Stackerman
2438129794Stackerman	bus_speed = adapter->hw.bus.speed;
2439129794Stackerman	bus_type = adapter->hw.bus.type;
2440129794Stackerman	sprintf(buf_speed,
2441129794Stackerman		bus_speed == ixgb_bus_speed_33 ? "33MHz" :
2442129794Stackerman		bus_speed == ixgb_bus_speed_66 ? "66MHz" :
2443129794Stackerman		bus_speed == ixgb_bus_speed_100 ? "100MHz" :
2444129794Stackerman		bus_speed == ixgb_bus_speed_133 ? "133MHz" :
2445129794Stackerman		"UNKNOWN");
2446198987Sjhb	device_printf(dev, "PCI_Bus_Speed = %s\n",
2447129794Stackerman	       buf_speed);
2448129794Stackerman
2449129794Stackerman	sprintf(buf_type,
2450129794Stackerman		bus_type == ixgb_bus_type_pci ? "PCI" :
2451129794Stackerman		bus_type == ixgb_bus_type_pcix ? "PCI-X" :
2452129794Stackerman		"UNKNOWN");
2453198987Sjhb	device_printf(dev, "PCI_Bus_Type = %s\n",
2454129794Stackerman	       buf_type);
2455129794Stackerman
2456198987Sjhb	device_printf(dev, "Tx Descriptors not Avail1 = %ld\n",
2457129794Stackerman	       adapter->no_tx_desc_avail1);
2458198987Sjhb	device_printf(dev, "Tx Descriptors not Avail2 = %ld\n",
2459129794Stackerman	       adapter->no_tx_desc_avail2);
2460198987Sjhb	device_printf(dev, "Std Mbuf Failed = %ld\n",
2461129794Stackerman	       adapter->mbuf_alloc_failed);
2462198987Sjhb	device_printf(dev, "Std Cluster Failed = %ld\n",
2463129794Stackerman	       adapter->mbuf_cluster_failed);
2464129794Stackerman
2465198987Sjhb	device_printf(dev, "Defer count = %lld\n",
2466129794Stackerman	       (long long)adapter->stats.dc);
2467198987Sjhb	device_printf(dev, "Missed Packets = %lld\n",
2468129794Stackerman	       (long long)adapter->stats.mpc);
2469198987Sjhb	device_printf(dev, "Receive No Buffers = %lld\n",
2470129794Stackerman	       (long long)adapter->stats.rnbc);
2471198987Sjhb	device_printf(dev, "Receive length errors = %lld\n",
2472129794Stackerman	       (long long)adapter->stats.rlec);
2473198987Sjhb	device_printf(dev, "Crc errors = %lld\n",
2474129794Stackerman	       (long long)adapter->stats.crcerrs);
2475198987Sjhb	device_printf(dev, "Driver dropped packets = %ld\n",
2476129794Stackerman	       adapter->dropped_pkts);
2477129794Stackerman
2478198987Sjhb	device_printf(dev, "XON Rcvd = %lld\n",
2479129794Stackerman	       (long long)adapter->stats.xonrxc);
2480198987Sjhb	device_printf(dev, "XON Xmtd = %lld\n",
2481129794Stackerman	       (long long)adapter->stats.xontxc);
2482198987Sjhb	device_printf(dev, "XOFF Rcvd = %lld\n",
2483129794Stackerman	       (long long)adapter->stats.xoffrxc);
2484198987Sjhb	device_printf(dev, "XOFF Xmtd = %lld\n",
2485129794Stackerman	       (long long)adapter->stats.xofftxc);
2486129794Stackerman
2487198987Sjhb	device_printf(dev, "Good Packets Rcvd = %lld\n",
2488129794Stackerman	       (long long)adapter->stats.gprcl);
2489198987Sjhb	device_printf(dev, "Good Packets Xmtd = %lld\n",
2490129794Stackerman	       (long long)adapter->stats.gptcl);
2491129794Stackerman
2492198987Sjhb	device_printf(dev, "Jumbo frames recvd = %lld\n",
2493129794Stackerman	       (long long)adapter->stats.jprcl);
2494198987Sjhb	device_printf(dev, "Jumbo frames Xmtd = %lld\n",
2495129794Stackerman	       (long long)adapter->stats.jptcl);
2496129794Stackerman
2497129794Stackerman	return;
2498129794Stackerman
2499129794Stackerman}
2500129794Stackerman
2501129794Stackermanstatic int
2502129794Stackermanixgb_sysctl_stats(SYSCTL_HANDLER_ARGS)
2503129794Stackerman{
2504129794Stackerman	int             error;
2505129794Stackerman	int             result;
2506129794Stackerman	struct adapter *adapter;
2507129794Stackerman
2508129794Stackerman	result = -1;
2509129794Stackerman	error = sysctl_handle_int(oidp, &result, 0, req);
2510129794Stackerman
2511129794Stackerman	if (error || !req->newptr)
2512129794Stackerman		return (error);
2513129794Stackerman
2514129794Stackerman	if (result == 1) {
2515129794Stackerman		adapter = (struct adapter *) arg1;
2516129794Stackerman		ixgb_print_hw_stats(adapter);
2517129794Stackerman	}
2518129794Stackerman	return error;
2519129794Stackerman}
2520