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: releng/10.3/sys/dev/ixgb/if_ixgb.c 294958 2016-01-27 22:31:08Z marius $*/
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 */
75253102Sjkim	{IXGB_VENDOR_ID, IXGB_DEVICE_ID_82597EX, PCI_ANY_ID, PCI_ANY_ID, 0},
76253102Sjkim	{IXGB_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),
162246128Ssbz
163246128Ssbz	DEVMETHOD_END
164129794Stackerman};
165129794Stackerman
166129794Stackermanstatic driver_t ixgb_driver = {
167129794Stackerman	"ixgb", ixgb_methods, sizeof(struct adapter),
168129794Stackerman};
169129794Stackerman
170129794Stackermanstatic devclass_t ixgb_devclass;
171192147SimpDRIVER_MODULE(ixgb, pci, ixgb_driver, ixgb_devclass, 0, 0);
172129794Stackerman
173192147SimpMODULE_DEPEND(ixgb, pci, 1, 1, 1);
174192147SimpMODULE_DEPEND(ixgb, ether, 1, 1, 1);
175144183Smux
176129794Stackerman/* some defines for controlling descriptor fetches in h/w */
177129794Stackerman#define RXDCTL_PTHRESH_DEFAULT 128	/* chip considers prefech below this */
178129794Stackerman#define RXDCTL_HTHRESH_DEFAULT 16	/* chip will only prefetch if tail is
179129794Stackerman					 * pushed this many descriptors from
180129794Stackerman					 * head */
181129794Stackerman#define RXDCTL_WTHRESH_DEFAULT 0	/* chip writes back at this many or RXT0 */
182129794Stackerman
183129794Stackerman
184129794Stackerman/*********************************************************************
185129794Stackerman *  Device identification routine
186129794Stackerman *
187129794Stackerman *  ixgb_probe determines if the driver should be loaded on
188129794Stackerman *  adapter based on PCI vendor/device id of the adapter.
189129794Stackerman *
190129794Stackerman *  return 0 on success, positive on failure
191129794Stackerman *********************************************************************/
192129794Stackerman
193129794Stackermanstatic int
194129794Stackermanixgb_probe(device_t dev)
195129794Stackerman{
196129794Stackerman	ixgb_vendor_info_t *ent;
197129794Stackerman
198129794Stackerman	u_int16_t       pci_vendor_id = 0;
199129794Stackerman	u_int16_t       pci_device_id = 0;
200129794Stackerman	u_int16_t       pci_subvendor_id = 0;
201129794Stackerman	u_int16_t       pci_subdevice_id = 0;
202129794Stackerman	char            adapter_name[60];
203129794Stackerman
204129794Stackerman	INIT_DEBUGOUT("ixgb_probe: begin");
205129794Stackerman
206129794Stackerman	pci_vendor_id = pci_get_vendor(dev);
207129794Stackerman	if (pci_vendor_id != IXGB_VENDOR_ID)
208129794Stackerman		return (ENXIO);
209129794Stackerman
210129794Stackerman	pci_device_id = pci_get_device(dev);
211129794Stackerman	pci_subvendor_id = pci_get_subvendor(dev);
212129794Stackerman	pci_subdevice_id = pci_get_subdevice(dev);
213129794Stackerman
214129794Stackerman	ent = ixgb_vendor_info_array;
215129794Stackerman	while (ent->vendor_id != 0) {
216129794Stackerman		if ((pci_vendor_id == ent->vendor_id) &&
217129794Stackerman		    (pci_device_id == ent->device_id) &&
218129794Stackerman
219129794Stackerman		    ((pci_subvendor_id == ent->subvendor_id) ||
220129794Stackerman		     (ent->subvendor_id == PCI_ANY_ID)) &&
221129794Stackerman
222129794Stackerman		    ((pci_subdevice_id == ent->subdevice_id) ||
223129794Stackerman		     (ent->subdevice_id == PCI_ANY_ID))) {
224129794Stackerman			sprintf(adapter_name, "%s, Version - %s",
225129794Stackerman				ixgb_strings[ent->index],
226129794Stackerman				ixgb_driver_version);
227129794Stackerman			device_set_desc_copy(dev, adapter_name);
228143160Simp			return (BUS_PROBE_DEFAULT);
229129794Stackerman		}
230129794Stackerman		ent++;
231129794Stackerman	}
232129794Stackerman
233129794Stackerman	return (ENXIO);
234129794Stackerman}
235129794Stackerman
236129794Stackerman/*********************************************************************
237129794Stackerman *  Device initialization routine
238129794Stackerman *
239129794Stackerman *  The attach entry point is called when the driver is being loaded.
240129794Stackerman *  This routine identifies the type of hardware, allocates all resources
241129794Stackerman *  and initializes the hardware.
242129794Stackerman *
243129794Stackerman *  return 0 on success, positive on failure
244129794Stackerman *********************************************************************/
245129794Stackerman
246129794Stackermanstatic int
247129794Stackermanixgb_attach(device_t dev)
248129794Stackerman{
249129794Stackerman	struct adapter *adapter;
250129794Stackerman	int             tsize, rsize;
251129794Stackerman	int             error = 0;
252129794Stackerman
253198987Sjhb	device_printf(dev, "%s\n", ixgb_copyright);
254129794Stackerman	INIT_DEBUGOUT("ixgb_attach: begin");
255129794Stackerman
256129794Stackerman	/* Allocate, clear, and link in our adapter structure */
257129794Stackerman	if (!(adapter = device_get_softc(dev))) {
258198987Sjhb		device_printf(dev, "adapter structure allocation failed\n");
259129794Stackerman		return (ENOMEM);
260129794Stackerman	}
261129794Stackerman	bzero(adapter, sizeof(struct adapter));
262129794Stackerman	adapter->dev = dev;
263129794Stackerman	adapter->osdep.dev = dev;
264144651Salc	IXGB_LOCK_INIT(adapter, device_get_nameunit(dev));
265129794Stackerman
266129794Stackerman	if (ixgb_adapter_list != NULL)
267129794Stackerman		ixgb_adapter_list->prev = adapter;
268129794Stackerman	adapter->next = ixgb_adapter_list;
269129794Stackerman	ixgb_adapter_list = adapter;
270129794Stackerman
271129794Stackerman	/* SYSCTL APIs */
272144183Smux	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
273144183Smux			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
274129794Stackerman			OID_AUTO, "stats", CTLTYPE_INT | CTLFLAG_RW,
275129794Stackerman			(void *)adapter, 0,
276129794Stackerman			ixgb_sysctl_stats, "I", "Statistics");
277129794Stackerman
278199539Sjhb	callout_init_mtx(&adapter->timer, &adapter->mtx, 0);
279129794Stackerman
280129794Stackerman	/* Determine hardware revision */
281129794Stackerman	ixgb_identify_hardware(adapter);
282129794Stackerman
283129794Stackerman	/* Parameters (to be read from user) */
284129794Stackerman	adapter->num_tx_desc = IXGB_MAX_TXD;
285129794Stackerman	adapter->num_rx_desc = IXGB_MAX_RXD;
286129794Stackerman	adapter->tx_int_delay = TIDV;
287129794Stackerman	adapter->rx_int_delay = RDTR;
288129794Stackerman	adapter->rx_buffer_len = IXGB_RXBUFFER_2048;
289129794Stackerman
290129794Stackerman	adapter->hw.fc.high_water = FCRTH;
291129794Stackerman	adapter->hw.fc.low_water = FCRTL;
292129794Stackerman	adapter->hw.fc.pause_time = FCPAUSE;
293129794Stackerman	adapter->hw.fc.send_xon = TRUE;
294129794Stackerman	adapter->hw.fc.type = FLOW_CONTROL;
295129794Stackerman
296129794Stackerman
297129794Stackerman	/* Set the max frame size assuming standard ethernet sized frames */
298129794Stackerman	adapter->hw.max_frame_size =
299129794Stackerman		ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN;
300129794Stackerman
301129794Stackerman	if (ixgb_allocate_pci_resources(adapter)) {
302198987Sjhb		device_printf(dev, "Allocation of PCI resources failed\n");
303129794Stackerman		error = ENXIO;
304129794Stackerman		goto err_pci;
305129794Stackerman	}
306129794Stackerman	tsize = IXGB_ROUNDUP(adapter->num_tx_desc *
307129794Stackerman			     sizeof(struct ixgb_tx_desc), 4096);
308129794Stackerman
309129794Stackerman	/* Allocate Transmit Descriptor ring */
310129794Stackerman	if (ixgb_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
311198987Sjhb		device_printf(dev, "Unable to allocate TxDescriptor memory\n");
312129794Stackerman		error = ENOMEM;
313129794Stackerman		goto err_tx_desc;
314129794Stackerman	}
315129794Stackerman	adapter->tx_desc_base = (struct ixgb_tx_desc *) adapter->txdma.dma_vaddr;
316129794Stackerman
317129794Stackerman	rsize = IXGB_ROUNDUP(adapter->num_rx_desc *
318129794Stackerman			     sizeof(struct ixgb_rx_desc), 4096);
319129794Stackerman
320129794Stackerman	/* Allocate Receive Descriptor ring */
321129794Stackerman	if (ixgb_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
322198987Sjhb		device_printf(dev, "Unable to allocate rx_desc memory\n");
323129794Stackerman		error = ENOMEM;
324129794Stackerman		goto err_rx_desc;
325129794Stackerman	}
326129794Stackerman	adapter->rx_desc_base = (struct ixgb_rx_desc *) adapter->rxdma.dma_vaddr;
327129794Stackerman
328211913Syongari	/* Allocate multicast array memory. */
329211913Syongari	adapter->mta = malloc(sizeof(u_int8_t) * IXGB_ETH_LENGTH_OF_ADDRESS *
330211913Syongari	    MAX_NUM_MULTICAST_ADDRESSES, M_DEVBUF, M_NOWAIT);
331211913Syongari	if (adapter->mta == NULL) {
332211913Syongari		device_printf(dev, "Can not allocate multicast setup array\n");
333211913Syongari		error = ENOMEM;
334211913Syongari		goto err_hw_init;
335211913Syongari	}
336211913Syongari
337129794Stackerman	/* Initialize the hardware */
338129794Stackerman	if (ixgb_hardware_init(adapter)) {
339198987Sjhb		device_printf(dev, "Unable to initialize the hardware\n");
340129794Stackerman		error = EIO;
341129794Stackerman		goto err_hw_init;
342129794Stackerman	}
343129794Stackerman	/* Setup OS specific network interface */
344211907Syongari	if (ixgb_setup_interface(dev, adapter) != 0)
345211907Syongari		goto err_hw_init;
346129794Stackerman
347129794Stackerman	/* Initialize statistics */
348129794Stackerman	ixgb_clear_hw_cntrs(&adapter->hw);
349129794Stackerman	ixgb_update_stats_counters(adapter);
350129794Stackerman
351129794Stackerman	INIT_DEBUGOUT("ixgb_attach: end");
352129794Stackerman	return (0);
353129794Stackerman
354129794Stackermanerr_hw_init:
355129794Stackerman	ixgb_dma_free(adapter, &adapter->rxdma);
356129794Stackermanerr_rx_desc:
357129794Stackerman	ixgb_dma_free(adapter, &adapter->txdma);
358129794Stackermanerr_tx_desc:
359129794Stackermanerr_pci:
360211907Syongari	if (adapter->ifp != NULL)
361211907Syongari		if_free(adapter->ifp);
362129794Stackerman	ixgb_free_pci_resources(adapter);
363129794Stackerman	sysctl_ctx_free(&adapter->sysctl_ctx);
364211913Syongari	free(adapter->mta, M_DEVBUF);
365129794Stackerman	return (error);
366129794Stackerman
367129794Stackerman}
368129794Stackerman
369129794Stackerman/*********************************************************************
370129794Stackerman *  Device removal routine
371129794Stackerman *
372129794Stackerman *  The detach entry point is called when the driver is being removed.
373129794Stackerman *  This routine stops the adapter and deallocates all the resources
374129794Stackerman *  that were allocated for driver operation.
375129794Stackerman *
376129794Stackerman *  return 0 on success, positive on failure
377129794Stackerman *********************************************************************/
378129794Stackerman
379129794Stackermanstatic int
380129794Stackermanixgb_detach(device_t dev)
381129794Stackerman{
382129794Stackerman	struct adapter *adapter = device_get_softc(dev);
383147256Sbrooks	struct ifnet   *ifp = adapter->ifp;
384129794Stackerman
385129794Stackerman	INIT_DEBUGOUT("ixgb_detach: begin");
386129794Stackerman
387150789Sglebius#ifdef DEVICE_POLLING
388150789Sglebius	if (ifp->if_capenable & IFCAP_POLLING)
389150789Sglebius		ether_poll_deregister(ifp);
390150789Sglebius#endif
391150789Sglebius
392144651Salc	IXGB_LOCK(adapter);
393129794Stackerman	adapter->in_detach = 1;
394129794Stackerman
395129794Stackerman	ixgb_stop(adapter);
396144651Salc	IXGB_UNLOCK(adapter);
397129794Stackerman
398129794Stackerman#if __FreeBSD_version < 500000
399199539Sjhb	ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
400129794Stackerman#else
401199539Sjhb	ether_ifdetach(ifp);
402150306Simp#endif
403199539Sjhb	callout_drain(&adapter->timer);
404150306Simp	ixgb_free_pci_resources(adapter);
405150306Simp#if __FreeBSD_version >= 500000
406199539Sjhb	if_free(ifp);
407129794Stackerman#endif
408129794Stackerman
409129794Stackerman	/* Free Transmit Descriptor ring */
410129794Stackerman	if (adapter->tx_desc_base) {
411129794Stackerman		ixgb_dma_free(adapter, &adapter->txdma);
412129794Stackerman		adapter->tx_desc_base = NULL;
413129794Stackerman	}
414129794Stackerman	/* Free Receive Descriptor ring */
415129794Stackerman	if (adapter->rx_desc_base) {
416129794Stackerman		ixgb_dma_free(adapter, &adapter->rxdma);
417129794Stackerman		adapter->rx_desc_base = NULL;
418129794Stackerman	}
419129794Stackerman	/* Remove from the adapter list */
420129794Stackerman	if (ixgb_adapter_list == adapter)
421129794Stackerman		ixgb_adapter_list = adapter->next;
422129794Stackerman	if (adapter->next != NULL)
423129794Stackerman		adapter->next->prev = adapter->prev;
424129794Stackerman	if (adapter->prev != NULL)
425129794Stackerman		adapter->prev->next = adapter->next;
426211913Syongari	free(adapter->mta, M_DEVBUF);
427129794Stackerman
428144651Salc	IXGB_LOCK_DESTROY(adapter);
429129794Stackerman	return (0);
430129794Stackerman}
431129794Stackerman
432129794Stackerman/*********************************************************************
433129794Stackerman *
434129794Stackerman *  Shutdown entry point
435129794Stackerman *
436129794Stackerman **********************************************************************/
437129794Stackerman
438129794Stackermanstatic int
439129794Stackermanixgb_shutdown(device_t dev)
440129794Stackerman{
441129794Stackerman	struct adapter *adapter = device_get_softc(dev);
442144651Salc	IXGB_LOCK(adapter);
443129794Stackerman	ixgb_stop(adapter);
444144651Salc	IXGB_UNLOCK(adapter);
445129794Stackerman	return (0);
446129794Stackerman}
447129794Stackerman
448129794Stackerman
449129794Stackerman/*********************************************************************
450129794Stackerman *  Transmit entry point
451129794Stackerman *
452129794Stackerman *  ixgb_start is called by the stack to initiate a transmit.
453129794Stackerman *  The driver will remain in this routine as long as there are
454129794Stackerman *  packets to transmit and transmit resources are available.
455129794Stackerman *  In case resources are not available stack is notified and
456129794Stackerman *  the packet is requeued.
457129794Stackerman **********************************************************************/
458129794Stackerman
459129794Stackermanstatic void
460144651Salcixgb_start_locked(struct ifnet * ifp)
461129794Stackerman{
462129794Stackerman	struct mbuf    *m_head;
463129794Stackerman	struct adapter *adapter = ifp->if_softc;
464129794Stackerman
465144651Salc	IXGB_LOCK_ASSERT(adapter);
466129794Stackerman
467129794Stackerman	if (!adapter->link_active)
468129794Stackerman		return;
469129794Stackerman
470129794Stackerman	while (ifp->if_snd.ifq_head != NULL) {
471129794Stackerman		IF_DEQUEUE(&ifp->if_snd, m_head);
472129794Stackerman
473129794Stackerman		if (m_head == NULL)
474129794Stackerman			break;
475129794Stackerman
476129794Stackerman		if (ixgb_encap(adapter, m_head)) {
477148887Srwatson			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
478129794Stackerman			IF_PREPEND(&ifp->if_snd, m_head);
479129794Stackerman			break;
480129794Stackerman		}
481129794Stackerman		/* Send a copy of the frame to the BPF listener */
482129794Stackerman#if __FreeBSD_version < 500000
483129794Stackerman		if (ifp->if_bpf)
484129794Stackerman			bpf_mtap(ifp, m_head);
485129794Stackerman#else
486167190Scsjp		ETHER_BPF_MTAP(ifp, m_head);
487129794Stackerman#endif
488129794Stackerman		/* Set timeout in case hardware has problems transmitting */
489199539Sjhb		adapter->tx_timer = IXGB_TX_TIMEOUT;
490129794Stackerman
491129794Stackerman	}
492129794Stackerman	return;
493129794Stackerman}
494129794Stackerman
495144651Salcstatic void
496144651Salcixgb_start(struct ifnet *ifp)
497144651Salc{
498144651Salc	struct adapter *adapter = ifp->if_softc;
499144651Salc
500144651Salc	IXGB_LOCK(adapter);
501144651Salc	ixgb_start_locked(ifp);
502144651Salc	IXGB_UNLOCK(adapter);
503144651Salc	return;
504144651Salc}
505144651Salc
506129794Stackerman/*********************************************************************
507129794Stackerman *  Ioctl entry point
508129794Stackerman *
509129794Stackerman *  ixgb_ioctl is called when the user wants to configure the
510129794Stackerman *  interface.
511129794Stackerman *
512129794Stackerman *  return 0 on success, positive on failure
513129794Stackerman **********************************************************************/
514129794Stackerman
515129794Stackermanstatic int
516129794Stackermanixgb_ioctl(struct ifnet * ifp, IOCTL_CMD_TYPE command, caddr_t data)
517129794Stackerman{
518144651Salc	int             mask, error = 0;
519129794Stackerman	struct ifreq   *ifr = (struct ifreq *) data;
520129794Stackerman	struct adapter *adapter = ifp->if_softc;
521129794Stackerman
522129794Stackerman	if (adapter->in_detach)
523129794Stackerman		goto out;
524129794Stackerman
525129794Stackerman	switch (command) {
526129794Stackerman	case SIOCSIFADDR:
527129794Stackerman	case SIOCGIFADDR:
528129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFADDR (Get/Set Interface Addr)");
529129794Stackerman		ether_ioctl(ifp, command, data);
530129794Stackerman		break;
531129794Stackerman	case SIOCSIFMTU:
532129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)");
533129794Stackerman		if (ifr->ifr_mtu > IXGB_MAX_JUMBO_FRAME_SIZE - ETHER_HDR_LEN) {
534129794Stackerman			error = EINVAL;
535129794Stackerman		} else {
536144651Salc			IXGB_LOCK(adapter);
537129794Stackerman			ifp->if_mtu = ifr->ifr_mtu;
538129794Stackerman			adapter->hw.max_frame_size =
539129794Stackerman				ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
540129794Stackerman
541144651Salc			ixgb_init_locked(adapter);
542144651Salc			IXGB_UNLOCK(adapter);
543129794Stackerman		}
544129794Stackerman		break;
545129794Stackerman	case SIOCSIFFLAGS:
546129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)");
547144651Salc		IXGB_LOCK(adapter);
548129794Stackerman		if (ifp->if_flags & IFF_UP) {
549148887Srwatson			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
550144651Salc				ixgb_init_locked(adapter);
551129794Stackerman			}
552129794Stackerman			ixgb_disable_promisc(adapter);
553129794Stackerman			ixgb_set_promisc(adapter);
554129794Stackerman		} else {
555148887Srwatson			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
556129794Stackerman				ixgb_stop(adapter);
557129794Stackerman			}
558129794Stackerman		}
559144651Salc		IXGB_UNLOCK(adapter);
560129794Stackerman		break;
561129794Stackerman	case SIOCADDMULTI:
562129794Stackerman	case SIOCDELMULTI:
563129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOC(ADD|DEL)MULTI");
564148887Srwatson		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
565144651Salc			IXGB_LOCK(adapter);
566129794Stackerman			ixgb_disable_intr(adapter);
567129794Stackerman			ixgb_set_multi(adapter);
568129794Stackerman			ixgb_enable_intr(adapter);
569144651Salc			IXGB_UNLOCK(adapter);
570129794Stackerman		}
571129794Stackerman		break;
572129794Stackerman	case SIOCSIFMEDIA:
573129794Stackerman	case SIOCGIFMEDIA:
574129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFMEDIA (Get/Set Interface Media)");
575129794Stackerman		error = ifmedia_ioctl(ifp, ifr, &adapter->media, command);
576129794Stackerman		break;
577129794Stackerman	case SIOCSIFCAP:
578129794Stackerman		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)");
579129794Stackerman		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
580150789Sglebius#ifdef DEVICE_POLLING
581150789Sglebius		if (mask & IFCAP_POLLING) {
582150789Sglebius			if (ifr->ifr_reqcap & IFCAP_POLLING) {
583150789Sglebius				error = ether_poll_register(ixgb_poll, ifp);
584150789Sglebius				if (error)
585150789Sglebius					return(error);
586150789Sglebius				IXGB_LOCK(adapter);
587150789Sglebius				ixgb_disable_intr(adapter);
588150789Sglebius				ifp->if_capenable |= IFCAP_POLLING;
589150789Sglebius				IXGB_UNLOCK(adapter);
590150789Sglebius			} else {
591150789Sglebius				error = ether_poll_deregister(ifp);
592150789Sglebius				/* Enable interrupt even in error case */
593150789Sglebius				IXGB_LOCK(adapter);
594150789Sglebius				ixgb_enable_intr(adapter);
595150789Sglebius				ifp->if_capenable &= ~IFCAP_POLLING;
596150789Sglebius				IXGB_UNLOCK(adapter);
597150789Sglebius			}
598150789Sglebius		}
599150789Sglebius#endif /* DEVICE_POLLING */
600129794Stackerman		if (mask & IFCAP_HWCSUM) {
601129794Stackerman			if (IFCAP_HWCSUM & ifp->if_capenable)
602129794Stackerman				ifp->if_capenable &= ~IFCAP_HWCSUM;
603129794Stackerman			else
604129794Stackerman				ifp->if_capenable |= IFCAP_HWCSUM;
605148887Srwatson			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
606129794Stackerman				ixgb_init(adapter);
607129794Stackerman		}
608129794Stackerman		break;
609129794Stackerman	default:
610129794Stackerman		IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%X)\n", (int)command);
611129794Stackerman		error = EINVAL;
612129794Stackerman	}
613129794Stackerman
614129794Stackermanout:
615129794Stackerman	return (error);
616129794Stackerman}
617129794Stackerman
618129794Stackerman/*********************************************************************
619129794Stackerman *  Watchdog entry point
620129794Stackerman *
621129794Stackerman *  This routine is called whenever hardware quits transmitting.
622129794Stackerman *
623129794Stackerman **********************************************************************/
624129794Stackerman
625129794Stackermanstatic void
626199539Sjhbixgb_watchdog(struct adapter *adapter)
627129794Stackerman{
628199539Sjhb	struct ifnet *ifp;
629129794Stackerman
630199539Sjhb	ifp = adapter->ifp;
631199539Sjhb
632129794Stackerman	/*
633129794Stackerman	 * If we are in this routine because of pause frames, then don't
634129794Stackerman	 * reset the hardware.
635129794Stackerman	 */
636129794Stackerman	if (IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF) {
637199539Sjhb		adapter->tx_timer = IXGB_TX_TIMEOUT;
638129794Stackerman		return;
639129794Stackerman	}
640198987Sjhb	if_printf(ifp, "watchdog timeout -- resetting\n");
641129794Stackerman
642129794Stackerman	ixgb_stop(adapter);
643199539Sjhb	ixgb_init_locked(adapter);
644129794Stackerman
645129794Stackerman
646129794Stackerman	ifp->if_oerrors++;
647129794Stackerman
648129794Stackerman	return;
649129794Stackerman}
650129794Stackerman
651129794Stackerman/*********************************************************************
652129794Stackerman *  Init entry point
653129794Stackerman *
654129794Stackerman *  This routine is used in two ways. It is used by the stack as
655129794Stackerman *  init entry point in network interface structure. It is also used
656129794Stackerman *  by the driver as a hw/sw initialization routine to get to a
657129794Stackerman *  consistent state.
658129794Stackerman *
659129794Stackerman *  return 0 on success, positive on failure
660129794Stackerman **********************************************************************/
661129794Stackerman
662129794Stackermanstatic void
663144651Salcixgb_init_locked(struct adapter *adapter)
664129794Stackerman{
665129794Stackerman	struct ifnet   *ifp;
666129794Stackerman
667129794Stackerman	INIT_DEBUGOUT("ixgb_init: begin");
668129794Stackerman
669144651Salc	IXGB_LOCK_ASSERT(adapter);
670129794Stackerman
671129794Stackerman	ixgb_stop(adapter);
672198987Sjhb	ifp = adapter->ifp;
673129794Stackerman
674129794Stackerman	/* Get the latest mac address, User can use a LAA */
675198987Sjhb	bcopy(IF_LLADDR(ifp), adapter->hw.curr_mac_addr,
676198987Sjhb	    IXGB_ETH_LENGTH_OF_ADDRESS);
677129794Stackerman
678129794Stackerman	/* Initialize the hardware */
679129794Stackerman	if (ixgb_hardware_init(adapter)) {
680198987Sjhb		if_printf(ifp, "Unable to initialize the hardware\n");
681129794Stackerman		return;
682129794Stackerman	}
683129794Stackerman	ixgb_enable_vlans(adapter);
684129794Stackerman
685129794Stackerman	/* Prepare transmit descriptors and buffers */
686129794Stackerman	if (ixgb_setup_transmit_structures(adapter)) {
687198987Sjhb		if_printf(ifp, "Could not setup transmit structures\n");
688129794Stackerman		ixgb_stop(adapter);
689129794Stackerman		return;
690129794Stackerman	}
691129794Stackerman	ixgb_initialize_transmit_unit(adapter);
692129794Stackerman
693129794Stackerman	/* Setup Multicast table */
694129794Stackerman	ixgb_set_multi(adapter);
695129794Stackerman
696129794Stackerman	/* Prepare receive descriptors and buffers */
697129794Stackerman	if (ixgb_setup_receive_structures(adapter)) {
698198987Sjhb		if_printf(ifp, "Could not setup receive structures\n");
699129794Stackerman		ixgb_stop(adapter);
700129794Stackerman		return;
701129794Stackerman	}
702129794Stackerman	ixgb_initialize_receive_unit(adapter);
703129794Stackerman
704160964Syar	/* Don't lose promiscuous settings */
705129794Stackerman	ixgb_set_promisc(adapter);
706129794Stackerman
707147256Sbrooks	ifp = adapter->ifp;
708148887Srwatson	ifp->if_drv_flags |= IFF_DRV_RUNNING;
709148887Srwatson	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
710129794Stackerman
711129794Stackerman
712129794Stackerman	if (ifp->if_capenable & IFCAP_TXCSUM)
713129794Stackerman		ifp->if_hwassist = IXGB_CHECKSUM_FEATURES;
714129794Stackerman	else
715129794Stackerman		ifp->if_hwassist = 0;
716129794Stackerman
717129794Stackerman
718129794Stackerman	/* Enable jumbo frames */
719129794Stackerman	if (ifp->if_mtu > ETHERMTU) {
720129794Stackerman		uint32_t        temp_reg;
721129794Stackerman		IXGB_WRITE_REG(&adapter->hw, MFS,
722129794Stackerman			       adapter->hw.max_frame_size << IXGB_MFS_SHIFT);
723129794Stackerman		temp_reg = IXGB_READ_REG(&adapter->hw, CTRL0);
724129794Stackerman		temp_reg |= IXGB_CTRL0_JFE;
725129794Stackerman		IXGB_WRITE_REG(&adapter->hw, CTRL0, temp_reg);
726129794Stackerman	}
727199539Sjhb	callout_reset(&adapter->timer, hz, ixgb_local_timer, adapter);
728129794Stackerman	ixgb_clear_hw_cntrs(&adapter->hw);
729129794Stackerman#ifdef DEVICE_POLLING
730129794Stackerman	/*
731129794Stackerman	 * Only disable interrupts if we are polling, make sure they are on
732129794Stackerman	 * otherwise.
733129794Stackerman	 */
734150789Sglebius	if (ifp->if_capenable & IFCAP_POLLING)
735129794Stackerman		ixgb_disable_intr(adapter);
736129794Stackerman	else
737150789Sglebius#endif
738129794Stackerman		ixgb_enable_intr(adapter);
739129794Stackerman
740129794Stackerman	return;
741129794Stackerman}
742129794Stackerman
743144651Salcstatic void
744144651Salcixgb_init(void *arg)
745144651Salc{
746144651Salc	struct adapter *adapter = arg;
747129794Stackerman
748144651Salc	IXGB_LOCK(adapter);
749144651Salc	ixgb_init_locked(adapter);
750144651Salc	IXGB_UNLOCK(adapter);
751144651Salc	return;
752144651Salc}
753144651Salc
754129794Stackerman#ifdef DEVICE_POLLING
755193096Sattiliostatic int
756144651Salcixgb_poll_locked(struct ifnet * ifp, enum poll_cmd cmd, int count)
757129794Stackerman{
758129794Stackerman	struct adapter *adapter = ifp->if_softc;
759129794Stackerman	u_int32_t       reg_icr;
760193096Sattilio	int		rx_npkts;
761129794Stackerman
762144651Salc	IXGB_LOCK_ASSERT(adapter);
763144651Salc
764129794Stackerman	if (cmd == POLL_AND_CHECK_STATUS) {
765129794Stackerman		reg_icr = IXGB_READ_REG(&adapter->hw, ICR);
766129794Stackerman		if (reg_icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)) {
767129794Stackerman			ixgb_check_for_link(&adapter->hw);
768129794Stackerman			ixgb_print_link_status(adapter);
769129794Stackerman		}
770129794Stackerman	}
771193096Sattilio	rx_npkts = ixgb_process_receive_interrupts(adapter, count);
772150789Sglebius	ixgb_clean_transmit_interrupts(adapter);
773150789Sglebius
774150789Sglebius	if (ifp->if_snd.ifq_head != NULL)
775144651Salc		ixgb_start_locked(ifp);
776193096Sattilio	return (rx_npkts);
777129794Stackerman}
778144651Salc
779193096Sattiliostatic int
780144651Salcixgb_poll(struct ifnet * ifp, enum poll_cmd cmd, int count)
781144651Salc{
782144651Salc	struct adapter *adapter = ifp->if_softc;
783193096Sattilio	int rx_npkts = 0;
784144651Salc
785144651Salc	IXGB_LOCK(adapter);
786150789Sglebius	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
787193096Sattilio		rx_npkts = ixgb_poll_locked(ifp, cmd, count);
788144651Salc	IXGB_UNLOCK(adapter);
789193096Sattilio	return (rx_npkts);
790144651Salc}
791150789Sglebius#endif /* DEVICE_POLLING */
792129794Stackerman
793129794Stackerman/*********************************************************************
794129794Stackerman *
795129794Stackerman *  Interrupt Service routine
796129794Stackerman *
797129794Stackerman **********************************************************************/
798129794Stackerman
799129794Stackermanstatic void
800129794Stackermanixgb_intr(void *arg)
801129794Stackerman{
802129794Stackerman	u_int32_t       loop_cnt = IXGB_MAX_INTR;
803129794Stackerman	u_int32_t       reg_icr;
804129794Stackerman	struct ifnet   *ifp;
805129794Stackerman	struct adapter *adapter = arg;
806129794Stackerman	boolean_t       rxdmt0 = FALSE;
807129794Stackerman
808144651Salc	IXGB_LOCK(adapter);
809144651Salc
810147256Sbrooks	ifp = adapter->ifp;
811129794Stackerman
812129794Stackerman#ifdef DEVICE_POLLING
813150789Sglebius	if (ifp->if_capenable & IFCAP_POLLING) {
814144651Salc		IXGB_UNLOCK(adapter);
815129794Stackerman		return;
816144651Salc	}
817150789Sglebius#endif
818129794Stackerman
819144651Salc	reg_icr = IXGB_READ_REG(&adapter->hw, ICR);
820144651Salc	if (reg_icr == 0) {
821144651Salc		IXGB_UNLOCK(adapter);
822129794Stackerman		return;
823144651Salc	}
824129794Stackerman
825129794Stackerman	if (reg_icr & IXGB_INT_RXDMT0)
826129794Stackerman		rxdmt0 = TRUE;
827129794Stackerman
828129794Stackerman#ifdef _SV_
829129794Stackerman	if (reg_icr & IXGB_INT_RXDMT0)
830129794Stackerman		adapter->sv_stats.icr_rxdmt0++;
831129794Stackerman	if (reg_icr & IXGB_INT_RXO)
832129794Stackerman		adapter->sv_stats.icr_rxo++;
833129794Stackerman	if (reg_icr & IXGB_INT_RXT0)
834129794Stackerman		adapter->sv_stats.icr_rxt0++;
835129794Stackerman	if (reg_icr & IXGB_INT_TXDW)
836129794Stackerman		adapter->sv_stats.icr_TXDW++;
837129794Stackerman#endif				/* _SV_ */
838129794Stackerman
839129794Stackerman	/* Link status change */
840129794Stackerman	if (reg_icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)) {
841129794Stackerman		ixgb_check_for_link(&adapter->hw);
842129794Stackerman		ixgb_print_link_status(adapter);
843129794Stackerman	}
844129794Stackerman	while (loop_cnt > 0) {
845148887Srwatson		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
846129794Stackerman			ixgb_process_receive_interrupts(adapter, -1);
847129794Stackerman			ixgb_clean_transmit_interrupts(adapter);
848129794Stackerman		}
849129794Stackerman		loop_cnt--;
850129794Stackerman	}
851129794Stackerman
852129794Stackerman	if (rxdmt0 && adapter->raidc) {
853129794Stackerman		IXGB_WRITE_REG(&adapter->hw, IMC, IXGB_INT_RXDMT0);
854129794Stackerman		IXGB_WRITE_REG(&adapter->hw, IMS, IXGB_INT_RXDMT0);
855129794Stackerman	}
856148887Srwatson	if (ifp->if_drv_flags & IFF_DRV_RUNNING && ifp->if_snd.ifq_head != NULL)
857144651Salc		ixgb_start_locked(ifp);
858129794Stackerman
859144651Salc	IXGB_UNLOCK(adapter);
860129794Stackerman	return;
861129794Stackerman}
862129794Stackerman
863129794Stackerman
864129794Stackerman/*********************************************************************
865129794Stackerman *
866129794Stackerman *  Media Ioctl callback
867129794Stackerman *
868129794Stackerman *  This routine is called whenever the user queries the status of
869129794Stackerman *  the interface using ifconfig.
870129794Stackerman *
871129794Stackerman **********************************************************************/
872129794Stackermanstatic void
873129794Stackermanixgb_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
874129794Stackerman{
875129794Stackerman	struct adapter *adapter = ifp->if_softc;
876129794Stackerman
877129794Stackerman	INIT_DEBUGOUT("ixgb_media_status: begin");
878129794Stackerman
879129794Stackerman	ixgb_check_for_link(&adapter->hw);
880129794Stackerman	ixgb_print_link_status(adapter);
881129794Stackerman
882129794Stackerman	ifmr->ifm_status = IFM_AVALID;
883129794Stackerman	ifmr->ifm_active = IFM_ETHER;
884129794Stackerman
885129794Stackerman	if (!adapter->hw.link_up)
886129794Stackerman		return;
887129794Stackerman
888129794Stackerman	ifmr->ifm_status |= IFM_ACTIVE;
889129794Stackerman	ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
890129794Stackerman
891129794Stackerman	return;
892129794Stackerman}
893129794Stackerman
894129794Stackerman/*********************************************************************
895129794Stackerman *
896129794Stackerman *  Media Ioctl callback
897129794Stackerman *
898129794Stackerman *  This routine is called when the user changes speed/duplex using
899129794Stackerman *  media/mediopt option with ifconfig.
900129794Stackerman *
901129794Stackerman **********************************************************************/
902129794Stackermanstatic int
903129794Stackermanixgb_media_change(struct ifnet * ifp)
904129794Stackerman{
905129794Stackerman	struct adapter *adapter = ifp->if_softc;
906129794Stackerman	struct ifmedia *ifm = &adapter->media;
907129794Stackerman
908129794Stackerman	INIT_DEBUGOUT("ixgb_media_change: begin");
909129794Stackerman
910129794Stackerman	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
911129794Stackerman		return (EINVAL);
912129794Stackerman
913129794Stackerman	return (0);
914129794Stackerman}
915129794Stackerman
916129794Stackerman/*********************************************************************
917129794Stackerman *
918129794Stackerman *  This routine maps the mbufs to tx descriptors.
919129794Stackerman *
920129794Stackerman *  return 0 on success, positive on failure
921129794Stackerman **********************************************************************/
922129794Stackerman
923129794Stackermanstatic int
924129794Stackermanixgb_encap(struct adapter * adapter, struct mbuf * m_head)
925129794Stackerman{
926129794Stackerman	u_int8_t        txd_popts;
927146339Salc	int             i, j, error, nsegs;
928129794Stackerman
929129794Stackerman#if __FreeBSD_version < 500000
930129794Stackerman	struct ifvlan  *ifv = NULL;
931129794Stackerman#endif
932146339Salc	bus_dma_segment_t segs[IXGB_MAX_SCATTER];
933146339Salc	bus_dmamap_t	map;
934129794Stackerman	struct ixgb_buffer *tx_buffer = NULL;
935129794Stackerman	struct ixgb_tx_desc *current_tx_desc = NULL;
936147256Sbrooks	struct ifnet   *ifp = adapter->ifp;
937129794Stackerman
938129794Stackerman	/*
939129794Stackerman	 * Force a cleanup if number of TX descriptors available hits the
940129794Stackerman	 * threshold
941129794Stackerman	 */
942129794Stackerman	if (adapter->num_tx_desc_avail <= IXGB_TX_CLEANUP_THRESHOLD) {
943129794Stackerman		ixgb_clean_transmit_interrupts(adapter);
944129794Stackerman	}
945129794Stackerman	if (adapter->num_tx_desc_avail <= IXGB_TX_CLEANUP_THRESHOLD) {
946129794Stackerman		adapter->no_tx_desc_avail1++;
947129794Stackerman		return (ENOBUFS);
948129794Stackerman	}
949129794Stackerman	/*
950129794Stackerman	 * Map the packet for DMA.
951129794Stackerman	 */
952146339Salc	if (bus_dmamap_create(adapter->txtag, BUS_DMA_NOWAIT, &map)) {
953129794Stackerman		adapter->no_tx_map_avail++;
954129794Stackerman		return (ENOMEM);
955129794Stackerman	}
956146339Salc	error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, m_head, segs,
957146339Salc					&nsegs, BUS_DMA_NOWAIT);
958129794Stackerman	if (error != 0) {
959129794Stackerman		adapter->no_tx_dma_setup++;
960198987Sjhb		if_printf(ifp, "ixgb_encap: bus_dmamap_load_mbuf failed; "
961198987Sjhb		       "error %u\n", error);
962146339Salc		bus_dmamap_destroy(adapter->txtag, map);
963129794Stackerman		return (error);
964129794Stackerman	}
965146339Salc	KASSERT(nsegs != 0, ("ixgb_encap: empty packet"));
966129794Stackerman
967146339Salc	if (nsegs > adapter->num_tx_desc_avail) {
968129794Stackerman		adapter->no_tx_desc_avail2++;
969146339Salc		bus_dmamap_destroy(adapter->txtag, map);
970129794Stackerman		return (ENOBUFS);
971129794Stackerman	}
972129794Stackerman	if (ifp->if_hwassist > 0) {
973129794Stackerman		ixgb_transmit_checksum_setup(adapter, m_head,
974129794Stackerman					     &txd_popts);
975129794Stackerman	} else
976129794Stackerman		txd_popts = 0;
977129794Stackerman
978129794Stackerman	/* Find out if we are in vlan mode */
979129794Stackerman#if __FreeBSD_version < 500000
980129794Stackerman	if ((m_head->m_flags & (M_PROTO1 | M_PKTHDR)) == (M_PROTO1 | M_PKTHDR) &&
981129794Stackerman	    m_head->m_pkthdr.rcvif != NULL &&
982129794Stackerman	    m_head->m_pkthdr.rcvif->if_type == IFT_L2VLAN)
983129794Stackerman		ifv = m_head->m_pkthdr.rcvif->if_softc;
984162375Sandre#elseif __FreeBSD_version < 700000
985129794Stackerman	mtag = VLAN_OUTPUT_TAG(ifp, m_head);
986129794Stackerman#endif
987129794Stackerman	i = adapter->next_avail_tx_desc;
988146339Salc	for (j = 0; j < nsegs; j++) {
989129794Stackerman		tx_buffer = &adapter->tx_buffer_area[i];
990129794Stackerman		current_tx_desc = &adapter->tx_desc_base[i];
991129794Stackerman
992146339Salc		current_tx_desc->buff_addr = htole64(segs[j].ds_addr);
993146339Salc		current_tx_desc->cmd_type_len = (adapter->txd_cmd | segs[j].ds_len);
994129794Stackerman		current_tx_desc->popts = txd_popts;
995129794Stackerman		if (++i == adapter->num_tx_desc)
996129794Stackerman			i = 0;
997129794Stackerman
998129794Stackerman		tx_buffer->m_head = NULL;
999129794Stackerman	}
1000129794Stackerman
1001146339Salc	adapter->num_tx_desc_avail -= nsegs;
1002129794Stackerman	adapter->next_avail_tx_desc = i;
1003129794Stackerman
1004129794Stackerman#if __FreeBSD_version < 500000
1005129794Stackerman	if (ifv != NULL) {
1006129794Stackerman		/* Set the vlan id */
1007129794Stackerman		current_tx_desc->vlan = ifv->ifv_tag;
1008162375Sandre#elseif __FreeBSD_version < 700000
1009129794Stackerman	if (mtag != NULL) {
1010129794Stackerman		/* Set the vlan id */
1011129794Stackerman		current_tx_desc->vlan = VLAN_TAG_VALUE(mtag);
1012162375Sandre#else
1013162375Sandre	if (m_head->m_flags & M_VLANTAG) {
1014162375Sandre		current_tx_desc->vlan = m_head->m_pkthdr.ether_vtag;
1015129794Stackerman#endif
1016129794Stackerman
1017129794Stackerman		/* Tell hardware to add tag */
1018129794Stackerman		current_tx_desc->cmd_type_len |= IXGB_TX_DESC_CMD_VLE;
1019129794Stackerman	}
1020129794Stackerman	tx_buffer->m_head = m_head;
1021146339Salc	tx_buffer->map = map;
1022146339Salc	bus_dmamap_sync(adapter->txtag, map, BUS_DMASYNC_PREWRITE);
1023129794Stackerman
1024129794Stackerman	/*
1025129794Stackerman	 * Last Descriptor of Packet needs End Of Packet (EOP)
1026129794Stackerman	 */
1027129794Stackerman	current_tx_desc->cmd_type_len |= (IXGB_TX_DESC_CMD_EOP);
1028129794Stackerman
1029129794Stackerman	/*
1030129794Stackerman	 * Advance the Transmit Descriptor Tail (Tdt), this tells the E1000
1031129794Stackerman	 * that this frame is available to transmit.
1032129794Stackerman	 */
1033129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDT, i);
1034129794Stackerman
1035129794Stackerman	return (0);
1036129794Stackerman}
1037129794Stackerman
1038129794Stackermanstatic void
1039129794Stackermanixgb_set_promisc(struct adapter * adapter)
1040129794Stackerman{
1041129794Stackerman
1042129794Stackerman	u_int32_t       reg_rctl;
1043147256Sbrooks	struct ifnet   *ifp = adapter->ifp;
1044129794Stackerman
1045129794Stackerman	reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL);
1046129794Stackerman
1047129794Stackerman	if (ifp->if_flags & IFF_PROMISC) {
1048129794Stackerman		reg_rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE);
1049129794Stackerman		IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
1050129794Stackerman	} else if (ifp->if_flags & IFF_ALLMULTI) {
1051129794Stackerman		reg_rctl |= IXGB_RCTL_MPE;
1052129794Stackerman		reg_rctl &= ~IXGB_RCTL_UPE;
1053129794Stackerman		IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
1054129794Stackerman	}
1055129794Stackerman	return;
1056129794Stackerman}
1057129794Stackerman
1058129794Stackermanstatic void
1059129794Stackermanixgb_disable_promisc(struct adapter * adapter)
1060129794Stackerman{
1061129794Stackerman	u_int32_t       reg_rctl;
1062129794Stackerman
1063129794Stackerman	reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL);
1064129794Stackerman
1065129794Stackerman	reg_rctl &= (~IXGB_RCTL_UPE);
1066129794Stackerman	reg_rctl &= (~IXGB_RCTL_MPE);
1067129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
1068129794Stackerman
1069129794Stackerman	return;
1070129794Stackerman}
1071129794Stackerman
1072129794Stackerman
1073129794Stackerman/*********************************************************************
1074129794Stackerman *  Multicast Update
1075129794Stackerman *
1076129794Stackerman *  This routine is called whenever multicast address list is updated.
1077129794Stackerman *
1078129794Stackerman **********************************************************************/
1079129794Stackerman
1080129794Stackermanstatic void
1081129794Stackermanixgb_set_multi(struct adapter * adapter)
1082129794Stackerman{
1083129794Stackerman	u_int32_t       reg_rctl = 0;
1084211913Syongari	u_int8_t        *mta;
1085129794Stackerman	struct ifmultiaddr *ifma;
1086129794Stackerman	int             mcnt = 0;
1087147256Sbrooks	struct ifnet   *ifp = adapter->ifp;
1088129794Stackerman
1089129794Stackerman	IOCTL_DEBUGOUT("ixgb_set_multi: begin");
1090129794Stackerman
1091211913Syongari	mta = adapter->mta;
1092211913Syongari	bzero(mta, sizeof(u_int8_t) * IXGB_ETH_LENGTH_OF_ADDRESS *
1093211913Syongari	    MAX_NUM_MULTICAST_ADDRESSES);
1094211913Syongari
1095195049Srwatson	if_maddr_rlock(ifp);
1096129794Stackerman#if __FreeBSD_version < 500000
1097129794Stackerman	LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1098129794Stackerman#else
1099129794Stackerman	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1100129794Stackerman#endif
1101129794Stackerman		if (ifma->ifma_addr->sa_family != AF_LINK)
1102129794Stackerman			continue;
1103129794Stackerman
1104129794Stackerman		bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
1105129794Stackerman		      &mta[mcnt * IXGB_ETH_LENGTH_OF_ADDRESS], IXGB_ETH_LENGTH_OF_ADDRESS);
1106129794Stackerman		mcnt++;
1107129794Stackerman	}
1108195049Srwatson	if_maddr_runlock(ifp);
1109129794Stackerman
1110129794Stackerman	if (mcnt > MAX_NUM_MULTICAST_ADDRESSES) {
1111129794Stackerman		reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL);
1112129794Stackerman		reg_rctl |= IXGB_RCTL_MPE;
1113129794Stackerman		IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
1114129794Stackerman	} else
1115129794Stackerman		ixgb_mc_addr_list_update(&adapter->hw, mta, mcnt, 0);
1116129794Stackerman
1117129794Stackerman	return;
1118129794Stackerman}
1119129794Stackerman
1120129794Stackerman
1121129794Stackerman/*********************************************************************
1122129794Stackerman *  Timer routine
1123129794Stackerman *
1124129794Stackerman *  This routine checks for link status and updates statistics.
1125129794Stackerman *
1126129794Stackerman **********************************************************************/
1127129794Stackerman
1128129794Stackermanstatic void
1129129794Stackermanixgb_local_timer(void *arg)
1130129794Stackerman{
1131129794Stackerman	struct ifnet   *ifp;
1132129794Stackerman	struct adapter *adapter = arg;
1133147256Sbrooks	ifp = adapter->ifp;
1134129794Stackerman
1135199539Sjhb	IXGB_LOCK_ASSERT(adapter);
1136129794Stackerman
1137129794Stackerman	ixgb_check_for_link(&adapter->hw);
1138129794Stackerman	ixgb_print_link_status(adapter);
1139129794Stackerman	ixgb_update_stats_counters(adapter);
1140148887Srwatson	if (ixgb_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) {
1141129794Stackerman		ixgb_print_hw_stats(adapter);
1142129794Stackerman	}
1143199539Sjhb	if (adapter->tx_timer != 0 && --adapter->tx_timer == 0)
1144199539Sjhb		ixgb_watchdog(adapter);
1145199539Sjhb	callout_reset(&adapter->timer, hz, ixgb_local_timer, adapter);
1146129794Stackerman}
1147129794Stackerman
1148129794Stackermanstatic void
1149129794Stackermanixgb_print_link_status(struct adapter * adapter)
1150129794Stackerman{
1151129794Stackerman	if (adapter->hw.link_up) {
1152129794Stackerman		if (!adapter->link_active) {
1153198987Sjhb			if_printf(adapter->ifp, "Link is up %d Mbps %s \n",
1154129794Stackerman			       10000,
1155129794Stackerman			       "Full Duplex");
1156129794Stackerman			adapter->link_active = 1;
1157129794Stackerman		}
1158129794Stackerman	} else {
1159129794Stackerman		if (adapter->link_active) {
1160198987Sjhb			if_printf(adapter->ifp, "Link is Down \n");
1161129794Stackerman			adapter->link_active = 0;
1162129794Stackerman		}
1163129794Stackerman	}
1164129794Stackerman
1165129794Stackerman	return;
1166129794Stackerman}
1167129794Stackerman
1168129794Stackerman
1169129794Stackerman
1170129794Stackerman/*********************************************************************
1171129794Stackerman *
1172129794Stackerman *  This routine disables all traffic on the adapter by issuing a
1173129794Stackerman *  global reset on the MAC and deallocates TX/RX buffers.
1174129794Stackerman *
1175129794Stackerman **********************************************************************/
1176129794Stackerman
1177129794Stackermanstatic void
1178129794Stackermanixgb_stop(void *arg)
1179129794Stackerman{
1180129794Stackerman	struct ifnet   *ifp;
1181129794Stackerman	struct adapter *adapter = arg;
1182147256Sbrooks	ifp = adapter->ifp;
1183129794Stackerman
1184144651Salc	IXGB_LOCK_ASSERT(adapter);
1185144651Salc
1186129794Stackerman	INIT_DEBUGOUT("ixgb_stop: begin\n");
1187129794Stackerman	ixgb_disable_intr(adapter);
1188129794Stackerman	adapter->hw.adapter_stopped = FALSE;
1189129794Stackerman	ixgb_adapter_stop(&adapter->hw);
1190144651Salc	callout_stop(&adapter->timer);
1191129794Stackerman	ixgb_free_transmit_structures(adapter);
1192129794Stackerman	ixgb_free_receive_structures(adapter);
1193129794Stackerman
1194129794Stackerman	/* Tell the stack that the interface is no longer active */
1195148887Srwatson	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1196199539Sjhb	adapter->tx_timer = 0;
1197129794Stackerman
1198129794Stackerman	return;
1199129794Stackerman}
1200129794Stackerman
1201129794Stackerman
1202129794Stackerman/*********************************************************************
1203129794Stackerman *
1204129794Stackerman *  Determine hardware revision.
1205129794Stackerman *
1206129794Stackerman **********************************************************************/
1207129794Stackermanstatic void
1208129794Stackermanixgb_identify_hardware(struct adapter * adapter)
1209129794Stackerman{
1210129794Stackerman	device_t        dev = adapter->dev;
1211129794Stackerman
1212129794Stackerman	/* Make sure our PCI config space has the necessary stuff set */
1213254263Sscottl	pci_enable_busmaster(dev);
1214129794Stackerman	adapter->hw.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
1215254263Sscottl
1216129794Stackerman	/* Save off the information about this board */
1217129794Stackerman	adapter->hw.vendor_id = pci_get_vendor(dev);
1218129794Stackerman	adapter->hw.device_id = pci_get_device(dev);
1219129794Stackerman	adapter->hw.revision_id = pci_read_config(dev, PCIR_REVID, 1);
1220129794Stackerman	adapter->hw.subsystem_vendor_id = pci_read_config(dev, PCIR_SUBVEND_0, 2);
1221129794Stackerman	adapter->hw.subsystem_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
1222129794Stackerman
1223129794Stackerman	/* Set MacType, etc. based on this PCI info */
1224129794Stackerman	switch (adapter->hw.device_id) {
1225129794Stackerman	case IXGB_DEVICE_ID_82597EX:
1226129794Stackerman	case IXGB_DEVICE_ID_82597EX_SR:
1227129794Stackerman		adapter->hw.mac_type = ixgb_82597;
1228129794Stackerman		break;
1229129794Stackerman	default:
1230129794Stackerman		INIT_DEBUGOUT1("Unknown device if 0x%x", adapter->hw.device_id);
1231198987Sjhb		device_printf(dev, "unsupported device id 0x%x\n",
1232198987Sjhb		    adapter->hw.device_id);
1233129794Stackerman	}
1234129794Stackerman
1235129794Stackerman	return;
1236129794Stackerman}
1237129794Stackerman
1238129794Stackermanstatic int
1239129794Stackermanixgb_allocate_pci_resources(struct adapter * adapter)
1240129794Stackerman{
1241129794Stackerman	int             rid;
1242129794Stackerman	device_t        dev = adapter->dev;
1243129794Stackerman
1244129794Stackerman	rid = IXGB_MMBA;
1245129794Stackerman	adapter->res_memory = bus_alloc_resource(dev, SYS_RES_MEMORY,
1246129794Stackerman						 &rid, 0, ~0, 1,
1247129794Stackerman						 RF_ACTIVE);
1248129794Stackerman	if (!(adapter->res_memory)) {
1249198987Sjhb		device_printf(dev, "Unable to allocate bus resource: memory\n");
1250129794Stackerman		return (ENXIO);
1251129794Stackerman	}
1252129794Stackerman	adapter->osdep.mem_bus_space_tag =
1253129794Stackerman		rman_get_bustag(adapter->res_memory);
1254129794Stackerman	adapter->osdep.mem_bus_space_handle =
1255129794Stackerman		rman_get_bushandle(adapter->res_memory);
1256129794Stackerman	adapter->hw.hw_addr = (uint8_t *) & adapter->osdep.mem_bus_space_handle;
1257129794Stackerman
1258129794Stackerman	rid = 0x0;
1259129794Stackerman	adapter->res_interrupt = bus_alloc_resource(dev, SYS_RES_IRQ,
1260129794Stackerman						    &rid, 0, ~0, 1,
1261129794Stackerman						  RF_SHAREABLE | RF_ACTIVE);
1262129794Stackerman	if (!(adapter->res_interrupt)) {
1263198987Sjhb		device_printf(dev,
1264198987Sjhb		    "Unable to allocate bus resource: interrupt\n");
1265129794Stackerman		return (ENXIO);
1266129794Stackerman	}
1267144651Salc	if (bus_setup_intr(dev, adapter->res_interrupt,
1268144651Salc			   INTR_TYPE_NET | INTR_MPSAFE,
1269166901Spiso			   NULL, (void (*) (void *))ixgb_intr, adapter,
1270129794Stackerman			   &adapter->int_handler_tag)) {
1271198987Sjhb		device_printf(dev, "Error registering interrupt handler!\n");
1272129794Stackerman		return (ENXIO);
1273129794Stackerman	}
1274129794Stackerman	adapter->hw.back = &adapter->osdep;
1275129794Stackerman
1276129794Stackerman	return (0);
1277129794Stackerman}
1278129794Stackerman
1279129794Stackermanstatic void
1280129794Stackermanixgb_free_pci_resources(struct adapter * adapter)
1281129794Stackerman{
1282129794Stackerman	device_t        dev = adapter->dev;
1283129794Stackerman
1284129794Stackerman	if (adapter->res_interrupt != NULL) {
1285129794Stackerman		bus_teardown_intr(dev, adapter->res_interrupt,
1286129794Stackerman				  adapter->int_handler_tag);
1287129794Stackerman		bus_release_resource(dev, SYS_RES_IRQ, 0,
1288129794Stackerman				     adapter->res_interrupt);
1289129794Stackerman	}
1290129794Stackerman	if (adapter->res_memory != NULL) {
1291129794Stackerman		bus_release_resource(dev, SYS_RES_MEMORY, IXGB_MMBA,
1292129794Stackerman				     adapter->res_memory);
1293129794Stackerman	}
1294129794Stackerman	if (adapter->res_ioport != NULL) {
1295129794Stackerman		bus_release_resource(dev, SYS_RES_IOPORT, adapter->io_rid,
1296129794Stackerman				     adapter->res_ioport);
1297129794Stackerman	}
1298129794Stackerman	return;
1299129794Stackerman}
1300129794Stackerman
1301129794Stackerman/*********************************************************************
1302129794Stackerman *
1303129794Stackerman *  Initialize the hardware to a configuration as specified by the
1304129794Stackerman *  adapter structure. The controller is reset, the EEPROM is
1305129794Stackerman *  verified, the MAC address is set, then the shared initialization
1306129794Stackerman *  routines are called.
1307129794Stackerman *
1308129794Stackerman **********************************************************************/
1309129794Stackermanstatic int
1310129794Stackermanixgb_hardware_init(struct adapter * adapter)
1311129794Stackerman{
1312129794Stackerman	/* Issue a global reset */
1313129794Stackerman	adapter->hw.adapter_stopped = FALSE;
1314129794Stackerman	ixgb_adapter_stop(&adapter->hw);
1315129794Stackerman
1316129794Stackerman	/* Make sure we have a good EEPROM before we read from it */
1317129794Stackerman	if (!ixgb_validate_eeprom_checksum(&adapter->hw)) {
1318198987Sjhb		device_printf(adapter->dev,
1319198987Sjhb		    "The EEPROM Checksum Is Not Valid\n");
1320129794Stackerman		return (EIO);
1321129794Stackerman	}
1322129794Stackerman	if (!ixgb_init_hw(&adapter->hw)) {
1323198987Sjhb		device_printf(adapter->dev, "Hardware Initialization Failed");
1324129794Stackerman		return (EIO);
1325129794Stackerman	}
1326129794Stackerman
1327129794Stackerman	return (0);
1328129794Stackerman}
1329129794Stackerman
1330129794Stackerman/*********************************************************************
1331129794Stackerman *
1332129794Stackerman *  Setup networking device structure and register an interface.
1333129794Stackerman *
1334129794Stackerman **********************************************************************/
1335211907Syongaristatic int
1336129794Stackermanixgb_setup_interface(device_t dev, struct adapter * adapter)
1337129794Stackerman{
1338129794Stackerman	struct ifnet   *ifp;
1339129794Stackerman	INIT_DEBUGOUT("ixgb_setup_interface: begin");
1340129794Stackerman
1341147256Sbrooks	ifp = adapter->ifp = if_alloc(IFT_ETHER);
1342211907Syongari	if (ifp == NULL) {
1343211907Syongari		device_printf(dev, "can not allocate ifnet structure\n");
1344211907Syongari		return (-1);
1345211907Syongari	}
1346129794Stackerman#if __FreeBSD_version >= 502000
1347129794Stackerman	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1348129794Stackerman#else
1349198987Sjhb	ifp->if_unit = device_get_unit(dev);
1350129794Stackerman	ifp->if_name = "ixgb";
1351129794Stackerman#endif
1352129794Stackerman	ifp->if_baudrate = 1000000000;
1353129794Stackerman	ifp->if_init = ixgb_init;
1354129794Stackerman	ifp->if_softc = adapter;
1355144651Salc	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1356129794Stackerman	ifp->if_ioctl = ixgb_ioctl;
1357129794Stackerman	ifp->if_start = ixgb_start;
1358129794Stackerman	ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 1;
1359129794Stackerman
1360129794Stackerman#if __FreeBSD_version < 500000
1361129794Stackerman	ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
1362129794Stackerman#else
1363147256Sbrooks	ether_ifattach(ifp, adapter->hw.curr_mac_addr);
1364129794Stackerman#endif
1365129794Stackerman
1366129794Stackerman	ifp->if_capabilities = IFCAP_HWCSUM;
1367129794Stackerman
1368129794Stackerman	/*
1369129794Stackerman	 * Tell the upper layer(s) we support long frames.
1370129794Stackerman	 */
1371129794Stackerman	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
1372129794Stackerman
1373129794Stackerman#if __FreeBSD_version >= 500000
1374129794Stackerman	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
1375129794Stackerman#endif
1376148637Sbrueffer
1377148637Sbrueffer	ifp->if_capenable = ifp->if_capabilities;
1378148637Sbrueffer
1379150789Sglebius#ifdef DEVICE_POLLING
1380150789Sglebius	ifp->if_capabilities |= IFCAP_POLLING;
1381150789Sglebius#endif
1382150789Sglebius
1383129794Stackerman	/*
1384129794Stackerman	 * Specify the media types supported by this adapter and register
1385129794Stackerman	 * callbacks to update media and link information
1386129794Stackerman	 */
1387129794Stackerman	ifmedia_init(&adapter->media, IFM_IMASK, ixgb_media_change,
1388129794Stackerman		     ixgb_media_status);
1389129794Stackerman	ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX | IFM_FDX,
1390129794Stackerman		    0, NULL);
1391129794Stackerman	ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX,
1392129794Stackerman		    0, NULL);
1393129794Stackerman	ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
1394129794Stackerman	ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
1395129794Stackerman
1396211907Syongari	return (0);
1397129794Stackerman}
1398129794Stackerman
1399129794Stackerman/********************************************************************
1400129794Stackerman * Manage DMA'able memory.
1401129794Stackerman *******************************************************************/
1402129794Stackermanstatic void
1403129794Stackermanixgb_dmamap_cb(void *arg, bus_dma_segment_t * segs, int nseg, int error)
1404129794Stackerman{
1405129794Stackerman	if (error)
1406129794Stackerman		return;
1407129794Stackerman	*(bus_addr_t *) arg = segs->ds_addr;
1408129794Stackerman	return;
1409129794Stackerman}
1410129794Stackerman
1411129794Stackermanstatic int
1412129794Stackermanixgb_dma_malloc(struct adapter * adapter, bus_size_t size,
1413129794Stackerman		struct ixgb_dma_alloc * dma, int mapflags)
1414129794Stackerman{
1415198987Sjhb	device_t dev;
1416129794Stackerman	int             r;
1417129794Stackerman
1418198987Sjhb	dev = adapter->dev;
1419232874Sscottl	r = bus_dma_tag_create(bus_get_dma_tag(dev),	/* parent */
1420129794Stackerman			       PAGE_SIZE, 0,	/* alignment, bounds */
1421129794Stackerman			       BUS_SPACE_MAXADDR,	/* lowaddr */
1422129794Stackerman			       BUS_SPACE_MAXADDR,	/* highaddr */
1423129794Stackerman			       NULL, NULL,	/* filter, filterarg */
1424129794Stackerman			       size,	/* maxsize */
1425129794Stackerman			       1,	/* nsegments */
1426129794Stackerman			       size,	/* maxsegsize */
1427129794Stackerman			       BUS_DMA_ALLOCNOW,	/* flags */
1428129794Stackerman#if __FreeBSD_version >= 502000
1429129794Stackerman			       NULL,	/* lockfunc */
1430129794Stackerman			       NULL,	/* lockfuncarg */
1431129794Stackerman#endif
1432129794Stackerman			       &dma->dma_tag);
1433129794Stackerman	if (r != 0) {
1434198987Sjhb		device_printf(dev, "ixgb_dma_malloc: bus_dma_tag_create failed; "
1435198987Sjhb		       "error %u\n", r);
1436129794Stackerman		goto fail_0;
1437129794Stackerman	}
1438129794Stackerman	r = bus_dmamem_alloc(dma->dma_tag, (void **)&dma->dma_vaddr,
1439129794Stackerman			     BUS_DMA_NOWAIT, &dma->dma_map);
1440129794Stackerman	if (r != 0) {
1441198987Sjhb		device_printf(dev, "ixgb_dma_malloc: bus_dmamem_alloc failed; "
1442198987Sjhb		       "error %u\n", r);
1443144183Smux		goto fail_1;
1444129794Stackerman	}
1445129794Stackerman	r = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr,
1446129794Stackerman			    size,
1447129794Stackerman			    ixgb_dmamap_cb,
1448129794Stackerman			    &dma->dma_paddr,
1449129794Stackerman			    mapflags | BUS_DMA_NOWAIT);
1450129794Stackerman	if (r != 0) {
1451198987Sjhb		device_printf(dev, "ixgb_dma_malloc: bus_dmamap_load failed; "
1452198987Sjhb		       "error %u\n", r);
1453144183Smux		goto fail_2;
1454129794Stackerman	}
1455129794Stackerman	dma->dma_size = size;
1456129794Stackerman	return (0);
1457129794Stackermanfail_2:
1458129794Stackerman	bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
1459129794Stackermanfail_1:
1460129794Stackerman	bus_dma_tag_destroy(dma->dma_tag);
1461129794Stackermanfail_0:
1462129794Stackerman	dma->dma_tag = NULL;
1463129794Stackerman	return (r);
1464129794Stackerman}
1465129794Stackerman
1466129794Stackerman
1467129794Stackerman
1468129794Stackermanstatic void
1469129794Stackermanixgb_dma_free(struct adapter * adapter, struct ixgb_dma_alloc * dma)
1470129794Stackerman{
1471129794Stackerman	bus_dmamap_unload(dma->dma_tag, dma->dma_map);
1472129794Stackerman	bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
1473129794Stackerman	bus_dma_tag_destroy(dma->dma_tag);
1474129794Stackerman}
1475129794Stackerman
1476129794Stackerman/*********************************************************************
1477129794Stackerman *
1478129794Stackerman *  Allocate memory for tx_buffer structures. The tx_buffer stores all
1479129794Stackerman *  the information needed to transmit a packet on the wire.
1480129794Stackerman *
1481129794Stackerman **********************************************************************/
1482129794Stackermanstatic int
1483129794Stackermanixgb_allocate_transmit_structures(struct adapter * adapter)
1484129794Stackerman{
1485129794Stackerman	if (!(adapter->tx_buffer_area =
1486129794Stackerman	      (struct ixgb_buffer *) malloc(sizeof(struct ixgb_buffer) *
1487129794Stackerman					    adapter->num_tx_desc, M_DEVBUF,
1488129794Stackerman					    M_NOWAIT | M_ZERO))) {
1489198987Sjhb		device_printf(adapter->dev,
1490198987Sjhb		    "Unable to allocate tx_buffer memory\n");
1491129794Stackerman		return ENOMEM;
1492129794Stackerman	}
1493129794Stackerman	bzero(adapter->tx_buffer_area,
1494129794Stackerman	      sizeof(struct ixgb_buffer) * adapter->num_tx_desc);
1495129794Stackerman
1496129794Stackerman	return 0;
1497129794Stackerman}
1498129794Stackerman
1499129794Stackerman/*********************************************************************
1500129794Stackerman *
1501129794Stackerman *  Allocate and initialize transmit structures.
1502129794Stackerman *
1503129794Stackerman **********************************************************************/
1504129794Stackermanstatic int
1505129794Stackermanixgb_setup_transmit_structures(struct adapter * adapter)
1506129794Stackerman{
1507129794Stackerman	/*
1508129794Stackerman	 * Setup DMA descriptor areas.
1509129794Stackerman	 */
1510232874Sscottl	if (bus_dma_tag_create(bus_get_dma_tag(adapter->dev),	/* parent */
1511129794Stackerman			       PAGE_SIZE, 0,	/* alignment, bounds */
1512129794Stackerman			       BUS_SPACE_MAXADDR,	/* lowaddr */
1513129794Stackerman			       BUS_SPACE_MAXADDR,	/* highaddr */
1514129794Stackerman			       NULL, NULL,	/* filter, filterarg */
1515129794Stackerman			       MCLBYTES * IXGB_MAX_SCATTER,	/* maxsize */
1516129794Stackerman			       IXGB_MAX_SCATTER,	/* nsegments */
1517129794Stackerman			       MCLBYTES,	/* maxsegsize */
1518129794Stackerman			       BUS_DMA_ALLOCNOW,	/* flags */
1519129794Stackerman#if __FreeBSD_version >= 502000
1520129794Stackerman			       NULL,	/* lockfunc */
1521129794Stackerman			       NULL,	/* lockfuncarg */
1522129794Stackerman#endif
1523129794Stackerman			       &adapter->txtag)) {
1524198987Sjhb		device_printf(adapter->dev, "Unable to allocate TX DMA tag\n");
1525129794Stackerman		return (ENOMEM);
1526129794Stackerman	}
1527129794Stackerman	if (ixgb_allocate_transmit_structures(adapter))
1528129794Stackerman		return ENOMEM;
1529129794Stackerman
1530129794Stackerman	bzero((void *)adapter->tx_desc_base,
1531129794Stackerman	      (sizeof(struct ixgb_tx_desc)) * adapter->num_tx_desc);
1532129794Stackerman
1533129794Stackerman	adapter->next_avail_tx_desc = 0;
1534129794Stackerman	adapter->oldest_used_tx_desc = 0;
1535129794Stackerman
1536129794Stackerman	/* Set number of descriptors available */
1537129794Stackerman	adapter->num_tx_desc_avail = adapter->num_tx_desc;
1538129794Stackerman
1539129794Stackerman	/* Set checksum context */
1540129794Stackerman	adapter->active_checksum_context = OFFLOAD_NONE;
1541129794Stackerman
1542129794Stackerman	return 0;
1543129794Stackerman}
1544129794Stackerman
1545129794Stackerman/*********************************************************************
1546129794Stackerman *
1547129794Stackerman *  Enable transmit unit.
1548129794Stackerman *
1549129794Stackerman **********************************************************************/
1550129794Stackermanstatic void
1551129794Stackermanixgb_initialize_transmit_unit(struct adapter * adapter)
1552129794Stackerman{
1553129794Stackerman	u_int32_t       reg_tctl;
1554144183Smux	u_int64_t       tdba = adapter->txdma.dma_paddr;
1555129794Stackerman
1556129794Stackerman	/* Setup the Base and Length of the Tx Descriptor Ring */
1557129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDBAL,
1558129794Stackerman		       (tdba & 0x00000000ffffffffULL));
1559129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDBAH, (tdba >> 32));
1560129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDLEN,
1561129794Stackerman		       adapter->num_tx_desc *
1562129794Stackerman		       sizeof(struct ixgb_tx_desc));
1563129794Stackerman
1564129794Stackerman	/* Setup the HW Tx Head and Tail descriptor pointers */
1565129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDH, 0);
1566129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TDT, 0);
1567129794Stackerman
1568129794Stackerman
1569129794Stackerman	HW_DEBUGOUT2("Base = %x, Length = %x\n",
1570129794Stackerman		     IXGB_READ_REG(&adapter->hw, TDBAL),
1571129794Stackerman		     IXGB_READ_REG(&adapter->hw, TDLEN));
1572129794Stackerman
1573129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TIDV, adapter->tx_int_delay);
1574129794Stackerman
1575129794Stackerman
1576129794Stackerman	/* Program the Transmit Control Register */
1577129794Stackerman	reg_tctl = IXGB_READ_REG(&adapter->hw, TCTL);
1578129794Stackerman	reg_tctl = IXGB_TCTL_TCE | IXGB_TCTL_TXEN | IXGB_TCTL_TPDE;
1579129794Stackerman	IXGB_WRITE_REG(&adapter->hw, TCTL, reg_tctl);
1580129794Stackerman
1581129794Stackerman	/* Setup Transmit Descriptor Settings for this adapter */
1582129794Stackerman	adapter->txd_cmd = IXGB_TX_DESC_TYPE | IXGB_TX_DESC_CMD_RS;
1583129794Stackerman
1584129794Stackerman	if (adapter->tx_int_delay > 0)
1585129794Stackerman		adapter->txd_cmd |= IXGB_TX_DESC_CMD_IDE;
1586129794Stackerman	return;
1587129794Stackerman}
1588129794Stackerman
1589129794Stackerman/*********************************************************************
1590129794Stackerman *
1591129794Stackerman *  Free all transmit related data structures.
1592129794Stackerman *
1593129794Stackerman **********************************************************************/
1594129794Stackermanstatic void
1595129794Stackermanixgb_free_transmit_structures(struct adapter * adapter)
1596129794Stackerman{
1597129794Stackerman	struct ixgb_buffer *tx_buffer;
1598129794Stackerman	int             i;
1599129794Stackerman
1600129794Stackerman	INIT_DEBUGOUT("free_transmit_structures: begin");
1601129794Stackerman
1602129794Stackerman	if (adapter->tx_buffer_area != NULL) {
1603129794Stackerman		tx_buffer = adapter->tx_buffer_area;
1604129794Stackerman		for (i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
1605129794Stackerman			if (tx_buffer->m_head != NULL) {
1606129794Stackerman				bus_dmamap_unload(adapter->txtag, tx_buffer->map);
1607129794Stackerman				bus_dmamap_destroy(adapter->txtag, tx_buffer->map);
1608129794Stackerman				m_freem(tx_buffer->m_head);
1609129794Stackerman			}
1610129794Stackerman			tx_buffer->m_head = NULL;
1611129794Stackerman		}
1612129794Stackerman	}
1613129794Stackerman	if (adapter->tx_buffer_area != NULL) {
1614129794Stackerman		free(adapter->tx_buffer_area, M_DEVBUF);
1615129794Stackerman		adapter->tx_buffer_area = NULL;
1616129794Stackerman	}
1617129794Stackerman	if (adapter->txtag != NULL) {
1618129794Stackerman		bus_dma_tag_destroy(adapter->txtag);
1619129794Stackerman		adapter->txtag = NULL;
1620129794Stackerman	}
1621129794Stackerman	return;
1622129794Stackerman}
1623129794Stackerman
1624129794Stackerman/*********************************************************************
1625129794Stackerman *
1626129794Stackerman *  The offload context needs to be set when we transfer the first
1627129794Stackerman *  packet of a particular protocol (TCP/UDP). We change the
1628129794Stackerman *  context only if the protocol type changes.
1629129794Stackerman *
1630129794Stackerman **********************************************************************/
1631129794Stackermanstatic void
1632129794Stackermanixgb_transmit_checksum_setup(struct adapter * adapter,
1633129794Stackerman			     struct mbuf * mp,
1634129794Stackerman			     u_int8_t * txd_popts)
1635129794Stackerman{
1636129794Stackerman	struct ixgb_context_desc *TXD;
1637129794Stackerman	struct ixgb_buffer *tx_buffer;
1638129794Stackerman	int             curr_txd;
1639129794Stackerman
1640129794Stackerman	if (mp->m_pkthdr.csum_flags) {
1641129794Stackerman
1642129794Stackerman		if (mp->m_pkthdr.csum_flags & CSUM_TCP) {
1643129794Stackerman			*txd_popts = IXGB_TX_DESC_POPTS_TXSM;
1644129794Stackerman			if (adapter->active_checksum_context == OFFLOAD_TCP_IP)
1645129794Stackerman				return;
1646129794Stackerman			else
1647129794Stackerman				adapter->active_checksum_context = OFFLOAD_TCP_IP;
1648129794Stackerman		} else if (mp->m_pkthdr.csum_flags & CSUM_UDP) {
1649129794Stackerman			*txd_popts = IXGB_TX_DESC_POPTS_TXSM;
1650129794Stackerman			if (adapter->active_checksum_context == OFFLOAD_UDP_IP)
1651129794Stackerman				return;
1652129794Stackerman			else
1653129794Stackerman				adapter->active_checksum_context = OFFLOAD_UDP_IP;
1654129794Stackerman		} else {
1655129794Stackerman			*txd_popts = 0;
1656129794Stackerman			return;
1657129794Stackerman		}
1658129794Stackerman	} else {
1659129794Stackerman		*txd_popts = 0;
1660129794Stackerman		return;
1661129794Stackerman	}
1662129794Stackerman
1663129794Stackerman	/*
1664129794Stackerman	 * If we reach this point, the checksum offload context needs to be
1665129794Stackerman	 * reset.
1666129794Stackerman	 */
1667129794Stackerman	curr_txd = adapter->next_avail_tx_desc;
1668129794Stackerman	tx_buffer = &adapter->tx_buffer_area[curr_txd];
1669129794Stackerman	TXD = (struct ixgb_context_desc *) & adapter->tx_desc_base[curr_txd];
1670129794Stackerman
1671129794Stackerman
1672129794Stackerman	TXD->tucss = ENET_HEADER_SIZE + sizeof(struct ip);
1673129794Stackerman	TXD->tucse = 0;
1674129794Stackerman
1675129794Stackerman	TXD->mss = 0;
1676129794Stackerman
1677129794Stackerman	if (adapter->active_checksum_context == OFFLOAD_TCP_IP) {
1678129794Stackerman		TXD->tucso =
1679129794Stackerman			ENET_HEADER_SIZE + sizeof(struct ip) +
1680129794Stackerman			offsetof(struct tcphdr, th_sum);
1681129794Stackerman	} else if (adapter->active_checksum_context == OFFLOAD_UDP_IP) {
1682129794Stackerman		TXD->tucso =
1683129794Stackerman			ENET_HEADER_SIZE + sizeof(struct ip) +
1684129794Stackerman			offsetof(struct udphdr, uh_sum);
1685129794Stackerman	}
1686129794Stackerman	TXD->cmd_type_len = IXGB_CONTEXT_DESC_CMD_TCP | IXGB_TX_DESC_CMD_RS | IXGB_CONTEXT_DESC_CMD_IDE;
1687129794Stackerman
1688129794Stackerman	tx_buffer->m_head = NULL;
1689129794Stackerman
1690129794Stackerman	if (++curr_txd == adapter->num_tx_desc)
1691129794Stackerman		curr_txd = 0;
1692129794Stackerman
1693129794Stackerman	adapter->num_tx_desc_avail--;
1694129794Stackerman	adapter->next_avail_tx_desc = curr_txd;
1695129794Stackerman	return;
1696129794Stackerman}
1697129794Stackerman
1698129794Stackerman/**********************************************************************
1699129794Stackerman *
1700129794Stackerman *  Examine each tx_buffer in the used queue. If the hardware is done
1701129794Stackerman *  processing the packet then free associated resources. The
1702129794Stackerman *  tx_buffer is put back on the free queue.
1703129794Stackerman *
1704129794Stackerman **********************************************************************/
1705129794Stackermanstatic void
1706129794Stackermanixgb_clean_transmit_interrupts(struct adapter * adapter)
1707129794Stackerman{
1708129794Stackerman	int             i, num_avail;
1709129794Stackerman	struct ixgb_buffer *tx_buffer;
1710129794Stackerman	struct ixgb_tx_desc *tx_desc;
1711129794Stackerman
1712144651Salc	IXGB_LOCK_ASSERT(adapter);
1713129794Stackerman
1714129794Stackerman	if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
1715129794Stackerman		return;
1716129794Stackerman
1717129794Stackerman#ifdef _SV_
1718129794Stackerman	adapter->clean_tx_interrupts++;
1719129794Stackerman#endif
1720129794Stackerman	num_avail = adapter->num_tx_desc_avail;
1721129794Stackerman	i = adapter->oldest_used_tx_desc;
1722129794Stackerman
1723129794Stackerman	tx_buffer = &adapter->tx_buffer_area[i];
1724129794Stackerman	tx_desc = &adapter->tx_desc_base[i];
1725129794Stackerman
1726129794Stackerman	while (tx_desc->status & IXGB_TX_DESC_STATUS_DD) {
1727129794Stackerman
1728129794Stackerman		tx_desc->status = 0;
1729129794Stackerman		num_avail++;
1730129794Stackerman
1731129794Stackerman		if (tx_buffer->m_head) {
1732129794Stackerman			bus_dmamap_sync(adapter->txtag, tx_buffer->map,
1733129794Stackerman					BUS_DMASYNC_POSTWRITE);
1734129794Stackerman			bus_dmamap_unload(adapter->txtag, tx_buffer->map);
1735129794Stackerman			bus_dmamap_destroy(adapter->txtag, tx_buffer->map);
1736129794Stackerman			m_freem(tx_buffer->m_head);
1737129794Stackerman			tx_buffer->m_head = NULL;
1738129794Stackerman		}
1739129794Stackerman		if (++i == adapter->num_tx_desc)
1740129794Stackerman			i = 0;
1741129794Stackerman
1742129794Stackerman		tx_buffer = &adapter->tx_buffer_area[i];
1743129794Stackerman		tx_desc = &adapter->tx_desc_base[i];
1744129794Stackerman	}
1745129794Stackerman
1746129794Stackerman	adapter->oldest_used_tx_desc = i;
1747129794Stackerman
1748129794Stackerman	/*
1749148887Srwatson	 * If we have enough room, clear IFF_DRV_OACTIVE to tell the stack that
1750129794Stackerman	 * it is OK to send packets. If there are no pending descriptors,
1751129794Stackerman	 * clear the timeout. Otherwise, if some descriptors have been freed,
1752129794Stackerman	 * restart the timeout.
1753129794Stackerman	 */
1754129794Stackerman	if (num_avail > IXGB_TX_CLEANUP_THRESHOLD) {
1755147256Sbrooks		struct ifnet   *ifp = adapter->ifp;
1756129794Stackerman
1757148887Srwatson		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1758129794Stackerman		if (num_avail == adapter->num_tx_desc)
1759199539Sjhb			adapter->tx_timer = 0;
1760129794Stackerman		else if (num_avail == adapter->num_tx_desc_avail)
1761199539Sjhb			adapter->tx_timer = IXGB_TX_TIMEOUT;
1762129794Stackerman	}
1763129794Stackerman	adapter->num_tx_desc_avail = num_avail;
1764129794Stackerman	return;
1765129794Stackerman}
1766129794Stackerman
1767129794Stackerman
1768129794Stackerman/*********************************************************************
1769129794Stackerman *
1770129794Stackerman *  Get a buffer from system mbuf buffer pool.
1771129794Stackerman *
1772129794Stackerman **********************************************************************/
1773129794Stackermanstatic int
1774129794Stackermanixgb_get_buf(int i, struct adapter * adapter,
1775129794Stackerman	     struct mbuf * nmp)
1776129794Stackerman{
1777129794Stackerman	register struct mbuf *mp = nmp;
1778129794Stackerman	struct ixgb_buffer *rx_buffer;
1779129794Stackerman	struct ifnet   *ifp;
1780129794Stackerman	bus_addr_t      paddr;
1781129794Stackerman	int             error;
1782129794Stackerman
1783147256Sbrooks	ifp = adapter->ifp;
1784129794Stackerman
1785129794Stackerman	if (mp == NULL) {
1786129794Stackerman
1787243857Sglebius		mp = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1788129794Stackerman
1789129794Stackerman		if (mp == NULL) {
1790129794Stackerman			adapter->mbuf_alloc_failed++;
1791129794Stackerman			return (ENOBUFS);
1792129794Stackerman		}
1793129794Stackerman		mp->m_len = mp->m_pkthdr.len = MCLBYTES;
1794129794Stackerman	} else {
1795129794Stackerman		mp->m_len = mp->m_pkthdr.len = MCLBYTES;
1796129794Stackerman		mp->m_data = mp->m_ext.ext_buf;
1797129794Stackerman		mp->m_next = NULL;
1798129794Stackerman	}
1799129794Stackerman
1800129794Stackerman	if (ifp->if_mtu <= ETHERMTU) {
1801129794Stackerman		m_adj(mp, ETHER_ALIGN);
1802129794Stackerman	}
1803129794Stackerman	rx_buffer = &adapter->rx_buffer_area[i];
1804129794Stackerman
1805129794Stackerman	/*
1806129794Stackerman	 * Using memory from the mbuf cluster pool, invoke the bus_dma
1807129794Stackerman	 * machinery to arrange the memory mapping.
1808129794Stackerman	 */
1809129794Stackerman	error = bus_dmamap_load(adapter->rxtag, rx_buffer->map,
1810129794Stackerman				mtod(mp, void *), mp->m_len,
1811129794Stackerman				ixgb_dmamap_cb, &paddr, 0);
1812129794Stackerman	if (error) {
1813129794Stackerman		m_free(mp);
1814129794Stackerman		return (error);
1815129794Stackerman	}
1816129794Stackerman	rx_buffer->m_head = mp;
1817129794Stackerman	adapter->rx_desc_base[i].buff_addr = htole64(paddr);
1818129794Stackerman	bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD);
1819129794Stackerman
1820129794Stackerman	return (0);
1821129794Stackerman}
1822129794Stackerman
1823129794Stackerman/*********************************************************************
1824129794Stackerman *
1825129794Stackerman *  Allocate memory for rx_buffer structures. Since we use one
1826129794Stackerman *  rx_buffer per received packet, the maximum number of rx_buffer's
1827129794Stackerman *  that we'll need is equal to the number of receive descriptors
1828129794Stackerman *  that we've allocated.
1829129794Stackerman *
1830129794Stackerman **********************************************************************/
1831129794Stackermanstatic int
1832129794Stackermanixgb_allocate_receive_structures(struct adapter * adapter)
1833129794Stackerman{
1834129794Stackerman	int             i, error;
1835129794Stackerman	struct ixgb_buffer *rx_buffer;
1836129794Stackerman
1837129794Stackerman	if (!(adapter->rx_buffer_area =
1838129794Stackerman	      (struct ixgb_buffer *) malloc(sizeof(struct ixgb_buffer) *
1839129794Stackerman					    adapter->num_rx_desc, M_DEVBUF,
1840129794Stackerman					    M_NOWAIT | M_ZERO))) {
1841198987Sjhb		device_printf(adapter->dev,
1842198987Sjhb		    "Unable to allocate rx_buffer memory\n");
1843129794Stackerman		return (ENOMEM);
1844129794Stackerman	}
1845129794Stackerman	bzero(adapter->rx_buffer_area,
1846129794Stackerman	      sizeof(struct ixgb_buffer) * adapter->num_rx_desc);
1847129794Stackerman
1848232874Sscottl	error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev),/* parent */
1849129794Stackerman				   PAGE_SIZE, 0,	/* alignment, bounds */
1850129794Stackerman				   BUS_SPACE_MAXADDR,	/* lowaddr */
1851129794Stackerman				   BUS_SPACE_MAXADDR,	/* highaddr */
1852129794Stackerman				   NULL, NULL,	/* filter, filterarg */
1853129794Stackerman				   MCLBYTES,	/* maxsize */
1854129794Stackerman				   1,	/* nsegments */
1855129794Stackerman				   MCLBYTES,	/* maxsegsize */
1856129794Stackerman				   BUS_DMA_ALLOCNOW,	/* flags */
1857129794Stackerman#if __FreeBSD_version >= 502000
1858129794Stackerman				   NULL,	/* lockfunc */
1859129794Stackerman				   NULL,	/* lockfuncarg */
1860129794Stackerman#endif
1861129794Stackerman				   &adapter->rxtag);
1862129794Stackerman	if (error != 0) {
1863198987Sjhb		device_printf(adapter->dev, "ixgb_allocate_receive_structures: "
1864129794Stackerman		       "bus_dma_tag_create failed; error %u\n",
1865198987Sjhb		       error);
1866129794Stackerman		goto fail_0;
1867129794Stackerman	}
1868129794Stackerman	rx_buffer = adapter->rx_buffer_area;
1869129794Stackerman	for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
1870129794Stackerman		error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
1871129794Stackerman					  &rx_buffer->map);
1872129794Stackerman		if (error != 0) {
1873198987Sjhb			device_printf(adapter->dev,
1874198987Sjhb			       "ixgb_allocate_receive_structures: "
1875129794Stackerman			       "bus_dmamap_create failed; error %u\n",
1876198987Sjhb			       error);
1877129794Stackerman			goto fail_1;
1878129794Stackerman		}
1879129794Stackerman	}
1880129794Stackerman
1881129794Stackerman	for (i = 0; i < adapter->num_rx_desc; i++) {
1882129794Stackerman		if (ixgb_get_buf(i, adapter, NULL) == ENOBUFS) {
1883129794Stackerman			adapter->rx_buffer_area[i].m_head = NULL;
1884129794Stackerman			adapter->rx_desc_base[i].buff_addr = 0;
1885129794Stackerman			return (ENOBUFS);
1886129794Stackerman		}
1887129794Stackerman	}
1888129794Stackerman
1889129794Stackerman	return (0);
1890129794Stackermanfail_1:
1891129794Stackerman	bus_dma_tag_destroy(adapter->rxtag);
1892129794Stackermanfail_0:
1893129794Stackerman	adapter->rxtag = NULL;
1894129794Stackerman	free(adapter->rx_buffer_area, M_DEVBUF);
1895129794Stackerman	adapter->rx_buffer_area = NULL;
1896129794Stackerman	return (error);
1897129794Stackerman}
1898129794Stackerman
1899129794Stackerman/*********************************************************************
1900129794Stackerman *
1901129794Stackerman *  Allocate and initialize receive structures.
1902129794Stackerman *
1903129794Stackerman **********************************************************************/
1904129794Stackermanstatic int
1905129794Stackermanixgb_setup_receive_structures(struct adapter * adapter)
1906129794Stackerman{
1907129794Stackerman	bzero((void *)adapter->rx_desc_base,
1908129794Stackerman	      (sizeof(struct ixgb_rx_desc)) * adapter->num_rx_desc);
1909129794Stackerman
1910129794Stackerman	if (ixgb_allocate_receive_structures(adapter))
1911129794Stackerman		return ENOMEM;
1912129794Stackerman
1913129794Stackerman	/* Setup our descriptor pointers */
1914129794Stackerman	adapter->next_rx_desc_to_check = 0;
1915129794Stackerman	adapter->next_rx_desc_to_use = 0;
1916129794Stackerman	return (0);
1917129794Stackerman}
1918129794Stackerman
1919129794Stackerman/*********************************************************************
1920129794Stackerman *
1921129794Stackerman *  Enable receive unit.
1922129794Stackerman *
1923129794Stackerman **********************************************************************/
1924129794Stackermanstatic void
1925129794Stackermanixgb_initialize_receive_unit(struct adapter * adapter)
1926129794Stackerman{
1927129794Stackerman	u_int32_t       reg_rctl;
1928129794Stackerman	u_int32_t       reg_rxcsum;
1929129794Stackerman	u_int32_t       reg_rxdctl;
1930129794Stackerman	struct ifnet   *ifp;
1931144183Smux	u_int64_t       rdba = adapter->rxdma.dma_paddr;
1932129794Stackerman
1933147256Sbrooks	ifp = adapter->ifp;
1934129794Stackerman
1935129794Stackerman	/*
1936129794Stackerman	 * Make sure receives are disabled while setting up the descriptor
1937129794Stackerman	 * ring
1938129794Stackerman	 */
1939129794Stackerman	reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL);
1940129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl & ~IXGB_RCTL_RXEN);
1941129794Stackerman
1942129794Stackerman	/* Set the Receive Delay Timer Register */
1943129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDTR,
1944129794Stackerman		       adapter->rx_int_delay);
1945129794Stackerman
1946129794Stackerman
1947129794Stackerman	/* Setup the Base and Length of the Rx Descriptor Ring */
1948129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDBAL,
1949129794Stackerman		       (rdba & 0x00000000ffffffffULL));
1950129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDBAH, (rdba >> 32));
1951129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDLEN, adapter->num_rx_desc *
1952129794Stackerman		       sizeof(struct ixgb_rx_desc));
1953129794Stackerman
1954129794Stackerman	/* Setup the HW Rx Head and Tail Descriptor Pointers */
1955129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDH, 0);
1956129794Stackerman
1957129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDT, adapter->num_rx_desc - 1);
1958129794Stackerman
1959129794Stackerman
1960129794Stackerman
1961129794Stackerman	reg_rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT
1962129794Stackerman		| RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT
1963129794Stackerman		| RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
1964129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RXDCTL, reg_rxdctl);
1965129794Stackerman
1966129794Stackerman
1967129794Stackerman	adapter->raidc = 1;
1968129794Stackerman	if (adapter->raidc) {
1969129794Stackerman		uint32_t        raidc;
1970129794Stackerman		uint8_t         poll_threshold;
1971129794Stackerman#define IXGB_RAIDC_POLL_DEFAULT 120
1972129794Stackerman
1973129794Stackerman		poll_threshold = ((adapter->num_rx_desc - 1) >> 3);
1974129794Stackerman		poll_threshold >>= 1;
1975129794Stackerman		poll_threshold &= 0x3F;
1976129794Stackerman		raidc = IXGB_RAIDC_EN | IXGB_RAIDC_RXT_GATE |
1977129794Stackerman			(IXGB_RAIDC_POLL_DEFAULT << IXGB_RAIDC_POLL_SHIFT) |
1978129794Stackerman			(adapter->rx_int_delay << IXGB_RAIDC_DELAY_SHIFT) |
1979129794Stackerman			poll_threshold;
1980129794Stackerman		IXGB_WRITE_REG(&adapter->hw, RAIDC, raidc);
1981129794Stackerman	}
1982129794Stackerman	/* Enable Receive Checksum Offload for TCP and UDP ? */
1983129794Stackerman	if (ifp->if_capenable & IFCAP_RXCSUM) {
1984129794Stackerman		reg_rxcsum = IXGB_READ_REG(&adapter->hw, RXCSUM);
1985129794Stackerman		reg_rxcsum |= IXGB_RXCSUM_TUOFL;
1986129794Stackerman		IXGB_WRITE_REG(&adapter->hw, RXCSUM, reg_rxcsum);
1987129794Stackerman	}
1988129794Stackerman	/* Setup the Receive Control Register */
1989129794Stackerman	reg_rctl = IXGB_READ_REG(&adapter->hw, RCTL);
1990129794Stackerman	reg_rctl &= ~(3 << IXGB_RCTL_MO_SHIFT);
1991129794Stackerman	reg_rctl |= IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 | IXGB_RCTL_SECRC |
1992129794Stackerman		IXGB_RCTL_CFF |
1993129794Stackerman		(adapter->hw.mc_filter_type << IXGB_RCTL_MO_SHIFT);
1994129794Stackerman
1995129794Stackerman	switch (adapter->rx_buffer_len) {
1996129794Stackerman	default:
1997129794Stackerman	case IXGB_RXBUFFER_2048:
1998129794Stackerman		reg_rctl |= IXGB_RCTL_BSIZE_2048;
1999129794Stackerman		break;
2000129794Stackerman	case IXGB_RXBUFFER_4096:
2001129794Stackerman		reg_rctl |= IXGB_RCTL_BSIZE_4096;
2002129794Stackerman		break;
2003129794Stackerman	case IXGB_RXBUFFER_8192:
2004129794Stackerman		reg_rctl |= IXGB_RCTL_BSIZE_8192;
2005129794Stackerman		break;
2006129794Stackerman	case IXGB_RXBUFFER_16384:
2007129794Stackerman		reg_rctl |= IXGB_RCTL_BSIZE_16384;
2008129794Stackerman		break;
2009129794Stackerman	}
2010129794Stackerman
2011129794Stackerman	reg_rctl |= IXGB_RCTL_RXEN;
2012129794Stackerman
2013129794Stackerman
2014129794Stackerman	/* Enable Receives */
2015129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
2016129794Stackerman
2017129794Stackerman	return;
2018129794Stackerman}
2019129794Stackerman
2020129794Stackerman/*********************************************************************
2021129794Stackerman *
2022129794Stackerman *  Free receive related data structures.
2023129794Stackerman *
2024129794Stackerman **********************************************************************/
2025129794Stackermanstatic void
2026129794Stackermanixgb_free_receive_structures(struct adapter * adapter)
2027129794Stackerman{
2028129794Stackerman	struct ixgb_buffer *rx_buffer;
2029129794Stackerman	int             i;
2030129794Stackerman
2031129794Stackerman	INIT_DEBUGOUT("free_receive_structures: begin");
2032129794Stackerman
2033129794Stackerman	if (adapter->rx_buffer_area != NULL) {
2034129794Stackerman		rx_buffer = adapter->rx_buffer_area;
2035129794Stackerman		for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
2036129794Stackerman			if (rx_buffer->map != NULL) {
2037129794Stackerman				bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
2038129794Stackerman				bus_dmamap_destroy(adapter->rxtag, rx_buffer->map);
2039129794Stackerman			}
2040129794Stackerman			if (rx_buffer->m_head != NULL)
2041129794Stackerman				m_freem(rx_buffer->m_head);
2042129794Stackerman			rx_buffer->m_head = NULL;
2043129794Stackerman		}
2044129794Stackerman	}
2045129794Stackerman	if (adapter->rx_buffer_area != NULL) {
2046129794Stackerman		free(adapter->rx_buffer_area, M_DEVBUF);
2047129794Stackerman		adapter->rx_buffer_area = NULL;
2048129794Stackerman	}
2049129794Stackerman	if (adapter->rxtag != NULL) {
2050129794Stackerman		bus_dma_tag_destroy(adapter->rxtag);
2051129794Stackerman		adapter->rxtag = NULL;
2052129794Stackerman	}
2053129794Stackerman	return;
2054129794Stackerman}
2055129794Stackerman
2056129794Stackerman/*********************************************************************
2057129794Stackerman *
2058129794Stackerman *  This routine executes in interrupt context. It replenishes
2059129794Stackerman *  the mbufs in the descriptor and sends data which has been
2060129794Stackerman *  dma'ed into host memory to upper layer.
2061129794Stackerman *
2062129794Stackerman *  We loop at most count times if count is > 0, or until done if
2063129794Stackerman *  count < 0.
2064129794Stackerman *
2065129794Stackerman *********************************************************************/
2066193096Sattiliostatic int
2067129794Stackermanixgb_process_receive_interrupts(struct adapter * adapter, int count)
2068129794Stackerman{
2069129794Stackerman	struct ifnet   *ifp;
2070129794Stackerman	struct mbuf    *mp;
2071129794Stackerman#if __FreeBSD_version < 500000
2072129794Stackerman	struct ether_header *eh;
2073129794Stackerman#endif
2074129794Stackerman	int             eop = 0;
2075129794Stackerman	int             len;
2076129794Stackerman	u_int8_t        accept_frame = 0;
2077129794Stackerman	int             i;
2078129794Stackerman	int             next_to_use = 0;
2079129794Stackerman	int             eop_desc;
2080193096Sattilio	int		rx_npkts = 0;
2081129794Stackerman	/* Pointer to the receive descriptor being examined. */
2082129794Stackerman	struct ixgb_rx_desc *current_desc;
2083129794Stackerman
2084144651Salc	IXGB_LOCK_ASSERT(adapter);
2085144651Salc
2086147256Sbrooks	ifp = adapter->ifp;
2087129794Stackerman	i = adapter->next_rx_desc_to_check;
2088129794Stackerman	next_to_use = adapter->next_rx_desc_to_use;
2089129794Stackerman	eop_desc = adapter->next_rx_desc_to_check;
2090129794Stackerman	current_desc = &adapter->rx_desc_base[i];
2091129794Stackerman
2092129794Stackerman	if (!((current_desc->status) & IXGB_RX_DESC_STATUS_DD)) {
2093129794Stackerman#ifdef _SV_
2094129794Stackerman		adapter->no_pkts_avail++;
2095129794Stackerman#endif
2096193096Sattilio		return (rx_npkts);
2097129794Stackerman	}
2098129794Stackerman	while ((current_desc->status & IXGB_RX_DESC_STATUS_DD) && (count != 0)) {
2099129794Stackerman
2100129794Stackerman		mp = adapter->rx_buffer_area[i].m_head;
2101129794Stackerman		bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map,
2102129794Stackerman				BUS_DMASYNC_POSTREAD);
2103129794Stackerman		accept_frame = 1;
2104129794Stackerman		if (current_desc->status & IXGB_RX_DESC_STATUS_EOP) {
2105129794Stackerman			count--;
2106129794Stackerman			eop = 1;
2107129794Stackerman		} else {
2108129794Stackerman			eop = 0;
2109129794Stackerman		}
2110129794Stackerman		len = current_desc->length;
2111129794Stackerman
2112129794Stackerman		if (current_desc->errors & (IXGB_RX_DESC_ERRORS_CE |
2113129794Stackerman			    IXGB_RX_DESC_ERRORS_SE | IXGB_RX_DESC_ERRORS_P |
2114129794Stackerman					    IXGB_RX_DESC_ERRORS_RXE)) {
2115129794Stackerman			accept_frame = 0;
2116129794Stackerman		}
2117129794Stackerman		if (accept_frame) {
2118129794Stackerman
2119129794Stackerman			/* Assign correct length to the current fragment */
2120129794Stackerman			mp->m_len = len;
2121129794Stackerman
2122129794Stackerman			if (adapter->fmp == NULL) {
2123129794Stackerman				mp->m_pkthdr.len = len;
2124129794Stackerman				adapter->fmp = mp;	/* Store the first mbuf */
2125129794Stackerman				adapter->lmp = mp;
2126129794Stackerman			} else {
2127129794Stackerman				/* Chain mbuf's together */
2128129794Stackerman				mp->m_flags &= ~M_PKTHDR;
2129129794Stackerman				adapter->lmp->m_next = mp;
2130129794Stackerman				adapter->lmp = adapter->lmp->m_next;
2131129794Stackerman				adapter->fmp->m_pkthdr.len += len;
2132129794Stackerman			}
2133129794Stackerman
2134129794Stackerman			if (eop) {
2135129794Stackerman				eop_desc = i;
2136129794Stackerman				adapter->fmp->m_pkthdr.rcvif = ifp;
2137129794Stackerman
2138129794Stackerman#if __FreeBSD_version < 500000
2139129794Stackerman				eh = mtod(adapter->fmp, struct ether_header *);
2140129794Stackerman
2141129794Stackerman				/* Remove ethernet header from mbuf */
2142129794Stackerman				m_adj(adapter->fmp, sizeof(struct ether_header));
2143129794Stackerman				ixgb_receive_checksum(adapter, current_desc,
2144129794Stackerman						      adapter->fmp);
2145129794Stackerman
2146129794Stackerman				if (current_desc->status & IXGB_RX_DESC_STATUS_VP)
2147129794Stackerman					VLAN_INPUT_TAG(eh, adapter->fmp,
2148129794Stackerman						     current_desc->special);
2149129794Stackerman				else
2150129794Stackerman					ether_input(ifp, eh, adapter->fmp);
2151129794Stackerman#else
2152129794Stackerman				ixgb_receive_checksum(adapter, current_desc,
2153129794Stackerman						      adapter->fmp);
2154162375Sandre#if __FreeBSD_version < 700000
2155129794Stackerman				if (current_desc->status & IXGB_RX_DESC_STATUS_VP)
2156129794Stackerman					VLAN_INPUT_TAG(ifp, adapter->fmp,
2157153512Sglebius						       current_desc->special);
2158162375Sandre#else
2159162375Sandre				if (current_desc->status & IXGB_RX_DESC_STATUS_VP) {
2160162375Sandre					adapter->fmp->m_pkthdr.ether_vtag =
2161162375Sandre					    current_desc->special;
2162162375Sandre					adapter->fmp->m_flags |= M_VLANTAG;
2163162375Sandre				}
2164162375Sandre#endif
2165129794Stackerman
2166144651Salc				if (adapter->fmp != NULL) {
2167144651Salc					IXGB_UNLOCK(adapter);
2168129794Stackerman					(*ifp->if_input) (ifp, adapter->fmp);
2169144651Salc					IXGB_LOCK(adapter);
2170193096Sattilio					rx_npkts++;
2171144651Salc				}
2172129794Stackerman#endif
2173129794Stackerman				adapter->fmp = NULL;
2174129794Stackerman				adapter->lmp = NULL;
2175129794Stackerman			}
2176129794Stackerman			adapter->rx_buffer_area[i].m_head = NULL;
2177129794Stackerman		} else {
2178129794Stackerman			adapter->dropped_pkts++;
2179129794Stackerman			if (adapter->fmp != NULL)
2180129794Stackerman				m_freem(adapter->fmp);
2181129794Stackerman			adapter->fmp = NULL;
2182129794Stackerman			adapter->lmp = NULL;
2183129794Stackerman		}
2184129794Stackerman
2185129794Stackerman		/* Zero out the receive descriptors status  */
2186129794Stackerman		current_desc->status = 0;
2187129794Stackerman
2188129794Stackerman		/* Advance our pointers to the next descriptor */
2189129794Stackerman		if (++i == adapter->num_rx_desc) {
2190129794Stackerman			i = 0;
2191129794Stackerman			current_desc = adapter->rx_desc_base;
2192129794Stackerman		} else
2193129794Stackerman			current_desc++;
2194129794Stackerman	}
2195129794Stackerman	adapter->next_rx_desc_to_check = i;
2196129794Stackerman
2197129794Stackerman	if (--i < 0)
2198129794Stackerman		i = (adapter->num_rx_desc - 1);
2199129794Stackerman
2200129794Stackerman	/*
2201129794Stackerman	 * 82597EX: Workaround for redundent write back in receive descriptor ring (causes
2202129794Stackerman 	 * memory corruption). Avoid using and re-submitting the most recently received RX
2203129794Stackerman	 * descriptor back to hardware.
2204129794Stackerman	 *
2205129794Stackerman	 * if(Last written back descriptor == EOP bit set descriptor)
2206129794Stackerman	 * 	then avoid re-submitting the most recently received RX descriptor
2207129794Stackerman	 *	back to hardware.
2208129794Stackerman	 * if(Last written back descriptor != EOP bit set descriptor)
2209129794Stackerman	 *	then avoid re-submitting the most recently received RX descriptors
2210129794Stackerman	 * 	till last EOP bit set descriptor.
2211129794Stackerman	 */
2212129794Stackerman	if (eop_desc != i) {
2213129794Stackerman		if (++eop_desc == adapter->num_rx_desc)
2214129794Stackerman			eop_desc = 0;
2215129794Stackerman		i = eop_desc;
2216129794Stackerman	}
2217129794Stackerman	/* Replenish the descriptors with new mbufs till last EOP bit set descriptor */
2218129794Stackerman	while (next_to_use != i) {
2219129794Stackerman		current_desc = &adapter->rx_desc_base[next_to_use];
2220129794Stackerman		if ((current_desc->errors & (IXGB_RX_DESC_ERRORS_CE |
2221129794Stackerman			    IXGB_RX_DESC_ERRORS_SE | IXGB_RX_DESC_ERRORS_P |
2222129794Stackerman					     IXGB_RX_DESC_ERRORS_RXE))) {
2223129794Stackerman			mp = adapter->rx_buffer_area[next_to_use].m_head;
2224129794Stackerman			ixgb_get_buf(next_to_use, adapter, mp);
2225129794Stackerman		} else {
2226129794Stackerman			if (ixgb_get_buf(next_to_use, adapter, NULL) == ENOBUFS)
2227129794Stackerman				break;
2228129794Stackerman		}
2229129794Stackerman		/* Advance our pointers to the next descriptor */
2230129794Stackerman		if (++next_to_use == adapter->num_rx_desc) {
2231129794Stackerman			next_to_use = 0;
2232129794Stackerman			current_desc = adapter->rx_desc_base;
2233129794Stackerman		} else
2234129794Stackerman			current_desc++;
2235129794Stackerman	}
2236129794Stackerman	adapter->next_rx_desc_to_use = next_to_use;
2237129794Stackerman	if (--next_to_use < 0)
2238129794Stackerman		next_to_use = (adapter->num_rx_desc - 1);
2239129794Stackerman	/* Advance the IXGB's Receive Queue #0  "Tail Pointer" */
2240129794Stackerman	IXGB_WRITE_REG(&adapter->hw, RDT, next_to_use);
2241129794Stackerman
2242193096Sattilio	return (rx_npkts);
2243129794Stackerman}
2244129794Stackerman
2245129794Stackerman/*********************************************************************
2246129794Stackerman *
2247129794Stackerman *  Verify that the hardware indicated that the checksum is valid.
2248129794Stackerman *  Inform the stack about the status of checksum so that stack
2249129794Stackerman *  doesn't spend time verifying the checksum.
2250129794Stackerman *
2251129794Stackerman *********************************************************************/
2252129794Stackermanstatic void
2253129794Stackermanixgb_receive_checksum(struct adapter * adapter,
2254129794Stackerman		      struct ixgb_rx_desc * rx_desc,
2255129794Stackerman		      struct mbuf * mp)
2256129794Stackerman{
2257129794Stackerman	if (rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) {
2258129794Stackerman		mp->m_pkthdr.csum_flags = 0;
2259129794Stackerman		return;
2260129794Stackerman	}
2261129794Stackerman	if (rx_desc->status & IXGB_RX_DESC_STATUS_IPCS) {
2262129794Stackerman		/* Did it pass? */
2263129794Stackerman		if (!(rx_desc->errors & IXGB_RX_DESC_ERRORS_IPE)) {
2264129794Stackerman			/* IP Checksum Good */
2265129794Stackerman			mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
2266129794Stackerman			mp->m_pkthdr.csum_flags |= CSUM_IP_VALID;
2267129794Stackerman
2268129794Stackerman		} else {
2269129794Stackerman			mp->m_pkthdr.csum_flags = 0;
2270129794Stackerman		}
2271129794Stackerman	}
2272129794Stackerman	if (rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS) {
2273129794Stackerman		/* Did it pass? */
2274129794Stackerman		if (!(rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE)) {
2275129794Stackerman			mp->m_pkthdr.csum_flags |=
2276129794Stackerman				(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
2277129794Stackerman			mp->m_pkthdr.csum_data = htons(0xffff);
2278129794Stackerman		}
2279129794Stackerman	}
2280129794Stackerman	return;
2281129794Stackerman}
2282129794Stackerman
2283129794Stackerman
2284129794Stackermanstatic void
2285129794Stackermanixgb_enable_vlans(struct adapter * adapter)
2286129794Stackerman{
2287129794Stackerman	uint32_t        ctrl;
2288129794Stackerman
2289129794Stackerman	ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
2290129794Stackerman	ctrl |= IXGB_CTRL0_VME;
2291129794Stackerman	IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
2292129794Stackerman
2293129794Stackerman	return;
2294129794Stackerman}
2295129794Stackerman
2296129794Stackerman
2297129794Stackermanstatic void
2298129794Stackermanixgb_enable_intr(struct adapter * adapter)
2299129794Stackerman{
2300129794Stackerman	IXGB_WRITE_REG(&adapter->hw, IMS, (IXGB_INT_RXT0 | IXGB_INT_TXDW |
2301129794Stackerman			    IXGB_INT_RXDMT0 | IXGB_INT_LSC | IXGB_INT_RXO));
2302129794Stackerman	return;
2303129794Stackerman}
2304129794Stackerman
2305129794Stackermanstatic void
2306129794Stackermanixgb_disable_intr(struct adapter * adapter)
2307129794Stackerman{
2308129794Stackerman	IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
2309129794Stackerman	return;
2310129794Stackerman}
2311129794Stackerman
2312129794Stackermanvoid
2313129794Stackermanixgb_write_pci_cfg(struct ixgb_hw * hw,
2314129794Stackerman		   uint32_t reg,
2315129794Stackerman		   uint16_t * value)
2316129794Stackerman{
2317129794Stackerman	pci_write_config(((struct ixgb_osdep *) hw->back)->dev, reg,
2318129794Stackerman			 *value, 2);
2319129794Stackerman}
2320129794Stackerman
2321129794Stackerman/**********************************************************************
2322129794Stackerman *
2323129794Stackerman *  Update the board statistics counters.
2324129794Stackerman *
2325129794Stackerman **********************************************************************/
2326129794Stackermanstatic void
2327129794Stackermanixgb_update_stats_counters(struct adapter * adapter)
2328129794Stackerman{
2329129794Stackerman	struct ifnet   *ifp;
2330129794Stackerman
2331129794Stackerman	adapter->stats.crcerrs += IXGB_READ_REG(&adapter->hw, CRCERRS);
2332129794Stackerman	adapter->stats.gprcl += IXGB_READ_REG(&adapter->hw, GPRCL);
2333129794Stackerman	adapter->stats.gprch += IXGB_READ_REG(&adapter->hw, GPRCH);
2334129794Stackerman	adapter->stats.gorcl += IXGB_READ_REG(&adapter->hw, GORCL);
2335129794Stackerman	adapter->stats.gorch += IXGB_READ_REG(&adapter->hw, GORCH);
2336129794Stackerman	adapter->stats.bprcl += IXGB_READ_REG(&adapter->hw, BPRCL);
2337129794Stackerman	adapter->stats.bprch += IXGB_READ_REG(&adapter->hw, BPRCH);
2338129794Stackerman	adapter->stats.mprcl += IXGB_READ_REG(&adapter->hw, MPRCL);
2339129794Stackerman	adapter->stats.mprch += IXGB_READ_REG(&adapter->hw, MPRCH);
2340129794Stackerman	adapter->stats.roc += IXGB_READ_REG(&adapter->hw, ROC);
2341129794Stackerman
2342129794Stackerman	adapter->stats.mpc += IXGB_READ_REG(&adapter->hw, MPC);
2343129794Stackerman	adapter->stats.dc += IXGB_READ_REG(&adapter->hw, DC);
2344129794Stackerman	adapter->stats.rlec += IXGB_READ_REG(&adapter->hw, RLEC);
2345129794Stackerman	adapter->stats.xonrxc += IXGB_READ_REG(&adapter->hw, XONRXC);
2346129794Stackerman	adapter->stats.xontxc += IXGB_READ_REG(&adapter->hw, XONTXC);
2347129794Stackerman	adapter->stats.xoffrxc += IXGB_READ_REG(&adapter->hw, XOFFRXC);
2348129794Stackerman	adapter->stats.xofftxc += IXGB_READ_REG(&adapter->hw, XOFFTXC);
2349129794Stackerman	adapter->stats.gptcl += IXGB_READ_REG(&adapter->hw, GPTCL);
2350129794Stackerman	adapter->stats.gptch += IXGB_READ_REG(&adapter->hw, GPTCH);
2351129794Stackerman	adapter->stats.gotcl += IXGB_READ_REG(&adapter->hw, GOTCL);
2352129794Stackerman	adapter->stats.gotch += IXGB_READ_REG(&adapter->hw, GOTCH);
2353129794Stackerman	adapter->stats.ruc += IXGB_READ_REG(&adapter->hw, RUC);
2354129794Stackerman	adapter->stats.rfc += IXGB_READ_REG(&adapter->hw, RFC);
2355129794Stackerman	adapter->stats.rjc += IXGB_READ_REG(&adapter->hw, RJC);
2356129794Stackerman	adapter->stats.torl += IXGB_READ_REG(&adapter->hw, TORL);
2357129794Stackerman	adapter->stats.torh += IXGB_READ_REG(&adapter->hw, TORH);
2358129794Stackerman	adapter->stats.totl += IXGB_READ_REG(&adapter->hw, TOTL);
2359129794Stackerman	adapter->stats.toth += IXGB_READ_REG(&adapter->hw, TOTH);
2360129794Stackerman	adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL);
2361129794Stackerman	adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH);
2362129794Stackerman	adapter->stats.tptl += IXGB_READ_REG(&adapter->hw, TPTL);
2363129794Stackerman	adapter->stats.tpth += IXGB_READ_REG(&adapter->hw, TPTH);
2364129794Stackerman	adapter->stats.plt64c += IXGB_READ_REG(&adapter->hw, PLT64C);
2365129794Stackerman	adapter->stats.mptcl += IXGB_READ_REG(&adapter->hw, MPTCL);
2366129794Stackerman	adapter->stats.mptch += IXGB_READ_REG(&adapter->hw, MPTCH);
2367129794Stackerman	adapter->stats.bptcl += IXGB_READ_REG(&adapter->hw, BPTCL);
2368129794Stackerman	adapter->stats.bptch += IXGB_READ_REG(&adapter->hw, BPTCH);
2369129794Stackerman
2370129794Stackerman	adapter->stats.uprcl += IXGB_READ_REG(&adapter->hw, UPRCL);
2371129794Stackerman	adapter->stats.uprch += IXGB_READ_REG(&adapter->hw, UPRCH);
2372129794Stackerman	adapter->stats.vprcl += IXGB_READ_REG(&adapter->hw, VPRCL);
2373129794Stackerman	adapter->stats.vprch += IXGB_READ_REG(&adapter->hw, VPRCH);
2374129794Stackerman	adapter->stats.jprcl += IXGB_READ_REG(&adapter->hw, JPRCL);
2375129794Stackerman	adapter->stats.jprch += IXGB_READ_REG(&adapter->hw, JPRCH);
2376129794Stackerman	adapter->stats.rnbc += IXGB_READ_REG(&adapter->hw, RNBC);
2377129794Stackerman	adapter->stats.icbc += IXGB_READ_REG(&adapter->hw, ICBC);
2378129794Stackerman	adapter->stats.ecbc += IXGB_READ_REG(&adapter->hw, ECBC);
2379129794Stackerman	adapter->stats.uptcl += IXGB_READ_REG(&adapter->hw, UPTCL);
2380129794Stackerman	adapter->stats.uptch += IXGB_READ_REG(&adapter->hw, UPTCH);
2381129794Stackerman	adapter->stats.vptcl += IXGB_READ_REG(&adapter->hw, VPTCL);
2382129794Stackerman	adapter->stats.vptch += IXGB_READ_REG(&adapter->hw, VPTCH);
2383129794Stackerman	adapter->stats.jptcl += IXGB_READ_REG(&adapter->hw, JPTCL);
2384129794Stackerman	adapter->stats.jptch += IXGB_READ_REG(&adapter->hw, JPTCH);
2385129794Stackerman	adapter->stats.tsctc += IXGB_READ_REG(&adapter->hw, TSCTC);
2386129794Stackerman	adapter->stats.tsctfc += IXGB_READ_REG(&adapter->hw, TSCTFC);
2387129794Stackerman	adapter->stats.ibic += IXGB_READ_REG(&adapter->hw, IBIC);
2388129794Stackerman	adapter->stats.lfc += IXGB_READ_REG(&adapter->hw, LFC);
2389129794Stackerman	adapter->stats.pfrc += IXGB_READ_REG(&adapter->hw, PFRC);
2390129794Stackerman	adapter->stats.pftc += IXGB_READ_REG(&adapter->hw, PFTC);
2391129794Stackerman	adapter->stats.mcfrc += IXGB_READ_REG(&adapter->hw, MCFRC);
2392129794Stackerman
2393147256Sbrooks	ifp = adapter->ifp;
2394129794Stackerman
2395129794Stackerman	/* Fill out the OS statistics structure */
2396129794Stackerman	ifp->if_ipackets = adapter->stats.gprcl;
2397129794Stackerman	ifp->if_opackets = adapter->stats.gptcl;
2398129794Stackerman	ifp->if_ibytes = adapter->stats.gorcl;
2399129794Stackerman	ifp->if_obytes = adapter->stats.gotcl;
2400129794Stackerman	ifp->if_imcasts = adapter->stats.mprcl;
2401129794Stackerman	ifp->if_collisions = 0;
2402129794Stackerman
2403129794Stackerman	/* Rx Errors */
2404129794Stackerman	ifp->if_ierrors =
2405129794Stackerman		adapter->dropped_pkts +
2406129794Stackerman		adapter->stats.crcerrs +
2407129794Stackerman		adapter->stats.rnbc +
2408129794Stackerman		adapter->stats.mpc +
2409129794Stackerman		adapter->stats.rlec;
2410129794Stackerman
2411129794Stackerman
2412129794Stackerman}
2413129794Stackerman
2414129794Stackerman
2415129794Stackerman/**********************************************************************
2416129794Stackerman *
2417129794Stackerman *  This routine is called only when ixgb_display_debug_stats is enabled.
2418129794Stackerman *  This routine provides a way to take a look at important statistics
2419129794Stackerman *  maintained by the driver and hardware.
2420129794Stackerman *
2421129794Stackerman **********************************************************************/
2422129794Stackermanstatic void
2423129794Stackermanixgb_print_hw_stats(struct adapter * adapter)
2424129794Stackerman{
2425129794Stackerman	char            buf_speed[100], buf_type[100];
2426129794Stackerman	ixgb_bus_speed  bus_speed;
2427129794Stackerman	ixgb_bus_type   bus_type;
2428198987Sjhb	device_t dev;
2429129794Stackerman
2430198987Sjhb	dev = adapter->dev;
2431129794Stackerman#ifdef _SV_
2432198987Sjhb	device_printf(dev, "Packets not Avail = %ld\n",
2433129794Stackerman	       adapter->no_pkts_avail);
2434198987Sjhb	device_printf(dev, "CleanTxInterrupts = %ld\n",
2435129794Stackerman	       adapter->clean_tx_interrupts);
2436198987Sjhb	device_printf(dev, "ICR RXDMT0 = %lld\n",
2437129794Stackerman	       (long long)adapter->sv_stats.icr_rxdmt0);
2438198987Sjhb	device_printf(dev, "ICR RXO = %lld\n",
2439129794Stackerman	       (long long)adapter->sv_stats.icr_rxo);
2440198987Sjhb	device_printf(dev, "ICR RXT0 = %lld\n",
2441129794Stackerman	       (long long)adapter->sv_stats.icr_rxt0);
2442198987Sjhb	device_printf(dev, "ICR TXDW = %lld\n",
2443129794Stackerman	       (long long)adapter->sv_stats.icr_TXDW);
2444129794Stackerman#endif				/* _SV_ */
2445129794Stackerman
2446129794Stackerman	bus_speed = adapter->hw.bus.speed;
2447129794Stackerman	bus_type = adapter->hw.bus.type;
2448129794Stackerman	sprintf(buf_speed,
2449129794Stackerman		bus_speed == ixgb_bus_speed_33 ? "33MHz" :
2450129794Stackerman		bus_speed == ixgb_bus_speed_66 ? "66MHz" :
2451129794Stackerman		bus_speed == ixgb_bus_speed_100 ? "100MHz" :
2452129794Stackerman		bus_speed == ixgb_bus_speed_133 ? "133MHz" :
2453129794Stackerman		"UNKNOWN");
2454198987Sjhb	device_printf(dev, "PCI_Bus_Speed = %s\n",
2455129794Stackerman	       buf_speed);
2456129794Stackerman
2457129794Stackerman	sprintf(buf_type,
2458129794Stackerman		bus_type == ixgb_bus_type_pci ? "PCI" :
2459129794Stackerman		bus_type == ixgb_bus_type_pcix ? "PCI-X" :
2460129794Stackerman		"UNKNOWN");
2461198987Sjhb	device_printf(dev, "PCI_Bus_Type = %s\n",
2462129794Stackerman	       buf_type);
2463129794Stackerman
2464198987Sjhb	device_printf(dev, "Tx Descriptors not Avail1 = %ld\n",
2465129794Stackerman	       adapter->no_tx_desc_avail1);
2466198987Sjhb	device_printf(dev, "Tx Descriptors not Avail2 = %ld\n",
2467129794Stackerman	       adapter->no_tx_desc_avail2);
2468198987Sjhb	device_printf(dev, "Std Mbuf Failed = %ld\n",
2469129794Stackerman	       adapter->mbuf_alloc_failed);
2470198987Sjhb	device_printf(dev, "Std Cluster Failed = %ld\n",
2471129794Stackerman	       adapter->mbuf_cluster_failed);
2472129794Stackerman
2473198987Sjhb	device_printf(dev, "Defer count = %lld\n",
2474129794Stackerman	       (long long)adapter->stats.dc);
2475198987Sjhb	device_printf(dev, "Missed Packets = %lld\n",
2476129794Stackerman	       (long long)adapter->stats.mpc);
2477198987Sjhb	device_printf(dev, "Receive No Buffers = %lld\n",
2478129794Stackerman	       (long long)adapter->stats.rnbc);
2479198987Sjhb	device_printf(dev, "Receive length errors = %lld\n",
2480129794Stackerman	       (long long)adapter->stats.rlec);
2481198987Sjhb	device_printf(dev, "Crc errors = %lld\n",
2482129794Stackerman	       (long long)adapter->stats.crcerrs);
2483198987Sjhb	device_printf(dev, "Driver dropped packets = %ld\n",
2484129794Stackerman	       adapter->dropped_pkts);
2485129794Stackerman
2486198987Sjhb	device_printf(dev, "XON Rcvd = %lld\n",
2487129794Stackerman	       (long long)adapter->stats.xonrxc);
2488198987Sjhb	device_printf(dev, "XON Xmtd = %lld\n",
2489129794Stackerman	       (long long)adapter->stats.xontxc);
2490198987Sjhb	device_printf(dev, "XOFF Rcvd = %lld\n",
2491129794Stackerman	       (long long)adapter->stats.xoffrxc);
2492198987Sjhb	device_printf(dev, "XOFF Xmtd = %lld\n",
2493129794Stackerman	       (long long)adapter->stats.xofftxc);
2494129794Stackerman
2495198987Sjhb	device_printf(dev, "Good Packets Rcvd = %lld\n",
2496129794Stackerman	       (long long)adapter->stats.gprcl);
2497198987Sjhb	device_printf(dev, "Good Packets Xmtd = %lld\n",
2498129794Stackerman	       (long long)adapter->stats.gptcl);
2499129794Stackerman
2500198987Sjhb	device_printf(dev, "Jumbo frames recvd = %lld\n",
2501129794Stackerman	       (long long)adapter->stats.jprcl);
2502198987Sjhb	device_printf(dev, "Jumbo frames Xmtd = %lld\n",
2503129794Stackerman	       (long long)adapter->stats.jptcl);
2504129794Stackerman
2505129794Stackerman	return;
2506129794Stackerman
2507129794Stackerman}
2508129794Stackerman
2509129794Stackermanstatic int
2510129794Stackermanixgb_sysctl_stats(SYSCTL_HANDLER_ARGS)
2511129794Stackerman{
2512129794Stackerman	int             error;
2513129794Stackerman	int             result;
2514129794Stackerman	struct adapter *adapter;
2515129794Stackerman
2516129794Stackerman	result = -1;
2517129794Stackerman	error = sysctl_handle_int(oidp, &result, 0, req);
2518129794Stackerman
2519129794Stackerman	if (error || !req->newptr)
2520129794Stackerman		return (error);
2521129794Stackerman
2522129794Stackerman	if (result == 1) {
2523129794Stackerman		adapter = (struct adapter *) arg1;
2524129794Stackerman		ixgb_print_hw_stats(adapter);
2525129794Stackerman	}
2526129794Stackerman	return error;
2527129794Stackerman}
2528