1 /**************************************************************************
3 * Copyright 2000-2006 Alacritech, Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") version 2 as published by the Free
18 * Software Foundation.
20 * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * The views and conclusions contained in the software and documentation
34 * are those of the authors and should not be interpreted as representing
35 * official policies, either expressed or implied, of Alacritech, Inc.
37 **************************************************************************/
42 * The SLICOSS driver for Alacritech's IS-NIC products.
44 * This driver is supposed to support:
46 * Mojave cards (single port PCI Gigabit) both copper and fiber
47 * Oasis cards (single and dual port PCI-x Gigabit) copper and fiber
48 * Kalahari cards (dual and quad port PCI-e Gigabit) copper and fiber
50 * The driver was acutally tested on Oasis and Kalahari cards.
53 * NOTE: This is the standard, non-accelerated version of Alacritech's
57 #include <linux/version.h>
59 #define SLIC_DUMP_ENABLED 0
60 #define KLUDGE_FOR_4GB_BOUNDARY 1
61 #define DEBUG_MICROCODE 1
62 #define SLIC_PRODUCTION_BUILD 1
63 #define SLIC_FAILURE_RESET 1
65 #define SLIC_ASSERT_ENABLED 1
66 #define SLIC_GET_STATS_ENABLED 1
67 #define SLIC_GET_STATS_TIMER_ENABLED 0
68 #define SLIC_PING_TIMER_ENABLED 1
69 #define SLIC_POWER_MANAGEMENT_ENABLED 0
70 #define SLIC_INTERRUPT_PROCESS_LIMIT 1
71 #define LINUX_FREES_ADAPTER_RESOURCES 1
72 #define SLIC_OFFLOAD_IP_CHECKSUM 1
73 #define STATS_TIMER_INTERVAL 2
74 #define PING_TIMER_INTERVAL 1
76 #include <linux/kernel.h>
77 #include <linux/string.h>
78 #include <linux/errno.h>
79 #include <linux/ioport.h>
80 #include <linux/slab.h>
81 #include <linux/interrupt.h>
82 #include <linux/timer.h>
83 #include <linux/pci.h>
84 #include <linux/spinlock.h>
85 #include <linux/init.h>
86 #include <linux/bitops.h>
88 #include <linux/netdevice.h>
89 #include <linux/etherdevice.h>
90 #include <linux/skbuff.h>
91 #include <linux/delay.h>
92 #include <linux/debugfs.h>
93 #include <linux/seq_file.h>
94 #include <linux/kthread.h>
95 #include <linux/module.h>
96 #include <linux/moduleparam.h>
98 #include <linux/types.h>
99 #include <linux/slab.h>
100 #include <linux/delay.h>
101 #include <linux/init.h>
102 #include <linux/pci.h>
103 #include <linux/dma-mapping.h>
104 #include <linux/netdevice.h>
105 #include <linux/etherdevice.h>
106 #include <linux/mii.h>
107 #include <linux/if_vlan.h>
108 #include <linux/skbuff.h>
109 #include <linux/string.h>
110 #include <asm/unaligned.h>
112 #include <linux/ethtool.h>
113 #define SLIC_ETHTOOL_SUPPORT 1
115 #include <linux/uaccess.h>
117 #include "gbdownload.h"
118 #include "gbrcvucode.h"
119 #include "oasisrcvucode.h"
121 #ifdef DEBUG_MICROCODE
122 #include "oasisdbgdownload.h"
124 #include "oasisdownload.h"
127 #if SLIC_DUMP_ENABLED
128 #include "slicdump.h"
131 #define SLIC_POWER_MANAGEMENT 0
133 static uint slic_first_init = 1;
134 static char *slic_banner = "Alacritech SLIC Technology(tm) Server "\
135 "and Storage Accelerator (Non-Accelerated)\n";
137 static char *slic_proc_version = "2.0.351 2006/07/14 12:26:00";
138 static char *slic_product_name = "SLIC Technology(tm) Server "\
139 "and Storage Accelerator (Non-Accelerated)";
140 static char *slic_vendor = "Alacritech, Inc.";
142 static int slic_debug = 1;
143 static int debug = -1;
144 static struct net_device *head_netdevice;
146 base_driver_t slic_global = { {}, 0, 0, 0, 1, NULL, NULL };
147 static int intagg_delay = 100;
148 static u32 dynamic_intagg;
151 static unsigned int rcv_count;
152 static struct dentry *slic_debugfs;
154 #define DRV_NAME "slicoss"
155 #define DRV_VERSION "2.0.1"
156 #define DRV_AUTHOR "Alacritech, Inc. Engineering"
157 #define DRV_DESCRIPTION "Alacritech SLIC Techonology(tm) "\
158 "Non-Accelerated Driver"
159 #define DRV_COPYRIGHT "Copyright 2000-2006 Alacritech, Inc. "\
160 "All rights reserved."
161 #define PFX DRV_NAME " "
163 MODULE_AUTHOR(DRV_AUTHOR);
164 MODULE_DESCRIPTION(DRV_DESCRIPTION);
165 MODULE_LICENSE("Dual BSD/GPL");
167 module_param(dynamic_intagg, int, 0);
168 MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting");
169 module_param(intagg_delay, int, 0);
170 MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay");
172 static struct pci_device_id slic_pci_tbl[] __devinitdata = {
173 {PCI_VENDOR_ID_ALACRITECH,
175 PCI_ANY_ID, PCI_ANY_ID,},
176 {PCI_VENDOR_ID_ALACRITECH,
178 PCI_ANY_ID, PCI_ANY_ID,},
182 MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
184 #define SLIC_GET_SLIC_HANDLE(_adapter, _pslic_handle) \
186 SLIC_ACQUIRE_IRQ_SPINLOCK(_adapter->handle_lock); \
187 _pslic_handle = _adapter->pfree_slic_handles; \
188 if (_pslic_handle) { \
189 ASSERT(_pslic_handle->type == SLIC_HANDLE_FREE); \
190 _adapter->pfree_slic_handles = _pslic_handle->next; \
192 SLIC_RELEASE_IRQ_SPINLOCK(_adapter->handle_lock); \
195 #define SLIC_FREE_SLIC_HANDLE(_adapter, _pslic_handle) \
197 _pslic_handle->type = SLIC_HANDLE_FREE; \
198 SLIC_ACQUIRE_IRQ_SPINLOCK(_adapter->handle_lock); \
199 _pslic_handle->next = _adapter->pfree_slic_handles; \
200 _adapter->pfree_slic_handles = _pslic_handle; \
201 SLIC_RELEASE_IRQ_SPINLOCK(_adapter->handle_lock); \
204 static void slic_debug_init(void);
205 static void slic_debug_cleanup(void);
206 static void slic_debug_adapter_create(p_adapter_t adapter);
207 static void slic_debug_adapter_destroy(p_adapter_t adapter);
208 static void slic_debug_card_create(p_sliccard_t card);
209 static void slic_debug_card_destroy(p_sliccard_t card);
211 inline void slic_reg32_write(void __iomem *reg, ulong32 value, uint flush)
218 inline void slic_reg64_write(p_adapter_t adapter,
221 void __iomem *regh, ulong32 paddrh, uint flush)
223 SLIC_ACQUIRE_IRQ_SPINLOCK(adapter->bit64reglock);
224 if (paddrh != adapter->curaddrupper) {
225 adapter->curaddrupper = paddrh;
226 writel(paddrh, regh);
231 SLIC_RELEASE_IRQ_SPINLOCK(adapter->bit64reglock);
234 inline ulong32 slic_reg32_read(u32 __iomem *reg, uint flush)
239 inline ulong32 slic_reg16_read(pulong32 reg, uint flush)
241 return (ushort) readw(reg);
244 void slic_init_driver(void)
246 if (slic_first_init) {
247 DBG_MSG("slicoss: %s slic_first_init set jiffies[%lx]\n",
250 SLIC_INIT_SPINLOCK(slic_global.driver_lock);
255 static void slic_dbg_macaddrs(p_adapter_t adapter)
257 DBG_MSG(" (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
258 adapter->netdev->name, adapter->currmacaddr[0],
259 adapter->currmacaddr[1], adapter->currmacaddr[2],
260 adapter->currmacaddr[3], adapter->currmacaddr[4],
261 adapter->currmacaddr[5]);
262 DBG_MSG(" (%s) mac %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
263 adapter->netdev->name, adapter->macaddr[0],
264 adapter->macaddr[1], adapter->macaddr[2],
265 adapter->macaddr[3], adapter->macaddr[4], adapter->macaddr[5]);
269 #ifdef DEBUG_REGISTER_TRACE
270 static void slic_dbg_register_trace(p_adapter_t adapter, p_sliccard_t card)
274 DBG_ERROR("Dump Register Write Trace: curr_ix == %d\n", card->debug_ix);
275 for (i = 0; i < 32; i++) {
276 DBG_ERROR("%2d %d %4x %x %x\n",
277 i, card->reg_type[i], card->reg_offset[i],
278 card->reg_value[i], card->reg_valueh[i]);
284 static void slic_init_adapter(struct net_device *netdev,
285 struct pci_dev *pcidev,
286 const struct pci_device_id *pci_tbl_entry,
287 void __iomem *memaddr, int chip_idx)
290 pslic_handle_t pslic_handle;
291 p_adapter_t adapter = (p_adapter_t) netdev_priv(netdev);
294 DBG_MSG("slicoss: %s (%s)\n netdev [%p]\n adapter[%p]\n "
295 "pcidev [%p]\n", __func__, netdev->name, netdev, adapter, pcidev);*/
296 /* adapter->pcidev = pcidev;*/
297 adapter->vendid = pci_tbl_entry->vendor;
298 adapter->devid = pci_tbl_entry->device;
299 adapter->subsysid = pci_tbl_entry->subdevice;
300 adapter->busnumber = pcidev->bus->number;
301 adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F);
302 adapter->functionnumber = (pcidev->devfn & 0x7);
303 adapter->memorylength = pci_resource_len(pcidev, 0);
304 adapter->slic_regs = (p_slic_regs_t) memaddr;
305 adapter->irq = pcidev->irq;
306 /* adapter->netdev = netdev;*/
307 adapter->next_netdevice = head_netdevice;
308 head_netdevice = netdev;
309 adapter->chipid = chip_idx;
310 adapter->port = 0; /*adapter->functionnumber;*/
311 adapter->cardindex = adapter->port;
312 adapter->memorybase = memaddr;
313 SLIC_INIT_SPINLOCK(adapter->upr_lock);
314 SLIC_INIT_SPINLOCK(adapter->bit64reglock);
315 SLIC_INIT_SPINLOCK(adapter->adapter_lock);
316 SLIC_INIT_SPINLOCK(adapter->reset_lock);
317 SLIC_INIT_SPINLOCK(adapter->handle_lock);
319 adapter->card_size = 1;
321 Initialize slic_handle array
323 ASSERT(SLIC_CMDQ_MAXCMDS <= 0xFFFF);
325 Start with 1. 0 is an invalid host handle.
327 for (index = 1, pslic_handle = &adapter->slic_handles[1];
328 index < SLIC_CMDQ_MAXCMDS; index++, pslic_handle++) {
330 pslic_handle->token.handle_index = index;
331 pslic_handle->type = SLIC_HANDLE_FREE;
332 pslic_handle->next = adapter->pfree_slic_handles;
333 adapter->pfree_slic_handles = pslic_handle;
336 DBG_MSG(".........\nix[%d] phandle[%p] pfree[%p] next[%p]\n",
337 index, pslic_handle, adapter->pfree_slic_handles, pslic_handle->next);*/
338 adapter->pshmem = (p_slic_shmem_t) pci_alloc_consistent(adapter->pcidev,
344 DBG_MSG("slicoss: %s (%s)\n pshmem [%p]\n phys_shmem[%p]\n"\
345 "slic_regs [%p]\n", __func__, netdev->name, adapter->pshmem,
346 (pvoid)adapter->phys_shmem, adapter->slic_regs);
348 ASSERT(adapter->pshmem);
350 SLIC_ZERO_MEMORY(adapter->pshmem, sizeof(slic_shmem_t));
355 int __devinit slic_entry_probe(struct pci_dev *pcidev,
356 const struct pci_device_id *pci_tbl_entry)
358 static int cards_found;
359 static int did_version;
361 struct net_device *netdev;
363 void __iomem *memmapped_ioaddr = NULL;
365 ulong mmio_start = 0;
367 p_sliccard_t card = NULL;
369 DBG_MSG("slicoss: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
370 __func__, jiffies, smp_processor_id());
372 slic_global.dynamic_intagg = dynamic_intagg;
374 err = pci_enable_device(pcidev);
376 DBG_MSG("Call pci_enable_device(%p) status[%x]\n", pcidev, err);
380 if (slic_debug > 0 && did_version++ == 0) {
382 printk(slic_proc_version);
385 err = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);
387 DBG_MSG("pci_set_dma_mask(DMA_64BIT_MASK) successful\n");
389 err = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
392 ("No usable DMA configuration, aborting err[%x]\n",
396 DBG_MSG("pci_set_dma_mask(DMA_32BIT_MASK) successful\n");
399 DBG_MSG("Call pci_request_regions\n");
401 err = pci_request_regions(pcidev, DRV_NAME);
403 DBG_MSG("pci_request_regions FAILED err[%x]\n", err);
407 DBG_MSG("call pci_set_master\n");
408 pci_set_master(pcidev);
410 DBG_MSG("call alloc_etherdev\n");
411 netdev = alloc_etherdev(sizeof(adapter_t));
414 goto err_out_exit_slic_probe;
416 DBG_MSG("alloc_etherdev for slic netdev[%p]\n", netdev);
418 SET_NETDEV_DEV(netdev, &pcidev->dev);
420 pci_set_drvdata(pcidev, netdev);
421 adapter = netdev_priv(netdev);
422 adapter->netdev = netdev;
423 adapter->pcidev = pcidev;
425 mmio_start = pci_resource_start(pcidev, 0);
426 mmio_len = pci_resource_len(pcidev, 0);
428 DBG_MSG("slicoss: call ioremap(mmio_start[%lx], mmio_len[%lx])\n",
429 mmio_start, mmio_len);
431 /* memmapped_ioaddr = (ulong32)ioremap_nocache(mmio_start, mmio_len);*/
432 memmapped_ioaddr = ioremap(mmio_start, mmio_len);
433 DBG_MSG("slicoss: %s MEMMAPPED_IOADDR [%p]\n", __func__,
435 if (!memmapped_ioaddr) {
436 DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
437 __func__, mmio_len, mmio_start);
438 goto err_out_free_mmio_region;
442 ("slicoss: %s found Alacritech SLICOSS PCI, MMIO at %p, "\
443 "start[%lx] len[%lx], IRQ %d.\n",
444 __func__, memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq);
446 slic_config_pci(pcidev);
450 slic_init_adapter(netdev,
451 pcidev, pci_tbl_entry, memmapped_ioaddr, cards_found);
453 status = slic_card_locate(adapter);
455 DBG_ERROR("%s cannot locate card\n", __func__);
456 goto err_out_free_mmio_region;
459 card = adapter->card;
461 if (!adapter->allocated) {
462 card->adapters_allocated++;
463 adapter->allocated = 1;
466 DBG_MSG("slicoss: %s card: %p\n", __func__,
468 DBG_MSG("slicoss: %s card->adapter[%d] == [%p]\n", __func__,
469 (uint) adapter->port, adapter);
470 DBG_MSG("slicoss: %s card->adapters_allocated [%d]\n", __func__,
471 card->adapters_allocated);
472 DBG_MSG("slicoss: %s card->adapters_activated [%d]\n", __func__,
473 card->adapters_activated);
475 status = slic_card_init(card, adapter);
477 if (status != STATUS_SUCCESS) {
478 card->state = CARD_FAIL;
479 adapter->state = ADAPT_FAIL;
480 adapter->linkstate = LINK_DOWN;
481 DBG_ERROR("slic_card_init FAILED status[%x]\n", status);
483 slic_adapter_set_hwaddr(adapter);
486 netdev->base_addr = (unsigned long)adapter->memorybase;
487 netdev->irq = adapter->irq;
488 netdev->open = slic_entry_open;
489 netdev->stop = slic_entry_halt;
490 netdev->hard_start_xmit = slic_xmit_start;
491 netdev->do_ioctl = slic_ioctl;
492 netdev->set_mac_address = slic_mac_set_address;
493 #if SLIC_GET_STATS_ENABLED
494 netdev->get_stats = slic_get_stats;
496 netdev->set_multicast_list = slic_mcast_set_list;
498 slic_debug_adapter_create(adapter);
500 strcpy(netdev->name, "eth%d");
501 err = register_netdev(netdev);
503 DBG_ERROR("Cannot register net device, aborting.\n");
508 ("slicoss: addr 0x%lx, irq %d, MAC addr "\
509 "%02X:%02X:%02X:%02X:%02X:%02X\n",
510 mmio_start, /*pci_resource_start(pcidev, 0), */ pcidev->irq,
511 netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
512 netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
515 DBG_MSG("slicoss: %s EXIT status[%x] jiffies[%lx] cpu %d\n",
516 __func__, status, jiffies, smp_processor_id());
521 iounmap(memmapped_ioaddr);
523 err_out_free_mmio_region:
524 release_mem_region(mmio_start, mmio_len);
526 err_out_exit_slic_probe:
527 DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies,
533 int slic_entry_open(struct net_device *dev)
535 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
536 p_sliccard_t card = adapter->card;
543 ("slicoss: %s adapter->activated[%d] card->adapters[%x] "\
544 "allocd[%x]\n", __func__, adapter->activated,
545 card->adapters_activated,
546 card->adapters_allocated);
548 ("slicoss: %s (%s): [jiffies[%lx] cpu %d] dev[%p] adapt[%p] "\
549 "port[%d] card[%p]\n",
550 __func__, adapter->netdev->name, jiffies, smp_processor_id(),
551 adapter->netdev, adapter, adapter->port, card);
553 netif_stop_queue(adapter->netdev);
555 SLIC_ACQUIRE_IRQ_SPINLOCK(slic_global.driver_lock);
557 if (!adapter->activated) {
558 card->adapters_activated++;
559 slic_global.num_slic_ports_active++;
560 adapter->activated = 1;
562 status = slic_if_init(adapter);
564 if (status != STATUS_SUCCESS) {
565 if (adapter->activated) {
566 card->adapters_activated--;
567 slic_global.num_slic_ports_active--;
568 adapter->activated = 0;
571 SLIC_RELEASE_IRQ_SPINLOCK(slic_global.driver_lock);
576 DBG_MSG("slicoss: %s set card->master[%p] adapter[%p]\n", __func__,
577 card->master, adapter);
579 card->master = adapter;
580 #if SLIC_DUMP_ENABLED
581 if (!(card->dumpthread_running))
582 init_waitqueue_head(&card->dump_wq);
586 SLIC_RELEASE_IRQ_SPINLOCK(slic_global.driver_lock);
589 #if SLIC_DUMP_ENABLED
590 if (!(card->dumpthread_running)) {
591 DBG_MSG("attempt to initialize dump thread\n");
592 status = slic_init_dump_thread(card);
594 Even if the dump thread fails, we will continue at this point
599 return STATUS_SUCCESS;
602 void __devexit slic_entry_remove(struct pci_dev *pcidev)
604 struct net_device *dev = pci_get_drvdata(pcidev);
605 ulong32 mmio_start = 0;
607 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
611 DBG_MSG("slicoss: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
613 slic_adapter_freeresources(adapter);
614 slic_unmap_mmio_space(adapter);
615 DBG_MSG("slicoss: %s unregister_netdev\n", __func__);
616 unregister_netdev(dev);
618 mmio_start = pci_resource_start(pcidev, 0);
619 mmio_len = pci_resource_len(pcidev, 0);
621 DBG_MSG("slicoss: %s rel_region(0) start[%x] len[%x]\n", __func__,
622 mmio_start, mmio_len);
623 release_mem_region(mmio_start, mmio_len);
625 DBG_MSG("slicoss: %s iounmap dev->base_addr[%x]\n", __func__,
626 (uint) dev->base_addr);
627 iounmap((void __iomem *)dev->base_addr);
628 ASSERT(adapter->card);
629 card = adapter->card;
630 ASSERT(card->adapters_allocated);
631 card->adapters_allocated--;
632 adapter->allocated = 0;
634 ("slicoss: %s init[%x] alloc[%x] card[%p] adapter[%p]\n",
635 __func__, card->adapters_activated, card->adapters_allocated,
637 if (!card->adapters_allocated) {
638 p_sliccard_t curr_card = slic_global.slic_card;
639 if (curr_card == card) {
640 slic_global.slic_card = card->next;
642 while (curr_card->next != card)
643 curr_card = curr_card->next;
645 curr_card->next = card->next;
647 ASSERT(slic_global.num_slic_cards);
648 slic_global.num_slic_cards--;
649 slic_card_cleanup(card);
651 DBG_MSG("slicoss: %s deallocate device\n", __func__);
652 SLIC_DEALLOCATE_MEM(dev);
653 DBG_MSG("slicoss: %s EXIT\n", __func__);
656 int slic_entry_halt(struct net_device *dev)
658 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
659 p_sliccard_t card = adapter->card;
660 p_slic_regs_t slic_regs = adapter->slic_regs;
662 SLIC_ACQUIRE_IRQ_SPINLOCK(slic_global.driver_lock);
664 DBG_MSG("slicoss: %s (%s) ENTER\n", __func__, dev->name);
665 DBG_MSG("slicoss: %s (%s) actvtd[%d] alloc[%d] state[%x] adapt[%p]\n",
666 __func__, dev->name, card->adapters_activated,
667 card->adapters_allocated, card->state, adapter);
668 slic_if_stop_queue(adapter);
669 adapter->state = ADAPT_DOWN;
670 adapter->linkstate = LINK_DOWN;
671 adapter->upr_list = NULL;
672 adapter->upr_busy = 0;
673 adapter->devflags_prev = 0;
674 DBG_MSG("slicoss: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
675 __func__, dev->name, adapter, adapter->state);
676 ASSERT(card->adapter[adapter->cardindex] == adapter);
677 WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
678 adapter->all_reg_writes++;
679 adapter->icr_reg_writes++;
680 slic_config_clear(adapter);
681 DBG_MSG("slicoss: %s (%s) dev[%p] adapt[%p] card[%p]\n",
682 __func__, dev->name, dev, adapter, card);
683 if (adapter->activated) {
684 card->adapters_activated--;
685 slic_global.num_slic_ports_active--;
686 adapter->activated = 0;
688 #ifdef AUTOMATIC_RESET
689 WRITE_REG(slic_regs->slic_reset_iface, 0, FLUSH);
692 * Reset the adapter's rsp, cmd, and rcv queues
694 slic_cmdq_reset(adapter);
695 slic_rspqueue_reset(adapter);
696 slic_rcvqueue_reset(adapter);
698 #ifdef AUTOMATIC_RESET
699 if (!card->adapters_activated) {
701 #if SLIC_DUMP_ENABLED
702 if (card->dumpthread_running) {
704 DBG_MSG("attempt to terminate dump thread pid[%x]\n",
706 status = kill_proc(card->dump_task_id->pid, SIGKILL, 1);
709 int count = 10 * 100;
710 while (card->dumpthread_running && --count) {
711 current->state = TASK_INTERRUPTIBLE;
717 ("slicmon thread cleanup FAILED \
719 card->dump_task_id->pid);
724 DBG_MSG("slicoss: %s (%s) initiate CARD_HALT\n", __func__,
727 slic_card_init(card, adapter);
731 DBG_MSG("slicoss: %s (%s) EXIT\n", __func__, dev->name);
732 DBG_MSG("slicoss: %s EXIT\n", __func__);
733 SLIC_RELEASE_IRQ_SPINLOCK(slic_global.driver_lock);
734 return STATUS_SUCCESS;
737 int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
741 DBG_MSG("slicoss: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev);
744 case SIOCSLICSETINTAGG:
746 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
750 if (copy_from_user(data, rq->ifr_data, 28)) {
752 ("copy_from_user FAILED getting initial \
758 "%s: set interrupt aggregation to %d\n",
760 slic_intagg_set(adapter, intagg);
763 #ifdef SLIC_USER_REQUEST_DUMP_ENABLED
764 case SIOCSLICDUMPCARD:
766 p_adapter_t adapter = (p_adapter_t) dev->priv;
770 ASSERT(adapter->card)
771 card = adapter->card;
773 DBG_IOCTL("slic_ioctl SIOCSLIC_DUMP_CARD\n");
775 if (card->dump_requested == SLIC_DUMP_DONE) {
777 "SLIC Card dump to be overwritten\n");
778 card->dump_requested = SLIC_DUMP_REQUESTED;
779 } else if ((card->dump_requested == SLIC_DUMP_REQUESTED)
780 || (card->dump_requested ==
781 SLIC_DUMP_IN_PROGRESS)) {
783 "SLIC Card dump Requested but already \
784 in progress... ignore\n");
787 "SLIC Card #%d Dump Requested\n",
789 card->dump_requested = SLIC_DUMP_REQUESTED;
795 #ifdef SLIC_TRACE_DUMP_ENABLED
796 case SIOCSLICTRACEDUMP:
801 DBG_IOCTL("slic_ioctl SIOCSLIC_TRACE_DUMP\n");
803 if (copy_from_user(data, rq->ifr_data, 28)) {
805 ("slic: copy_from_user FAILED getting \
806 initial simba param\n");
811 if (tracemon_request == SLIC_DUMP_DONE) {
813 ("ATK Diagnostic Trace Dump Requested\n");
814 tracemon_request = SLIC_DUMP_REQUESTED;
815 tracemon_request_type = value;
816 tracemon_timestamp = jiffies;
817 } else if ((tracemon_request == SLIC_DUMP_REQUESTED) ||
819 SLIC_DUMP_IN_PROGRESS)) {
821 ("ATK Diagnostic Trace Dump Requested but \
822 already in progress... ignore\n");
825 ("ATK Diagnostic Trace Dump Requested\n");
826 tracemon_request = SLIC_DUMP_REQUESTED;
827 tracemon_request_type = value;
828 tracemon_timestamp = jiffies;
833 #if SLIC_ETHTOOL_SUPPORT
836 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
837 struct ethtool_cmd data;
838 struct ethtool_cmd ecmd;
841 /* DBG_MSG("slicoss: %s SIOCETHTOOL\n", __func__); */
842 if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
845 if (ecmd.cmd == ETHTOOL_GSET) {
847 (SUPPORTED_10baseT_Half |
848 SUPPORTED_10baseT_Full |
849 SUPPORTED_100baseT_Half |
850 SUPPORTED_100baseT_Full |
851 SUPPORTED_Autoneg | SUPPORTED_MII);
852 data.port = PORT_MII;
853 data.transceiver = XCVR_INTERNAL;
854 data.phy_address = 0;
855 if (adapter->linkspeed == LINK_100MB)
856 data.speed = SPEED_100;
857 else if (adapter->linkspeed == LINK_10MB)
858 data.speed = SPEED_10;
862 if (adapter->linkduplex == LINK_FULLD)
863 data.duplex = DUPLEX_FULL;
865 data.duplex = DUPLEX_HALF;
867 data.autoneg = AUTONEG_ENABLE;
871 (rq->ifr_data, &data, sizeof(data)))
874 } else if (ecmd.cmd == ETHTOOL_SSET) {
875 if (!capable(CAP_NET_ADMIN))
878 if (adapter->linkspeed == LINK_100MB)
879 data.speed = SPEED_100;
880 else if (adapter->linkspeed == LINK_10MB)
881 data.speed = SPEED_10;
885 if (adapter->linkduplex == LINK_FULLD)
886 data.duplex = DUPLEX_FULL;
888 data.duplex = DUPLEX_HALF;
890 data.autoneg = AUTONEG_ENABLE;
893 if ((ecmd.speed != data.speed) ||
894 (ecmd.duplex != data.duplex)) {
898 if (ecmd.speed == SPEED_10) {
901 ("%s: slic ETHTOOL set \
905 speed = PCR_SPEED_100;
907 ("%s: slic ETHTOOL set \
911 if (ecmd.duplex == DUPLEX_FULL) {
912 duplex = PCR_DUPLEX_FULL;
914 (": duplex==FULL\n");
918 (": duplex==HALF\n");
920 slic_link_config(adapter,
922 slic_link_event_handler(adapter);
929 /* DBG_MSG("slicoss: %s UNSUPPORTED[%x]\n", __func__, cmd); */
934 #define XMIT_FAIL_LINK_STATE 1
935 #define XMIT_FAIL_ZERO_LENGTH 2
936 #define XMIT_FAIL_HOSTCMD_FAIL 3
938 static void slic_xmit_build_request(p_adapter_t adapter,
939 p_slic_hostcmd_t hcmd, struct sk_buff *skb)
941 p_slic_host64_cmd_t ihcmd;
944 ihcmd = &hcmd->cmd64;
946 ihcmd->flags = (adapter->port << IHFLG_IFSHFT);
947 ihcmd->command = IHCMD_XMT_REQ;
948 ihcmd->u.slic_buffers.totlen = skb->len;
949 phys_addr = SLIC_GET_DMA_ADDRESS_WRITE(adapter, skb->data, skb->len);
950 ihcmd->u.slic_buffers.bufs[0].paddrl = SLIC_GET_ADDR_LOW(phys_addr);
951 ihcmd->u.slic_buffers.bufs[0].paddrh = SLIC_GET_ADDR_HIGH(phys_addr);
952 ihcmd->u.slic_buffers.bufs[0].length = skb->len;
953 #if defined(CONFIG_X86_64)
954 hcmd->cmdsize = (ulong32) ((((ulong64)&ihcmd->u.slic_buffers.bufs[1] -
955 (ulong64) hcmd) + 31) >> 5);
956 #elif defined(CONFIG_X86)
957 hcmd->cmdsize = ((((ulong32) &ihcmd->u.slic_buffers.bufs[1] -
958 (ulong32) hcmd) + 31) >> 5);
964 #define NORMAL_ETHFRAME 0
966 int slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
969 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
970 p_slic_hostcmd_t hcmd = NULL;
972 ulong32 skbtype = NORMAL_ETHFRAME;
973 pvoid offloadcmd = NULL;
975 card = adapter->card;
978 DBG_ERROR("xmit_start (%s) ENTER skb[%p] len[%d] linkstate[%x] state[%x]\n",
979 adapter->netdev->name, skb, skb->len, adapter->linkstate,
982 if ((adapter->linkstate != LINK_UP) ||
983 (adapter->state != ADAPT_UP) || (card->state != CARD_UP)) {
984 status = XMIT_FAIL_LINK_STATE;
987 } else if (skb->len == 0) {
988 status = XMIT_FAIL_ZERO_LENGTH;
992 if (skbtype == NORMAL_ETHFRAME) {
993 hcmd = slic_cmdq_getfree(adapter);
995 adapter->xmitq_full = 1;
996 status = XMIT_FAIL_HOSTCMD_FAIL;
999 ASSERT(hcmd->pslic_handle);
1000 ASSERT(hcmd->cmd64.hosthandle ==
1001 hcmd->pslic_handle->token.handle_token);
1004 hcmd->type = SLIC_CMD_DUMB;
1005 if (skbtype == NORMAL_ETHFRAME)
1006 slic_xmit_build_request(adapter, hcmd, skb);
1008 adapter->stats.tx_packets++;
1009 adapter->stats.tx_bytes += skb->len;
1012 if (adapter->kill_card) {
1013 p_slic_host64_cmd_t ihcmd;
1015 ihcmd = &hcmd->cmd64;
1017 ihcmd->flags |= 0x40;
1018 adapter->kill_card = 0; /* only do this once */
1021 if (hcmd->paddrh == 0) {
1022 WRITE_REG(adapter->slic_regs->slic_cbar,
1023 (hcmd->paddrl | hcmd->cmdsize), DONT_FLUSH);
1025 WRITE_REG64(adapter,
1026 adapter->slic_regs->slic_cbar64,
1027 (hcmd->paddrl | hcmd->cmdsize),
1028 adapter->slic_regs->slic_addr_upper,
1029 hcmd->paddrh, DONT_FLUSH);
1034 slic_xmit_fail(adapter, skb, offloadcmd, skbtype, status);
1038 void slic_xmit_fail(p_adapter_t adapter,
1039 struct sk_buff *skb,
1040 pvoid cmd, ulong32 skbtype, ulong32 status)
1042 if (adapter->xmitq_full)
1043 slic_if_stop_queue(adapter);
1044 if ((cmd == NULL) && (status <= XMIT_FAIL_HOSTCMD_FAIL)) {
1046 case XMIT_FAIL_LINK_STATE:
1048 ("(%s) reject xmit skb[%p: %x] linkstate[%s] \
1049 adapter[%s:%d] card[%s:%d]\n",
1050 adapter->netdev->name, skb, skb->pkt_type,
1051 SLIC_LINKSTATE(adapter->linkstate),
1052 SLIC_ADAPTER_STATE(adapter->state), adapter->state,
1053 SLIC_CARD_STATE(adapter->card->state),
1054 adapter->card->state);
1056 case XMIT_FAIL_ZERO_LENGTH:
1058 ("xmit_start skb->len == 0 skb[%p] type[%x]!!!! \n",
1059 skb, skb->pkt_type);
1061 case XMIT_FAIL_HOSTCMD_FAIL:
1063 ("xmit_start skb[%p] type[%x] No host commands \
1065 skb, skb->pkt_type);
1072 adapter->stats.tx_dropped++;
1075 void slic_xmit_timeout(struct net_device *dev)
1078 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
1082 card = adapter->card;
1084 for (i = 0; i < card->card_size; i++) {
1085 if (card->adapter[i])
1086 slic_if_stop_queue(card->adapter[i]);
1088 if (!card->reset_in_progress) {
1090 ("%s card[%p] state[%x] adapter[%p] port[%d] state[%x]\n",
1091 __func__, card, card->state, adapter, adapter->port,
1093 slic_card_reset(adapter);
1097 void slic_rcv_handle_error(p_adapter_t adapter, p_slic_rcvbuf_t rcvbuf)
1099 p_slic_hddr_wds hdr = (p_slic_hddr_wds) rcvbuf->data;
1101 if (adapter->devid != SLIC_1GB_DEVICE_ID) {
1102 if (hdr->frame_status14 & VRHSTAT_802OE)
1103 adapter->if_events.oflow802++;
1104 if (hdr->frame_status14 & VRHSTAT_TPOFLO)
1105 adapter->if_events.Tprtoflow++;
1106 if (hdr->frame_status_b14 & VRHSTATB_802UE)
1107 adapter->if_events.uflow802++;
1108 if (hdr->frame_status_b14 & VRHSTATB_RCVE) {
1109 adapter->if_events.rcvearly++;
1110 adapter->stats.rx_fifo_errors++;
1112 if (hdr->frame_status_b14 & VRHSTATB_BUFF) {
1113 adapter->if_events.Bufov++;
1114 adapter->stats.rx_over_errors++;
1116 if (hdr->frame_status_b14 & VRHSTATB_CARRE) {
1117 adapter->if_events.Carre++;
1118 adapter->stats.tx_carrier_errors++;
1120 if (hdr->frame_status_b14 & VRHSTATB_LONGE)
1121 adapter->if_events.Longe++;
1122 if (hdr->frame_status_b14 & VRHSTATB_PREA)
1123 adapter->if_events.Invp++;
1124 if (hdr->frame_status_b14 & VRHSTATB_CRC) {
1125 adapter->if_events.Crc++;
1126 adapter->stats.rx_crc_errors++;
1128 if (hdr->frame_status_b14 & VRHSTATB_DRBL)
1129 adapter->if_events.Drbl++;
1130 if (hdr->frame_status_b14 & VRHSTATB_CODE)
1131 adapter->if_events.Code++;
1132 if (hdr->frame_status_b14 & VRHSTATB_TPCSUM)
1133 adapter->if_events.TpCsum++;
1134 if (hdr->frame_status_b14 & VRHSTATB_TPHLEN)
1135 adapter->if_events.TpHlen++;
1136 if (hdr->frame_status_b14 & VRHSTATB_IPCSUM)
1137 adapter->if_events.IpCsum++;
1138 if (hdr->frame_status_b14 & VRHSTATB_IPLERR)
1139 adapter->if_events.IpLen++;
1140 if (hdr->frame_status_b14 & VRHSTATB_IPHERR)
1141 adapter->if_events.IpHlen++;
1143 if (hdr->frame_statusGB & VGBSTAT_XPERR) {
1144 ulong32 xerr = hdr->frame_statusGB >> VGBSTAT_XERRSHFT;
1146 if (xerr == VGBSTAT_XCSERR)
1147 adapter->if_events.TpCsum++;
1148 if (xerr == VGBSTAT_XUFLOW)
1149 adapter->if_events.Tprtoflow++;
1150 if (xerr == VGBSTAT_XHLEN)
1151 adapter->if_events.TpHlen++;
1153 if (hdr->frame_statusGB & VGBSTAT_NETERR) {
1156 frame_statusGB >> VGBSTAT_NERRSHFT) &
1158 if (nerr == VGBSTAT_NCSERR)
1159 adapter->if_events.IpCsum++;
1160 if (nerr == VGBSTAT_NUFLOW)
1161 adapter->if_events.IpLen++;
1162 if (nerr == VGBSTAT_NHLEN)
1163 adapter->if_events.IpHlen++;
1165 if (hdr->frame_statusGB & VGBSTAT_LNKERR) {
1166 ulong32 lerr = hdr->frame_statusGB & VGBSTAT_LERRMSK;
1168 if (lerr == VGBSTAT_LDEARLY)
1169 adapter->if_events.rcvearly++;
1170 if (lerr == VGBSTAT_LBOFLO)
1171 adapter->if_events.Bufov++;
1172 if (lerr == VGBSTAT_LCODERR)
1173 adapter->if_events.Code++;
1174 if (lerr == VGBSTAT_LDBLNBL)
1175 adapter->if_events.Drbl++;
1176 if (lerr == VGBSTAT_LCRCERR)
1177 adapter->if_events.Crc++;
1178 if (lerr == VGBSTAT_LOFLO)
1179 adapter->if_events.oflow802++;
1180 if (lerr == VGBSTAT_LUFLO)
1181 adapter->if_events.uflow802++;
1187 #define TCP_OFFLOAD_FRAME_PUSHFLAG 0x10000000
1188 #define M_FAST_PATH 0x0040
1190 void slic_rcv_handler(p_adapter_t adapter)
1192 struct sk_buff *skb;
1193 p_slic_rcvbuf_t rcvbuf;
1196 while ((skb = slic_rcvqueue_getnext(adapter))) {
1200 rcvbuf = (p_slic_rcvbuf_t) skb->head;
1201 adapter->card->events++;
1202 if (rcvbuf->status & IRHDDR_ERR) {
1203 adapter->rx_errors++;
1204 slic_rcv_handle_error(adapter, rcvbuf);
1205 slic_rcvqueue_reinsert(adapter, skb);
1209 if (!slic_mac_filter(adapter, (p_ether_header) rcvbuf->data)) {
1212 ("slicoss: %s (%s) drop frame due to mac filter\n",
1213 __func__, adapter->netdev->name);
1215 slic_rcvqueue_reinsert(adapter, skb);
1218 skb_pull(skb, SLIC_RCVBUF_HEADSIZE);
1219 rx_bytes = (rcvbuf->length & IRHDDR_FLEN_MSK);
1220 skb_put(skb, rx_bytes);
1221 adapter->stats.rx_packets++;
1222 adapter->stats.rx_bytes += rx_bytes;
1223 #if SLIC_OFFLOAD_IP_CHECKSUM
1224 skb->ip_summed = CHECKSUM_UNNECESSARY;
1227 skb->dev = adapter->netdev;
1228 skb->protocol = eth_type_trans(skb, skb->dev);
1232 #if SLIC_INTERRUPT_PROCESS_LIMIT
1233 if (frames >= SLIC_RCVQ_MAX_PROCESS_ISR) {
1234 adapter->rcv_interrupt_yields++;
1239 adapter->max_isr_rcvs = max(adapter->max_isr_rcvs, frames);
1242 void slic_xmit_complete(p_adapter_t adapter)
1244 p_slic_hostcmd_t hcmd;
1245 p_slic_rspbuf_t rspbuf;
1247 slic_handle_word_t slic_handle_word;
1250 rspbuf = slic_rspqueue_getnext(adapter);
1253 adapter->xmit_completes++;
1254 adapter->card->events++;
1256 Get the complete host command buffer
1258 slic_handle_word.handle_token = rspbuf->hosthandle;
1259 ASSERT(slic_handle_word.handle_index);
1260 ASSERT(slic_handle_word.handle_index <= SLIC_CMDQ_MAXCMDS);
1262 (p_slic_hostcmd_t) adapter->slic_handles[slic_handle_word.
1265 /* hcmd = (p_slic_hostcmd_t) rspbuf->hosthandle; */
1267 ASSERT(hcmd->pslic_handle ==
1268 &adapter->slic_handles[slic_handle_word.handle_index]);
1270 DBG_ERROR("xmit_complete (%s) hcmd[%p] hosthandle[%x]\n",
1271 adapter->netdev->name, hcmd, hcmd->cmd64.hosthandle);
1272 DBG_ERROR(" skb[%p] len %d hcmdtype[%x]\n", hcmd->skb,
1273 hcmd->skb->len, hcmd->type);
1275 if (hcmd->type == SLIC_CMD_DUMB) {
1277 dev_kfree_skb_irq(hcmd->skb);
1278 slic_cmdq_putdone_irq(adapter, hcmd);
1281 rspbuf->hosthandle = 0;
1284 adapter->max_isr_xmits = max(adapter->max_isr_xmits, frames);
1287 static irqreturn_t slic_interrupt(int irq, void *dev_id)
1289 struct net_device *dev = (struct net_device *) dev_id;
1290 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
1293 if ((adapter->pshmem) && (adapter->pshmem->isr)) {
1294 WRITE_REG(adapter->slic_regs->slic_icr, ICR_INT_MASK, FLUSH);
1295 isr = adapter->isrcopy = adapter->pshmem->isr;
1296 adapter->pshmem->isr = 0;
1297 adapter->num_isrs++;
1298 switch (adapter->card->state) {
1300 if (isr & ~ISR_IO) {
1301 if (isr & ISR_ERR) {
1302 adapter->error_interrupts++;
1303 if (isr & ISR_RMISS) {
1308 p_slic_rcvqueue_t rcvq =
1312 error_rmiss_interrupts++;
1314 rcv_count = rcvq->count;
1315 pre_count = rcvq->count;
1316 errors = rcvq->errors;
1318 while (rcvq->count <
1319 SLIC_RCVQ_FILLTHRESH) {
1327 ("(%s): [%x] ISR_RMISS \
1328 initial[%x] pre[%x] \
1331 adapter->netdev->name,
1332 isr, rcv_count, pre_count,
1333 errors, rcvq->count);
1334 } else if (isr & ISR_XDROP) {
1336 ("isr & ISR_ERR [%x] \
1341 ("isr & ISR_ERR [%x]\n",
1346 if (isr & ISR_LEVENT) {
1347 /*DBG_MSG("%s (%s) ISR_LEVENT \n",
1348 __func__, adapter->netdev->name);*/
1349 adapter->linkevent_interrupts++;
1350 slic_link_event_handler(adapter);
1353 if ((isr & ISR_UPC) ||
1354 (isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
1355 adapter->upr_interrupts++;
1356 slic_upr_request_complete(adapter, isr);
1360 if (isr & ISR_RCV) {
1361 adapter->rcv_interrupts++;
1362 slic_rcv_handler(adapter);
1365 if (isr & ISR_CMD) {
1366 adapter->xmit_interrupts++;
1367 slic_xmit_complete(adapter);
1372 if ((isr & ISR_UPC) ||
1373 (isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
1374 adapter->upr_interrupts++;
1375 slic_upr_request_complete(adapter, isr);
1383 adapter->isrcopy = 0;
1384 adapter->all_reg_writes += 2;
1385 adapter->isr_reg_writes++;
1386 WRITE_REG(adapter->slic_regs->slic_isr, 0, FLUSH);
1388 adapter->false_interrupts++;
1394 * slic_link_event_handler -
1396 * Initiate a link configuration sequence. The link configuration begins
1397 * by issuing a READ_LINK_STATUS command to the Utility Processor on the
1398 * SLIC. Since the command finishes asynchronously, the slic_upr_comlete
1399 * routine will follow it up witha UP configuration write command, which
1400 * will also complete asynchronously.
1403 void slic_link_event_handler(p_adapter_t adapter)
1406 p_slic_shmem_t pshmem;
1408 if (adapter->state != ADAPT_UP) {
1409 /* Adapter is not operational. Ignore. */
1413 pshmem = (p_slic_shmem_t) adapter->phys_shmem;
1415 #if defined(CONFIG_X86_64)
1417 DBG_MSG("slic_event_handler pshmem->linkstatus[%x] pshmem[%p]\n \
1418 &linkstatus[%p] &isr[%p]\n", adapter->pshmem->linkstatus, pshmem,
1419 &pshmem->linkstatus, &pshmem->isr);
1421 status = slic_upr_request(adapter,
1423 SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
1424 SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
1426 #elif defined(CONFIG_X86)
1427 status = slic_upr_request(adapter, SLIC_UPR_RLSR,
1428 (ulong32) &pshmem->linkstatus, /* no 4GB wrap guaranteed */
1433 ASSERT((status == STATUS_SUCCESS) || (status == STATUS_PENDING));
1436 void slic_init_cleanup(p_adapter_t adapter)
1438 DBG_MSG("slicoss: %s ENTER adapter[%p] ", __func__, adapter);
1439 if (adapter->intrregistered) {
1440 DBG_MSG("FREE_IRQ ");
1441 adapter->intrregistered = 0;
1442 free_irq(adapter->netdev->irq, adapter->netdev);
1445 if (adapter->pshmem) {
1446 DBG_MSG("FREE_SHMEM ");
1447 DBG_MSG("adapter[%p] port %d pshmem[%p] FreeShmem ",
1448 adapter, adapter->port, (pvoid) adapter->pshmem);
1449 pci_free_consistent(adapter->pcidev,
1450 sizeof(slic_shmem_t),
1451 adapter->pshmem, adapter->phys_shmem);
1452 adapter->pshmem = NULL;
1453 adapter->phys_shmem = (dma_addr_t) NULL;
1455 #if SLIC_GET_STATS_TIMER_ENABLED
1456 if (adapter->statstimerset) {
1457 DBG_MSG("statstimer ");
1458 adapter->statstimerset = 0;
1459 del_timer(&adapter->statstimer);
1462 #if !SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED
1463 /*#if SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED*/
1464 if (adapter->pingtimerset) {
1465 DBG_MSG("pingtimer ");
1466 adapter->pingtimerset = 0;
1467 del_timer(&adapter->pingtimer);
1470 slic_rspqueue_free(adapter);
1471 slic_cmdq_free(adapter);
1472 slic_rcvqueue_free(adapter);
1477 #if SLIC_GET_STATS_ENABLED
1478 struct net_device_stats *slic_get_stats(struct net_device *dev)
1480 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
1481 struct net_device_stats *stats;
1484 stats = &adapter->stats;
1485 stats->collisions = adapter->slic_stats.iface.xmit_collisions;
1486 stats->rx_errors = adapter->slic_stats.iface.rcv_errors;
1487 stats->tx_errors = adapter->slic_stats.iface.xmt_errors;
1488 stats->rx_missed_errors = adapter->slic_stats.iface.rcv_discards;
1489 stats->tx_heartbeat_errors = 0;
1490 stats->tx_aborted_errors = 0;
1491 stats->tx_window_errors = 0;
1492 stats->tx_fifo_errors = 0;
1493 stats->rx_frame_errors = 0;
1494 stats->rx_length_errors = 0;
1495 return &adapter->stats;
1500 * Allocate a mcast_address structure to hold the multicast address.
1503 int slic_mcast_add_list(p_adapter_t adapter, pchar address)
1505 p_mcast_address_t mcaddr, mlist;
1508 /* Check to see if it already exists */
1509 mlist = adapter->mcastaddrs;
1511 ETHER_EQ_ADDR(mlist->address, address, equaladdr);
1513 return STATUS_SUCCESS;
1514 mlist = mlist->next;
1517 /* Doesn't already exist. Allocate a structure to hold it */
1518 mcaddr = SLIC_ALLOCATE_MEM(sizeof(mcast_address_t), GFP_ATOMIC);
1522 memcpy(mcaddr->address, address, 6);
1524 mcaddr->next = adapter->mcastaddrs;
1525 adapter->mcastaddrs = mcaddr;
1527 return STATUS_SUCCESS;
1531 * Functions to obtain the CRC corresponding to the destination mac address.
1532 * This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using
1534 * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 +
1537 * After the CRC for the 6 bytes is generated (but before the value is
1539 * we must then transpose the value and return bits 30-23.
1542 static u32 slic_crc_table[256]; /* Table of CRCs for all possible byte values */
1543 static u32 slic_crc_init; /* Is table initialized */
1546 * Contruct the CRC32 table
1548 void slic_mcast_init_crc32(void)
1550 ulong32 c; /* CRC shit reg */
1551 ulong32 e = 0; /* Poly X-or pattern */
1552 int i; /* counter */
1553 int k; /* byte being shifted into crc */
1555 static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
1557 for (i = 0; i < sizeof(p) / sizeof(int); i++)
1558 e |= 1L << (31 - p[i]);
1560 for (i = 1; i < 256; i++) {
1563 c = c & 1 ? (c >> 1) ^ e : c >> 1;
1564 slic_crc_table[i] = c;
1569 * Return the MAC hast as described above.
1571 uchar slic_mcast_get_mac_hash(pchar macaddr)
1578 if (!slic_crc_init) {
1579 slic_mcast_init_crc32();
1583 crc = 0xFFFFFFFF; /* Preload shift register, per crc-32 spec */
1584 for (i = 0, p = macaddr; i < 6; ++p, ++i)
1585 crc = (crc >> 8) ^ slic_crc_table[(crc ^ *p) & 0xFF];
1587 /* Return bits 1-8, transposed */
1588 for (i = 1; i < 9; i++)
1589 machash |= (((crc >> i) & 1) << (8 - i));
1594 void slic_mcast_set_bit(p_adapter_t adapter, pchar address)
1598 /* Get the CRC polynomial for the mac address */
1599 crcpoly = slic_mcast_get_mac_hash(address);
1601 /* We only have space on the SLIC for 64 entries. Lop
1602 * off the top two bits. (2^6 = 64)
1606 /* OR in the new bit into our 64 bit mask. */
1607 adapter->mcastmask |= (ulong64) 1 << crcpoly;
1610 void slic_mcast_set_list(struct net_device *dev)
1612 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
1613 int status = STATUS_SUCCESS;
1616 struct dev_mc_list *mc_list = dev->mc_list;
1617 int mc_count = dev->mc_count;
1621 for (i = 1; i <= mc_count; i++) {
1622 addresses = (pchar) &mc_list->dmi_addr;
1623 if (mc_list->dmi_addrlen == 6) {
1624 status = slic_mcast_add_list(adapter, addresses);
1625 if (status != STATUS_SUCCESS)
1631 slic_mcast_set_bit(adapter, addresses);
1632 mc_list = mc_list->next;
1635 DBG_MSG("%s a->devflags_prev[%x] dev->flags[%x] status[%x]\n",
1636 __func__, adapter->devflags_prev, dev->flags, status);
1637 if (adapter->devflags_prev != dev->flags) {
1638 adapter->macopts = MAC_DIRECTED;
1640 if (dev->flags & IFF_BROADCAST)
1641 adapter->macopts |= MAC_BCAST;
1642 if (dev->flags & IFF_PROMISC)
1643 adapter->macopts |= MAC_PROMISC;
1644 if (dev->flags & IFF_ALLMULTI)
1645 adapter->macopts |= MAC_ALLMCAST;
1646 if (dev->flags & IFF_MULTICAST)
1647 adapter->macopts |= MAC_MCAST;
1649 adapter->devflags_prev = dev->flags;
1650 DBG_MSG("%s call slic_config_set adapter->macopts[%x]\n",
1651 __func__, adapter->macopts);
1652 slic_config_set(adapter, TRUE);
1654 if (status == STATUS_SUCCESS)
1655 slic_mcast_set_mask(adapter);
1660 void slic_mcast_set_mask(p_adapter_t adapter)
1662 p_slic_regs_t slic_regs = adapter->slic_regs;
1664 DBG_MSG("%s ENTER (%s) macopts[%x] mask[%llx]\n", __func__,
1665 adapter->netdev->name, (uint) adapter->macopts,
1666 adapter->mcastmask);
1668 if (adapter->macopts & (MAC_ALLMCAST | MAC_PROMISC)) {
1669 /* Turn on all multicast addresses. We have to do this for
1670 * promiscuous mode as well as ALLMCAST mode. It saves the
1671 * Microcode from having to keep state about the MAC
1674 /* DBG_MSG("slicoss: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n\
1675 SLUT MODE!!!\n",__func__); */
1676 WRITE_REG(slic_regs->slic_mcastlow, 0xFFFFFFFF, FLUSH);
1677 WRITE_REG(slic_regs->slic_mcasthigh, 0xFFFFFFFF, FLUSH);
1678 /* DBG_MSG("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",
1679 _func__, adapter->netdev->name); */
1681 /* Commit our multicast mast to the SLIC by writing to the
1682 * multicast address mask registers
1684 DBG_MSG("%s (%s) WRITE mcastlow[%x] mcasthigh[%x]\n",
1685 __func__, adapter->netdev->name,
1686 ((ulong) (adapter->mcastmask & 0xFFFFFFFF)),
1687 ((ulong) ((adapter->mcastmask >> 32) & 0xFFFFFFFF)));
1689 WRITE_REG(slic_regs->slic_mcastlow,
1690 (ulong32) (adapter->mcastmask & 0xFFFFFFFF), FLUSH);
1691 WRITE_REG(slic_regs->slic_mcasthigh,
1692 (ulong32) ((adapter->mcastmask >> 32) & 0xFFFFFFFF),
1697 void slic_timer_ping(ulong dev)
1699 p_adapter_t adapter;
1703 adapter = (p_adapter_t) ((struct net_device *) dev)->priv;
1705 card = adapter->card;
1707 #if !SLIC_DUMP_ENABLED
1708 /*#if SLIC_DUMP_ENABLED*/
1709 if ((adapter->state == ADAPT_UP) && (card->state == CARD_UP)) {
1712 if (card->pingstatus != ISR_PINGMASK) {
1713 if (errormsg++ < 5) {
1715 ("%s (%s) CARD HAS CRASHED PING_status == \
1717 __func__, adapter->netdev->name,
1718 card->pingstatus, errormsg);
1720 /* ASSERT(card->pingstatus == ISR_PINGMASK); */
1722 if (goodmsg++ < 5) {
1724 ("slicoss: %s (%s) PING_status == %x \
1725 GOOD!!!!!!!! msg# %d\n",
1726 __func__, adapter->netdev->name,
1727 card->pingstatus, errormsg);
1730 card->pingstatus = 0;
1731 status = slic_upr_request(adapter, SLIC_UPR_PING, 0, 0, 0, 0);
1733 ASSERT(status == 0);
1735 DBG_MSG("slicoss %s (%s) adapter[%p] NOT UP!!!!\n",
1736 __func__, adapter->netdev->name, adapter);
1739 adapter->pingtimer.expires =
1740 jiffies + SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
1741 add_timer(&adapter->pingtimer);
1744 void slic_if_stop_queue(p_adapter_t adapter)
1746 netif_stop_queue(adapter->netdev);
1749 void slic_if_start_queue(p_adapter_t adapter)
1751 netif_start_queue(adapter->netdev);
1757 * Perform initialization of our slic interface.
1760 int slic_if_init(p_adapter_t adapter)
1762 p_sliccard_t card = adapter->card;
1763 struct net_device *dev = adapter->netdev;
1764 p_slic_regs_t slic_regs = adapter->slic_regs;
1765 p_slic_shmem_t pshmem;
1769 DBG_MSG("slicoss: %s (%s) ENTER states[%d:%d:%d:%d] flags[%x]\n",
1770 __func__, adapter->netdev->name,
1771 adapter->queues_initialized, adapter->state, adapter->linkstate,
1772 card->state, dev->flags);
1774 /* adapter should be down at this point */
1775 if (adapter->state != ADAPT_DOWN) {
1776 DBG_ERROR("slic_if_init adapter->state != ADAPT_DOWN\n");
1779 ASSERT(adapter->linkstate == LINK_DOWN);
1781 adapter->devflags_prev = dev->flags;
1782 adapter->macopts = MAC_DIRECTED;
1784 DBG_MSG("slicoss: %s (%s) Set MAC options: ", __func__,
1785 adapter->netdev->name);
1786 if (dev->flags & IFF_BROADCAST) {
1787 adapter->macopts |= MAC_BCAST;
1790 if (dev->flags & IFF_PROMISC) {
1791 adapter->macopts |= MAC_PROMISC;
1792 DBG_MSG("PROMISC ");
1794 if (dev->flags & IFF_ALLMULTI) {
1795 adapter->macopts |= MAC_ALLMCAST;
1796 DBG_MSG("ALL_MCAST ");
1798 if (dev->flags & IFF_MULTICAST) {
1799 adapter->macopts |= MAC_MCAST;
1804 status = slic_adapter_allocresources(adapter);
1805 if (status != STATUS_SUCCESS) {
1807 ("slic_if_init: slic_adapter_allocresources FAILED %x\n",
1809 slic_adapter_freeresources(adapter);
1813 if (!adapter->queues_initialized) {
1814 DBG_MSG("slicoss: %s call slic_rspqueue_init\n", __func__);
1815 if (slic_rspqueue_init(adapter))
1818 ("slicoss: %s call slic_cmdq_init adapter[%p] port %d \n",
1819 __func__, adapter, adapter->port);
1820 if (slic_cmdq_init(adapter))
1823 ("slicoss: %s call slic_rcvqueue_init adapter[%p] \
1824 port %d \n", __func__, adapter, adapter->port);
1825 if (slic_rcvqueue_init(adapter))
1827 adapter->queues_initialized = 1;
1829 DBG_MSG("slicoss: %s disable interrupts(slic)\n", __func__);
1831 WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
1834 if (!adapter->isp_initialized) {
1835 pshmem = (p_slic_shmem_t) adapter->phys_shmem;
1837 SLIC_ACQUIRE_IRQ_SPINLOCK(adapter->bit64reglock);
1839 #if defined(CONFIG_X86_64)
1840 WRITE_REG(slic_regs->slic_addr_upper,
1841 SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
1842 WRITE_REG(slic_regs->slic_isp,
1843 SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
1844 #elif defined(CONFIG_X86)
1845 WRITE_REG(slic_regs->slic_addr_upper, (ulong32) 0, DONT_FLUSH);
1846 WRITE_REG(slic_regs->slic_isp, (ulong32) &pshmem->isr, FLUSH);
1850 SLIC_RELEASE_IRQ_SPINLOCK(adapter->bit64reglock);
1851 adapter->isp_initialized = 1;
1854 adapter->state = ADAPT_UP;
1855 if (!card->loadtimerset) {
1856 init_timer(&card->loadtimer);
1857 card->loadtimer.expires =
1858 jiffies + SLIC_SECS_TO_JIFFS(SLIC_LOADTIMER_PERIOD);
1859 card->loadtimer.data = (ulong) card;
1860 card->loadtimer.function = &slic_timer_load_check;
1861 add_timer(&card->loadtimer);
1863 card->loadtimerset = 1;
1865 #if SLIC_GET_STATS_TIMER_ENABLED
1866 if (!adapter->statstimerset) {
1867 DBG_MSG("slicoss: %s start getstats_timer(slic)\n",
1869 init_timer(&adapter->statstimer);
1870 adapter->statstimer.expires =
1871 jiffies + SLIC_SECS_TO_JIFFS(STATS_TIMER_INTERVAL);
1872 adapter->statstimer.data = (ulong) adapter->netdev;
1873 adapter->statstimer.function = &slic_timer_get_stats;
1874 add_timer(&adapter->statstimer);
1875 adapter->statstimerset = 1;
1878 #if !SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED
1879 /*#if SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED*/
1880 if (!adapter->pingtimerset) {
1881 DBG_MSG("slicoss: %s start card_ping_timer(slic)\n",
1883 init_timer(&adapter->pingtimer);
1884 adapter->pingtimer.expires =
1885 jiffies + SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
1886 adapter->pingtimer.data = (ulong) dev;
1887 adapter->pingtimer.function = &slic_timer_ping;
1888 add_timer(&adapter->pingtimer);
1889 adapter->pingtimerset = 1;
1890 adapter->card->pingstatus = ISR_PINGMASK;
1895 * clear any pending events, then enable interrupts
1897 DBG_MSG("slicoss: %s ENABLE interrupts(slic)\n", __func__);
1898 adapter->isrcopy = 0;
1899 adapter->pshmem->isr = 0;
1900 WRITE_REG(slic_regs->slic_isr, 0, FLUSH);
1901 WRITE_REG(slic_regs->slic_icr, ICR_INT_ON, FLUSH);
1903 DBG_MSG("slicoss: %s call slic_link_config(slic)\n", __func__);
1904 slic_link_config(adapter, LINK_AUTOSPEED, LINK_AUTOD);
1905 slic_link_event_handler(adapter);
1907 DBG_MSG("slicoss: %s EXIT\n", __func__);
1908 return STATUS_SUCCESS;
1911 void slic_unmap_mmio_space(p_adapter_t adapter)
1913 #if LINUX_FREES_ADAPTER_RESOURCES
1914 if (adapter->slic_regs)
1915 iounmap(adapter->slic_regs);
1916 adapter->slic_regs = NULL;
1920 int slic_adapter_allocresources(p_adapter_t adapter)
1922 if (!adapter->intrregistered) {
1926 ("slicoss: %s AllocAdaptRsrcs adapter[%p] shmem[%p] \
1927 phys_shmem[%p] dev->irq[%x] %x\n",
1928 __func__, adapter, adapter->pshmem,
1929 (void *)adapter->phys_shmem, adapter->netdev->irq,
1932 SLIC_RELEASE_IRQ_SPINLOCK(slic_global.driver_lock);
1934 retval = request_irq(adapter->netdev->irq,
1937 adapter->netdev->name, adapter->netdev);
1939 SLIC_ACQUIRE_IRQ_SPINLOCK(slic_global.driver_lock);
1942 DBG_ERROR("slicoss: request_irq (%s) FAILED [%x]\n",
1943 adapter->netdev->name, retval);
1946 adapter->intrregistered = 1;
1948 ("slicoss: %s AllocAdaptRsrcs adapter[%p] shmem[%p] \
1949 pshmem[%p] dev->irq[%x]\n",
1950 __func__, adapter, adapter->pshmem,
1951 (void *)adapter->pshmem, adapter->netdev->irq);
1953 return STATUS_SUCCESS;
1956 void slic_config_pci(struct pci_dev *pcidev)
1961 pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
1962 DBG_MSG("slicoss: %s PCI command[%4.4x]\n", __func__, pci_command);
1964 new_command = pci_command | PCI_COMMAND_MASTER
1965 | PCI_COMMAND_MEMORY
1966 | PCI_COMMAND_INVALIDATE
1967 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
1968 if (pci_command != new_command) {
1969 DBG_MSG("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n",
1970 __func__, pci_command, new_command);
1971 pci_write_config_word(pcidev, PCI_COMMAND, new_command);
1975 void slic_adapter_freeresources(p_adapter_t adapter)
1977 DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
1978 slic_init_cleanup(adapter);
1979 SLIC_ZERO_MEMORY(&adapter->stats, sizeof(struct net_device_stats));
1980 adapter->error_interrupts = 0;
1981 adapter->rcv_interrupts = 0;
1982 adapter->xmit_interrupts = 0;
1983 adapter->linkevent_interrupts = 0;
1984 adapter->upr_interrupts = 0;
1985 adapter->num_isrs = 0;
1986 adapter->xmit_completes = 0;
1987 adapter->rcv_broadcasts = 0;
1988 adapter->rcv_multicasts = 0;
1989 adapter->rcv_unicasts = 0;
1990 DBG_MSG("slicoss: %s EXIT\n", __func__);
1996 * Write phy control to configure link duplex/speed
1999 void slic_link_config(p_adapter_t adapter,
2000 ulong32 linkspeed, ulong32 linkduplex)
2006 ulong32 phy_gctlreg;
2008 if (adapter->state != ADAPT_UP) {
2010 ("%s (%s) ADAPT Not up yet, Return! speed[%x] duplex[%x]\n",
2011 __func__, adapter->netdev->name, linkspeed,
2015 DBG_MSG("slicoss: %s (%s) slic_link_config: speed[%x] duplex[%x]\n",
2016 __func__, adapter->netdev->name, linkspeed, linkduplex);
2018 ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
2019 || (adapter->devid == SLIC_2GB_DEVICE_ID));
2021 if (linkspeed > LINK_1000MB)
2022 linkspeed = LINK_AUTOSPEED;
2023 if (linkduplex > LINK_AUTOD)
2024 linkduplex = LINK_AUTOD;
2026 if ((linkspeed == LINK_AUTOSPEED) || (linkspeed == LINK_1000MB)) {
2027 if (adapter->flags & ADAPT_FLAGS_FIBERMEDIA) {
2028 /* We've got a fiber gigabit interface, and register
2029 * 4 is different in fiber mode than in copper mode
2032 /* advertise FD only @1000 Mb */
2033 phy_advreg = (MIICR_REG_4 | (PAR_ADV1000XFD));
2034 /* enable PAUSE frames */
2035 phy_advreg |= PAR_ASYMPAUSE_FIBER;
2036 WRITE_REG(adapter->slic_regs->slic_wphy, phy_advreg,
2039 if (linkspeed == LINK_AUTOSPEED) {
2040 /* reset phy, enable auto-neg */
2043 (PCR_RESET | PCR_AUTONEG |
2045 WRITE_REG(adapter->slic_regs->slic_wphy,
2047 } else { /* forced 1000 Mb FD*/
2048 /* power down phy to break link
2049 this may not work) */
2050 phy_config = (MIICR_REG_PCR | PCR_POWERDOWN);
2051 WRITE_REG(adapter->slic_regs->slic_wphy,
2053 /* wait, Marvell says 1 sec,
2054 try to get away with 10 ms */
2055 slic_stall_msec(10);
2057 /* disable auto-neg, set speed/duplex,
2058 soft reset phy, powerup */
2061 (PCR_RESET | PCR_SPEED_1000 |
2063 WRITE_REG(adapter->slic_regs->slic_wphy,
2066 } else { /* copper gigabit */
2068 /* Auto-Negotiate or 1000 Mb must be auto negotiated
2069 * We've got a copper gigabit interface, and
2070 * register 4 is different in copper mode than
2073 if (linkspeed == LINK_AUTOSPEED) {
2074 /* advertise 10/100 Mb modes */
2077 (PAR_ADV100FD | PAR_ADV100HD | PAR_ADV10FD
2080 /* linkspeed == LINK_1000MB -
2081 don't advertise 10/100 Mb modes */
2082 phy_advreg = MIICR_REG_4;
2084 /* enable PAUSE frames */
2085 phy_advreg |= PAR_ASYMPAUSE;
2086 /* required by the Cicada PHY */
2087 phy_advreg |= PAR_802_3;
2088 WRITE_REG(adapter->slic_regs->slic_wphy, phy_advreg,
2090 /* advertise FD only @1000 Mb */
2091 phy_gctlreg = (MIICR_REG_9 | (PGC_ADV1000FD));
2092 WRITE_REG(adapter->slic_regs->slic_wphy, phy_gctlreg,
2095 if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
2097 enable auto crossover */
2099 (MIICR_REG_16 | (MRV_REG16_XOVERON));
2100 WRITE_REG(adapter->slic_regs->slic_wphy,
2103 /* reset phy, enable auto-neg */
2106 (PCR_RESET | PCR_AUTONEG |
2108 WRITE_REG(adapter->slic_regs->slic_wphy,
2110 } else { /* it's a Cicada PHY */
2111 /* enable and restart auto-neg (don't reset) */
2114 (PCR_AUTONEG | PCR_AUTONEG_RST));
2115 WRITE_REG(adapter->slic_regs->slic_wphy,
2121 if (linkspeed == LINK_10MB)
2124 speed = PCR_SPEED_100;
2125 if (linkduplex == LINK_HALFD)
2128 duplex = PCR_DUPLEX_FULL;
2130 if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
2132 disable auto crossover */
2133 phy_config = (MIICR_REG_16 | (MRV_REG16_XOVEROFF));
2134 WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
2138 /* power down phy to break link (this may not work) */
2139 phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN | speed | duplex));
2140 WRITE_REG(adapter->slic_regs->slic_wphy, phy_config, FLUSH);
2142 /* wait, Marvell says 1 sec, try to get away with 10 ms */
2143 slic_stall_msec(10);
2145 if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
2147 disable auto-neg, set speed,
2148 soft reset phy, powerup */
2150 (MIICR_REG_PCR | (PCR_RESET | speed | duplex));
2151 WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
2153 } else { /* it's a Cicada PHY */
2154 /* disable auto-neg, set speed, powerup */
2155 phy_config = (MIICR_REG_PCR | (speed | duplex));
2156 WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
2162 ("slicoss: %s (%s) EXIT slic_link_config : state[%d] \
2163 phy_config[%x]\n", __func__, adapter->netdev->name, adapter->state,
2167 void slic_card_cleanup(p_sliccard_t card)
2169 DBG_MSG("slicoss: %s ENTER\n", __func__);
2171 #if SLIC_DUMP_ENABLED
2172 if (card->dumpbuffer) {
2173 SLIC_DEALLOCATE_MEM(card->dumpbuffer);
2174 card->dumpbuffer = NULL;
2175 card->dumpbuffer_phys = 0;
2176 card->dumpbuffer_physl = 0;
2177 card->dumpbuffer_physh = 0;
2179 if (card->cmdbuffer) {
2180 SLIC_DEALLOCATE_MEM(card->cmdbuffer);
2181 card->cmdbuffer = NULL;
2182 card->cmdbuffer_phys = 0;
2183 card->cmdbuffer_physl = 0;
2184 card->cmdbuffer_physh = 0;
2188 if (card->loadtimerset) {
2189 card->loadtimerset = 0;
2190 del_timer(&card->loadtimer);
2193 slic_debug_card_destroy(card);
2195 SLIC_DEALLOCATE_MEM(card);
2196 DBG_MSG("slicoss: %s EXIT\n", __func__);
2199 static int slic_card_download_gbrcv(p_adapter_t adapter)
2201 p_slic_regs_t slic_regs = adapter->slic_regs;
2203 puchar instruction = NULL;
2204 ulong32 rcvucodelen = 0;
2206 switch (adapter->devid) {
2207 case SLIC_2GB_DEVICE_ID:
2208 instruction = (puchar) &OasisRcvUCode[0];
2209 rcvucodelen = OasisRcvUCodeLen;
2211 case SLIC_1GB_DEVICE_ID:
2212 instruction = (puchar) &GBRcvUCode[0];
2213 rcvucodelen = GBRcvUCodeLen;
2220 /* start download */
2221 WRITE_REG(slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH);
2223 /* download the rcv sequencer ucode */
2224 for (codeaddr = 0; codeaddr < rcvucodelen; codeaddr++) {
2225 /* write out instruction address */
2226 WRITE_REG(slic_regs->slic_rcv_wcs, codeaddr, FLUSH);
2228 /* write out the instruction data low addr */
2229 WRITE_REG(slic_regs->slic_rcv_wcs,
2230 (ulong32) *(pulong32) instruction, FLUSH);
2233 /* write out the instruction data high addr */
2234 WRITE_REG(slic_regs->slic_rcv_wcs, (ulong32) *instruction,
2239 /* download finished */
2240 WRITE_REG(slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
2245 int slic_card_download(p_adapter_t adapter)
2248 int thissectionsize;
2250 p_slic_regs_t slic_regs = adapter->slic_regs;
2251 ulong32 *instruction = NULL;
2252 ulong32 *lastinstruct = NULL;
2253 ulong32 *startinstruct = NULL;
2254 puchar nextinstruct;
2255 ulong32 baseaddress;
2258 ulong32 numsects = 0;
2259 ulong32 sectsize[3];
2260 ulong32 sectstart[3];
2262 /* DBG_MSG ("slicoss: %s (%s) adapter[%p] card[%p] devid[%x] \
2263 jiffies[%lx] cpu %d\n", __func__, adapter->netdev->name, adapter,
2264 adapter->card, adapter->devid,jiffies, smp_processor_id()); */
2266 switch (adapter->devid) {
2267 case SLIC_2GB_DEVICE_ID:
2268 /* DBG_MSG ("slicoss: %s devid==SLIC_2GB_DEVICE_ID sections[%x]\n",
2269 __func__, (uint) ONumSections); */
2270 numsects = ONumSections;
2271 for (i = 0; i < numsects; i++) {
2272 sectsize[i] = OSectionSize[i];
2273 sectstart[i] = OSectionStart[i];
2276 case SLIC_1GB_DEVICE_ID:
2277 /* DBG_MSG ("slicoss: %s devid==SLIC_1GB_DEVICE_ID sections[%x]\n",
2278 __func__, (uint) MNumSections); */
2279 numsects = MNumSections;
2280 for (i = 0; i < numsects; i++) {
2281 sectsize[i] = MSectionSize[i];
2282 sectstart[i] = MSectionStart[i];
2290 ASSERT(numsects <= 3);
2292 for (section = 0; section < numsects; section++) {
2293 switch (adapter->devid) {
2294 case SLIC_2GB_DEVICE_ID:
2295 instruction = (pulong32) &OasisUCode[section][0];
2296 baseaddress = sectstart[section];
2297 thissectionsize = sectsize[section] >> 3;
2299 (pulong32) &OasisUCode[section][sectsize[section] -
2302 case SLIC_1GB_DEVICE_ID:
2303 instruction = (pulong32) &MojaveUCode[section][0];
2304 baseaddress = sectstart[section];
2305 thissectionsize = sectsize[section] >> 3;
2307 (pulong32) &MojaveUCode[section][sectsize[section]
2315 baseaddress = sectstart[section];
2316 thissectionsize = sectsize[section] >> 3;
2318 for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
2319 startinstruct = instruction;
2320 nextinstruct = ((puchar) instruction) + 8;
2321 /* Write out instruction address */
2322 WRITE_REG(slic_regs->slic_wcs, baseaddress + codeaddr,
2324 /* Write out instruction to low addr */
2325 WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
2326 #ifdef CONFIG_X86_64
2327 instruction = (pulong32) ((puchar) instruction + 4);
2331 /* Write out instruction to high addr */
2332 WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
2333 #ifdef CONFIG_X86_64
2334 instruction = (pulong32) ((puchar) instruction + 4);
2341 for (section = 0; section < numsects; section++) {
2342 switch (adapter->devid) {
2343 case SLIC_2GB_DEVICE_ID:
2344 instruction = (pulong32) &OasisUCode[section][0];
2346 case SLIC_1GB_DEVICE_ID:
2347 instruction = (pulong32) &MojaveUCode[section][0];
2354 baseaddress = sectstart[section];
2355 if (baseaddress < 0x8000)
2357 thissectionsize = sectsize[section] >> 3;
2359 /* DBG_MSG ("slicoss: COMPARE secton[%x] baseaddr[%x] sectnsize[%x]\n",
2360 (uint)section,baseaddress,thissectionsize);*/
2362 for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
2363 /* Write out instruction address */
2364 WRITE_REG(slic_regs->slic_wcs,
2365 SLIC_WCS_COMPARE | (baseaddress + codeaddr),
2367 /* Write out instruction to low addr */
2368 WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
2369 #ifdef CONFIG_X86_64
2370 instruction = (pulong32) ((puchar) instruction + 4);
2374 /* Write out instruction to high addr */
2375 WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
2376 #ifdef CONFIG_X86_64
2377 instruction = (pulong32) ((puchar) instruction + 4);
2381 /* Check SRAM location zero. If it is non-zero. Abort.*/
2382 failure = READ_REG(slic_regs->slic_reset, 0);
2385 ("slicoss: %s FAILURE EXIT codeaddr[%x] \
2386 thissectionsize[%x] failure[%x]\n",
2387 __func__, codeaddr, thissectionsize,
2394 /* DBG_MSG ("slicoss: Compare done\n");*/
2396 /* Everything OK, kick off the card */
2397 slic_stall_msec(10);
2398 WRITE_REG(slic_regs->slic_wcs, SLIC_WCS_START, FLUSH);
2400 /* stall for 20 ms, long enough for ucode to init card
2401 and reach mainloop */
2402 slic_stall_msec(20);
2404 DBG_MSG("slicoss: %s (%s) EXIT adapter[%p] card[%p]\n",
2405 __func__, adapter->netdev->name, adapter, adapter->card);
2407 return STATUS_SUCCESS;
2410 void slic_adapter_set_hwaddr(p_adapter_t adapter)
2412 p_sliccard_t card = adapter->card;
2414 /* DBG_MSG ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n",
2415 __func__, card->config_set, adapter->port, adapter->physport,
2416 adapter->functionnumber);
2418 slic_dbg_macaddrs(adapter); */
2420 if ((adapter->card) && (card->config_set)) {
2421 memcpy(adapter->macaddr,
2422 card->config.MacInfo[adapter->functionnumber].macaddrA,
2423 sizeof(slic_config_mac_t));
2424 /* DBG_MSG ("%s AFTER copying from config.macinfo into currmacaddr\n",
2426 slic_dbg_macaddrs(adapter);*/
2427 if (!(adapter->currmacaddr[0] || adapter->currmacaddr[1] ||
2428 adapter->currmacaddr[2] || adapter->currmacaddr[3] ||
2429 adapter->currmacaddr[4] || adapter->currmacaddr[5])) {
2430 memcpy(adapter->currmacaddr, adapter->macaddr, 6);
2432 if (adapter->netdev) {
2433 memcpy(adapter->netdev->dev_addr, adapter->currmacaddr,
2437 /* DBG_MSG ("%s EXIT port %d\n", __func__, adapter->port);
2438 slic_dbg_macaddrs(adapter); */
2441 void slic_card_halt(p_sliccard_t card, p_adapter_t adapter)
2443 p_slic_regs_t slic_regs = adapter->slic_regs;
2445 DBG_MSG("slicoss: %s ENTER card[%p] adapter[%p] card->state[%x]\n",
2446 __func__, card, adapter, card->state);
2447 WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
2448 adapter->all_reg_writes++;
2449 adapter->icr_reg_writes++;
2450 slic_config_clear(adapter);
2451 WRITE_REG(slic_regs->slic_reset_iface, 0, FLUSH);
2452 slic_soft_reset(adapter);
2453 DBG_MSG("slicoss: %s EXIT card[%p] adapter[%p] card->state[%x]\n",
2454 __func__, card, adapter, card->state);
2459 void slic_intagg_set(p_adapter_t adapter, ulong32 value)
2461 p_slic_regs_t slic_regs = adapter->slic_regs;
2463 WRITE_REG(slic_regs->slic_intagg, value, FLUSH);
2464 adapter->card->loadlevel_current = value;
2467 int slic_card_init(p_sliccard_t card, p_adapter_t adapter)
2469 p_slic_regs_t slic_regs = adapter->slic_regs;
2470 pslic_eeprom_t peeprom;
2471 poslic_eeprom_t pOeeprom;
2472 dma_addr_t phys_config;
2473 ulong32 phys_configh;
2474 ulong32 phys_configl;
2476 p_slic_shmem_t pshmem;
2478 uint macaddrs = card->card_size;
2483 pslic_config_mac_t pmac;
2490 ("slicoss: %s ENTER card[%p] adapter[%p] card->state[%x] \
2491 size[%d]\n", __func__, card, adapter, card->state, card->card_size);
2493 /* Reset everything except PCI configuration space */
2494 slic_soft_reset(adapter);
2496 /* Download the microcode */
2497 status = slic_card_download(adapter);
2499 if (status != STATUS_SUCCESS) {
2500 DBG_ERROR("SLIC download failed bus %d slot %d\n",
2501 (uint) adapter->busnumber,
2502 (uint) adapter->slotnumber);
2506 if (!card->config_set) {
2507 peeprom = pci_alloc_consistent(adapter->pcidev,
2508 sizeof(slic_eeprom_t),
2511 phys_configl = SLIC_GET_ADDR_LOW(phys_config);
2512 phys_configh = SLIC_GET_ADDR_HIGH(phys_config);
2514 DBG_MSG("slicoss: %s Eeprom info adapter [%p]\n "
2515 "size [%x]\n peeprom [%p]\n "
2516 "phys_config [%p]\n phys_configl[%x]\n "
2517 "phys_configh[%x]\n",
2518 __func__, adapter, (ulong32) sizeof(slic_eeprom_t),
2519 peeprom, (pvoid) phys_config, phys_configl,
2523 ("SLIC eeprom read failed to get memory bus %d \
2525 (uint) adapter->busnumber,
2526 (uint) adapter->slotnumber);
2529 SLIC_ZERO_MEMORY(peeprom, sizeof(slic_eeprom_t));
2531 WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
2533 pshmem = (p_slic_shmem_t) adapter->phys_shmem;
2535 SLIC_ACQUIRE_IRQ_SPINLOCK(adapter->bit64reglock);
2536 WRITE_REG(slic_regs->slic_addr_upper, 0, DONT_FLUSH);
2537 WRITE_REG(slic_regs->slic_isp,
2538 SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
2539 SLIC_RELEASE_IRQ_SPINLOCK(adapter->bit64reglock);
2541 slic_config_get(adapter, phys_configl, phys_configh);
2544 if (adapter->pshmem->isr) {
2545 DBG_MSG("%s shmem[%p] shmem->isr[%x]\n",
2546 __func__, adapter->pshmem,
2547 adapter->pshmem->isr);
2549 if (adapter->pshmem->isr & ISR_UPC) {
2550 adapter->pshmem->isr = 0;
2551 WRITE_REG64(adapter,
2552 slic_regs->slic_isp,
2554 slic_regs->slic_addr_upper,
2556 WRITE_REG(slic_regs->slic_isr, 0,
2559 slic_upr_request_complete(adapter, 0);
2562 adapter->pshmem->isr = 0;
2563 WRITE_REG(slic_regs->slic_isr, 0,
2571 ("SLIC: %d config data fetch timed\
2572 out!\n", adapter->port);
2573 DBG_MSG("%s shmem[%p] shmem->isr[%x]\n",
2574 __func__, adapter->pshmem,
2575 adapter->pshmem->isr);
2576 WRITE_REG64(adapter,
2577 slic_regs->slic_isp, 0,
2578 slic_regs->slic_addr_upper,
2585 switch (adapter->devid) {
2587 case SLIC_2GB_DEVICE_ID:
2588 /* extract EEPROM data and pointers to EEPROM data */
2589 pOeeprom = (poslic_eeprom_t) peeprom;
2590 eecodesize = pOeeprom->EecodeSize;
2591 dramsize = pOeeprom->DramSize;
2592 pmac = pOeeprom->MacInfo;
2593 fruformat = pOeeprom->FruFormat;
2594 patkfru = &pOeeprom->AtkFru;
2595 oemfruformat = pOeeprom->OemFruFormat;
2596 poemfru = &pOeeprom->OemFru;
2598 /* Minor kludge for Oasis card
2599 get 2 MAC addresses from the
2600 EEPROM to ensure that function 1
2601 gets the Port 1 MAC address */
2604 /* extract EEPROM data and pointers to EEPROM data */
2605 eecodesize = peeprom->EecodeSize;
2606 dramsize = peeprom->DramSize;
2607 pmac = peeprom->u2.mac.MacInfo;
2608 fruformat = peeprom->FruFormat;
2609 patkfru = &peeprom->AtkFru;
2610 oemfruformat = peeprom->OemFruFormat;
2611 poemfru = &peeprom->OemFru;
2615 card->config.EepromValid = FALSE;
2617 /* see if the EEPROM is valid by checking it's checksum */
2618 if ((eecodesize <= MAX_EECODE_SIZE) &&
2619 (eecodesize >= MIN_EECODE_SIZE)) {
2622 *(pushort) ((pchar) peeprom + (eecodesize - 2));
2624 calculate the EEPROM checksum
2627 ~slic_eeprom_cksum((pchar) peeprom,
2630 if the ucdoe chksum flag bit worked,
2631 we wouldn't need this shit
2633 if (ee_chksum == calc_chksum)
2634 card->config.EepromValid = TRUE;
2636 /* copy in the DRAM size */
2637 card->config.DramSize = dramsize;
2639 /* copy in the MAC address(es) */
2640 for (i = 0; i < macaddrs; i++) {
2641 memcpy(&card->config.MacInfo[i],
2642 &pmac[i], sizeof(slic_config_mac_t));
2644 /* DBG_MSG ("%s EEPROM Checksum Good? %d MacAddress\n",__func__,
2645 card->config.EepromValid); */
2647 /* copy the Alacritech FRU information */
2648 card->config.FruFormat = fruformat;
2649 memcpy(&card->config.AtkFru, patkfru, sizeof(atk_fru_t));
2651 pci_free_consistent(adapter->pcidev,
2652 sizeof(slic_eeprom_t),
2653 peeprom, phys_config);
2655 ("slicoss: %s adapter%d [%p] size[%x] FREE peeprom[%p] \
2657 __func__, adapter->port, adapter,
2658 (ulong32) sizeof(slic_eeprom_t), peeprom,
2659 (pvoid) phys_config);
2661 if ((!card->config.EepromValid) &&
2662 (adapter->reg_params.fail_on_bad_eeprom)) {
2663 WRITE_REG64(adapter,
2664 slic_regs->slic_isp,
2665 0, slic_regs->slic_addr_upper, 0, FLUSH);
2667 ("unsupported CONFIGURATION EEPROM invalid\n");
2671 card->config_set = 1;
2674 if (slic_card_download_gbrcv(adapter)) {
2675 DBG_ERROR("%s unable to download GB receive microcode\n",
2680 if (slic_global.dynamic_intagg) {
2682 ("Dynamic Interrupt Aggregation[ENABLED]: slic%d \
2683 SET intagg to %d\n",
2685 slic_intagg_set(adapter, 0);
2687 slic_intagg_set(adapter, intagg_delay);
2689 ("Dynamic Interrupt Aggregation[DISABLED]: slic%d \
2690 SET intagg to %d\n",
2691 card->cardnum, intagg_delay);
2695 * Initialize ping status to "ok"
2697 card->pingstatus = ISR_PINGMASK;
2699 #if SLIC_DUMP_ENABLED
2700 if (!card->dumpbuffer) {
2702 SLIC_ALLOCATE_MEM(DUMP_PAGE_SIZE, GFP_ATOMIC);
2704 ASSERT(card->dumpbuffer);
2705 if (card->dumpbuffer == NULL)
2709 * Smear the shared memory structure and then obtain
2710 * the PHYSICAL address of this structure
2712 SLIC_ZERO_MEMORY(card->dumpbuffer, DUMP_PAGE_SIZE);
2713 card->dumpbuffer_phys = SLIC_GET_PHYSICAL_ADDRESS(card->dumpbuffer);
2714 card->dumpbuffer_physh = SLIC_GET_ADDR_HIGH(card->dumpbuffer_phys);
2715 card->dumpbuffer_physl = SLIC_GET_ADDR_LOW(card->dumpbuffer_phys);
2718 * Allocate COMMAND BUFFER
2720 if (!card->cmdbuffer) {
2722 SLIC_ALLOCATE_MEM(sizeof(dump_cmd_t), GFP_ATOMIC);
2724 ASSERT(card->cmdbuffer);
2725 if (card->cmdbuffer == NULL)
2729 * Smear the shared memory structure and then obtain
2730 * the PHYSICAL address of this structure
2732 SLIC_ZERO_MEMORY(card->cmdbuffer, sizeof(dump_cmd_t));
2733 card->cmdbuffer_phys = SLIC_GET_PHYSICAL_ADDRESS(card->cmdbuffer);
2734 card->cmdbuffer_physh = SLIC_GET_ADDR_HIGH(card->cmdbuffer_phys);
2735 card->cmdbuffer_physl = SLIC_GET_ADDR_LOW(card->cmdbuffer_phys);
2739 * Lastly, mark our card state as up and return success
2741 card->state = CARD_UP;
2742 card->reset_in_progress = 0;
2743 DBG_MSG("slicoss: %s EXIT card[%p] adapter[%p] card->state[%x]\n",
2744 __func__, card, adapter, card->state);
2746 return STATUS_SUCCESS;
2749 ulong32 slic_card_locate(p_adapter_t adapter)
2751 p_sliccard_t card = slic_global.slic_card;
2752 p_physcard_t physcard = slic_global.phys_card;
2754 u16 __iomem *hostid_reg;
2756 uint rdhostid_offset = 0;
2758 DBG_MSG("slicoss: %s adapter[%p] slot[%x] bus[%x] port[%x]\n",
2759 __func__, adapter, adapter->slotnumber, adapter->busnumber,
2762 switch (adapter->devid) {
2763 case SLIC_2GB_DEVICE_ID:
2764 rdhostid_offset = SLIC_RDHOSTID_2GB;
2766 case SLIC_1GB_DEVICE_ID:
2767 rdhostid_offset = SLIC_RDHOSTID_1GB;
2775 (u16 __iomem *) (((u8 __iomem *) (adapter->slic_regs)) +
2777 DBG_MSG("slicoss: %s *hostid_reg[%p] == ", __func__, hostid_reg);
2779 /* read the 16 bit hostid from SRAM */
2780 /* card_hostid = READ_REGP16(hostid_reg, 0);*/
2781 card_hostid = (ushort) readw(hostid_reg);
2782 DBG_MSG(" card_hostid[%x]\n", card_hostid);
2784 /* Initialize a new card structure if need be */
2785 if (card_hostid == SLIC_HOSTID_DEFAULT) {
2786 card = kzalloc(sizeof(sliccard_t), GFP_KERNEL);
2790 card->next = slic_global.slic_card;
2791 slic_global.slic_card = card;
2793 if (adapter->devid == SLIC_2GB_DEVICE_ID) {
2795 ("SLICOSS ==> Initialize 2 Port Gigabit Server \
2796 and Storage Accelerator\n");
2799 ("SLICOSS ==> Initialize 1 Port Gigabit Server \
2800 and Storage Accelerator\n");
2803 card->busnumber = adapter->busnumber;
2804 card->slotnumber = adapter->slotnumber;
2806 /* Find an available cardnum */
2807 for (i = 0; i < SLIC_MAX_CARDS; i++) {
2808 if (slic_global.cardnuminuse[i] == 0) {
2809 slic_global.cardnuminuse[i] = 1;
2814 slic_global.num_slic_cards++;
2815 DBG_MSG("\nCARDNUM == %d Total %d Card[%p]\n\n",
2816 card->cardnum, slic_global.num_slic_cards, card);
2818 slic_debug_card_create(card);
2821 ("slicoss: %s CARD already allocated, find the \
2822 correct card\n", __func__);
2823 /* Card exists, find the card this adapter belongs to */
2826 ("slicoss: %s card[%p] slot[%x] bus[%x] \
2827 adaptport[%p] hostid[%x] cardnum[%x]\n",
2828 __func__, card, card->slotnumber,
2829 card->busnumber, card->adapter[adapter->port],
2830 card_hostid, card->cardnum);
2832 if (card->cardnum == card_hostid)
2840 return STATUS_FAILURE;
2841 /* Put the adapter in the card's adapter list */
2842 ASSERT(card->adapter[adapter->port] == NULL);
2843 if (!card->adapter[adapter->port]) {
2844 card->adapter[adapter->port] = adapter;
2845 adapter->card = card;
2848 card->card_size = 1; /* one port per *logical* card */
2851 for (i = 0; i < SLIC_MAX_PORTS; i++) {
2852 if (!physcard->adapter[i])
2857 ASSERT(i != SLIC_MAX_PORTS);
2858 if (physcard->adapter[i]->slotnumber == adapter->slotnumber)
2860 physcard = physcard->next;
2863 /* no structure allocated for this physical card yet */
2865 (p_physcard_t) SLIC_ALLOCATE_MEM(sizeof(physcard_t),
2868 SLIC_ZERO_MEMORY(physcard, sizeof(physcard_t));
2871 ("\n%s Allocate a PHYSICALcard:\n PHYSICAL_Card[%p]\n\
2872 LogicalCard [%p]\n adapter [%p]\n",
2873 __func__, physcard, card, adapter);
2875 physcard->next = slic_global.phys_card;
2876 slic_global.phys_card = physcard;
2877 physcard->adapters_allocd = 1;
2879 physcard->adapters_allocd++;
2881 /* Note - this is ZERO relative */
2882 adapter->physport = physcard->adapters_allocd - 1;
2884 ASSERT(physcard->adapter[adapter->physport] == NULL);
2885 physcard->adapter[adapter->physport] = adapter;
2886 adapter->physcard = physcard;
2887 DBG_MSG(" PHYSICAL_Port %d Logical_Port %d\n", adapter->physport,
2893 void slic_card_remaster(p_adapter_t adapter)
2895 p_sliccard_t card = adapter->card;
2898 DBG_MSG("slicoss: %s card->master[%p] == adapter[%p]??\n",
2899 __func__, card->master, adapter);
2900 if (card->master != adapter)
2902 card->master = NULL;
2903 for (i = 0; i < SLIC_MAX_PORTS; i++) {
2904 if (card->adapter[i] && (card->adapter[i] != adapter)) {
2905 card->master = card->adapter[i];
2906 DBG_MSG("slicoss: %s NEW MASTER SET card->master[%p]"
2907 " == card->adapter[%d]\n", __func__,
2914 void slic_soft_reset(p_adapter_t adapter)
2916 if (adapter->card->state == CARD_UP) {
2917 DBG_MSG("slicoss: %s QUIESCE adapter[%p] card[%p] devid[%x]\n",
2918 __func__, adapter, adapter->card, adapter->devid);
2919 WRITE_REG(adapter->slic_regs->slic_quiesce, 0, FLUSH);
2922 /* DBG_MSG ("slicoss: %s (%s) adapter[%p] card[%p] devid[%x]\n",
2923 __func__, adapter->netdev->name, adapter, adapter->card,
2926 WRITE_REG(adapter->slic_regs->slic_reset, SLIC_RESET_MAGIC, FLUSH);
2930 void slic_card_reset(p_adapter_t adapter)
2932 p_sliccard_t card = adapter->card;
2933 p_slic_upr_t upr = adapter->upr_list;
2934 p_slic_upr_t upr_next = NULL;
2936 #if SLIC_FAILURE_RESET
2940 ("slicoss: %s adapter[%p] port[%d] state[%x] card[%p] state[%x]\n",
2941 __func__, adapter, adapter->port, adapter->state, card,
2943 SLIC_ACQUIRE_IRQ_SPINLOCK(adapter->adapter_lock);
2944 SLIC_ACQUIRE_IRQ_SPINLOCK(adapter->reset_lock);
2945 if (card->state == CARD_DIAG) {
2946 SLIC_RELEASE_IRQ_SPINLOCK(adapter->reset_lock);
2947 SLIC_RELEASE_IRQ_SPINLOCK(adapter->adapter_lock);
2950 SLIC_ACQUIRE_IRQ_SPINLOCK(slic_global.driver_lock);
2951 card->reset_in_progress = 1;
2952 #if SLIC_FAILURE_RESET
2953 if (adapter->state != ADAPT_RESET) {
2954 SLIC_RELEASE_IRQ_SPINLOCK(slic_global.driver_lock);
2955 SLIC_RELEASE_IRQ_SPINLOCK(adapter->reset_lock);
2956 SLIC_RELEASE_IRQ_SPINLOCK(adapter->adapter_lock);
2960 adapter->state = ADAPT_DOWN;
2961 adapter->linkstate = LINK_DOWN;
2963 if (adapter->gennumber == card->gennumber) {
2964 for (i = 0; i < card->card_size; i++) {
2965 if (card->adapter[i]) {
2966 if (card->adapter[i] == adapter)
2968 if (card->adapter[i]->state == ADAPT_UP) {
2969 card->adapter[i]->state = ADAPT_RESET;
2970 adapter->linkstate = LINK_DOWN;
2974 #if SLIC_FAILURE_RESET
2975 slic_soft_reset(adapter);
2976 card->state = CARD_DOWN;
2977 card->master = NULL;
2978 card->adapters_activated = 0;
2982 adapter->gennumber = card->gennumber;
2983 adapter->pshmem->isr = 0;
2984 adapter->isrcopy = 0;
2985 SLIC_RELEASE_IRQ_SPINLOCK(adapter->reset_lock);
2986 for (i = 0; i < card->card_size; i++) {
2987 if (card->adapter[i])
2988 slic_cmdq_reset(card->adapter[i]);
2991 upr_next = upr->next;
2992 SLIC_DEALLOCATE_MEM(upr);
2995 adapter->upr_list = NULL;
2996 adapter->upr_busy = 0;
2997 #if SLIC_FAILURE_RESET
2998 status = slic_if_init(adapter);
2999 if ((status == 0) && (!card->master))
3000 card->master = adapter;
3001 slic_mcast_set_mask(adapter);
3003 SLIC_RELEASE_IRQ_SPINLOCK(slic_global.driver_lock);
3004 SLIC_RELEASE_IRQ_SPINLOCK(adapter->adapter_lock);
3006 ("slicoss: %s EXIT adapter[%p] port[%d] state[%x] card[%p] \
3007 state[%x]\n", __func__, adapter, adapter->port, adapter->state,
3012 void slic_config_set(p_adapter_t adapter, boolean linkchange)
3016 p_slic_regs_t slic_regs = adapter->slic_regs;
3018 DBG_MSG("slicoss: %s (%s) slic_interface_enable[%p](%d)\n",
3019 __func__, adapter->netdev->name, adapter,
3020 adapter->cardindex);
3024 slic_mac_config(adapter);
3025 RcrReset = GRCR_RESET;
3027 slic_mac_address_config(adapter);
3031 if (adapter->linkduplex == LINK_FULLD) {
3033 value = (GXCR_RESET | /* Always reset */
3034 GXCR_XMTEN | /* Enable transmit */
3035 GXCR_PAUSEEN); /* Enable pause */
3037 DBG_MSG("slicoss: FDX adapt[%p] set xmtcfg to [%x]\n", adapter,
3039 WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
3041 /* Setup rcvcfg last */
3042 value = (RcrReset | /* Reset, if linkchange */
3043 GRCR_CTLEN | /* Enable CTL frames */
3044 GRCR_ADDRAEN | /* Address A enable */
3045 GRCR_RCVBAD | /* Rcv bad frames */
3046 (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
3049 value = (GXCR_RESET | /* Always reset */
3050 GXCR_XMTEN); /* Enable transmit */
3052 DBG_MSG("slicoss: HDX adapt[%p] set xmtcfg to [%x]\n", adapter,
3054 WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
3056 /* Setup rcvcfg last */
3057 value = (RcrReset | /* Reset, if linkchange */
3058 GRCR_ADDRAEN | /* Address A enable */
3059 GRCR_RCVBAD | /* Rcv bad frames */
3060 (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
3063 if (adapter->state != ADAPT_DOWN) {
3064 /* Only enable receive if we are restarting or running */
3065 value |= GRCR_RCVEN;
3068 if (adapter->macopts & MAC_PROMISC)
3069 value |= GRCR_RCVALL;
3071 DBG_MSG("slicoss: adapt[%p] set rcvcfg to [%x]\n", adapter, value);
3072 WRITE_REG(slic_regs->slic_wrcfg, value, FLUSH);
3076 * Turn off RCV and XMT, power down PHY
3078 void slic_config_clear(p_adapter_t adapter)
3082 p_slic_regs_t slic_regs = adapter->slic_regs;
3085 value = (GXCR_RESET | /* Always reset */
3086 GXCR_PAUSEEN); /* Enable pause */
3088 WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
3090 value = (GRCR_RESET | /* Always reset */
3091 GRCR_CTLEN | /* Enable CTL frames */
3092 GRCR_ADDRAEN | /* Address A enable */
3093 (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
3095 WRITE_REG(slic_regs->slic_wrcfg, value, FLUSH);
3097 /* power down phy */
3098 phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN));
3099 WRITE_REG(slic_regs->slic_wphy, phy_config, FLUSH);
3102 void slic_config_get(p_adapter_t adapter, ulong32 config, ulong32 config_h)
3106 status = slic_upr_request(adapter,
3108 (ulong32) config, (ulong32) config_h, 0, 0);
3109 ASSERT(status == 0);
3112 void slic_mac_address_config(p_adapter_t adapter)
3116 p_slic_regs_t slic_regs = adapter->slic_regs;
3118 value = *(pulong32) &adapter->currmacaddr[2];
3119 value = ntohl(value);
3120 WRITE_REG(slic_regs->slic_wraddral, value, FLUSH);
3121 WRITE_REG(slic_regs->slic_wraddrbl, value, FLUSH);
3123 value2 = (ulong32) ((adapter->currmacaddr[0] << 8 |
3124 adapter->currmacaddr[1]) & 0xFFFF);
3126 WRITE_REG(slic_regs->slic_wraddrah, value2, FLUSH);
3127 WRITE_REG(slic_regs->slic_wraddrbh, value2, FLUSH);
3129 DBG_MSG("%s value1[%x] value2[%x] Call slic_mcast_set_mask\n",
3130 __func__, value, value2);
3131 slic_dbg_macaddrs(adapter);
3133 /* Write our multicast mask out to the card. This is done */
3134 /* here in addition to the slic_mcast_addr_set routine */
3135 /* because ALL_MCAST may have been enabled or disabled */
3136 slic_mcast_set_mask(adapter);
3139 void slic_mac_config(p_adapter_t adapter)
3142 p_slic_regs_t slic_regs = adapter->slic_regs;
3144 /* Setup GMAC gaps */
3145 if (adapter->linkspeed == LINK_1000MB) {
3146 value = ((GMCR_GAPBB_1000 << GMCR_GAPBB_SHIFT) |
3147 (GMCR_GAPR1_1000 << GMCR_GAPR1_SHIFT) |
3148 (GMCR_GAPR2_1000 << GMCR_GAPR2_SHIFT));
3150 value = ((GMCR_GAPBB_100 << GMCR_GAPBB_SHIFT) |
3151 (GMCR_GAPR1_100 << GMCR_GAPR1_SHIFT) |
3152 (GMCR_GAPR2_100 << GMCR_GAPR2_SHIFT));
3156 if (adapter->linkspeed == LINK_1000MB)
3159 /* enable fullduplex */
3160 if ((adapter->linkduplex == LINK_FULLD)
3161 || (adapter->macopts & MAC_LOOPBACK)) {
3162 value |= GMCR_FULLD;
3165 /* write mac config */
3166 WRITE_REG(slic_regs->slic_wmcfg, value, FLUSH);
3168 /* setup mac addresses */
3169 slic_mac_address_config(adapter);
3172 boolean slic_mac_filter(p_adapter_t adapter, p_ether_header ether_frame)
3174 ulong32 opts = adapter->macopts;
3175 pulong32 dhost4 = (pulong32) ðer_frame->ether_dhost[0];
3176 pushort dhost2 = (pushort) ðer_frame->ether_dhost[4];
3179 if (opts & MAC_PROMISC) {
3180 DBG_MSG("slicoss: %s (%s) PROMISCUOUS. Accept frame\n",
3181 __func__, adapter->netdev->name);
3185 if ((*dhost4 == 0xFFFFFFFF) && (*dhost2 == 0xFFFF)) {
3186 if (opts & MAC_BCAST) {
3187 adapter->rcv_broadcasts++;
3194 if (ether_frame->ether_dhost[0] & 0x01) {
3195 if (opts & MAC_ALLMCAST) {
3196 adapter->rcv_multicasts++;
3197 adapter->stats.multicast++;
3200 if (opts & MAC_MCAST) {
3201 p_mcast_address_t mcaddr = adapter->mcastaddrs;
3204 ETHER_EQ_ADDR(mcaddr->address,
3205 ether_frame->ether_dhost,
3208 adapter->rcv_multicasts++;
3209 adapter->stats.multicast++;
3212 mcaddr = mcaddr->next;
3219 if (opts & MAC_DIRECTED) {
3220 adapter->rcv_unicasts++;
3227 int slic_mac_set_address(struct net_device *dev, pvoid ptr)
3229 p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
3230 struct sockaddr *addr = ptr;
3232 DBG_MSG("%s ENTER (%s)\n", __func__, adapter->netdev->name);
3234 if (netif_running(dev))
3238 DBG_MSG("slicoss: %s (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
3239 __func__, adapter->netdev->name, adapter->currmacaddr[0],
3240 adapter->currmacaddr[1], adapter->currmacaddr[2],
3241 adapter->currmacaddr[3], adapter->currmacaddr[4],
3242 adapter->currmacaddr[5]);
3243 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
3244 memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
3245 DBG_MSG("slicoss: %s (%s) new %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
3246 __func__, adapter->netdev->name, adapter->currmacaddr[0],
3247 adapter->currmacaddr[1], adapter->currmacaddr[2],
3248 adapter->currmacaddr[3], adapter->currmacaddr[4],
3249 adapter->currmacaddr[5]);
3251 slic_config_set(adapter, TRUE);
3256 * slic_timer_get_stats
3258 * Timer function used to suck the statistics out of the card every
3259 * 50 seconds or whatever STATS_TIMER_INTERVAL is set to.
3262 void slic_timer_get_stats(ulong dev)
3264 p_adapter_t adapter;
3266 p_slic_shmem_t pshmem;
3269 adapter = (p_adapter_t) ((struct net_device *)dev)->priv;
3271 card = adapter->card;
3274 if ((card->state == CARD_UP) &&
3275 (adapter->state == ADAPT_UP) && (adapter->linkstate == LINK_UP)) {
3276 pshmem = (p_slic_shmem_t) adapter->phys_shmem;
3277 #ifdef CONFIG_X86_64
3278 slic_upr_request(adapter,
3280 SLIC_GET_ADDR_LOW(&pshmem->inicstats),
3281 SLIC_GET_ADDR_HIGH(&pshmem->inicstats), 0, 0);
3282 #elif defined(CONFIG_X86)
3283 slic_upr_request(adapter,
3285 (ulong32) &pshmem->inicstats, 0, 0, 0);
3290 /* DBG_MSG ("slicoss: %s adapter[%p] linkstate[%x] NOT UP!\n",
3291 __func__, adapter, adapter->linkstate); */
3293 adapter->statstimer.expires = jiffies +
3294 SLIC_SECS_TO_JIFFS(STATS_TIMER_INTERVAL);
3295 add_timer(&adapter->statstimer);
3298 void slic_timer_load_check(ulong cardaddr)
3300 p_sliccard_t card = (p_sliccard_t) cardaddr;
3301 p_adapter_t adapter = card->master;
3302 ulong32 load = card->events;
3305 if ((adapter) && (adapter->state == ADAPT_UP) &&
3306 (card->state == CARD_UP) && (slic_global.dynamic_intagg)) {
3307 if (adapter->devid == SLIC_1GB_DEVICE_ID) {
3308 if (adapter->linkspeed == LINK_1000MB)
3311 if (load > SLIC_LOAD_5)
3312 level = SLIC_INTAGG_5;
3313 else if (load > SLIC_LOAD_4)
3314 level = SLIC_INTAGG_4;
3315 else if (load > SLIC_LOAD_3)
3316 level = SLIC_INTAGG_3;
3317 else if (load > SLIC_LOAD_2)
3318 level = SLIC_INTAGG_2;
3319 else if (load > SLIC_LOAD_1)
3320 level = SLIC_INTAGG_1;
3322 level = SLIC_INTAGG_0;
3324 if (card->loadlevel_current != level) {
3325 card->loadlevel_current = level;
3326 WRITE_REG(adapter->slic_regs->slic_intagg,
3330 if (load > SLIC_LOAD_5)
3331 level = SLIC_INTAGG_5;
3332 else if (load > SLIC_LOAD_4)
3333 level = SLIC_INTAGG_4;
3334 else if (load > SLIC_LOAD_3)
3335 level = SLIC_INTAGG_3;
3336 else if (load > SLIC_LOAD_2)
3337 level = SLIC_INTAGG_2;
3338 else if (load > SLIC_LOAD_1)
3339 level = SLIC_INTAGG_1;
3341 level = SLIC_INTAGG_0;
3342 if (card->loadlevel_current != level) {
3343 card->loadlevel_current = level;
3344 WRITE_REG(adapter->slic_regs->slic_intagg,
3350 card->loadtimer.expires =
3351 jiffies + SLIC_SECS_TO_JIFFS(SLIC_LOADTIMER_PERIOD);
3352 add_timer(&card->loadtimer);
3355 void slic_stall_msec(int stall)
3360 void slic_stall_usec(int stall)
3365 void slic_assert_fail(void)
3369 cpuid = smp_processor_id();
3370 curr_pid = current->pid;
3372 DBG_ERROR("%s CPU # %d ---- PID # %d\n", __func__, cpuid, curr_pid);
3375 int slic_upr_queue_request(p_adapter_t adapter,
3376 ulong32 upr_request,
3379 ulong32 upr_buffer, ulong32 upr_buffer_h)
3382 p_slic_upr_t uprqueue;
3384 upr = SLIC_ALLOCATE_MEM(sizeof(slic_upr_t), GFP_ATOMIC);
3386 DBG_MSG("%s COULD NOT ALLOCATE UPR MEM\n", __func__);
3390 upr->adapter = adapter->port;
3391 upr->upr_request = upr_request;
3392 upr->upr_data = upr_data;
3393 upr->upr_buffer = upr_buffer;
3394 upr->upr_data_h = upr_data_h;
3395 upr->upr_buffer_h = upr_buffer_h;
3397 if (adapter->upr_list) {
3398 uprqueue = adapter->upr_list;
3400 while (uprqueue->next)
3401 uprqueue = uprqueue->next;
3402 uprqueue->next = upr;
3404 adapter->upr_list = upr;
3406 return STATUS_SUCCESS;
3409 int slic_upr_request(p_adapter_t adapter,
3410 ulong32 upr_request,
3413 ulong32 upr_buffer, ulong32 upr_buffer_h)
3417 SLIC_ACQUIRE_IRQ_SPINLOCK(adapter->upr_lock);
3418 status = slic_upr_queue_request(adapter,
3421 upr_data_h, upr_buffer, upr_buffer_h);
3422 if (status != STATUS_SUCCESS) {
3423 SLIC_RELEASE_IRQ_SPINLOCK(adapter->upr_lock);
3426 slic_upr_start(adapter);
3427 SLIC_RELEASE_IRQ_SPINLOCK(adapter->upr_lock);
3428 return STATUS_PENDING;
3431 void slic_upr_request_complete(p_adapter_t adapter, ulong32 isr)
3433 p_sliccard_t card = adapter->card;
3436 /* if (card->dump_requested) {
3437 DBG_MSG("ENTER slic_upr_request_complete Dump in progress ISR[%x]\n",
3440 SLIC_ACQUIRE_IRQ_SPINLOCK(adapter->upr_lock);
3441 upr = adapter->upr_list;
3444 SLIC_RELEASE_IRQ_SPINLOCK(adapter->upr_lock);
3447 adapter->upr_list = upr->next;
3449 adapter->upr_busy = 0;
3450 ASSERT(adapter->port == upr->adapter);
3451 switch (upr->upr_request) {
3452 case SLIC_UPR_STATS:
3454 #if SLIC_GET_STATS_ENABLED
3455 p_slic_stats_t slicstats =
3456 (p_slic_stats_t) &adapter->pshmem->inicstats;
3457 p_slic_stats_t newstats = slicstats;
3458 p_slic_stats_t old = &adapter->inicstats_prev;
3459 p_slicnet_stats_t stst = &adapter->slic_stats;
3461 if (isr & ISR_UPCERR) {
3463 ("SLIC_UPR_STATS command failed isr[%x]\n",
3468 #if SLIC_GET_STATS_ENABLED
3469 /* DBG_MSG ("slicoss: %s rcv %lx:%lx:%lx:%lx:%lx %lx %lx "
3470 "xmt %lx:%lx:%lx:%lx:%lx %lx %lx\n",
3472 slicstats->rcv_unicasts100,
3473 slicstats->rcv_bytes100,
3474 slicstats->rcv_bytes100,
3475 slicstats->rcv_tcp_bytes100,
3476 slicstats->rcv_tcp_segs100,
3477 slicstats->rcv_other_error100,
3478 slicstats->rcv_drops100,
3479 slicstats->xmit_unicasts100,
3480 slicstats->xmit_bytes100,
3481 slicstats->xmit_bytes100,
3482 slicstats->xmit_tcp_bytes100,
3483 slicstats->xmit_tcp_segs100,
3484 slicstats->xmit_other_error100,
3485 slicstats->xmit_collisions100);*/
3486 UPDATE_STATS_GB(stst->tcp.xmit_tcp_segs,
3487 newstats->xmit_tcp_segs_gb,
3488 old->xmit_tcp_segs_gb);
3490 UPDATE_STATS_GB(stst->tcp.xmit_tcp_bytes,
3491 newstats->xmit_tcp_bytes_gb,
3492 old->xmit_tcp_bytes_gb);
3494 UPDATE_STATS_GB(stst->tcp.rcv_tcp_segs,
3495 newstats->rcv_tcp_segs_gb,
3496 old->rcv_tcp_segs_gb);
3498 UPDATE_STATS_GB(stst->tcp.rcv_tcp_bytes,
3499 newstats->rcv_tcp_bytes_gb,
3500 old->rcv_tcp_bytes_gb);
3502 UPDATE_STATS_GB(stst->iface.xmt_bytes,
3503 newstats->xmit_bytes_gb,
3504 old->xmit_bytes_gb);
3506 UPDATE_STATS_GB(stst->iface.xmt_ucast,
3507 newstats->xmit_unicasts_gb,
3508 old->xmit_unicasts_gb);
3510 UPDATE_STATS_GB(stst->iface.rcv_bytes,
3511 newstats->rcv_bytes_gb,
3514 UPDATE_STATS_GB(stst->iface.rcv_ucast,
3515 newstats->rcv_unicasts_gb,
3516 old->rcv_unicasts_gb);
3518 UPDATE_STATS_GB(stst->iface.xmt_errors,
3519 newstats->xmit_collisions_gb,
3520 old->xmit_collisions_gb);
3522 UPDATE_STATS_GB(stst->iface.xmt_errors,
3523 newstats->xmit_excess_collisions_gb,
3524 old->xmit_excess_collisions_gb);
3526 UPDATE_STATS_GB(stst->iface.xmt_errors,
3527 newstats->xmit_other_error_gb,
3528 old->xmit_other_error_gb);
3530 UPDATE_STATS_GB(stst->iface.rcv_errors,
3531 newstats->rcv_other_error_gb,
3532 old->rcv_other_error_gb);
3534 UPDATE_STATS_GB(stst->iface.rcv_discards,
3535 newstats->rcv_drops_gb,
3538 if (newstats->rcv_drops_gb > old->rcv_drops_gb) {
3539 adapter->rcv_drops +=
3540 (newstats->rcv_drops_gb -
3543 memcpy(old, newstats, sizeof(slic_stats_t));
3548 slic_link_upr_complete(adapter, isr);
3550 case SLIC_UPR_RCONFIG:
3565 card->pingstatus |= (isr & ISR_PINGDSMASK);
3567 #if SLIC_DUMP_ENABLED
3569 card->dumpstatus |= (isr & ISR_UPCMASK);
3575 SLIC_DEALLOCATE_MEM(upr);
3576 slic_upr_start(adapter);
3577 SLIC_RELEASE_IRQ_SPINLOCK(adapter->upr_lock);
3580 void slic_upr_start(p_adapter_t adapter)
3583 p_slic_regs_t slic_regs = adapter->slic_regs;
3589 upr = adapter->upr_list;
3592 if (adapter->upr_busy)
3594 adapter->upr_busy = 1;
3596 switch (upr->upr_request) {
3597 case SLIC_UPR_STATS:
3598 if (upr->upr_data_h == 0) {
3599 WRITE_REG(slic_regs->slic_stats, upr->upr_data, FLUSH);
3601 WRITE_REG64(adapter,
3602 slic_regs->slic_stats64,
3604 slic_regs->slic_addr_upper,
3605 upr->upr_data_h, FLUSH);
3610 WRITE_REG64(adapter,
3611 slic_regs->slic_rlsr,
3613 slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
3616 case SLIC_UPR_RCONFIG:
3617 DBG_MSG("%s SLIC_UPR_RCONFIG!!!!\n", __func__);
3618 DBG_MSG("WRITE_REG64 adapter[%p]\n"
3619 " a->slic_regs[%p] slic_regs[%p]\n"
3620 " &slic_rconfig[%p] &slic_addr_upper[%p]\n"
3622 " uprdata[%x] uprdatah[%x]\n",
3623 adapter, adapter->slic_regs, slic_regs,
3624 &slic_regs->slic_rconfig, &slic_regs->slic_addr_upper,
3625 upr, upr->upr_data, upr->upr_data_h);
3626 WRITE_REG64(adapter,
3627 slic_regs->slic_rconfig,
3629 slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
3631 #if SLIC_DUMP_ENABLED
3634 DBG_MSG("%s SLIC_UPR_DUMP!!!!\n", __func__);
3635 DBG_MSG("WRITE_REG64 adapter[%p]\n"
3636 " upr_buffer[%x] upr_bufferh[%x]\n"
3637 " upr_data[%x] upr_datah[%x]\n"
3638 " cmdbuff[%p] cmdbuffP[%p]\n"
3639 " dumpbuff[%p] dumpbuffP[%p]\n",
3640 adapter, upr->upr_buffer, upr->upr_buffer_h,
3641 upr->upr_data, upr->upr_data_h,
3642 adapter->card->cmdbuffer,
3643 (void *)adapter->card->cmdbuffer_phys,
3644 adapter->card->dumpbuffer, (
3645 void *)adapter->card->dumpbuffer_phys);
3647 ptr1 = (char *)slic_regs;
3648 ptr2 = (char *)(&slic_regs->slic_dump_cmd);
3649 cmdoffset = ptr2 - ptr1;
3650 DBG_MSG("slic_dump_cmd register offset [%x]\n", cmdoffset);
3652 if (upr->upr_buffer || upr->upr_buffer_h) {
3653 WRITE_REG64(adapter,
3654 slic_regs->slic_dump_data,
3656 slic_regs->slic_addr_upper,
3657 upr->upr_buffer_h, FLUSH);
3659 WRITE_REG64(adapter,
3660 slic_regs->slic_dump_cmd,
3662 slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
3666 WRITE_REG(slic_regs->slic_ping, 1, FLUSH);
3673 void slic_link_upr_complete(p_adapter_t adapter, ulong32 isr)
3675 ulong32 linkstatus = adapter->pshmem->linkstatus;
3680 DBG_MSG("%s: %s ISR[%x] linkstatus[%x]\n adapter[%p](%d)\n",
3681 __func__, adapter->netdev->name, isr, linkstatus, adapter,
3682 adapter->cardindex);
3684 if ((isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
3685 p_slic_shmem_t pshmem;
3687 pshmem = (p_slic_shmem_t) adapter->phys_shmem;
3688 #if defined(CONFIG_X86_64)
3689 slic_upr_queue_request(adapter,
3691 SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
3692 SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
3694 #elif defined(CONFIG_X86)
3695 slic_upr_queue_request(adapter,
3697 (ulong32) &pshmem->linkstatus,
3698 SLIC_GET_ADDR_HIGH(pshmem), 0, 0);
3704 if (adapter->state != ADAPT_UP)
3707 ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
3708 || (adapter->devid == SLIC_2GB_DEVICE_ID));
3710 linkup = linkstatus & GIG_LINKUP ? LINK_UP : LINK_DOWN;
3711 if (linkstatus & GIG_SPEED_1000) {
3712 linkspeed = LINK_1000MB;
3713 DBG_MSG("slicoss: %s (%s) GIGABIT Speed==1000MB ",
3714 __func__, adapter->netdev->name);
3715 } else if (linkstatus & GIG_SPEED_100) {
3716 linkspeed = LINK_100MB;
3717 DBG_MSG("slicoss: %s (%s) GIGABIT Speed==100MB ", __func__,
3718 adapter->netdev->name);
3720 linkspeed = LINK_10MB;
3721 DBG_MSG("slicoss: %s (%s) GIGABIT Speed==10MB ", __func__,
3722 adapter->netdev->name);
3724 if (linkstatus & GIG_FULLDUPLEX) {
3725 linkduplex = LINK_FULLD;
3726 DBG_MSG(" Duplex == FULL\n");
3728 linkduplex = LINK_HALFD;
3729 DBG_MSG(" Duplex == HALF\n");
3732 if ((adapter->linkstate == LINK_DOWN) && (linkup == LINK_DOWN)) {
3733 DBG_MSG("slicoss: %s (%s) physport(%d) link still down\n",
3734 __func__, adapter->netdev->name, adapter->physport);
3738 /* link up event, but nothing has changed */
3739 if ((adapter->linkstate == LINK_UP) &&
3740 (linkup == LINK_UP) &&
3741 (adapter->linkspeed == linkspeed) &&
3742 (adapter->linkduplex == linkduplex)) {
3743 DBG_MSG("slicoss: %s (%s) port(%d) link still up\n",
3744 __func__, adapter->netdev->name, adapter->physport);
3748 /* link has changed at this point */
3750 /* link has gone from up to down */
3751 if (linkup == LINK_DOWN) {
3752 adapter->linkstate = LINK_DOWN;
3753 DBG_MSG("slicoss: %s %d LinkDown!\n", __func__,
3758 /* link has gone from down to up */
3759 adapter->linkspeed = linkspeed;
3760 adapter->linkduplex = linkduplex;
3762 if (adapter->linkstate != LINK_UP) {
3764 DBG_MSG("%s call slic_config_set\n", __func__);
3765 slic_config_set(adapter, TRUE);
3766 adapter->linkstate = LINK_UP;
3767 DBG_MSG("\n(%s) Link UP: CALL slic_if_start_queue",
3768 adapter->netdev->name);
3769 slic_if_start_queue(adapter);
3772 switch (linkspeed) {
3775 ("\n(%s) LINK UP!: GIGABIT SPEED == 1000MB duplex[%x]\n",
3776 adapter->netdev->name, adapter->linkduplex);
3779 DBG_MSG("\n(%s) LINK UP!: SPEED == 100MB duplex[%x]\n",
3780 adapter->netdev->name, adapter->linkduplex);
3783 DBG_MSG("\n(%s) LINK UP!: SPEED == 10MB duplex[%x]\n",
3784 adapter->netdev->name, adapter->linkduplex);
3791 * this is here to checksum the eeprom, there is some ucode bug
3792 * which prevens us from using the ucode result.
3793 * remove this once ucode is fixed.
3795 ushort slic_eeprom_cksum(pchar m, int len)
3797 #define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
3798 #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);\
3803 ulong32 byte_swapped = 0;
3820 #ifdef CONFIG_X86_64
3821 w_int = (ulong32) ((ulong) w & 0x00000000FFFFFFFF);
3823 w_int = (ulong32) (w);
3825 if ((1 & w_int) && (len > 0)) {
3828 s_util.c[0] = *(puchar) w;
3829 w = (pushort) ((char *)w + 1);
3834 /* Unroll the loop to make overhead from branches &c small. */
3835 while ((len -= 32) >= 0) {
3852 w = (pushort) ((ulong) w + 16); /* verify */
3855 while ((len -= 8) >= 0) {
3860 w = (pushort) ((ulong) w + 4); /* verify */
3863 if (len != 0 || byte_swapped != 0) {
3865 while ((len -= 2) >= 0)
3866 sum += *w++; /* verify */
3872 s_util.c[1] = *(pchar) w;
3879 } else if (len == -1) {
3880 s_util.c[0] = *(pchar) w;
3889 return (ushort) sum;
3892 int slic_rspqueue_init(p_adapter_t adapter)
3895 p_slic_rspqueue_t rspq = &adapter->rspqueue;
3896 p_slic_regs_t slic_regs = adapter->slic_regs;
3899 DBG_MSG("slicoss: %s (%s) ENTER adapter[%p]\n", __func__,
3900 adapter->netdev->name, adapter);
3901 ASSERT(adapter->state == ADAPT_DOWN);
3902 SLIC_ZERO_MEMORY(rspq, sizeof(slic_rspqueue_t));
3904 rspq->num_pages = SLIC_RSPQ_PAGES_GB;
3906 for (i = 0; i < rspq->num_pages; i++) {
3908 pci_alloc_consistent(adapter->pcidev, PAGE_SIZE,
3910 if (!rspq->vaddr[i]) {
3912 ("rspqueue_init_failed pci_alloc_consistent\n");
3913 slic_rspqueue_free(adapter);
3914 return STATUS_FAILURE;
3916 #ifndef CONFIG_X86_64
3917 ASSERT(((ulong32) rspq->vaddr[i] & 0xFFFFF000) ==
3918 (ulong32) rspq->vaddr[i]);
3919 ASSERT(((ulong32) rspq->paddr[i] & 0xFFFFF000) ==
3920 (ulong32) rspq->paddr[i]);
3922 SLIC_ZERO_MEMORY(rspq->vaddr[i], PAGE_SIZE);
3923 /* DBG_MSG("slicoss: %s UPLOAD RSPBUFF Page pageix[%x] paddr[%p] "
3925 __func__, i, (void *)rspq->paddr[i], rspq->vaddr[i]); */
3928 WRITE_REG(slic_regs->slic_rbar,
3929 (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
3932 WRITE_REG64(adapter,
3933 slic_regs->slic_rbar64,
3934 (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
3935 slic_regs->slic_addr_upper,
3936 paddrh, DONT_FLUSH);
3940 rspq->pageindex = 0;
3941 rspq->rspbuf = (p_slic_rspbuf_t) rspq->vaddr[0];
3942 DBG_MSG("slicoss: %s (%s) EXIT adapter[%p]\n", __func__,
3943 adapter->netdev->name, adapter);
3944 return STATUS_SUCCESS;
3947 int slic_rspqueue_reset(p_adapter_t adapter)
3949 p_slic_rspqueue_t rspq = &adapter->rspqueue;
3951 DBG_MSG("slicoss: %s (%s) ENTER adapter[%p]\n", __func__,
3952 adapter->netdev->name, adapter);
3953 ASSERT(adapter->state == ADAPT_DOWN);
3956 DBG_MSG("slicoss: Nothing to do. rspq[%p]\n"
3960 rspq, rspq->offset, rspq->pageindex, rspq->rspbuf);
3962 DBG_MSG("slicoss: %s (%s) EXIT adapter[%p]\n", __func__,
3963 adapter->netdev->name, adapter);
3964 return STATUS_SUCCESS;
3967 void slic_rspqueue_free(p_adapter_t adapter)
3970 slic_rspqueue_t *rspq = &adapter->rspqueue;
3972 DBG_MSG("slicoss: %s adapter[%p] port %d rspq[%p] FreeRSPQ\n",
3973 __func__, adapter, adapter->physport, rspq);
3974 for (i = 0; i < rspq->num_pages; i++) {
3975 if (rspq->vaddr[i]) {
3977 ("slicoss: pci_free_consistent rspq->vaddr[%p] \
3979 rspq->vaddr[i], (pvoid) rspq->paddr[i]);
3980 pci_free_consistent(adapter->pcidev, PAGE_SIZE,
3981 rspq->vaddr[i], rspq->paddr[i]);
3983 rspq->vaddr[i] = NULL;
3987 rspq->pageindex = 0;
3988 rspq->rspbuf = NULL;
3991 p_slic_rspbuf_t slic_rspqueue_getnext(p_adapter_t adapter)
3993 p_slic_rspqueue_t rspq = &adapter->rspqueue;
3994 p_slic_rspbuf_t buf;
3996 if (!(rspq->rspbuf->status))
4000 #ifndef CONFIG_X86_64
4001 ASSERT((buf->status & 0xFFFFFFE0) == 0);
4003 ASSERT(buf->hosthandle);
4004 if (++rspq->offset < SLIC_RSPQ_BUFSINPAGE) {
4006 #ifndef CONFIG_X86_64
4007 ASSERT(((ulong32) rspq->rspbuf & 0xFFFFFFE0) ==
4008 (ulong32) rspq->rspbuf);
4011 ASSERT(rspq->offset == SLIC_RSPQ_BUFSINPAGE);
4012 WRITE_REG64(adapter,
4013 adapter->slic_regs->slic_rbar64,
4015 paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
4016 adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
4017 rspq->pageindex = (++rspq->pageindex) % rspq->num_pages;
4019 rspq->rspbuf = (p_slic_rspbuf_t) rspq->vaddr[rspq->pageindex];
4020 #ifndef CONFIG_X86_64
4021 ASSERT(((ulong32) rspq->rspbuf & 0xFFFFF000) ==
4022 (ulong32) rspq->rspbuf);
4025 #ifndef CONFIG_X86_64
4026 ASSERT(((ulong32) buf & 0xFFFFFFE0) == (ulong32) buf);
4031 void slic_cmdqmem_init(p_adapter_t adapter)
4033 slic_cmdqmem_t *cmdqmem = &adapter->cmdqmem;
4035 SLIC_ZERO_MEMORY(cmdqmem, sizeof(slic_cmdqmem_t));
4038 void slic_cmdqmem_free(p_adapter_t adapter)
4040 slic_cmdqmem_t *cmdqmem = &adapter->cmdqmem;
4043 DBG_MSG("slicoss: (%s) adapter[%p] port %d rspq[%p] Free CMDQ Memory\n",
4044 __func__, adapter, adapter->physport, cmdqmem);
4045 for (i = 0; i < SLIC_CMDQ_MAXPAGES; i++) {
4046 if (cmdqmem->pages[i]) {
4047 DBG_MSG("slicoss: %s Deallocate page CmdQPage[%p]\n",
4048 __func__, (pvoid) cmdqmem->pages[i]);
4049 pci_free_consistent(adapter->pcidev,
4051 (pvoid) cmdqmem->pages[i],
4052 cmdqmem->dma_pages[i]);
4055 SLIC_ZERO_MEMORY(cmdqmem, sizeof(slic_cmdqmem_t));
4058 pulong32 slic_cmdqmem_addpage(p_adapter_t adapter)
4060 p_slic_cmdqmem_t cmdqmem = &adapter->cmdqmem;
4063 if (cmdqmem->pagecnt >= SLIC_CMDQ_MAXPAGES)
4065 pageaddr = pci_alloc_consistent(adapter->pcidev,
4067 &cmdqmem->dma_pages[cmdqmem->pagecnt]);
4070 #ifndef CONFIG_X86_64
4071 ASSERT(((ulong32) pageaddr & 0xFFFFF000) == (ulong32) pageaddr);
4073 cmdqmem->pages[cmdqmem->pagecnt] = pageaddr;
4078 int slic_cmdq_init(p_adapter_t adapter)
4083 DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
4084 ASSERT(adapter->state == ADAPT_DOWN);
4085 SLIC_ZERO_MEMORY(&adapter->cmdq_all, sizeof(slic_cmdqueue_t));
4086 SLIC_ZERO_MEMORY(&adapter->cmdq_free, sizeof(slic_cmdqueue_t));
4087 SLIC_ZERO_MEMORY(&adapter->cmdq_done, sizeof(slic_cmdqueue_t));
4088 SLIC_INIT_SPINLOCK(adapter->cmdq_all.lock);
4089 SLIC_INIT_SPINLOCK(adapter->cmdq_free.lock);
4090 SLIC_INIT_SPINLOCK(adapter->cmdq_done.lock);
4091 slic_cmdqmem_init(adapter);
4092 adapter->slic_handle_ix = 1;
4093 for (i = 0; i < SLIC_CMDQ_INITPAGES; i++) {
4094 pageaddr = slic_cmdqmem_addpage(adapter);
4095 #ifndef CONFIG_X86_64
4096 ASSERT(((ulong32) pageaddr & 0xFFFFF000) == (ulong32) pageaddr);
4099 slic_cmdq_free(adapter);
4100 return STATUS_FAILURE;
4102 slic_cmdq_addcmdpage(adapter, pageaddr);
4104 adapter->slic_handle_ix = 1;
4105 DBG_MSG("slicoss: %s reset slic_handle_ix to ONE\n", __func__);
4107 return STATUS_SUCCESS;
4110 void slic_cmdq_free(p_adapter_t adapter)
4112 p_slic_hostcmd_t cmd;
4114 DBG_MSG("slicoss: %s adapter[%p] port %d FreeCommandsFrom CMDQ\n",
4115 __func__, adapter, adapter->physport);
4116 cmd = adapter->cmdq_all.head;
4119 struct sk_buff *tempskb;
4124 dev_kfree_skb_irq(tempskb);
4127 cmd = cmd->next_all;
4129 SLIC_ZERO_MEMORY(&adapter->cmdq_all, sizeof(slic_cmdqueue_t));
4130 SLIC_ZERO_MEMORY(&adapter->cmdq_free, sizeof(slic_cmdqueue_t));
4131 SLIC_ZERO_MEMORY(&adapter->cmdq_done, sizeof(slic_cmdqueue_t));
4132 slic_cmdqmem_free(adapter);
4135 void slic_cmdq_reset(p_adapter_t adapter)
4137 p_slic_hostcmd_t hcmd;
4138 struct sk_buff *skb;
4139 ulong32 outstanding;
4141 DBG_MSG("%s ENTER adapter[%p]\n", __func__, adapter);
4142 SLIC_ACQUIRE_IRQ_SPINLOCK(adapter->cmdq_free.lock);
4143 SLIC_ACQUIRE_IRQ_SPINLOCK(adapter->cmdq_done.lock);
4144 outstanding = adapter->cmdq_all.count - adapter->cmdq_done.count;
4145 outstanding -= adapter->cmdq_free.count;
4146 hcmd = adapter->cmdq_all.head;
4151 DBG_MSG("slicoss: %s hcmd[%p] skb[%p] ", __func__,
4155 DBG_MSG(" Free SKB\n");
4156 dev_kfree_skb_irq(skb);
4158 hcmd = hcmd->next_all;
4160 adapter->cmdq_free.count = 0;
4161 adapter->cmdq_free.head = NULL;
4162 adapter->cmdq_free.tail = NULL;
4163 adapter->cmdq_done.count = 0;
4164 adapter->cmdq_done.head = NULL;
4165 adapter->cmdq_done.tail = NULL;
4166 adapter->cmdq_free.head = adapter->cmdq_all.head;
4167 hcmd = adapter->cmdq_all.head;
4169 adapter->cmdq_free.count++;
4170 hcmd->next = hcmd->next_all;
4171 hcmd = hcmd->next_all;
4173 if (adapter->cmdq_free.count != adapter->cmdq_all.count) {
4174 DBG_ERROR("%s free_count %d != all count %d\n", __func__,
4175 adapter->cmdq_free.count, adapter->cmdq_all.count);
4177 SLIC_RELEASE_IRQ_SPINLOCK(adapter->cmdq_done.lock);
4178 SLIC_RELEASE_IRQ_SPINLOCK(adapter->cmdq_free.lock);
4179 DBG_MSG("%s EXIT adapter[%p]\n", __func__, adapter);
4182 void slic_cmdq_addcmdpage(p_adapter_t adapter, pulong32 page)
4184 p_slic_hostcmd_t cmd;
4185 p_slic_hostcmd_t prev;
4186 p_slic_hostcmd_t tail;
4187 p_slic_cmdqueue_t cmdq;
4193 pslic_handle_t pslic_handle;
4196 cmd = (p_slic_hostcmd_t) cmdaddr;
4197 /* DBG_MSG("CMDQ Page addr[%p] ix[%d] pfree[%p]\n", cmdaddr, slic_handle_ix,
4198 adapter->pfree_slic_handles); */
4201 phys_addr = SLIC_GET_PHYSICAL_ADDRESS((void *)page);
4202 phys_addrl = SLIC_GET_ADDR_LOW(phys_addr);
4203 phys_addrh = SLIC_GET_ADDR_HIGH(phys_addr);
4207 while ((cmdcnt < SLIC_CMDQ_CMDSINPAGE) &&
4208 (adapter->slic_handle_ix < 256)) {
4209 /* Allocate and initialize a SLIC_HANDLE for this command */
4210 SLIC_GET_SLIC_HANDLE(adapter, pslic_handle);
4211 if (pslic_handle == NULL)
4213 ASSERT(pslic_handle ==
4214 &adapter->slic_handles[pslic_handle->token.
4216 pslic_handle->type = SLIC_HANDLE_CMD;
4217 pslic_handle->address = (pvoid) cmd;
4218 pslic_handle->offset = (ushort) adapter->slic_handle_ix++;
4219 pslic_handle->other_handle = NULL;
4220 pslic_handle->next = NULL;
4222 cmd->pslic_handle = pslic_handle;
4223 cmd->cmd64.hosthandle = pslic_handle->token.handle_token;
4225 cmd->paddrl = phys_addrl;
4226 cmd->paddrh = phys_addrh;
4227 cmd->next_all = prev;
4230 phys_addrl += SLIC_HOSTCMD_SIZE;
4231 cmdaddr += SLIC_HOSTCMD_SIZE;
4233 cmd = (p_slic_hostcmd_t) cmdaddr;
4237 cmdq = &adapter->cmdq_all;
4238 cmdq->count += cmdcnt; /* SLIC_CMDQ_CMDSINPAGE; mooktodo */
4239 tail->next_all = cmdq->head;
4240 ASSERT(VALID_ADDRESS(prev));
4242 cmdq = &adapter->cmdq_free;
4243 SLIC_ACQUIRE_IRQ_SPINLOCK(cmdq->lock);
4244 cmdq->count += cmdcnt; /* SLIC_CMDQ_CMDSINPAGE; mooktodo */
4245 tail->next = cmdq->head;
4246 ASSERT(VALID_ADDRESS(prev));
4248 SLIC_RELEASE_IRQ_SPINLOCK(cmdq->lock);
4251 p_slic_hostcmd_t slic_cmdq_getfree(p_adapter_t adapter)
4253 p_slic_cmdqueue_t cmdq = &adapter->cmdq_free;
4254 p_slic_hostcmd_t cmd = NULL;
4257 SLIC_ACQUIRE_IRQ_SPINLOCK(cmdq->lock);
4261 cmdq->head = cmd->next;
4263 SLIC_RELEASE_IRQ_SPINLOCK(cmdq->lock);
4265 slic_cmdq_getdone(adapter);
4272 SLIC_RELEASE_IRQ_SPINLOCK(cmdq->lock);
4273 pageaddr = slic_cmdqmem_addpage(adapter);
4275 slic_cmdq_addcmdpage(adapter, pageaddr);
4276 goto lock_and_retry;
4283 void slic_cmdq_getdone(p_adapter_t adapter)
4285 p_slic_cmdqueue_t done_cmdq = &adapter->cmdq_done;
4286 p_slic_cmdqueue_t free_cmdq = &adapter->cmdq_free;
4288 ASSERT(free_cmdq->head == NULL);
4289 SLIC_ACQUIRE_IRQ_SPINLOCK(done_cmdq->lock);
4290 ASSERT(VALID_ADDRESS(done_cmdq->head));
4292 free_cmdq->head = done_cmdq->head;
4293 free_cmdq->count = done_cmdq->count;
4294 done_cmdq->head = NULL;
4295 done_cmdq->tail = NULL;
4296 done_cmdq->count = 0;
4297 SLIC_RELEASE_IRQ_SPINLOCK(done_cmdq->lock);
4300 void slic_cmdq_putdone(p_adapter_t adapter, p_slic_hostcmd_t cmd)
4302 p_slic_cmdqueue_t cmdq = &adapter->cmdq_done;
4304 SLIC_ACQUIRE_IRQ_SPINLOCK(cmdq->lock);
4306 ASSERT(VALID_ADDRESS(cmdq->head));
4307 cmd->next = cmdq->head;
4308 ASSERT(VALID_ADDRESS(cmd));
4311 SLIC_RELEASE_IRQ_SPINLOCK(cmdq->lock);
4314 void slic_cmdq_putdone_irq(p_adapter_t adapter, p_slic_hostcmd_t cmd)
4316 p_slic_cmdqueue_t cmdq = &adapter->cmdq_done;
4318 SLIC_ACQUIRE_SPINLOCK(cmdq->lock);
4320 ASSERT(VALID_ADDRESS(cmdq->head));
4321 cmd->next = cmdq->head;
4322 ASSERT(VALID_ADDRESS(cmd));
4325 if ((adapter->xmitq_full) && (cmdq->count > 10))
4326 netif_wake_queue(adapter->netdev);
4327 SLIC_RELEASE_SPINLOCK(cmdq->lock);
4330 int slic_rcvqueue_init(p_adapter_t adapter)
4333 p_slic_rcvqueue_t rcvq = &adapter->rcvqueue;
4335 DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
4336 ASSERT(adapter->state == ADAPT_DOWN);
4339 rcvq->size = SLIC_RCVQ_ENTRIES;
4342 i = (SLIC_RCVQ_ENTRIES / SLIC_RCVQ_FILLENTRIES);
4345 count += slic_rcvqueue_fill(adapter);
4348 if (rcvq->count < SLIC_RCVQ_MINENTRIES) {
4349 slic_rcvqueue_free(adapter);
4350 return STATUS_FAILURE;
4352 DBG_MSG("slicoss: %s EXIT adapter[%p]\n", __func__, adapter);
4353 return STATUS_SUCCESS;
4356 int slic_rcvqueue_reset(p_adapter_t adapter)
4358 p_slic_rcvqueue_t rcvq = &adapter->rcvqueue;
4360 DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
4361 ASSERT(adapter->state == ADAPT_DOWN);
4364 DBG_MSG("slicoss: Nothing to do. rcvq[%p]\n"
4368 rcvq, rcvq->count, rcvq->head, rcvq->tail);
4370 DBG_MSG("slicoss: %s EXIT adapter[%p]\n", __func__, adapter);
4371 return STATUS_SUCCESS;
4374 void slic_rcvqueue_free(p_adapter_t adapter)
4376 slic_rcvqueue_t *rcvq = &adapter->rcvqueue;
4377 struct sk_buff *skb;
4379 while (rcvq->head) {
4381 rcvq->head = rcvq->head->next;
4389 struct sk_buff *slic_rcvqueue_getnext(p_adapter_t adapter)
4391 p_slic_rcvqueue_t rcvq = &adapter->rcvqueue;
4392 struct sk_buff *skb;
4393 p_slic_rcvbuf_t rcvbuf;
4398 rcvbuf = (p_slic_rcvbuf_t) skb->head;
4401 if (rcvbuf->status & IRHDDR_SVALID) {
4402 rcvq->head = rcvq->head->next;
4409 DBG_ERROR("RcvQ Empty!! adapter[%p] rcvq[%p] count[%x]\n",
4410 adapter, rcvq, rcvq->count);
4413 while (rcvq->count < SLIC_RCVQ_FILLTHRESH) {
4414 count = slic_rcvqueue_fill(adapter);
4423 int slic_rcvqueue_fill(p_adapter_t adapter)
4428 p_slic_rcvqueue_t rcvq = &adapter->rcvqueue;
4431 while (i < SLIC_RCVQ_FILLENTRIES) {
4432 p_slic_rcvbuf_t rcvbuf;
4433 struct sk_buff *skb;
4434 #ifdef KLUDGE_FOR_4GB_BOUNDARY
4437 skb = alloc_skb(SLIC_RCVQ_RCVBUFSIZE, GFP_ATOMIC);
4439 paddr = (void *)SLIC_GET_DMA_ADDRESS_READ(adapter,
4441 SLIC_RCVQ_RCVBUFSIZE);
4442 paddrl = SLIC_GET_ADDR_LOW(paddr);
4443 paddrh = SLIC_GET_ADDR_HIGH(paddr);
4445 skb->len = SLIC_RCVBUF_HEADSIZE;
4446 rcvbuf = (p_slic_rcvbuf_t) skb->head;
4449 #ifdef KLUDGE_FOR_4GB_BOUNDARY
4452 ("%s: LOW 32bits PHYSICAL ADDRESS == 0 "
4458 " paddrh[%x]\n", __func__, skb,
4459 skb->data, skb->len, paddr, paddrl,
4461 DBG_ERROR(" rcvq->head[%p]\n"
4463 " rcvq->count[%x]\n",
4464 rcvq->head, rcvq->tail, rcvq->count);
4465 DBG_ERROR("SKIP THIS SKB!!!!!!!!\n");
4466 goto retry_rcvqfill;
4471 ("\n\n%s: LOW 32bits PHYSICAL ADDRESS == 0 "
4472 "skb[%p] GIVE TO CARD ANYWAY\n"
4476 " paddrh[%x]\n", __func__, skb,
4477 skb->data, paddr, paddrl, paddrh);
4481 WRITE_REG(adapter->slic_regs->slic_hbar,
4482 (ulong32) paddrl, DONT_FLUSH);
4484 WRITE_REG64(adapter,
4485 adapter->slic_regs->slic_hbar64,
4487 adapter->slic_regs->slic_addr_upper,
4488 (ulong32) paddrh, DONT_FLUSH);
4491 rcvq->tail->next = skb;
4499 ("%s slic_rcvqueue_fill could only get [%d] "
4501 adapter->netdev->name, i);
4508 ulong32 slic_rcvqueue_reinsert(p_adapter_t adapter, struct sk_buff *skb)
4510 p_slic_rcvqueue_t rcvq = &adapter->rcvqueue;
4514 p_slic_rcvbuf_t rcvbuf = (p_slic_rcvbuf_t) skb->head;
4516 ASSERT(skb->len == SLIC_RCVBUF_HEADSIZE);
4517 paddr = (void *)SLIC_GET_DMA_ADDRESS_READ(adapter,
4519 SLIC_RCVQ_RCVBUFSIZE);
4523 paddrl = SLIC_GET_ADDR_LOW(paddr);
4524 paddrh = SLIC_GET_ADDR_HIGH(paddr);
4528 ("%s: LOW 32bits PHYSICAL ADDRESS == 0 skb[%p] PROBLEM\n"
4529 " skbdata[%p]\n" " skblen[%x]\n"
4530 " paddr[%p]\n" " paddrl[%x]\n"
4531 " paddrh[%x]\n", __func__, skb, skb->data,
4532 skb->len, paddr, paddrl, paddrh);
4533 DBG_ERROR(" rcvq->head[%p]\n"
4535 " rcvq->count[%x]\n", rcvq->head, rcvq->tail,
4539 WRITE_REG(adapter->slic_regs->slic_hbar, (ulong32) paddrl,
4542 WRITE_REG64(adapter,
4543 adapter->slic_regs->slic_hbar64,
4545 adapter->slic_regs->slic_addr_upper,
4546 paddrh, DONT_FLUSH);
4549 rcvq->tail->next = skb;
4557 static int slic_debug_card_show(struct seq_file *seq, void *v)
4561 p_sliccard_t card = seq->private;
4562 pslic_config_t config = &card->config;
4563 puchar fru = (puchar) (&card->config.atk_fru);
4564 puchar oemfru = (puchar) (&card->config.OemFru);
4567 seq_printf(seq, "driver_version : %s", slic_proc_version);
4568 seq_printf(seq, "Microcode versions: \n");
4569 seq_printf(seq, " Gigabit (gb) : %s %s\n",
4570 MOJAVE_UCODE_VERS_STRING, MOJAVE_UCODE_VERS_DATE);
4571 seq_printf(seq, " Gigabit Receiver : %s %s\n",
4572 GB_RCVUCODE_VERS_STRING, GB_RCVUCODE_VERS_DATE);
4573 seq_printf(seq, "Vendor : %s\n", slic_vendor);
4574 seq_printf(seq, "Product Name : %s\n", slic_product_name);
4576 seq_printf(seq, "VendorId : %4.4X\n",
4578 seq_printf(seq, "DeviceId : %4.4X\n",
4580 seq_printf(seq, "RevisionId : %2.2x\n",
4581 config->RevisionId);
4582 seq_printf(seq, "Bus # : %d\n", card->busnumber);
4583 seq_printf(seq, "Device # : %d\n", card->slotnumber);
4584 seq_printf(seq, "Interfaces : %d\n", card->card_size);
4585 seq_printf(seq, " Initialized : %d\n",
4586 card->adapters_activated);
4587 seq_printf(seq, " Allocated : %d\n",
4588 card->adapters_allocated);
4589 ASSERT(card->card_size <= SLIC_NBR_MACS);
4590 for (i = 0; i < card->card_size; i++) {
4592 " MAC%d : %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
4593 i, config->macinfo[i].macaddrA[0],
4594 config->macinfo[i].macaddrA[1],
4595 config->macinfo[i].macaddrA[2],
4596 config->macinfo[i].macaddrA[3],
4597 config->macinfo[i].macaddrA[4],
4598 config->macinfo[i].macaddrA[5]);
4600 seq_printf(seq, " IF Init State Duplex/Speed irq\n");
4601 seq_printf(seq, " -------------------------------\n");
4602 for (i = 0; i < card->adapters_allocated; i++) {
4603 p_adapter_t adapter;
4605 adapter = card->adapter[i];
4608 " %d %d %s %s %s 0x%X\n",
4609 adapter->physport, adapter->state,
4610 SLIC_LINKSTATE(adapter->linkstate),
4611 SLIC_DUPLEX(adapter->linkduplex),
4612 SLIC_SPEED(adapter->linkspeed),
4613 (uint) adapter->irq);
4616 seq_printf(seq, "Generation # : %4.4X\n", card->gennumber);
4617 seq_printf(seq, "RcvQ max entries : %4.4X\n",
4619 seq_printf(seq, "Ping Status : %8.8X\n",
4621 seq_printf(seq, "Minimum grant : %2.2x\n",
4623 seq_printf(seq, "Maximum Latency : %2.2x\n", config->MaxLat);
4624 seq_printf(seq, "PciStatus : %4.4x\n",
4626 seq_printf(seq, "Debug Device Id : %4.4x\n",
4628 seq_printf(seq, "DRAM ROM Function : %4.4x\n",
4630 seq_printf(seq, "Network interface Pin 1 : %2.2x\n",
4631 config->NetIntPin1);
4632 seq_printf(seq, "Network interface Pin 2 : %2.2x\n",
4633 config->NetIntPin1);
4634 seq_printf(seq, "Network interface Pin 3 : %2.2x\n",
4635 config->NetIntPin1);
4636 seq_printf(seq, "PM capabilities : %4.4X\n",
4638 seq_printf(seq, "Network Clock Controls : %4.4X\n",
4639 config->NwClkCtrls);
4641 switch (config->FruFormat) {
4642 case ATK_FRU_FORMAT:
4645 "Vendor : Alacritech, Inc.\n");
4647 "Assembly # : %c%c%c%c%c%c\n",
4648 fru[0], fru[1], fru[2], fru[3], fru[4],
4651 "Revision # : %c%c\n",
4654 if (config->OEMFruFormat == VENDOR4_FRU_FORMAT) {
4657 "%c%c%c%c%c%c%c%c%c%c%c%c\n",
4658 fru[8], fru[9], fru[10],
4659 fru[11], fru[12], fru[13],
4660 fru[16], fru[17], fru[18],
4661 fru[19], fru[20], fru[21]);
4665 "%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
4666 fru[8], fru[9], fru[10],
4667 fru[11], fru[12], fru[13],
4668 fru[14], fru[15], fru[16],
4669 fru[17], fru[18], fru[19],
4678 "Vendor : Alacritech, Inc.\n");
4680 "Serial # : Empty FRU\n");
4685 switch (config->OEMFruFormat) {
4686 case VENDOR1_FRU_FORMAT:
4688 seq_printf(seq, "FRU Information:\n");
4689 seq_printf(seq, " Commodity # : %c\n",
4692 " Assembly # : %c%c%c%c\n",
4693 oemfru[1], oemfru[2], oemfru[3], oemfru[4]);
4695 " Revision # : %c%c\n",
4696 oemfru[5], oemfru[6]);
4698 " Supplier # : %c%c\n",
4699 oemfru[7], oemfru[8]);
4702 oemfru[9], oemfru[10]);
4704 " Sequence # : %c%c%c\n",
4705 oemfru[11], oemfru[12], oemfru[13]);
4709 case VENDOR2_FRU_FORMAT:
4711 seq_printf(seq, "FRU Information:\n");
4714 "%c%c%c%c%c%c%c%c\n",
4715 oemfru[0], oemfru[1], oemfru[2],
4716 oemfru[3], oemfru[4], oemfru[5],
4717 oemfru[6], oemfru[7]);
4719 " Supplier # : %c%c%c%c%c\n",
4720 oemfru[8], oemfru[9], oemfru[10],
4721 oemfru[11], oemfru[12]);
4724 oemfru[13], oemfru[14], oemfru[15]);
4726 " Sequence # : %c%c%c%c\n",
4727 oemfru[16], oemfru[17], oemfru[18],
4732 case VENDOR3_FRU_FORMAT:
4734 seq_printf(seq, "FRU Information:\n");
4737 case VENDOR4_FRU_FORMAT:
4739 seq_printf(seq, "FRU Information:\n");
4742 "%c%c%c%c%c%c%c%c\n",
4743 oemfru[0], oemfru[1], oemfru[2],
4744 oemfru[3], oemfru[4], oemfru[5],
4745 oemfru[6], oemfru[7]);
4748 "%c%c%c%c%c%c%c%c\n",
4749 oemfru[8], oemfru[9], oemfru[10],
4750 oemfru[11], oemfru[12], oemfru[13],
4751 oemfru[14], oemfru[15]);
4754 "%c%c%c%c%c%c%c%c\n",
4755 oemfru[16], oemfru[17], oemfru[18],
4756 oemfru[19], oemfru[20], oemfru[21],
4757 oemfru[22], oemfru[23]);
4769 static int slic_debug_adapter_show(struct seq_file *seq, void *v)
4771 p_adapter_t adapter = seq->private;
4773 if ((adapter->netdev) && (adapter->netdev->name)) {
4774 seq_printf(seq, "info: interface : %s\n",
4775 adapter->netdev->name);
4777 seq_printf(seq, "info: status : %s\n",
4778 SLIC_LINKSTATE(adapter->linkstate));
4779 seq_printf(seq, "info: port : %d\n",
4781 seq_printf(seq, "info: speed : %s\n",
4782 SLIC_SPEED(adapter->linkspeed));
4783 seq_printf(seq, "info: duplex : %s\n",
4784 SLIC_DUPLEX(adapter->linkduplex));
4785 seq_printf(seq, "info: irq : 0x%X\n",
4786 (uint) adapter->irq);
4787 seq_printf(seq, "info: Interrupt Agg Delay: %d usec\n",
4788 adapter->card->loadlevel_current);
4789 seq_printf(seq, "info: RcvQ max entries : %4.4X\n",
4791 seq_printf(seq, "info: RcvQ current : %4.4X\n",
4792 adapter->rcvqueue.count);
4793 seq_printf(seq, "rx stats: packets : %8.8lX\n",
4794 adapter->stats.rx_packets);
4795 seq_printf(seq, "rx stats: bytes : %8.8lX\n",
4796 adapter->stats.rx_bytes);
4797 seq_printf(seq, "rx stats: broadcasts : %8.8X\n",
4798 adapter->rcv_broadcasts);
4799 seq_printf(seq, "rx stats: multicasts : %8.8X\n",
4800 adapter->rcv_multicasts);
4801 seq_printf(seq, "rx stats: unicasts : %8.8X\n",
4802 adapter->rcv_unicasts);
4803 seq_printf(seq, "rx stats: errors : %8.8X\n",
4804 (ulong32) adapter->slic_stats.iface.rcv_errors);
4805 seq_printf(seq, "rx stats: Missed errors : %8.8X\n",
4806 (ulong32) adapter->slic_stats.iface.rcv_discards);
4807 seq_printf(seq, "rx stats: drops : %8.8X\n",
4808 (ulong32) adapter->rcv_drops);
4809 seq_printf(seq, "tx stats: packets : %8.8lX\n",
4810 adapter->stats.tx_packets);
4811 seq_printf(seq, "tx stats: bytes : %8.8lX\n",
4812 adapter->stats.tx_bytes);
4813 seq_printf(seq, "tx stats: errors : %8.8X\n",
4814 (ulong32) adapter->slic_stats.iface.xmt_errors);
4815 seq_printf(seq, "rx stats: multicasts : %8.8lX\n",
4816 adapter->stats.multicast);
4817 seq_printf(seq, "tx stats: collision errors : %8.8X\n",
4818 (ulong32) adapter->slic_stats.iface.xmit_collisions);
4819 seq_printf(seq, "perf: Max rcv frames/isr : %8.8X\n",
4820 adapter->max_isr_rcvs);
4821 seq_printf(seq, "perf: Rcv interrupt yields : %8.8X\n",
4822 adapter->rcv_interrupt_yields);
4823 seq_printf(seq, "perf: Max xmit complete/isr : %8.8X\n",
4824 adapter->max_isr_xmits);
4825 seq_printf(seq, "perf: error interrupts : %8.8X\n",
4826 adapter->error_interrupts);
4827 seq_printf(seq, "perf: error rmiss interrupts : %8.8X\n",
4828 adapter->error_rmiss_interrupts);
4829 seq_printf(seq, "perf: rcv interrupts : %8.8X\n",
4830 adapter->rcv_interrupts);
4831 seq_printf(seq, "perf: xmit interrupts : %8.8X\n",
4832 adapter->xmit_interrupts);
4833 seq_printf(seq, "perf: link event interrupts : %8.8X\n",
4834 adapter->linkevent_interrupts);
4835 seq_printf(seq, "perf: UPR interrupts : %8.8X\n",
4836 adapter->upr_interrupts);
4837 seq_printf(seq, "perf: interrupt count : %8.8X\n",
4839 seq_printf(seq, "perf: false interrupts : %8.8X\n",
4840 adapter->false_interrupts);
4841 seq_printf(seq, "perf: All register writes : %8.8X\n",
4842 adapter->all_reg_writes);
4843 seq_printf(seq, "perf: ICR register writes : %8.8X\n",
4844 adapter->icr_reg_writes);
4845 seq_printf(seq, "perf: ISR register writes : %8.8X\n",
4846 adapter->isr_reg_writes);
4847 seq_printf(seq, "ifevents: overflow 802 errors : %8.8X\n",
4848 adapter->if_events.oflow802);
4849 seq_printf(seq, "ifevents: transport overflow errors: %8.8X\n",
4850 adapter->if_events.Tprtoflow);
4851 seq_printf(seq, "ifevents: underflow errors : %8.8X\n",
4852 adapter->if_events.uflow802);
4853 seq_printf(seq, "ifevents: receive early : %8.8X\n",
4854 adapter->if_events.rcvearly);
4855 seq_printf(seq, "ifevents: buffer overflows : %8.8X\n",
4856 adapter->if_events.Bufov);
4857 seq_printf(seq, "ifevents: carrier errors : %8.8X\n",
4858 adapter->if_events.Carre);
4859 seq_printf(seq, "ifevents: Long : %8.8X\n",
4860 adapter->if_events.Longe);
4861 seq_printf(seq, "ifevents: invalid preambles : %8.8X\n",
4862 adapter->if_events.Invp);
4863 seq_printf(seq, "ifevents: CRC errors : %8.8X\n",
4864 adapter->if_events.Crc);
4865 seq_printf(seq, "ifevents: dribble nibbles : %8.8X\n",
4866 adapter->if_events.Drbl);
4867 seq_printf(seq, "ifevents: Code violations : %8.8X\n",
4868 adapter->if_events.Code);
4869 seq_printf(seq, "ifevents: TCP checksum errors : %8.8X\n",
4870 adapter->if_events.TpCsum);
4871 seq_printf(seq, "ifevents: TCP header short errors : %8.8X\n",
4872 adapter->if_events.TpHlen);
4873 seq_printf(seq, "ifevents: IP checksum errors : %8.8X\n",
4874 adapter->if_events.IpCsum);
4875 seq_printf(seq, "ifevents: IP frame incompletes : %8.8X\n",
4876 adapter->if_events.IpLen);
4877 seq_printf(seq, "ifevents: IP headers shorts : %8.8X\n",
4878 adapter->if_events.IpHlen);
4882 static int slic_debug_adapter_open(struct inode *inode, struct file *file)
4884 return single_open(file, slic_debug_adapter_show, inode->i_private);
4887 static int slic_debug_card_open(struct inode *inode, struct file *file)
4889 return single_open(file, slic_debug_card_show, inode->i_private);
4892 static const struct file_operations slic_debug_adapter_fops = {
4893 .owner = THIS_MODULE,
4894 .open = slic_debug_adapter_open,
4896 .llseek = seq_lseek,
4897 .release = single_release,
4900 static const struct file_operations slic_debug_card_fops = {
4901 .owner = THIS_MODULE,
4902 .open = slic_debug_card_open,
4904 .llseek = seq_lseek,
4905 .release = single_release,
4908 static void slic_debug_adapter_create(p_adapter_t adapter)
4912 p_sliccard_t card = adapter->card;
4914 if (!card->debugfs_dir)
4917 sprintf(name, "port%d", adapter->port);
4918 d = debugfs_create_file(name, S_IRUGO,
4919 card->debugfs_dir, adapter,
4920 &slic_debug_adapter_fops);
4921 if (!d || IS_ERR(d))
4922 pr_info(PFX "%s: debugfs create failed\n", name);
4924 adapter->debugfs_entry = d;
4927 static void slic_debug_adapter_destroy(p_adapter_t adapter)
4929 if (adapter->debugfs_entry) {
4930 debugfs_remove(adapter->debugfs_entry);
4931 adapter->debugfs_entry = NULL;
4935 static void slic_debug_card_create(p_sliccard_t card)
4938 char name[IFNAMSIZ];
4940 snprintf(name, sizeof(name), "slic%d", card->cardnum);
4941 d = debugfs_create_dir(name, slic_debugfs);
4942 if (!d || IS_ERR(d))
4943 pr_info(PFX "%s: debugfs create dir failed\n",
4946 card->debugfs_dir = d;
4947 d = debugfs_create_file("cardinfo", S_IRUGO,
4949 &slic_debug_card_fops);
4950 if (!d || IS_ERR(d))
4951 pr_info(PFX "%s: debugfs create failed\n",
4954 card->debugfs_cardinfo = d;
4958 static void slic_debug_card_destroy(p_sliccard_t card)
4962 for (i = 0; i < card->card_size; i++) {
4963 p_adapter_t adapter;
4965 adapter = card->adapter[i];
4967 slic_debug_adapter_destroy(adapter);
4969 if (card->debugfs_cardinfo) {
4970 debugfs_remove(card->debugfs_cardinfo);
4971 card->debugfs_cardinfo = NULL;
4973 if (card->debugfs_dir) {
4974 debugfs_remove(card->debugfs_dir);
4975 card->debugfs_dir = NULL;
4979 static void slic_debug_init(void)
4983 ent = debugfs_create_dir("slic", NULL);
4984 if (!ent || IS_ERR(ent)) {
4985 pr_info(PFX "debugfs create directory failed\n");
4992 static void slic_debug_cleanup(void)
4995 debugfs_remove(slic_debugfs);
4996 slic_debugfs = NULL;
5000 /*=============================================================================
5001 =============================================================================
5003 === SLIC DUMP MANAGEMENT SECTION ===
5006 === Dump routines ===
5009 =============================================================================
5010 ============================================================================*/
5012 #if SLIC_DUMP_ENABLED
5016 pvoid slic_dump_handle; /* thread handle */
5019 * These are the only things you should do on a core-file: use only these
5020 * functions to write out all the necessary info.
5022 static int slic_dump_seek(struct file *SLIChandle, ulong32 file_offset)
5024 if (SLIChandle->f_pos != file_offset) {
5025 /*DBG_MSG("slic_dump_seek now needed [%x : %x]\n",
5026 (ulong32)SLIChandle->f_pos, (ulong32)file_offset); */
5027 if (SLIChandle->f_op->llseek) {
5028 if (SLIChandle->f_op->
5029 llseek(SLIChandle, file_offset, 0) != file_offset)
5032 SLIChandle->f_pos = file_offset;
5038 static int slic_dump_write(p_sliccard_t card,
5039 const void *addr, int size, ulong32 file_offset)
5043 struct file *SLIChandle = card->dumphandle;
5045 #ifdef HISTORICAL /* legacy */
5046 down(&SLIChandle->f_dentry->d_inode->i_sem);
5049 slic_dump_seek(SLIChandle, file_offset);
5052 SLIChandle->f_op->write(SLIChandle, addr, size,
5053 &SLIChandle->f_pos);
5058 card->dumptime_complete = jiffies;
5059 card->dumptime_delta = card->dumptime_complete - card->dumptime_start;
5060 card->dumptime_start = jiffies;
5063 up(&SLIChandle->f_dentry->d_inode->i_sem);
5066 DBG_ERROR("%s: addr[%p] size[%x] result[%x] file_offset[%x]\n",
5067 __func__, addr, size, result, file_offset);
5072 uint slic_init_dump_thread(p_sliccard_t card)
5074 card->dump_task_id = kthread_run(slic_dump_thread, (void *)card, 0);
5076 /* DBG_MSG("create slic_dump_thread dump_pid[%x]\n", card->dump_pid); */
5077 if (IS_ERR(card->dump_task_id)) {
5078 DBG_MSG("create slic_dump_thread FAILED \n");
5079 return STATUS_FAILURE;
5082 return STATUS_SUCCESS;
5085 int slic_dump_thread(void *context)
5087 p_sliccard_t card = (p_sliccard_t) context;
5088 p_adapter_t adapter;
5089 p_adapter_t dump_adapter = NULL;
5090 ulong32 dump_complete = 0;
5091 ulong32 delay = SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
5092 p_slic_regs_t pregs;
5094 p_slic_upr_t upr, uprnext;
5099 card->dumpthread_running = 1;
5104 * This thread doesn't need any user-level access,
5105 * so get rid of all our resources
5107 exit_files(current); /* daemonize doesn't do exit_files */
5108 current->files = init_task.files;
5109 atomic_inc(¤t->files->count);
5112 daemonize("%s", "slicmon");
5114 /* Setup a nice name */
5115 strcpy(current->comm, "slicmon");
5117 ("slic_dump_thread[slicmon] daemon is alive card[%p] pid[%x]\n",
5118 card, card->dump_task_id->pid);
5121 * Send me a signal to get me to die (for debugging)
5125 * If card state is not set to up, skip
5127 if (card->state != CARD_UP) {
5128 if (card->adapters_activated)
5134 * Check the results of our last ping.
5137 #ifdef SLIC_FAILURE_DUMP
5138 if (card->pingstatus != ISR_PINGMASK) {
5140 ("\n[slicmon] CARD #%d TIMED OUT - status "
5141 "%x: DUMP THE CARD!\n",
5142 card->cardnum, card->pingstatus);
5147 * Cause a card RESET instead?
5149 if (card->pingstatus != ISR_PINGMASK) {
5150 /* todo. do we want to reset the card in production */
5151 /* DBG_MSG("\n[slicmon] CARD #%d TIMED OUT - "
5152 status %x: RESET THE CARD!\n", card->cardnum,
5153 card->pingstatus); */
5155 ("\n[slicmon] CARD #%d TIMED OUT - status %x: "
5157 card->cardnum, card->pingstatus);
5162 || (card->dump_requested == SLIC_DUMP_REQUESTED)) {
5163 if (card->dump_requested == SLIC_DUMP_REQUESTED) {
5165 ("[slicmon]: Dump card Requested: Card %x\n",
5168 if (card->pingstatus != ISR_PINGMASK) {
5172 if (card->adapter[0]) {
5173 if ((card->adapter[0])->memorylength >=
5175 sizeof(slic_crash_info)) {
5177 p_slic_crash_info crashinfo;
5180 ((char *)card->adapter[0]->
5186 cpuid = crashinfo->cpu_id;
5187 crashpc = crashinfo->crash_pc;
5191 ("[slicmon]: Dump card: Card %x crashed "
5192 "and failed to answer PING. "
5193 "CPUID[%x] PC[%x]\n ",
5194 card->cardnum, cpuid, crashpc);
5197 card->dump_requested = SLIC_DUMP_IN_PROGRESS;
5200 * Set the card state to DOWN and the adapter states
5201 * to RESET.They will check this in SimbaCheckForHang
5202 * and initiate interface reset (which in turn will
5203 * reinitialize the card).
5205 card->state = CARD_DOWN;
5207 for (i = 0; i < card->card_size; i++) {
5208 adapter = card->adapter[i];
5210 slic_if_stop_queue(adapter);
5212 if (adapter->state == ADAPT_UP) {
5213 adapter->state = ADAPT_RESET;
5214 adapter->linkstate = LINK_DOWN;
5216 ("[slicmon]: SLIC Card[%d] "
5217 "Port[%d] adapter[%p] "
5219 (uint) card->cardnum,
5222 #if SLIC_GET_STATS_TIMER_ENABLED
5223 /* free stats timer */
5224 if (adapter->statstimerset) {
5225 adapter->statstimerset = 0;
5226 del_timer(&adapter->statstimer);
5232 for (i = 0; i < card->card_size; i++) {
5233 adapter = card->adapter[i];
5234 if ((adapter) && (adapter->activated)) {
5235 pregs = adapter->slic_regs;
5236 dump_adapter = adapter;
5239 * If the dump status is zero, then
5240 * the utility processor has crashed.
5241 * If this is the case, any pending
5242 * utilityprocessor requests will not
5243 * complete and our dump commands will
5246 * To avoid this we will clear any
5247 * pending utility processor requests
5250 if (!card->pingstatus) {
5251 SLIC_ACQUIRE_IRQ_SPINLOCK
5252 (adapter->upr_lock);
5253 upr = adapter->upr_list;
5255 uprnext = upr->next;
5260 adapter->upr_list = 0;
5261 adapter->upr_busy = 0;
5262 SLIC_RELEASE_IRQ_SPINLOCK
5263 (adapter->upr_lock);
5266 slic_dump_card(card, FALSE);
5270 if (dump_complete) {
5271 DBG_ERROR("SLIC Dump Complete\n");
5272 /* Only dump the card one time */
5279 ("slic dump completed. "
5280 "Reenable interfaces\n");
5281 slic_card_init(card, dump_adapter);
5284 * Reenable the adapters that were reset
5286 for (i = 0; i < card->card_size; i++) {
5287 adapter = card->adapter[i];
5289 if (adapter->state ==
5293 "Card[%d] Port[%d] adapter[%p] "
5300 adapter->linkstate =
5308 card->dump_requested = SLIC_DUMP_DONE;
5311 /* if pingstatus != ISR_PINGMASK) || dump_requested...ELSE
5312 * We received a valid ping response.
5313 * Clear the Pingstatus field, find a valid adapter
5314 * structure and send another ping.
5316 for (i = 0; i < card->card_size; i++) {
5317 adapter = card->adapter[i];
5318 if (adapter && (adapter->state == ADAPT_UP)) {
5319 card->pingstatus = 0;
5320 slic_upr_request(adapter, SLIC_UPR_PING,
5322 break; /* Only issue one per card */
5327 SLIC_INTERRUPTIBLE_SLEEP_ON_TIMEOUT(card->dump_wq, delay);
5328 } while (!signal_pending(current));
5331 /* DBG_MSG("[slicmon] slic_dump_thread card[%p] pid[%x] ENDING\n",
5332 card, card->dump_pid); */
5333 card->dumpthread_running = 0;
5339 * Read a single byte from our dump index file. This
5340 * value is used as our suffix for our dump path. The
5341 * value is incremented and written back to the file
5343 uchar slic_get_dump_index(pchar path)
5346 #ifdef SLIC_DUMP_INDEX_SUPPORT
5354 * Open the index file. If one doesn't exist, create it
5356 status = create_file(&FileHandle);
5358 if (status != STATUS_SUCCESS)
5361 status = read_file(FileHandle, &index, 1, &offset);
5365 status = write_file(FileHandle, &index, 1, &offset);
5367 close_file(FileHandle);
5374 struct file *slic_dump_open_file(p_sliccard_t card)
5376 struct file *SLIChandle = NULL;
5377 struct dentry *dentry = NULL;
5378 struct inode *inode = NULL;
5381 card->dumpfile_fs = get_fs();
5385 memset(SLICfile, 0, sizeof(SLICfile));
5386 sprintf(SLICfile, "/var/tmp/slic%d-dump-%d", card->cardnum,
5387 (uint) card->dump_count);
5391 filp_open(SLICfile, O_CREAT | O_RDWR | O_SYNC | O_LARGEFILE, 0666);
5393 DBG_MSG("[slicmon]: Dump Card #%d to file: %s \n", card->cardnum,
5396 /* DBG_MSG("[slicmon] filp_open %s SLIChandle[%p]\n", SLICfile, SLIChandle);*/
5398 if (IS_ERR(SLIChandle))
5401 dentry = SLIChandle->f_dentry;
5402 inode = dentry->d_inode;
5404 /* DBG_MSG("[slicmon] inode[%p] i_nlink[%x] i_mode[%x] i_op[%p] i_fop[%p]\n"
5405 "f_op->write[%p]\n",
5406 inode, inode->i_nlink, inode->i_mode, inode->i_op,
5407 inode->i_fop, SLIChandle->f_op->write); */
5408 if (inode->i_nlink > 1)
5409 goto close_slicdump; /* multiple links - don't dump */
5411 if (!S_ISREG(inode->i_mode))
5412 goto close_slicdump;
5414 if (!inode->i_op || !inode->i_fop)
5415 goto close_slicdump;
5417 if (!SLIChandle->f_op->write)
5418 goto close_slicdump;
5421 * If we got here we have SUCCESSFULLY OPENED the dump file
5423 /* DBG_MSG("opened %s SLIChandle[%p]\n", SLICfile, SLIChandle); */
5427 DBG_MSG("[slicmon] slic_dump_open_file failed close SLIChandle[%p]\n",
5429 filp_close(SLIChandle, NULL);
5432 set_fs(card->dumpfile_fs);
5437 void slic_dump_close_file(p_sliccard_t card)
5440 /* DBG_MSG("[slicmon] slic_dump_CLOSE_file close SLIChandle[%p]\n",
5441 card->dumphandle); */
5443 filp_close(card->dumphandle, NULL);
5445 set_fs(card->dumpfile_fs);
5448 ulong32 slic_dump_card(p_sliccard_t card, boolean resume)
5450 p_adapter_t adapter = card->master;
5453 ulong32 len, offset;
5454 ulong32 sram_size, dram_size, regs;
5455 sliccore_hdr_t corehdr;
5456 ulong32 file_offset;
5459 ulong32 max_queues = 0;
5462 card->dumphandle = slic_dump_open_file(card);
5464 if (card->dumphandle == NULL) {
5465 DBG_MSG("[slicmon] Cant create Dump file - dump failed\n");
5468 if (!card->dumpbuffer) {
5469 DBG_MSG("[slicmon] Insufficient memory for dump\n");
5472 if (!card->cmdbuffer) {
5473 DBG_MSG("[slicmon] Insufficient cmd memory for dump\n");
5478 * Write the file version to the core header.
5480 namestr = slic_proc_version;
5481 for (i = 0; i < (DRIVER_NAME_SIZE - 1); i++, namestr++) {
5484 corehdr.driver_version[i] = *namestr;
5486 corehdr.driver_version[i] = 0;
5488 file_offset = sizeof(sliccore_hdr_t);
5491 * Issue the following debug commands to the SLIC:
5492 * - Halt both receive and transmit
5493 * - Dump receive registers
5494 * - Dump transmit registers
5499 DBG_MSG("slicDump HALT Receive Processor\n");
5500 card->dumptime_start = jiffies;
5502 status = slic_dump_halt(card, PROC_RECEIVE);
5503 if (status != STATUS_SUCCESS) {
5505 ("Cant halt receive sequencer - dump failed status[%x]\n",
5510 DBG_MSG("slicDump HALT Transmit Processor\n");
5511 status = slic_dump_halt(card, PROC_TRANSMIT);
5512 if (status != STATUS_SUCCESS) {
5513 DBG_ERROR("Cant halt transmit sequencer - dump failed\n");
5517 /* Dump receive regs */
5518 status = slic_dump_reg(card, PROC_RECEIVE);
5519 if (status != STATUS_SUCCESS) {
5520 DBG_ERROR("Cant dump receive registers - dump failed\n");
5524 DBG_MSG("slicDump Write Receive REGS len[%x] offset[%x]\n",
5525 (SLIC_NUM_REG * 4), file_offset);
5528 slic_dump_write(card, card->dumpbuffer, SLIC_NUM_REG * 4,
5532 ("Cant write rcv registers to dump file - dump failed\n");
5536 corehdr.RcvRegOff = file_offset;
5537 corehdr.RcvRegsize = SLIC_NUM_REG * 4;
5538 file_offset += SLIC_NUM_REG * 4;
5540 /* Dump transmit regs */
5541 status = slic_dump_reg(card, PROC_TRANSMIT);
5542 if (status != STATUS_SUCCESS) {
5543 DBG_ERROR("Cant dump transmit registers - dump failed\n");
5547 DBG_MSG("slicDump Write XMIT REGS len[%x] offset[%x]\n",
5548 (SLIC_NUM_REG * 4), file_offset);
5551 slic_dump_write(card, card->dumpbuffer, SLIC_NUM_REG * 4,
5555 ("Cant write xmt registers to dump file - dump failed\n");
5559 corehdr.XmtRegOff = file_offset;
5560 corehdr.XmtRegsize = SLIC_NUM_REG * 4;
5561 file_offset += SLIC_NUM_REG * 4;
5563 regs = SLIC_GBMAX_REG;
5565 corehdr.FileRegOff = file_offset;
5566 corehdr.FileRegsize = regs * 4;
5568 for (offset = 0; regs;) {
5569 len = MIN(regs, 16); /* Can only xfr 16 regs at a time */
5571 status = slic_dump_data(card, offset, (ushort) len, DESC_RFILE);
5573 if (status != STATUS_SUCCESS) {
5574 DBG_ERROR("Cant dump register file - dump failed\n");
5578 DBG_MSG("slicDump Write RegisterFile len[%x] offset[%x]\n",
5579 (len * 4), file_offset);
5582 slic_dump_write(card, card->dumpbuffer, len * 4,
5586 ("Cant write register file to dump file - "
5591 file_offset += len * 4;
5596 dram_size = card->config.DramSize * 0x10000;
5598 switch (adapter->devid) {
5599 case SLIC_2GB_DEVICE_ID:
5600 sram_size = SLIC_SRAM_SIZE2GB;
5602 case SLIC_1GB_DEVICE_ID:
5603 sram_size = SLIC_SRAM_SIZE1GB;
5611 corehdr.SramOff = file_offset;
5612 corehdr.Sramsize = sram_size;
5614 for (offset = 0; sram_size;) {
5615 len = MIN(sram_size, DUMP_BUF_SIZE);
5616 status = slic_dump_data(card, offset, (ushort) len, DESC_SRAM);
5617 if (status != STATUS_SUCCESS) {
5619 ("[slicmon] Cant dump SRAM at offset %x - "
5620 "dump failed\n", (uint) offset);
5624 DBG_MSG("[slicmon] slicDump Write SRAM len[%x] offset[%x]\n",
5628 slic_dump_write(card, card->dumpbuffer, len, file_offset);
5631 ("[slicmon] Cant write SRAM to dump file - "
5641 corehdr.DramOff = file_offset;
5642 corehdr.Dramsize = dram_size;
5644 for (offset = 0; dram_size;) {
5645 len = MIN(dram_size, DUMP_BUF_SIZE);
5647 status = slic_dump_data(card, offset, (ushort) len, DESC_DRAM);
5648 if (status != STATUS_SUCCESS) {
5650 ("[slicmon] Cant dump dram at offset %x - "
5651 "dump failed\n", (uint) offset);
5655 DBG_MSG("slicDump Write DRAM len[%x] offset[%x]\n", len,
5659 slic_dump_write(card, card->dumpbuffer, len, file_offset);
5662 ("[slicmon] Cant write DRAM to dump file - "
5672 max_queues = SLIC_MAX_QUEUE;
5674 for (queue = 0; queue < max_queues; queue++) {
5675 pulong32 qarray = (pulong32) card->dumpbuffer;
5676 ulong32 qarray_physl = card->dumpbuffer_physl;
5677 ulong32 qarray_physh = card->dumpbuffer_physh;
5682 DBG_MSG("[slicmon] Start Dump of QUEUE #0x%x\n", (uint) queue);
5684 for (offset = 0; offset < (DUMP_BUF_SIZE >> 2); offset++) {
5688 status = slic_dump_queue(card,
5690 qarray_physh, queue);
5693 if (status != STATUS_SUCCESS)
5696 if (jiffies > qstart) {
5697 qdelta = jiffies - qstart;
5703 qdelta = qtotal / offset;
5707 /* DBG_MSG(" slicDump Write QUEUE #0x%x len[%x] offset[%x] "
5708 "avgjiffs[%x]\n", queue, (offset*4), file_offset, qdelta); */
5711 slic_dump_write(card, card->dumpbuffer, offset * 4,
5716 ("[slicmon] Cant write QUEUES to dump file - "
5721 corehdr.queues[queue].queueOff = file_offset;
5722 corehdr.queues[queue].queuesize = offset * 4;
5723 file_offset += offset * 4;
5725 /* DBG_MSG(" Reload QUEUE #0x%x elements[%x]\n", (uint)queue, offset);*/
5727 * Fill the queue back up
5729 for (i = 0; i < offset; i++) {
5733 status = slic_dump_load_queue(card, qarray[i], queue);
5734 if (status != STATUS_SUCCESS)
5737 if (jiffies > qstart) {
5738 qdelta = jiffies - qstart;
5744 qdelta = qtotal / offset;
5748 /* DBG_MSG(" Reload DONE avgjiffs[%x]\n", qdelta); */
5753 len = SLIC_GB_CAMAB_SZE * 4;
5754 status = slic_dump_cam(card, 0, len, DUMP_CAM_A);
5755 if (status != STATUS_SUCCESS) {
5756 DBG_ERROR("[slicmon] Can't dump CAM_A - dump failed\n");
5760 result = slic_dump_write(card, card->dumpbuffer, len, file_offset);
5763 ("[slicmon] Can't write CAM_A data to dump file - "
5767 corehdr.CamAMOff = file_offset;
5768 corehdr.CamASize = len;
5771 len = SLIC_GB_CAMCD_SZE * 4;
5772 status = slic_dump_cam(card, 0, len, DUMP_CAM_C);
5774 DBG_ERROR("[slicmon] Can't dump CAM_C - dump failed\n");
5778 result = slic_dump_write(card, card->dumpbuffer, len, file_offset);
5781 ("[slicmon] Can't write CAM_C data to dump file - "
5785 corehdr.CamCMOff = file_offset;
5786 corehdr.CamCSize = len;
5791 * Write out the core header
5794 DBG_MSG("[slicmon] Write CoreHeader len[%x] offset[%x]\n",
5795 (uint) sizeof(sliccore_hdr_t), file_offset);
5798 slic_dump_write(card, &corehdr, sizeof(sliccore_hdr_t),
5800 DBG_MSG("[slicmon] corehdr xoff[%x] xsz[%x]\n"
5801 " roff[%x] rsz[%x] fileoff[%x] filesz[%x]\n"
5802 " sramoff[%x] sramsz[%x], dramoff[%x] dramsz[%x]\n"
5803 " corehdr_offset[%x]\n", corehdr.XmtRegOff,
5804 corehdr.XmtRegsize, corehdr.RcvRegOff, corehdr.RcvRegsize,
5805 corehdr.FileRegOff, corehdr.FileRegsize, corehdr.SramOff,
5806 corehdr.Sramsize, corehdr.DramOff, corehdr.Dramsize,
5807 (uint) sizeof(sliccore_hdr_t));
5808 for (i = 0; i < max_queues; i++) {
5809 DBG_MSG("[slicmon] QUEUE 0x%x offset[%x] size[%x]\n",
5810 (uint) i, corehdr.queues[i].queueOff,
5811 corehdr.queues[i].queuesize);
5815 slic_dump_close_file(card);
5818 DBG_MSG("slicDump RESTART RECEIVE and XMIT PROCESSORS\n\n");
5819 slic_dump_resume(card, PROC_RECEIVE);
5820 slic_dump_resume(card, PROC_TRANSMIT);
5826 ulong32 slic_dump_halt(p_sliccard_t card, uchar proc)
5828 puchar cmd = card->cmdbuffer;
5830 *cmd = COMMAND_BYTE(CMD_HALT, 0, proc);
5832 return slic_dump_send_cmd(card,
5833 card->cmdbuffer_physl,
5834 card->cmdbuffer_physh, 0, 0);
5837 ulong32 slic_dump_resume(p_sliccard_t card, uchar proc)
5839 puchar cmd = card->cmdbuffer;
5841 *cmd = COMMAND_BYTE(CMD_RUN, 0, proc);
5843 return slic_dump_send_cmd(card,
5844 card->cmdbuffer_physl,
5845 card->cmdbuffer_physh, 0, 0);
5848 ulong32 slic_dump_reg(p_sliccard_t card, uchar proc)
5850 pdump_cmd_t dump = (pdump_cmd_t) card->cmdbuffer;
5852 dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, proc);
5853 dump->desc = DESC_REG;
5857 return slic_dump_send_cmd(card,
5858 card->cmdbuffer_physl,
5859 card->cmdbuffer_physh,
5860 card->dumpbuffer_physl,
5861 card->dumpbuffer_physh);
5864 ulong32 slic_dump_data(p_sliccard_t card,
5865 ulong32 addr, ushort count, uchar desc)
5867 pdump_cmd_t dump = (pdump_cmd_t) card->cmdbuffer;
5869 dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, PROC_RECEIVE);
5871 dump->count = count;
5874 return slic_dump_send_cmd(card,
5875 card->cmdbuffer_physl,
5876 card->cmdbuffer_physh,
5877 card->dumpbuffer_physl,
5878 card->dumpbuffer_physh);
5881 ulong32 slic_dump_queue(p_sliccard_t card,
5882 ulong32 addr, ulong32 buf_physh, ulong32 queue)
5884 pdump_cmd_t dump = (pdump_cmd_t) card->cmdbuffer;
5886 dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, PROC_RECEIVE);
5887 dump->desc = DESC_QUEUE;
5891 return slic_dump_send_cmd(card,
5892 card->cmdbuffer_physl,
5893 card->cmdbuffer_physh,
5894 addr, card->dumpbuffer_physh);
5897 ulong32 slic_dump_load_queue(p_sliccard_t card, ulong32 data, ulong32 queue)
5899 pdump_cmd_t load = (pdump_cmd_t) card->cmdbuffer;
5901 load->cmd = COMMAND_BYTE(CMD_LOAD, 0, PROC_RECEIVE);
5902 load->desc = DESC_QUEUE;
5903 load->count = (ushort) queue;
5906 return slic_dump_send_cmd(card,
5907 card->cmdbuffer_physl,
5908 card->cmdbuffer_physh, 0, 0);
5911 ulong32 slic_dump_cam(p_sliccard_t card,
5912 ulong32 addr, ulong32 count, uchar desc)
5914 pdump_cmd_t dump = (pdump_cmd_t) card->cmdbuffer;
5916 dump->cmd = COMMAND_BYTE(CMD_CAM_OPS, 0, PROC_NONE);
5918 dump->count = count;
5921 return slic_dump_send_cmd(card,
5922 card->cmdbuffer_physl,
5923 card->cmdbuffer_physh,
5924 addr, card->dumpbuffer_physh);
5927 ulong32 slic_dump_send_cmd(p_sliccard_t card,
5930 ulong32 buf_physl, ulong32 buf_physh)
5932 ulong timeout = SLIC_MS_TO_JIFFIES(500); /* 500 msec */
5933 ulong32 attempts = 5;
5934 ulong32 delay = SLIC_MS_TO_JIFFIES(10); /* 10 msec */
5935 p_adapter_t adapter = card->master;
5940 * Zero the Dumpstatus field of the adapter structure
5942 card->dumpstatus = 0;
5944 * Issue the dump command via a utility processor request.
5946 * Kludge: We use the Informationbuffer parameter to hold
5947 * the buffer address
5949 slic_upr_request(adapter, SLIC_UPR_DUMP, cmd_physl, cmd_physh,
5950 buf_physl, buf_physh);
5954 * Spin until completion or timeout.
5956 while (!card->dumpstatus) {
5959 if (jiffies > timeout) {
5961 * Complete the timed-out DUMP UPR request.
5963 slic_upr_request_complete(adapter, 0);
5965 ("%s: TIMED OUT num_sleeps[%x] "
5967 __func__, num_sleeps, STATUS_FAILURE);
5969 return STATUS_FAILURE;
5972 SLIC_INTERRUPTIBLE_SLEEP_ON_TIMEOUT(card->dump_wq,
5976 if (card->dumpstatus & ISR_UPCERR) {
5978 * Error (or queue empty)
5980 /* DBG_ERROR("[slicmon] %s: DUMP_STATUS & ISR_UPCERR status[%x]\n",
5981 __func__, STATUS_FAILURE); */
5983 return STATUS_FAILURE;
5984 } else if (card->dumpstatus & ISR_UPCBSY) {
5988 DBG_ERROR("%s: ISR_UPCBUSY attempt[%x]\n", __func__,
5996 return STATUS_SUCCESS;
6001 DBG_ERROR("%s: GAVE UP AFTER SEVERAL ATTEMPTS status[%x]\n",
6002 __func__, STATUS_FAILURE);
6005 * Gave up after several attempts
6007 return STATUS_FAILURE;
6011 /*=============================================================================
6012 =============================================================================
6014 === *** END **** END **** END **** END *** ===
6015 === SLIC DUMP MANAGEMENT SECTION ===
6019 =============================================================================
6020 ============================================================================*/
6022 /******************************************************************************/
6023 /**************** MODULE INITIATION / TERMINATION FUNCTIONS ***************/
6024 /******************************************************************************/
6026 static struct pci_driver slic_driver = {
6028 .id_table = slic_pci_tbl,
6029 .probe = slic_entry_probe,
6030 .remove = slic_entry_remove,
6031 #if SLIC_POWER_MANAGEMENT_ENABLED
6032 .suspend = slicpm_suspend,
6033 .resume = slicpm_resume,
6035 /* .shutdown = slic_shutdown, MOOK_INVESTIGATE */
6038 static int __init slic_module_init(void)
6040 struct pci_device_id *pcidev;
6043 /* DBG_MSG("slicoss: %s ENTER cpu %d\n", __func__, smp_processor_id()); */
6047 if (debug >= 0 && slic_debug != debug)
6048 printk(SLICLEVEL "slicoss: debug level is %d.\n", debug);
6052 pcidev = (struct pci_device_id *)slic_driver.id_table;
6053 /* DBG_MSG("slicoss: %s call pci_module_init jiffies[%lx] cpu #%d\n",
6054 __func__, jiffies, smp_processor_id()); */
6056 ret = pci_register_driver(&slic_driver);
6058 /* DBG_MSG("slicoss: %s EXIT after call pci_module_init jiffies[%lx] "
6059 "cpu #%d status[%x]\n",__func__, jiffies,
6060 smp_processor_id(), ret); */
6065 static void __exit slic_module_cleanup(void)
6067 /* DBG_MSG("slicoss: %s ENTER\n", __func__); */
6068 pci_unregister_driver(&slic_driver);
6069 slic_debug_cleanup();
6070 /* DBG_MSG("slicoss: %s EXIT\n", __func__); */
6073 module_init(slic_module_init);
6074 module_exit(slic_module_cleanup);