]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/staging/sxg/sxg.c
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6-omap-h63xx.git] / drivers / staging / sxg / sxg.c
1 /**************************************************************************
2  *
3  * Copyright (C) 2000-2008 Alacritech, Inc.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above
12  *    copyright notice, this list of conditions and the following
13  *    disclaimer in the documentation and/or other materials provided
14  *    with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ALACRITECH, INC. OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * The views and conclusions contained in the software and documentation
30  * are those of the authors and should not be interpreted as representing
31  * official policies, either expressed or implied, of Alacritech, Inc.
32  *
33  **************************************************************************/
34
35 /*
36  * FILENAME: sxg.c
37  *
38  * The SXG driver for Alacritech's 10Gbe products.
39  *
40  * NOTE: This is the standard, non-accelerated version of Alacritech's
41  *       IS-NIC driver.
42  */
43
44 #include <linux/kernel.h>
45 #include <linux/string.h>
46 #include <linux/errno.h>
47 #include <linux/module.h>
48 #include <linux/moduleparam.h>
49 #include <linux/ioport.h>
50 #include <linux/slab.h>
51 #include <linux/interrupt.h>
52 #include <linux/timer.h>
53 #include <linux/pci.h>
54 #include <linux/spinlock.h>
55 #include <linux/init.h>
56 #include <linux/netdevice.h>
57 #include <linux/etherdevice.h>
58 #include <linux/ethtool.h>
59 #include <linux/skbuff.h>
60 #include <linux/delay.h>
61 #include <linux/types.h>
62 #include <linux/dma-mapping.h>
63 #include <linux/mii.h>
64
65 #define SLIC_DUMP_ENABLED               0
66 #define SLIC_GET_STATS_ENABLED          0
67 #define LINUX_FREES_ADAPTER_RESOURCES   1
68 #define SXG_OFFLOAD_IP_CHECKSUM         0
69 #define SXG_POWER_MANAGEMENT_ENABLED    0
70 #define VPCI                            0
71 #define DBG                             1
72 #define ATK_DEBUG                       1
73
74 #include "sxg_os.h"
75 #include "sxghw.h"
76 #include "sxghif.h"
77 #include "sxg.h"
78 #include "sxgdbg.h"
79
80 #include "sxgphycode.h"
81 #include "saharadbgdownload.h"
82
83 static int sxg_allocate_buffer_memory(p_adapter_t adapter, u32 Size,
84                                       SXG_BUFFER_TYPE BufferType);
85 static void sxg_allocate_rcvblock_complete(p_adapter_t adapter, void *RcvBlock,
86                                            dma_addr_t PhysicalAddress,
87                                            u32 Length);
88 static void sxg_allocate_sgl_buffer_complete(p_adapter_t adapter,
89                                              PSXG_SCATTER_GATHER SxgSgl,
90                                              dma_addr_t PhysicalAddress,
91                                              u32 Length);
92
93 static void sxg_mcast_init_crc32(void);
94
95 static int sxg_entry_open(p_net_device dev);
96 static int sxg_entry_halt(p_net_device dev);
97 static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd);
98 static int sxg_send_packets(struct sk_buff *skb, p_net_device dev);
99 static int sxg_transmit_packet(p_adapter_t adapter, struct sk_buff *skb);
100 static void sxg_dumb_sgl(PSCATTER_GATHER_LIST pSgl, PSXG_SCATTER_GATHER SxgSgl);
101
102 static void sxg_handle_interrupt(p_adapter_t adapter);
103 static int sxg_process_isr(p_adapter_t adapter, u32 MessageId);
104 static u32 sxg_process_event_queue(p_adapter_t adapter, u32 RssId);
105 static void sxg_complete_slow_send(p_adapter_t adapter);
106 static struct sk_buff *sxg_slow_receive(p_adapter_t adapter, PSXG_EVENT Event);
107 static void sxg_process_rcv_error(p_adapter_t adapter, u32 ErrorStatus);
108 static bool sxg_mac_filter(p_adapter_t adapter,
109                            p_ether_header EtherHdr, ushort length);
110
111 #if SLIC_GET_STATS_ENABLED
112 static struct net_device_stats *sxg_get_stats(p_net_device dev);
113 #endif
114
115 #define XXXTODO 0
116
117 #if XXXTODO
118 static int sxg_mac_set_address(p_net_device dev, void *ptr);
119 static void sxg_mcast_set_list(p_net_device dev);
120 #endif
121
122 static void sxg_adapter_set_hwaddr(p_adapter_t adapter);
123
124 static void sxg_unmap_mmio_space(p_adapter_t adapter);
125
126 static int sxg_initialize_adapter(p_adapter_t adapter);
127 static void sxg_stock_rcv_buffers(p_adapter_t adapter);
128 static void sxg_complete_descriptor_blocks(p_adapter_t adapter,
129                                            unsigned char Index);
130 static int sxg_initialize_link(p_adapter_t adapter);
131 static int sxg_phy_init(p_adapter_t adapter);
132 static void sxg_link_event(p_adapter_t adapter);
133 static SXG_LINK_STATE sxg_get_link_state(p_adapter_t adapter);
134 static void sxg_link_state(p_adapter_t adapter, SXG_LINK_STATE LinkState);
135 static int sxg_write_mdio_reg(p_adapter_t adapter,
136                               u32 DevAddr, u32 RegAddr, u32 Value);
137 static int sxg_read_mdio_reg(p_adapter_t adapter,
138                              u32 DevAddr, u32 RegAddr, u32 *pValue);
139
140 static unsigned int sxg_first_init = 1;
141 static char *sxg_banner =
142     "Alacritech SLIC Technology(tm) Server and Storage 10Gbe Accelerator (Non-Accelerated)\n";
143
144 static int sxg_debug = 1;
145 static int debug = -1;
146 static p_net_device head_netdevice = NULL;
147
148 static sxgbase_driver_t sxg_global = {
149         .dynamic_intagg = 1,
150 };
151 static int intagg_delay = 100;
152 static u32 dynamic_intagg = 0;
153
154 #define DRV_NAME        "sxg"
155 #define DRV_VERSION     "1.0.1"
156 #define DRV_AUTHOR      "Alacritech, Inc. Engineering"
157 #define DRV_DESCRIPTION "Alacritech SLIC Techonology(tm) Non-Accelerated 10Gbe Driver"
158 #define DRV_COPYRIGHT   "Copyright 2000-2008 Alacritech, Inc.  All rights reserved."
159
160 MODULE_AUTHOR(DRV_AUTHOR);
161 MODULE_DESCRIPTION(DRV_DESCRIPTION);
162 MODULE_LICENSE("GPL");
163
164 module_param(dynamic_intagg, int, 0);
165 MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting");
166 module_param(intagg_delay, int, 0);
167 MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay");
168
169 static struct pci_device_id sxg_pci_tbl[] __devinitdata = {
170         {PCI_DEVICE(SXG_VENDOR_ID, SXG_DEVICE_ID)},
171         {0,}
172 };
173
174 MODULE_DEVICE_TABLE(pci, sxg_pci_tbl);
175
176 /***********************************************************************
177 ************************************************************************
178 ************************************************************************
179 ************************************************************************
180 ************************************************************************/
181
182 static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush)
183 {
184         writel(value, reg);
185         if (flush)
186                 mb();
187 }
188
189 static inline void sxg_reg64_write(p_adapter_t adapter, void __iomem *reg,
190                                    u64 value, u32 cpu)
191 {
192         u32 value_high = (u32) (value >> 32);
193         u32 value_low = (u32) (value & 0x00000000FFFFFFFF);
194         unsigned long flags;
195
196         spin_lock_irqsave(&adapter->Bit64RegLock, flags);
197         writel(value_high, (void __iomem *)(&adapter->UcodeRegs[cpu].Upper));
198         writel(value_low, reg);
199         spin_unlock_irqrestore(&adapter->Bit64RegLock, flags);
200 }
201
202 static void sxg_init_driver(void)
203 {
204         if (sxg_first_init) {
205                 DBG_ERROR("sxg: %s sxg_first_init set jiffies[%lx]\n",
206                           __func__, jiffies);
207                 sxg_first_init = 0;
208                 spin_lock_init(&sxg_global.driver_lock);
209         }
210 }
211
212 static void sxg_dbg_macaddrs(p_adapter_t adapter)
213 {
214         DBG_ERROR("  (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
215                   adapter->netdev->name, adapter->currmacaddr[0],
216                   adapter->currmacaddr[1], adapter->currmacaddr[2],
217                   adapter->currmacaddr[3], adapter->currmacaddr[4],
218                   adapter->currmacaddr[5]);
219         DBG_ERROR("  (%s) mac  %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
220                   adapter->netdev->name, adapter->macaddr[0],
221                   adapter->macaddr[1], adapter->macaddr[2],
222                   adapter->macaddr[3], adapter->macaddr[4],
223                   adapter->macaddr[5]);
224         return;
225 }
226
227 /* SXG Globals */
228 static SXG_DRIVER SxgDriver;
229
230 #ifdef  ATKDBG
231 static sxg_trace_buffer_t LSxgTraceBuffer;
232 #endif /* ATKDBG */
233 static sxg_trace_buffer_t *SxgTraceBuffer = NULL;
234
235 /*
236  * sxg_download_microcode
237  *
238  * Download Microcode to Sahara adapter
239  *
240  * Arguments -
241  *              adapter         - A pointer to our adapter structure
242  *              UcodeSel        - microcode file selection
243  *
244  * Return
245  *      int
246  */
247 static bool sxg_download_microcode(p_adapter_t adapter, SXG_UCODE_SEL UcodeSel)
248 {
249         PSXG_HW_REGS HwRegs = adapter->HwRegs;
250         u32 Section;
251         u32 ThisSectionSize;
252         u32 *Instruction = NULL;
253         u32 BaseAddress, AddressOffset, Address;
254 /*      u32                         Failure; */
255         u32 ValueRead;
256         u32 i;
257         u32 numSections = 0;
258         u32 sectionSize[16];
259         u32 sectionStart[16];
260
261         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DnldUcod",
262                   adapter, 0, 0, 0);
263         DBG_ERROR("sxg: %s ENTER\n", __func__);
264
265         switch (UcodeSel) {
266         case SXG_UCODE_SAHARA:  /* Sahara operational ucode */
267                 numSections = SNumSections;
268                 for (i = 0; i < numSections; i++) {
269                         sectionSize[i] = SSectionSize[i];
270                         sectionStart[i] = SSectionStart[i];
271                 }
272                 break;
273         default:
274                 printk(KERN_ERR KBUILD_MODNAME
275                        ": Woah, big error with the microcode!\n");
276                 break;
277         }
278
279         DBG_ERROR("sxg: RESET THE CARD\n");
280         /* First, reset the card */
281         WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
282
283         /* Download each section of the microcode as specified in */
284         /* its download file.  The *download.c file is generated using */
285         /* the saharaobjtoc facility which converts the metastep .obj */
286         /* file to a .c file which contains a two dimentional array. */
287         for (Section = 0; Section < numSections; Section++) {
288                 DBG_ERROR("sxg: SECTION # %d\n", Section);
289                 switch (UcodeSel) {
290                 case SXG_UCODE_SAHARA:
291                         Instruction = (u32 *) & SaharaUCode[Section][0];
292                         break;
293                 default:
294                         ASSERT(0);
295                         break;
296                 }
297                 BaseAddress = sectionStart[Section];
298                 ThisSectionSize = sectionSize[Section] / 12;    /* Size in instructions */
299                 for (AddressOffset = 0; AddressOffset < ThisSectionSize;
300                      AddressOffset++) {
301                         Address = BaseAddress + AddressOffset;
302                         ASSERT((Address & ~MICROCODE_ADDRESS_MASK) == 0);
303                         /* Write instruction bits 31 - 0 */
304                         WRITE_REG(HwRegs->UcodeDataLow, *Instruction, FLUSH);
305                         /* Write instruction bits 63-32 */
306                         WRITE_REG(HwRegs->UcodeDataMiddle, *(Instruction + 1),
307                                   FLUSH);
308                         /* Write instruction bits 95-64 */
309                         WRITE_REG(HwRegs->UcodeDataHigh, *(Instruction + 2),
310                                   FLUSH);
311                         /* Write instruction address with the WRITE bit set */
312                         WRITE_REG(HwRegs->UcodeAddr,
313                                   (Address | MICROCODE_ADDRESS_WRITE), FLUSH);
314                         /* Sahara bug in the ucode download logic - the write to DataLow */
315                         /* for the next instruction could get corrupted.  To avoid this, */
316                         /* write to DataLow again for this instruction (which may get */
317                         /* corrupted, but it doesn't matter), then increment the address */
318                         /* and write the data for the next instruction to DataLow.  That */
319                         /* write should succeed. */
320                         WRITE_REG(HwRegs->UcodeDataLow, *Instruction, TRUE);
321                         /* Advance 3 u32S to start of next instruction */
322                         Instruction += 3;
323                 }
324         }
325         /* Now repeat the entire operation reading the instruction back and */
326         /* checking for parity errors */
327         for (Section = 0; Section < numSections; Section++) {
328                 DBG_ERROR("sxg: check SECTION # %d\n", Section);
329                 switch (UcodeSel) {
330                 case SXG_UCODE_SAHARA:
331                         Instruction = (u32 *) & SaharaUCode[Section][0];
332                         break;
333                 default:
334                         ASSERT(0);
335                         break;
336                 }
337                 BaseAddress = sectionStart[Section];
338                 ThisSectionSize = sectionSize[Section] / 12;    /* Size in instructions */
339                 for (AddressOffset = 0; AddressOffset < ThisSectionSize;
340                      AddressOffset++) {
341                         Address = BaseAddress + AddressOffset;
342                         /* Write the address with the READ bit set */
343                         WRITE_REG(HwRegs->UcodeAddr,
344                                   (Address | MICROCODE_ADDRESS_READ), FLUSH);
345                         /* Read it back and check parity bit. */
346                         READ_REG(HwRegs->UcodeAddr, ValueRead);
347                         if (ValueRead & MICROCODE_ADDRESS_PARITY) {
348                                 DBG_ERROR("sxg: %s PARITY ERROR\n",
349                                           __func__);
350
351                                 return (FALSE); /* Parity error */
352                         }
353                         ASSERT((ValueRead & MICROCODE_ADDRESS_MASK) == Address);
354                         /* Read the instruction back and compare */
355                         READ_REG(HwRegs->UcodeDataLow, ValueRead);
356                         if (ValueRead != *Instruction) {
357                                 DBG_ERROR("sxg: %s MISCOMPARE LOW\n",
358                                           __func__);
359                                 return (FALSE); /* Miscompare */
360                         }
361                         READ_REG(HwRegs->UcodeDataMiddle, ValueRead);
362                         if (ValueRead != *(Instruction + 1)) {
363                                 DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n",
364                                           __func__);
365                                 return (FALSE); /* Miscompare */
366                         }
367                         READ_REG(HwRegs->UcodeDataHigh, ValueRead);
368                         if (ValueRead != *(Instruction + 2)) {
369                                 DBG_ERROR("sxg: %s MISCOMPARE HIGH\n",
370                                           __func__);
371                                 return (FALSE); /* Miscompare */
372                         }
373                         /* Advance 3 u32S to start of next instruction */
374                         Instruction += 3;
375                 }
376         }
377
378         /* Everything OK, Go. */
379         WRITE_REG(HwRegs->UcodeAddr, MICROCODE_ADDRESS_GO, FLUSH);
380
381         /* Poll the CardUp register to wait for microcode to initialize */
382         /* Give up after 10,000 attemps (500ms). */
383         for (i = 0; i < 10000; i++) {
384                 udelay(50);
385                 READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead);
386                 if (ValueRead == 0xCAFE) {
387                         DBG_ERROR("sxg: %s BOO YA 0xCAFE\n", __func__);
388                         break;
389                 }
390         }
391         if (i == 10000) {
392                 DBG_ERROR("sxg: %s TIMEOUT\n", __func__);
393
394                 return (FALSE); /* Timeout */
395         }
396         /* Now write the LoadSync register.  This is used to */
397         /* synchronize with the card so it can scribble on the memory */
398         /* that contained 0xCAFE from the "CardUp" step above */
399         if (UcodeSel == SXG_UCODE_SAHARA) {
400                 WRITE_REG(adapter->UcodeRegs[0].LoadSync, 0, FLUSH);
401         }
402
403         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDnldUcd",
404                   adapter, 0, 0, 0);
405         DBG_ERROR("sxg: %s EXIT\n", __func__);
406
407         return (TRUE);
408 }
409
410 /*
411  * sxg_allocate_resources - Allocate memory and locks
412  *
413  * Arguments -
414  *      adapter         - A pointer to our adapter structure
415  *
416  * Return
417  *      int
418  */
419 static int sxg_allocate_resources(p_adapter_t adapter)
420 {
421         int status;
422         u32 i;
423         u32 RssIds, IsrCount;
424 /*      PSXG_XMT_RING                                   XmtRing; */
425 /*      PSXG_RCV_RING                                   RcvRing; */
426
427         DBG_ERROR("%s ENTER\n", __func__);
428
429         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocRes",
430                   adapter, 0, 0, 0);
431
432         /* Windows tells us how many CPUs it plans to use for */
433         /* RSS */
434         RssIds = SXG_RSS_CPU_COUNT(adapter);
435         IsrCount = adapter->MsiEnabled ? RssIds : 1;
436
437         DBG_ERROR("%s Setup the spinlocks\n", __func__);
438
439         /* Allocate spinlocks and initialize listheads first. */
440         spin_lock_init(&adapter->RcvQLock);
441         spin_lock_init(&adapter->SglQLock);
442         spin_lock_init(&adapter->XmtZeroLock);
443         spin_lock_init(&adapter->Bit64RegLock);
444         spin_lock_init(&adapter->AdapterLock);
445
446         DBG_ERROR("%s Setup the lists\n", __func__);
447
448         InitializeListHead(&adapter->FreeRcvBuffers);
449         InitializeListHead(&adapter->FreeRcvBlocks);
450         InitializeListHead(&adapter->AllRcvBlocks);
451         InitializeListHead(&adapter->FreeSglBuffers);
452         InitializeListHead(&adapter->AllSglBuffers);
453
454         /* Mark these basic allocations done.  This flags essentially */
455         /* tells the SxgFreeResources routine that it can grab spinlocks */
456         /* and reference listheads. */
457         adapter->BasicAllocations = TRUE;
458         /* Main allocation loop.  Start with the maximum supported by */
459         /* the microcode and back off if memory allocation */
460         /* fails.  If we hit a minimum, fail. */
461
462         for (;;) {
463                 DBG_ERROR("%s Allocate XmtRings size[%x]\n", __func__,
464                           (unsigned int)(sizeof(SXG_XMT_RING) * 1));
465
466                 /* Start with big items first - receive and transmit rings.  At the moment */
467                 /* I'm going to keep the ring size fixed and adjust the number of */
468                 /* TCBs if we fail.  Later we might consider reducing the ring size as well.. */
469                 adapter->XmtRings = pci_alloc_consistent(adapter->pcidev,
470                                                          sizeof(SXG_XMT_RING) *
471                                                          1,
472                                                          &adapter->PXmtRings);
473                 DBG_ERROR("%s XmtRings[%p]\n", __func__, adapter->XmtRings);
474
475                 if (!adapter->XmtRings) {
476                         goto per_tcb_allocation_failed;
477                 }
478                 memset(adapter->XmtRings, 0, sizeof(SXG_XMT_RING) * 1);
479
480                 DBG_ERROR("%s Allocate RcvRings size[%x]\n", __func__,
481                           (unsigned int)(sizeof(SXG_RCV_RING) * 1));
482                 adapter->RcvRings =
483                     pci_alloc_consistent(adapter->pcidev,
484                                          sizeof(SXG_RCV_RING) * 1,
485                                          &adapter->PRcvRings);
486                 DBG_ERROR("%s RcvRings[%p]\n", __func__, adapter->RcvRings);
487                 if (!adapter->RcvRings) {
488                         goto per_tcb_allocation_failed;
489                 }
490                 memset(adapter->RcvRings, 0, sizeof(SXG_RCV_RING) * 1);
491                 break;
492
493               per_tcb_allocation_failed:
494                 /* an allocation failed.  Free any successful allocations. */
495                 if (adapter->XmtRings) {
496                         pci_free_consistent(adapter->pcidev,
497                                             sizeof(SXG_XMT_RING) * 4096,
498                                             adapter->XmtRings,
499                                             adapter->PXmtRings);
500                         adapter->XmtRings = NULL;
501                 }
502                 if (adapter->RcvRings) {
503                         pci_free_consistent(adapter->pcidev,
504                                             sizeof(SXG_RCV_RING) * 4096,
505                                             adapter->RcvRings,
506                                             adapter->PRcvRings);
507                         adapter->RcvRings = NULL;
508                 }
509                 /* Loop around and try again.... */
510         }
511
512         DBG_ERROR("%s Initialize RCV ZERO and XMT ZERO rings\n", __func__);
513         /* Initialize rcv zero and xmt zero rings */
514         SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE);
515         SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE);
516
517         /* Sanity check receive data structure format */
518         ASSERT((adapter->ReceiveBufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
519                (adapter->ReceiveBufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
520         ASSERT(sizeof(SXG_RCV_DESCRIPTOR_BLOCK) ==
521                SXG_RCV_DESCRIPTOR_BLOCK_SIZE);
522
523         /* Allocate receive data buffers.  We allocate a block of buffers and */
524         /* a corresponding descriptor block at once.  See sxghw.h:SXG_RCV_BLOCK */
525         for (i = 0; i < SXG_INITIAL_RCV_DATA_BUFFERS;
526              i += SXG_RCV_DESCRIPTORS_PER_BLOCK) {
527                 sxg_allocate_buffer_memory(adapter,
528                                            SXG_RCV_BLOCK_SIZE(adapter->
529                                                               ReceiveBufferSize),
530                                            SXG_BUFFER_TYPE_RCV);
531         }
532         /* NBL resource allocation can fail in the 'AllocateComplete' routine, which */
533         /* doesn't return status.  Make sure we got the number of buffers we requested */
534         if (adapter->FreeRcvBufferCount < SXG_INITIAL_RCV_DATA_BUFFERS) {
535                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF6",
536                           adapter, adapter->FreeRcvBufferCount, SXG_MAX_ENTRIES,
537                           0);
538                 return (STATUS_RESOURCES);
539         }
540
541         DBG_ERROR("%s Allocate EventRings size[%x]\n", __func__,
542                   (unsigned int)(sizeof(SXG_EVENT_RING) * RssIds));
543
544         /* Allocate event queues. */
545         adapter->EventRings = pci_alloc_consistent(adapter->pcidev,
546                                                    sizeof(SXG_EVENT_RING) *
547                                                    RssIds,
548                                                    &adapter->PEventRings);
549
550         if (!adapter->EventRings) {
551                 /* Caller will call SxgFreeAdapter to clean up above allocations */
552                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF8",
553                           adapter, SXG_MAX_ENTRIES, 0, 0);
554                 status = STATUS_RESOURCES;
555                 goto per_tcb_allocation_failed;
556         }
557         memset(adapter->EventRings, 0, sizeof(SXG_EVENT_RING) * RssIds);
558
559         DBG_ERROR("%s Allocate ISR size[%x]\n", __func__, IsrCount);
560         /* Allocate ISR */
561         adapter->Isr = pci_alloc_consistent(adapter->pcidev,
562                                             IsrCount, &adapter->PIsr);
563         if (!adapter->Isr) {
564                 /* Caller will call SxgFreeAdapter to clean up above allocations */
565                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF9",
566                           adapter, SXG_MAX_ENTRIES, 0, 0);
567                 status = STATUS_RESOURCES;
568                 goto per_tcb_allocation_failed;
569         }
570         memset(adapter->Isr, 0, sizeof(u32) * IsrCount);
571
572         DBG_ERROR("%s Allocate shared XMT ring zero index location size[%x]\n",
573                   __func__, (unsigned int)sizeof(u32));
574
575         /* Allocate shared XMT ring zero index location */
576         adapter->XmtRingZeroIndex = pci_alloc_consistent(adapter->pcidev,
577                                                          sizeof(u32),
578                                                          &adapter->
579                                                          PXmtRingZeroIndex);
580         if (!adapter->XmtRingZeroIndex) {
581                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF10",
582                           adapter, SXG_MAX_ENTRIES, 0, 0);
583                 status = STATUS_RESOURCES;
584                 goto per_tcb_allocation_failed;
585         }
586         memset(adapter->XmtRingZeroIndex, 0, sizeof(u32));
587
588         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlcResS",
589                   adapter, SXG_MAX_ENTRIES, 0, 0);
590
591         DBG_ERROR("%s EXIT\n", __func__);
592         return (STATUS_SUCCESS);
593 }
594
595 /*
596  * sxg_config_pci -
597  *
598  * Set up PCI Configuration space
599  *
600  * Arguments -
601  *              pcidev                  - A pointer to our adapter structure
602  *
603  */
604 static void sxg_config_pci(struct pci_dev *pcidev)
605 {
606         u16 pci_command;
607         u16 new_command;
608
609         pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
610         DBG_ERROR("sxg: %s  PCI command[%4.4x]\n", __func__, pci_command);
611         /* Set the command register */
612         new_command = pci_command | (PCI_COMMAND_MEMORY |       /* Memory Space Enable */
613                                      PCI_COMMAND_MASTER |       /* Bus master enable */
614                                      PCI_COMMAND_INVALIDATE |   /* Memory write and invalidate */
615                                      PCI_COMMAND_PARITY |       /* Parity error response */
616                                      PCI_COMMAND_SERR | /* System ERR */
617                                      PCI_COMMAND_FAST_BACK);    /* Fast back-to-back */
618         if (pci_command != new_command) {
619                 DBG_ERROR("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n",
620                           __func__, pci_command, new_command);
621                 pci_write_config_word(pcidev, PCI_COMMAND, new_command);
622         }
623 }
624
625 static int sxg_entry_probe(struct pci_dev *pcidev,
626                            const struct pci_device_id *pci_tbl_entry)
627 {
628         static int did_version = 0;
629         int err;
630         struct net_device *netdev;
631         p_adapter_t adapter;
632         void __iomem *memmapped_ioaddr;
633         u32 status = 0;
634         ulong mmio_start = 0;
635         ulong mmio_len = 0;
636
637         DBG_ERROR("sxg: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
638                   __func__, jiffies, smp_processor_id());
639
640         /* Initialize trace buffer */
641 #ifdef ATKDBG
642         SxgTraceBuffer = &LSxgTraceBuffer;
643         SXG_TRACE_INIT(SxgTraceBuffer, TRACE_NOISY);
644 #endif
645
646         sxg_global.dynamic_intagg = dynamic_intagg;
647
648         err = pci_enable_device(pcidev);
649
650         DBG_ERROR("Call pci_enable_device(%p)  status[%x]\n", pcidev, err);
651         if (err) {
652                 return err;
653         }
654
655         if (sxg_debug > 0 && did_version++ == 0) {
656                 printk(KERN_INFO "%s\n", sxg_banner);
657                 printk(KERN_INFO "%s\n", DRV_VERSION);
658         }
659
660         if (!(err = pci_set_dma_mask(pcidev, DMA_64BIT_MASK))) {
661                 DBG_ERROR("pci_set_dma_mask(DMA_64BIT_MASK) successful\n");
662         } else {
663                 if ((err = pci_set_dma_mask(pcidev, DMA_32BIT_MASK))) {
664                         DBG_ERROR
665                             ("No usable DMA configuration, aborting  err[%x]\n",
666                              err);
667                         return err;
668                 }
669                 DBG_ERROR("pci_set_dma_mask(DMA_32BIT_MASK) successful\n");
670         }
671
672         DBG_ERROR("Call pci_request_regions\n");
673
674         err = pci_request_regions(pcidev, DRV_NAME);
675         if (err) {
676                 DBG_ERROR("pci_request_regions FAILED err[%x]\n", err);
677                 return err;
678         }
679
680         DBG_ERROR("call pci_set_master\n");
681         pci_set_master(pcidev);
682
683         DBG_ERROR("call alloc_etherdev\n");
684         netdev = alloc_etherdev(sizeof(adapter_t));
685         if (!netdev) {
686                 err = -ENOMEM;
687                 goto err_out_exit_sxg_probe;
688         }
689         DBG_ERROR("alloc_etherdev for slic netdev[%p]\n", netdev);
690
691         SET_NETDEV_DEV(netdev, &pcidev->dev);
692
693         pci_set_drvdata(pcidev, netdev);
694         adapter = netdev_priv(netdev);
695         adapter->netdev = netdev;
696         adapter->pcidev = pcidev;
697
698         mmio_start = pci_resource_start(pcidev, 0);
699         mmio_len = pci_resource_len(pcidev, 0);
700
701         DBG_ERROR("sxg: call ioremap(mmio_start[%lx], mmio_len[%lx])\n",
702                   mmio_start, mmio_len);
703
704         memmapped_ioaddr = ioremap(mmio_start, mmio_len);
705         DBG_ERROR("sxg: %s MEMMAPPED_IOADDR [%p]\n", __func__,
706                   memmapped_ioaddr);
707         if (!memmapped_ioaddr) {
708                 DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
709                           __func__, mmio_len, mmio_start);
710                 goto err_out_free_mmio_region;
711         }
712
713         DBG_ERROR
714             ("sxg: %s found Alacritech SXG PCI, MMIO at %p, start[%lx] len[%lx], IRQ %d.\n",
715              __func__, memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq);
716
717         adapter->HwRegs = (void *)memmapped_ioaddr;
718         adapter->base_addr = memmapped_ioaddr;
719
720         mmio_start = pci_resource_start(pcidev, 2);
721         mmio_len = pci_resource_len(pcidev, 2);
722
723         DBG_ERROR("sxg: call ioremap(mmio_start[%lx], mmio_len[%lx])\n",
724                   mmio_start, mmio_len);
725
726         memmapped_ioaddr = ioremap(mmio_start, mmio_len);
727         DBG_ERROR("sxg: %s MEMMAPPED_IOADDR [%p]\n", __func__,
728                   memmapped_ioaddr);
729         if (!memmapped_ioaddr) {
730                 DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
731                           __func__, mmio_len, mmio_start);
732                 goto err_out_free_mmio_region;
733         }
734
735         DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, "
736                   "start[%lx] len[%lx], IRQ %d.\n", __func__,
737                   memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq);
738
739         adapter->UcodeRegs = (void *)memmapped_ioaddr;
740
741         adapter->State = SXG_STATE_INITIALIZING;
742         /* Maintain a list of all adapters anchored by */
743         /* the global SxgDriver structure. */
744         adapter->Next = SxgDriver.Adapters;
745         SxgDriver.Adapters = adapter;
746         adapter->AdapterID = ++SxgDriver.AdapterID;
747
748         /* Initialize CRC table used to determine multicast hash */
749         sxg_mcast_init_crc32();
750
751         adapter->JumboEnabled = FALSE;
752         adapter->RssEnabled = FALSE;
753         if (adapter->JumboEnabled) {
754                 adapter->FrameSize = JUMBOMAXFRAME;
755                 adapter->ReceiveBufferSize = SXG_RCV_JUMBO_BUFFER_SIZE;
756         } else {
757                 adapter->FrameSize = ETHERMAXFRAME;
758                 adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE;
759         }
760
761 /*    status = SXG_READ_EEPROM(adapter); */
762 /*    if (!status) { */
763 /*        goto sxg_init_bad; */
764 /*    } */
765
766         DBG_ERROR("sxg: %s ENTER sxg_config_pci\n", __func__);
767         sxg_config_pci(pcidev);
768         DBG_ERROR("sxg: %s EXIT sxg_config_pci\n", __func__);
769
770         DBG_ERROR("sxg: %s ENTER sxg_init_driver\n", __func__);
771         sxg_init_driver();
772         DBG_ERROR("sxg: %s EXIT sxg_init_driver\n", __func__);
773
774         adapter->vendid = pci_tbl_entry->vendor;
775         adapter->devid = pci_tbl_entry->device;
776         adapter->subsysid = pci_tbl_entry->subdevice;
777         adapter->busnumber = pcidev->bus->number;
778         adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F);
779         adapter->functionnumber = (pcidev->devfn & 0x7);
780         adapter->memorylength = pci_resource_len(pcidev, 0);
781         adapter->irq = pcidev->irq;
782         adapter->next_netdevice = head_netdevice;
783         head_netdevice = netdev;
784 /*      adapter->chipid = chip_idx; */
785         adapter->port = 0;      /*adapter->functionnumber; */
786         adapter->cardindex = adapter->port;
787
788         /* Allocate memory and other resources */
789         DBG_ERROR("sxg: %s ENTER sxg_allocate_resources\n", __func__);
790         status = sxg_allocate_resources(adapter);
791         DBG_ERROR("sxg: %s EXIT sxg_allocate_resources status %x\n",
792                   __func__, status);
793         if (status != STATUS_SUCCESS) {
794                 goto err_out_unmap;
795         }
796
797         DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__);
798         if (sxg_download_microcode(adapter, SXG_UCODE_SAHARA)) {
799                 DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
800                           __func__);
801                 sxg_adapter_set_hwaddr(adapter);
802         } else {
803                 adapter->state = ADAPT_FAIL;
804                 adapter->linkstate = LINK_DOWN;
805                 DBG_ERROR("sxg_download_microcode FAILED status[%x]\n", status);
806         }
807
808         netdev->base_addr = (unsigned long)adapter->base_addr;
809         netdev->irq = adapter->irq;
810         netdev->open = sxg_entry_open;
811         netdev->stop = sxg_entry_halt;
812         netdev->hard_start_xmit = sxg_send_packets;
813         netdev->do_ioctl = sxg_ioctl;
814 #if XXXTODO
815         netdev->set_mac_address = sxg_mac_set_address;
816 #if SLIC_GET_STATS_ENABLED
817         netdev->get_stats = sxg_get_stats;
818 #endif
819         netdev->set_multicast_list = sxg_mcast_set_list;
820 #endif
821
822         strcpy(netdev->name, "eth%d");
823 /*  strcpy(netdev->name, pci_name(pcidev)); */
824         if ((err = register_netdev(netdev))) {
825                 DBG_ERROR("Cannot register net device, aborting. %s\n",
826                           netdev->name);
827                 goto err_out_unmap;
828         }
829
830         DBG_ERROR
831             ("sxg: %s addr 0x%lx, irq %d, MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n",
832              netdev->name, netdev->base_addr, pcidev->irq, netdev->dev_addr[0],
833              netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3],
834              netdev->dev_addr[4], netdev->dev_addr[5]);
835
836 /*sxg_init_bad: */
837         ASSERT(status == FALSE);
838 /*      sxg_free_adapter(adapter); */
839
840         DBG_ERROR("sxg: %s EXIT status[%x] jiffies[%lx] cpu %d\n", __func__,
841                   status, jiffies, smp_processor_id());
842         return status;
843
844       err_out_unmap:
845         iounmap((void *)memmapped_ioaddr);
846
847       err_out_free_mmio_region:
848         release_mem_region(mmio_start, mmio_len);
849
850       err_out_exit_sxg_probe:
851
852         DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies,
853                   smp_processor_id());
854
855         return -ENODEV;
856 }
857
858 /***********************************************************************
859  * LINE BASE Interrupt routines..
860  ***********************************************************************/
861 /*
862  *
863  * sxg_disable_interrupt
864  *
865  * DisableInterrupt Handler
866  *
867  * Arguments:
868  *
869  *   adapter:   Our adapter structure
870  *
871  * Return Value:
872  *      None.
873  */
874 static void sxg_disable_interrupt(p_adapter_t adapter)
875 {
876         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DisIntr",
877                   adapter, adapter->InterruptsEnabled, 0, 0);
878         /* For now, RSS is disabled with line based interrupts */
879         ASSERT(adapter->RssEnabled == FALSE);
880         ASSERT(adapter->MsiEnabled == FALSE);
881         /* */
882         /* Turn off interrupts by writing to the icr register. */
883         /* */
884         WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_DISABLE), TRUE);
885
886         adapter->InterruptsEnabled = 0;
887
888         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDisIntr",
889                   adapter, adapter->InterruptsEnabled, 0, 0);
890 }
891
892 /*
893  *
894  * sxg_enable_interrupt
895  *
896  * EnableInterrupt Handler
897  *
898  * Arguments:
899  *
900  *   adapter:   Our adapter structure
901  *
902  * Return Value:
903  *      None.
904  */
905 static void sxg_enable_interrupt(p_adapter_t adapter)
906 {
907         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "EnIntr",
908                   adapter, adapter->InterruptsEnabled, 0, 0);
909         /* For now, RSS is disabled with line based interrupts */
910         ASSERT(adapter->RssEnabled == FALSE);
911         ASSERT(adapter->MsiEnabled == FALSE);
912         /* */
913         /* Turn on interrupts by writing to the icr register. */
914         /* */
915         WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_ENABLE), TRUE);
916
917         adapter->InterruptsEnabled = 1;
918
919         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XEnIntr",
920                   adapter, 0, 0, 0);
921 }
922
923 /*
924  *
925  * sxg_isr - Process an line-based interrupt
926  *
927  * Arguments:
928  *              Context                 - Our adapter structure
929  *              QueueDefault    - Output parameter to queue to default CPU
930  *              TargetCpus              - Output bitmap to schedule DPC's
931  *
932  * Return Value:
933  *      TRUE if our interrupt
934  */
935 static irqreturn_t sxg_isr(int irq, void *dev_id)
936 {
937         p_net_device dev = (p_net_device) dev_id;
938         p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
939 /*      u32                 CpuMask = 0, i; */
940
941         adapter->Stats.NumInts++;
942         if (adapter->Isr[0] == 0) {
943                 /* The SLIC driver used to experience a number of spurious interrupts */
944                 /* due to the delay associated with the masking of the interrupt */
945                 /* (we'd bounce back in here).  If we see that again with Sahara, */
946                 /* add a READ_REG of the Icr register after the WRITE_REG below. */
947                 adapter->Stats.FalseInts++;
948                 return IRQ_NONE;
949         }
950         /* */
951         /* Move the Isr contents and clear the value in */
952         /* shared memory, and mask interrupts */
953         /* */
954         adapter->IsrCopy[0] = adapter->Isr[0];
955         adapter->Isr[0] = 0;
956         WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE);
957 /*      ASSERT(adapter->IsrDpcsPending == 0); */
958 #if XXXTODO                     /* RSS Stuff */
959         /* If RSS is enabled and the ISR specifies */
960         /* SXG_ISR_EVENT, then schedule DPC's */
961         /* based on event queues. */
962         if (adapter->RssEnabled && (adapter->IsrCopy[0] & SXG_ISR_EVENT)) {
963                 for (i = 0;
964                      i < adapter->RssSystemInfo->ProcessorInfo.RssCpuCount;
965                      i++) {
966                         PSXG_EVENT_RING EventRing = &adapter->EventRings[i];
967                         PSXG_EVENT Event =
968                             &EventRing->Ring[adapter->NextEvent[i]];
969                         unsigned char Cpu =
970                             adapter->RssSystemInfo->RssIdToCpu[i];
971                         if (Event->Status & EVENT_STATUS_VALID) {
972                                 adapter->IsrDpcsPending++;
973                                 CpuMask |= (1 << Cpu);
974                         }
975                 }
976         }
977         /* Now, either schedule the CPUs specified by the CpuMask, */
978         /* or queue default */
979         if (CpuMask) {
980                 *QueueDefault = FALSE;
981         } else {
982                 adapter->IsrDpcsPending = 1;
983                 *QueueDefault = TRUE;
984         }
985         *TargetCpus = CpuMask;
986 #endif
987         /* */
988         /*  There are no DPCs in Linux, so call the handler now */
989         /* */
990         sxg_handle_interrupt(adapter);
991
992         return IRQ_HANDLED;
993 }
994
995 static void sxg_handle_interrupt(p_adapter_t adapter)
996 {
997 /*    unsigned char           RssId   = 0; */
998         u32 NewIsr;
999
1000         if (adapter->Stats.RcvNoBuffer < 5) {
1001                 DBG_ERROR("Enter sxg_handle_interrupt ISR[%x]\n",
1002                           adapter->IsrCopy[0]);
1003         }
1004         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "HndlIntr",
1005                   adapter, adapter->IsrCopy[0], 0, 0);
1006         /* For now, RSS is disabled with line based interrupts */
1007         ASSERT(adapter->RssEnabled == FALSE);
1008         ASSERT(adapter->MsiEnabled == FALSE);
1009         ASSERT(adapter->IsrCopy[0]);
1010 /*/////////////////////////// */
1011
1012         /* Always process the event queue. */
1013         sxg_process_event_queue(adapter,
1014                                 (adapter->RssEnabled ? /*RssId */ 0 : 0));
1015
1016 #if XXXTODO                     /* RSS stuff */
1017         if (--adapter->IsrDpcsPending) {
1018                 /* We're done. */
1019                 ASSERT(adapter->RssEnabled);
1020                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DPCsPend",
1021                           adapter, 0, 0, 0);
1022                 return;
1023         }
1024 #endif
1025         /* */
1026         /* Last (or only) DPC processes the ISR and clears the interrupt. */
1027         /* */
1028         NewIsr = sxg_process_isr(adapter, 0);
1029         /* */
1030         /* Reenable interrupts */
1031         /* */
1032         adapter->IsrCopy[0] = 0;
1033         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ClearIsr",
1034                   adapter, NewIsr, 0, 0);
1035
1036         if (adapter->Stats.RcvNoBuffer < 5) {
1037                 DBG_ERROR
1038                     ("Exit sxg_handle_interrupt2 after enabling interrupt\n");
1039         }
1040
1041         WRITE_REG(adapter->UcodeRegs[0].Isr, NewIsr, TRUE);
1042
1043         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XHndlInt",
1044                   adapter, 0, 0, 0);
1045 }
1046
1047 /*
1048  *
1049  * sxg_process_isr - Process an interrupt.  Called from the line-based and
1050  *                      message based interrupt DPC routines
1051  *
1052  * Arguments:
1053  *              adapter                 - Our adapter structure
1054  *              Queue                   - The ISR that needs processing
1055  *
1056  * Return Value:
1057  *      None
1058  */
1059 static int sxg_process_isr(p_adapter_t adapter, u32 MessageId)
1060 {
1061         u32 Isr = adapter->IsrCopy[MessageId];
1062         u32 NewIsr = 0;
1063
1064         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ProcIsr",
1065                   adapter, Isr, 0, 0);
1066
1067         /* Error */
1068         if (Isr & SXG_ISR_ERR) {
1069                 if (Isr & SXG_ISR_PDQF) {
1070                         adapter->Stats.PdqFull++;
1071                         DBG_ERROR("%s: SXG_ISR_ERR  PDQF!!\n", __func__);
1072                 }
1073                 /* No host buffer */
1074                 if (Isr & SXG_ISR_RMISS) {
1075                         /* There is a bunch of code in the SLIC driver which */
1076                         /* attempts to process more receive events per DPC */
1077                         /* if we start to fall behind.  We'll probably */
1078                         /* need to do something similar here, but hold */
1079                         /* off for now.  I don't want to make the code more */
1080                         /* complicated than strictly needed. */
1081                         adapter->Stats.RcvNoBuffer++;
1082                         if (adapter->Stats.RcvNoBuffer < 5) {
1083                                 DBG_ERROR("%s: SXG_ISR_ERR  RMISS!!\n",
1084                                           __func__);
1085                         }
1086                 }
1087                 /* Card crash */
1088                 if (Isr & SXG_ISR_DEAD) {
1089                         /* Set aside the crash info and set the adapter state to RESET */
1090                         adapter->CrashCpu =
1091                             (unsigned char)((Isr & SXG_ISR_CPU) >>
1092                                             SXG_ISR_CPU_SHIFT);
1093                         adapter->CrashLocation = (ushort) (Isr & SXG_ISR_CRASH);
1094                         adapter->Dead = TRUE;
1095                         DBG_ERROR("%s: ISR_DEAD %x, CPU: %d\n", __func__,
1096                                   adapter->CrashLocation, adapter->CrashCpu);
1097                 }
1098                 /* Event ring full */
1099                 if (Isr & SXG_ISR_ERFULL) {
1100                         /* Same issue as RMISS, really.  This means the */
1101                         /* host is falling behind the card.  Need to increase */
1102                         /* event ring size, process more events per interrupt, */
1103                         /* and/or reduce/remove interrupt aggregation. */
1104                         adapter->Stats.EventRingFull++;
1105                         DBG_ERROR("%s: SXG_ISR_ERR  EVENT RING FULL!!\n",
1106                                   __func__);
1107                 }
1108                 /* Transmit drop - no DRAM buffers or XMT error */
1109                 if (Isr & SXG_ISR_XDROP) {
1110                         adapter->Stats.XmtDrops++;
1111                         adapter->Stats.XmtErrors++;
1112                         DBG_ERROR("%s: SXG_ISR_ERR  XDROP!!\n", __func__);
1113                 }
1114         }
1115         /* Slowpath send completions */
1116         if (Isr & SXG_ISR_SPSEND) {
1117                 sxg_complete_slow_send(adapter);
1118         }
1119         /* Dump */
1120         if (Isr & SXG_ISR_UPC) {
1121                 ASSERT(adapter->DumpCmdRunning);        /* Maybe change when debug is added.. */
1122                 adapter->DumpCmdRunning = FALSE;
1123         }
1124         /* Link event */
1125         if (Isr & SXG_ISR_LINK) {
1126                 sxg_link_event(adapter);
1127         }
1128         /* Debug - breakpoint hit */
1129         if (Isr & SXG_ISR_BREAK) {
1130                 /* At the moment AGDB isn't written to support interactive */
1131                 /* debug sessions.  When it is, this interrupt will be used */
1132                 /* to signal AGDB that it has hit a breakpoint.  For now, ASSERT. */
1133                 ASSERT(0);
1134         }
1135         /* Heartbeat response */
1136         if (Isr & SXG_ISR_PING) {
1137                 adapter->PingOutstanding = FALSE;
1138         }
1139         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XProcIsr",
1140                   adapter, Isr, NewIsr, 0);
1141
1142         return (NewIsr);
1143 }
1144
1145 /*
1146  *
1147  * sxg_process_event_queue - Process our event queue
1148  *
1149  * Arguments:
1150  *              - adapter       - Adapter structure
1151  *              - RssId         - The event queue requiring processing
1152  *
1153  * Return Value:
1154  *      None.
1155  */
1156 static u32 sxg_process_event_queue(p_adapter_t adapter, u32 RssId)
1157 {
1158         PSXG_EVENT_RING EventRing = &adapter->EventRings[RssId];
1159         PSXG_EVENT Event = &EventRing->Ring[adapter->NextEvent[RssId]];
1160         u32 EventsProcessed = 0, Batches = 0;
1161         u32 num_skbs = 0;
1162         struct sk_buff *skb;
1163 #ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
1164         struct sk_buff *prev_skb = NULL;
1165         struct sk_buff *IndicationList[SXG_RCV_ARRAYSIZE];
1166         u32 Index;
1167         PSXG_RCV_DATA_BUFFER_HDR RcvDataBufferHdr;
1168 #endif
1169         u32 ReturnStatus = 0;
1170
1171         ASSERT((adapter->State == SXG_STATE_RUNNING) ||
1172                (adapter->State == SXG_STATE_PAUSING) ||
1173                (adapter->State == SXG_STATE_PAUSED) ||
1174                (adapter->State == SXG_STATE_HALTING));
1175         /* We may still have unprocessed events on the queue if */
1176         /* the card crashed.  Don't process them. */
1177         if (adapter->Dead) {
1178                 return (0);
1179         }
1180         /* In theory there should only be a single processor that */
1181         /* accesses this queue, and only at interrupt-DPC time.  So */
1182         /* we shouldn't need a lock for any of this. */
1183         while (Event->Status & EVENT_STATUS_VALID) {
1184                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "Event",
1185                           Event, Event->Code, Event->Status,
1186                           adapter->NextEvent);
1187                 switch (Event->Code) {
1188                 case EVENT_CODE_BUFFERS:
1189                         ASSERT(!(Event->CommandIndex & 0xFF00));        /* SXG_RING_INFO Head & Tail == unsigned char */
1190                         /* */
1191                         sxg_complete_descriptor_blocks(adapter,
1192                                                        Event->CommandIndex);
1193                         /* */
1194                         break;
1195                 case EVENT_CODE_SLOWRCV:
1196                         --adapter->RcvBuffersOnCard;
1197                         if ((skb = sxg_slow_receive(adapter, Event))) {
1198                                 u32 rx_bytes;
1199 #ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
1200                                 /* Add it to our indication list */
1201                                 SXG_ADD_RCV_PACKET(adapter, skb, prev_skb,
1202                                                    IndicationList, num_skbs);
1203                                 /*  In Linux, we just pass up each skb to the protocol above at this point, */
1204                                 /*  there is no capability of an indication list. */
1205 #else
1206 /* CHECK            skb_pull(skb, INIC_RCVBUF_HEADSIZE); */
1207                                 rx_bytes = Event->Length;       /* (rcvbuf->length & IRHDDR_FLEN_MSK); */
1208                                 skb_put(skb, rx_bytes);
1209                                 adapter->stats.rx_packets++;
1210                                 adapter->stats.rx_bytes += rx_bytes;
1211 #if SXG_OFFLOAD_IP_CHECKSUM
1212                                 skb->ip_summed = CHECKSUM_UNNECESSARY;
1213 #endif
1214                                 skb->dev = adapter->netdev;
1215                                 skb->protocol = eth_type_trans(skb, skb->dev);
1216                                 netif_rx(skb);
1217 #endif
1218                         }
1219                         break;
1220                 default:
1221                         DBG_ERROR("%s: ERROR  Invalid EventCode %d\n",
1222                                   __func__, Event->Code);
1223 /*                      ASSERT(0); */
1224                 }
1225                 /* See if we need to restock card receive buffers. */
1226                 /* There are two things to note here: */
1227                 /*      First - This test is not SMP safe.  The */
1228                 /*              adapter->BuffersOnCard field is protected via atomic interlocked calls, but */
1229                 /*              we do not protect it with respect to these tests.  The only way to do that */
1230                 /*      is with a lock, and I don't want to grab a lock every time we adjust the */
1231                 /*      BuffersOnCard count.  Instead, we allow the buffer replenishment to be off */
1232                 /*      once in a while.  The worst that can happen is the card is given one */
1233                 /*      more-or-less descriptor block than the arbitrary value we've chosen. */
1234                 /*      No big deal */
1235                 /*      In short DO NOT ADD A LOCK HERE, OR WHERE RcvBuffersOnCard is adjusted. */
1236                 /*      Second - We expect this test to rarely evaluate to true.  We attempt to */
1237                 /*      refill descriptor blocks as they are returned to us */
1238                 /*      (sxg_complete_descriptor_blocks), so The only time this should evaluate */
1239                 /*      to true is when sxg_complete_descriptor_blocks failed to allocate */
1240                 /*              receive buffers. */
1241                 if (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
1242                         sxg_stock_rcv_buffers(adapter);
1243                 }
1244                 /* It's more efficient to just set this to zero. */
1245                 /* But clearing the top bit saves potential debug info... */
1246                 Event->Status &= ~EVENT_STATUS_VALID;
1247                 /* Advanct to the next event */
1248                 SXG_ADVANCE_INDEX(adapter->NextEvent[RssId], EVENT_RING_SIZE);
1249                 Event = &EventRing->Ring[adapter->NextEvent[RssId]];
1250                 EventsProcessed++;
1251                 if (EventsProcessed == EVENT_RING_BATCH) {
1252                         /* Release a batch of events back to the card */
1253                         WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
1254                                   EVENT_RING_BATCH, FALSE);
1255                         EventsProcessed = 0;
1256                         /* If we've processed our batch limit, break out of the */
1257                         /* loop and return SXG_ISR_EVENT to arrange for us to */
1258                         /* be called again */
1259                         if (Batches++ == EVENT_BATCH_LIMIT) {
1260                                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
1261                                           TRACE_NOISY, "EvtLimit", Batches,
1262                                           adapter->NextEvent, 0, 0);
1263                                 ReturnStatus = SXG_ISR_EVENT;
1264                                 break;
1265                         }
1266                 }
1267         }
1268 #ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
1269         /* */
1270         /* Indicate any received dumb-nic frames */
1271         /* */
1272         SXG_INDICATE_PACKETS(adapter, IndicationList, num_skbs);
1273 #endif
1274         /* */
1275         /* Release events back to the card. */
1276         /* */
1277         if (EventsProcessed) {
1278                 WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
1279                           EventsProcessed, FALSE);
1280         }
1281         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XPrcEvnt",
1282                   Batches, EventsProcessed, adapter->NextEvent, num_skbs);
1283
1284         return (ReturnStatus);
1285 }
1286
1287 /*
1288  * sxg_complete_slow_send - Complete slowpath or dumb-nic sends
1289  *
1290  * Arguments -
1291  *      adapter         - A pointer to our adapter structure
1292
1293  * Return
1294  *      None
1295  */
1296 static void sxg_complete_slow_send(p_adapter_t adapter)
1297 {
1298         PSXG_XMT_RING XmtRing = &adapter->XmtRings[0];
1299         PSXG_RING_INFO XmtRingInfo = &adapter->XmtRingZeroInfo;
1300         u32 *ContextType;
1301         PSXG_CMD XmtCmd;
1302
1303         /* NOTE - This lock is dropped and regrabbed in this loop. */
1304         /* This means two different processors can both be running */
1305         /* through this loop. Be *very* careful. */
1306         spin_lock(&adapter->XmtZeroLock);
1307         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnds",
1308                   adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
1309
1310         while (XmtRingInfo->Tail != *adapter->XmtRingZeroIndex) {
1311                 /* Locate the current Cmd (ring descriptor entry), and */
1312                 /* associated SGL, and advance the tail */
1313                 SXG_RETURN_CMD(XmtRing, XmtRingInfo, XmtCmd, ContextType);
1314                 ASSERT(ContextType);
1315                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
1316                           XmtRingInfo->Head, XmtRingInfo->Tail, XmtCmd, 0);
1317                 /* Clear the SGL field. */
1318                 XmtCmd->Sgl = 0;
1319
1320                 switch (*ContextType) {
1321                 case SXG_SGL_DUMB:
1322                         {
1323                                 struct sk_buff *skb;
1324                                 /* Dumb-nic send.  Command context is the dumb-nic SGL */
1325                                 skb = (struct sk_buff *)ContextType;
1326                                 /* Complete the send */
1327                                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
1328                                           TRACE_IMPORTANT, "DmSndCmp", skb, 0,
1329                                           0, 0);
1330                                 ASSERT(adapter->Stats.XmtQLen);
1331                                 adapter->Stats.XmtQLen--;       /* within XmtZeroLock */
1332                                 adapter->Stats.XmtOk++;
1333                                 /* Now drop the lock and complete the send back to */
1334                                 /* Microsoft.  We need to drop the lock because */
1335                                 /* Microsoft can come back with a chimney send, which */
1336                                 /* results in a double trip in SxgTcpOuput */
1337                                 spin_unlock(&adapter->XmtZeroLock);
1338                                 SXG_COMPLETE_DUMB_SEND(adapter, skb);
1339                                 /* and reacquire.. */
1340                                 spin_lock(&adapter->XmtZeroLock);
1341                         }
1342                         break;
1343                 default:
1344                         ASSERT(0);
1345                 }
1346         }
1347         spin_unlock(&adapter->XmtZeroLock);
1348         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
1349                   adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
1350 }
1351
1352 /*
1353  * sxg_slow_receive
1354  *
1355  * Arguments -
1356  *      adapter         - A pointer to our adapter structure
1357  *      Event           - Receive event
1358  *
1359  * Return
1360  *       skb
1361  */
1362 static struct sk_buff *sxg_slow_receive(p_adapter_t adapter, PSXG_EVENT Event)
1363 {
1364         PSXG_RCV_DATA_BUFFER_HDR RcvDataBufferHdr;
1365         struct sk_buff *Packet;
1366
1367         RcvDataBufferHdr = (PSXG_RCV_DATA_BUFFER_HDR) Event->HostHandle;
1368         ASSERT(RcvDataBufferHdr);
1369         ASSERT(RcvDataBufferHdr->State == SXG_BUFFER_ONCARD);
1370         ASSERT(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr) ==
1371                RcvDataBufferHdr->VirtualAddress);
1372         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event,
1373                   RcvDataBufferHdr, RcvDataBufferHdr->State,
1374                   RcvDataBufferHdr->VirtualAddress);
1375         /* Drop rcv frames in non-running state */
1376         switch (adapter->State) {
1377         case SXG_STATE_RUNNING:
1378                 break;
1379         case SXG_STATE_PAUSING:
1380         case SXG_STATE_PAUSED:
1381         case SXG_STATE_HALTING:
1382                 goto drop;
1383         default:
1384                 ASSERT(0);
1385                 goto drop;
1386         }
1387
1388         /* Change buffer state to UPSTREAM */
1389         RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;
1390         if (Event->Status & EVENT_STATUS_RCVERR) {
1391                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvError",
1392                           Event, Event->Status, Event->HostHandle, 0);
1393                 /* XXXTODO - Remove this print later */
1394                 DBG_ERROR("SXG: Receive error %x\n", *(u32 *)
1395                           SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr));
1396                 sxg_process_rcv_error(adapter, *(u32 *)
1397                                       SXG_RECEIVE_DATA_LOCATION
1398                                       (RcvDataBufferHdr));
1399                 goto drop;
1400         }
1401 #if XXXTODO                     /* VLAN stuff */
1402         /* If there's a VLAN tag, extract it and validate it */
1403         if (((p_ether_header) (SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->
1404             EtherType == ETHERTYPE_VLAN) {
1405                 if (SxgExtractVlanHeader(adapter, RcvDataBufferHdr, Event) !=
1406                     STATUS_SUCCESS) {
1407                         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY,
1408                                   "BadVlan", Event,
1409                                   SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
1410                                   Event->Length, 0);
1411                         goto drop;
1412                 }
1413         }
1414 #endif
1415         /* */
1416         /* Dumb-nic frame.  See if it passes our mac filter and update stats */
1417         /* */
1418         if (!sxg_mac_filter(adapter, (p_ether_header)
1419                             SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
1420                             Event->Length)) {
1421                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvFiltr",
1422                           Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
1423                           Event->Length, 0);
1424                 goto drop;
1425         }
1426
1427         Packet = RcvDataBufferHdr->SxgDumbRcvPacket;
1428
1429         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumbRcv",
1430                   RcvDataBufferHdr, Packet, Event->Length, 0);
1431         /* */
1432         /* Lastly adjust the receive packet length. */
1433         /* */
1434         SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
1435
1436         return (Packet);
1437
1438       drop:
1439         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DropRcv",
1440                   RcvDataBufferHdr, Event->Length, 0, 0);
1441         adapter->Stats.RcvDiscards++;
1442         spin_lock(&adapter->RcvQLock);
1443         SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
1444         spin_unlock(&adapter->RcvQLock);
1445         return (NULL);
1446 }
1447
1448 /*
1449  * sxg_process_rcv_error - process receive error and update
1450  * stats
1451  *
1452  * Arguments:
1453  *              adapter         - Adapter structure
1454  *              ErrorStatus     - 4-byte receive error status
1455  *
1456  * Return Value:
1457  *      None
1458  */
1459 static void sxg_process_rcv_error(p_adapter_t adapter, u32 ErrorStatus)
1460 {
1461         u32 Error;
1462
1463         adapter->Stats.RcvErrors++;
1464
1465         if (ErrorStatus & SXG_RCV_STATUS_TRANSPORT_ERROR) {
1466                 Error = ErrorStatus & SXG_RCV_STATUS_TRANSPORT_MASK;
1467                 switch (Error) {
1468                 case SXG_RCV_STATUS_TRANSPORT_CSUM:
1469                         adapter->Stats.TransportCsum++;
1470                         break;
1471                 case SXG_RCV_STATUS_TRANSPORT_UFLOW:
1472                         adapter->Stats.TransportUflow++;
1473                         break;
1474                 case SXG_RCV_STATUS_TRANSPORT_HDRLEN:
1475                         adapter->Stats.TransportHdrLen++;
1476                         break;
1477                 }
1478         }
1479         if (ErrorStatus & SXG_RCV_STATUS_NETWORK_ERROR) {
1480                 Error = ErrorStatus & SXG_RCV_STATUS_NETWORK_MASK;
1481                 switch (Error) {
1482                 case SXG_RCV_STATUS_NETWORK_CSUM:
1483                         adapter->Stats.NetworkCsum++;
1484                         break;
1485                 case SXG_RCV_STATUS_NETWORK_UFLOW:
1486                         adapter->Stats.NetworkUflow++;
1487                         break;
1488                 case SXG_RCV_STATUS_NETWORK_HDRLEN:
1489                         adapter->Stats.NetworkHdrLen++;
1490                         break;
1491                 }
1492         }
1493         if (ErrorStatus & SXG_RCV_STATUS_PARITY) {
1494                 adapter->Stats.Parity++;
1495         }
1496         if (ErrorStatus & SXG_RCV_STATUS_LINK_ERROR) {
1497                 Error = ErrorStatus & SXG_RCV_STATUS_LINK_MASK;
1498                 switch (Error) {
1499                 case SXG_RCV_STATUS_LINK_PARITY:
1500                         adapter->Stats.LinkParity++;
1501                         break;
1502                 case SXG_RCV_STATUS_LINK_EARLY:
1503                         adapter->Stats.LinkEarly++;
1504                         break;
1505                 case SXG_RCV_STATUS_LINK_BUFOFLOW:
1506                         adapter->Stats.LinkBufOflow++;
1507                         break;
1508                 case SXG_RCV_STATUS_LINK_CODE:
1509                         adapter->Stats.LinkCode++;
1510                         break;
1511                 case SXG_RCV_STATUS_LINK_DRIBBLE:
1512                         adapter->Stats.LinkDribble++;
1513                         break;
1514                 case SXG_RCV_STATUS_LINK_CRC:
1515                         adapter->Stats.LinkCrc++;
1516                         break;
1517                 case SXG_RCV_STATUS_LINK_OFLOW:
1518                         adapter->Stats.LinkOflow++;
1519                         break;
1520                 case SXG_RCV_STATUS_LINK_UFLOW:
1521                         adapter->Stats.LinkUflow++;
1522                         break;
1523                 }
1524         }
1525 }
1526
1527 /*
1528  * sxg_mac_filter
1529  *
1530  * Arguments:
1531  *              adapter         - Adapter structure
1532  *              pether          - Ethernet header
1533  *              length          - Frame length
1534  *
1535  * Return Value:
1536  *      TRUE if the frame is to be allowed
1537  */
1538 static bool sxg_mac_filter(p_adapter_t adapter, p_ether_header EtherHdr,
1539                            ushort length)
1540 {
1541         bool EqualAddr;
1542
1543         if (SXG_MULTICAST_PACKET(EtherHdr)) {
1544                 if (SXG_BROADCAST_PACKET(EtherHdr)) {
1545                         /* broadcast */
1546                         if (adapter->MacFilter & MAC_BCAST) {
1547                                 adapter->Stats.DumbRcvBcastPkts++;
1548                                 adapter->Stats.DumbRcvBcastBytes += length;
1549                                 adapter->Stats.DumbRcvPkts++;
1550                                 adapter->Stats.DumbRcvBytes += length;
1551                                 return (TRUE);
1552                         }
1553                 } else {
1554                         /* multicast */
1555                         if (adapter->MacFilter & MAC_ALLMCAST) {
1556                                 adapter->Stats.DumbRcvMcastPkts++;
1557                                 adapter->Stats.DumbRcvMcastBytes += length;
1558                                 adapter->Stats.DumbRcvPkts++;
1559                                 adapter->Stats.DumbRcvBytes += length;
1560                                 return (TRUE);
1561                         }
1562                         if (adapter->MacFilter & MAC_MCAST) {
1563                                 PSXG_MULTICAST_ADDRESS MulticastAddrs =
1564                                     adapter->MulticastAddrs;
1565                                 while (MulticastAddrs) {
1566                                         ETHER_EQ_ADDR(MulticastAddrs->Address,
1567                                                       EtherHdr->ether_dhost,
1568                                                       EqualAddr);
1569                                         if (EqualAddr) {
1570                                                 adapter->Stats.
1571                                                     DumbRcvMcastPkts++;
1572                                                 adapter->Stats.
1573                                                     DumbRcvMcastBytes += length;
1574                                                 adapter->Stats.DumbRcvPkts++;
1575                                                 adapter->Stats.DumbRcvBytes +=
1576                                                     length;
1577                                                 return (TRUE);
1578                                         }
1579                                         MulticastAddrs = MulticastAddrs->Next;
1580                                 }
1581                         }
1582                 }
1583         } else if (adapter->MacFilter & MAC_DIRECTED) {
1584                 /* Not broadcast or multicast.  Must be directed at us or */
1585                 /* the card is in promiscuous mode.  Either way, consider it */
1586                 /* ours if MAC_DIRECTED is set */
1587                 adapter->Stats.DumbRcvUcastPkts++;
1588                 adapter->Stats.DumbRcvUcastBytes += length;
1589                 adapter->Stats.DumbRcvPkts++;
1590                 adapter->Stats.DumbRcvBytes += length;
1591                 return (TRUE);
1592         }
1593         if (adapter->MacFilter & MAC_PROMISC) {
1594                 /* Whatever it is, keep it. */
1595                 adapter->Stats.DumbRcvPkts++;
1596                 adapter->Stats.DumbRcvBytes += length;
1597                 return (TRUE);
1598         }
1599         adapter->Stats.RcvDiscards++;
1600         return (FALSE);
1601 }
1602
1603 static int sxg_register_interrupt(p_adapter_t adapter)
1604 {
1605         if (!adapter->intrregistered) {
1606                 int retval;
1607
1608                 DBG_ERROR
1609                     ("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x] %x\n",
1610                      __func__, adapter, adapter->netdev->irq, NR_IRQS);
1611
1612                 spin_unlock_irqrestore(&sxg_global.driver_lock,
1613                                        sxg_global.flags);
1614
1615                 retval = request_irq(adapter->netdev->irq,
1616                                      &sxg_isr,
1617                                      IRQF_SHARED,
1618                                      adapter->netdev->name, adapter->netdev);
1619
1620                 spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
1621
1622                 if (retval) {
1623                         DBG_ERROR("sxg: request_irq (%s) FAILED [%x]\n",
1624                                   adapter->netdev->name, retval);
1625                         return (retval);
1626                 }
1627                 adapter->intrregistered = 1;
1628                 adapter->IntRegistered = TRUE;
1629                 /* Disable RSS with line-based interrupts */
1630                 adapter->MsiEnabled = FALSE;
1631                 adapter->RssEnabled = FALSE;
1632                 DBG_ERROR("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x]\n",
1633                           __func__, adapter, adapter->netdev->irq);
1634         }
1635         return (STATUS_SUCCESS);
1636 }
1637
1638 static void sxg_deregister_interrupt(p_adapter_t adapter)
1639 {
1640         DBG_ERROR("sxg: %s ENTER adapter[%p]\n", __func__, adapter);
1641 #if XXXTODO
1642         slic_init_cleanup(adapter);
1643 #endif
1644         memset(&adapter->stats, 0, sizeof(struct net_device_stats));
1645         adapter->error_interrupts = 0;
1646         adapter->rcv_interrupts = 0;
1647         adapter->xmit_interrupts = 0;
1648         adapter->linkevent_interrupts = 0;
1649         adapter->upr_interrupts = 0;
1650         adapter->num_isrs = 0;
1651         adapter->xmit_completes = 0;
1652         adapter->rcv_broadcasts = 0;
1653         adapter->rcv_multicasts = 0;
1654         adapter->rcv_unicasts = 0;
1655         DBG_ERROR("sxg: %s EXIT\n", __func__);
1656 }
1657
1658 /*
1659  *  sxg_if_init
1660  *
1661  *  Perform initialization of our slic interface.
1662  *
1663  */
1664 static int sxg_if_init(p_adapter_t adapter)
1665 {
1666         p_net_device dev = adapter->netdev;
1667         int status = 0;
1668
1669         DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d:%d] flags[%x]\n",
1670                   __func__, adapter->netdev->name,
1671                   adapter->queues_initialized, adapter->state,
1672                   adapter->linkstate, dev->flags);
1673
1674         /* adapter should be down at this point */
1675         if (adapter->state != ADAPT_DOWN) {
1676                 DBG_ERROR("sxg_if_init adapter->state != ADAPT_DOWN\n");
1677                 return (-EIO);
1678         }
1679         ASSERT(adapter->linkstate == LINK_DOWN);
1680
1681         adapter->devflags_prev = dev->flags;
1682         adapter->macopts = MAC_DIRECTED;
1683         if (dev->flags) {
1684                 DBG_ERROR("sxg: %s (%s) Set MAC options: ", __func__,
1685                           adapter->netdev->name);
1686                 if (dev->flags & IFF_BROADCAST) {
1687                         adapter->macopts |= MAC_BCAST;
1688                         DBG_ERROR("BCAST ");
1689                 }
1690                 if (dev->flags & IFF_PROMISC) {
1691                         adapter->macopts |= MAC_PROMISC;
1692                         DBG_ERROR("PROMISC ");
1693                 }
1694                 if (dev->flags & IFF_ALLMULTI) {
1695                         adapter->macopts |= MAC_ALLMCAST;
1696                         DBG_ERROR("ALL_MCAST ");
1697                 }
1698                 if (dev->flags & IFF_MULTICAST) {
1699                         adapter->macopts |= MAC_MCAST;
1700                         DBG_ERROR("MCAST ");
1701                 }
1702                 DBG_ERROR("\n");
1703         }
1704         status = sxg_register_interrupt(adapter);
1705         if (status != STATUS_SUCCESS) {
1706                 DBG_ERROR("sxg_if_init: sxg_register_interrupt FAILED %x\n",
1707                           status);
1708                 sxg_deregister_interrupt(adapter);
1709                 return (status);
1710         }
1711
1712         adapter->state = ADAPT_UP;
1713
1714         /*
1715          *    clear any pending events, then enable interrupts
1716          */
1717         DBG_ERROR("sxg: %s ENABLE interrupts(slic)\n", __func__);
1718
1719         return (STATUS_SUCCESS);
1720 }
1721
1722 static int sxg_entry_open(p_net_device dev)
1723 {
1724         p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
1725         int status;
1726
1727         ASSERT(adapter);
1728         DBG_ERROR("sxg: %s adapter->activated[%d]\n", __func__,
1729                   adapter->activated);
1730         DBG_ERROR
1731             ("sxg: %s (%s): [jiffies[%lx] cpu %d] dev[%p] adapt[%p] port[%d]\n",
1732              __func__, adapter->netdev->name, jiffies, smp_processor_id(),
1733              adapter->netdev, adapter, adapter->port);
1734
1735         netif_stop_queue(adapter->netdev);
1736
1737         spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
1738         if (!adapter->activated) {
1739                 sxg_global.num_sxg_ports_active++;
1740                 adapter->activated = 1;
1741         }
1742         /* Initialize the adapter */
1743         DBG_ERROR("sxg: %s ENTER sxg_initialize_adapter\n", __func__);
1744         status = sxg_initialize_adapter(adapter);
1745         DBG_ERROR("sxg: %s EXIT sxg_initialize_adapter status[%x]\n",
1746                   __func__, status);
1747
1748         if (status == STATUS_SUCCESS) {
1749                 DBG_ERROR("sxg: %s ENTER sxg_if_init\n", __func__);
1750                 status = sxg_if_init(adapter);
1751                 DBG_ERROR("sxg: %s EXIT sxg_if_init status[%x]\n", __func__,
1752                           status);
1753         }
1754
1755         if (status != STATUS_SUCCESS) {
1756                 if (adapter->activated) {
1757                         sxg_global.num_sxg_ports_active--;
1758                         adapter->activated = 0;
1759                 }
1760                 spin_unlock_irqrestore(&sxg_global.driver_lock,
1761                                        sxg_global.flags);
1762                 return (status);
1763         }
1764         DBG_ERROR("sxg: %s ENABLE ALL INTERRUPTS\n", __func__);
1765
1766         /* Enable interrupts */
1767         SXG_ENABLE_ALL_INTERRUPTS(adapter);
1768
1769         DBG_ERROR("sxg: %s EXIT\n", __func__);
1770
1771         spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
1772         return STATUS_SUCCESS;
1773 }
1774
1775 static void __devexit sxg_entry_remove(struct pci_dev *pcidev)
1776 {
1777         p_net_device dev = pci_get_drvdata(pcidev);
1778         u32 mmio_start = 0;
1779         unsigned int mmio_len = 0;
1780         p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
1781
1782         ASSERT(adapter);
1783         DBG_ERROR("sxg: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
1784                   adapter);
1785         sxg_deregister_interrupt(adapter);
1786         sxg_unmap_mmio_space(adapter);
1787         DBG_ERROR("sxg: %s unregister_netdev\n", __func__);
1788         unregister_netdev(dev);
1789
1790         mmio_start = pci_resource_start(pcidev, 0);
1791         mmio_len = pci_resource_len(pcidev, 0);
1792
1793         DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __func__,
1794                   mmio_start, mmio_len);
1795         release_mem_region(mmio_start, mmio_len);
1796
1797         DBG_ERROR("sxg: %s iounmap dev->base_addr[%x]\n", __func__,
1798                   (unsigned int)dev->base_addr);
1799         iounmap((char *)dev->base_addr);
1800
1801         DBG_ERROR("sxg: %s deallocate device\n", __func__);
1802         kfree(dev);
1803         DBG_ERROR("sxg: %s EXIT\n", __func__);
1804 }
1805
1806 static int sxg_entry_halt(p_net_device dev)
1807 {
1808         p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
1809
1810         spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
1811         DBG_ERROR("sxg: %s (%s) ENTER\n", __func__, dev->name);
1812
1813         netif_stop_queue(adapter->netdev);
1814         adapter->state = ADAPT_DOWN;
1815         adapter->linkstate = LINK_DOWN;
1816         adapter->devflags_prev = 0;
1817         DBG_ERROR("sxg: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
1818                   __func__, dev->name, adapter, adapter->state);
1819
1820         DBG_ERROR("sxg: %s (%s) EXIT\n", __func__, dev->name);
1821         DBG_ERROR("sxg: %s EXIT\n", __func__);
1822         spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
1823         return (STATUS_SUCCESS);
1824 }
1825
1826 static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
1827 {
1828         ASSERT(rq);
1829 /*      DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev); */
1830         switch (cmd) {
1831         case SIOCSLICSETINTAGG:
1832                 {
1833 /*                      p_adapter_t adapter = (p_adapter_t) netdev_priv(dev); */
1834                         u32 data[7];
1835                         u32 intagg;
1836
1837                         if (copy_from_user(data, rq->ifr_data, 28)) {
1838                                 DBG_ERROR
1839                                     ("copy_from_user FAILED  getting initial params\n");
1840                                 return -EFAULT;
1841                         }
1842                         intagg = data[0];
1843                         printk(KERN_EMERG
1844                                "%s: set interrupt aggregation to %d\n",
1845                                __func__, intagg);
1846                         return 0;
1847                 }
1848
1849         default:
1850 /*              DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */
1851                 return -EOPNOTSUPP;
1852         }
1853         return 0;
1854 }
1855
1856 #define NORMAL_ETHFRAME     0
1857
1858 /*
1859  *
1860  * sxg_send_packets - Send a skb packet
1861  *
1862  * Arguments:
1863  *                      skb                     - The packet to send
1864  *                      dev                     - Our linux net device that refs our adapter
1865  *
1866  * Return:
1867  *              0   regardless of outcome    XXXTODO refer to e1000 driver
1868  */
1869 static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
1870 {
1871         p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
1872         u32 status = STATUS_SUCCESS;
1873
1874         DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __func__,
1875                   skb);
1876         /* Check the adapter state */
1877         switch (adapter->State) {
1878         case SXG_STATE_INITIALIZING:
1879         case SXG_STATE_HALTED:
1880         case SXG_STATE_SHUTDOWN:
1881                 ASSERT(0);      /* unexpected */
1882                 /* fall through */
1883         case SXG_STATE_RESETTING:
1884         case SXG_STATE_SLEEP:
1885         case SXG_STATE_BOOTDIAG:
1886         case SXG_STATE_DIAG:
1887         case SXG_STATE_HALTING:
1888                 status = STATUS_FAILURE;
1889                 break;
1890         case SXG_STATE_RUNNING:
1891                 if (adapter->LinkState != SXG_LINK_UP) {
1892                         status = STATUS_FAILURE;
1893                 }
1894                 break;
1895         default:
1896                 ASSERT(0);
1897                 status = STATUS_FAILURE;
1898         }
1899         if (status != STATUS_SUCCESS) {
1900                 goto xmit_fail;
1901         }
1902         /* send a packet */
1903         status = sxg_transmit_packet(adapter, skb);
1904         if (status == STATUS_SUCCESS) {
1905                 goto xmit_done;
1906         }
1907
1908       xmit_fail:
1909         /* reject & complete all the packets if they cant be sent */
1910         if (status != STATUS_SUCCESS) {
1911 #if XXXTODO
1912 /*      sxg_send_packets_fail(adapter, skb, status); */
1913 #else
1914                 SXG_DROP_DUMB_SEND(adapter, skb);
1915                 adapter->stats.tx_dropped++;
1916 #endif
1917         }
1918         DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __func__,
1919                   status);
1920
1921       xmit_done:
1922         return 0;
1923 }
1924
1925 /*
1926  * sxg_transmit_packet
1927  *
1928  * This function transmits a single packet.
1929  *
1930  * Arguments -
1931  *              adapter                 - Pointer to our adapter structure
1932  *      skb             - The packet to be sent
1933  *
1934  * Return -
1935  *              STATUS of send
1936  */
1937 static int sxg_transmit_packet(p_adapter_t adapter, struct sk_buff *skb)
1938 {
1939         PSCATTER_GATHER_LIST pSgl;
1940         PSXG_SCATTER_GATHER SxgSgl;
1941         void *SglBuffer;
1942         u32 SglBufferLength;
1943
1944         /* The vast majority of work is done in the shared */
1945         /* sxg_dumb_sgl routine. */
1946         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSend",
1947                   adapter, skb, 0, 0);
1948
1949         /* Allocate a SGL buffer */
1950         SXG_GET_SGL_BUFFER(adapter, SxgSgl);
1951         if (!SxgSgl) {
1952                 adapter->Stats.NoSglBuf++;
1953                 adapter->Stats.XmtErrors++;
1954                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "SndPktF1",
1955                           adapter, skb, 0, 0);
1956                 return (STATUS_RESOURCES);
1957         }
1958         ASSERT(SxgSgl->adapter == adapter);
1959         SglBuffer = SXG_SGL_BUFFER(SxgSgl);
1960         SglBufferLength = SXG_SGL_BUF_SIZE;
1961         SxgSgl->VlanTag.VlanTci = 0;
1962         SxgSgl->VlanTag.VlanTpid = 0;
1963         SxgSgl->Type = SXG_SGL_DUMB;
1964         SxgSgl->DumbPacket = skb;
1965         pSgl = NULL;
1966
1967         /* Call the common sxg_dumb_sgl routine to complete the send. */
1968         sxg_dumb_sgl(pSgl, SxgSgl);
1969         /* Return success   sxg_dumb_sgl (or something later) will complete it. */
1970         return (STATUS_SUCCESS);
1971 }
1972
1973 /*
1974  * sxg_dumb_sgl
1975  *
1976  * Arguments:
1977  *              pSgl     -
1978  *              SxgSgl   - SXG_SCATTER_GATHER
1979  *
1980  * Return Value:
1981  *      None.
1982  */
1983 static void sxg_dumb_sgl(PSCATTER_GATHER_LIST pSgl, PSXG_SCATTER_GATHER SxgSgl)
1984 {
1985         p_adapter_t adapter = SxgSgl->adapter;
1986         struct sk_buff *skb = SxgSgl->DumbPacket;
1987         /* For now, all dumb-nic sends go on RSS queue zero */
1988         PSXG_XMT_RING XmtRing = &adapter->XmtRings[0];
1989         PSXG_RING_INFO XmtRingInfo = &adapter->XmtRingZeroInfo;
1990         PSXG_CMD XmtCmd = NULL;
1991 /*      u32                         Index = 0; */
1992         u32 DataLength = skb->len;
1993 /*  unsigned int                                BufLen; */
1994 /*      u32                         SglOffset; */
1995         u64 phys_addr;
1996
1997         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
1998                   pSgl, SxgSgl, 0, 0);
1999
2000         /* Set aside a pointer to the sgl */
2001         SxgSgl->pSgl = pSgl;
2002
2003         /* Sanity check that our SGL format is as we expect. */
2004         ASSERT(sizeof(SXG_X64_SGE) == sizeof(SCATTER_GATHER_ELEMENT));
2005         /* Shouldn't be a vlan tag on this frame */
2006         ASSERT(SxgSgl->VlanTag.VlanTci == 0);
2007         ASSERT(SxgSgl->VlanTag.VlanTpid == 0);
2008
2009         /* From here below we work with the SGL placed in our */
2010         /* buffer. */
2011
2012         SxgSgl->Sgl.NumberOfElements = 1;
2013
2014         /* Grab the spinlock and acquire a command */
2015         spin_lock(&adapter->XmtZeroLock);
2016         SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
2017         if (XmtCmd == NULL) {
2018                 /* Call sxg_complete_slow_send to see if we can */
2019                 /* free up any XmtRingZero entries and then try again */
2020                 spin_unlock(&adapter->XmtZeroLock);
2021                 sxg_complete_slow_send(adapter);
2022                 spin_lock(&adapter->XmtZeroLock);
2023                 SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
2024                 if (XmtCmd == NULL) {
2025                         adapter->Stats.XmtZeroFull++;
2026                         goto abortcmd;
2027                 }
2028         }
2029         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd",
2030                   XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
2031         /* Update stats */
2032         adapter->Stats.DumbXmtPkts++;
2033         adapter->Stats.DumbXmtBytes += DataLength;
2034 #if XXXTODO                     /* Stats stuff */
2035         if (SXG_MULTICAST_PACKET(EtherHdr)) {
2036                 if (SXG_BROADCAST_PACKET(EtherHdr)) {
2037                         adapter->Stats.DumbXmtBcastPkts++;
2038                         adapter->Stats.DumbXmtBcastBytes += DataLength;
2039                 } else {
2040                         adapter->Stats.DumbXmtMcastPkts++;
2041                         adapter->Stats.DumbXmtMcastBytes += DataLength;
2042                 }
2043         } else {
2044                 adapter->Stats.DumbXmtUcastPkts++;
2045                 adapter->Stats.DumbXmtUcastBytes += DataLength;
2046         }
2047 #endif
2048         /* Fill in the command */
2049         /* Copy out the first SGE to the command and adjust for offset */
2050         phys_addr =
2051             pci_map_single(adapter->pcidev, skb->data, skb->len,
2052                            PCI_DMA_TODEVICE);
2053         XmtCmd->Buffer.FirstSgeAddress = SXG_GET_ADDR_HIGH(phys_addr);
2054         XmtCmd->Buffer.FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress << 32;
2055         XmtCmd->Buffer.FirstSgeAddress =
2056             XmtCmd->Buffer.FirstSgeAddress | SXG_GET_ADDR_LOW(phys_addr);
2057 /*      XmtCmd->Buffer.FirstSgeAddress = SxgSgl->Sgl.Elements[Index].Address; */
2058 /*      XmtCmd->Buffer.FirstSgeAddress.LowPart += MdlOffset; */
2059         XmtCmd->Buffer.FirstSgeLength = DataLength;
2060         /* Set a pointer to the remaining SGL entries */
2061 /*      XmtCmd->Sgl = SxgSgl->PhysicalAddress; */
2062         /* Advance the physical address of the SxgSgl structure to */
2063         /* the second SGE */
2064 /*      SglOffset = (u32)((u32 *)(&SxgSgl->Sgl.Elements[Index+1]) - */
2065 /*                                              (u32 *)SxgSgl); */
2066 /*      XmtCmd->Sgl.LowPart += SglOffset; */
2067         XmtCmd->Buffer.SgeOffset = 0;
2068         /* Note - TotalLength might be overwritten with MSS below.. */
2069         XmtCmd->Buffer.TotalLength = DataLength;
2070         XmtCmd->SgEntries = 1;  /*(ushort)(SxgSgl->Sgl.NumberOfElements - Index); */
2071         XmtCmd->Flags = 0;
2072         /* */
2073         /* Advance transmit cmd descripter by 1. */
2074         /* NOTE - See comments in SxgTcpOutput where we write */
2075         /* to the XmtCmd register regarding CPU ID values and/or */
2076         /* multiple commands. */
2077         /* */
2078         /* */
2079         WRITE_REG(adapter->UcodeRegs[0].XmtCmd, 1, TRUE);
2080         /* */
2081         /* */
2082         adapter->Stats.XmtQLen++;       /* Stats within lock */
2083         spin_unlock(&adapter->XmtZeroLock);
2084         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2",
2085                   XmtCmd, pSgl, SxgSgl, 0);
2086         return;
2087
2088       abortcmd:
2089         /* NOTE - Only jump to this label AFTER grabbing the */
2090         /* XmtZeroLock, and DO NOT DROP IT between the */
2091         /* command allocation and the following abort. */
2092         if (XmtCmd) {
2093                 SXG_ABORT_CMD(XmtRingInfo);
2094         }
2095         spin_unlock(&adapter->XmtZeroLock);
2096
2097 /* failsgl: */
2098         /* Jump to this label if failure occurs before the */
2099         /* XmtZeroLock is grabbed */
2100         adapter->Stats.XmtErrors++;
2101         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal",
2102                   pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail);
2103
2104         SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket);    /* SxgSgl->DumbPacket is the skb */
2105 }
2106
2107 /***************************************************************
2108  * Link management functions
2109  ***************************************************************/
2110
2111 /*
2112  * sxg_initialize_link - Initialize the link stuff
2113  *
2114  * Arguments -
2115  *      adapter         - A pointer to our adapter structure
2116  *
2117  * Return
2118  *      status
2119  */
2120 static int sxg_initialize_link(p_adapter_t adapter)
2121 {
2122         PSXG_HW_REGS HwRegs = adapter->HwRegs;
2123         u32 Value;
2124         u32 ConfigData;
2125         u32 MaxFrame;
2126         int status;
2127
2128         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitLink",
2129                   adapter, 0, 0, 0);
2130
2131         /* Reset PHY and XGXS module */
2132         WRITE_REG(HwRegs->LinkStatus, LS_SERDES_POWER_DOWN, TRUE);
2133
2134         /* Reset transmit configuration register */
2135         WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_RESET, TRUE);
2136
2137         /* Reset receive configuration register */
2138         WRITE_REG(HwRegs->RcvConfig, RCV_CONFIG_RESET, TRUE);
2139
2140         /* Reset all MAC modules */
2141         WRITE_REG(HwRegs->MacConfig0, AXGMAC_CFG0_SUB_RESET, TRUE);
2142
2143         /* Link address 0 */
2144         /* XXXTODO - This assumes the MAC address (0a:0b:0c:0d:0e:0f) */
2145         /* is stored with the first nibble (0a) in the byte 0 */
2146         /* of the Mac address.  Possibly reverse? */
2147         Value = *(u32 *) adapter->MacAddr;
2148         WRITE_REG(HwRegs->LinkAddress0Low, Value, TRUE);
2149         /* also write the MAC address to the MAC.  Endian is reversed. */
2150         WRITE_REG(HwRegs->MacAddressLow, ntohl(Value), TRUE);
2151         Value = (*(u16 *) & adapter->MacAddr[4] & 0x0000FFFF);
2152         WRITE_REG(HwRegs->LinkAddress0High, Value | LINK_ADDRESS_ENABLE, TRUE);
2153         /* endian swap for the MAC (put high bytes in bits [31:16], swapped) */
2154         Value = ntohl(Value);
2155         WRITE_REG(HwRegs->MacAddressHigh, Value, TRUE);
2156         /* Link address 1 */
2157         WRITE_REG(HwRegs->LinkAddress1Low, 0, TRUE);
2158         WRITE_REG(HwRegs->LinkAddress1High, 0, TRUE);
2159         /* Link address 2 */
2160         WRITE_REG(HwRegs->LinkAddress2Low, 0, TRUE);
2161         WRITE_REG(HwRegs->LinkAddress2High, 0, TRUE);
2162         /* Link address 3 */
2163         WRITE_REG(HwRegs->LinkAddress3Low, 0, TRUE);
2164         WRITE_REG(HwRegs->LinkAddress3High, 0, TRUE);
2165
2166         /* Enable MAC modules */
2167         WRITE_REG(HwRegs->MacConfig0, 0, TRUE);
2168
2169         /* Configure MAC */
2170         WRITE_REG(HwRegs->MacConfig1, (AXGMAC_CFG1_XMT_PAUSE |  /* Allow sending of pause */
2171                                        AXGMAC_CFG1_XMT_EN |     /* Enable XMT */
2172                                        AXGMAC_CFG1_RCV_PAUSE |  /* Enable detection of pause */
2173                                        AXGMAC_CFG1_RCV_EN |     /* Enable receive */
2174                                        AXGMAC_CFG1_SHORT_ASSERT |       /* short frame detection */
2175                                        AXGMAC_CFG1_CHECK_LEN |  /* Verify frame length */
2176                                        AXGMAC_CFG1_GEN_FCS |    /* Generate FCS */
2177                                        AXGMAC_CFG1_PAD_64),     /* Pad frames to 64 bytes */
2178                   TRUE);
2179
2180         /* Set AXGMAC max frame length if jumbo.  Not needed for standard MTU */
2181         if (adapter->JumboEnabled) {
2182                 WRITE_REG(HwRegs->MacMaxFrameLen, AXGMAC_MAXFRAME_JUMBO, TRUE);
2183         }
2184         /* AMIIM Configuration Register - */
2185         /* The value placed in the AXGMAC_AMIIM_CFG_HALF_CLOCK portion */
2186         /* (bottom bits) of this register is used to determine the */
2187         /* MDC frequency as specified in the A-XGMAC Design Document. */
2188         /* This value must not be zero.  The following value (62 or 0x3E) */
2189         /* is based on our MAC transmit clock frequency (MTCLK) of 312.5 MHz. */
2190         /* Given a maximum MDIO clock frequency of 2.5 MHz (see the PHY spec), */
2191         /* we get:  312.5/(2*(X+1)) < 2.5  ==> X = 62. */
2192         /* This value happens to be the default value for this register, */
2193         /* so we really don't have to do this. */
2194         WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE);
2195
2196         /* Power up and enable PHY and XAUI/XGXS/Serdes logic */
2197         WRITE_REG(HwRegs->LinkStatus,
2198                   (LS_PHY_CLR_RESET |
2199                    LS_XGXS_ENABLE |
2200                    LS_XGXS_CTL | LS_PHY_CLK_EN | LS_ATTN_ALARM), TRUE);
2201         DBG_ERROR("After Power Up and enable PHY in sxg_initialize_link\n");
2202
2203         /* Per information given by Aeluros, wait 100 ms after removing reset. */
2204         /* It's not enough to wait for the self-clearing reset bit in reg 0 to clear. */
2205         mdelay(100);
2206
2207         /* Verify the PHY has come up by checking that the Reset bit has cleared. */
2208         status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   /* PHY PMA/PMD module */
2209                                    PHY_PMA_CONTROL1,    /* PMA/PMD control register */
2210                                    &Value);
2211         if (status != STATUS_SUCCESS)
2212                 return (STATUS_FAILURE);
2213         if (Value & PMA_CONTROL1_RESET) /* reset complete if bit is 0 */
2214                 return (STATUS_FAILURE);
2215
2216         /* The SERDES should be initialized by now - confirm */
2217         READ_REG(HwRegs->LinkStatus, Value);
2218         if (Value & LS_SERDES_DOWN)     /* verify SERDES is initialized */
2219                 return (STATUS_FAILURE);
2220
2221         /* The XAUI link should also be up - confirm */
2222         if (!(Value & LS_XAUI_LINK_UP)) /* verify XAUI link is up */
2223                 return (STATUS_FAILURE);
2224
2225         /* Initialize the PHY */
2226         status = sxg_phy_init(adapter);
2227         if (status != STATUS_SUCCESS)
2228                 return (STATUS_FAILURE);
2229
2230         /* Enable the Link Alarm */
2231         status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,  /* PHY PMA/PMD module */
2232                                     LASI_CONTROL,       /* LASI control register */
2233                                     LASI_CTL_LS_ALARM_ENABLE);  /* enable link alarm bit */
2234         if (status != STATUS_SUCCESS)
2235                 return (STATUS_FAILURE);
2236
2237         /* XXXTODO - temporary - verify bit is set */
2238         status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   /* PHY PMA/PMD module */
2239                                    LASI_CONTROL,        /* LASI control register */
2240                                    &Value);
2241         if (status != STATUS_SUCCESS)
2242                 return (STATUS_FAILURE);
2243         if (!(Value & LASI_CTL_LS_ALARM_ENABLE)) {
2244                 DBG_ERROR("Error!  LASI Control Alarm Enable bit not set!\n");
2245         }
2246         /* Enable receive */
2247         MaxFrame = adapter->JumboEnabled ? JUMBOMAXFRAME : ETHERMAXFRAME;
2248         ConfigData = (RCV_CONFIG_ENABLE |
2249                       RCV_CONFIG_ENPARSE |
2250                       RCV_CONFIG_RCVBAD |
2251                       RCV_CONFIG_RCVPAUSE |
2252                       RCV_CONFIG_TZIPV6 |
2253                       RCV_CONFIG_TZIPV4 |
2254                       RCV_CONFIG_HASH_16 |
2255                       RCV_CONFIG_SOCKET | RCV_CONFIG_BUFSIZE(MaxFrame));
2256         WRITE_REG(HwRegs->RcvConfig, ConfigData, TRUE);
2257
2258         WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_ENABLE, TRUE);
2259
2260         /* Mark the link as down.  We'll get a link event when it comes up. */
2261         sxg_link_state(adapter, SXG_LINK_DOWN);
2262
2263         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInitLnk",
2264                   adapter, 0, 0, 0);
2265         return (STATUS_SUCCESS);
2266 }
2267
2268 /*
2269  * sxg_phy_init - Initialize the PHY
2270  *
2271  * Arguments -
2272  *      adapter         - A pointer to our adapter structure
2273  *
2274  * Return
2275  *      status
2276  */
2277 static int sxg_phy_init(p_adapter_t adapter)
2278 {
2279         u32 Value;
2280         PPHY_UCODE p;
2281         int status;
2282
2283         DBG_ERROR("ENTER %s\n", __func__);
2284
2285         /* Read a register to identify the PHY type */
2286         status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   /* PHY PMA/PMD module */
2287                                    0xC205,      /* PHY ID register (?) */
2288                                    &Value);     /*    XXXTODO - add def */
2289         if (status != STATUS_SUCCESS)
2290                 return (STATUS_FAILURE);
2291
2292         if (Value == 0x0012) {  /* 0x0012 == AEL2005C PHY(?) - XXXTODO - add def */
2293                 DBG_ERROR
2294                     ("AEL2005C PHY detected.  Downloading PHY microcode.\n");
2295
2296                 /* Initialize AEL2005C PHY and download PHY microcode */
2297                 for (p = PhyUcode; p->Addr != 0xFFFF; p++) {
2298                         if (p->Addr == 0) {
2299                                 /* if address == 0, data == sleep time in ms */
2300                                 mdelay(p->Data);
2301                         } else {
2302                                 /* write the given data to the specified address */
2303                                 status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,  /* PHY PMA/PMD module */
2304                                                             p->Addr,    /* PHY address */
2305                                                             p->Data);   /* PHY data */
2306                                 if (status != STATUS_SUCCESS)
2307                                         return (STATUS_FAILURE);
2308                         }
2309                 }
2310         }
2311         DBG_ERROR("EXIT %s\n", __func__);
2312
2313         return (STATUS_SUCCESS);
2314 }
2315
2316 /*
2317  * sxg_link_event - Process a link event notification from the card
2318  *
2319  * Arguments -
2320  *      adapter         - A pointer to our adapter structure
2321  *
2322  * Return
2323  *      None
2324  */
2325 static void sxg_link_event(p_adapter_t adapter)
2326 {
2327         PSXG_HW_REGS HwRegs = adapter->HwRegs;
2328         SXG_LINK_STATE LinkState;
2329         int status;
2330         u32 Value;
2331
2332         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "LinkEvnt",
2333                   adapter, 0, 0, 0);
2334         DBG_ERROR("ENTER %s\n", __func__);
2335
2336         /* Check the Link Status register.  We should have a Link Alarm. */
2337         READ_REG(HwRegs->LinkStatus, Value);
2338         if (Value & LS_LINK_ALARM) {
2339                 /* We got a Link Status alarm.  First, pause to let the */
2340                 /* link state settle (it can bounce a number of times) */
2341                 mdelay(10);
2342
2343                 /* Now clear the alarm by reading the LASI status register. */
2344                 status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   /* PHY PMA/PMD module */
2345                                            LASI_STATUS, /* LASI status register */
2346                                            &Value);
2347                 if (status != STATUS_SUCCESS) {
2348                         DBG_ERROR("Error reading LASI Status MDIO register!\n");
2349                         sxg_link_state(adapter, SXG_LINK_DOWN);
2350 /*                      ASSERT(0); */
2351                 }
2352                 ASSERT(Value & LASI_STATUS_LS_ALARM);
2353
2354                 /* Now get and set the link state */
2355                 LinkState = sxg_get_link_state(adapter);
2356                 sxg_link_state(adapter, LinkState);
2357                 DBG_ERROR("SXG: Link Alarm occurred.  Link is %s\n",
2358                           ((LinkState == SXG_LINK_UP) ? "UP" : "DOWN"));
2359         } else {
2360                 /* XXXTODO - Assuming Link Attention is only being generated for the */
2361                 /* Link Alarm pin (and not for a XAUI Link Status change), then it's */
2362                 /* impossible to get here.  Yet we've gotten here twice (under extreme */
2363                 /* conditions - bouncing the link up and down many times a second). */
2364                 /* Needs further investigation. */
2365                 DBG_ERROR("SXG: sxg_link_event: Can't get here!\n");
2366                 DBG_ERROR("SXG: Link Status == 0x%08X.\n", Value);
2367 /*              ASSERT(0); */
2368         }
2369         DBG_ERROR("EXIT %s\n", __func__);
2370
2371 }
2372
2373 /*
2374  * sxg_get_link_state - Determine if the link is up or down
2375  *
2376  * Arguments -
2377  *      adapter         - A pointer to our adapter structure
2378  *
2379  * Return
2380  *      Link State
2381  */
2382 static SXG_LINK_STATE sxg_get_link_state(p_adapter_t adapter)
2383 {
2384         int status;
2385         u32 Value;
2386
2387         DBG_ERROR("ENTER %s\n", __func__);
2388
2389         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "GetLink",
2390                   adapter, 0, 0, 0);
2391
2392         /* Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if */
2393         /* the following 3 bits (from 3 different MDIO registers) are all true. */
2394         status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   /* PHY PMA/PMD module */
2395                                    PHY_PMA_RCV_DET,     /* PMA/PMD Receive Signal Detect register */
2396                                    &Value);
2397         if (status != STATUS_SUCCESS)
2398                 goto bad;
2399
2400         /* If PMA/PMD receive signal detect is 0, then the link is down */
2401         if (!(Value & PMA_RCV_DETECT))
2402                 return (SXG_LINK_DOWN);
2403
2404         status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS,   /* PHY PCS module */
2405                                    PHY_PCS_10G_STATUS1, /* PCS 10GBASE-R Status 1 register */
2406                                    &Value);
2407         if (status != STATUS_SUCCESS)
2408                 goto bad;
2409
2410         /* If PCS is not locked to receive blocks, then the link is down */
2411         if (!(Value & PCS_10B_BLOCK_LOCK))
2412                 return (SXG_LINK_DOWN);
2413
2414         status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS,    /* PHY XS module */
2415                                    PHY_XS_LANE_STATUS,  /* XS Lane Status register */
2416                                    &Value);
2417         if (status != STATUS_SUCCESS)
2418                 goto bad;
2419
2420         /* If XS transmit lanes are not aligned, then the link is down */
2421         if (!(Value & XS_LANE_ALIGN))
2422                 return (SXG_LINK_DOWN);
2423
2424         /* All 3 bits are true, so the link is up */
2425         DBG_ERROR("EXIT %s\n", __func__);
2426
2427         return (SXG_LINK_UP);
2428
2429       bad:
2430         /* An error occurred reading an MDIO register.  This shouldn't happen. */
2431         DBG_ERROR("Error reading an MDIO register!\n");
2432         ASSERT(0);
2433         return (SXG_LINK_DOWN);
2434 }
2435
2436 static void sxg_indicate_link_state(p_adapter_t adapter,
2437                                     SXG_LINK_STATE LinkState)
2438 {
2439         if (adapter->LinkState == SXG_LINK_UP) {
2440                 DBG_ERROR("%s: LINK now UP, call netif_start_queue\n",
2441                           __func__);
2442                 netif_start_queue(adapter->netdev);
2443         } else {
2444                 DBG_ERROR("%s: LINK now DOWN, call netif_stop_queue\n",
2445                           __func__);
2446                 netif_stop_queue(adapter->netdev);
2447         }
2448 }
2449
2450 /*
2451  * sxg_link_state - Set the link state and if necessary, indicate.
2452  *      This routine the central point of processing for all link state changes.
2453  *      Nothing else in the driver should alter the link state or perform
2454  *      link state indications
2455  *
2456  * Arguments -
2457  *      adapter         - A pointer to our adapter structure
2458  *      LinkState       - The link state
2459  *
2460  * Return
2461  *      None
2462  */
2463 static void sxg_link_state(p_adapter_t adapter, SXG_LINK_STATE LinkState)
2464 {
2465         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "LnkINDCT",
2466                   adapter, LinkState, adapter->LinkState, adapter->State);
2467
2468         DBG_ERROR("ENTER %s\n", __func__);
2469
2470         /* Hold the adapter lock during this routine.  Maybe move */
2471         /* the lock to the caller. */
2472         spin_lock(&adapter->AdapterLock);
2473         if (LinkState == adapter->LinkState) {
2474                 /* Nothing changed.. */
2475                 spin_unlock(&adapter->AdapterLock);
2476                 DBG_ERROR("EXIT #0 %s\n", __func__);
2477                 return;
2478         }
2479         /* Save the adapter state */
2480         adapter->LinkState = LinkState;
2481
2482         /* Drop the lock and indicate link state */
2483         spin_unlock(&adapter->AdapterLock);
2484         DBG_ERROR("EXIT #1 %s\n", __func__);
2485
2486         sxg_indicate_link_state(adapter, LinkState);
2487 }
2488
2489 /*
2490  * sxg_write_mdio_reg - Write to a register on the MDIO bus
2491  *
2492  * Arguments -
2493  *      adapter         - A pointer to our adapter structure
2494  *  DevAddr     - MDIO device number being addressed
2495  *  RegAddr     - register address for the specified MDIO device
2496  *  Value               - value to write to the MDIO register
2497  *
2498  * Return
2499  *      status
2500  */
2501 static int sxg_write_mdio_reg(p_adapter_t adapter,
2502                               u32 DevAddr, u32 RegAddr, u32 Value)
2503 {
2504         PSXG_HW_REGS HwRegs = adapter->HwRegs;
2505         u32 AddrOp;             /* Address operation (written to MIIM field reg) */
2506         u32 WriteOp;            /* Write operation (written to MIIM field reg) */
2507         u32 Cmd;                /* Command (written to MIIM command reg) */
2508         u32 ValueRead;
2509         u32 Timeout;
2510
2511 /*  DBG_ERROR("ENTER %s\n", __func__); */
2512
2513         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
2514                   adapter, 0, 0, 0);
2515
2516         /* Ensure values don't exceed field width */
2517         DevAddr &= 0x001F;      /* 5-bit field */
2518         RegAddr &= 0xFFFF;      /* 16-bit field */
2519         Value &= 0xFFFF;        /* 16-bit field */
2520
2521         /* Set MIIM field register bits for an MIIM address operation */
2522         AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
2523             (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
2524             (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
2525             (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr;
2526
2527         /* Set MIIM field register bits for an MIIM write operation */
2528         WriteOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
2529             (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
2530             (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
2531             (MIIM_OP_WRITE << AXGMAC_AMIIM_FIELD_OP_SHIFT) | Value;
2532
2533         /* Set MIIM command register bits to execute an MIIM command */
2534         Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION;
2535
2536         /* Reset the command register command bit (in case it's not 0) */
2537         WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
2538
2539         /* MIIM write to set the address of the specified MDIO register */
2540         WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE);
2541
2542         /* Write to MIIM Command Register to execute to address operation */
2543         WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
2544
2545         /* Poll AMIIM Indicator register to wait for completion */
2546         Timeout = SXG_LINK_TIMEOUT;
2547         do {
2548                 udelay(100);    /* Timeout in 100us units */
2549                 READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
2550                 if (--Timeout == 0) {
2551                         return (STATUS_FAILURE);
2552                 }
2553         } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
2554
2555         /* Reset the command register command bit */
2556         WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
2557
2558         /* MIIM write to set up an MDIO write operation */
2559         WRITE_REG(HwRegs->MacAmiimField, WriteOp, TRUE);
2560
2561         /* Write to MIIM Command Register to execute the write operation */
2562         WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
2563
2564         /* Poll AMIIM Indicator register to wait for completion */
2565         Timeout = SXG_LINK_TIMEOUT;
2566         do {
2567                 udelay(100);    /* Timeout in 100us units */
2568                 READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
2569                 if (--Timeout == 0) {
2570                         return (STATUS_FAILURE);
2571                 }
2572         } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
2573
2574 /*  DBG_ERROR("EXIT %s\n", __func__); */
2575
2576         return (STATUS_SUCCESS);
2577 }
2578
2579 /*
2580  * sxg_read_mdio_reg - Read a register on the MDIO bus
2581  *
2582  * Arguments -
2583  *      adapter         - A pointer to our adapter structure
2584  *  DevAddr     - MDIO device number being addressed
2585  *  RegAddr     - register address for the specified MDIO device
2586  *  pValue              - pointer to where to put data read from the MDIO register
2587  *
2588  * Return
2589  *      status
2590  */
2591 static int sxg_read_mdio_reg(p_adapter_t adapter,
2592                              u32 DevAddr, u32 RegAddr, u32 *pValue)
2593 {
2594         PSXG_HW_REGS HwRegs = adapter->HwRegs;
2595         u32 AddrOp;             /* Address operation (written to MIIM field reg) */
2596         u32 ReadOp;             /* Read operation (written to MIIM field reg) */
2597         u32 Cmd;                /* Command (written to MIIM command reg) */
2598         u32 ValueRead;
2599         u32 Timeout;
2600
2601         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
2602                   adapter, 0, 0, 0);
2603 /*  DBG_ERROR("ENTER %s\n", __func__); */
2604
2605         /* Ensure values don't exceed field width */
2606         DevAddr &= 0x001F;      /* 5-bit field */
2607         RegAddr &= 0xFFFF;      /* 16-bit field */
2608
2609         /* Set MIIM field register bits for an MIIM address operation */
2610         AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
2611             (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
2612             (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
2613             (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr;
2614
2615         /* Set MIIM field register bits for an MIIM read operation */
2616         ReadOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
2617             (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
2618             (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
2619             (MIIM_OP_READ << AXGMAC_AMIIM_FIELD_OP_SHIFT);
2620
2621         /* Set MIIM command register bits to execute an MIIM command */
2622         Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION;
2623
2624         /* Reset the command register command bit (in case it's not 0) */
2625         WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
2626
2627         /* MIIM write to set the address of the specified MDIO register */
2628         WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE);
2629
2630         /* Write to MIIM Command Register to execute to address operation */
2631         WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
2632
2633         /* Poll AMIIM Indicator register to wait for completion */
2634         Timeout = SXG_LINK_TIMEOUT;
2635         do {
2636                 udelay(100);    /* Timeout in 100us units */
2637                 READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
2638                 if (--Timeout == 0) {
2639                         return (STATUS_FAILURE);
2640                 }
2641         } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
2642
2643         /* Reset the command register command bit */
2644         WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
2645
2646         /* MIIM write to set up an MDIO register read operation */
2647         WRITE_REG(HwRegs->MacAmiimField, ReadOp, TRUE);
2648
2649         /* Write to MIIM Command Register to execute the read operation */
2650         WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
2651
2652         /* Poll AMIIM Indicator register to wait for completion */
2653         Timeout = SXG_LINK_TIMEOUT;
2654         do {
2655                 udelay(100);    /* Timeout in 100us units */
2656                 READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
2657                 if (--Timeout == 0) {
2658                         return (STATUS_FAILURE);
2659                 }
2660         } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
2661
2662         /* Read the MDIO register data back from the field register */
2663         READ_REG(HwRegs->MacAmiimField, *pValue);
2664         *pValue &= 0xFFFF;      /* data is in the lower 16 bits */
2665
2666 /*  DBG_ERROR("EXIT %s\n", __func__); */
2667
2668         return (STATUS_SUCCESS);
2669 }
2670
2671 /*
2672  * Functions to obtain the CRC corresponding to the destination mac address.
2673  * This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using
2674  * the polynomial:
2675  *   x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1.
2676  *
2677  * After the CRC for the 6 bytes is generated (but before the value is complemented),
2678  * we must then transpose the value and return bits 30-23.
2679  *
2680  */
2681 static u32 sxg_crc_table[256];  /* Table of CRC's for all possible byte values */
2682
2683 /*
2684  *  Contruct the CRC32 table
2685  */
2686 static void sxg_mcast_init_crc32(void)
2687 {
2688         u32 c;                  /*  CRC shit reg                 */
2689         u32 e = 0;              /*  Poly X-or pattern            */
2690         int i;                  /*  counter                      */
2691         int k;                  /*  byte being shifted into crc  */
2692
2693         static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
2694
2695         for (i = 0; i < sizeof(p) / sizeof(int); i++) {
2696                 e |= 1L << (31 - p[i]);
2697         }
2698
2699         for (i = 1; i < 256; i++) {
2700                 c = i;
2701                 for (k = 8; k; k--) {
2702                         c = c & 1 ? (c >> 1) ^ e : c >> 1;
2703                 }
2704                 sxg_crc_table[i] = c;
2705         }
2706 }
2707
2708 #if XXXTODO
2709 static u32 sxg_crc_init;        /* Is table initialized */
2710 /*
2711  *  Return the MAC hast as described above.
2712  */
2713 static unsigned char sxg_mcast_get_mac_hash(char *macaddr)
2714 {
2715         u32 crc;
2716         char *p;
2717         int i;
2718         unsigned char machash = 0;
2719
2720         if (!sxg_crc_init) {
2721                 sxg_mcast_init_crc32();
2722                 sxg_crc_init = 1;
2723         }
2724
2725         crc = 0xFFFFFFFF;       /* Preload shift register, per crc-32 spec */
2726         for (i = 0, p = macaddr; i < 6; ++p, ++i) {
2727                 crc = (crc >> 8) ^ sxg_crc_table[(crc ^ *p) & 0xFF];
2728         }
2729
2730         /* Return bits 1-8, transposed */
2731         for (i = 1; i < 9; i++) {
2732                 machash |= (((crc >> i) & 1) << (8 - i));
2733         }
2734
2735         return (machash);
2736 }
2737
2738 static void sxg_mcast_set_mask(p_adapter_t adapter)
2739 {
2740         PSXG_UCODE_REGS sxg_regs = adapter->UcodeRegs;
2741
2742         DBG_ERROR("%s ENTER (%s) macopts[%x] mask[%llx]\n", __func__,
2743                   adapter->netdev->name, (unsigned int)adapter->MacFilter,
2744                   adapter->MulticastMask);
2745
2746         if (adapter->MacFilter & (MAC_ALLMCAST | MAC_PROMISC)) {
2747                 /* Turn on all multicast addresses. We have to do this for promiscuous
2748                  * mode as well as ALLMCAST mode.  It saves the Microcode from having
2749                  * to keep state about the MAC configuration.
2750                  */
2751 /*              DBG_ERROR("sxg: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n      SLUT MODE!!!\n",__func__); */
2752                 WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH);
2753                 WRITE_REG(sxg_regs->McastHigh, 0xFFFFFFFF, FLUSH);
2754 /*        DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",__func__, adapter->netdev->name); */
2755
2756         } else {
2757                 /* Commit our multicast mast to the SLIC by writing to the multicast
2758                  * address mask registers
2759                  */
2760                 DBG_ERROR("%s (%s) WRITE mcastlow[%lx] mcasthigh[%lx]\n",
2761                           __func__, adapter->netdev->name,
2762                           ((ulong) (adapter->MulticastMask & 0xFFFFFFFF)),
2763                           ((ulong)
2764                            ((adapter->MulticastMask >> 32) & 0xFFFFFFFF)));
2765
2766                 WRITE_REG(sxg_regs->McastLow,
2767                           (u32) (adapter->MulticastMask & 0xFFFFFFFF), FLUSH);
2768                 WRITE_REG(sxg_regs->McastHigh,
2769                           (u32) ((adapter->
2770                                   MulticastMask >> 32) & 0xFFFFFFFF), FLUSH);
2771         }
2772 }
2773
2774 /*
2775  *  Allocate a mcast_address structure to hold the multicast address.
2776  *  Link it in.
2777  */
2778 static int sxg_mcast_add_list(p_adapter_t adapter, char *address)
2779 {
2780         p_mcast_address_t mcaddr, mlist;
2781         bool equaladdr;
2782
2783         /* Check to see if it already exists */
2784         mlist = adapter->mcastaddrs;
2785         while (mlist) {
2786                 ETHER_EQ_ADDR(mlist->address, address, equaladdr);
2787                 if (equaladdr) {
2788                         return (STATUS_SUCCESS);
2789                 }
2790                 mlist = mlist->next;
2791         }
2792
2793         /* Doesn't already exist.  Allocate a structure to hold it */
2794         mcaddr = kmalloc(sizeof(mcast_address_t), GFP_ATOMIC);
2795         if (mcaddr == NULL)
2796                 return 1;
2797
2798         memcpy(mcaddr->address, address, 6);
2799
2800         mcaddr->next = adapter->mcastaddrs;
2801         adapter->mcastaddrs = mcaddr;
2802
2803         return (STATUS_SUCCESS);
2804 }
2805
2806 static void sxg_mcast_set_bit(p_adapter_t adapter, char *address)
2807 {
2808         unsigned char crcpoly;
2809
2810         /* Get the CRC polynomial for the mac address */
2811         crcpoly = sxg_mcast_get_mac_hash(address);
2812
2813         /* We only have space on the SLIC for 64 entries.  Lop
2814          * off the top two bits. (2^6 = 64)
2815          */
2816         crcpoly &= 0x3F;
2817
2818         /* OR in the new bit into our 64 bit mask. */
2819         adapter->MulticastMask |= (u64) 1 << crcpoly;
2820 }
2821
2822 static void sxg_mcast_set_list(p_net_device dev)
2823 {
2824         p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
2825         int status = STATUS_SUCCESS;
2826         int i;
2827         char *addresses;
2828         struct dev_mc_list *mc_list = dev->mc_list;
2829         int mc_count = dev->mc_count;
2830
2831         ASSERT(adapter);
2832
2833         for (i = 1; i <= mc_count; i++) {
2834                 addresses = (char *)&mc_list->dmi_addr;
2835                 if (mc_list->dmi_addrlen == 6) {
2836                         status = sxg_mcast_add_list(adapter, addresses);
2837                         if (status != STATUS_SUCCESS) {
2838                                 break;
2839                         }
2840                 } else {
2841                         status = -EINVAL;
2842                         break;
2843                 }
2844                 sxg_mcast_set_bit(adapter, addresses);
2845                 mc_list = mc_list->next;
2846         }
2847
2848         DBG_ERROR("%s a->devflags_prev[%x] dev->flags[%x] status[%x]\n",
2849                   __func__, adapter->devflags_prev, dev->flags, status);
2850         if (adapter->devflags_prev != dev->flags) {
2851                 adapter->macopts = MAC_DIRECTED;
2852                 if (dev->flags) {
2853                         if (dev->flags & IFF_BROADCAST) {
2854                                 adapter->macopts |= MAC_BCAST;
2855                         }
2856                         if (dev->flags & IFF_PROMISC) {
2857                                 adapter->macopts |= MAC_PROMISC;
2858                         }
2859                         if (dev->flags & IFF_ALLMULTI) {
2860                                 adapter->macopts |= MAC_ALLMCAST;
2861                         }
2862                         if (dev->flags & IFF_MULTICAST) {
2863                                 adapter->macopts |= MAC_MCAST;
2864                         }
2865                 }
2866                 adapter->devflags_prev = dev->flags;
2867                 DBG_ERROR("%s call sxg_config_set adapter->macopts[%x]\n",
2868                           __func__, adapter->macopts);
2869                 sxg_config_set(adapter, TRUE);
2870         } else {
2871                 if (status == STATUS_SUCCESS) {
2872                         sxg_mcast_set_mask(adapter);
2873                 }
2874         }
2875         return;
2876 }
2877 #endif
2878
2879 static void sxg_unmap_mmio_space(p_adapter_t adapter)
2880 {
2881 #if LINUX_FREES_ADAPTER_RESOURCES
2882 /*      if (adapter->Regs) { */
2883 /*              iounmap(adapter->Regs); */
2884 /*      } */
2885 /*      adapter->slic_regs = NULL; */
2886 #endif
2887 }
2888
2889 #if XXXTODO
2890 /*
2891  * SxgFreeResources - Free everything allocated in SxgAllocateResources
2892  *
2893  * Arguments -
2894  *      adapter         - A pointer to our adapter structure
2895  *
2896  * Return
2897  *      none
2898  */
2899 void SxgFreeResources(p_adapter_t adapter)
2900 {
2901         u32 RssIds, IsrCount;
2902         PTCP_OBJECT TcpObject;
2903         u32 i;
2904         BOOLEAN TimerCancelled;
2905
2906         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FreeRes",
2907                   adapter, adapter->MaxTcbs, 0, 0);
2908
2909         RssIds = SXG_RSS_CPU_COUNT(adapter);
2910         IsrCount = adapter->MsiEnabled ? RssIds : 1;
2911
2912         if (adapter->BasicAllocations == FALSE) {
2913                 /* No allocations have been made, including spinlocks, */
2914                 /* or listhead initializations.  Return. */
2915                 return;
2916         }
2917
2918         if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
2919                 SxgFreeRcvBlocks(adapter);
2920         }
2921         if (!(IsListEmpty(&adapter->AllSglBuffers))) {
2922                 SxgFreeSglBuffers(adapter);
2923         }
2924         /* Free event queues. */
2925         if (adapter->EventRings) {
2926                 pci_free_consistent(adapter->pcidev,
2927                                     sizeof(SXG_EVENT_RING) * RssIds,
2928                                     adapter->EventRings, adapter->PEventRings);
2929         }
2930         if (adapter->Isr) {
2931                 pci_free_consistent(adapter->pcidev,
2932                                     sizeof(u32) * IsrCount,
2933                                     adapter->Isr, adapter->PIsr);
2934         }
2935         if (adapter->XmtRingZeroIndex) {
2936                 pci_free_consistent(adapter->pcidev,
2937                                     sizeof(u32),
2938                                     adapter->XmtRingZeroIndex,
2939                                     adapter->PXmtRingZeroIndex);
2940         }
2941         if (adapter->IndirectionTable) {
2942                 pci_free_consistent(adapter->pcidev,
2943                                     SXG_MAX_RSS_TABLE_SIZE,
2944                                     adapter->IndirectionTable,
2945                                     adapter->PIndirectionTable);
2946         }
2947
2948         SXG_FREE_PACKET_POOL(adapter->PacketPoolHandle);
2949         SXG_FREE_BUFFER_POOL(adapter->BufferPoolHandle);
2950
2951         /* Unmap register spaces */
2952         SxgUnmapResources(adapter);
2953
2954         /* Deregister DMA */
2955         if (adapter->DmaHandle) {
2956                 SXG_DEREGISTER_DMA(adapter->DmaHandle);
2957         }
2958         /* Deregister interrupt */
2959         SxgDeregisterInterrupt(adapter);
2960
2961         /* Possibly free system info (5.2 only) */
2962         SXG_RELEASE_SYSTEM_INFO(adapter);
2963
2964         SxgDiagFreeResources(adapter);
2965
2966         SxgFreeMCastAddrs(adapter);
2967
2968         if (SXG_TIMER_ALLOCATED(adapter->ResetTimer)) {
2969                 SXG_CANCEL_TIMER(adapter->ResetTimer, TimerCancelled);
2970                 SXG_FREE_TIMER(adapter->ResetTimer);
2971         }
2972         if (SXG_TIMER_ALLOCATED(adapter->RssTimer)) {
2973                 SXG_CANCEL_TIMER(adapter->RssTimer, TimerCancelled);
2974                 SXG_FREE_TIMER(adapter->RssTimer);
2975         }
2976         if (SXG_TIMER_ALLOCATED(adapter->OffloadTimer)) {
2977                 SXG_CANCEL_TIMER(adapter->OffloadTimer, TimerCancelled);
2978                 SXG_FREE_TIMER(adapter->OffloadTimer);
2979         }
2980
2981         adapter->BasicAllocations = FALSE;
2982
2983         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFreeRes",
2984                   adapter, adapter->MaxTcbs, 0, 0);
2985 }
2986 #endif
2987
2988 /*
2989  * sxg_allocate_complete -
2990  *
2991  * This routine is called when a memory allocation has completed.
2992  *
2993  * Arguments -
2994  *      p_adapter_t     - Our adapter structure
2995  *      VirtualAddress  - Memory virtual address
2996  *      PhysicalAddress - Memory physical address
2997  *      Length          - Length of memory allocated (or 0)
2998  *      Context         - The type of buffer allocated
2999  *
3000  * Return
3001  *      None.
3002  */
3003 static void sxg_allocate_complete(p_adapter_t adapter,
3004                                   void *VirtualAddress,
3005                                   dma_addr_t PhysicalAddress,
3006                                   u32 Length, SXG_BUFFER_TYPE Context)
3007 {
3008         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocCmp",
3009                   adapter, VirtualAddress, Length, Context);
3010         ASSERT(adapter->AllocationsPending);
3011         --adapter->AllocationsPending;
3012
3013         switch (Context) {
3014
3015         case SXG_BUFFER_TYPE_RCV:
3016                 sxg_allocate_rcvblock_complete(adapter,
3017                                                VirtualAddress,
3018                                                PhysicalAddress, Length);
3019                 break;
3020         case SXG_BUFFER_TYPE_SGL:
3021                 sxg_allocate_sgl_buffer_complete(adapter, (PSXG_SCATTER_GATHER)
3022                                                  VirtualAddress,
3023                                                  PhysicalAddress, Length);
3024                 break;
3025         }
3026         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocCmp",
3027                   adapter, VirtualAddress, Length, Context);
3028 }
3029
3030 /*
3031  * sxg_allocate_buffer_memory - Shared memory allocation routine used for
3032  *              synchronous and asynchronous buffer allocations
3033  *
3034  * Arguments -
3035  *      adapter         - A pointer to our adapter structure
3036  *      Size            - block size to allocate
3037  *      BufferType      - Type of buffer to allocate
3038  *
3039  * Return
3040  *      int
3041  */
3042 static int sxg_allocate_buffer_memory(p_adapter_t adapter,
3043                                       u32 Size, SXG_BUFFER_TYPE BufferType)
3044 {
3045         int status;
3046         void *Buffer;
3047         dma_addr_t pBuffer;
3048
3049         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocMem",
3050                   adapter, Size, BufferType, 0);
3051         /* Grab the adapter lock and check the state. */
3052         /* If we're in anything other than INITIALIZING or */
3053         /* RUNNING state, fail.  This is to prevent */
3054         /* allocations in an improper driver state */
3055         spin_lock(&adapter->AdapterLock);
3056
3057         /* Increment the AllocationsPending count while holding */
3058         /* the lock.  Pause processing relies on this */
3059         ++adapter->AllocationsPending;
3060         spin_unlock(&adapter->AdapterLock);
3061
3062         /* At initialization time allocate resources synchronously. */
3063         Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer);
3064         if (Buffer == NULL) {
3065                 spin_lock(&adapter->AdapterLock);
3066                 /* Decrement the AllocationsPending count while holding */
3067                 /* the lock.  Pause processing relies on this */
3068                 --adapter->AllocationsPending;
3069                 spin_unlock(&adapter->AdapterLock);
3070                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlcMemF1",
3071                           adapter, Size, BufferType, 0);
3072                 return (STATUS_RESOURCES);
3073         }
3074         sxg_allocate_complete(adapter, Buffer, pBuffer, Size, BufferType);
3075         status = STATUS_SUCCESS;
3076
3077         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocMem",
3078                   adapter, Size, BufferType, status);
3079         return (status);
3080 }
3081
3082 /*
3083  * sxg_allocate_rcvblock_complete - Complete a receive descriptor block allocation
3084  *
3085  * Arguments -
3086  *      adapter                         - A pointer to our adapter structure
3087  *      RcvBlock                        - receive block virtual address
3088  *      PhysicalAddress         - Physical address
3089  *      Length                          - Memory length
3090  *
3091  * Return
3092  *
3093  */
3094 static void sxg_allocate_rcvblock_complete(p_adapter_t adapter,
3095                                            void *RcvBlock,
3096                                            dma_addr_t PhysicalAddress,
3097                                            u32 Length)
3098 {
3099         u32 i;
3100         u32 BufferSize = adapter->ReceiveBufferSize;
3101         u64 Paddr;
3102         PSXG_RCV_BLOCK_HDR RcvBlockHdr;
3103         unsigned char *RcvDataBuffer;
3104         PSXG_RCV_DATA_BUFFER_HDR RcvDataBufferHdr;
3105         PSXG_RCV_DESCRIPTOR_BLOCK RcvDescriptorBlock;
3106         PSXG_RCV_DESCRIPTOR_BLOCK_HDR RcvDescriptorBlockHdr;
3107
3108         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlRcvBlk",
3109                   adapter, RcvBlock, Length, 0);
3110         if (RcvBlock == NULL) {
3111                 goto fail;
3112         }
3113         memset(RcvBlock, 0, Length);
3114         ASSERT((BufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
3115                (BufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
3116         ASSERT(Length == SXG_RCV_BLOCK_SIZE(BufferSize));
3117         /* First, initialize the contained pool of receive data */
3118         /* buffers.  This initialization requires NBL/NB/MDL allocations, */
3119         /* If any of them fail, free the block and return without */
3120         /* queueing the shared memory */
3121         RcvDataBuffer = RcvBlock;
3122 #if 0
3123         for (i = 0, Paddr = *PhysicalAddress;
3124              i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
3125              i++, Paddr.LowPart += BufferSize, RcvDataBuffer += BufferSize)
3126 #endif
3127                 for (i = 0, Paddr = PhysicalAddress;
3128                      i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
3129                      i++, Paddr += BufferSize, RcvDataBuffer += BufferSize) {
3130                         /* */
3131                         RcvDataBufferHdr =
3132                             (PSXG_RCV_DATA_BUFFER_HDR) (RcvDataBuffer +
3133                                                         SXG_RCV_DATA_BUFFER_HDR_OFFSET
3134                                                         (BufferSize));
3135                         RcvDataBufferHdr->VirtualAddress = RcvDataBuffer;
3136                         RcvDataBufferHdr->PhysicalAddress = Paddr;
3137                         RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;  /* For FREE macro assertion */
3138                         RcvDataBufferHdr->Size =
3139                             SXG_RCV_BUFFER_DATA_SIZE(BufferSize);
3140
3141                         SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr);
3142                         if (RcvDataBufferHdr->SxgDumbRcvPacket == NULL)
3143                                 goto fail;
3144
3145                 }
3146
3147         /* Place this entire block of memory on the AllRcvBlocks queue so it can be */
3148         /* free later */
3149         RcvBlockHdr =
3150             (PSXG_RCV_BLOCK_HDR) ((unsigned char *)RcvBlock +
3151                                   SXG_RCV_BLOCK_HDR_OFFSET(BufferSize));
3152         RcvBlockHdr->VirtualAddress = RcvBlock;
3153         RcvBlockHdr->PhysicalAddress = PhysicalAddress;
3154         spin_lock(&adapter->RcvQLock);
3155         adapter->AllRcvBlockCount++;
3156         InsertTailList(&adapter->AllRcvBlocks, &RcvBlockHdr->AllList);
3157         spin_unlock(&adapter->RcvQLock);
3158
3159         /* Now free the contained receive data buffers that we initialized above */
3160         RcvDataBuffer = RcvBlock;
3161         for (i = 0, Paddr = PhysicalAddress;
3162              i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
3163              i++, Paddr += BufferSize, RcvDataBuffer += BufferSize) {
3164                 RcvDataBufferHdr = (PSXG_RCV_DATA_BUFFER_HDR) (RcvDataBuffer +
3165                                                                SXG_RCV_DATA_BUFFER_HDR_OFFSET
3166                                                                (BufferSize));
3167                 spin_lock(&adapter->RcvQLock);
3168                 SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
3169                 spin_unlock(&adapter->RcvQLock);
3170         }
3171
3172         /* Locate the descriptor block and put it on a separate free queue */
3173         RcvDescriptorBlock =
3174             (PSXG_RCV_DESCRIPTOR_BLOCK) ((unsigned char *)RcvBlock +
3175                                          SXG_RCV_DESCRIPTOR_BLOCK_OFFSET
3176                                          (BufferSize));
3177         RcvDescriptorBlockHdr =
3178             (PSXG_RCV_DESCRIPTOR_BLOCK_HDR) ((unsigned char *)RcvBlock +
3179                                              SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET
3180                                              (BufferSize));
3181         RcvDescriptorBlockHdr->VirtualAddress = RcvDescriptorBlock;
3182         RcvDescriptorBlockHdr->PhysicalAddress = Paddr;
3183         spin_lock(&adapter->RcvQLock);
3184         SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter, RcvDescriptorBlockHdr);
3185         spin_unlock(&adapter->RcvQLock);
3186         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlRBlk",
3187                   adapter, RcvBlock, Length, 0);
3188         return;
3189       fail:
3190         /* Free any allocated resources */
3191         if (RcvBlock) {
3192                 RcvDataBuffer = RcvBlock;
3193                 for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
3194                      i++, RcvDataBuffer += BufferSize) {
3195                         RcvDataBufferHdr =
3196                             (PSXG_RCV_DATA_BUFFER_HDR) (RcvDataBuffer +
3197                                                         SXG_RCV_DATA_BUFFER_HDR_OFFSET
3198                                                         (BufferSize));
3199                         SXG_FREE_RCV_PACKET(RcvDataBufferHdr);
3200                 }
3201                 pci_free_consistent(adapter->pcidev,
3202                                     Length, RcvBlock, PhysicalAddress);
3203         }
3204         DBG_ERROR("%s: OUT OF RESOURCES\n", __func__);
3205         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "RcvAFail",
3206                   adapter, adapter->FreeRcvBufferCount,
3207                   adapter->FreeRcvBlockCount, adapter->AllRcvBlockCount);
3208         adapter->Stats.NoMem++;
3209 }
3210
3211 /*
3212  * sxg_allocate_sgl_buffer_complete - Complete a SGL buffer allocation
3213  *
3214  * Arguments -
3215  *      adapter                         - A pointer to our adapter structure
3216  *      SxgSgl                          - SXG_SCATTER_GATHER buffer
3217  *      PhysicalAddress         - Physical address
3218  *      Length                          - Memory length
3219  *
3220  * Return
3221  *
3222  */
3223 static void sxg_allocate_sgl_buffer_complete(p_adapter_t adapter,
3224                                              PSXG_SCATTER_GATHER SxgSgl,
3225                                              dma_addr_t PhysicalAddress,
3226                                              u32 Length)
3227 {
3228         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlSglCmp",
3229                   adapter, SxgSgl, Length, 0);
3230         spin_lock(&adapter->SglQLock);
3231         adapter->AllSglBufferCount++;
3232         memset(SxgSgl, 0, sizeof(SXG_SCATTER_GATHER));
3233         SxgSgl->PhysicalAddress = PhysicalAddress;      /* *PhysicalAddress; */
3234         SxgSgl->adapter = adapter;      /* Initialize backpointer once */
3235         InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList);
3236         spin_unlock(&adapter->SglQLock);
3237         SxgSgl->State = SXG_BUFFER_BUSY;
3238         SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL);
3239         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlSgl",
3240                   adapter, SxgSgl, Length, 0);
3241 }
3242
3243 static unsigned char temp_mac_address[6] =
3244     { 0x00, 0xab, 0xcd, 0xef, 0x12, 0x69 };
3245
3246 static void sxg_adapter_set_hwaddr(p_adapter_t adapter)
3247 {
3248 /*  DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n", __func__, */
3249 /*             card->config_set, adapter->port, adapter->physport, adapter->functionnumber); */
3250 /* */
3251 /*  sxg_dbg_macaddrs(adapter); */
3252
3253         memcpy(adapter->macaddr, temp_mac_address, sizeof(SXG_CONFIG_MAC));
3254 /*      DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n", __func__); */
3255 /*      sxg_dbg_macaddrs(adapter); */
3256         if (!(adapter->currmacaddr[0] ||
3257               adapter->currmacaddr[1] ||
3258               adapter->currmacaddr[2] ||
3259               adapter->currmacaddr[3] ||
3260               adapter->currmacaddr[4] || adapter->currmacaddr[5])) {
3261                 memcpy(adapter->currmacaddr, adapter->macaddr, 6);
3262         }
3263         if (adapter->netdev) {
3264                 memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6);
3265         }
3266 /*  DBG_ERROR ("%s EXIT port %d\n", __func__, adapter->port); */
3267         sxg_dbg_macaddrs(adapter);
3268
3269 }
3270
3271 #if XXXTODO
3272 static int sxg_mac_set_address(p_net_device dev, void *ptr)
3273 {
3274         p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
3275         struct sockaddr *addr = ptr;
3276
3277         DBG_ERROR("%s ENTER (%s)\n", __func__, adapter->netdev->name);
3278
3279         if (netif_running(dev)) {
3280                 return -EBUSY;
3281         }
3282         if (!adapter) {
3283                 return -EBUSY;
3284         }
3285         DBG_ERROR("sxg: %s (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
3286                   __func__, adapter->netdev->name, adapter->currmacaddr[0],
3287                   adapter->currmacaddr[1], adapter->currmacaddr[2],
3288                   adapter->currmacaddr[3], adapter->currmacaddr[4],
3289                   adapter->currmacaddr[5]);
3290         memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
3291         memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
3292         DBG_ERROR("sxg: %s (%s) new %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
3293                   __func__, adapter->netdev->name, adapter->currmacaddr[0],
3294                   adapter->currmacaddr[1], adapter->currmacaddr[2],
3295                   adapter->currmacaddr[3], adapter->currmacaddr[4],
3296                   adapter->currmacaddr[5]);
3297
3298         sxg_config_set(adapter, TRUE);
3299         return 0;
3300 }
3301 #endif
3302
3303 /*****************************************************************************/
3304 /*************  SXG DRIVER FUNCTIONS  (below) ********************************/
3305 /*****************************************************************************/
3306
3307 /*
3308  * sxg_initialize_adapter - Initialize adapter
3309  *
3310  * Arguments -
3311  *      adapter         - A pointer to our adapter structure
3312  *
3313  * Return
3314  *      int
3315  */
3316 static int sxg_initialize_adapter(p_adapter_t adapter)
3317 {
3318         u32 RssIds, IsrCount;
3319         u32 i;
3320         int status;
3321
3322         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitAdpt",
3323                   adapter, 0, 0, 0);
3324
3325         RssIds = 1;             /*  XXXTODO  SXG_RSS_CPU_COUNT(adapter); */
3326         IsrCount = adapter->MsiEnabled ? RssIds : 1;
3327
3328         /* Sanity check SXG_UCODE_REGS structure definition to */
3329         /* make sure the length is correct */
3330         ASSERT(sizeof(SXG_UCODE_REGS) == SXG_REGISTER_SIZE_PER_CPU);
3331
3332         /* Disable interrupts */
3333         SXG_DISABLE_ALL_INTERRUPTS(adapter);
3334
3335         /* Set MTU */
3336         ASSERT((adapter->FrameSize == ETHERMAXFRAME) ||
3337                (adapter->FrameSize == JUMBOMAXFRAME));
3338         WRITE_REG(adapter->UcodeRegs[0].LinkMtu, adapter->FrameSize, TRUE);
3339
3340         /* Set event ring base address and size */
3341         WRITE_REG64(adapter,
3342                     adapter->UcodeRegs[0].EventBase, adapter->PEventRings, 0);
3343         WRITE_REG(adapter->UcodeRegs[0].EventSize, EVENT_RING_SIZE, TRUE);
3344
3345         /* Per-ISR initialization */
3346         for (i = 0; i < IsrCount; i++) {
3347                 u64 Addr;
3348                 /* Set interrupt status pointer */
3349                 Addr = adapter->PIsr + (i * sizeof(u32));
3350                 WRITE_REG64(adapter, adapter->UcodeRegs[i].Isp, Addr, i);
3351         }
3352
3353         /* XMT ring zero index */
3354         WRITE_REG64(adapter,
3355                     adapter->UcodeRegs[0].SPSendIndex,
3356                     adapter->PXmtRingZeroIndex, 0);
3357
3358         /* Per-RSS initialization */
3359         for (i = 0; i < RssIds; i++) {
3360                 /* Release all event ring entries to the Microcode */
3361                 WRITE_REG(adapter->UcodeRegs[i].EventRelease, EVENT_RING_SIZE,
3362                           TRUE);
3363         }
3364
3365         /* Transmit ring base and size */
3366         WRITE_REG64(adapter,
3367                     adapter->UcodeRegs[0].XmtBase, adapter->PXmtRings, 0);
3368         WRITE_REG(adapter->UcodeRegs[0].XmtSize, SXG_XMT_RING_SIZE, TRUE);
3369
3370         /* Receive ring base and size */
3371         WRITE_REG64(adapter,
3372                     adapter->UcodeRegs[0].RcvBase, adapter->PRcvRings, 0);
3373         WRITE_REG(adapter->UcodeRegs[0].RcvSize, SXG_RCV_RING_SIZE, TRUE);
3374
3375         /* Populate the card with receive buffers */
3376         sxg_stock_rcv_buffers(adapter);
3377
3378         /* Initialize checksum offload capabilities.  At the moment */
3379         /* we always enable IP and TCP receive checksums on the card. */
3380         /* Depending on the checksum configuration specified by the */
3381         /* user, we can choose to report or ignore the checksum */
3382         /* information provided by the card. */
3383         WRITE_REG(adapter->UcodeRegs[0].ReceiveChecksum,
3384                   SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED, TRUE);
3385
3386         /* Initialize the MAC, XAUI */
3387         DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __func__);
3388         status = sxg_initialize_link(adapter);
3389         DBG_ERROR("sxg: %s EXIT sxg_initialize_link status[%x]\n", __func__,
3390                   status);
3391         if (status != STATUS_SUCCESS) {
3392                 return (status);
3393         }
3394         /* Initialize Dead to FALSE. */
3395         /* SlicCheckForHang or SlicDumpThread will take it from here. */
3396         adapter->Dead = FALSE;
3397         adapter->PingOutstanding = FALSE;
3398
3399         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInit",
3400                   adapter, 0, 0, 0);
3401         return (STATUS_SUCCESS);
3402 }
3403
3404 /*
3405  * sxg_fill_descriptor_block - Populate a descriptor block and give it to
3406  * the card.  The caller should hold the RcvQLock
3407  *
3408  * Arguments -
3409  *      adapter         - A pointer to our adapter structure
3410  *  RcvDescriptorBlockHdr       - Descriptor block to fill
3411  *
3412  * Return
3413  *      status
3414  */
3415 static int sxg_fill_descriptor_block(p_adapter_t adapter,
3416                                      PSXG_RCV_DESCRIPTOR_BLOCK_HDR
3417                                      RcvDescriptorBlockHdr)
3418 {
3419         u32 i;
3420         PSXG_RING_INFO RcvRingInfo = &adapter->RcvRingZeroInfo;
3421         PSXG_RCV_DATA_BUFFER_HDR RcvDataBufferHdr;
3422         PSXG_RCV_DESCRIPTOR_BLOCK RcvDescriptorBlock;
3423         PSXG_CMD RingDescriptorCmd;
3424         PSXG_RCV_RING RingZero = &adapter->RcvRings[0];
3425
3426         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FilBlk",
3427                   adapter, adapter->RcvBuffersOnCard,
3428                   adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
3429
3430         ASSERT(RcvDescriptorBlockHdr);
3431
3432         /* If we don't have the resources to fill the descriptor block, */
3433         /* return failure */
3434         if ((adapter->FreeRcvBufferCount < SXG_RCV_DESCRIPTORS_PER_BLOCK) ||
3435             SXG_RING_FULL(RcvRingInfo)) {
3436                 adapter->Stats.NoMem++;
3437                 return (STATUS_FAILURE);
3438         }
3439         /* Get a ring descriptor command */
3440         SXG_GET_CMD(RingZero,
3441                     RcvRingInfo, RingDescriptorCmd, RcvDescriptorBlockHdr);
3442         ASSERT(RingDescriptorCmd);
3443         RcvDescriptorBlockHdr->State = SXG_BUFFER_ONCARD;
3444         RcvDescriptorBlock =
3445             (PSXG_RCV_DESCRIPTOR_BLOCK) RcvDescriptorBlockHdr->VirtualAddress;
3446
3447         /* Fill in the descriptor block */
3448         for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; i++) {
3449                 SXG_GET_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
3450                 ASSERT(RcvDataBufferHdr);
3451                 SXG_REINIATIALIZE_PACKET(RcvDataBufferHdr->SxgDumbRcvPacket);
3452                 RcvDataBufferHdr->State = SXG_BUFFER_ONCARD;
3453                 RcvDescriptorBlock->Descriptors[i].VirtualAddress =
3454                     (void *)RcvDataBufferHdr;
3455                 RcvDescriptorBlock->Descriptors[i].PhysicalAddress =
3456                     RcvDataBufferHdr->PhysicalAddress;
3457         }
3458         /* Add the descriptor block to receive descriptor ring 0 */
3459         RingDescriptorCmd->Sgl = RcvDescriptorBlockHdr->PhysicalAddress;
3460
3461         /* RcvBuffersOnCard is not protected via the receive lock (see */
3462         /* sxg_process_event_queue) We don't want to grap a lock every time a */
3463         /* buffer is returned to us, so we use atomic interlocked functions */
3464         /* instead. */
3465         adapter->RcvBuffersOnCard += SXG_RCV_DESCRIPTORS_PER_BLOCK;
3466
3467         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DscBlk",
3468                   RcvDescriptorBlockHdr,
3469                   RingDescriptorCmd, RcvRingInfo->Head, RcvRingInfo->Tail);
3470
3471         WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 1, true);
3472         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFilBlk",
3473                   adapter, adapter->RcvBuffersOnCard,
3474                   adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
3475         return (STATUS_SUCCESS);
3476 }
3477
3478 /*
3479  * sxg_stock_rcv_buffers - Stock the card with receive buffers
3480  *
3481  * Arguments -
3482  *      adapter         - A pointer to our adapter structure
3483  *
3484  * Return
3485  *      None
3486  */
3487 static void sxg_stock_rcv_buffers(p_adapter_t adapter)
3488 {
3489         PSXG_RCV_DESCRIPTOR_BLOCK_HDR RcvDescriptorBlockHdr;
3490
3491         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "StockBuf",
3492                   adapter, adapter->RcvBuffersOnCard,
3493                   adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
3494         /* First, see if we've got less than our minimum threshold of */
3495         /* receive buffers, there isn't an allocation in progress, and */
3496         /* we haven't exceeded our maximum.. get another block of buffers */
3497         /* None of this needs to be SMP safe.  It's round numbers. */
3498         if ((adapter->FreeRcvBufferCount < SXG_MIN_RCV_DATA_BUFFERS) &&
3499             (adapter->AllRcvBlockCount < SXG_MAX_RCV_BLOCKS) &&
3500             (adapter->AllocationsPending == 0)) {
3501                 sxg_allocate_buffer_memory(adapter,
3502                                            SXG_RCV_BLOCK_SIZE(adapter->
3503                                                               ReceiveBufferSize),
3504                                            SXG_BUFFER_TYPE_RCV);
3505         }
3506         /* Now grab the RcvQLock lock and proceed */
3507         spin_lock(&adapter->RcvQLock);
3508         while (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
3509                 PLIST_ENTRY _ple;
3510
3511                 /* Get a descriptor block */
3512                 RcvDescriptorBlockHdr = NULL;
3513                 if (adapter->FreeRcvBlockCount) {
3514                         _ple = RemoveHeadList(&adapter->FreeRcvBlocks);
3515                         RcvDescriptorBlockHdr =
3516                             container_of(_ple, SXG_RCV_DESCRIPTOR_BLOCK_HDR,
3517                                          FreeList);
3518                         adapter->FreeRcvBlockCount--;
3519                         RcvDescriptorBlockHdr->State = SXG_BUFFER_BUSY;
3520                 }
3521
3522                 if (RcvDescriptorBlockHdr == NULL) {
3523                         /* Bail out.. */
3524                         adapter->Stats.NoMem++;
3525                         break;
3526                 }
3527                 /* Fill in the descriptor block and give it to the card */
3528                 if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) ==
3529                     STATUS_FAILURE) {
3530                         /* Free the descriptor block */
3531                         SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter,
3532                                                       RcvDescriptorBlockHdr);
3533                         break;
3534                 }
3535         }
3536         spin_unlock(&adapter->RcvQLock);
3537         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFilBlks",
3538                   adapter, adapter->RcvBuffersOnCard,
3539                   adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
3540 }
3541
3542 /*
3543  * sxg_complete_descriptor_blocks - Return descriptor blocks that have been
3544  * completed by the microcode
3545  *
3546  * Arguments -
3547  *      adapter         - A pointer to our adapter structure
3548  *      Index           - Where the microcode is up to
3549  *
3550  * Return
3551  *      None
3552  */
3553 static void sxg_complete_descriptor_blocks(p_adapter_t adapter,
3554                                            unsigned char Index)
3555 {
3556         PSXG_RCV_RING RingZero = &adapter->RcvRings[0];
3557         PSXG_RING_INFO RcvRingInfo = &adapter->RcvRingZeroInfo;
3558         PSXG_RCV_DESCRIPTOR_BLOCK_HDR RcvDescriptorBlockHdr;
3559         PSXG_CMD RingDescriptorCmd;
3560
3561         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlks",
3562                   adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
3563
3564         /* Now grab the RcvQLock lock and proceed */
3565         spin_lock(&adapter->RcvQLock);
3566         ASSERT(Index != RcvRingInfo->Tail);
3567         while (RcvRingInfo->Tail != Index) {
3568                 /* */
3569                 /* Locate the current Cmd (ring descriptor entry), and */
3570                 /* associated receive descriptor block, and advance */
3571                 /* the tail */
3572                 /* */
3573                 SXG_RETURN_CMD(RingZero,
3574                                RcvRingInfo,
3575                                RingDescriptorCmd, RcvDescriptorBlockHdr);
3576                 SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlk",
3577                           RcvRingInfo->Head, RcvRingInfo->Tail,
3578                           RingDescriptorCmd, RcvDescriptorBlockHdr);
3579
3580                 /* Clear the SGL field */
3581                 RingDescriptorCmd->Sgl = 0;
3582                 /* Attempt to refill it and hand it right back to the */
3583                 /* card.  If we fail to refill it, free the descriptor block */
3584                 /* header.  The card will be restocked later via the */
3585                 /* RcvBuffersOnCard test */
3586                 if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) ==
3587                     STATUS_FAILURE) {
3588                         SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter,
3589                                                       RcvDescriptorBlockHdr);
3590                 }
3591         }
3592         spin_unlock(&adapter->RcvQLock);
3593         SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XCRBlks",
3594                   adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
3595 }
3596
3597 static struct pci_driver sxg_driver = {
3598         .name = DRV_NAME,
3599         .id_table = sxg_pci_tbl,
3600         .probe = sxg_entry_probe,
3601         .remove = sxg_entry_remove,
3602 #if SXG_POWER_MANAGEMENT_ENABLED
3603         .suspend = sxgpm_suspend,
3604         .resume = sxgpm_resume,
3605 #endif
3606 /*    .shutdown   =     slic_shutdown,  MOOK_INVESTIGATE */
3607 };
3608
3609 static int __init sxg_module_init(void)
3610 {
3611         sxg_init_driver();
3612
3613         if (debug >= 0)
3614                 sxg_debug = debug;
3615
3616         return pci_register_driver(&sxg_driver);
3617 }
3618
3619 static void __exit sxg_module_cleanup(void)
3620 {
3621         pci_unregister_driver(&sxg_driver);
3622 }
3623
3624 module_init(sxg_module_init);
3625 module_exit(sxg_module_cleanup);