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