From foo@baz Tue Sep 15 10:09:27 PDT 2009 Date: Tue, 15 Sep 2009 10:09:27 -0700 To: Greg KH From: Greg Kroah-Hartman Subject: Staging: remove sxg driver Unfortunatly, the upstream company has abandonded development of this driver. So it's best to just remove the driver from the tree. Cc: Christopher Harrer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 drivers/staging/Makefile | 1 drivers/staging/sxg/Kconfig | 11 drivers/staging/sxg/Makefile | 3 drivers/staging/sxg/README | 12 drivers/staging/sxg/sxg.c | 4543 ----------------------------------- drivers/staging/sxg/sxg.h | 787 ------ drivers/staging/sxg/sxg_ethtool.c | 328 -- drivers/staging/sxg/sxg_os.h | 149 - drivers/staging/sxg/sxgdbg.h | 184 - drivers/staging/sxg/sxghif.h | 1014 ------- drivers/staging/sxg/sxghw.h | 1020 ------- drivers/staging/sxg/sxgphycode-1.2.h | 130 - 13 files changed, 8184 deletions(-) --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -45,8 +45,6 @@ source "drivers/staging/et131x/Kconfig" source "drivers/staging/slicoss/Kconfig" -source "drivers/staging/sxg/Kconfig" - source "drivers/staging/go7007/Kconfig" source "drivers/staging/usbip/Kconfig" --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -5,7 +5,6 @@ obj-$(CONFIG_STAGING) += staging.o obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ -obj-$(CONFIG_SXG) += sxg/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ obj-$(CONFIG_USB_IP_COMMON) += usbip/ obj-$(CONFIG_W35UND) += winbond/ --- a/drivers/staging/sxg/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config SXG - tristate "Alacritech SLIC Technology Non-Accelerated 10Gbe support" - depends on PCI && NETDEV_10000 - depends on X86 - default n - help - This driver supports the Alacritech SLIC Technology Non-Accelerated - 10Gbe network cards. - - To compile this driver as a module, choose - M here: the module will be called sxg_nic. --- a/drivers/staging/sxg/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_SXG) += sxg_nic.o - -sxg_nic-y := sxg.o sxg_ethtool.o --- a/drivers/staging/sxg/README +++ /dev/null @@ -1,12 +0,0 @@ -This is the rough cut at a driver for the Alacritech SLIC Technology -Non-Accelerated 10Gbe network driver. - -TODO: - - remove wrappers - - checkpatch.pl cleanups - - new functionality that the card needs - - remove reliance on x86 - -Please send patches to: - Greg Kroah-Hartman -for any cleanups that you do to this driver. --- a/drivers/staging/sxg/sxg.c +++ /dev/null @@ -1,4543 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2000-2008 Alacritech, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Alacritech, Inc. - * - * Parts developed by LinSysSoft Sahara team - * - **************************************************************************/ - -/* - * FILENAME: sxg.c - * - * The SXG driver for Alacritech's 10Gbe products. - * - * NOTE: This is the standard, non-accelerated version of Alacritech's - * IS-NIC driver. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SLIC_GET_STATS_ENABLED 0 -#define LINUX_FREES_ADAPTER_RESOURCES 1 -#define SXG_OFFLOAD_IP_CHECKSUM 0 -#define SXG_POWER_MANAGEMENT_ENABLED 0 -#define VPCI 0 -#define ATK_DEBUG 1 -#define SXG_UCODE_DEBUG 0 - - -#include "sxg_os.h" -#include "sxghw.h" -#include "sxghif.h" -#include "sxg.h" -#include "sxgdbg.h" -#include "sxgphycode-1.2.h" - -static int sxg_allocate_buffer_memory(struct adapter_t *adapter, u32 Size, - enum sxg_buffer_type BufferType); -static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter, - void *RcvBlock, - dma_addr_t PhysicalAddress, - u32 Length); -static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter, - struct sxg_scatter_gather *SxgSgl, - dma_addr_t PhysicalAddress, - u32 Length); - -static void sxg_mcast_init_crc32(void); -static int sxg_entry_open(struct net_device *dev); -static int sxg_second_open(struct net_device * dev); -static int sxg_entry_halt(struct net_device *dev); -static int sxg_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev); -static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb); -static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, - struct sxg_scatter_gather *SxgSgl); - -static void sxg_handle_interrupt(struct adapter_t *adapter, int *work_done, - int budget); -static void sxg_interrupt(struct adapter_t *adapter); -static int sxg_poll(struct napi_struct *napi, int budget); -static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId); -static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId, - int *sxg_napi_continue, int *work_done, int budget); -static void sxg_complete_slow_send(struct adapter_t *adapter); -static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, - struct sxg_event *Event); -static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus); -static bool sxg_mac_filter(struct adapter_t *adapter, - struct ether_header *EtherHdr, ushort length); -static struct net_device_stats *sxg_get_stats(struct net_device * dev); -void sxg_free_resources(struct adapter_t *adapter); -void sxg_free_rcvblocks(struct adapter_t *adapter); -void sxg_free_sgl_buffers(struct adapter_t *adapter); -void sxg_unmap_resources(struct adapter_t *adapter); -void sxg_free_mcast_addrs(struct adapter_t *adapter); -void sxg_collect_statistics(struct adapter_t *adapter); -static int sxg_register_interrupt(struct adapter_t *adapter); -static void sxg_remove_isr(struct adapter_t *adapter); -static irqreturn_t sxg_isr(int irq, void *dev_id); - -static void sxg_watchdog(unsigned long data); -static void sxg_update_link_status (struct work_struct *work); - -#define XXXTODO 0 - -#if XXXTODO -static int sxg_mac_set_address(struct net_device *dev, void *ptr); -#endif -static void sxg_mcast_set_list(struct net_device *dev); - -static int sxg_adapter_set_hwaddr(struct adapter_t *adapter); - -static int sxg_initialize_adapter(struct adapter_t *adapter); -static void sxg_stock_rcv_buffers(struct adapter_t *adapter); -static void sxg_complete_descriptor_blocks(struct adapter_t *adapter, - unsigned char Index); -int sxg_change_mtu (struct net_device *netdev, int new_mtu); -static int sxg_initialize_link(struct adapter_t *adapter); -static int sxg_phy_init(struct adapter_t *adapter); -static void sxg_link_event(struct adapter_t *adapter); -static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter); -static void sxg_link_state(struct adapter_t *adapter, - enum SXG_LINK_STATE LinkState); -static int sxg_write_mdio_reg(struct adapter_t *adapter, - u32 DevAddr, u32 RegAddr, u32 Value); -static int sxg_read_mdio_reg(struct adapter_t *adapter, - u32 DevAddr, u32 RegAddr, u32 *pValue); -static void sxg_set_mcast_addr(struct adapter_t *adapter); - -static unsigned int sxg_first_init = 1; -static char *sxg_banner = - "Alacritech SLIC Technology(tm) Server and Storage \ - 10Gbe Accelerator (Non-Accelerated)\n"; - -static int sxg_debug = 1; -static int debug = -1; -static struct net_device *head_netdevice = NULL; - -static struct sxgbase_driver sxg_global = { - .dynamic_intagg = 1, -}; -static int intagg_delay = 100; -static u32 dynamic_intagg = 0; - -char sxg_driver_name[] = "sxg_nic"; -#define DRV_AUTHOR "Alacritech, Inc. Engineering" -#define DRV_DESCRIPTION \ - "Alacritech SLIC Techonology(tm) Non-Accelerated 10Gbe Driver" -#define DRV_COPYRIGHT \ - "Copyright 2000-2008 Alacritech, Inc. All rights reserved." - -MODULE_AUTHOR(DRV_AUTHOR); -MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_LICENSE("GPL"); - -module_param(dynamic_intagg, int, 0); -MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting"); -module_param(intagg_delay, int, 0); -MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay"); - -static struct pci_device_id sxg_pci_tbl[] __devinitdata = { - {PCI_DEVICE(SXG_VENDOR_ID, SXG_DEVICE_ID)}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, sxg_pci_tbl); - -static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush) -{ - writel(value, reg); - if (flush) - mb(); -} - -static inline void sxg_reg64_write(struct adapter_t *adapter, void __iomem *reg, - u64 value, u32 cpu) -{ - u32 value_high = (u32) (value >> 32); - u32 value_low = (u32) (value & 0x00000000FFFFFFFF); - unsigned long flags; - - spin_lock_irqsave(&adapter->Bit64RegLock, flags); - writel(value_high, (void __iomem *)(&adapter->UcodeRegs[cpu].Upper)); - writel(value_low, reg); - spin_unlock_irqrestore(&adapter->Bit64RegLock, flags); -} - -static void sxg_init_driver(void) -{ - if (sxg_first_init) { - DBG_ERROR("sxg: %s sxg_first_init set jiffies[%lx]\n", - __func__, jiffies); - sxg_first_init = 0; - spin_lock_init(&sxg_global.driver_lock); - } -} - -static void sxg_dbg_macaddrs(struct adapter_t *adapter) -{ - DBG_ERROR(" (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - adapter->netdev->name, adapter->currmacaddr[0], - adapter->currmacaddr[1], adapter->currmacaddr[2], - adapter->currmacaddr[3], adapter->currmacaddr[4], - adapter->currmacaddr[5]); - DBG_ERROR(" (%s) mac %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - adapter->netdev->name, adapter->macaddr[0], - adapter->macaddr[1], adapter->macaddr[2], - adapter->macaddr[3], adapter->macaddr[4], - adapter->macaddr[5]); - return; -} - -/* SXG Globals */ -static struct sxg_driver SxgDriver; - -#ifdef ATKDBG -static struct sxg_trace_buffer LSxgTraceBuffer; -#endif /* ATKDBG */ -static struct sxg_trace_buffer *SxgTraceBuffer = NULL; - -/* - * MSI Related API's - */ -int sxg_register_intr(struct adapter_t *adapter); -int sxg_enable_msi_x(struct adapter_t *adapter); -int sxg_add_msi_isr(struct adapter_t *adapter); -void sxg_remove_msix_isr(struct adapter_t *adapter); -int sxg_set_interrupt_capability(struct adapter_t *adapter); - -int sxg_set_interrupt_capability(struct adapter_t *adapter) -{ - int ret; - - ret = sxg_enable_msi_x(adapter); - if (ret != STATUS_SUCCESS) { - adapter->msi_enabled = FALSE; - DBG_ERROR("sxg_set_interrupt_capability MSI-X Disable\n"); - } else { - adapter->msi_enabled = TRUE; - DBG_ERROR("sxg_set_interrupt_capability MSI-X Enable\n"); - } - return ret; -} - -int sxg_register_intr(struct adapter_t *adapter) -{ - int ret = 0; - - if (adapter->msi_enabled) { - ret = sxg_add_msi_isr(adapter); - } - else { - DBG_ERROR("MSI-X Enable Failed. Using Pin INT\n"); - ret = sxg_register_interrupt(adapter); - if (ret != STATUS_SUCCESS) { - DBG_ERROR("sxg_register_interrupt Failed\n"); - } - } - return ret; -} - -int sxg_enable_msi_x(struct adapter_t *adapter) -{ - int ret; - - adapter->nr_msix_entries = 1; - adapter->msi_entries = kmalloc(adapter->nr_msix_entries * - sizeof(struct msix_entry),GFP_KERNEL); - if (!adapter->msi_entries) { - DBG_ERROR("%s:MSI Entries memory allocation Failed\n",__func__); - return -ENOMEM; - } - memset(adapter->msi_entries, 0, adapter->nr_msix_entries * - sizeof(struct msix_entry)); - - ret = pci_enable_msix(adapter->pcidev, adapter->msi_entries, - adapter->nr_msix_entries); - if (ret) { - DBG_ERROR("Enabling MSI-X with %d vectors failed\n", - adapter->nr_msix_entries); - /*Should try with less vector returned.*/ - kfree(adapter->msi_entries); - return STATUS_FAILURE; /*MSI-X Enable failed.*/ - } - return (STATUS_SUCCESS); -} - -int sxg_add_msi_isr(struct adapter_t *adapter) -{ - int ret,i; - - if (!adapter->intrregistered) { - spin_unlock_irqrestore(&sxg_global.driver_lock, - sxg_global.flags); - for (i=0; inr_msix_entries; i++) { - ret = request_irq (adapter->msi_entries[i].vector, - sxg_isr, - IRQF_SHARED, - adapter->netdev->name, - adapter->netdev); - if (ret) { - spin_lock_irqsave(&sxg_global.driver_lock, - sxg_global.flags); - DBG_ERROR("sxg: MSI-X request_irq (%s) " - "FAILED [%x]\n", adapter->netdev->name, - ret); - return (ret); - } - } - } - spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); - adapter->msi_enabled = TRUE; - adapter->intrregistered = 1; - adapter->IntRegistered = TRUE; - return (STATUS_SUCCESS); -} - -void sxg_remove_msix_isr(struct adapter_t *adapter) -{ - int i,vector; - struct net_device *netdev = adapter->netdev; - - for(i=0; i< adapter->nr_msix_entries;i++) - { - vector = adapter->msi_entries[i].vector; - DBG_ERROR("%s : Freeing IRQ vector#%d\n",__func__,vector); - free_irq(vector,netdev); - } -} - - -static void sxg_remove_isr(struct adapter_t *adapter) -{ - struct net_device *netdev = adapter->netdev; - if (adapter->msi_enabled) - sxg_remove_msix_isr(adapter); - else - free_irq(adapter->netdev->irq, netdev); -} - -void sxg_reset_interrupt_capability(struct adapter_t *adapter) -{ - if (adapter->msi_enabled) { - pci_disable_msix(adapter->pcidev); - kfree(adapter->msi_entries); - adapter->msi_entries = NULL; - } - return; -} - -/* - * sxg_download_microcode - * - * Download Microcode to Sahara adapter using the Linux - * Firmware module to get the ucode.sys file. - * - * Arguments - - * adapter - A pointer to our adapter structure - * UcodeSel - microcode file selection - * - * Return - * int - */ -static bool sxg_download_microcode(struct adapter_t *adapter, - enum SXG_UCODE_SEL UcodeSel) -{ - const struct firmware *fw; - const char *file = ""; - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - int ret; - int ucode_start; - u32 Section; - u32 ThisSectionSize; - u32 instruction = 0; - u32 BaseAddress, AddressOffset, Address; - /* u32 Failure; */ - u32 ValueRead; - u32 i; - u32 index = 0; - u32 num_sections = 0; - u32 sectionSize[16]; - u32 sectionStart[16]; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DnldUcod", - adapter, 0, 0, 0); - - /* - * This routine is only implemented to download the microcode - * for the Revision B Sahara chip. Rev A and Diagnostic - * microcode is not supported at this time. If Rev A or - * diagnostic ucode is required, this routine will obviously - * need to change. Also, eventually need to add support for - * Rev B checked version of ucode. That's easy enough once - * the free version of Rev B works. - */ - ASSERT(UcodeSel == SXG_UCODE_SYSTEM); - ASSERT(adapter->asictype == SAHARA_REV_B); -#if SXG_UCODE_DEBUG - file = "sxg/saharadbgdownloadB.sys"; -#else - file = "sxg/saharadownloadB.sys"; -#endif - ret = request_firmware(&fw, file, &adapter->pcidev->dev); - if (ret) { - DBG_ERROR("%s SXG_NIC: Failed to load firmware %s\n", __func__,file); - return ret; - } - - /* - * The microcode .sys file contains starts with a 4 byte word containing - * the number of sections. That is followed by "num_sections" 4 byte - * words containing each "section" size. That is followed num_sections - * 4 byte words containing each section "start" address. - * - * Following the above header, the .sys file contains num_sections, - * where each section size is specified, newline delineatetd 12 byte - * microcode instructions. - */ - num_sections = *(u32 *)(fw->data + index); - index += 4; - ASSERT(num_sections <= 3); - for (i = 0; i < num_sections; i++) { - sectionSize[i] = *(u32 *)(fw->data + index); - index += 4; - } - for (i = 0; i < num_sections; i++) { - sectionStart[i] = *(u32 *)(fw->data + index); - index += 4; - } - - /* First, reset the card */ - WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH); - udelay(50); - HwRegs = adapter->HwRegs; - - /* - * Download each section of the microcode as specified in - * sectionSize[index] to sectionStart[index] address. As - * described above, the .sys file contains 12 byte word - * microcode instructions. The *download.sys file is generated - * using the objtosys.exe utility that was built for Sahara - * microcode. - */ - /* See usage of this below when we read back for parity */ - ucode_start = index; - instruction = *(u32 *)(fw->data + index); - index += 4; - - for (Section = 0; Section < num_sections; Section++) { - BaseAddress = sectionStart[Section]; - /* Size in instructions */ - ThisSectionSize = sectionSize[Section] / 12; - for (AddressOffset = 0; AddressOffset < ThisSectionSize; - AddressOffset++) { - u32 first_instr = 0; /* See comment below */ - - Address = BaseAddress + AddressOffset; - ASSERT((Address & ~MICROCODE_ADDRESS_MASK) == 0); - /* Write instruction bits 31 - 0 (low) */ - first_instr = instruction; - WRITE_REG(HwRegs->UcodeDataLow, instruction, FLUSH); - instruction = *(u32 *)(fw->data + index); - index += 4; /* Advance to the "next" instruction */ - - /* Write instruction bits 63-32 (middle) */ - WRITE_REG(HwRegs->UcodeDataMiddle, instruction, FLUSH); - instruction = *(u32 *)(fw->data + index); - index += 4; /* Advance to the "next" instruction */ - - /* Write instruction bits 95-64 (high) */ - WRITE_REG(HwRegs->UcodeDataHigh, instruction, FLUSH); - instruction = *(u32 *)(fw->data + index); - index += 4; /* Advance to the "next" instruction */ - - /* Write instruction address with the WRITE bit set */ - WRITE_REG(HwRegs->UcodeAddr, - (Address | MICROCODE_ADDRESS_WRITE), FLUSH); - /* - * Sahara bug in the ucode download logic - the write to DataLow - * for the next instruction could get corrupted. To avoid this, - * write to DataLow again for this instruction (which may get - * corrupted, but it doesn't matter), then increment the address - * and write the data for the next instruction to DataLow. That - * write should succeed. - */ - WRITE_REG(HwRegs->UcodeDataLow, first_instr, FLUSH); - } - } - /* - * Now repeat the entire operation reading the instruction back and - * checking for parity errors - */ - index = ucode_start; - - for (Section = 0; Section < num_sections; Section++) { - BaseAddress = sectionStart[Section]; - /* Size in instructions */ - ThisSectionSize = sectionSize[Section] / 12; - for (AddressOffset = 0; AddressOffset < ThisSectionSize; - AddressOffset++) { - Address = BaseAddress + AddressOffset; - /* Write the address with the READ bit set */ - WRITE_REG(HwRegs->UcodeAddr, - (Address | MICROCODE_ADDRESS_READ), FLUSH); - /* Read it back and check parity bit. */ - READ_REG(HwRegs->UcodeAddr, ValueRead); - if (ValueRead & MICROCODE_ADDRESS_PARITY) { - DBG_ERROR("sxg: %s PARITY ERROR\n", - __func__); - - return FALSE; /* Parity error */ - } - ASSERT((ValueRead & MICROCODE_ADDRESS_MASK) == Address); - /* Read the instruction back and compare */ - /* First instruction */ - instruction = *(u32 *)(fw->data + index); - index += 4; - READ_REG(HwRegs->UcodeDataLow, ValueRead); - if (ValueRead != instruction) { - DBG_ERROR("sxg: %s MISCOMPARE LOW\n", - __func__); - return FALSE; /* Miscompare */ - } - instruction = *(u32 *)(fw->data + index); - index += 4; - READ_REG(HwRegs->UcodeDataMiddle, ValueRead); - if (ValueRead != instruction) { - DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n", - __func__); - return FALSE; /* Miscompare */ - } - instruction = *(u32 *)(fw->data + index); - index += 4; - READ_REG(HwRegs->UcodeDataHigh, ValueRead); - if (ValueRead != instruction) { - DBG_ERROR("sxg: %s MISCOMPARE HIGH\n", - __func__); - return FALSE; /* Miscompare */ - } - } - } - - /* download finished */ - release_firmware(fw); - /* Everything OK, Go. */ - WRITE_REG(HwRegs->UcodeAddr, MICROCODE_ADDRESS_GO, FLUSH); - - /* - * Poll the CardUp register to wait for microcode to initialize - * Give up after 10,000 attemps (500ms). - */ - for (i = 0; i < 10000; i++) { - udelay(50); - READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead); - if (ValueRead == 0xCAFE) { - break; - } - } - if (i == 10000) { - DBG_ERROR("sxg: %s TIMEOUT bringing up card - verify MICROCODE\n", __func__); - - return FALSE; /* Timeout */ - } - /* - * Now write the LoadSync register. This is used to - * synchronize with the card so it can scribble on the memory - * that contained 0xCAFE from the "CardUp" step above - */ - if (UcodeSel == SXG_UCODE_SYSTEM) { - WRITE_REG(adapter->UcodeRegs[0].LoadSync, 0, FLUSH); - } - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDnldUcd", - adapter, 0, 0, 0); - return (TRUE); -} - -/* - * sxg_allocate_resources - Allocate memory and locks - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - int - */ -static int sxg_allocate_resources(struct adapter_t *adapter) -{ - int status = STATUS_SUCCESS; - u32 RssIds, IsrCount; - /* struct sxg_xmt_ring *XmtRing; */ - /* struct sxg_rcv_ring *RcvRing; */ - - DBG_ERROR("%s ENTER\n", __func__); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocRes", - adapter, 0, 0, 0); - - /* Windows tells us how many CPUs it plans to use for */ - /* RSS */ - RssIds = SXG_RSS_CPU_COUNT(adapter); - IsrCount = adapter->msi_enabled ? RssIds : 1; - - DBG_ERROR("%s Setup the spinlocks\n", __func__); - - /* Allocate spinlocks and initialize listheads first. */ - spin_lock_init(&adapter->RcvQLock); - spin_lock_init(&adapter->SglQLock); - spin_lock_init(&adapter->XmtZeroLock); - spin_lock_init(&adapter->Bit64RegLock); - spin_lock_init(&adapter->AdapterLock); - atomic_set(&adapter->pending_allocations, 0); - - DBG_ERROR("%s Setup the lists\n", __func__); - - InitializeListHead(&adapter->FreeRcvBuffers); - InitializeListHead(&adapter->FreeRcvBlocks); - InitializeListHead(&adapter->AllRcvBlocks); - InitializeListHead(&adapter->FreeSglBuffers); - InitializeListHead(&adapter->AllSglBuffers); - - /* - * Mark these basic allocations done. This flags essentially - * tells the SxgFreeResources routine that it can grab spinlocks - * and reference listheads. - */ - adapter->BasicAllocations = TRUE; - /* - * Main allocation loop. Start with the maximum supported by - * the microcode and back off if memory allocation - * fails. If we hit a minimum, fail. - */ - - for (;;) { - DBG_ERROR("%s Allocate XmtRings size[%x]\n", __func__, - (unsigned int)(sizeof(struct sxg_xmt_ring) * 1)); - - /* - * Start with big items first - receive and transmit rings. - * At the moment I'm going to keep the ring size fixed and - * adjust the TCBs if we fail. Later we might - * consider reducing the ring size as well.. - */ - adapter->XmtRings = pci_alloc_consistent(adapter->pcidev, - sizeof(struct sxg_xmt_ring) * - 1, - &adapter->PXmtRings); - DBG_ERROR("%s XmtRings[%p]\n", __func__, adapter->XmtRings); - - if (!adapter->XmtRings) { - goto per_tcb_allocation_failed; - } - memset(adapter->XmtRings, 0, sizeof(struct sxg_xmt_ring) * 1); - - DBG_ERROR("%s Allocate RcvRings size[%x]\n", __func__, - (unsigned int)(sizeof(struct sxg_rcv_ring) * 1)); - adapter->RcvRings = - pci_alloc_consistent(adapter->pcidev, - sizeof(struct sxg_rcv_ring) * 1, - &adapter->PRcvRings); - DBG_ERROR("%s RcvRings[%p]\n", __func__, adapter->RcvRings); - if (!adapter->RcvRings) { - goto per_tcb_allocation_failed; - } - memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1); - adapter->ucode_stats = kzalloc(sizeof(struct sxg_ucode_stats), GFP_ATOMIC); - adapter->pucode_stats = pci_map_single(adapter->pcidev, - adapter->ucode_stats, - sizeof(struct sxg_ucode_stats), - PCI_DMA_FROMDEVICE); -// memset(adapter->ucode_stats, 0, sizeof(struct sxg_ucode_stats)); - break; - - per_tcb_allocation_failed: - /* an allocation failed. Free any successful allocations. */ - if (adapter->XmtRings) { - pci_free_consistent(adapter->pcidev, - sizeof(struct sxg_xmt_ring) * 1, - adapter->XmtRings, - adapter->PXmtRings); - adapter->XmtRings = NULL; - } - if (adapter->RcvRings) { - pci_free_consistent(adapter->pcidev, - sizeof(struct sxg_rcv_ring) * 1, - adapter->RcvRings, - adapter->PRcvRings); - adapter->RcvRings = NULL; - } - /* Loop around and try again.... */ - if (adapter->ucode_stats) { - pci_unmap_single(adapter->pcidev, - sizeof(struct sxg_ucode_stats), - adapter->pucode_stats, PCI_DMA_FROMDEVICE); - adapter->ucode_stats = NULL; - } - - } - - DBG_ERROR("%s Initialize RCV ZERO and XMT ZERO rings\n", __func__); - /* Initialize rcv zero and xmt zero rings */ - SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE); - SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE); - - /* Sanity check receive data structure format */ - /* ASSERT((adapter->ReceiveBufferSize == SXG_RCV_DATA_BUFFER_SIZE) || - (adapter->ReceiveBufferSize == SXG_RCV_JUMBO_BUFFER_SIZE)); */ - ASSERT(sizeof(struct sxg_rcv_descriptor_block) == - SXG_RCV_DESCRIPTOR_BLOCK_SIZE); - - DBG_ERROR("%s Allocate EventRings size[%x]\n", __func__, - (unsigned int)(sizeof(struct sxg_event_ring) * RssIds)); - - /* Allocate event queues. */ - adapter->EventRings = pci_alloc_consistent(adapter->pcidev, - sizeof(struct sxg_event_ring) * - RssIds, - &adapter->PEventRings); - - if (!adapter->EventRings) { - /* Caller will call SxgFreeAdapter to clean up above - * allocations */ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF8", - adapter, SXG_MAX_ENTRIES, 0, 0); - status = STATUS_RESOURCES; - goto per_tcb_allocation_failed; - } - memset(adapter->EventRings, 0, sizeof(struct sxg_event_ring) * RssIds); - - DBG_ERROR("%s Allocate ISR size[%x]\n", __func__, IsrCount); - /* Allocate ISR */ - adapter->Isr = pci_alloc_consistent(adapter->pcidev, - IsrCount, &adapter->PIsr); - if (!adapter->Isr) { - /* Caller will call SxgFreeAdapter to clean up above - * allocations */ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF9", - adapter, SXG_MAX_ENTRIES, 0, 0); - status = STATUS_RESOURCES; - goto per_tcb_allocation_failed; - } - memset(adapter->Isr, 0, sizeof(u32) * IsrCount); - - DBG_ERROR("%s Allocate shared XMT ring zero index location size[%x]\n", - __func__, (unsigned int)sizeof(u32)); - - /* Allocate shared XMT ring zero index location */ - adapter->XmtRingZeroIndex = pci_alloc_consistent(adapter->pcidev, - sizeof(u32), - &adapter-> - PXmtRingZeroIndex); - if (!adapter->XmtRingZeroIndex) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF10", - adapter, SXG_MAX_ENTRIES, 0, 0); - status = STATUS_RESOURCES; - goto per_tcb_allocation_failed; - } - memset(adapter->XmtRingZeroIndex, 0, sizeof(u32)); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlcResS", - adapter, SXG_MAX_ENTRIES, 0, 0); - - return status; -} - -/* - * sxg_config_pci - - * - * Set up PCI Configuration space - * - * Arguments - - * pcidev - A pointer to our adapter structure - */ -static void sxg_config_pci(struct pci_dev *pcidev) -{ - u16 pci_command; - u16 new_command; - - pci_read_config_word(pcidev, PCI_COMMAND, &pci_command); - DBG_ERROR("sxg: %s PCI command[%4.4x]\n", __func__, pci_command); - /* Set the command register */ - new_command = pci_command | ( - /* Memory Space Enable */ - PCI_COMMAND_MEMORY | - /* Bus master enable */ - PCI_COMMAND_MASTER | - /* Memory write and invalidate */ - PCI_COMMAND_INVALIDATE | - /* Parity error response */ - PCI_COMMAND_PARITY | - /* System ERR */ - PCI_COMMAND_SERR | - /* Fast back-to-back */ - PCI_COMMAND_FAST_BACK); - if (pci_command != new_command) { - DBG_ERROR("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n", - __func__, pci_command, new_command); - pci_write_config_word(pcidev, PCI_COMMAND, new_command); - } -} - -/* - * sxg_read_config - * @adapter : Pointer to the adapter structure for the card - * This function will read the configuration data from EEPROM/FLASH - */ -static inline int sxg_read_config(struct adapter_t *adapter) -{ - /* struct sxg_config data; */ - struct sxg_config *config; - struct sw_cfg_data *data; - dma_addr_t p_addr; - unsigned long status; - unsigned long i; - config = pci_alloc_consistent(adapter->pcidev, - sizeof(struct sxg_config), &p_addr); - - if(!config) { - /* - * We cant get even this much memory. Raise a hell - * Get out of here - */ - printk(KERN_ERR"%s : Could not allocate memory for reading \ - EEPROM\n", __func__); - return -ENOMEM; - } - - data = &config->SwCfg; - - /* Initialize (reflective memory) status register */ - WRITE_REG(adapter->UcodeRegs[0].ConfigStat, SXG_CFG_TIMEOUT, TRUE); - - /* Send request to fetch configuration data */ - WRITE_REG64(adapter, adapter->UcodeRegs[0].Config, p_addr, 0); - for(i=0; i<1000; i++) { - READ_REG(adapter->UcodeRegs[0].ConfigStat, status); - if (status != SXG_CFG_TIMEOUT) - break; - mdelay(1); /* Do we really need this */ - } - - switch(status) { - /* Config read from EEPROM succeeded */ - case SXG_CFG_LOAD_EEPROM: - /* Config read from Flash succeeded */ - case SXG_CFG_LOAD_FLASH: - /* - * Copy the MAC address to adapter structure - * TODO: We are not doing the remaining part : FRU, etc - */ - memcpy(adapter->macaddr, data->MacAddr[0].MacAddr, - sizeof(struct sxg_config_mac)); - break; - case SXG_CFG_TIMEOUT: - case SXG_CFG_LOAD_INVALID: - case SXG_CFG_LOAD_ERROR: - default: /* Fix default handler later */ - printk(KERN_WARNING"%s : We could not read the config \ - word. Status = %ld\n", __func__, status); - break; - } - pci_free_consistent(adapter->pcidev, sizeof(struct sw_cfg_data), data, - p_addr); - if (adapter->netdev) { - memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6); - memcpy(adapter->netdev->perm_addr, adapter->currmacaddr, 6); - } - sxg_dbg_macaddrs(adapter); - - return status; -} - -static const struct net_device_ops sxg_netdev_ops = { - .ndo_open = sxg_entry_open, - .ndo_stop = sxg_entry_halt, - .ndo_start_xmit = sxg_send_packets, - .ndo_do_ioctl = sxg_ioctl, - .ndo_change_mtu = sxg_change_mtu, - .ndo_get_stats = sxg_get_stats, - .ndo_set_multicast_list = sxg_mcast_set_list, - .ndo_validate_addr = eth_validate_addr, -#if XXXTODO - .ndo_set_mac_address = sxg_mac_set_address, -#else - .ndo_set_mac_address = eth_mac_addr, -#endif -}; - -static int sxg_entry_probe(struct pci_dev *pcidev, - const struct pci_device_id *pci_tbl_entry) -{ - static int did_version = 0; - int err; - struct net_device *netdev; - struct adapter_t *adapter; - void __iomem *memmapped_ioaddr; - u32 status = 0; - ulong mmio_start = 0; - ulong mmio_len = 0; - unsigned char revision_id; - - DBG_ERROR("sxg: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n", - __func__, jiffies, smp_processor_id()); - - /* Initialize trace buffer */ -#ifdef ATKDBG - SxgTraceBuffer = &LSxgTraceBuffer; - SXG_TRACE_INIT(SxgTraceBuffer, TRACE_NOISY); -#endif - - sxg_global.dynamic_intagg = dynamic_intagg; - - err = pci_enable_device(pcidev); - - DBG_ERROR("Call pci_enable_device(%p) status[%x]\n", pcidev, err); - if (err) { - return err; - } - - if (sxg_debug > 0 && did_version++ == 0) { - printk(KERN_INFO "%s\n", sxg_banner); - printk(KERN_INFO "%s\n", SXG_DRV_VERSION); - } - - pci_read_config_byte(pcidev, PCI_REVISION_ID, &revision_id); - - if (!(err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64)))) { - DBG_ERROR("pci_set_dma_mask(DMA_BIT_MASK(64)) successful\n"); - } else { - if ((err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)))) { - DBG_ERROR - ("No usable DMA configuration, aborting err[%x]\n", - err); - return err; - } - DBG_ERROR("pci_set_dma_mask(DMA_BIT_MASK(32)) successful\n"); - } - - DBG_ERROR("Call pci_request_regions\n"); - - err = pci_request_regions(pcidev, sxg_driver_name); - if (err) { - DBG_ERROR("pci_request_regions FAILED err[%x]\n", err); - return err; - } - - DBG_ERROR("call pci_set_master\n"); - pci_set_master(pcidev); - - DBG_ERROR("call alloc_etherdev\n"); - netdev = alloc_etherdev(sizeof(struct adapter_t)); - if (!netdev) { - err = -ENOMEM; - goto err_out_exit_sxg_probe; - } - DBG_ERROR("alloc_etherdev for slic netdev[%p]\n", netdev); - - SET_NETDEV_DEV(netdev, &pcidev->dev); - - pci_set_drvdata(pcidev, netdev); - adapter = netdev_priv(netdev); - if (revision_id == 1) { - adapter->asictype = SAHARA_REV_A; - } else if (revision_id == 2) { - adapter->asictype = SAHARA_REV_B; - } else { - ASSERT(0); - DBG_ERROR("%s Unexpected revision ID %x\n", __func__, revision_id); - goto err_out_exit_sxg_probe; - } - adapter->netdev = netdev; - adapter->pcidev = pcidev; - - mmio_start = pci_resource_start(pcidev, 0); - mmio_len = pci_resource_len(pcidev, 0); - - DBG_ERROR("sxg: call ioremap(mmio_start[%lx], mmio_len[%lx])\n", - mmio_start, mmio_len); - - memmapped_ioaddr = ioremap(mmio_start, mmio_len); - DBG_ERROR("sxg: %s MEMMAPPED_IOADDR [%p]\n", __func__, - memmapped_ioaddr); - if (!memmapped_ioaddr) { - DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n", - __func__, mmio_len, mmio_start); - goto err_out_free_mmio_region_0; - } - - DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, start[%lx] \ - len[%lx], IRQ %d.\n", __func__, memmapped_ioaddr, mmio_start, - mmio_len, pcidev->irq); - - adapter->HwRegs = (void *)memmapped_ioaddr; - adapter->base_addr = memmapped_ioaddr; - - mmio_start = pci_resource_start(pcidev, 2); - mmio_len = pci_resource_len(pcidev, 2); - - DBG_ERROR("sxg: call ioremap(mmio_start[%lx], mmio_len[%lx])\n", - mmio_start, mmio_len); - - memmapped_ioaddr = ioremap(mmio_start, mmio_len); - DBG_ERROR("sxg: %s MEMMAPPED_IOADDR [%p]\n", __func__, - memmapped_ioaddr); - if (!memmapped_ioaddr) { - DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n", - __func__, mmio_len, mmio_start); - goto err_out_free_mmio_region_2; - } - - DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, " - "start[%lx] len[%lx], IRQ %d.\n", __func__, - memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq); - - adapter->UcodeRegs = (void *)memmapped_ioaddr; - - adapter->State = SXG_STATE_INITIALIZING; - /* - * Maintain a list of all adapters anchored by - * the global SxgDriver structure. - */ - adapter->Next = SxgDriver.Adapters; - SxgDriver.Adapters = adapter; - adapter->AdapterID = ++SxgDriver.AdapterID; - - /* Initialize CRC table used to determine multicast hash */ - sxg_mcast_init_crc32(); - - adapter->JumboEnabled = FALSE; - adapter->RssEnabled = FALSE; - if (adapter->JumboEnabled) { - adapter->FrameSize = JUMBOMAXFRAME; - adapter->ReceiveBufferSize = SXG_RCV_JUMBO_BUFFER_SIZE; - } else { - adapter->FrameSize = ETHERMAXFRAME; - adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE; - } - - /* - * status = SXG_READ_EEPROM(adapter); - * if (!status) { - * goto sxg_init_bad; - * } - */ - - DBG_ERROR("sxg: %s ENTER sxg_config_pci\n", __func__); - sxg_config_pci(pcidev); - DBG_ERROR("sxg: %s EXIT sxg_config_pci\n", __func__); - - DBG_ERROR("sxg: %s ENTER sxg_init_driver\n", __func__); - sxg_init_driver(); - DBG_ERROR("sxg: %s EXIT sxg_init_driver\n", __func__); - - adapter->vendid = pci_tbl_entry->vendor; - adapter->devid = pci_tbl_entry->device; - adapter->subsysid = pci_tbl_entry->subdevice; - adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F); - adapter->functionnumber = (pcidev->devfn & 0x7); - adapter->memorylength = pci_resource_len(pcidev, 0); - adapter->irq = pcidev->irq; - adapter->next_netdevice = head_netdevice; - head_netdevice = netdev; - adapter->port = 0; /*adapter->functionnumber; */ - - /* Allocate memory and other resources */ - DBG_ERROR("sxg: %s ENTER sxg_allocate_resources\n", __func__); - status = sxg_allocate_resources(adapter); - DBG_ERROR("sxg: %s EXIT sxg_allocate_resources status %x\n", - __func__, status); - if (status != STATUS_SUCCESS) { - goto err_out_unmap; - } - - DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__); - if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) { - DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n", - __func__); - sxg_read_config(adapter); - status = sxg_adapter_set_hwaddr(adapter); - } else { - adapter->state = ADAPT_FAIL; - adapter->linkstate = LINK_DOWN; - DBG_ERROR("sxg_download_microcode FAILED status[%x]\n", status); - } - - netdev->base_addr = (unsigned long)adapter->base_addr; - netdev->irq = adapter->irq; - netdev->netdev_ops = &sxg_netdev_ops; - SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops); - netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - err = sxg_set_interrupt_capability(adapter); - if (err != STATUS_SUCCESS) - DBG_ERROR("Cannot enable MSI-X capability\n"); - - strcpy(netdev->name, "eth%d"); - /* strcpy(netdev->name, pci_name(pcidev)); */ - if ((err = register_netdev(netdev))) { - DBG_ERROR("Cannot register net device, aborting. %s\n", - netdev->name); - goto err_out_unmap; - } - - netif_napi_add(netdev, &adapter->napi, - sxg_poll, SXG_NETDEV_WEIGHT); - netdev->watchdog_timeo = 2 * HZ; - init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &sxg_watchdog; - adapter->watchdog_timer.data = (unsigned long) adapter; - INIT_WORK(&adapter->update_link_status, sxg_update_link_status); - - DBG_ERROR - ("sxg: %s addr 0x%lx, irq %d, MAC addr \ - %02X:%02X:%02X:%02X:%02X:%02X\n", - netdev->name, netdev->base_addr, pcidev->irq, netdev->dev_addr[0], - netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3], - netdev->dev_addr[4], netdev->dev_addr[5]); - - /* sxg_init_bad: */ - ASSERT(status == FALSE); - /* sxg_free_adapter(adapter); */ - - DBG_ERROR("sxg: %s EXIT status[%x] jiffies[%lx] cpu %d\n", __func__, - status, jiffies, smp_processor_id()); - return status; - - err_out_unmap: - sxg_free_resources(adapter); - - err_out_free_mmio_region_2: - - mmio_start = pci_resource_start(pcidev, 2); - mmio_len = pci_resource_len(pcidev, 2); - release_mem_region(mmio_start, mmio_len); - - err_out_free_mmio_region_0: - - mmio_start = pci_resource_start(pcidev, 0); - mmio_len = pci_resource_len(pcidev, 0); - - release_mem_region(mmio_start, mmio_len); - - err_out_exit_sxg_probe: - - DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies, - smp_processor_id()); - - pci_disable_device(pcidev); - DBG_ERROR("sxg: %s deallocate device\n", __func__); - kfree(netdev); - printk("Exit %s, Sxg driver loading failed..\n", __func__); - - return -ENODEV; -} - -/* - * LINE BASE Interrupt routines.. - * - * sxg_disable_interrupt - * - * DisableInterrupt Handler - * - * Arguments: - * - * adapter: Our adapter structure - * - * Return Value: - * None. - */ -static void sxg_disable_interrupt(struct adapter_t *adapter) -{ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DisIntr", - adapter, adapter->InterruptsEnabled, 0, 0); - /* For now, RSS is disabled with line based interrupts */ - ASSERT(adapter->RssEnabled == FALSE); - /* Turn off interrupts by writing to the icr register. */ - WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_DISABLE), TRUE); - - adapter->InterruptsEnabled = 0; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDisIntr", - adapter, adapter->InterruptsEnabled, 0, 0); -} - -/* - * sxg_enable_interrupt - * - * EnableInterrupt Handler - * - * Arguments: - * - * adapter: Our adapter structure - * - * Return Value: - * None. - */ -static void sxg_enable_interrupt(struct adapter_t *adapter) -{ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "EnIntr", - adapter, adapter->InterruptsEnabled, 0, 0); - /* For now, RSS is disabled with line based interrupts */ - ASSERT(adapter->RssEnabled == FALSE); - /* Turn on interrupts by writing to the icr register. */ - WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_ENABLE), TRUE); - - adapter->InterruptsEnabled = 1; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XEnIntr", - adapter, 0, 0, 0); -} - -/* - * sxg_isr - Process an line-based interrupt - * - * Arguments: - * Context - Our adapter structure - * QueueDefault - Output parameter to queue to default CPU - * TargetCpus - Output bitmap to schedule DPC's - * - * Return Value: TRUE if our interrupt - */ -static irqreturn_t sxg_isr(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *) dev_id; - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - - if(adapter->state != ADAPT_UP) - return IRQ_NONE; - adapter->Stats.NumInts++; - if (adapter->Isr[0] == 0) { - /* - * The SLIC driver used to experience a number of spurious - * interrupts due to the delay associated with the masking of - * the interrupt (we'd bounce back in here). If we see that - * again with Sahara,add a READ_REG of the Icr register after - * the WRITE_REG below. - */ - adapter->Stats.FalseInts++; - return IRQ_NONE; - } - /* - * Move the Isr contents and clear the value in - * shared memory, and mask interrupts - */ - /* ASSERT(adapter->IsrDpcsPending == 0); */ -#if XXXTODO /* RSS Stuff */ - /* - * If RSS is enabled and the ISR specifies SXG_ISR_EVENT, then - * schedule DPC's based on event queues. - */ - if (adapter->RssEnabled && (adapter->IsrCopy[0] & SXG_ISR_EVENT)) { - for (i = 0; - i < adapter->RssSystemInfo->ProcessorInfo.RssCpuCount; - i++) { - struct sxg_event_ring *EventRing = - &adapter->EventRings[i]; - struct sxg_event *Event = - &EventRing->Ring[adapter->NextEvent[i]]; - unsigned char Cpu = - adapter->RssSystemInfo->RssIdToCpu[i]; - if (Event->Status & EVENT_STATUS_VALID) { - adapter->IsrDpcsPending++; - CpuMask |= (1 << Cpu); - } - } - } - /* - * Now, either schedule the CPUs specified by the CpuMask, - * or queue default - */ - if (CpuMask) { - *QueueDefault = FALSE; - } else { - adapter->IsrDpcsPending = 1; - *QueueDefault = TRUE; - } - *TargetCpus = CpuMask; -#endif - sxg_interrupt(adapter); - - return IRQ_HANDLED; -} - -static void sxg_interrupt(struct adapter_t *adapter) -{ - WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE); - - if (napi_schedule_prep(&adapter->napi)) { - __napi_schedule(&adapter->napi); - } -} - -static void sxg_handle_interrupt(struct adapter_t *adapter, int *work_done, - int budget) -{ - /* unsigned char RssId = 0; */ - u32 NewIsr; - int sxg_napi_continue = 1; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "HndlIntr", - adapter, adapter->IsrCopy[0], 0, 0); - /* For now, RSS is disabled with line based interrupts */ - ASSERT(adapter->RssEnabled == FALSE); - - adapter->IsrCopy[0] = adapter->Isr[0]; - adapter->Isr[0] = 0; - - /* Always process the event queue. */ - while (sxg_napi_continue) - { - sxg_process_event_queue(adapter, - (adapter->RssEnabled ? /*RssId */ 0 : 0), - &sxg_napi_continue, work_done, budget); - } - -#if XXXTODO /* RSS stuff */ - if (--adapter->IsrDpcsPending) { - /* We're done. */ - ASSERT(adapter->RssEnabled); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DPCsPend", - adapter, 0, 0, 0); - return; - } -#endif - /* Last (or only) DPC processes the ISR and clears the interrupt. */ - NewIsr = sxg_process_isr(adapter, 0); - /* Reenable interrupts */ - adapter->IsrCopy[0] = 0; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ClearIsr", - adapter, NewIsr, 0, 0); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XHndlInt", - adapter, 0, 0, 0); -} -static int sxg_poll(struct napi_struct *napi, int budget) -{ - struct adapter_t *adapter = container_of(napi, struct adapter_t, napi); - int work_done = 0; - - sxg_handle_interrupt(adapter, &work_done, budget); - - if (work_done < budget) { - napi_complete(napi); - WRITE_REG(adapter->UcodeRegs[0].Isr, 0, TRUE); - } - return work_done; -} - -/* - * sxg_process_isr - Process an interrupt. Called from the line-based and - * message based interrupt DPC routines - * - * Arguments: - * adapter - Our adapter structure - * Queue - The ISR that needs processing - * - * Return Value: - * None - */ -static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId) -{ - u32 Isr = adapter->IsrCopy[MessageId]; - u32 NewIsr = 0; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ProcIsr", - adapter, Isr, 0, 0); - - /* Error */ - if (Isr & SXG_ISR_ERR) { - if (Isr & SXG_ISR_PDQF) { - adapter->Stats.PdqFull++; - DBG_ERROR("%s: SXG_ISR_ERR PDQF!!\n", __func__); - } - /* No host buffer */ - if (Isr & SXG_ISR_RMISS) { - /* - * There is a bunch of code in the SLIC driver which - * attempts to process more receive events per DPC - * if we start to fall behind. We'll probablyd - * need to do something similar here, but hold - * off for now. I don't want to make the code more - * complicated than strictly needed. - */ - adapter->stats.rx_missed_errors++; - if (adapter->stats.rx_missed_errors< 5) { - DBG_ERROR("%s: SXG_ISR_ERR RMISS!!\n", - __func__); - } - } - /* Card crash */ - if (Isr & SXG_ISR_DEAD) { - /* - * Set aside the crash info and set the adapter state - * to RESET - */ - adapter->CrashCpu = (unsigned char) - ((Isr & SXG_ISR_CPU) >> SXG_ISR_CPU_SHIFT); - adapter->CrashLocation = (ushort) (Isr & SXG_ISR_CRASH); - adapter->Dead = TRUE; - DBG_ERROR("%s: ISR_DEAD %x, CPU: %d\n", __func__, - adapter->CrashLocation, adapter->CrashCpu); - } - /* Event ring full */ - if (Isr & SXG_ISR_ERFULL) { - /* - * Same issue as RMISS, really. This means the - * host is falling behind the card. Need to increase - * event ring size, process more events per interrupt, - * and/or reduce/remove interrupt aggregation. - */ - adapter->Stats.EventRingFull++; - DBG_ERROR("%s: SXG_ISR_ERR EVENT RING FULL!!\n", - __func__); - } - /* Transmit drop - no DRAM buffers or XMT error */ - if (Isr & SXG_ISR_XDROP) { - DBG_ERROR("%s: SXG_ISR_ERR XDROP!!\n", __func__); - } - } - /* Slowpath send completions */ - if (Isr & SXG_ISR_SPSEND) { - sxg_complete_slow_send(adapter); - } - /* Dump */ - if (Isr & SXG_ISR_UPC) { - /* Maybe change when debug is added.. */ -// ASSERT(adapter->DumpCmdRunning); - adapter->DumpCmdRunning = FALSE; - } - /* Link event */ - if (Isr & SXG_ISR_LINK) { - if (adapter->state != ADAPT_DOWN) { - adapter->link_status_changed = 1; - schedule_work(&adapter->update_link_status); - } - } - /* Debug - breakpoint hit */ - if (Isr & SXG_ISR_BREAK) { - /* - * At the moment AGDB isn't written to support interactive - * debug sessions. When it is, this interrupt will be used to - * signal AGDB that it has hit a breakpoint. For now, ASSERT. - */ - ASSERT(0); - } - /* Heartbeat response */ - if (Isr & SXG_ISR_PING) { - adapter->PingOutstanding = FALSE; - } - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XProcIsr", - adapter, Isr, NewIsr, 0); - - return (NewIsr); -} - -/* - * sxg_rcv_checksum - Set the checksum for received packet - * - * Arguements: - * @adapter - Adapter structure on which packet is received - * @skb - Packet which is receieved - * @Event - Event read from hardware - */ - -void sxg_rcv_checksum(struct adapter_t *adapter, struct sk_buff *skb, - struct sxg_event *Event) -{ - skb->ip_summed = CHECKSUM_NONE; - if (likely(adapter->flags & SXG_RCV_IP_CSUM_ENABLED)) { - if (likely(adapter->flags & SXG_RCV_TCP_CSUM_ENABLED) - && (Event->Status & EVENT_STATUS_TCPIP)) { - if(!(Event->Status & EVENT_STATUS_TCPBAD)) - skb->ip_summed = CHECKSUM_UNNECESSARY; - if(!(Event->Status & EVENT_STATUS_IPBAD)) - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else if(Event->Status & EVENT_STATUS_IPONLY) { - if(!(Event->Status & EVENT_STATUS_IPBAD)) - skb->ip_summed = CHECKSUM_UNNECESSARY; - } - } -} - -/* - * sxg_process_event_queue - Process our event queue - * - * Arguments: - * - adapter - Adapter structure - * - RssId - The event queue requiring processing - * - * Return Value: - * None. - */ -static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId, - int *sxg_napi_continue, int *work_done, int budget) -{ - struct sxg_event_ring *EventRing = &adapter->EventRings[RssId]; - struct sxg_event *Event = &EventRing->Ring[adapter->NextEvent[RssId]]; - u32 EventsProcessed = 0, Batches = 0; - struct sk_buff *skb; -#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS - struct sk_buff *prev_skb = NULL; - struct sk_buff *IndicationList[SXG_RCV_ARRAYSIZE]; - u32 Index; - struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr; -#endif - u32 ReturnStatus = 0; - int sxg_rcv_data_buffers = SXG_RCV_DATA_BUFFERS; - - ASSERT((adapter->State == SXG_STATE_RUNNING) || - (adapter->State == SXG_STATE_PAUSING) || - (adapter->State == SXG_STATE_PAUSED) || - (adapter->State == SXG_STATE_HALTING)); - /* - * We may still have unprocessed events on the queue if - * the card crashed. Don't process them. - */ - if (adapter->Dead) { - return (0); - } - /* - * In theory there should only be a single processor that - * accesses this queue, and only at interrupt-DPC time. So/ - * we shouldn't need a lock for any of this. - */ - while (Event->Status & EVENT_STATUS_VALID) { - (*sxg_napi_continue) = 1; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "Event", - Event, Event->Code, Event->Status, - adapter->NextEvent); - switch (Event->Code) { - case EVENT_CODE_BUFFERS: - /* struct sxg_ring_info Head & Tail == unsigned char */ - ASSERT(!(Event->CommandIndex & 0xFF00)); - sxg_complete_descriptor_blocks(adapter, - Event->CommandIndex); - break; - case EVENT_CODE_SLOWRCV: - (*work_done)++; - --adapter->RcvBuffersOnCard; - if ((skb = sxg_slow_receive(adapter, Event))) { - u32 rx_bytes; -#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS - /* Add it to our indication list */ - SXG_ADD_RCV_PACKET(adapter, skb, prev_skb, - IndicationList, num_skbs); - /* - * Linux, we just pass up each skb to the - * protocol above at this point, there is no - * capability of an indication list. - */ -#else - /* CHECK skb_pull(skb, INIC_RCVBUF_HEADSIZE); */ - /* (rcvbuf->length & IRHDDR_FLEN_MSK); */ - rx_bytes = Event->Length; - adapter->stats.rx_packets++; - adapter->stats.rx_bytes += rx_bytes; - sxg_rcv_checksum(adapter, skb, Event); - skb->dev = adapter->netdev; - netif_receive_skb(skb); -#endif - } - break; - default: - DBG_ERROR("%s: ERROR Invalid EventCode %d\n", - __func__, Event->Code); - /* ASSERT(0); */ - } - /* - * See if we need to restock card receive buffers. - * There are two things to note here: - * First - This test is not SMP safe. The - * adapter->BuffersOnCard field is protected via atomic - * interlocked calls, but we do not protect it with respect - * to these tests. The only way to do that is with a lock, - * and I don't want to grab a lock every time we adjust the - * BuffersOnCard count. Instead, we allow the buffer - * replenishment to be off once in a while. The worst that - * can happen is the card is given on more-or-less descriptor - * block than the arbitrary value we've chosen. No big deal - * In short DO NOT ADD A LOCK HERE, OR WHERE RcvBuffersOnCard - * is adjusted. - * Second - We expect this test to rarely - * evaluate to true. We attempt to refill descriptor blocks - * as they are returned to us (sxg_complete_descriptor_blocks) - * so The only time this should evaluate to true is when - * sxg_complete_descriptor_blocks failed to allocate - * receive buffers. - */ - if (adapter->JumboEnabled) - sxg_rcv_data_buffers = SXG_JUMBO_RCV_DATA_BUFFERS; - - if (adapter->RcvBuffersOnCard < sxg_rcv_data_buffers) { - sxg_stock_rcv_buffers(adapter); - } - /* - * It's more efficient to just set this to zero. - * But clearing the top bit saves potential debug info... - */ - Event->Status &= ~EVENT_STATUS_VALID; - /* Advance to the next event */ - SXG_ADVANCE_INDEX(adapter->NextEvent[RssId], EVENT_RING_SIZE); - Event = &EventRing->Ring[adapter->NextEvent[RssId]]; - EventsProcessed++; - if (EventsProcessed == EVENT_RING_BATCH) { - /* Release a batch of events back to the card */ - WRITE_REG(adapter->UcodeRegs[RssId].EventRelease, - EVENT_RING_BATCH, FALSE); - EventsProcessed = 0; - /* - * If we've processed our batch limit, break out of the - * loop and return SXG_ISR_EVENT to arrange for us to - * be called again - */ - if (Batches++ == EVENT_BATCH_LIMIT) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, - TRACE_NOISY, "EvtLimit", Batches, - adapter->NextEvent, 0, 0); - ReturnStatus = SXG_ISR_EVENT; - break; - } - } - if (*work_done >= budget) { - WRITE_REG(adapter->UcodeRegs[RssId].EventRelease, - EventsProcessed, FALSE); - EventsProcessed = 0; - (*sxg_napi_continue) = 0; - break; - } - } - if (!(Event->Status & EVENT_STATUS_VALID)) - (*sxg_napi_continue) = 0; - -#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS - /* Indicate any received dumb-nic frames */ - SXG_INDICATE_PACKETS(adapter, IndicationList, num_skbs); -#endif - /* Release events back to the card. */ - if (EventsProcessed) { - WRITE_REG(adapter->UcodeRegs[RssId].EventRelease, - EventsProcessed, FALSE); - } - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XPrcEvnt", - Batches, EventsProcessed, adapter->NextEvent, num_skbs); - - return (ReturnStatus); -} - -/* - * sxg_complete_slow_send - Complete slowpath or dumb-nic sends - * - * Arguments - - * adapter - A pointer to our adapter structure - * Return - * None - */ -static void sxg_complete_slow_send(struct adapter_t *adapter) -{ - struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0]; - struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo; - u32 *ContextType; - struct sxg_cmd *XmtCmd; - unsigned long flags = 0; - unsigned long sgl_flags = 0; - unsigned int processed_count = 0; - - /* - * NOTE - This lock is dropped and regrabbed in this loop. - * This means two different processors can both be running/ - * through this loop. Be *very* careful. - */ - spin_lock_irqsave(&adapter->XmtZeroLock, flags); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnds", - adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0); - - while ((XmtRingInfo->Tail != *adapter->XmtRingZeroIndex) - && processed_count++ < SXG_COMPLETE_SLOW_SEND_LIMIT) { - /* - * Locate the current Cmd (ring descriptor entry), and - * associated SGL, and advance the tail - */ - SXG_RETURN_CMD(XmtRing, XmtRingInfo, XmtCmd, ContextType); - ASSERT(ContextType); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd", - XmtRingInfo->Head, XmtRingInfo->Tail, XmtCmd, 0); - /* Clear the SGL field. */ - XmtCmd->Sgl = 0; - - switch (*ContextType) { - case SXG_SGL_DUMB: - { - struct sk_buff *skb; - struct sxg_scatter_gather *SxgSgl = - (struct sxg_scatter_gather *)ContextType; - dma64_addr_t FirstSgeAddress; - u32 FirstSgeLength; - - /* Dumb-nic send. Command context is the dumb-nic SGL */ - skb = (struct sk_buff *)ContextType; - skb = SxgSgl->DumbPacket; - FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress; - FirstSgeLength = XmtCmd->Buffer.FirstSgeLength; - /* Complete the send */ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, - TRACE_IMPORTANT, "DmSndCmp", skb, 0, - 0, 0); - ASSERT(adapter->Stats.XmtQLen); - /* - * Now drop the lock and complete the send - * back to Microsoft. We need to drop the lock - * because Microsoft can come back with a - * chimney send, which results in a double trip - * in SxgTcpOuput - */ - spin_unlock_irqrestore( - &adapter->XmtZeroLock, flags); - - SxgSgl->DumbPacket = NULL; - SXG_COMPLETE_DUMB_SEND(adapter, skb, - FirstSgeAddress, - FirstSgeLength); - SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL); - /* and reacquire.. */ - spin_lock_irqsave(&adapter->XmtZeroLock, flags); - } - break; - default: - ASSERT(0); - } - } - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd", - adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0); -} - -/* - * sxg_slow_receive - * - * Arguments - - * adapter - A pointer to our adapter structure - * Event - Receive event - * - * Return - skb - */ -static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, - struct sxg_event *Event) -{ - u32 BufferSize = adapter->ReceiveBufferSize; - struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr; - struct sk_buff *Packet; - static int read_counter = 0; - - RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) Event->HostHandle; - if(read_counter++ & 0x100) - { - sxg_collect_statistics(adapter); - read_counter = 0; - } - ASSERT(RcvDataBufferHdr); - ASSERT(RcvDataBufferHdr->State == SXG_BUFFER_ONCARD); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event, - RcvDataBufferHdr, RcvDataBufferHdr->State, - /*RcvDataBufferHdr->VirtualAddress*/ 0); - /* Drop rcv frames in non-running state */ - switch (adapter->State) { - case SXG_STATE_RUNNING: - break; - case SXG_STATE_PAUSING: - case SXG_STATE_PAUSED: - case SXG_STATE_HALTING: - goto drop; - default: - ASSERT(0); - goto drop; - } - - /* - * memcpy(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr), - * RcvDataBufferHdr->VirtualAddress, Event->Length); - */ - - /* Change buffer state to UPSTREAM */ - RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM; - if (Event->Status & EVENT_STATUS_RCVERR) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvError", - Event, Event->Status, Event->HostHandle, 0); - sxg_process_rcv_error(adapter, *(u32 *) - SXG_RECEIVE_DATA_LOCATION - (RcvDataBufferHdr)); - goto drop; - } -#if XXXTODO /* VLAN stuff */ - /* If there's a VLAN tag, extract it and validate it */ - if (((struct ether_header *) - (SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->EtherType - == ETHERTYPE_VLAN) { - if (SxgExtractVlanHeader(adapter, RcvDataBufferHdr, Event) != - STATUS_SUCCESS) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, - "BadVlan", Event, - SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr), - Event->Length, 0); - goto drop; - } - } -#endif - /* Dumb-nic frame. See if it passes our mac filter and update stats */ - - if (!sxg_mac_filter(adapter, - (struct ether_header *)(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)), - Event->Length)) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvFiltr", - Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr), - Event->Length, 0); - goto drop; - } - - Packet = RcvDataBufferHdr->SxgDumbRcvPacket; - SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event); - Packet->protocol = eth_type_trans(Packet, adapter->netdev); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumbRcv", - RcvDataBufferHdr, Packet, Event->Length, 0); - /* Lastly adjust the receive packet length. */ - RcvDataBufferHdr->SxgDumbRcvPacket = NULL; - RcvDataBufferHdr->PhysicalAddress = (dma_addr_t)NULL; - SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize); - if (RcvDataBufferHdr->skb) - { - spin_lock(&adapter->RcvQLock); - SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr); - // adapter->RcvBuffersOnCard ++; - spin_unlock(&adapter->RcvQLock); - } - return (Packet); - - drop: - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DropRcv", - RcvDataBufferHdr, Event->Length, 0, 0); - adapter->stats.rx_dropped++; -// adapter->Stats.RcvDiscards++; - spin_lock(&adapter->RcvQLock); - SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr); - spin_unlock(&adapter->RcvQLock); - return (NULL); -} - -/* - * sxg_process_rcv_error - process receive error and update - * stats - * - * Arguments: - * adapter - Adapter structure - * ErrorStatus - 4-byte receive error status - * - * Return Value : None - */ -static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus) -{ - u32 Error; - - adapter->stats.rx_errors++; - - if (ErrorStatus & SXG_RCV_STATUS_TRANSPORT_ERROR) { - Error = ErrorStatus & SXG_RCV_STATUS_TRANSPORT_MASK; - switch (Error) { - case SXG_RCV_STATUS_TRANSPORT_CSUM: - adapter->Stats.TransportCsum++; - break; - case SXG_RCV_STATUS_TRANSPORT_UFLOW: - adapter->Stats.TransportUflow++; - break; - case SXG_RCV_STATUS_TRANSPORT_HDRLEN: - adapter->Stats.TransportHdrLen++; - break; - } - } - if (ErrorStatus & SXG_RCV_STATUS_NETWORK_ERROR) { - Error = ErrorStatus & SXG_RCV_STATUS_NETWORK_MASK; - switch (Error) { - case SXG_RCV_STATUS_NETWORK_CSUM: - adapter->Stats.NetworkCsum++; - break; - case SXG_RCV_STATUS_NETWORK_UFLOW: - adapter->Stats.NetworkUflow++; - break; - case SXG_RCV_STATUS_NETWORK_HDRLEN: - adapter->Stats.NetworkHdrLen++; - break; - } - } - if (ErrorStatus & SXG_RCV_STATUS_PARITY) { - adapter->Stats.Parity++; - } - if (ErrorStatus & SXG_RCV_STATUS_LINK_ERROR) { - Error = ErrorStatus & SXG_RCV_STATUS_LINK_MASK; - switch (Error) { - case SXG_RCV_STATUS_LINK_PARITY: - adapter->Stats.LinkParity++; - break; - case SXG_RCV_STATUS_LINK_EARLY: - adapter->Stats.LinkEarly++; - break; - case SXG_RCV_STATUS_LINK_BUFOFLOW: - adapter->Stats.LinkBufOflow++; - break; - case SXG_RCV_STATUS_LINK_CODE: - adapter->Stats.LinkCode++; - break; - case SXG_RCV_STATUS_LINK_DRIBBLE: - adapter->Stats.LinkDribble++; - break; - case SXG_RCV_STATUS_LINK_CRC: - adapter->Stats.LinkCrc++; - break; - case SXG_RCV_STATUS_LINK_OFLOW: - adapter->Stats.LinkOflow++; - break; - case SXG_RCV_STATUS_LINK_UFLOW: - adapter->Stats.LinkUflow++; - break; - } - } -} - -/* - * sxg_mac_filter - * - * Arguments: - * adapter - Adapter structure - * pether - Ethernet header - * length - Frame length - * - * Return Value : TRUE if the frame is to be allowed - */ -static bool sxg_mac_filter(struct adapter_t *adapter, - struct ether_header *EtherHdr, ushort length) -{ - bool EqualAddr; - struct net_device *dev = adapter->netdev; - - if (SXG_MULTICAST_PACKET(EtherHdr)) { - if (SXG_BROADCAST_PACKET(EtherHdr)) { - /* broadcast */ - if (adapter->MacFilter & MAC_BCAST) { - adapter->Stats.DumbRcvBcastPkts++; - adapter->Stats.DumbRcvBcastBytes += length; - return (TRUE); - } - } else { - /* multicast */ - if (adapter->MacFilter & MAC_ALLMCAST) { - adapter->Stats.DumbRcvMcastPkts++; - adapter->Stats.DumbRcvMcastBytes += length; - return (TRUE); - } - if (adapter->MacFilter & MAC_MCAST) { - struct dev_mc_list *mclist = dev->mc_list; - while (mclist) { - ETHER_EQ_ADDR(mclist->da_addr, - EtherHdr->ether_dhost, - EqualAddr); - if (EqualAddr) { - adapter->Stats. - DumbRcvMcastPkts++; - adapter->Stats. - DumbRcvMcastBytes += length; - return (TRUE); - } - mclist = mclist->next; - } - } - } - } else if (adapter->MacFilter & MAC_DIRECTED) { - /* - * Not broadcast or multicast. Must be directed at us or - * the card is in promiscuous mode. Either way, consider it - * ours if MAC_DIRECTED is set - */ - adapter->Stats.DumbRcvUcastPkts++; - adapter->Stats.DumbRcvUcastBytes += length; - return (TRUE); - } - if (adapter->MacFilter & MAC_PROMISC) { - /* Whatever it is, keep it. */ - return (TRUE); - } - return (FALSE); -} - -static int sxg_register_interrupt(struct adapter_t *adapter) -{ - if (!adapter->intrregistered) { - int retval; - - DBG_ERROR - ("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x] %x\n", - __func__, adapter, adapter->netdev->irq, NR_IRQS); - - spin_unlock_irqrestore(&sxg_global.driver_lock, - sxg_global.flags); - - retval = request_irq(adapter->netdev->irq, - &sxg_isr, - IRQF_SHARED, - adapter->netdev->name, adapter->netdev); - - spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); - - if (retval) { - DBG_ERROR("sxg: request_irq (%s) FAILED [%x]\n", - adapter->netdev->name, retval); - return (retval); - } - adapter->intrregistered = 1; - adapter->IntRegistered = TRUE; - /* Disable RSS with line-based interrupts */ - adapter->RssEnabled = FALSE; - DBG_ERROR("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x]\n", - __func__, adapter, adapter->netdev->irq); - } - return (STATUS_SUCCESS); -} - -static void sxg_deregister_interrupt(struct adapter_t *adapter) -{ - DBG_ERROR("sxg: %s ENTER adapter[%p]\n", __func__, adapter); -#if XXXTODO - slic_init_cleanup(adapter); -#endif - memset(&adapter->stats, 0, sizeof(struct net_device_stats)); - adapter->error_interrupts = 0; - adapter->rcv_interrupts = 0; - adapter->xmit_interrupts = 0; - adapter->linkevent_interrupts = 0; - adapter->upr_interrupts = 0; - adapter->num_isrs = 0; - adapter->xmit_completes = 0; - adapter->rcv_broadcasts = 0; - adapter->rcv_multicasts = 0; - adapter->rcv_unicasts = 0; - DBG_ERROR("sxg: %s EXIT\n", __func__); -} - -/* - * sxg_if_init - * - * Perform initialization of our slic interface. - * - */ -static int sxg_if_init(struct adapter_t *adapter) -{ - struct net_device *dev = adapter->netdev; - int status = 0; - - DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d] flags[%x]\n", - __func__, adapter->netdev->name, - adapter->state, - adapter->linkstate, dev->flags); - - /* adapter should be down at this point */ - if (adapter->state != ADAPT_DOWN) { - DBG_ERROR("sxg_if_init adapter->state != ADAPT_DOWN\n"); - return (-EIO); - } - ASSERT(adapter->linkstate == LINK_DOWN); - - adapter->devflags_prev = dev->flags; - adapter->MacFilter = MAC_DIRECTED; - if (dev->flags) { - DBG_ERROR("sxg: %s (%s) Set MAC options: ", __func__, - adapter->netdev->name); - if (dev->flags & IFF_BROADCAST) { - adapter->MacFilter |= MAC_BCAST; - DBG_ERROR("BCAST "); - } - if (dev->flags & IFF_PROMISC) { - adapter->MacFilter |= MAC_PROMISC; - DBG_ERROR("PROMISC "); - } - if (dev->flags & IFF_ALLMULTI) { - adapter->MacFilter |= MAC_ALLMCAST; - DBG_ERROR("ALL_MCAST "); - } - if (dev->flags & IFF_MULTICAST) { - adapter->MacFilter |= MAC_MCAST; - DBG_ERROR("MCAST "); - } - DBG_ERROR("\n"); - } - status = sxg_register_intr(adapter); - if (status != STATUS_SUCCESS) { - DBG_ERROR("sxg_if_init: sxg_register_intr FAILED %x\n", - status); - sxg_deregister_interrupt(adapter); - return (status); - } - - adapter->state = ADAPT_UP; - - /* clear any pending events, then enable interrupts */ - DBG_ERROR("sxg: %s ENABLE interrupts(slic)\n", __func__); - - return (STATUS_SUCCESS); -} - -void sxg_set_interrupt_aggregation(struct adapter_t *adapter) -{ - /* - * Top bit disables aggregation on xmt (SXG_AGG_XMT_DISABLE). - * Make sure Max is less than 0x8000. - */ - adapter->max_aggregation = SXG_MAX_AGG_DEFAULT; - adapter->min_aggregation = SXG_MIN_AGG_DEFAULT; - WRITE_REG(adapter->UcodeRegs[0].Aggregation, - ((adapter->max_aggregation << SXG_MAX_AGG_SHIFT) | - adapter->min_aggregation), - TRUE); -} - -static int sxg_entry_open(struct net_device *dev) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - int status; - static int turn; - int sxg_initial_rcv_data_buffers = SXG_INITIAL_RCV_DATA_BUFFERS; - int i; - - if (adapter->JumboEnabled == TRUE) { - sxg_initial_rcv_data_buffers = - SXG_INITIAL_JUMBO_RCV_DATA_BUFFERS; - SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, - SXG_JUMBO_RCV_RING_SIZE); - } - - /* - * Allocate receive data buffers. We allocate a block of buffers and - * a corresponding descriptor block at once. See sxghw.h:SXG_RCV_BLOCK - */ - - for (i = 0; i < sxg_initial_rcv_data_buffers; - i += SXG_RCV_DESCRIPTORS_PER_BLOCK) - { - status = sxg_allocate_buffer_memory(adapter, - SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE), - SXG_BUFFER_TYPE_RCV); - if (status != STATUS_SUCCESS) - return status; - } - /* - * NBL resource allocation can fail in the 'AllocateComplete' routine, - * which doesn't return status. Make sure we got the number of buffers - * we requested - */ - - if (adapter->FreeRcvBufferCount < sxg_initial_rcv_data_buffers) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF6", - adapter, adapter->FreeRcvBufferCount, SXG_MAX_ENTRIES, - 0); - return (STATUS_RESOURCES); - } - /* - * The microcode expects it to be downloaded on every open. - */ - DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__); - if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) { - DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n", - __func__); - sxg_read_config(adapter); - } else { - adapter->state = ADAPT_FAIL; - adapter->linkstate = LINK_DOWN; - DBG_ERROR("sxg_download_microcode FAILED status[%x]\n", - status); - } - msleep(5); - - if (turn) { - sxg_second_open(adapter->netdev); - - return STATUS_SUCCESS; - } - - turn++; - - ASSERT(adapter); - DBG_ERROR("sxg: %s adapter->activated[%d]\n", __func__, - adapter->activated); - DBG_ERROR - ("sxg: %s (%s): [jiffies[%lx] cpu %d] dev[%p] adapt[%p] port[%d]\n", - __func__, adapter->netdev->name, jiffies, smp_processor_id(), - adapter->netdev, adapter, adapter->port); - - netif_stop_queue(adapter->netdev); - - spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); - if (!adapter->activated) { - sxg_global.num_sxg_ports_active++; - adapter->activated = 1; - } - /* Initialize the adapter */ - DBG_ERROR("sxg: %s ENTER sxg_initialize_adapter\n", __func__); - status = sxg_initialize_adapter(adapter); - DBG_ERROR("sxg: %s EXIT sxg_initialize_adapter status[%x]\n", - __func__, status); - - if (status == STATUS_SUCCESS) { - DBG_ERROR("sxg: %s ENTER sxg_if_init\n", __func__); - status = sxg_if_init(adapter); - DBG_ERROR("sxg: %s EXIT sxg_if_init status[%x]\n", __func__, - status); - } - - if (status != STATUS_SUCCESS) { - if (adapter->activated) { - sxg_global.num_sxg_ports_active--; - adapter->activated = 0; - } - spin_unlock_irqrestore(&sxg_global.driver_lock, - sxg_global.flags); - return (status); - } - DBG_ERROR("sxg: %s ENABLE ALL INTERRUPTS\n", __func__); - sxg_set_interrupt_aggregation(adapter); - napi_enable(&adapter->napi); - - /* Enable interrupts */ - SXG_ENABLE_ALL_INTERRUPTS(adapter); - - DBG_ERROR("sxg: %s EXIT\n", __func__); - - spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); - mod_timer(&adapter->watchdog_timer, jiffies); - - return STATUS_SUCCESS; -} - -int sxg_second_open(struct net_device * dev) -{ - struct adapter_t *adapter = (struct adapter_t*) netdev_priv(dev); - int status = 0; - - spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); - netif_start_queue(adapter->netdev); - adapter->state = ADAPT_UP; - adapter->linkstate = LINK_UP; - - status = sxg_initialize_adapter(adapter); - sxg_set_interrupt_aggregation(adapter); - napi_enable(&adapter->napi); - /* Re-enable interrupts */ - SXG_ENABLE_ALL_INTERRUPTS(adapter); - - sxg_register_intr(adapter); - spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); - mod_timer(&adapter->watchdog_timer, jiffies); - return (STATUS_SUCCESS); - -} - -static void __devexit sxg_entry_remove(struct pci_dev *pcidev) -{ - u32 mmio_start = 0; - u32 mmio_len = 0; - - struct net_device *dev = pci_get_drvdata(pcidev); - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - - flush_scheduled_work(); - - /* Deallocate Resources */ - unregister_netdev(dev); - sxg_reset_interrupt_capability(adapter); - sxg_free_resources(adapter); - - ASSERT(adapter); - - mmio_start = pci_resource_start(pcidev, 0); - mmio_len = pci_resource_len(pcidev, 0); - - DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __func__, - mmio_start, mmio_len); - release_mem_region(mmio_start, mmio_len); - - mmio_start = pci_resource_start(pcidev, 2); - mmio_len = pci_resource_len(pcidev, 2); - - DBG_ERROR("sxg: %s rel_region(2) start[%x] len[%x]\n", __func__, - mmio_start, mmio_len); - release_mem_region(mmio_start, mmio_len); - - pci_disable_device(pcidev); - - DBG_ERROR("sxg: %s deallocate device\n", __func__); - kfree(dev); - DBG_ERROR("sxg: %s EXIT\n", __func__); -} - -static int sxg_entry_halt(struct net_device *dev) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - int i; - u32 RssIds, IsrCount; - unsigned long flags; - - RssIds = SXG_RSS_CPU_COUNT(adapter); - IsrCount = adapter->msi_enabled ? RssIds : 1; - /* Disable interrupts */ - spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); - SXG_DISABLE_ALL_INTERRUPTS(adapter); - adapter->state = ADAPT_DOWN; - adapter->linkstate = LINK_DOWN; - - spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); - sxg_deregister_interrupt(adapter); - WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH); - mdelay(5000); - - del_timer_sync(&adapter->watchdog_timer); - netif_stop_queue(dev); - netif_carrier_off(dev); - - napi_disable(&adapter->napi); - - WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 0, true); - adapter->devflags_prev = 0; - DBG_ERROR("sxg: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n", - __func__, dev->name, adapter, adapter->state); - - spin_lock(&adapter->RcvQLock); - /* Free all the blocks and the buffers, moved from remove() routine */ - if (!(IsListEmpty(&adapter->AllRcvBlocks))) { - sxg_free_rcvblocks(adapter); - } - - - InitializeListHead(&adapter->FreeRcvBuffers); - InitializeListHead(&adapter->FreeRcvBlocks); - InitializeListHead(&adapter->AllRcvBlocks); - InitializeListHead(&adapter->FreeSglBuffers); - InitializeListHead(&adapter->AllSglBuffers); - - adapter->FreeRcvBufferCount = 0; - adapter->FreeRcvBlockCount = 0; - adapter->AllRcvBlockCount = 0; - adapter->RcvBuffersOnCard = 0; - adapter->PendingRcvCount = 0; - - memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1); - memset(adapter->EventRings, 0, sizeof(struct sxg_event_ring) * RssIds); - memset(adapter->Isr, 0, sizeof(u32) * IsrCount); - for (i = 0; i < SXG_MAX_RING_SIZE; i++) - adapter->RcvRingZeroInfo.Context[i] = NULL; - SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE); - SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE); - - spin_unlock(&adapter->RcvQLock); - - spin_lock_irqsave(&adapter->XmtZeroLock, flags); - adapter->AllSglBufferCount = 0; - adapter->FreeSglBufferCount = 0; - adapter->PendingXmtCount = 0; - memset(adapter->XmtRings, 0, sizeof(struct sxg_xmt_ring) * 1); - memset(adapter->XmtRingZeroIndex, 0, sizeof(u32)); - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - - for (i = 0; i < SXG_MAX_RSS; i++) { - adapter->NextEvent[i] = 0; - } - atomic_set(&adapter->pending_allocations, 0); - adapter->intrregistered = 0; - sxg_remove_isr(adapter); - DBG_ERROR("sxg: %s (%s) EXIT\n", __func__, dev->name); - return (STATUS_SUCCESS); -} - -static int sxg_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - ASSERT(rq); -/* DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev);*/ - switch (cmd) { - case SIOCSLICSETINTAGG: - { - /* struct adapter_t *adapter = (struct adapter_t *) - * netdev_priv(dev); - */ - u32 data[7]; - u32 intagg; - - if (copy_from_user(data, rq->ifr_data, 28)) { - DBG_ERROR("copy_from_user FAILED getting \ - initial params\n"); - return -EFAULT; - } - intagg = data[0]; - printk(KERN_EMERG - "%s: set interrupt aggregation to %d\n", - __func__, intagg); - return 0; - } - - default: - /* DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */ - return -EOPNOTSUPP; - } - return 0; -} - -#define NORMAL_ETHFRAME 0 - -/* - * sxg_send_packets - Send a skb packet - * - * Arguments: - * skb - The packet to send - * dev - Our linux net device that refs our adapter - * - * Return: - * 0 regardless of outcome XXXTODO refer to e1000 driver - */ -static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - u32 status = STATUS_SUCCESS; - - /* - * DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __func__, - * skb); - */ - - /* Check the adapter state */ - switch (adapter->State) { - case SXG_STATE_INITIALIZING: - case SXG_STATE_HALTED: - case SXG_STATE_SHUTDOWN: - ASSERT(0); /* unexpected */ - /* fall through */ - case SXG_STATE_RESETTING: - case SXG_STATE_SLEEP: - case SXG_STATE_BOOTDIAG: - case SXG_STATE_DIAG: - case SXG_STATE_HALTING: - status = STATUS_FAILURE; - break; - case SXG_STATE_RUNNING: - if (adapter->LinkState != SXG_LINK_UP) { - status = STATUS_FAILURE; - } - break; - default: - ASSERT(0); - status = STATUS_FAILURE; - } - if (status != STATUS_SUCCESS) { - goto xmit_fail; - } - /* send a packet */ - status = sxg_transmit_packet(adapter, skb); - if (status == STATUS_SUCCESS) { - goto xmit_done; - } - - xmit_fail: - /* reject & complete all the packets if they cant be sent */ - if (status != STATUS_SUCCESS) { -#if XXXTODO - /* sxg_send_packets_fail(adapter, skb, status); */ -#else - SXG_DROP_DUMB_SEND(adapter, skb); - adapter->stats.tx_dropped++; - return NETDEV_TX_BUSY; -#endif - } - DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __func__, - status); - - xmit_done: - return NETDEV_TX_OK; -} - -/* - * sxg_transmit_packet - * - * This function transmits a single packet. - * - * Arguments - - * adapter - Pointer to our adapter structure - * skb - The packet to be sent - * - * Return - STATUS of send - */ -static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb) -{ - struct sxg_x64_sgl *pSgl; - struct sxg_scatter_gather *SxgSgl; - unsigned long sgl_flags; - /* void *SglBuffer; */ - /* u32 SglBufferLength; */ - - /* - * The vast majority of work is done in the shared - * sxg_dumb_sgl routine. - */ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSend", - adapter, skb, 0, 0); - - /* Allocate a SGL buffer */ - SXG_GET_SGL_BUFFER(adapter, SxgSgl, 0); - if (!SxgSgl) { - adapter->Stats.NoSglBuf++; - adapter->stats.tx_errors++; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "SndPktF1", - adapter, skb, 0, 0); - return (STATUS_RESOURCES); - } - ASSERT(SxgSgl->adapter == adapter); - /*SglBuffer = SXG_SGL_BUFFER(SxgSgl); - SglBufferLength = SXG_SGL_BUF_SIZE; */ - SxgSgl->VlanTag.VlanTci = 0; - SxgSgl->VlanTag.VlanTpid = 0; - SxgSgl->Type = SXG_SGL_DUMB; - SxgSgl->DumbPacket = skb; - pSgl = NULL; - - /* Call the common sxg_dumb_sgl routine to complete the send. */ - return (sxg_dumb_sgl(pSgl, SxgSgl)); -} - -/* - * sxg_dumb_sgl - * - * Arguments: - * pSgl - - * SxgSgl - struct sxg_scatter_gather - * - * Return Value: - * Status of send operation. - */ -static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, - struct sxg_scatter_gather *SxgSgl) -{ - struct adapter_t *adapter = SxgSgl->adapter; - struct sk_buff *skb = SxgSgl->DumbPacket; - /* For now, all dumb-nic sends go on RSS queue zero */ - struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0]; - struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo; - struct sxg_cmd *XmtCmd = NULL; - /* u32 Index = 0; */ - u32 DataLength = skb->len; - /* unsigned int BufLen; */ - /* u32 SglOffset; */ - u64 phys_addr; - unsigned long flags; - unsigned long queue_id=0; - int offload_cksum = 0; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl", - pSgl, SxgSgl, 0, 0); - - /* Set aside a pointer to the sgl */ - SxgSgl->pSgl = pSgl; - - /* Sanity check that our SGL format is as we expect. */ - ASSERT(sizeof(struct sxg_x64_sge) == sizeof(struct sxg_x64_sge)); - /* Shouldn't be a vlan tag on this frame */ - ASSERT(SxgSgl->VlanTag.VlanTci == 0); - ASSERT(SxgSgl->VlanTag.VlanTpid == 0); - - /* - * From here below we work with the SGL placed in our - * buffer. - */ - - SxgSgl->Sgl.NumberOfElements = 1; - /* - * Set ucode Queue ID based on bottom bits of destination TCP port. - * This Queue ID splits slowpath/dumb-nic packet processing across - * multiple threads on the card to improve performance. It is split - * using the TCP port to avoid out-of-order packets that can result - * from multithreaded processing. We use the destination port because - * we expect to be run on a server, so in nearly all cases the local - * port is likely to be constant (well-known server port) and the - * remote port is likely to be random. The exception to this is iSCSI, - * in which case we use the sport instead. Note - * that original attempt at XOR'ing source and dest port resulted in - * poor balance on NTTTCP/iometer applications since they tend to - * line up (even-even, odd-odd..). - */ - - if (skb->protocol == htons(ETH_P_IP)) { - struct iphdr *ip; - - ip = ip_hdr(skb); - if (ip->protocol == IPPROTO_TCP) - offload_cksum = 1; - if (!offload_cksum || !tcp_hdr(skb)) - queue_id = 0; - else if (offload_cksum && (DataLength >= sizeof( - struct tcphdr))){ - queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? - (ntohs (tcp_hdr(skb)->source) & - SXG_LARGE_SEND_QUEUE_MASK): - (ntohs(tcp_hdr(skb)->dest) & - SXG_LARGE_SEND_QUEUE_MASK)); - } - } else if (skb->protocol == htons(ETH_P_IPV6)) { - if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) - offload_cksum = 1; - if (!offload_cksum || !tcp_hdr(skb)) - queue_id = 0; - else if (offload_cksum && (DataLength>=sizeof(struct tcphdr))){ - queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? - (ntohs (tcp_hdr(skb)->source) & - SXG_LARGE_SEND_QUEUE_MASK): - (ntohs(tcp_hdr(skb)->dest) & - SXG_LARGE_SEND_QUEUE_MASK)); - } - } - - /* Grab the spinlock and acquire a command */ - spin_lock_irqsave(&adapter->XmtZeroLock, flags); - SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl); - if (XmtCmd == NULL) { - /* - * Call sxg_complete_slow_send to see if we can - * free up any XmtRingZero entries and then try again - */ - - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - sxg_complete_slow_send(adapter); - spin_lock_irqsave(&adapter->XmtZeroLock, flags); - SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl); - if (XmtCmd == NULL) { - adapter->Stats.XmtZeroFull++; - goto abortcmd; - } - } - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd", - XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0); - memset(XmtCmd, '\0', sizeof(*XmtCmd)); - XmtCmd->SgEntries = 1; - XmtCmd->Flags = 0; - if (skb->ip_summed == CHECKSUM_PARTIAL) { - /* - * We need to set the Checkum in IP header to 0. This is - * required by hardware. - */ - if (offload_cksum) { - ip_hdr(skb)->check = 0x0; - XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP; - XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP; - /* - * Dont know if length will require a change in - * case of VLAN - */ - XmtCmd->CsumFlags.MacLen = ETH_HLEN; - XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >> - SXG_NW_HDR_LEN_SHIFT; - } else { - if (skb_checksum_help(skb)){ - printk(KERN_EMERG "Dropped UDP packet for" - " incorrect checksum calculation\n"); - if (XmtCmd) - SXG_ABORT_CMD(XmtRingInfo); - spin_unlock_irqrestore(&adapter->XmtZeroLock, - flags); - return STATUS_SUCCESS; - } - } - } - - /* - * Fill in the command - * Copy out the first SGE to the command and adjust for offset - */ - phys_addr = pci_map_single(adapter->pcidev, skb->data, skb->len, - PCI_DMA_TODEVICE); - - /* - * SAHARA SGL WORKAROUND - * See if the SGL straddles a 64k boundary. If so, skip to - * the start of the next 64k boundary and continue - */ - - if ((adapter->asictype == SAHARA_REV_A) && - (SXG_INVALID_SGL(phys_addr,skb->data_len))) - { - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - if (XmtCmd) - SXG_ABORT_CMD(XmtRingInfo); - /* Silently drop this packet */ - printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n"); - return STATUS_SUCCESS; - } - XmtCmd->Buffer.FirstSgeAddress = phys_addr; - XmtCmd->Buffer.FirstSgeLength = DataLength; - XmtCmd->Buffer.SgeOffset = 0; - XmtCmd->Buffer.TotalLength = DataLength; - - /* - * Advance transmit cmd descripter by 1. - * NOTE - See comments in SxgTcpOutput where we write - * to the XmtCmd register regarding CPU ID values and/or - * multiple commands. - * Top 16 bits specify queue_id. See comments about queue_id above - */ - /* Four queues at the moment */ - ASSERT((queue_id & ~SXG_LARGE_SEND_QUEUE_MASK) == 0); - WRITE_REG(adapter->UcodeRegs[0].XmtCmd, ((queue_id << 16) | 1), TRUE); - adapter->Stats.XmtQLen++; /* Stats within lock */ - /* Update stats */ - adapter->stats.tx_packets++; - adapter->stats.tx_bytes += DataLength; -#if XXXTODO /* Stats stuff */ - if (SXG_MULTICAST_PACKET(EtherHdr)) { - if (SXG_BROADCAST_PACKET(EtherHdr)) { - adapter->Stats.DumbXmtBcastPkts++; - adapter->Stats.DumbXmtBcastBytes += DataLength; - } else { - adapter->Stats.DumbXmtMcastPkts++; - adapter->Stats.DumbXmtMcastBytes += DataLength; - } - } else { - adapter->Stats.DumbXmtUcastPkts++; - adapter->Stats.DumbXmtUcastBytes += DataLength; - } -#endif - - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2", - XmtCmd, pSgl, SxgSgl, 0); - return STATUS_SUCCESS; - - abortcmd: - /* - * NOTE - Only jump to this label AFTER grabbing the - * XmtZeroLock, and DO NOT DROP IT between the - * command allocation and the following abort. - */ - if (XmtCmd) { - SXG_ABORT_CMD(XmtRingInfo); - } - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - -/* - * failsgl: - * Jump to this label if failure occurs before the - * XmtZeroLock is grabbed - */ - adapter->stats.tx_errors++; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal", - pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail); - /* SxgSgl->DumbPacket is the skb */ - // SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket); - - return STATUS_FAILURE; -} - -/* - * Link management functions - * - * sxg_initialize_link - Initialize the link stuff - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * status - */ -static int sxg_initialize_link(struct adapter_t *adapter) -{ - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - u32 Value; - u32 ConfigData; - u32 MaxFrame; - u32 AxgMacReg1; - int status; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitLink", - adapter, 0, 0, 0); - - /* Reset PHY and XGXS module */ - WRITE_REG(HwRegs->LinkStatus, LS_SERDES_POWER_DOWN, TRUE); - - /* Reset transmit configuration register */ - WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_RESET, TRUE); - - /* Reset receive configuration register */ - WRITE_REG(HwRegs->RcvConfig, RCV_CONFIG_RESET, TRUE); - - /* Reset all MAC modules */ - WRITE_REG(HwRegs->MacConfig0, AXGMAC_CFG0_SUB_RESET, TRUE); - - /* - * Link address 0 - * XXXTODO - This assumes the MAC address (0a:0b:0c:0d:0e:0f) - * is stored with the first nibble (0a) in the byte 0 - * of the Mac address. Possibly reverse? - */ - Value = *(u32 *) adapter->macaddr; - WRITE_REG(HwRegs->LinkAddress0Low, Value, TRUE); - /* also write the MAC address to the MAC. Endian is reversed. */ - WRITE_REG(HwRegs->MacAddressLow, ntohl(Value), TRUE); - Value = (*(u16 *) & adapter->macaddr[4] & 0x0000FFFF); - WRITE_REG(HwRegs->LinkAddress0High, Value | LINK_ADDRESS_ENABLE, TRUE); - /* endian swap for the MAC (put high bytes in bits [31:16], swapped) */ - Value = ntohl(Value); - WRITE_REG(HwRegs->MacAddressHigh, Value, TRUE); - /* Link address 1 */ - WRITE_REG(HwRegs->LinkAddress1Low, 0, TRUE); - WRITE_REG(HwRegs->LinkAddress1High, 0, TRUE); - /* Link address 2 */ - WRITE_REG(HwRegs->LinkAddress2Low, 0, TRUE); - WRITE_REG(HwRegs->LinkAddress2High, 0, TRUE); - /* Link address 3 */ - WRITE_REG(HwRegs->LinkAddress3Low, 0, TRUE); - WRITE_REG(HwRegs->LinkAddress3High, 0, TRUE); - - /* Enable MAC modules */ - WRITE_REG(HwRegs->MacConfig0, 0, TRUE); - - /* Configure MAC */ - AxgMacReg1 = ( /* Enable XMT */ - AXGMAC_CFG1_XMT_EN | - /* Enable receive */ - AXGMAC_CFG1_RCV_EN | - /* short frame detection */ - AXGMAC_CFG1_SHORT_ASSERT | - /* Verify frame length */ - AXGMAC_CFG1_CHECK_LEN | - /* Generate FCS */ - AXGMAC_CFG1_GEN_FCS | - /* Pad frames to 64 bytes */ - AXGMAC_CFG1_PAD_64); - - if (adapter->XmtFcEnabled) { - AxgMacReg1 |= AXGMAC_CFG1_XMT_PAUSE; /* Allow sending of pause */ - } - if (adapter->RcvFcEnabled) { - AxgMacReg1 |= AXGMAC_CFG1_RCV_PAUSE; /* Enable detection of pause */ - } - - WRITE_REG(HwRegs->MacConfig1, AxgMacReg1, TRUE); - - /* Set AXGMAC max frame length if jumbo. Not needed for standard MTU */ - if (adapter->JumboEnabled) { - WRITE_REG(HwRegs->MacMaxFrameLen, AXGMAC_MAXFRAME_JUMBO, TRUE); - } - /* - * AMIIM Configuration Register - - * The value placed in the AXGMAC_AMIIM_CFG_HALF_CLOCK portion - * (bottom bits) of this register is used to determine the MDC frequency - * as specified in the A-XGMAC Design Document. This value must not be - * zero. The following value (62 or 0x3E) is based on our MAC transmit - * clock frequency (MTCLK) of 312.5 MHz. Given a maximum MDIO clock - * frequency of 2.5 MHz (see the PHY spec), we get: - * 312.5/(2*(X+1)) < 2.5 ==> X = 62. - * This value happens to be the default value for this register, so we - * really don't have to do this. - */ - if (adapter->asictype == SAHARA_REV_B) { - WRITE_REG(HwRegs->MacAmiimConfig, 0x0000001F, TRUE); - } else { - WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE); - } - - /* Power up and enable PHY and XAUI/XGXS/Serdes logic */ - WRITE_REG(HwRegs->LinkStatus, - (LS_PHY_CLR_RESET | - LS_XGXS_ENABLE | - LS_XGXS_CTL | - LS_PHY_CLK_EN | - LS_ATTN_ALARM), - TRUE); - DBG_ERROR("After Power Up and enable PHY in sxg_initialize_link\n"); - - /* - * Per information given by Aeluros, wait 100 ms after removing reset. - * It's not enough to wait for the self-clearing reset bit in reg 0 to - * clear. - */ - mdelay(100); - - /* Verify the PHY has come up by checking that the Reset bit has - * cleared. - */ - status = sxg_read_mdio_reg(adapter, - MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */ - PHY_PMA_CONTROL1, /* PMA/PMD control register */ - &Value); - DBG_ERROR("After sxg_read_mdio_reg Value[%x] fail=%x\n", Value, - (Value & PMA_CONTROL1_RESET)); - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - if (Value & PMA_CONTROL1_RESET) /* reset complete if bit is 0 */ - return (STATUS_FAILURE); - - /* The SERDES should be initialized by now - confirm */ - READ_REG(HwRegs->LinkStatus, Value); - if (Value & LS_SERDES_DOWN) /* verify SERDES is initialized */ - return (STATUS_FAILURE); - - /* The XAUI link should also be up - confirm */ - if (!(Value & LS_XAUI_LINK_UP)) /* verify XAUI link is up */ - return (STATUS_FAILURE); - - /* Initialize the PHY */ - status = sxg_phy_init(adapter); - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - - /* Enable the Link Alarm */ - - /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module - * LASI_CONTROL - LASI control register - * LASI_CTL_LS_ALARM_ENABLE - enable link alarm bit - */ - status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA, - LASI_CONTROL, - LASI_CTL_LS_ALARM_ENABLE); - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - - /* XXXTODO - temporary - verify bit is set */ - - /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module - * LASI_CONTROL - LASI control register - */ - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, - LASI_CONTROL, - &Value); - - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - if (!(Value & LASI_CTL_LS_ALARM_ENABLE)) { - DBG_ERROR("Error! LASI Control Alarm Enable bit not set!\n"); - } - /* Enable receive */ - MaxFrame = adapter->JumboEnabled ? JUMBOMAXFRAME : ETHERMAXFRAME; - ConfigData = (RCV_CONFIG_ENABLE | - RCV_CONFIG_ENPARSE | - RCV_CONFIG_RCVBAD | - RCV_CONFIG_RCVPAUSE | - RCV_CONFIG_TZIPV6 | - RCV_CONFIG_TZIPV4 | - RCV_CONFIG_HASH_16 | - RCV_CONFIG_SOCKET | RCV_CONFIG_BUFSIZE(MaxFrame)); - - if (adapter->asictype == SAHARA_REV_B) { - ConfigData |= (RCV_CONFIG_HIPRICTL | - RCV_CONFIG_NEWSTATUSFMT); - } - WRITE_REG(HwRegs->RcvConfig, ConfigData, TRUE); - - WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_ENABLE, TRUE); - - /* Mark the link as down. We'll get a link event when it comes up. */ - sxg_link_state(adapter, SXG_LINK_DOWN); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInitLnk", - adapter, 0, 0, 0); - return (STATUS_SUCCESS); -} - -/* - * sxg_phy_init - Initialize the PHY - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * status - */ -static int sxg_phy_init(struct adapter_t *adapter) -{ - u32 Value; - struct phy_ucode *p; - int status; - - DBG_ERROR("ENTER %s\n", __func__); - - /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module - * 0xC205 - PHY ID register (?) - * &Value - XXXTODO - add def - */ - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, - 0xC205, - &Value); - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - - if (Value == 0x0012) { - /* 0x0012 == AEL2005C PHY(?) - XXXTODO - add def */ - DBG_ERROR("AEL2005C PHY detected. Downloading PHY \ - microcode.\n"); - - /* Initialize AEL2005C PHY and download PHY microcode */ - for (p = PhyUcode; p->Addr != 0xFFFF; p++) { - if (p->Addr == 0) { - /* if address == 0, data == sleep time in ms */ - mdelay(p->Data); - } else { - /* write the given data to the specified address */ - status = sxg_write_mdio_reg(adapter, - MIIM_DEV_PHY_PMA, - /* PHY address */ - p->Addr, - /* PHY data */ - p->Data); - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - } - } - } - DBG_ERROR("EXIT %s\n", __func__); - - return (STATUS_SUCCESS); -} - -/* - * sxg_link_event - Process a link event notification from the card - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * None - */ -static void sxg_link_event(struct adapter_t *adapter) -{ - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - struct net_device *netdev = adapter->netdev; - enum SXG_LINK_STATE LinkState; - int status; - u32 Value; - - if (adapter->state == ADAPT_DOWN) - return; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "LinkEvnt", - adapter, 0, 0, 0); - DBG_ERROR("ENTER %s\n", __func__); - - /* Check the Link Status register. We should have a Link Alarm. */ - READ_REG(HwRegs->LinkStatus, Value); - if (Value & LS_LINK_ALARM) { - /* - * We got a Link Status alarm. First, pause to let the - * link state settle (it can bounce a number of times) - */ - mdelay(10); - - /* Now clear the alarm by reading the LASI status register. */ - /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module */ - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, - /* LASI status register */ - LASI_STATUS, - &Value); - if (status != STATUS_SUCCESS) { - DBG_ERROR("Error reading LASI Status MDIO register!\n"); - sxg_link_state(adapter, SXG_LINK_DOWN); - /* ASSERT(0); */ - } - /* - * We used to assert that the LASI_LS_ALARM bit was set, as - * it should be. But there appears to be cases during - * initialization (when the PHY is reset and re-initialized) - * when we get a link alarm, but the status bit is 0 when we - * read it. Rather than trying to assure this never happens - * (and nver being certain), just ignore it. - - * ASSERT(Value & LASI_STATUS_LS_ALARM); - */ - - /* Now get and set the link state */ - LinkState = sxg_get_link_state(adapter); - sxg_link_state(adapter, LinkState); - DBG_ERROR("SXG: Link Alarm occurred. Link is %s\n", - ((LinkState == SXG_LINK_UP) ? "UP" : "DOWN")); - if (LinkState == SXG_LINK_UP) { - netif_carrier_on(netdev); - netif_tx_start_all_queues(netdev); - } else { - netif_tx_stop_all_queues(netdev); - netif_carrier_off(netdev); - } - } else { - /* - * XXXTODO - Assuming Link Attention is only being generated - * for the Link Alarm pin (and not for a XAUI Link Status change) - * , then it's impossible to get here. Yet we've gotten here - * twice (under extreme conditions - bouncing the link up and - * down many times a second). Needs further investigation. - */ - DBG_ERROR("SXG: sxg_link_event: Can't get here!\n"); - DBG_ERROR("SXG: Link Status == 0x%08X.\n", Value); - /* ASSERT(0); */ - } - DBG_ERROR("EXIT %s\n", __func__); - -} - -/* - * sxg_get_link_state - Determine if the link is up or down - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * Link State - */ -static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter) -{ - int status; - u32 Value; - - DBG_ERROR("ENTER %s\n", __func__); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "GetLink", - adapter, 0, 0, 0); - - /* - * Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if - * the following 3 bits (from 3 different MDIO registers) are all true. - */ - - /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module */ - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, - /* PMA/PMD Receive Signal Detect register */ - PHY_PMA_RCV_DET, - &Value); - if (status != STATUS_SUCCESS) - goto bad; - - /* If PMA/PMD receive signal detect is 0, then the link is down */ - if (!(Value & PMA_RCV_DETECT)) - return (SXG_LINK_DOWN); - - /* MIIM_DEV_PHY_PCS - PHY PCS module */ - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS, - /* PCS 10GBASE-R Status 1 register */ - PHY_PCS_10G_STATUS1, - &Value); - if (status != STATUS_SUCCESS) - goto bad; - - /* If PCS is not locked to receive blocks, then the link is down */ - if (!(Value & PCS_10B_BLOCK_LOCK)) - return (SXG_LINK_DOWN); - - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS,/* PHY XS module */ - /* XS Lane Status register */ - PHY_XS_LANE_STATUS, - &Value); - if (status != STATUS_SUCCESS) - goto bad; - - /* If XS transmit lanes are not aligned, then the link is down */ - if (!(Value & XS_LANE_ALIGN)) - return (SXG_LINK_DOWN); - - /* All 3 bits are true, so the link is up */ - DBG_ERROR("EXIT %s\n", __func__); - - return (SXG_LINK_UP); - - bad: - /* An error occurred reading an MDIO register. This shouldn't happen. */ - DBG_ERROR("Error reading an MDIO register!\n"); - ASSERT(0); - return (SXG_LINK_DOWN); -} - -static void sxg_indicate_link_state(struct adapter_t *adapter, - enum SXG_LINK_STATE LinkState) -{ - if (adapter->LinkState == SXG_LINK_UP) { - DBG_ERROR("%s: LINK now UP, call netif_start_queue\n", - __func__); - netif_start_queue(adapter->netdev); - } else { - DBG_ERROR("%s: LINK now DOWN, call netif_stop_queue\n", - __func__); - netif_stop_queue(adapter->netdev); - } -} - -/* - * sxg_change_mtu - Change the Maximum Transfer Unit - * * @returns 0 on success, negative on failure - */ -int sxg_change_mtu (struct net_device *netdev, int new_mtu) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(netdev); - - if (!((new_mtu == SXG_DEFAULT_MTU) || (new_mtu == SXG_JUMBO_MTU))) - return -EINVAL; - - if(new_mtu == netdev->mtu) - return 0; - - netdev->mtu = new_mtu; - - if (new_mtu == SXG_JUMBO_MTU) { - adapter->JumboEnabled = TRUE; - adapter->FrameSize = JUMBOMAXFRAME; - adapter->ReceiveBufferSize = SXG_RCV_JUMBO_BUFFER_SIZE; - } else { - adapter->JumboEnabled = FALSE; - adapter->FrameSize = ETHERMAXFRAME; - adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE; - } - - sxg_entry_halt(netdev); - sxg_entry_open(netdev); - return 0; -} - -/* - * sxg_link_state - Set the link state and if necessary, indicate. - * This routine the central point of processing for all link state changes. - * Nothing else in the driver should alter the link state or perform - * link state indications - * - * Arguments - - * adapter - A pointer to our adapter structure - * LinkState - The link state - * - * Return - * None - */ -static void sxg_link_state(struct adapter_t *adapter, - enum SXG_LINK_STATE LinkState) -{ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "LnkINDCT", - adapter, LinkState, adapter->LinkState, adapter->State); - - DBG_ERROR("ENTER %s\n", __func__); - - /* - * Hold the adapter lock during this routine. Maybe move - * the lock to the caller. - */ - /* IMP TODO : Check if we can survive without taking this lock */ -// spin_lock(&adapter->AdapterLock); - if (LinkState == adapter->LinkState) { - /* Nothing changed.. */ -// spin_unlock(&adapter->AdapterLock); - DBG_ERROR("EXIT #0 %s. Link status = %d\n", - __func__, LinkState); - return; - } - /* Save the adapter state */ - adapter->LinkState = LinkState; - - /* Drop the lock and indicate link state */ -// spin_unlock(&adapter->AdapterLock); - DBG_ERROR("EXIT #1 %s\n", __func__); - - sxg_indicate_link_state(adapter, LinkState); -} - -/* - * sxg_write_mdio_reg - Write to a register on the MDIO bus - * - * Arguments - - * adapter - A pointer to our adapter structure - * DevAddr - MDIO device number being addressed - * RegAddr - register address for the specified MDIO device - * Value - value to write to the MDIO register - * - * Return - * status - */ -static int sxg_write_mdio_reg(struct adapter_t *adapter, - u32 DevAddr, u32 RegAddr, u32 Value) -{ - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - /* Address operation (written to MIIM field reg) */ - u32 AddrOp; - /* Write operation (written to MIIM field reg) */ - u32 WriteOp; - u32 Cmd;/* Command (written to MIIM command reg) */ - u32 ValueRead; - u32 Timeout; - - /* DBG_ERROR("ENTER %s\n", __func__); */ - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO", - adapter, 0, 0, 0); - - /* Ensure values don't exceed field width */ - DevAddr &= 0x001F; /* 5-bit field */ - RegAddr &= 0xFFFF; /* 16-bit field */ - Value &= 0xFFFF; /* 16-bit field */ - - /* Set MIIM field register bits for an MIIM address operation */ - AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) | - (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) | - (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) | - (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr; - - /* Set MIIM field register bits for an MIIM write operation */ - WriteOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) | - (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) | - (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) | - (MIIM_OP_WRITE << AXGMAC_AMIIM_FIELD_OP_SHIFT) | Value; - - /* Set MIIM command register bits to execute an MIIM command */ - Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION; - - /* Reset the command register command bit (in case it's not 0) */ - WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE); - - /* MIIM write to set the address of the specified MDIO register */ - WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE); - - /* Write to MIIM Command Register to execute to address operation */ - WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE); - - /* Poll AMIIM Indicator register to wait for completion */ - Timeout = SXG_LINK_TIMEOUT; - do { - udelay(100); /* Timeout in 100us units */ - READ_REG(HwRegs->MacAmiimIndicator, ValueRead); - if (--Timeout == 0) { - return (STATUS_FAILURE); - } - } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY); - - /* Reset the command register command bit */ - WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE); - - /* MIIM write to set up an MDIO write operation */ - WRITE_REG(HwRegs->MacAmiimField, WriteOp, TRUE); - - /* Write to MIIM Command Register to execute the write operation */ - WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE); - - /* Poll AMIIM Indicator register to wait for completion */ - Timeout = SXG_LINK_TIMEOUT; - do { - udelay(100); /* Timeout in 100us units */ - READ_REG(HwRegs->MacAmiimIndicator, ValueRead); - if (--Timeout == 0) { - return (STATUS_FAILURE); - } - } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY); - - /* DBG_ERROR("EXIT %s\n", __func__); */ - - return (STATUS_SUCCESS); -} - -/* - * sxg_read_mdio_reg - Read a register on the MDIO bus - * - * Arguments - - * adapter - A pointer to our adapter structure - * DevAddr - MDIO device number being addressed - * RegAddr - register address for the specified MDIO device - * pValue - pointer to where to put data read from the MDIO register - * - * Return - * status - */ -static int sxg_read_mdio_reg(struct adapter_t *adapter, - u32 DevAddr, u32 RegAddr, u32 *pValue) -{ - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - u32 AddrOp; /* Address operation (written to MIIM field reg) */ - u32 ReadOp; /* Read operation (written to MIIM field reg) */ - u32 Cmd; /* Command (written to MIIM command reg) */ - u32 ValueRead; - u32 Timeout; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO", - adapter, 0, 0, 0); - DBG_ERROR("ENTER %s\n", __func__); - - /* Ensure values don't exceed field width */ - DevAddr &= 0x001F; /* 5-bit field */ - RegAddr &= 0xFFFF; /* 16-bit field */ - - /* Set MIIM field register bits for an MIIM address operation */ - AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) | - (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) | - (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) | - (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr; - - /* Set MIIM field register bits for an MIIM read operation */ - ReadOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) | - (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) | - (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) | - (MIIM_OP_READ << AXGMAC_AMIIM_FIELD_OP_SHIFT); - - /* Set MIIM command register bits to execute an MIIM command */ - Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION; - - /* Reset the command register command bit (in case it's not 0) */ - WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE); - - /* MIIM write to set the address of the specified MDIO register */ - WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE); - - /* Write to MIIM Command Register to execute to address operation */ - WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE); - - /* Poll AMIIM Indicator register to wait for completion */ - Timeout = SXG_LINK_TIMEOUT; - do { - udelay(100); /* Timeout in 100us units */ - READ_REG(HwRegs->MacAmiimIndicator, ValueRead); - if (--Timeout == 0) { - DBG_ERROR("EXIT %s with STATUS_FAILURE 1\n", __func__); - - return (STATUS_FAILURE); - } - } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY); - - /* Reset the command register command bit */ - WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE); - - /* MIIM write to set up an MDIO register read operation */ - WRITE_REG(HwRegs->MacAmiimField, ReadOp, TRUE); - - /* Write to MIIM Command Register to execute the read operation */ - WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE); - - /* Poll AMIIM Indicator register to wait for completion */ - Timeout = SXG_LINK_TIMEOUT; - do { - udelay(100); /* Timeout in 100us units */ - READ_REG(HwRegs->MacAmiimIndicator, ValueRead); - if (--Timeout == 0) { - DBG_ERROR("EXIT %s with STATUS_FAILURE 2\n", __func__); - - return (STATUS_FAILURE); - } - } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY); - - /* Read the MDIO register data back from the field register */ - READ_REG(HwRegs->MacAmiimField, *pValue); - *pValue &= 0xFFFF; /* data is in the lower 16 bits */ - - DBG_ERROR("EXIT %s\n", __func__); - - return (STATUS_SUCCESS); -} - -/* - * Functions to obtain the CRC corresponding to the destination mac address. - * This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using - * the polynomial: - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 - * + x^4 + x^2 + x^1. - * - * After the CRC for the 6 bytes is generated (but before the value is - * complemented), we must then transpose the value and return bits 30-23. - */ -static u32 sxg_crc_table[256];/* Table of CRC's for all possible byte values */ -static u32 sxg_crc_init; /* Is table initialized */ - -/* Contruct the CRC32 table */ -static void sxg_mcast_init_crc32(void) -{ - u32 c; /* CRC shit reg */ - u32 e = 0; /* Poly X-or pattern */ - int i; /* counter */ - int k; /* byte being shifted into crc */ - - static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 }; - - for (i = 0; i < ARRAY_SIZE(p); i++) { - e |= 1L << (31 - p[i]); - } - - for (i = 1; i < 256; i++) { - c = i; - for (k = 8; k; k--) { - c = c & 1 ? (c >> 1) ^ e : c >> 1; - } - sxg_crc_table[i] = c; - } -} - -/* - * Return the MAC hast as described above. - */ -static unsigned char sxg_mcast_get_mac_hash(char *macaddr) -{ - u32 crc; - char *p; - int i; - unsigned char machash = 0; - - if (!sxg_crc_init) { - sxg_mcast_init_crc32(); - sxg_crc_init = 1; - } - - crc = 0xFFFFFFFF; /* Preload shift register, per crc-32 spec */ - for (i = 0, p = macaddr; i < 6; ++p, ++i) { - crc = (crc >> 8) ^ sxg_crc_table[(crc ^ *p) & 0xFF]; - } - - /* Return bits 1-8, transposed */ - for (i = 1; i < 9; i++) { - machash |= (((crc >> i) & 1) << (8 - i)); - } - - return (machash); -} - -static void sxg_mcast_set_mask(struct adapter_t *adapter) -{ - struct sxg_ucode_regs *sxg_regs = adapter->UcodeRegs; - - DBG_ERROR("%s ENTER (%s) MacFilter[%x] mask[%llx]\n", __func__, - adapter->netdev->name, (unsigned int)adapter->MacFilter, - adapter->MulticastMask); - - if (adapter->MacFilter & (MAC_ALLMCAST | MAC_PROMISC)) { - /* - * Turn on all multicast addresses. We have to do this for - * promiscuous mode as well as ALLMCAST mode. It saves the - * Microcode from having keep state about the MAC configuration - */ - /* DBG_ERROR("sxg: %s MacFilter = MAC_ALLMCAST | MAC_PROMISC\n \ - * SLUT MODE!!!\n",__func__); - */ - WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH); - WRITE_REG(sxg_regs->McastHigh, 0xFFFFFFFF, FLUSH); - /* DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high \ - * 0xFFFFFFFF\n",__func__, adapter->netdev->name); - */ - - } else { - /* - * Commit our multicast mast to the SLIC by writing to the - * multicast address mask registers - */ - DBG_ERROR("%s (%s) WRITE mcastlow[%lx] mcasthigh[%lx]\n", - __func__, adapter->netdev->name, - ((ulong) (adapter->MulticastMask & 0xFFFFFFFF)), - ((ulong) - ((adapter->MulticastMask >> 32) & 0xFFFFFFFF))); - - WRITE_REG(sxg_regs->McastLow, - (u32) (adapter->MulticastMask & 0xFFFFFFFF), FLUSH); - WRITE_REG(sxg_regs->McastHigh, - (u32) ((adapter-> - MulticastMask >> 32) & 0xFFFFFFFF), FLUSH); - } -} - -static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address) -{ - unsigned char crcpoly; - - /* Get the CRC polynomial for the mac address */ - crcpoly = sxg_mcast_get_mac_hash(address); - - /* - * We only have space on the SLIC for 64 entries. Lop - * off the top two bits. (2^6 = 64) - */ - crcpoly &= 0x3F; - - /* OR in the new bit into our 64 bit mask. */ - adapter->MulticastMask |= (u64) 1 << crcpoly; -} - -/* - * Function takes MAC addresses from dev_mc_list and generates the Mask - */ - -static void sxg_set_mcast_addr(struct adapter_t *adapter) -{ - struct dev_mc_list *mclist; - struct net_device *dev = adapter->netdev; - int i; - - if (adapter->MacFilter & (MAC_ALLMCAST | MAC_MCAST)) { - for (i = 0, mclist = dev->mc_list; i < dev->mc_count; - i++, mclist = mclist->next) { - sxg_mcast_set_bit(adapter,mclist->da_addr); - } - } - sxg_mcast_set_mask(adapter); -} - -static void sxg_mcast_set_list(struct net_device *dev) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - - ASSERT(adapter); - if (dev->flags & IFF_PROMISC) - adapter->MacFilter |= MAC_PROMISC; - if (dev->flags & IFF_MULTICAST) - adapter->MacFilter |= MAC_MCAST; - if (dev->flags & IFF_ALLMULTI) - adapter->MacFilter |= MAC_ALLMCAST; - - //XXX handle other flags as well - sxg_set_mcast_addr(adapter); -} - -void sxg_free_sgl_buffers(struct adapter_t *adapter) -{ - struct list_entry *ple; - struct sxg_scatter_gather *Sgl; - - while(!(IsListEmpty(&adapter->AllSglBuffers))) { - ple = RemoveHeadList(&adapter->AllSglBuffers); - Sgl = container_of(ple, struct sxg_scatter_gather, AllList); - kfree(Sgl); - adapter->AllSglBufferCount--; - } -} - -void sxg_free_rcvblocks(struct adapter_t *adapter) -{ - u32 i; - void *temp_RcvBlock; - struct list_entry *ple; - struct sxg_rcv_block_hdr *RcvBlockHdr; - struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr; - ASSERT((adapter->state == SXG_STATE_INITIALIZING) || - (adapter->state == SXG_STATE_HALTING)); - while(!(IsListEmpty(&adapter->AllRcvBlocks))) { - - ple = RemoveHeadList(&adapter->AllRcvBlocks); - RcvBlockHdr = container_of(ple, struct sxg_rcv_block_hdr, AllList); - - if(RcvBlockHdr->VirtualAddress) { - temp_RcvBlock = RcvBlockHdr->VirtualAddress; - - for(i=0; i< SXG_RCV_DESCRIPTORS_PER_BLOCK; - i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) { - RcvDataBufferHdr = - (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock; - SXG_FREE_RCV_PACKET(RcvDataBufferHdr); - } - } - - pci_free_consistent(adapter->pcidev, - SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE), - RcvBlockHdr->VirtualAddress, - RcvBlockHdr->PhysicalAddress); - adapter->AllRcvBlockCount--; - } - ASSERT(adapter->AllRcvBlockCount == 0); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk", - adapter, 0, 0, 0); -} -void sxg_free_mcast_addrs(struct adapter_t *adapter) -{ - struct sxg_multicast_address *address; - while(adapter->MulticastAddrs) { - address = adapter->MulticastAddrs; - adapter->MulticastAddrs = address->Next; - kfree(address); - } - - adapter->MulticastMask= 0; -} - -void sxg_unmap_resources(struct adapter_t *adapter) -{ - if(adapter->HwRegs) { - iounmap((void *)adapter->HwRegs); - } - if(adapter->UcodeRegs) { - iounmap((void *)adapter->UcodeRegs); - } - - ASSERT(adapter->AllRcvBlockCount == 0); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk", - adapter, 0, 0, 0); -} - - - -/* - * sxg_free_resources - Free everything allocated in SxgAllocateResources - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * none - */ -void sxg_free_resources(struct adapter_t *adapter) -{ - u32 RssIds, IsrCount; - RssIds = SXG_RSS_CPU_COUNT(adapter); - IsrCount = adapter->msi_enabled ? RssIds : 1; - - if (adapter->BasicAllocations == FALSE) { - /* - * No allocations have been made, including spinlocks, - * or listhead initializations. Return. - */ - return; - } - - if (!(IsListEmpty(&adapter->AllRcvBlocks))) { - sxg_free_rcvblocks(adapter); - } - if (!(IsListEmpty(&adapter->AllSglBuffers))) { - sxg_free_sgl_buffers(adapter); - } - - if (adapter->XmtRingZeroIndex) { - pci_free_consistent(adapter->pcidev, - sizeof(u32), - adapter->XmtRingZeroIndex, - adapter->PXmtRingZeroIndex); - } - if (adapter->Isr) { - pci_free_consistent(adapter->pcidev, - sizeof(u32) * IsrCount, - adapter->Isr, adapter->PIsr); - } - - if (adapter->EventRings) { - pci_free_consistent(adapter->pcidev, - sizeof(struct sxg_event_ring) * RssIds, - adapter->EventRings, adapter->PEventRings); - } - if (adapter->RcvRings) { - pci_free_consistent(adapter->pcidev, - sizeof(struct sxg_rcv_ring) * 1, - adapter->RcvRings, - adapter->PRcvRings); - adapter->RcvRings = NULL; - } - - if(adapter->XmtRings) { - pci_free_consistent(adapter->pcidev, - sizeof(struct sxg_xmt_ring) * 1, - adapter->XmtRings, - adapter->PXmtRings); - adapter->XmtRings = NULL; - } - - if (adapter->ucode_stats) { - pci_unmap_single(adapter->pcidev, - sizeof(struct sxg_ucode_stats), - adapter->pucode_stats, PCI_DMA_FROMDEVICE); - adapter->ucode_stats = NULL; - } - - - /* Unmap register spaces */ - sxg_unmap_resources(adapter); - - sxg_free_mcast_addrs(adapter); - - adapter->BasicAllocations = FALSE; - -} - -/* - * sxg_allocate_complete - - * - * This routine is called when a memory allocation has completed. - * - * Arguments - - * struct adapter_t * - Our adapter structure - * VirtualAddress - Memory virtual address - * PhysicalAddress - Memory physical address - * Length - Length of memory allocated (or 0) - * Context - The type of buffer allocated - * - * Return - * None. - */ -static int sxg_allocate_complete(struct adapter_t *adapter, - void *VirtualAddress, - dma_addr_t PhysicalAddress, - u32 Length, enum sxg_buffer_type Context) -{ - int status = 0; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocCmp", - adapter, VirtualAddress, Length, Context); - ASSERT(atomic_read(&adapter->pending_allocations)); - atomic_dec(&adapter->pending_allocations); - - switch (Context) { - - case SXG_BUFFER_TYPE_RCV: - status = sxg_allocate_rcvblock_complete(adapter, - VirtualAddress, - PhysicalAddress, Length); - break; - case SXG_BUFFER_TYPE_SGL: - sxg_allocate_sgl_buffer_complete(adapter, (struct sxg_scatter_gather *) - VirtualAddress, - PhysicalAddress, Length); - break; - } - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocCmp", - adapter, VirtualAddress, Length, Context); - - return status; -} - -/* - * sxg_allocate_buffer_memory - Shared memory allocation routine used for - * synchronous and asynchronous buffer allocations - * - * Arguments - - * adapter - A pointer to our adapter structure - * Size - block size to allocate - * BufferType - Type of buffer to allocate - * - * Return - * int - */ -static int sxg_allocate_buffer_memory(struct adapter_t *adapter, - u32 Size, enum sxg_buffer_type BufferType) -{ - int status; - void *Buffer; - dma_addr_t pBuffer; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocMem", - adapter, Size, BufferType, 0); - /* - * Grab the adapter lock and check the state. If we're in anything other - * than INITIALIZING or RUNNING state, fail. This is to prevent - * allocations in an improper driver state - */ - - atomic_inc(&adapter->pending_allocations); - - if(BufferType != SXG_BUFFER_TYPE_SGL) - Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer); - else { - Buffer = kzalloc(Size, GFP_ATOMIC); - pBuffer = (dma_addr_t)NULL; - } - if (Buffer == NULL) { - /* - * Decrement the AllocationsPending count while holding - * the lock. Pause processing relies on this - */ - atomic_dec(&adapter->pending_allocations); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlcMemF1", - adapter, Size, BufferType, 0); - return (STATUS_RESOURCES); - } - status = sxg_allocate_complete(adapter, Buffer, pBuffer, Size, BufferType); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocMem", - adapter, Size, BufferType, status); - return status; -} - -/* - * sxg_allocate_rcvblock_complete - Complete a receive descriptor - * block allocation - * - * Arguments - - * adapter - A pointer to our adapter structure - * RcvBlock - receive block virtual address - * PhysicalAddress - Physical address - * Length - Memory length - * - * Return - */ -static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter, - void *RcvBlock, - dma_addr_t PhysicalAddress, - u32 Length) -{ - u32 i; - u32 BufferSize = adapter->ReceiveBufferSize; - u64 Paddr; - void *temp_RcvBlock; - struct sxg_rcv_block_hdr *RcvBlockHdr; - struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr; - struct sxg_rcv_descriptor_block *RcvDescriptorBlock; - struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlRcvBlk", - adapter, RcvBlock, Length, 0); - if (RcvBlock == NULL) { - goto fail; - } - memset(RcvBlock, 0, Length); - ASSERT((BufferSize == SXG_RCV_DATA_BUFFER_SIZE) || - (BufferSize == SXG_RCV_JUMBO_BUFFER_SIZE)); - ASSERT(Length == SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE)); - /* - * First, initialize the contained pool of receive data buffers. - * This initialization requires NBL/NB/MDL allocations, if any of them - * fail, free the block and return without queueing the shared memory - */ - //RcvDataBuffer = RcvBlock; - temp_RcvBlock = RcvBlock; - for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; - i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) { - RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) - temp_RcvBlock; - /* For FREE macro assertion */ - RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM; - SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize); - if (RcvDataBufferHdr->SxgDumbRcvPacket == NULL) - goto fail; - - } - - /* - * Place this entire block of memory on the AllRcvBlocks queue so it - * can be free later - */ - - RcvBlockHdr = (struct sxg_rcv_block_hdr *) ((unsigned char *)RcvBlock + - SXG_RCV_BLOCK_HDR_OFFSET(SXG_RCV_DATA_HDR_SIZE)); - RcvBlockHdr->VirtualAddress = RcvBlock; - RcvBlockHdr->PhysicalAddress = PhysicalAddress; - spin_lock(&adapter->RcvQLock); - adapter->AllRcvBlockCount++; - InsertTailList(&adapter->AllRcvBlocks, &RcvBlockHdr->AllList); - spin_unlock(&adapter->RcvQLock); - - /* Now free the contained receive data buffers that we - * initialized above */ - temp_RcvBlock = RcvBlock; - for (i = 0, Paddr = PhysicalAddress; - i < SXG_RCV_DESCRIPTORS_PER_BLOCK; - i++, Paddr += SXG_RCV_DATA_HDR_SIZE, - temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) { - RcvDataBufferHdr = - (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock; - spin_lock(&adapter->RcvQLock); - SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr); - spin_unlock(&adapter->RcvQLock); - } - - /* Locate the descriptor block and put it on a separate free queue */ - RcvDescriptorBlock = - (struct sxg_rcv_descriptor_block *) ((unsigned char *)RcvBlock + - SXG_RCV_DESCRIPTOR_BLOCK_OFFSET - (SXG_RCV_DATA_HDR_SIZE)); - RcvDescriptorBlockHdr = - (struct sxg_rcv_descriptor_block_hdr *) ((unsigned char *)RcvBlock + - SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET - (SXG_RCV_DATA_HDR_SIZE)); - RcvDescriptorBlockHdr->VirtualAddress = RcvDescriptorBlock; - RcvDescriptorBlockHdr->PhysicalAddress = Paddr; - spin_lock(&adapter->RcvQLock); - SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter, RcvDescriptorBlockHdr); - spin_unlock(&adapter->RcvQLock); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlRBlk", - adapter, RcvBlock, Length, 0); - return STATUS_SUCCESS; -fail: - /* Free any allocated resources */ - if (RcvBlock) { - temp_RcvBlock = RcvBlock; - for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; - i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) { - RcvDataBufferHdr = - (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock; - SXG_FREE_RCV_PACKET(RcvDataBufferHdr); - } - pci_free_consistent(adapter->pcidev, - Length, RcvBlock, PhysicalAddress); - } - DBG_ERROR("%s: OUT OF RESOURCES\n", __func__); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "RcvAFail", - adapter, adapter->FreeRcvBufferCount, - adapter->FreeRcvBlockCount, adapter->AllRcvBlockCount); - adapter->Stats.NoMem++; - /* As allocation failed, free all previously allocated blocks..*/ - //sxg_free_rcvblocks(adapter); - - return STATUS_RESOURCES; -} - -/* - * sxg_allocate_sgl_buffer_complete - Complete a SGL buffer allocation - * - * Arguments - - * adapter - A pointer to our adapter structure - * SxgSgl - struct sxg_scatter_gather buffer - * PhysicalAddress - Physical address - * Length - Memory length - * - * Return - */ -static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter, - struct sxg_scatter_gather *SxgSgl, - dma_addr_t PhysicalAddress, - u32 Length) -{ - unsigned long sgl_flags; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlSglCmp", - adapter, SxgSgl, Length, 0); - spin_lock_irqsave(&adapter->SglQLock, sgl_flags); - adapter->AllSglBufferCount++; - /* PhysicalAddress; */ - SxgSgl->PhysicalAddress = PhysicalAddress; - /* Initialize backpointer once */ - SxgSgl->adapter = adapter; - InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList); - spin_unlock_irqrestore(&adapter->SglQLock, sgl_flags); - SxgSgl->State = SXG_BUFFER_BUSY; - SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlSgl", - adapter, SxgSgl, Length, 0); -} - - -static int sxg_adapter_set_hwaddr(struct adapter_t *adapter) -{ - /* - * DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] \ - * funct#[%d]\n", __func__, card->config_set, - * adapter->port, adapter->physport, adapter->functionnumber); - * - * sxg_dbg_macaddrs(adapter); - */ - /* DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n", - * __func__); - */ - - /* sxg_dbg_macaddrs(adapter); */ - - struct net_device * dev = adapter->netdev; - if(!dev) - { - printk("sxg: Dev is Null\n"); - } - - DBG_ERROR("%s ENTER (%s)\n", __func__, adapter->netdev->name); - - if (netif_running(dev)) { - return -EBUSY; - } - if (!adapter) { - return -EBUSY; - } - - if (!(adapter->currmacaddr[0] || - adapter->currmacaddr[1] || - adapter->currmacaddr[2] || - adapter->currmacaddr[3] || - adapter->currmacaddr[4] || adapter->currmacaddr[5])) { - memcpy(adapter->currmacaddr, adapter->macaddr, 6); - } - if (adapter->netdev) { - memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6); - memcpy(adapter->netdev->perm_addr, adapter->currmacaddr, 6); - } - /* DBG_ERROR ("%s EXIT port %d\n", __func__, adapter->port); */ - sxg_dbg_macaddrs(adapter); - - return 0; -} - -#if XXXTODO -static int sxg_mac_set_address(struct net_device *dev, void *ptr) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - struct sockaddr *addr = ptr; - - DBG_ERROR("%s ENTER (%s)\n", __func__, adapter->netdev->name); - - if (netif_running(dev)) { - return -EBUSY; - } - if (!adapter) { - return -EBUSY; - } - DBG_ERROR("sxg: %s (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - __func__, adapter->netdev->name, adapter->currmacaddr[0], - adapter->currmacaddr[1], adapter->currmacaddr[2], - adapter->currmacaddr[3], adapter->currmacaddr[4], - adapter->currmacaddr[5]); - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len); - DBG_ERROR("sxg: %s (%s) new %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - __func__, adapter->netdev->name, adapter->currmacaddr[0], - adapter->currmacaddr[1], adapter->currmacaddr[2], - adapter->currmacaddr[3], adapter->currmacaddr[4], - adapter->currmacaddr[5]); - - sxg_config_set(adapter, TRUE); - return 0; -} -#endif - -/* - * SXG DRIVER FUNCTIONS (below) - * - * sxg_initialize_adapter - Initialize adapter - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - int - */ -static int sxg_initialize_adapter(struct adapter_t *adapter) -{ - u32 RssIds, IsrCount; - u32 i; - int status; - int sxg_rcv_ring_size = SXG_RCV_RING_SIZE; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitAdpt", - adapter, 0, 0, 0); - - RssIds = 1; /* XXXTODO SXG_RSS_CPU_COUNT(adapter); */ - IsrCount = adapter->msi_enabled ? RssIds : 1; - - /* - * Sanity check SXG_UCODE_REGS structure definition to - * make sure the length is correct - */ - ASSERT(sizeof(struct sxg_ucode_regs) == SXG_REGISTER_SIZE_PER_CPU); - - /* Disable interrupts */ - SXG_DISABLE_ALL_INTERRUPTS(adapter); - - /* Set MTU */ - ASSERT((adapter->FrameSize == ETHERMAXFRAME) || - (adapter->FrameSize == JUMBOMAXFRAME)); - WRITE_REG(adapter->UcodeRegs[0].LinkMtu, adapter->FrameSize, TRUE); - - /* Set event ring base address and size */ - WRITE_REG64(adapter, - adapter->UcodeRegs[0].EventBase, adapter->PEventRings, 0); - WRITE_REG(adapter->UcodeRegs[0].EventSize, EVENT_RING_SIZE, TRUE); - - /* Per-ISR initialization */ - for (i = 0; i < IsrCount; i++) { - u64 Addr; - /* Set interrupt status pointer */ - Addr = adapter->PIsr + (i * sizeof(u32)); - WRITE_REG64(adapter, adapter->UcodeRegs[i].Isp, Addr, i); - } - - /* XMT ring zero index */ - WRITE_REG64(adapter, - adapter->UcodeRegs[0].SPSendIndex, - adapter->PXmtRingZeroIndex, 0); - - /* Per-RSS initialization */ - for (i = 0; i < RssIds; i++) { - /* Release all event ring entries to the Microcode */ - WRITE_REG(adapter->UcodeRegs[i].EventRelease, EVENT_RING_SIZE, - TRUE); - } - - /* Transmit ring base and size */ - WRITE_REG64(adapter, - adapter->UcodeRegs[0].XmtBase, adapter->PXmtRings, 0); - WRITE_REG(adapter->UcodeRegs[0].XmtSize, SXG_XMT_RING_SIZE, TRUE); - - /* Receive ring base and size */ - WRITE_REG64(adapter, - adapter->UcodeRegs[0].RcvBase, adapter->PRcvRings, 0); - if (adapter->JumboEnabled == TRUE) - sxg_rcv_ring_size = SXG_JUMBO_RCV_RING_SIZE; - WRITE_REG(adapter->UcodeRegs[0].RcvSize, sxg_rcv_ring_size, TRUE); - - /* Populate the card with receive buffers */ - sxg_stock_rcv_buffers(adapter); - - /* - * Initialize checksum offload capabilities. At the moment we always - * enable IP and TCP receive checksums on the card. Depending on the - * checksum configuration specified by the user, we can choose to - * report or ignore the checksum information provided by the card. - */ - WRITE_REG(adapter->UcodeRegs[0].ReceiveChecksum, - SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED, TRUE); - - adapter->flags |= (SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED ); - - /* Initialize the MAC, XAUI */ - DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __func__); - status = sxg_initialize_link(adapter); - DBG_ERROR("sxg: %s EXIT sxg_initialize_link status[%x]\n", __func__, - status); - if (status != STATUS_SUCCESS) { - return (status); - } - /* - * Initialize Dead to FALSE. - * SlicCheckForHang or SlicDumpThread will take it from here. - */ - adapter->Dead = FALSE; - adapter->PingOutstanding = FALSE; - adapter->XmtFcEnabled = TRUE; - adapter->RcvFcEnabled = TRUE; - - adapter->State = SXG_STATE_RUNNING; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInit", - adapter, 0, 0, 0); - return (STATUS_SUCCESS); -} - -/* - * sxg_fill_descriptor_block - Populate a descriptor block and give it to - * the card. The caller should hold the RcvQLock - * - * Arguments - - * adapter - A pointer to our adapter structure - * RcvDescriptorBlockHdr - Descriptor block to fill - * - * Return - * status - */ -static int sxg_fill_descriptor_block(struct adapter_t *adapter, - struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr) -{ - u32 i; - struct sxg_ring_info *RcvRingInfo = &adapter->RcvRingZeroInfo; - struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr; - struct sxg_rcv_descriptor_block *RcvDescriptorBlock; - struct sxg_cmd *RingDescriptorCmd; - struct sxg_rcv_ring *RingZero = &adapter->RcvRings[0]; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FilBlk", - adapter, adapter->RcvBuffersOnCard, - adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount); - - ASSERT(RcvDescriptorBlockHdr); - - /* - * If we don't have the resources to fill the descriptor block, - * return failure - */ - if ((adapter->FreeRcvBufferCount < SXG_RCV_DESCRIPTORS_PER_BLOCK) || - SXG_RING_FULL(RcvRingInfo)) { - adapter->Stats.NoMem++; - return (STATUS_FAILURE); - } - /* Get a ring descriptor command */ - SXG_GET_CMD(RingZero, - RcvRingInfo, RingDescriptorCmd, RcvDescriptorBlockHdr); - ASSERT(RingDescriptorCmd); - RcvDescriptorBlockHdr->State = SXG_BUFFER_ONCARD; - RcvDescriptorBlock = (struct sxg_rcv_descriptor_block *) - RcvDescriptorBlockHdr->VirtualAddress; - - /* Fill in the descriptor block */ - for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; i++) { - SXG_GET_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr); - ASSERT(RcvDataBufferHdr); -// ASSERT(RcvDataBufferHdr->SxgDumbRcvPacket); - if (!RcvDataBufferHdr->SxgDumbRcvPacket) { - SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, - adapter->ReceiveBufferSize); - if(RcvDataBufferHdr->skb) - RcvDataBufferHdr->SxgDumbRcvPacket = - RcvDataBufferHdr->skb; - else - goto no_memory; - } - SXG_REINIATIALIZE_PACKET(RcvDataBufferHdr->SxgDumbRcvPacket); - RcvDataBufferHdr->State = SXG_BUFFER_ONCARD; - RcvDescriptorBlock->Descriptors[i].VirtualAddress = - (void *)RcvDataBufferHdr; - - RcvDescriptorBlock->Descriptors[i].PhysicalAddress = - RcvDataBufferHdr->PhysicalAddress; - } - /* Add the descriptor block to receive descriptor ring 0 */ - RingDescriptorCmd->Sgl = RcvDescriptorBlockHdr->PhysicalAddress; - - /* - * RcvBuffersOnCard is not protected via the receive lock (see - * sxg_process_event_queue) We don't want to grap a lock every time a - * buffer is returned to us, so we use atomic interlocked functions - * instead. - */ - adapter->RcvBuffersOnCard += SXG_RCV_DESCRIPTORS_PER_BLOCK; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DscBlk", - RcvDescriptorBlockHdr, - RingDescriptorCmd, RcvRingInfo->Head, RcvRingInfo->Tail); - - WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 1, true); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFilBlk", - adapter, adapter->RcvBuffersOnCard, - adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount); - return (STATUS_SUCCESS); -no_memory: - for (; i >= 0 ; i--) { - if (RcvDescriptorBlock->Descriptors[i].VirtualAddress) { - RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) - RcvDescriptorBlock->Descriptors[i]. - VirtualAddress; - RcvDescriptorBlock->Descriptors[i].PhysicalAddress = - (dma_addr_t)NULL; - RcvDescriptorBlock->Descriptors[i].VirtualAddress=NULL; - } - SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr); - } - RcvDescriptorBlockHdr->State = SXG_BUFFER_FREE; - SXG_RETURN_CMD(RingZero, RcvRingInfo, RingDescriptorCmd, - RcvDescriptorBlockHdr); - - return (-ENOMEM); -} - -/* - * sxg_stock_rcv_buffers - Stock the card with receive buffers - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * None - */ -static void sxg_stock_rcv_buffers(struct adapter_t *adapter) -{ - struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr; - int sxg_rcv_data_buffers = SXG_RCV_DATA_BUFFERS; - int sxg_min_rcv_data_buffers = SXG_MIN_RCV_DATA_BUFFERS; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "StockBuf", - adapter, adapter->RcvBuffersOnCard, - adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount); - /* - * First, see if we've got less than our minimum threshold of - * receive buffers, there isn't an allocation in progress, and - * we haven't exceeded our maximum.. get another block of buffers - * None of this needs to be SMP safe. It's round numbers. - */ - if (adapter->JumboEnabled == TRUE) - sxg_min_rcv_data_buffers = SXG_MIN_JUMBO_RCV_DATA_BUFFERS; - if ((adapter->FreeRcvBufferCount < sxg_min_rcv_data_buffers) && - (adapter->AllRcvBlockCount < SXG_MAX_RCV_BLOCKS) && - (atomic_read(&adapter->pending_allocations) == 0)) { - sxg_allocate_buffer_memory(adapter, - SXG_RCV_BLOCK_SIZE - (SXG_RCV_DATA_HDR_SIZE), - SXG_BUFFER_TYPE_RCV); - } - /* Now grab the RcvQLock lock and proceed */ - spin_lock(&adapter->RcvQLock); - if (adapter->JumboEnabled) - sxg_rcv_data_buffers = SXG_JUMBO_RCV_DATA_BUFFERS; - while (adapter->RcvBuffersOnCard < sxg_rcv_data_buffers) { - struct list_entry *_ple; - - /* Get a descriptor block */ - RcvDescriptorBlockHdr = NULL; - if (adapter->FreeRcvBlockCount) { - _ple = RemoveHeadList(&adapter->FreeRcvBlocks); - RcvDescriptorBlockHdr = - container_of(_ple, struct sxg_rcv_descriptor_block_hdr, - FreeList); - adapter->FreeRcvBlockCount--; - RcvDescriptorBlockHdr->State = SXG_BUFFER_BUSY; - } - - if (RcvDescriptorBlockHdr == NULL) { - /* Bail out.. */ - adapter->Stats.NoMem++; - break; - } - /* Fill in the descriptor block and give it to the card */ - if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) == - STATUS_FAILURE) { - /* Free the descriptor block */ - SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter, - RcvDescriptorBlockHdr); - break; - } - } - spin_unlock(&adapter->RcvQLock); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFilBlks", - adapter, adapter->RcvBuffersOnCard, - adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount); -} - -/* - * sxg_complete_descriptor_blocks - Return descriptor blocks that have been - * completed by the microcode - * - * Arguments - - * adapter - A pointer to our adapter structure - * Index - Where the microcode is up to - * - * Return - * None - */ -static void sxg_complete_descriptor_blocks(struct adapter_t *adapter, - unsigned char Index) -{ - struct sxg_rcv_ring *RingZero = &adapter->RcvRings[0]; - struct sxg_ring_info *RcvRingInfo = &adapter->RcvRingZeroInfo; - struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr; - struct sxg_cmd *RingDescriptorCmd; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlks", - adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail); - - /* Now grab the RcvQLock lock and proceed */ - spin_lock(&adapter->RcvQLock); - ASSERT(Index != RcvRingInfo->Tail); - while (sxg_ring_get_forward_diff(RcvRingInfo, Index, - RcvRingInfo->Tail) > 3) { - /* - * Locate the current Cmd (ring descriptor entry), and - * associated receive descriptor block, and advance - * the tail - */ - SXG_RETURN_CMD(RingZero, - RcvRingInfo, - RingDescriptorCmd, RcvDescriptorBlockHdr); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlk", - RcvRingInfo->Head, RcvRingInfo->Tail, - RingDescriptorCmd, RcvDescriptorBlockHdr); - - /* Clear the SGL field */ - RingDescriptorCmd->Sgl = 0; - /* - * Attempt to refill it and hand it right back to the - * card. If we fail to refill it, free the descriptor block - * header. The card will be restocked later via the - * RcvBuffersOnCard test - */ - if (sxg_fill_descriptor_block(adapter, - RcvDescriptorBlockHdr) == STATUS_FAILURE) - SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter, - RcvDescriptorBlockHdr); - } - spin_unlock(&adapter->RcvQLock); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XCRBlks", - adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail); -} - -/* - * Read the statistics which the card has been maintaining. - */ -void sxg_collect_statistics(struct adapter_t *adapter) -{ - if(adapter->ucode_stats) - WRITE_REG64(adapter, adapter->UcodeRegs[0].GetUcodeStats, - adapter->pucode_stats, 0); - adapter->stats.rx_fifo_errors = adapter->ucode_stats->ERDrops; - adapter->stats.rx_over_errors = adapter->ucode_stats->NBDrops; - adapter->stats.tx_fifo_errors = adapter->ucode_stats->XDrops; -} - -static struct net_device_stats *sxg_get_stats(struct net_device * dev) -{ - struct adapter_t *adapter = netdev_priv(dev); - - sxg_collect_statistics(adapter); - return (&adapter->stats); -} - -static void sxg_watchdog(unsigned long data) -{ - struct adapter_t *adapter = (struct adapter_t *) data; - - if (adapter->state != ADAPT_DOWN) { - sxg_link_event(adapter); - /* Reset the timer */ - mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ)); - } -} - -static void sxg_update_link_status (struct work_struct *work) -{ - struct adapter_t *adapter = (struct adapter_t *)container_of - (work, struct adapter_t, update_link_status); - if (likely(adapter->link_status_changed)) { - sxg_link_event(adapter); - adapter->link_status_changed = 0; - } -} - -static struct pci_driver sxg_driver = { - .name = sxg_driver_name, - .id_table = sxg_pci_tbl, - .probe = sxg_entry_probe, - .remove = __devexit_p(sxg_entry_remove), -#if SXG_POWER_MANAGEMENT_ENABLED - .suspend = sxgpm_suspend, - .resume = sxgpm_resume, -#endif - /* .shutdown = slic_shutdown, MOOK_INVESTIGATE */ -}; - -static int __init sxg_module_init(void) -{ - sxg_init_driver(); - - if (debug >= 0) - sxg_debug = debug; - - return pci_register_driver(&sxg_driver); -} - -static void __exit sxg_module_cleanup(void) -{ - pci_unregister_driver(&sxg_driver); -} - -module_init(sxg_module_init); -module_exit(sxg_module_cleanup); --- a/drivers/staging/sxg/sxgdbg.h +++ /dev/null @@ -1,184 +0,0 @@ -/************************************************************************** - * - * Copyright © 2000-2008 Alacritech, Inc. All rights reserved. - * - * $Id: sxgdbg.h,v 1.1 2008/06/27 12:49:28 mook Exp $ - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Alacritech, Inc. - * - **************************************************************************/ - -/* - * FILENAME: sxgdbg.h - * - * All debug and assertion-based definitions and macros are included - * in this file for the SXGOSS driver. - */ -#ifndef _SXG_DEBUG_H_ -#define _SXG_DEBUG_H_ - -#define ATKDBG 1 -#define ATK_TRACE_ENABLED 0 - -#define DBG_ERROR(n, args...) printk(KERN_WARNING n, ##args) - -#ifdef ASSERT -#undef ASSERT -#endif - -#define SXG_ASSERT_ENABLED -#ifdef SXG_ASSERT_ENABLED -#ifndef ASSERT -#define ASSERT(a) \ - { \ - if (!(a)) { \ - DBG_ERROR("ASSERT() Failure: file %s, function %s line %d\n", \ - __FILE__, __func__, __LINE__); \ - } \ - } -#endif -#else -#ifndef ASSERT -#define ASSERT(a) -#endif -#endif /* SXG_ASSERT_ENABLED */ - - -#ifdef ATKDBG -/* - * Global for timer granularity; every driver must have an instance - * of this initialized to 0 - */ - -extern ulong ATKTimerDiv; - -/* - * trace_entry - - * - * This structure defines an entry in the trace buffer. The - * first few fields mean the same from entry to entry, while - * the meaning of last several fields change to suit the - * needs of the trace entry. Typically they are function call - * parameters. - */ -struct trace_entry { - char name[8];/* 8 character name - like 's'i'm'b'a'r'c'v' */ - u32 time; /* Current clock tic */ - unsigned char cpu; /* Current CPU */ - unsigned char irql; /* Current IRQL */ - unsigned char driver;/* The driver which added the trace call */ - /* pad to 4 byte boundary - will probably get used */ - unsigned char pad2; - u32 arg1; /* Caller arg1 */ - u32 arg2; /* Caller arg2 */ - u32 arg3; /* Caller arg3 */ - u32 arg4; /* Caller arg4 */ -}; - -/* Driver types for driver field in struct trace_entry */ -#define TRACE_SXG 1 -#define TRACE_VPCI 2 -#define TRACE_SLIC 3 - -#define TRACE_ENTRIES 1024 - -struct sxg_trace_buffer { - /* aid for windbg extension */ - unsigned int size; - unsigned int in; /* Where to add */ - unsigned int level; /* Current Trace level */ - spinlock_t lock; /* For MP tracing */ - struct trace_entry entries[TRACE_ENTRIES];/* The circular buffer */ -}; - -/* - * The trace levels - * - * XXX At the moment I am only defining critical, important, and noisy. - * I am leaving room for more if anyone wants them. - */ -#define TRACE_NONE 0 /* For trace level - if no tracing wanted */ -#define TRACE_CRITICAL 1 /* minimal tracing - only critical stuff */ -#define TRACE_IMPORTANT 5 /* more tracing - anything important */ -#define TRACE_NOISY 10 /* Everything in the world */ - - -/* The macros themselves */ -#if ATK_TRACE_ENABLED -#define SXG_TRACE_INIT(buffer, tlevel) \ -{ \ - memset((buffer), 0, sizeof(struct sxg_trace_buffer)); \ - (buffer)->level = (tlevel); \ - (buffer)->size = TRACE_ENTRIES; \ - spin_lock_init(&(buffer)->lock); \ -} -#else -#define SXG_TRACE_INIT(buffer, tlevel) -#endif - -/*The trace macro. This is active only if ATK_TRACE_ENABLED is set. */ -#if ATK_TRACE_ENABLED -#define SXG_TRACE(tdriver, buffer, tlevel, tname, a1, a2, a3, a4) { \ - if ((buffer) && ((buffer)->level >= (tlevel))) { \ - unsigned int trace_irql = 0;/* ?????? FIX THIS */\ - unsigned int trace_len; \ - struct trace_entry *trace_entry; \ - struct timeval timev; \ - if(spin_trylock(&(buffer)->lock)) { \ - trace_entry = &(buffer)->entries[(buffer)->in]; \ - do_gettimeofday(&timev); \ - \ - memset(trace_entry->name, 0, 8); \ - trace_len = strlen(tname); \ - trace_len = trace_len > 8 ? 8 : trace_len; \ - memcpy(trace_entry->name, (tname), trace_len); \ - trace_entry->time = timev.tv_usec; \ - trace_entry->cpu = (unsigned char)(smp_processor_id() & 0xFF);\ - trace_entry->driver = (tdriver); \ - trace_entry->irql = trace_irql; \ - trace_entry->arg1 = (ulong)(a1); \ - trace_entry->arg2 = (ulong)(a2); \ - trace_entry->arg3 = (ulong)(a3); \ - trace_entry->arg4 = (ulong)(a4); \ - \ - (buffer)->in++; \ - if ((buffer)->in == TRACE_ENTRIES) \ - (buffer)->in = 0; \ - \ - spin_unlock(&(buffer)->lock); \ - } \ - } \ -} -#else -#define SXG_TRACE(tdriver, buffer, tlevel, tname, a1, a2, a3, a4) -#endif - -#endif - -#endif /* _SXG_DEBUG_H_ */ --- a/drivers/staging/sxg/sxg_ethtool.c +++ /dev/null @@ -1,328 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2000-2008 Alacritech, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Alacritech, Inc. - * - **************************************************************************/ - -/* - * FILENAME: sxg_ethtool.c - * - * The ethtool support for SXG driver for Alacritech's 10Gbe products. - * - * NOTE: This is the standard, non-accelerated version of Alacritech's - * IS-NIC driver. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sxg_os.h" -#include "sxghw.h" -#include "sxghif.h" -#include "sxg.h" - -struct sxg_nic_stats { - char stat_string[ETH_GSTRING_LEN]; - int sizeof_stat; - int stat_offset; -}; - -#define SXG_NIC_STATS(m) sizeof(((struct adapter_t *)0)->m), \ - offsetof(struct adapter_t, m) - -#define USER_VIEWABLE_EEPROM_SIZE 28 - -static struct sxg_nic_stats sxg_nic_gstrings_stats[] = { - {"xmit_ring_0_full", SXG_NIC_STATS(Stats.XmtZeroFull)}, - - /* May be will need in future */ -/* {"dumb_xmit_broadcast_packets", SXG_NIC_STATS(Stats.DumbXmtBcastPkts)}, - {"dumb_xmit_broadcast_bytes", SXG_NIC_STATS(Stats.DumbXmtBcastBytes)}, - {"dumb_xmit_unicast_packets", SXG_NIC_STATS(Stats.DumbXmtUcastPkts)}, - {"dumb_xmit_unicast_bytes", SXG_NIC_STATS(Stats.DumbXmtUcastBytes)}, -*/ - {"xmit_queue_length", SXG_NIC_STATS(Stats.XmtQLen)}, - {"memory_allocation_failure", SXG_NIC_STATS(Stats.NoMem)}, - {"Interrupts", SXG_NIC_STATS(Stats.NumInts)}, - {"false_interrupts", SXG_NIC_STATS(Stats.FalseInts)}, - {"processed_data_queue_full", SXG_NIC_STATS(Stats.PdqFull)}, - {"event_ring_full", SXG_NIC_STATS(Stats.EventRingFull)}, - {"transport_checksum_error", SXG_NIC_STATS(Stats.TransportCsum)}, - {"transport_underflow_error", SXG_NIC_STATS(Stats.TransportUflow)}, - {"transport_header_length_error", SXG_NIC_STATS(Stats.TransportHdrLen)}, - {"network_checksum_error", SXG_NIC_STATS(Stats.NetworkCsum)}, - {"network_underflow_error", SXG_NIC_STATS(Stats.NetworkUflow)}, - {"network_header_length_error", SXG_NIC_STATS(Stats.NetworkHdrLen)}, - {"receive_parity_error", SXG_NIC_STATS(Stats.Parity)}, - {"link_parity_error", SXG_NIC_STATS(Stats.LinkParity)}, - {"link/data early_error", SXG_NIC_STATS(Stats.LinkEarly)}, - {"buffer_overflow_error", SXG_NIC_STATS(Stats.LinkBufOflow)}, - {"link_code_error", SXG_NIC_STATS(Stats.LinkCode)}, - {"dribble nibble", SXG_NIC_STATS(Stats.LinkDribble)}, - {"CRC_error", SXG_NIC_STATS(Stats.LinkCrc)}, - {"link_overflow_error", SXG_NIC_STATS(Stats.LinkOflow)}, - {"link_underflow_error", SXG_NIC_STATS(Stats.LinkUflow)}, - - /* May be need in future */ -/* {"dumb_rcv_broadcast_packets", SXG_NIC_STATS(Stats.DumbRcvBcastPkts)}, - {"dumb_rcv_broadcast_bytes", SXG_NIC_STATS(Stats.DumbRcvBcastBytes)}, -*/ {"dumb_rcv_multicast_packets", SXG_NIC_STATS(Stats.DumbRcvMcastPkts)}, - {"dumb_rcv_multicast_bytes", SXG_NIC_STATS(Stats.DumbRcvMcastBytes)}, -/* {"dumb_rcv_unicast_packets", SXG_NIC_STATS(Stats.DumbRcvUcastPkts)}, - {"dumb_rcv_unicast_bytes", SXG_NIC_STATS(Stats.DumbRcvUcastBytes)}, -*/ - {"no_sgl_buffer", SXG_NIC_STATS(Stats.NoSglBuf)}, -}; - -#define SXG_NIC_STATS_LEN ARRAY_SIZE(sxg_nic_gstrings_stats) - -static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush) -{ - writel(value, reg); - if (flush) - mb(); -} - -static inline void sxg_reg64_write(struct adapter_t *adapter, void __iomem *reg, - u64 value, u32 cpu) -{ - u32 value_high = (u32) (value >> 32); - u32 value_low = (u32) (value & 0x00000000FFFFFFFF); - unsigned long flags; - - spin_lock_irqsave(&adapter->Bit64RegLock, flags); - writel(value_high, (void __iomem *)(&adapter->UcodeRegs[cpu].Upper)); - writel(value_low, reg); - spin_unlock_irqrestore(&adapter->Bit64RegLock, flags); -} - -static void -sxg_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) -{ - struct adapter_t *adapter = netdev_priv(dev); - strncpy(drvinfo->driver, sxg_driver_name, 32); - strncpy(drvinfo->version, SXG_DRV_VERSION, 32); -// strncpy(drvinfo->fw_version, SAHARA_UCODE_VERS_STRING, 32); - strncpy(drvinfo->bus_info, pci_name(adapter->pcidev), 32); - /* TODO : Read the major and minor number of firmware. Is this - * from the FLASH/EEPROM or download file ? - */ - /* LINSYS : Check if this is correct or if not find the right value - * Also check what is the right EEPROM length : EEPROM_SIZE_XFMR or EEPROM_SIZE_NO_XFMR - */ -} - -static int sxg_nic_set_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) -{ - /* No settings are applicable as we support only 10Gb/FIBRE_media */ - return -EOPNOTSUPP; -} - -static void -sxg_nic_get_strings(struct net_device *netdev, u32 stringset, u8 * data) -{ - int index; - - switch(stringset) { - case ETH_SS_TEST: - break; - case ETH_SS_STATS: - for (index = 0; index < SXG_NIC_STATS_LEN; index++) { - memcpy(data + index * ETH_GSTRING_LEN, - sxg_nic_gstrings_stats[index].stat_string, - ETH_GSTRING_LEN); - } - break; - } -} - -static void -sxg_nic_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, u64 * data) -{ - struct adapter_t *adapter = netdev_priv(netdev); - int index; - for (index = 0; index < SXG_NIC_STATS_LEN; index++) { - char *p = (char *)adapter + - sxg_nic_gstrings_stats[index].stat_offset; - data[index] = (sxg_nic_gstrings_stats[index].sizeof_stat == - sizeof(u64)) ? *(u64 *) p : *(u32 *) p; - } -} - -static int sxg_nic_get_sset_count(struct net_device *netdev, int sset) -{ - switch (sset) { - case ETH_SS_STATS: - return SXG_NIC_STATS_LEN; - default: - return -EOPNOTSUPP; - } -} - -static int sxg_nic_get_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) -{ - struct adapter_t *adapter = netdev_priv(netdev); - - ecmd->supported = SUPPORTED_10000baseT_Full; - ecmd->autoneg = AUTONEG_ENABLE; //VSS check This - ecmd->transceiver = XCVR_EXTERNAL; //VSS check This - - /* For Fibre Channel */ - ecmd->supported |= SUPPORTED_FIBRE; - ecmd->advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); - ecmd->port = PORT_FIBRE; - - - /* Link Speed */ - if(adapter->LinkState & SXG_LINK_UP) { - ecmd->speed = SPEED_10000; //adapter->LinkSpeed; - ecmd->duplex = DUPLEX_FULL; - } - return 0; -} - -static u32 sxg_nic_get_rx_csum(struct net_device *netdev) -{ - struct adapter_t *adapter = netdev_priv(netdev); - return ((adapter->flags & SXG_RCV_IP_CSUM_ENABLED) && - (adapter->flags & SXG_RCV_TCP_CSUM_ENABLED)); -} - -static int sxg_nic_set_rx_csum(struct net_device *netdev, u32 data) -{ - struct adapter_t *adapter = netdev_priv(netdev); - if (data) - adapter->flags |= SXG_RCV_IP_CSUM_ENABLED; - else - adapter->flags &= ~SXG_RCV_IP_CSUM_ENABLED; - /* - * We dont need to write to the card to do checksums. - * It does it anyways. - */ - return 0; -} - -static int sxg_nic_get_regs_len(struct net_device *dev) -{ - return (SXG_HWREG_MEMSIZE + SXG_UCODEREG_MEMSIZE); -} - -static void sxg_nic_get_regs(struct net_device *netdev, - struct ethtool_regs *regs, void *p) -{ - struct adapter_t *adapter = netdev_priv(netdev); - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - struct sxg_ucode_regs *UcodeRegs = adapter->UcodeRegs; - u32 *buff = p; - - memset(p, 0, (sizeof(struct sxg_hw_regs)+sizeof(struct sxg_ucode_regs))); - memcpy(buff, HwRegs, sizeof(struct sxg_hw_regs)); - memcpy((buff+sizeof(struct sxg_hw_regs)), UcodeRegs, sizeof(struct sxg_ucode_regs)); -} - -static int sxg_nic_get_eeprom_len(struct net_device *netdev) -{ - return (USER_VIEWABLE_EEPROM_SIZE); -} - -static int sxg_nic_get_eeprom(struct net_device *netdev, - struct ethtool_eeprom *eeprom, u8 *bytes) -{ - struct adapter_t *adapter = netdev_priv(netdev); - struct sw_cfg_data *data; - unsigned long i, status; - dma_addr_t p_addr; - - data = pci_alloc_consistent(adapter->pcidev, sizeof(struct sw_cfg_data), - &p_addr); - if(!data) { - /* - * We cant get even this much memory. Raise a hell - * Get out of here - */ - printk(KERN_ERR"%s : Could not allocate memory for reading \ - EEPROM\n", __func__); - return -ENOMEM; - } - - WRITE_REG(adapter->UcodeRegs[0].ConfigStat, SXG_CFG_TIMEOUT, TRUE); - WRITE_REG64(adapter, adapter->UcodeRegs[0].Config, p_addr, 0); - for(i=0; i<1000; i++) { - READ_REG(adapter->UcodeRegs[0].ConfigStat, status); - if (status != SXG_CFG_TIMEOUT) - break; - mdelay(1); /* Do we really need this */ - } - - memset(bytes, 0, eeprom->len); - memcpy(bytes, data->MacAddr[0].MacAddr, sizeof(struct sxg_config_mac)); - memcpy(bytes+6, data->AtkFru.PartNum, 6); - memcpy(bytes+12, data->AtkFru.Revision, 2); - memcpy(bytes+14, data->AtkFru.Serial, 14); - - return 0; -} - -const struct ethtool_ops sxg_nic_ethtool_ops = { - .get_settings = sxg_nic_get_settings, - .set_settings = sxg_nic_set_settings, - .get_drvinfo = sxg_nic_get_drvinfo, - .get_regs_len = sxg_nic_get_regs_len, - .get_regs = sxg_nic_get_regs, - .get_link = ethtool_op_get_link, -// .get_wol = sxg_nic_get_wol, - .get_eeprom_len = sxg_nic_get_eeprom_len, - .get_eeprom = sxg_nic_get_eeprom, -// .get_pauseparam = sxg_nic_get_pauseparam, -// .set_pauseparam = sxg_nic_set_pauseparam, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, -// .get_tso = sxg_nic_get_tso, -// .set_tso = sxg_nic_set_tso, -// .self_test = sxg_nic_diag_test, - .get_strings = sxg_nic_get_strings, - .get_ethtool_stats = sxg_nic_get_ethtool_stats, - .get_sset_count = sxg_nic_get_sset_count, - .get_rx_csum = sxg_nic_get_rx_csum, - .set_rx_csum = sxg_nic_set_rx_csum, -// .get_coalesce = sxg_nic_get_intr_coalesce, -// .set_coalesce = sxg_nic_set_intr_coalesce, -}; --- a/drivers/staging/sxg/sxg.h +++ /dev/null @@ -1,787 +0,0 @@ -/************************************************************************** - * - * Copyright © 2000-2008 Alacritech, Inc. All rights reserved. - * - * $Id: sxg.h,v 1.3 2008/07/24 17:25:08 chris Exp $ - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Alacritech, Inc. - * - **************************************************************************/ - -/* - * FILENAME: sxg.h - * - * This is the base set of header definitions for the SXG driver. - */ -#ifndef __SXG_DRIVER_H__ -#define __SXG_DRIVER_H__ - -#define SLIC_DUMP_ENABLED 0 - -#define SXG_DRV_NAME "sxg" /* TBD: This might be removed eventually */ -#define SXG_DRV_VERSION "1.0.1" - -extern char sxg_driver_name[]; - -#define SXG_NETDEV_WEIGHT 64 - -/* - * struct sxg_stats - Probably move these to someplace where - * the slicstat (sxgstat?) program can get them. - */ -struct sxg_stats { - /* Xmt */ - u64 DumbXmtUcastPkts; /* directed packets */ - u64 DumbXmtMcastPkts; /* Multicast packets */ - u64 DumbXmtBcastPkts; /* OID_GEN_BROADCAST_FRAMES_RCV */ - u64 DumbXmtUcastBytes; /* OID_GEN_DIRECTED_BYTES_XMIT */ - u64 DumbXmtMcastBytes; /* OID_GEN_MULTICAST_BYTES_XMIT */ - u64 DumbXmtBcastBytes; /* OID_GEN_BROADCAST_BYTES_XMIT */ - u64 XmtQLen; /* OID_GEN_TRANSMIT_QUEUE_LENGTH */ - u64 XmtZeroFull; /* Transmit ring zero full */ - /* Rcv */ - u64 DumbRcvUcastBytes; /* OID_GEN_DIRECTED_BYTES_RCV */ - u64 DumbRcvMcastBytes; /* OID_GEN_MULTICAST_BYTES_RCV */ - u64 DumbRcvBcastBytes; /* OID_GEN_BROADCAST_BYTES_RCV */ - u64 DumbRcvUcastPkts; /* directed packets */ - u64 DumbRcvMcastPkts; /* Multicast packets */ - u64 DumbRcvBcastPkts; /* OID_GEN_BROADCAST_FRAMES_RCV */ - u64 PdqFull; /* Processed Data Queue Full */ - u64 EventRingFull; /* Event ring full */ - /* Verbose stats */ - u64 NoSglBuf; /* SGL buffer allocation failure */ - u64 NoMem; /* Memory allocation failure */ - u64 NumInts; /* Interrupts */ - u64 FalseInts; /* Interrupt with ISR == 0 */ - /* Sahara receive status */ - u64 TransportCsum; /* SXG_RCV_STATUS_TRANSPORT_CSUM */ - u64 TransportUflow; /* SXG_RCV_STATUS_TRANSPORT_UFLOW */ - u64 TransportHdrLen; /* SXG_RCV_STATUS_TRANSPORT_HDRLEN */ - u64 NetworkCsum; /* SXG_RCV_STATUS_NETWORK_CSUM: */ - u64 NetworkUflow; /* SXG_RCV_STATUS_NETWORK_UFLOW: */ - u64 NetworkHdrLen; /* SXG_RCV_STATUS_NETWORK_HDRLEN: */ - u64 Parity; /* SXG_RCV_STATUS_PARITY */ - u64 LinkParity; /* SXG_RCV_STATUS_LINK_PARITY: */ - u64 LinkEarly; /* SXG_RCV_STATUS_LINK_EARLY: */ - u64 LinkBufOflow; /* SXG_RCV_STATUS_LINK_BUFOFLOW: */ - u64 LinkCode; /* SXG_RCV_STATUS_LINK_CODE: */ - u64 LinkDribble; /* SXG_RCV_STATUS_LINK_DRIBBLE: */ - u64 LinkCrc; /* SXG_RCV_STATUS_LINK_CRC: */ - u64 LinkOflow; /* SXG_RCV_STATUS_LINK_OFLOW: */ - u64 LinkUflow; /* SXG_RCV_STATUS_LINK_UFLOW: */ -}; - - -/* DUMB-NIC Send path definitions */ - -#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb, _phys_addr, _size) { \ - ASSERT(_skb); \ - pci_unmap_single(_pAdapt->pcidev, _size, _phys_addr, PCI_DMA_TODEVICE); \ - dev_kfree_skb_irq(_skb); \ -} - -#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) { \ - ASSERT(_skb); \ -} - -/* - * Locate current receive header buffer location. Use this - * instead of RcvDataHdr->VirtualAddress since the data - * may have been offset by SXG_ADVANCE_MDL_OFFSET - */ -#define SXG_RECEIVE_DATA_LOCATION(_RcvDataHdr) (_RcvDataHdr)->skb->data - -/* Dumb-NIC receive processing */ -/* Define an SXG_PACKET as an NDIS_PACKET */ -#define PSXG_PACKET struct sk_buff * -/* Indications array size */ -#define SXG_RCV_ARRAYSIZE 64 - -#define SXG_ALLOCATE_RCV_PACKET(_pAdapt, _RcvDataBufferHdr, BufferSize) {\ - struct sk_buff * skb; \ - skb = netdev_alloc_skb(_pAdapt->netdev, BufferSize); \ - if (skb) { \ - (_RcvDataBufferHdr)->skb = skb; \ - skb->next = NULL; \ - _RcvDataBufferHdr->PhysicalAddress = pci_map_single(adapter->pcidev,\ - _RcvDataBufferHdr->skb->data, BufferSize, PCI_DMA_FROMDEVICE); \ - if (SXG_INVALID_SGL(_RcvDataBufferHdr->PhysicalAddress,BufferSize)) \ - printk(KERN_EMERG "SXG_ALLOCATE_RCV_PACKET: RCV packet" \ - "non-64k boundary aligned\n"); \ - } else { \ - (_RcvDataBufferHdr)->skb = NULL; \ - } \ -} - -#define SXG_FREE_RCV_PACKET(_RcvDataBufferHdr) { \ - if((_RcvDataBufferHdr)->skb) { \ - dev_kfree_skb((_RcvDataBufferHdr)->skb); \ - } \ -} - -/* - * Macro to add a NDIS_PACKET to an indication array - * If we fill up our array of packet pointers, then indicate this - * block up now and start on a new one. - */ -#define SXG_ADD_RCV_PACKET(_pAdapt, _Packet, _PrevPacket, _IndicationList, \ - _NumPackets) { \ - (_IndicationList)[_NumPackets] = (_Packet); \ - (_NumPackets)++; \ - if((_NumPackets) == SXG_RCV_ARRAYSIZE) { \ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv", \ - (_NumPackets), 0, 0, 0); \ - netif_rx((_IndicationList),(_NumPackets)); \ - (_NumPackets) = 0; \ - } \ -} - -#define SXG_INDICATE_PACKETS(_pAdapt, _IndicationList, _NumPackets) { \ - if(_NumPackets) { \ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv", \ - (_NumPackets), 0, 0, 0); \ - netif_rx((_IndicationList),(_NumPackets)); \ - (_NumPackets) = 0; \ - } \ -} - -#define SXG_REINIATIALIZE_PACKET(_Packet) \ - {} /*_NdisReinitializePacket(_Packet)*/ - /* this is not necessary with an skb */ - -/* Definitions to initialize Dumb-nic Receive NBLs */ -#define SXG_RCV_PACKET_BUFFER_HDR(_Packet) (((struct sxg_rcv_nbl_reserved *)\ - ((_Packet)->MiniportReservedEx))->RcvDataBufferHdr) - -#define SXG_RCV_SET_CHECKSUM_INFO(_Packet, _Cpi) \ - NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), \ - TcpIpChecksumPacketInfo) = (PVOID)(_Cpi) - -#define SXG_RCV_SET_TOEPLITZ(_Packet, _Toeplitz, _Type, _Function) { \ - NDIS_PACKET_SET_HASH_VALUE((_Packet), (_Toeplitz)); \ - NDIS_PACKET_SET_HASH_TYPE((_Packet), (_Type)); \ - NDIS_PACKET_SET_HASH_FUNCTION((_Packet), (_Function)); \ -} - -#define SXG_RCV_SET_VLAN_INFO(_Packet, _VlanId, _Priority) { \ - NDIS_PACKET_8021Q_INFO _Packet8021qInfo; \ - _Packet8021qInfo.TagHeader.VlanId = (_VlanId); \ - _Packet8021qInfo.TagHeader.UserPriority = (_Priority); \ - NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), Ieee8021QNetBufferListInfo) = \ - _Packet8021qInfo.Value; \ -} - -#define SXG_ADJUST_RCV_PACKET(_Packet, _RcvDataBufferHdr, _Event) { \ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbRcv", \ - (_RcvDataBufferHdr), (_Packet), \ - (_Event)->Status, 0); \ - /* ASSERT((_Event)->Length <= (_RcvDataBufferHdr)->Size); */ \ - skb_put(Packet, (_Event)->Length); \ -} - -/* - * Macros to free a receive data buffer and receive data descriptor block - * NOTE - Lock must be held with RCV macros - */ -#define SXG_GET_RCV_DATA_BUFFER(_pAdapt, _Hdr) { \ - struct list_entry *_ple; \ - _Hdr = NULL; \ - if((_pAdapt)->FreeRcvBufferCount) { \ - ASSERT(!(IsListEmpty(&(_pAdapt)->FreeRcvBuffers))); \ - _ple = RemoveHeadList(&(_pAdapt)->FreeRcvBuffers); \ - (_Hdr) = container_of(_ple, struct sxg_rcv_data_buffer_hdr, \ - FreeList); \ - (_pAdapt)->FreeRcvBufferCount--; \ - ASSERT((_Hdr)->State == SXG_BUFFER_FREE); \ - } \ -} - -#define SXG_FREE_RCV_DATA_BUFFER(_pAdapt, _Hdr) { \ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RtnDHdr", \ - (_Hdr), (_pAdapt)->FreeRcvBufferCount, \ - (_Hdr)->State, 0/*(_Hdr)->VirtualAddress*/); \ -/* SXG_RESTORE_MDL_OFFSET(_Hdr); */ \ - (_pAdapt)->FreeRcvBufferCount++; \ - ASSERT(((_pAdapt)->AllRcvBlockCount * SXG_RCV_DESCRIPTORS_PER_BLOCK) \ - >= (_pAdapt)->FreeRcvBufferCount); \ - ASSERT((_Hdr)->State != SXG_BUFFER_FREE); \ - (_Hdr)->State = SXG_BUFFER_FREE; \ - InsertTailList(&(_pAdapt)->FreeRcvBuffers, &((_Hdr)->FreeList)); \ -} - -#define SXG_FREE_RCV_DESCRIPTOR_BLOCK(_pAdapt, _Hdr) { \ - ASSERT((_Hdr)->State != SXG_BUFFER_FREE); \ - (_Hdr)->State = SXG_BUFFER_FREE; \ - (_pAdapt)->FreeRcvBlockCount++; \ - ASSERT((_pAdapt)->AllRcvBlockCount >= (_pAdapt)->FreeRcvBlockCount); \ - InsertTailList(&(_pAdapt)->FreeRcvBlocks, &(_Hdr)->FreeList); \ -} - -/* SGL macros */ -#define SXG_FREE_SGL_BUFFER(_pAdapt, _Sgl, _NB) { \ - spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \ - (_pAdapt)->FreeSglBufferCount++; \ - ASSERT((_pAdapt)->AllSglBufferCount >= (_pAdapt)->FreeSglBufferCount); \ - ASSERT(!((_Sgl)->State & SXG_BUFFER_FREE)); \ - (_Sgl)->State = SXG_BUFFER_FREE; \ - InsertTailList(&(_pAdapt)->FreeSglBuffers, &(_Sgl)->FreeList); \ - spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags); \ -} - -/* - * Get an SGL buffer from the free queue. The first part of this macro - * attempts to keep ahead of buffer depletion by allocating more when - * we hit a minimum threshold. Note that we don't grab the lock - * until after that. We're dealing with round numbers here, so we don't need to, - * and not grabbing it avoids a possible double-trip. - */ -#define SXG_GET_SGL_BUFFER(_pAdapt, _Sgl, _irq) { \ - struct list_entry *_ple; \ - if ((_pAdapt->FreeSglBufferCount < SXG_MIN_SGL_BUFFERS) && \ - (_pAdapt->AllSglBufferCount < SXG_MAX_SGL_BUFFERS) && \ - (atomic_read(&_pAdapt->pending_allocations) == 0)) { \ - sxg_allocate_buffer_memory(_pAdapt, \ - (sizeof(struct sxg_scatter_gather) + SXG_SGL_BUF_SIZE),\ - SXG_BUFFER_TYPE_SGL); \ - } \ - _Sgl = NULL; \ - if(!_irq) \ - spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \ - else \ - spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \ - if((_pAdapt)->FreeSglBufferCount) { \ - ASSERT(!(IsListEmpty(&(_pAdapt)->FreeSglBuffers))); \ - _ple = RemoveHeadList(&(_pAdapt)->FreeSglBuffers); \ - (_Sgl) = container_of(_ple, struct sxg_scatter_gather, \ - FreeList); \ - (_pAdapt)->FreeSglBufferCount--; \ - ASSERT((_Sgl)->State == SXG_BUFFER_FREE); \ - (_Sgl)->State = SXG_BUFFER_BUSY; \ - (_Sgl)->pSgl = NULL; \ - } \ - if(!_irq) \ - spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\ - else \ - spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\ -} - -/* - * struct sxg_multicast_address - * Linked list of multicast addresses. - */ -struct sxg_multicast_address { - unsigned char Address[6]; - struct sxg_multicast_address *Next; -}; - -/* - * Structure to maintain chimney send and receive buffer queues. - * This structure maintains NET_BUFFER_LIST queues that are - * given to us via the Chimney MiniportTcpOffloadSend and - * MiniportTcpOffloadReceive routines. This structure DOES NOT - * manage our data buffer queue - */ -struct sxg_buffer_queue { - u32 Type; /* Slow or fast - See below */ - u32 Direction; /* Xmt or Rcv */ - u32 Bytes; /* Byte count */ - u32 * Head; /* Send queue head */ - u32 * Tail; /* Send queue tail */ -/* PNET_BUFFER_LIST NextNBL;*/ /* Short cut - next NBL */ -/* PNET_BUFFER NextNB; */ /* Short cut - next NB */ -}; - -#define SXG_SLOW_SEND_BUFFER 0 -#define SXG_FAST_SEND_BUFFER 1 -#define SXG_RECEIVE_BUFFER 2 - -#define SXG_INIT_BUFFER(_Buffer, _Type) { \ - (_Buffer)->Type = (_Type); \ - if((_Type) == SXG_RECEIVE_BUFFER) { \ - (_Buffer)->Direction = 0; \ - } else { \ - (_Buffer)->Direction = NDIS_SG_LIST_WRITE_TO_DEVICE; \ - } \ - (_Buffer)->Bytes = 0; \ - (_Buffer)->Head = NULL; \ - (_Buffer)->Tail = NULL; \ -} - - -#define SXG_RSS_CPU_COUNT(_pAdapt) \ - ((_pAdapt)->RssEnabled ? NR_CPUS : 1) - -/* DRIVER and ADAPTER structures */ - -/* - * Adapter states - These states closely match the adapter states - * documented in the DDK (with a few exceptions). - */ -enum SXG_STATE { - SXG_STATE_INITIALIZING, /* Initializing */ - SXG_STATE_BOOTDIAG, /* Boot-Diagnostic mode */ - SXG_STATE_PAUSING, /* Pausing */ - SXG_STATE_PAUSED, /* Paused */ - SXG_STATE_RUNNING, /* Running */ - SXG_STATE_RESETTING, /* Reset in progress */ - SXG_STATE_SLEEP, /* Sleeping */ - SXG_STATE_DIAG, /* Diagnostic mode */ - SXG_STATE_HALTING, /* Halting */ - SXG_STATE_HALTED, /* Down or not-initialized */ - SXG_STATE_SHUTDOWN /* shutdown */ -}; - -/* Link state */ -enum SXG_LINK_STATE { - SXG_LINK_DOWN, - SXG_LINK_UP -}; - -/* Link initialization timeout in 100us units */ -#define SXG_LINK_TIMEOUT 100000 /* 10 Seconds - REDUCE! */ - - -/* Microcode file selection codes */ -enum SXG_UCODE_SEL { - SXG_UCODE_SYSTEM, /* System (operational) uucode */ - SXG_UCODE_SDIAGCPU, /* System CPU diagnostic ucode */ - SXG_UCODE_SDIAGSYS /* System diagnostic ucode */ -}; - - -#define SXG_DISABLE_ALL_INTERRUPTS(_padapt) sxg_disable_interrupt(_padapt) -#define SXG_ENABLE_ALL_INTERRUPTS(_padapt) sxg_enable_interrupt(_padapt) - -/* This probably lives in a proto.h file. Move later */ -#define SXG_MULTICAST_PACKET(_pether) ((_pether)->ether_dhost[0] & 0x01) -#define SXG_BROADCAST_PACKET(_pether) \ - ((*(u32 *)(_pether)->ether_dhost == 0xFFFFFFFF) && \ - (*(u16 *)&(_pether)->ether_dhost[4] == 0xFFFF)) - -/* For DbgPrints */ -#define SXG_ID DPFLTR_IHVNETWORK_ID -#define SXG_ERROR DPFLTR_ERROR_LEVEL - -/* - * struct sxg_driver structure - - * - * contains information about the sxg driver. There is only - * one of these, and it is defined as a global. - */ - -struct sxg_driver { - struct adapter_t *Adapters; /* Linked list of adapters */ - ushort AdapterID; /* Maintain unique adapter ID */ -}; - -#ifdef STATUS_SUCCESS -#undef STATUS_SUCCESS -#endif - -/* TODO: We need to try and use NETDEV_TX_* before posting this out */ -#define STATUS_SUCCESS 0 -#define STATUS_PENDING 0 -#define STATUS_FAILURE -1 -#define STATUS_ERROR -2 -#define STATUS_NOT_SUPPORTED -3 -#define STATUS_BUFFER_TOO_SHORT -4 -#define STATUS_RESOURCES -5 - -#define SLIC_MAX_CARDS 32 -#define SLIC_MAX_PORTS 4 /* Max # of ports per card */ -#if SLIC_DUMP_ENABLED - -/* - * Dump buffer size - * This cannot be bigger than the max DMA size the card supports, - * given the current code structure in the host and ucode. - * Mojave supports 16K, Oasis supports 16K-1, so - * just set this at 15K, shouldnt make that much of a diff. - */ -#define DUMP_BUF_SIZE 0x3C00 -#endif - -#define MIN(a, b) ((u32)(a) < (u32)(b) ? (a) : (b)) -#define MAX(a, b) ((u32)(a) > (u32)(b) ? (a) : (b)) - -struct mcast_address { - unsigned char address[6]; - struct mcast_address *next; -}; - -#define CARD_DOWN 0x00000000 -#define CARD_UP 0x00000001 -#define CARD_FAIL 0x00000002 -#define CARD_DIAG 0x00000003 -#define CARD_SLEEP 0x00000004 - -#define ADAPT_DOWN 0x00 -#define ADAPT_UP 0x01 -#define ADAPT_FAIL 0x02 -#define ADAPT_RESET 0x03 -#define ADAPT_SLEEP 0x04 - -#define ADAPT_FLAGS_BOOTTIME 0x0001 -#define ADAPT_FLAGS_IS64BIT 0x0002 -#define ADAPT_FLAGS_PENDINGLINKDOWN 0x0004 -#define ADAPT_FLAGS_FIBERMEDIA 0x0008 -#define ADAPT_FLAGS_LOCKS_ALLOCED 0x0010 -#define ADAPT_FLAGS_INT_REGISTERED 0x0020 -#define ADAPT_FLAGS_LOAD_TIMER_SET 0x0040 -#define ADAPT_FLAGS_STATS_TIMER_SET 0x0080 -#define ADAPT_FLAGS_RESET_TIMER_SET 0x0100 - -#define LINK_DOWN 0x00 -#define LINK_CONFIG 0x01 -#define LINK_UP 0x02 - -#define LINK_10MB 0x00 -#define LINK_100MB 0x01 -#define LINK_AUTOSPEED 0x02 -#define LINK_1000MB 0x03 -#define LINK_10000MB 0x04 - -#define LINK_HALFD 0x00 -#define LINK_FULLD 0x01 -#define LINK_AUTOD 0x02 - -#define MAC_DIRECTED 0x00000001 -#define MAC_BCAST 0x00000002 -#define MAC_MCAST 0x00000004 -#define MAC_PROMISC 0x00000008 -#define MAC_LOOPBACK 0x00000010 -#define MAC_ALLMCAST 0x00000020 - -#define SLIC_DUPLEX(x) ((x==LINK_FULLD) ? "FDX" : "HDX") -#define SLIC_SPEED(x) ((x==LINK_100MB) ? "100Mb" : \ - ((x==LINK_1000MB) ? "1000Mb" : " 10Mb")) -#define SLIC_LINKSTATE(x) ((x==LINK_DOWN) ? "Down" : "Up ") -#define SLIC_ADAPTER_STATE(x) ((x==ADAPT_UP) ? "UP" : "Down") -#define SLIC_CARD_STATE(x) ((x==CARD_UP) ? "UP" : "Down") - - -struct ether_header { - unsigned char ether_dhost[6]; - unsigned char ether_shost[6]; - ushort ether_type; -}; - - -#define NUM_CFG_SPACES 2 -#define NUM_CFG_REGS 64 - -/* - * We split LSS sends across four microcode queues derived from - * destination TCP port (if TCP/IP). - */ -#define SXG_LARGE_SEND_QUEUE_MASK 0x3 -#define ISCSI_PORT 0xbc0c /* 3260 */ - -struct physcard { - struct adapter_t *adapter[SLIC_MAX_PORTS]; - struct physcard *next; - unsigned int adapters_allocd; -}; - -struct sxgbase_driver { - spinlock_t driver_lock; - unsigned long flags; /* irqsave for spinlock */ - u32 num_sxg_cards; - u32 num_sxg_ports; - u32 num_sxg_ports_active; - u32 dynamic_intagg; - struct physcard *phys_card; -}; - - -struct adapter_t { - void * ifp; - unsigned int port; - struct napi_struct napi; - struct physcard *physcard; - unsigned int physport; - unsigned int slotnumber; - unsigned int functionnumber; - ushort vendid; - ushort devid; - ushort subsysid; - u32 irq; - - void __iomem * base_addr; - u32 memorylength; - u32 drambase; - u32 dramlength; - enum asic_type asictype; /* type of ASIC (chip) */ - unsigned int activated; - u32 intrregistered; - unsigned int isp_initialized; - unsigned char state; - unsigned char linkstate; - unsigned int flags; - unsigned char macaddr[6]; - unsigned char currmacaddr[6]; - u32 macopts; - ushort devflags_prev; - u64 mcastmask; - struct mcast_address *mcastaddrs; - struct timer_list pingtimer; - u32 pingtimerset; - struct timer_list statstimer; - u32 statstimerset; - struct timer_list vpci_timer; - u32 vpci_timerset; - struct timer_list loadtimer; - u32 loadtimerset; - - u32 xmitq_full; - u32 all_reg_writes; - u32 icr_reg_writes; - u32 isr_reg_writes; - u32 error_interrupts; - u32 error_rmiss_interrupts; - u32 rx_errors; - u32 rcv_drops; - u32 rcv_interrupts; - u32 xmit_interrupts; - u32 linkevent_interrupts; - u32 upr_interrupts; - u32 num_isrs; - u32 false_interrupts; - u32 tx_packets; - u32 xmit_completes; - u32 tx_drops; - u32 rcv_broadcasts; - u32 rcv_multicasts; - u32 rcv_unicasts; - u32 max_isr_rcvs; - u32 max_isr_xmits; - u32 rcv_interrupt_yields; - u32 intagg_period; - struct net_device_stats stats; - u32 * MiniportHandle; /* Our miniport handle */ - enum SXG_STATE State; /* Adapter state */ - enum SXG_LINK_STATE LinkState; /* Link state */ - u64 LinkSpeed; /* Link Speed */ - u32 PowerState; /* NDIS power state */ - struct adapter_t *Next; /* Linked list */ - ushort AdapterID; /* 1..n */ - struct net_device * netdev; - struct net_device * next_netdevice; - struct pci_dev *pcidev; - - struct sxg_multicast_address *MulticastAddrs; /* Multicast list */ - u64 MulticastMask; /* Multicast mask */ - u32 *InterruptHandle; /* Register Interrupt handle */ - u32 InterruptLevel; /* From Resource list */ - u32 InterruptVector; /* From Resource list */ - spinlock_t AdapterLock; /* Serialize access adapter routines */ - spinlock_t Bit64RegLock; /* For writing 64-bit addresses */ - struct sxg_hw_regs *HwRegs; /* Sahara HW Register Memory (BAR0/1) */ - struct sxg_ucode_regs *UcodeRegs; /* Microcode Register Memory (BAR2/3) */ - struct sxg_tcb_regs *TcbRegs; /* Same as Ucode regs - See sxghw.h */ - ushort FrameSize; /* Maximum frame size */ - u32 * DmaHandle; /* NDIS DMA handle */ - u32 * PacketPoolHandle; /* Used with NDIS 5.2 only. Don't ifdef out */ - u32 * BufferPoolHandle; /* Used with NDIS 5.2 only. Don't ifdef out */ - u32 MacFilter; /* NDIS MAC Filter */ - struct sxg_event_ring *EventRings; /* Host event rings. 1/CPU to 16 max */ - dma_addr_t PEventRings; /* Physical address */ - u32 NextEvent[SXG_MAX_RSS]; /* Current location in ring */ - dma_addr_t PTcbBuffers; /* TCB Buffers - physical address */ - dma_addr_t PTcbCompBuffers; /* TCB Composite Buffers - phys addr */ - struct sxg_xmt_ring *XmtRings; /* Transmit rings */ - dma_addr_t PXmtRings; /* Transmit rings - physical address */ - struct sxg_ring_info XmtRingZeroInfo; /* Transmit ring 0 info */ - - spinlock_t XmtZeroLock; /* Transmit ring 0 lock */ - u32 * XmtRingZeroIndex; /* Shared XMT ring 0 index */ - dma_addr_t PXmtRingZeroIndex; /* Shared XMT ring 0 index - physical */ - struct list_entry FreeProtocolHeaders;/* Free protocol headers */ - u32 FreeProtoHdrCount; /* Count */ - void * ProtocolHeaders; /* Block of protocol header */ - dma_addr_t PProtocolHeaders; /* Block of protocol headers - phys */ - - struct sxg_rcv_ring *RcvRings; /* Receive rings */ - dma_addr_t PRcvRings; /* Receive rings - physical address */ - struct sxg_ucode_stats *ucode_stats; /* Ucode Stats */ - /* Ucode Stats - physical address */ - dma_addr_t pucode_stats; - - struct sxg_ring_info RcvRingZeroInfo; /* Receive ring 0 info */ - - u32 * Isr; /* Interrupt status register */ - dma_addr_t PIsr; /* ISR - physical address */ - u32 IsrCopy[SXG_MAX_RSS]; /* Copy of ISR */ - ushort InterruptsEnabled; /* Bitmask of enabled vectors */ - unsigned char *IndirectionTable; /* RSS indirection table */ - dma_addr_t PIndirectionTable; /* Physical address */ - ushort RssTableSize; /* From NDIS_RECEIVE_SCALE_PARAMETERS */ - ushort HashKeySize; /* From NDIS_RECEIVE_SCALE_PARAMETERS */ - unsigned char HashSecretKey[40]; /* rss key */ - u32 HashInformation; - /* Receive buffer queues */ - spinlock_t RcvQLock; /* Receive Queue Lock */ - struct list_entry FreeRcvBuffers; /* Free SXG_DATA_BUFFER queue */ - struct list_entry FreeRcvBlocks; /* Free SXG_RCV_DESCRIPTOR_BLOCK Q */ - struct list_entry AllRcvBlocks; /* All SXG_RCV_BLOCKs */ - ushort FreeRcvBufferCount; /* Number of free rcv data buffers */ - ushort FreeRcvBlockCount; /* # of free rcv descriptor blocks */ - ushort AllRcvBlockCount; /* Number of total receive blocks */ - ushort ReceiveBufferSize; /* SXG_RCV_DATA/JUMBO_BUFFER_SIZE only */ - /* Converted this to a atomic variable - u32 AllocationsPending; */ - atomic_t pending_allocations; - u32 AllocationsPending; /* Receive allocation pending */ - u32 RcvBuffersOnCard; /* SXG_DATA_BUFFERS owned by card */ - /* SGL buffers */ - spinlock_t SglQLock; /* SGL Queue Lock */ - struct list_entry FreeSglBuffers; /* Free struct sxg_scatter_gather */ - struct list_entry AllSglBuffers; /* All struct sxg_scatter_gather */ - ushort FreeSglBufferCount; /* Number of free SGL buffers */ - ushort AllSglBufferCount; /* Number of total SGL buffers */ - u32 CurrentTime; /* Tick count */ - u32 FastpathConnections;/* # of fastpath connections */ - /* Various single-bit flags: */ - u32 BasicAllocations:1; /* Locks and listheads */ - u32 IntRegistered:1; /* Interrupt registered */ - u32 PingOutstanding:1; /* Ping outstanding to card */ - u32 Dead:1; /* Card dead */ - u32 DumpDriver:1; /* OID_SLIC_DRIVER_DUMP request */ - u32 DumpCard:1; /* OID_SLIC_CARD_DUMP request */ - u32 DumpCmdRunning:1; /* Dump command in progress */ - u32 DebugRunning:1; /* AGDB debug in progress */ - u32 JumboEnabled:1; /* Jumbo frames enabled */ - u32 msi_enabled:1; /* MSI interrupt enabled */ - u32 RssEnabled:1; /* RSS Enabled */ - u32 FailOnBadEeprom:1; /* Fail on Bad Eeprom */ - u32 DiagStart:1; /* Init adapter for diagnostic start */ - u32 XmtFcEnabled:1; - u32 RcvFcEnabled:1; - /* Stats */ - u32 PendingRcvCount; /* Outstanding rcv indications */ - u32 PendingXmtCount; /* Outstanding send requests */ - struct sxg_stats Stats; /* Statistics */ - u32 ReassBufs; /* Number of reassembly buffers */ - /* Card Crash Info */ - ushort CrashLocation; /* Microcode crash location */ - unsigned char CrashCpu; /* Sahara CPU ID */ - /* Diagnostics */ - /* PDIAG_CMD DiagCmds; */ /* List of free diagnostic commands */ - /* PDIAG_BUFFER DiagBuffers; */ /* List of free diagnostic buffers */ - /* PDIAG_REQ DiagReqQ; */ /* List of outstanding (asynchronous) diag requests */ - /* u32 DiagCmdTimeout; */ /* Time out for diag cmds (seconds) XXXTODO - replace with SXG_PARAM var? */ - /* unsigned char DiagDmaDesc[DMA_CPU_CTXS]; */ /* Free DMA descriptors bit field (32 CPU ctx * 8 DMA ctx) */ - /* - * Put preprocessor-conditional fields at the end so we don't - * have to recompile sxgdbg everytime we reconfigure the driver - */ -#if defined(CONFIG_X86) - u32 AddrUpper; /* Upper 32 bits of 64-bit register */ -#endif - unsigned short max_aggregation; - unsigned short min_aggregation; - /*#if SXG_FAILURE_DUMP */ - /* NDIS_EVENT DumpThreadEvent; */ /* syncronize dump thread */ - /* BOOLEAN DumpThreadRunning; */ /* termination flag */ - /* PSXG_DUMP_CMD DumpBuffer; */ /* 68k - Cmd and Buffer */ - /* dma_addr_t PDumpBuffer; */ /* Physical address */ - /*#endif */ /* SXG_FAILURE_DUMP */ - /*MSI-X related data elements*/ - u32 nr_msix_entries; - struct msix_entry *msi_entries; - struct timer_list watchdog_timer; - struct work_struct update_link_status; - u32 link_status_changed; -}; - -#if SLIC_DUMP_ENABLED -#define SLIC_DUMP_REQUESTED 1 -#define SLIC_DUMP_IN_PROGRESS 2 -#define SLIC_DUMP_DONE 3 - -/* - * Microcode crash information structure. This - * structure is written out to the card's SRAM when the microcode panic's. - */ -struct slic_crash_info { - ushort cpu_id; - ushort crash_pc; -}; - -#define CRASH_INFO_OFFSET 0x155C - -#endif - -#define UPDATE_STATS(largestat, newstat, oldstat) \ -{ \ - if ((newstat) < (oldstat)) \ - (largestat) += ((newstat) + (0xFFFFFFFF - oldstat + 1)); \ - else \ - (largestat) += ((newstat) - (oldstat)); \ -} - -#define UPDATE_STATS_GB(largestat, newstat, oldstat) \ -{ \ - (largestat) += ((newstat) - (oldstat)); \ -} - -#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \ -{ \ - _Result = TRUE; \ - if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \ - _Result = FALSE; \ - if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \ - _Result = FALSE; \ -} - -#define ETHERMAXFRAME 1514 -#define JUMBOMAXFRAME 9014 - -#define SXG_JUMBO_MTU 9000 -#define SXG_DEFAULT_MTU 1500 - -#if defined(CONFIG_X86_64) || defined(CONFIG_IA64) -#define SXG_GET_ADDR_LOW(_addr) (u32)((u64)(_addr) & 0x00000000FFFFFFFF) -#define SXG_GET_ADDR_HIGH(_addr) \ - (u32)(((u64)(_addr) >> 32) & 0x00000000FFFFFFFF) -#else -#define SXG_GET_ADDR_LOW(_addr) (u32)_addr -#define SXG_GET_ADDR_HIGH(_addr) (u32)0 -#endif - -#define FLUSH TRUE -#define DONT_FLUSH FALSE - -#define SIOCSLICDUMPCARD (SIOCDEVPRIVATE+9) -#define SIOCSLICSETINTAGG (SIOCDEVPRIVATE+10) -#define SIOCSLICTRACEDUMP (SIOCDEVPRIVATE+11) - -extern const struct ethtool_ops sxg_nic_ethtool_ops; -#define SXG_COMPLETE_SLOW_SEND_LIMIT 128 -#endif /* __SXG_DRIVER_H__ */ --- a/drivers/staging/sxg/sxghif.h +++ /dev/null @@ -1,1014 +0,0 @@ -/******************************************************************* - * Copyright © 1997-2007 Alacritech, Inc. All rights reserved - * - * $Id: sxghif.h,v 1.5 2008/07/24 19:18:22 chris Exp $ - * - * sxghif.h: - * - * This file contains structures and definitions for the - * Alacritech Sahara host interface - ******************************************************************/ - -#define DBG 1 - -/* UCODE Registers */ -struct sxg_ucode_regs { - /* Address 0 - 0x3F = Command codes 0-15 for TCB 0. Excode 0 */ - u32 Icr; /* Code = 0 (extended), ExCode = 0 - Int control */ - u32 RsvdReg1; /* Code = 1 - TOE -NA */ - u32 RsvdReg2; /* Code = 2 - TOE -NA */ - u32 RsvdReg3; /* Code = 3 - TOE -NA */ - u32 RsvdReg4; /* Code = 4 - TOE -NA */ - u32 RsvdReg5; /* Code = 5 - TOE -NA */ - u32 CardUp; /* Code = 6 - Microcode initialized when 1 */ - u32 RsvdReg7; /* Code = 7 - TOE -NA */ - u32 ConfigStat; /* Code = 8 - Configuration data load status */ - u32 RsvdReg9; /* Code = 9 - TOE -NA */ - u32 CodeNotUsed[6]; /* Codes 10-15 not used. ExCode = 0 */ - /* This brings us to ExCode 1 at address 0x40 = Interrupt status pointer */ - u32 Isp; /* Code = 0 (extended), ExCode = 1 */ - u32 PadEx1[15]; /* Codes 1-15 not used with extended codes */ - /* ExCode 2 = Interrupt Status Register */ - u32 Isr; /* Code = 0 (extended), ExCode = 2 */ - u32 PadEx2[15]; - /* ExCode 3 = Event base register. Location of event rings */ - u32 EventBase; /* Code = 0 (extended), ExCode = 3 */ - u32 PadEx3[15]; - /* ExCode 4 = Event ring size */ - u32 EventSize; /* Code = 0 (extended), ExCode = 4 */ - u32 PadEx4[15]; - /* ExCode 5 = TCB Buffers base address */ - u32 TcbBase; /* Code = 0 (extended), ExCode = 5 */ - u32 PadEx5[15]; - /* ExCode 6 = TCB Composite Buffers base address */ - u32 TcbCompBase; /* Code = 0 (extended), ExCode = 6 */ - u32 PadEx6[15]; - /* ExCode 7 = Transmit ring base address */ - u32 XmtBase; /* Code = 0 (extended), ExCode = 7 */ - u32 PadEx7[15]; - /* ExCode 8 = Transmit ring size */ - u32 XmtSize; /* Code = 0 (extended), ExCode = 8 */ - u32 PadEx8[15]; - /* ExCode 9 = Receive ring base address */ - u32 RcvBase; /* Code = 0 (extended), ExCode = 9 */ - u32 PadEx9[15]; - /* ExCode 10 = Receive ring size */ - u32 RcvSize; /* Code = 0 (extended), ExCode = 10 */ - u32 PadEx10[15]; - /* ExCode 11 = Read EEPROM/Flash Config */ - u32 Config; /* Code = 0 (extended), ExCode = 11 */ - u32 PadEx11[15]; - /* ExCode 12 = Multicast bits 31:0 */ - u32 McastLow; /* Code = 0 (extended), ExCode = 12 */ - u32 PadEx12[15]; - /* ExCode 13 = Multicast bits 63:32 */ - u32 McastHigh; /* Code = 0 (extended), ExCode = 13 */ - u32 PadEx13[15]; - /* ExCode 14 = Ping */ - u32 Ping; /* Code = 0 (extended), ExCode = 14 */ - u32 PadEx14[15]; - /* ExCode 15 = Link MTU */ - u32 LinkMtu; /* Code = 0 (extended), ExCode = 15 */ - u32 PadEx15[15]; - /* ExCode 16 = Download synchronization */ - u32 LoadSync; /* Code = 0 (extended), ExCode = 16 */ - u32 PadEx16[15]; - /* ExCode 17 = Upper DRAM address bits on 32-bit systems */ - u32 Upper; /* Code = 0 (extended), ExCode = 17 */ - u32 PadEx17[15]; - /* ExCode 18 = Slowpath Send Index Address */ - u32 SPSendIndex; /* Code = 0 (extended), ExCode = 18 */ - u32 PadEx18[15]; - /* ExCode 19 = Get ucode statistics */ - u32 GetUcodeStats; /* Code = 0 (extended), ExCode = 19 */ - u32 PadEx19[15]; - /* ExCode 20 = Aggregation - See sxgmisc.c:SxgSetInterruptAggregation */ - u32 Aggregation; /* Code = 0 (extended), ExCode = 20 */ - u32 PadEx20[15]; - /* ExCode 21 = Receive MDL push timer */ - u32 PushTicks; /* Code = 0 (extended), ExCode = 21 */ - u32 PadEx21[15]; - /* ExCode 22 = ACK Frequency */ - u32 AckFrequency; /* Code = 0 (extended), ExCode = 22 */ - u32 PadEx22[15]; - /* ExCode 23 = TOE NA */ - u32 RsvdReg23; - u32 PadEx23[15]; - /* ExCode 24 = TOE NA */ - u32 RsvdReg24; - u32 PadEx24[15]; - /* ExCode 25 = TOE NA */ - u32 RsvdReg25; /* Code = 0 (extended), ExCode = 25 */ - u32 PadEx25[15]; - /* ExCode 26 = Receive checksum requirements */ - u32 ReceiveChecksum; /* Code = 0 (extended), ExCode = 26 */ - u32 PadEx26[15]; - /* ExCode 27 = RSS Requirements */ - u32 Rss; /* Code = 0 (extended), ExCode = 27 */ - u32 PadEx27[15]; - /* ExCode 28 = RSS Table */ - u32 RssTable; /* Code = 0 (extended), ExCode = 28 */ - u32 PadEx28[15]; - /* ExCode 29 = Event ring release entries */ - u32 EventRelease; /* Code = 0 (extended), ExCode = 29 */ - u32 PadEx29[15]; - /* ExCode 30 = Number of receive bufferlist commands on ring 0 */ - u32 RcvCmd; /* Code = 0 (extended), ExCode = 30 */ - u32 PadEx30[15]; - /* ExCode 31 = slowpath transmit command - Data[31:0] = 1 */ - u32 XmtCmd; /* Code = 0 (extended), ExCode = 31 */ - u32 PadEx31[15]; - /* ExCode 32 = Dump command */ - u32 DumpCmd; /* Code = 0 (extended), ExCode = 32 */ - u32 PadEx32[15]; - /* ExCode 33 = Debug command */ - u32 DebugCmd; /* Code = 0 (extended), ExCode = 33 */ - u32 PadEx33[15]; - /* - * There are 128 possible extended commands - each of account for 16 - * words (including the non-relevent base command codes 1-15). - * Pad for the remainder of these here to bring us to the next CPU - * base. As extended codes are added, reduce the first array value in - * the following field - */ - u32 PadToNextCpu[94][16]; /* 94 = 128 - 34 (34 = Excodes 0 - 33)*/ -}; - -/* Interrupt control register (0) values */ -#define SXG_ICR_DISABLE 0x00000000 -#define SXG_ICR_ENABLE 0x00000001 -#define SXG_ICR_MASK 0x00000002 -#define SXG_ICR_MSGID_MASK 0xFFFF0000 -#define SXG_ICR_MSGID_SHIFT 16 -#define SXG_ICR(_MessageId, _Data) \ - ((((_MessageId) << SXG_ICR_MSGID_SHIFT) & \ - SXG_ICR_MSGID_MASK) | (_Data)) - -#define SXG_MIN_AGG_DEFAULT 0x0010 /* Minimum aggregation default */ -#define SXG_MAX_AGG_DEFAULT 0x0040 /* Maximum aggregation default */ -#define SXG_MAX_AGG_SHIFT 16 /* Maximum in top 16 bits of register */ -/* Disable interrupt aggregation on xmt */ -#define SXG_AGG_XMT_DISABLE 0x80000000 - -/* The Microcode supports up to 16 RSS queues (RevB) */ -#define SXG_MAX_RSS 16 -#define SXG_MAX_RSS_REVA 8 - -#define SXG_MAX_RSS_TABLE_SIZE 256 /* 256-byte max */ - -#define SXG_RSS_REVA_TCP6 0x00000001 /* RSS TCP over IPv6 */ -#define SXG_RSS_REVA_TCP4 0x00000002 /* RSS TCP over IPv4 */ -#define SXG_RSS_IP 0x00000001 /* RSS TCP over IPv6 */ -#define SXG_RSS_TCP 0x00000002 /* RSS TCP over IPv4 */ -#define SXG_RSS_LEGACY 0x00000004 /* Line-base interrupts */ -#define SXG_RSS_TABLE_SIZE 0x0000FF00 /* Table size mask */ - -#define SXG_RSS_TABLE_SHIFT 8 -#define SXG_RSS_BASE_CPU 0x00FF0000 /* Base CPU (not used) */ -#define SXG_RSS_BASE_SHIFT 16 - -#define SXG_RCV_IP_CSUM_ENABLED 0x00000001 /* ExCode 26 (ReceiveChecksum) */ -#define SXG_RCV_TCP_CSUM_ENABLED 0x00000002 /* ExCode 26 (ReceiveChecksum) */ - -#define SXG_XMT_CPUID_SHIFT 16 - -/* - * Status returned by ucode in the ConfigStat reg (see above) when attempted - * to load configuration data from the EEPROM/Flash. - */ -#define SXG_CFG_TIMEOUT 1 /* init value - timeout if unchanged */ -#define SXG_CFG_LOAD_EEPROM 2 /* config data loaded from EEPROM */ -#define SXG_CFG_LOAD_FLASH 3 /* config data loaded from flash */ -#define SXG_CFG_LOAD_INVALID 4 /* no valid config data found */ -#define SXG_CFG_LOAD_ERROR 5 /* hardware error */ - -#define SXG_CHECK_FOR_HANG_TIME 5 - -/* - * TCB registers - This is really the same register memory area as UCODE_REGS - * above, but defined differently. Bits 17:06 of the address define the TCB, - * which means each TCB area occupies 0x40 (64) bytes, or 16 u32S. What really - * is happening is that these registers occupy the "PadEx[15]" areas in the - * struct sxg_ucode_regs definition above - */ -struct sxg_tcb_regs { - u32 ExCode; /* Extended codes - see SXG_UCODE_REGS */ - u32 Xmt; /* Code = 1 - # of Xmt descriptors added to ring */ - u32 Rcv; /* Code = 2 - # of Rcv descriptors added to ring */ - u32 Rsvd1; /* Code = 3 - TOE NA */ - u32 Rsvd2; /* Code = 4 - TOE NA */ - u32 Rsvd3; /* Code = 5 - TOE NA */ - u32 Invalid1; /* Code = 6 - Reserved for "CardUp" see above */ - u32 Rsvd4; /* Code = 7 - TOE NA */ - u32 Invalid2; /* Code = 8 - Reserved for "ConfigStat" see above */ - u32 Rsvd5; /* Code = 9 - TOE NA */ - u32 Pad[6]; /* Codes 10-15 - Not used. */ -}; - -/*************************************************************************** - * ISR Format - * 31 0 - * _______________________________________ - * | | | | | | | | | - * |____|____|____|____|____|____|____|____| - * ^^^^ ^^^^ ^^^^ ^^^^ \ / - * ERR --|||| |||| |||| |||| ----------------- - * EVENT ---||| |||| |||| |||| | - * ----|| |||| |||| |||| |-- Crash Address - * UPC -----| |||| |||| |||| - * LEVENT -------|||| |||| |||| - * PDQF --------||| |||| |||| - * RMISS ---------|| |||| |||| - * BREAK ----------| |||| |||| - * HBEATOK ------------|||| |||| - * NOHBEAT -------------||| |||| - * ERFULL --------------|| |||| - * XDROP ---------------| |||| - * -----------------|||| - * -----------------||||--\ - * ||---|-CpuId of crash - * |----/ - ***************************************************************************/ -#define SXG_ISR_ERR 0x80000000 /* Error */ -#define SXG_ISR_EVENT 0x40000000 /* Event ring event */ -#define SXG_ISR_NONE1 0x20000000 /* Not used */ -#define SXG_ISR_UPC 0x10000000 /* Dump/debug command complete*/ -#define SXG_ISR_LINK 0x08000000 /* Link event */ -#define SXG_ISR_PDQF 0x04000000 /* Processed data queue full */ -#define SXG_ISR_RMISS 0x02000000 /* Drop - no host buf */ -#define SXG_ISR_BREAK 0x01000000 /* Breakpoint hit */ -#define SXG_ISR_PING 0x00800000 /* Heartbeat response */ -#define SXG_ISR_DEAD 0x00400000 /* Card crash */ -#define SXG_ISR_ERFULL 0x00200000 /* Event ring full */ -#define SXG_ISR_XDROP 0x00100000 /* XMT Drop - no DRAM bufs or XMT err */ -#define SXG_ISR_SPSEND 0x00080000 /* Slow send complete */ -#define SXG_ISR_CPU 0x00070000 /* Dead CPU mask */ -#define SXG_ISR_CPU_SHIFT 16 /* Dead CPU shift */ -#define SXG_ISR_CRASH 0x0000FFFF /* Crash address mask */ - -/*************************************************************************** - * Event Ring entry - * - * 31 15 0 - * .___________________.___________________. - * |<------------ Pad 0 ------------>| - * |_________|_________|_________|_________|0 0x00 - * |<------------ Pad 1 ------------>| - * |_________|_________|_________|_________|4 0x04 - * |<------------ Pad 2 ------------>| - * |_________|_________|_________|_________|8 0x08 - * |<----------- Event Word 0 ------------>| - * |_________|_________|_________|_________|12 0x0c - * |<----------- Event Word 1 ------------>| - * |_________|_________|_________|_________|16 0x10 - * |<------------- Toeplitz ------------>| - * |_________|_________|_________|_________|20 0x14 - * |<----- Length ---->|<------ TCB Id --->| - * |_________|_________|_________|_________|24 0x18 - * |<----- Status ---->|Evnt Code|Flsh Code| - * |_________|_________|_________|_________|28 0x1c - * ^ ^^^^ ^^^^ - * |- VALID |||| ||||- RBUFC - * |||| |||-- SLOWR - * |||| ||--- UNUSED - * |||| |---- FASTC - * ||||------ FASTR - * |||------- - * ||-------- - * |--------- - * - * Slowpath status: - * _______________________________________ - * |<----- Status ---->|Evnt Code|Flsh Code| - * |_________|Cmd Index|_________|_________|28 0x1c - * ^^^ ^^^^ - * ||| ||||- ISTCPIP6 - * ||| |||-- IPONLY - * ||| ||--- RCVERR - * ||| |---- IPCBAD - * |||------ TCPCBAD - * ||------- ISTCPIP - * |-------- SCERR - * - ************************************************************************/ -#pragma pack(push, 1) -struct sxg_event { - u32 Pad[1]; /* not used */ - u32 SndUna; /* SndUna value */ - u32 Resid; /* receive MDL resid */ - union { - void * HostHandle; /* Receive host handle */ - u32 Rsvd1; /* TOE NA */ - struct { - u32 NotUsed; - u32 Rsvd2; /* TOE NA */ - } Flush; - }; - u32 Toeplitz; /* RSS Toeplitz hash */ - union { - ushort Rsvd3; /* TOE NA */ - ushort HdrOffset; /* Slowpath */ - }; - ushort Length; - unsigned char Rsvd4; /* TOE NA */ - unsigned char Code; /* Event code */ - unsigned char CommandIndex; /* New ring index */ - unsigned char Status; /* Event status */ -}; -#pragma pack(pop) - -/* Event code definitions */ -#define EVENT_CODE_BUFFERS 0x01 /* Receive buffer list command (ring 0) */ -#define EVENT_CODE_SLOWRCV 0x02 /* Slowpath receive */ -#define EVENT_CODE_UNUSED 0x04 /* Was slowpath commands complete */ - -/* Status values */ -#define EVENT_STATUS_VALID 0x80 /* Entry valid */ - -/* Slowpath status */ -#define EVENT_STATUS_ERROR 0x40 /* Completed with error. Index in next byte */ -#define EVENT_STATUS_TCPIP4 0x20 /* TCPIPv4 frame */ -#define EVENT_STATUS_TCPBAD 0x10 /* Bad TCP checksum */ -#define EVENT_STATUS_IPBAD 0x08 /* Bad IP checksum */ -#define EVENT_STATUS_RCVERR 0x04 /* Slowpath receive error */ -#define EVENT_STATUS_IPONLY 0x02 /* IP frame */ -#define EVENT_STATUS_TCPIP6 0x01 /* TCPIPv6 frame */ -#define EVENT_STATUS_TCPIP 0x21 /* Combination of v4 and v6 */ - -/* - * Event ring - * Size must be power of 2, between 128 and 16k - */ -#define EVENT_RING_SIZE 4096 -#define EVENT_RING_BATCH 16 /* Hand entries back 16 at a time. */ -/* Stop processing events after 4096 (256 * 16) */ -#define EVENT_BATCH_LIMIT 256 - -struct sxg_event_ring { - struct sxg_event Ring[EVENT_RING_SIZE]; -}; - -/* TCB Buffers */ -/* Maximum number of TCBS supported by hardware/microcode */ -#define SXG_MAX_TCB 4096 -/* Minimum TCBs before we fail initialization */ -#define SXG_MIN_TCB 512 -/* - * TCB Hash - * The bucket is determined by bits 11:4 of the toeplitz if we support 4k - * offloaded connections, 10:4 if we support 2k and so on. - */ -#define SXG_TCB_BUCKET_SHIFT 4 -#define SXG_TCB_PER_BUCKET 16 -#define SXG_TCB_BUCKET_MASK 0xFF0 /* Bucket portion of TCB ID */ -#define SXG_TCB_ELEMENT_MASK 0x00F /* Element within bucket */ -#define SXG_TCB_BUCKETS 256 /* 256 * 16 = 4k */ - -#define SXG_TCB_BUFFER_SIZE 512 /* ASSERT format is correct */ - -#define SXG_TCB_RCVQ_SIZE 736 - -#define SXG_TCB_COMPOSITE_BUFFER_SIZE 1024 - -#define SXG_LOCATE_TCP_FRAME_HDR(_TcpObject, _IPv6) \ - (((_TcpObject)->VlanId) ? \ - ((_IPv6) ? /* Vlan frame header = yes */ \ - &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.SxgTcp: \ - &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.SxgTcp): \ - ((_IPv6) ? /* Vlan frame header = No */ \ - &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.SxgTcp : \ - &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.SxgTcp)) - -#define SXG_LOCATE_IP_FRAME_HDR(_TcpObject) \ - (_TcpObject)->VlanId ? \ - &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.Ip: \ - &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.Ip - -#define SXG_LOCATE_IP6_FRAME_HDR(TcpObject) \ - (_TcpObject)->VlanId ? \ - &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.Ip: \ - &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.Ip - -#if DBG -/* - * Horrible kludge to distinguish dumb-nic, slowpath, and - * fastpath traffic. Decrement the HopLimit by one - * for slowpath, two for fastpath. This assumes the limit is measurably - * greater than two, which I think is reasonable. - * Obviously this is DBG only. Maybe remove later, or #if 0 so we - * can set it when needed - */ -#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath) { \ - PIPV6_HDR _Ip6FrameHdr; \ - if ((_TcpObject)->IPv6) { \ - _Ip6FrameHdr = SXG_LOCATE_IP6_FRAME_HDR((_TcpObject)); \ - if (_FastPath) { \ - _Ip6FrameHdr->HopLimit = \ - (_TcpObject)->Cached.TtlOrHopLimit - 2; \ - } else { \ - _Ip6FrameHdr->HopLimit = \ - (_TcpObject)->Cached.TtlOrHopLimit - 1; \ - } \ - } \ -} -#else -/* Do nothing with free build */ -#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath) -#endif - -/* Receive and transmit rings */ -#define SXG_MAX_RING_SIZE 256 -#define SXG_XMT_RING_SIZE 128 /* Start with 128 */ -#define SXG_RCV_RING_SIZE 128 /* Start with 128 */ -#define SXG_MAX_ENTRIES 4096 -#define SXG_JUMBO_RCV_RING_SIZE 32 - -/* Structure and macros to manage a ring */ -struct sxg_ring_info { - /* Where we add entries - Note unsigned char:RING_SIZE */ - unsigned char Head; - unsigned char Tail; /* Where we pull off completed entries */ - ushort Size; /* Ring size - Must be multiple of 2 */ - void * Context[SXG_MAX_RING_SIZE]; /* Shadow ring */ -}; - -#define SXG_INITIALIZE_RING(_ring, _size) { \ - (_ring).Head = 0; \ - (_ring).Tail = 0; \ - (_ring).Size = (_size); \ -} - -#define SXG_ADVANCE_INDEX(_index, _size) \ - ((_index) = ((_index) + 1) & ((_size) - 1)) -#define SXG_PREVIOUS_INDEX(_index, _size) \ - (((_index) - 1) &((_size) - 1)) -#define SXG_RING_EMPTY(_ring) ((_ring)->Head == (_ring)->Tail) -#define SXG_RING_FULL(_ring) \ - ((((_ring)->Head + 1) & ((_ring)->Size - 1)) == (_ring)->Tail) -#define SXG_RING_ADVANCE_HEAD(_ring) \ - SXG_ADVANCE_INDEX((_ring)->Head, ((_ring)->Size)) -#define SXG_RING_RETREAT_HEAD(_ring) ((_ring)->Head = \ - SXG_PREVIOUS_INDEX((_ring)->Head, (_ring)->Size)) -#define SXG_RING_ADVANCE_TAIL(_ring) { \ - ASSERT((_ring)->Tail != (_ring)->Head); \ - SXG_ADVANCE_INDEX((_ring)->Tail, ((_ring)->Size)); \ -} -/* - * Set cmd to the next available ring entry, set the shadow context - * entry and advance the ring. - * The appropriate lock must be held when calling this macro - */ -#define SXG_GET_CMD(_ring, _ringinfo, _cmd, _context) { \ - if(SXG_RING_FULL(_ringinfo)) { \ - (_cmd) = NULL; \ - } else { \ - (_cmd) = &(_ring)->Descriptors[(_ringinfo)->Head]; \ - (_ringinfo)->Context[(_ringinfo)->Head] = (void *)(_context);\ - SXG_RING_ADVANCE_HEAD(_ringinfo); \ - } \ -} - -/* - * Abort the previously allocated command by retreating the head. - * NOTE - The appopriate lock MUST NOT BE DROPPED between the SXG_GET_CMD - * and SXG_ABORT_CMD calls. - */ -#define SXG_ABORT_CMD(_ringinfo) { \ - ASSERT(!(SXG_RING_EMPTY(_ringinfo))); \ - SXG_RING_RETREAT_HEAD(_ringinfo); \ - (_ringinfo)->Context[(_ringinfo)->Head] = NULL; \ -} - -/* - * For the given ring, return a pointer to the tail cmd and context, - * clear the context and advance the tail - */ -#define SXG_RETURN_CMD(_ring, _ringinfo, _cmd, _context) { \ - (_cmd) = &(_ring)->Descriptors[(_ringinfo)->Tail]; \ - (_context) = (_ringinfo)->Context[(_ringinfo)->Tail]; \ - (_ringinfo)->Context[(_ringinfo)->Tail] = NULL; \ - SXG_RING_ADVANCE_TAIL(_ringinfo); \ -} - -/* - * For a given ring find out how much the first pointer is ahead of - * the second pointer. "ahead" recognises the fact that the ring can wrap - */ -static inline int sxg_ring_get_forward_diff (struct sxg_ring_info *ringinfo, - int a, int b) { - if ((a < 0 || a > ringinfo->Size ) || (b < 0 || b > ringinfo->Size)) - return -1; - if (a > b) /* _a is lagging _b and _b has not wrapped around */ - return (a - b); - else - return ((ringinfo->Size - (b - a))); -} - -/*************************************************************** - * Host Command Buffer - commands to INIC via the Cmd Rings - * - * 31 15 0 - * .___________________.___________________. - * |<-------------- Sgl Low -------------->| - * |_________|_________|_________|_________|0 0x00 - * |<-------------- Sgl High ------------->| - * |_________|_________|_________|_________|4 0x04 - * |<------------- Sge 0 Low ----------->| - * |_________|_________|_________|_________|8 0x08 - * |<------------- Sge 0 High ----------->| - * |_________|_________|_________|_________|12 0x0c - * |<------------ Sge 0 Length ---------->| - * |_________|_________|_________|_________|16 0x10 - * |<----------- Window Update ----------->| - * |<-------- SP 1st SGE offset ---------->| - * |_________|_________|_________|_________|20 0x14 - * |<----------- Total Length ------------>| - * |_________|_________|_________|_________|24 0x18 - * |<----- LCnt ------>|<----- Flags ----->| - * |_________|_________|_________|_________|28 0x1c - ****************************************************************/ -#pragma pack(push, 1) -struct sxg_cmd { - dma64_addr_t Sgl; /* Physical address of SGL */ - union { - struct { - dma64_addr_t FirstSgeAddress; /* Address of first SGE */ - u32 FirstSgeLength; /* Length of first SGE */ - union { - u32 Rsvd1; /* TOE NA */ - u32 SgeOffset; /* Slowpath - 2nd SGE offset */ - /* MDL completion - clobbers update */ - u32 Resid; - }; - union { - u32 TotalLength; /* Total transfer length */ - u32 Mss; /* LSO MSS */ - }; - } Buffer; - }; - union { - struct { - unsigned char Flags:4; /* slowpath flags */ - unsigned char IpHl:4; /* Ip header length (>>2) */ - unsigned char MacLen; /* Mac header len */ - } CsumFlags; - struct { - ushort Flags:4; /* slowpath flags */ - ushort TcpHdrOff:7; /* TCP */ - ushort MacLen:5; /* Mac header len */ - } LsoFlags; - ushort Flags; /* flags */ - }; - union { - ushort SgEntries; /* SG entry count including first sge */ - struct { - unsigned char Status; /* Copied from event status */ - unsigned char NotUsed; - } Status; - }; -}; -#pragma pack(pop) - -#pragma pack(push, 1) -struct vlan_hdr { - ushort VlanTci; - ushort VlanTpid; -}; -#pragma pack(pop) - -/******************************************************************** - * Slowpath Flags: - * - * - * LSS Flags: - * .--- - * /.--- TCP Large segment send - * //.--- - * ///.--- - * 3 1 1 //// - * 1 5 0 |||| - * .___________________.____________vvvv. - * | |MAC | TCP | | - * | LCnt |hlen|hdroff|Flgs| - * |___________________|||||||||||||____| - * - * - * Checksum Flags - * - * .--- - * /.--- - * //.--- Checksum TCP - * ///.--- Checksum IP - * 3 1 //// No bits - normal send - * 1 5 7 |||| - * .___________________._______________vvvv. - * | | Offload | IP | | - * | LCnt |MAC hlen |Hlen|Flgs| - * |___________________|____|____|____|____| - * - *****************************************************************/ -/* Slowpath CMD flags */ -#define SXG_SLOWCMD_CSUM_IP 0x01 /* Checksum IP */ -#define SXG_SLOWCMD_CSUM_TCP 0x02 /* Checksum TCP */ -#define SXG_SLOWCMD_LSO 0x04 /* Large segment send */ - -struct sxg_xmt_ring { - struct sxg_cmd Descriptors[SXG_XMT_RING_SIZE]; -}; - -struct sxg_rcv_ring { - struct sxg_cmd Descriptors[SXG_RCV_RING_SIZE]; -}; - -/* - * Share memory buffer types - Used to identify asynchronous - * shared memory allocation - */ -enum sxg_buffer_type { - SXG_BUFFER_TYPE_RCV, /* Receive buffer */ - SXG_BUFFER_TYPE_SGL /* SGL buffer */ -}; - -/* State for SXG buffers */ -#define SXG_BUFFER_FREE 0x01 -#define SXG_BUFFER_BUSY 0x02 -#define SXG_BUFFER_ONCARD 0x04 -#define SXG_BUFFER_UPSTREAM 0x08 - -/* - * Receive data buffers - * - * Receive data buffers are given to the Sahara card 128 at a time. - * This is accomplished by filling in a "receive descriptor block" - * with 128 "receive descriptors". Each descriptor consists of - * a physical address, which the card uses as the address to - * DMA data into, and a virtual address, which is given back - * to the host in the "HostHandle" portion of an event. - * The receive descriptor data structure is defined below - * as sxg_rcv_data_descriptor, and the corresponding block - * is defined as sxg_rcv_descriptor_block. - * - * This receive descriptor block is given to the card by filling - * in the Sgl field of a sxg_cmd entry from pAdapt->RcvRings[0] - * with the physical address of the receive descriptor block. - * - * Both the receive buffers and the receive descriptor blocks - * require additional data structures to maintain them - * on a free queue and contain other information associated with them. - * Those data structures are defined as the sxg_rcv_data_buffer_hdr - * and sxg_rcv_descriptor_block_hdr respectively. - * - * Since both the receive buffers and the receive descriptor block - * must be accessible by the card, both must be allocated out of - * shared memory. To ensure that we always have a descriptor - * block available for every 128 buffers, we allocate all of - * these resources together in a single block. This entire - * block is managed by a struct sxg_rcv_block_hdr, who's sole purpose - * is to maintain address information so that the entire block - * can be free later. - * - * Further complicating matters is the fact that the receive - * buffers must be variable in length in order to accomodate - * jumbo frame configurations. We configure the buffer - * length so that the buffer and it's corresponding struct - * sxg_rcv_data_buffer_hdr structure add up to an even - * boundary. Then we place the remaining data structures after 128 - * of them as shown in the following diagram: - * - * _________________________________________ - * | | - * | Variable length receive buffer #1 | - * |_________________________________________| - * | | - * | sxg_rcv_data_buffer_hdr #1 | - * |_________________________________________| <== Even 2k or 10k boundary - * | | - * | ... repeat 2-128 .. | - * |_________________________________________| - * | | - * | struct sxg_rcv_descriptor_block | - * | Contains sxg_rcv_data_descriptor * 128 | - * |_________________________________________| - * | | - * | struct sxg_rcv_descriptor_block_hdr | - * |_________________________________________| - * | | - * | struct sxg_rcv_block_hdr | - * |_________________________________________| - * - * Memory consumption: - * Non-jumbo: - * Buffers and sxg_rcv_data_buffer_hdr = 2k * 128 = 256k - * + struct sxg_rcv_descriptor_block = 2k - * + struct sxg_rcv_descriptor_block_hdr = ~32 - * + struct sxg_rcv_block_hdr = ~32 - * => Total = ~258k/block - * - * Jumbo: - * Buffers and sxg_rcv_data_buffer_hdr = 10k * 128 = 1280k - * + struct sxg_rcv_descriptor_block = 2k - * + struct sxg_rcv_descriptor_block_hdr = ~32 - * + struct sxg_rcv_block_hdr = ~32 - * => Total = ~1282k/block - * - */ -#define SXG_RCV_DATA_BUFFERS 8192 /* Amount to give to the card */ -#define SXG_INITIAL_RCV_DATA_BUFFERS 16384 /* Initial pool of buffers */ -/* Minimum amount and when to get more */ -#define SXG_MIN_RCV_DATA_BUFFERS 4096 -#define SXG_MAX_RCV_BLOCKS 256 /* = 32k receive buffers */ -/* Amount to give to the card in case of jumbo frames */ -#define SXG_JUMBO_RCV_DATA_BUFFERS 2048 -/* Initial pool of buffers in case of jumbo buffers */ -#define SXG_INITIAL_JUMBO_RCV_DATA_BUFFERS 4096 -#define SXG_MIN_JUMBO_RCV_DATA_BUFFERS 1024 - -/* Receive buffer header */ -struct sxg_rcv_data_buffer_hdr { - dma64_addr_t PhysicalAddress; /* Buffer physical address */ - /* - * Note - DO NOT USE the VirtualAddress field to locate data. - * Use the sxg.h:SXG_RECEIVE_DATA_LOCATION macro instead. - */ - struct list_entry FreeList; /* Free queue of buffers */ - unsigned char State; /* See SXG_BUFFER state above */ - struct sk_buff * skb; /* Double mapped (nbl and pkt)*/ -}; - -/* - * SxgSlowReceive uses the PACKET (skb) contained - * in the struct sxg_rcv_data_buffer_hdr when indicating dumb-nic data - */ -#define SxgDumbRcvPacket skb - -/* Space for struct sxg_rcv_data_buffer_hdr */ -#define SXG_RCV_DATA_HDR_SIZE sizeof(struct sxg_rcv_data_buffer_hdr) -/* Non jumbo = 2k including HDR */ -#define SXG_RCV_DATA_BUFFER_SIZE 2048 -/* jumbo = 10k including HDR */ -#define SXG_RCV_JUMBO_BUFFER_SIZE 10240 - -/* Receive data descriptor */ -struct sxg_rcv_data_descriptor { - union { - struct sk_buff *VirtualAddress; /* Host handle */ - u64 ForceTo8Bytes; /*Force x86 to 8-byte boundary*/ - }; - dma64_addr_t PhysicalAddress; -}; - -/* Receive descriptor block */ -#define SXG_RCV_DESCRIPTORS_PER_BLOCK 128 -#define SXG_RCV_DESCRIPTOR_BLOCK_SIZE 2048 /* For sanity check */ - -struct sxg_rcv_descriptor_block { - struct sxg_rcv_data_descriptor Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK]; -}; - -/* Receive descriptor block header */ -struct sxg_rcv_descriptor_block_hdr { - void *VirtualAddress; /* start of 2k buffer */ - dma64_addr_t PhysicalAddress;/* and it's physical address */ - struct list_entry FreeList;/* free queue of descriptor blocks */ - unsigned char State; /* see sxg_buffer state above */ -}; - -/* Receive block header */ -struct sxg_rcv_block_hdr { - void *VirtualAddress; /* Start of virtual memory */ - dma64_addr_t PhysicalAddress;/* ..and it's physical address*/ - struct list_entry AllList; /* Queue of all SXG_RCV_BLOCKS*/ -}; - -/* Macros to determine data structure offsets into receive block */ -#define SXG_RCV_BLOCK_SIZE(_Buffersize) \ - (((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \ - (sizeof(struct sxg_rcv_descriptor_block)) + \ - (sizeof(struct sxg_rcv_descriptor_block_hdr)) + \ - (sizeof(struct sxg_rcv_block_hdr))) -#define SXG_RCV_BUFFER_DATA_SIZE(_Buffersize) \ - ((_Buffersize) - SXG_RCV_DATA_HDR_SIZE) -#define SXG_RCV_DATA_BUFFER_HDR_OFFSET(_Buffersize) \ - ((_Buffersize) - SXG_RCV_DATA_HDR_SIZE) -#define SXG_RCV_DESCRIPTOR_BLOCK_OFFSET(_Buffersize) \ - ((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) -#define SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET(_Buffersize) \ - (((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \ - (sizeof(struct sxg_rcv_descriptor_block))) -#define SXG_RCV_BLOCK_HDR_OFFSET(_Buffersize) \ - (((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \ - (sizeof(struct sxg_rcv_descriptor_block)) + \ - (sizeof(struct sxg_rcv_descriptor_block_hdr))) - -/* Scatter gather list buffer */ -#define SXG_INITIAL_SGL_BUFFERS 8192 /* Initial pool of SGL buffers */ -#define SXG_MIN_SGL_BUFFERS 2048 /* Minimum amount and when to get more*/ -/* Maximum to allocate (note ADAPT:ushort) */ -#define SXG_MAX_SGL_BUFFERS 16384 - -/* - * SXG_SGL_POOL_PROPERTIES - This structure is used to define a pool of SGL - * buffers. These buffers are allocated out of shared memory and used to - * contain a physical scatter gather list structure that is shared - * with the card. - * - * We split our SGL buffers into multiple pools based on size. The motivation - * is that some applications perform very large I/Os (1MB for example), so - * we need to be able to allocate an SGL to accommodate such a request. - * But such an SGL would require 256 24-byte SG entries - ~6k. - * Given that the vast majority of I/Os are much smaller than 1M, allocating - * a single pool of SGL buffers would be a horribly inefficient use of - * memory. - * - * The following structure includes two fields relating to its size. - * The NBSize field specifies the largest NET_BUFFER that can be handled - * by the particular pool. The SGEntries field defines the size, in - * entries, of the SGL for that pool. The SGEntries is determined by - * dividing the NBSize by the expected page size (4k), and then padding - * it by some appropriate amount as insurance (20% or so..??). - */ -struct sxg_sgl_pool_properties { - u32 NBSize; /* Largest NET_BUFFER size for this pool */ - ushort SGEntries; /* Number of entries in SGL */ - ushort InitialBuffers; /* Number to allocate at initializationtime */ - ushort MinBuffers; /* When to get more */ - ushort MaxBuffers; /* When to stop */ - ushort PerCpuThreshold;/* See sxgh.h:SXG_RESOURCES */ -}; - -/* - * At the moment I'm going to statically initialize 4 pools: - * 100k buffer pool: The vast majority of the expected buffers are expected - * to be less than or equal to 100k. At 30 entries per and - * 8k initial buffers amounts to ~4MB of memory - * NOTE - This used to be 64K with 20 entries, but during - * WHQL NDIS 6.0 Testing (2c_mini6stress) MS does their - * best to send absurd NBL's with ridiculous SGLs, we - * have received 400byte sends contained in SGL's that - * have 28 entries - * 1M buffer pool: Buffers between 64k and 1M. Allocate 256 initial - * buffers with 300 entries each => ~2MB of memory - * 5M buffer pool: Not expected often, if at all. 32 initial buffers - * at 1500 entries each => ~1MB of memory - * 10M buffer pool: Not expected at all, except under pathelogical conditions. - * Allocate one at initialization time. - * Note - 10M is the current limit of what we can realistically - * support due to the sahara SGL bug described in the - * SAHARA SGL WORKAROUND below. We will likely adjust the - * number of pools and/or pool properties over time. - */ -#define SXG_NUM_SGL_POOLS 4 -#define INITIALIZE_SGL_POOL_PROPERTIES \ -struct sxg_sgl_pool_properties SxgSglPoolProperties[SXG_NUM_SGL_POOLS] =\ -{ \ - { 102400, 30, 8192, 2048, 16384, 256}, \ - { 1048576, 300, 256, 128, 1024, 16}, \ - { 5252880, 1500, 32, 16, 512, 0}, \ - {10485760, 2700, 2, 4, 32, 0}, \ -}; - -extern struct sxg_sgl_pool_properties SxgSglPoolProperties[]; - -#define SXG_MAX_SGL_BUFFER_SIZE \ - SxgSglPoolProperties[SXG_NUM_SGL_POOLS - 1].NBSize - -/* - * SAHARA SGL WORKAROUND!! - * The current Sahara card uses a 16-bit counter when advancing - * SGL address locations. This means that if an SGL crosses - * a 64k boundary, the hardware will actually skip back to - * the start of the previous 64k boundary, with obviously - * undesirable results. - * - * We currently workaround this issue by allocating SGL buffers - * in 64k blocks and skipping over buffers that straddle the boundary. - */ -#define SXG_INVALID_SGL(phys_addr,len) \ - (((phys_addr >> 16) != ( (phys_addr + len) >> 16 ))) - -/* - * Allocate SGLs in blocks so we can skip over invalid entries. - * We allocation 64k worth of SGL buffers, including the - * struct sxg_sgl_block_hdr, plus one for padding - */ -#define SXG_SGL_BLOCK_SIZE 65536 -#define SXG_SGL_ALLOCATION_SIZE(_Pool) \ - SXG_SGL_BLOCK_SIZE + SXG_SGL_SIZE(_Pool) - -struct sxg_sgl_block_hdr { - ushort Pool; /* Associated SGL pool */ - /* struct sxg_scatter_gather blocks */ - struct list_entry List; - dma64_addr_t PhysicalAddress;/* physical address */ -}; - -/* - * The following definition denotes the maximum block of memory that the - * card can DMA to.It is specified in the call to NdisMRegisterScatterGatherDma. - * For now, use the same value as used in the Slic/Oasis driver, which - * is 128M. That should cover any expected MDL that I can think of. - */ -#define SXG_MAX_PHYS_MAP (1024 * 1024 * 128) - -/* Self identifying structure type */ -enum SXG_SGL_TYPE { - SXG_SGL_DUMB, /* Dumb NIC SGL */ - SXG_SGL_SLOW, /* Slowpath protocol header - see below */ - SXG_SGL_CHIMNEY /* Chimney offload SGL */ -}; - -/* - * The ucode expects an NDIS SGL structure that - * is formatted for an x64 system. When running - * on an x64 system, we can simply hand the NDIS SGL - * to the card directly. For x86 systems we must reconstruct - * the SGL. The following structure defines an x64 - * formatted SGL entry - */ -struct sxg_x64_sge { - dma64_addr_t Address; /* same as wdm.h */ - u32 Length; /* same as wdm.h */ - u32 CompilerPad; /* The compiler pads to 8-bytes */ - u64 Reserved; /* u32 * in wdm.h. Force to 8 bytes */ -}; - -/* - * Our SGL structure - Essentially the same as - * wdm.h:SCATTER_GATHER_LIST. Note the variable number of - * elements based on the pool specified above - */ -struct sxg_x64_sgl { - u32 NumberOfElements; - u32 *Reserved; - struct sxg_x64_sge Elements[1]; /* Variable */ -}; - -struct sxg_scatter_gather { - enum SXG_SGL_TYPE Type; /* FIRST! Dumb-nic or offload */ - ushort Pool; /* Associated SGL pool */ - ushort Entries; /* SGL total entries */ - void * adapter; /* Back pointer to adapter */ - /* Free struct sxg_scatter_gather blocks */ - struct list_entry FreeList; - /* All struct sxg_scatter_gather blocks */ - struct list_entry AllList; - dma64_addr_t PhysicalAddress;/* physical address */ - unsigned char State; /* See SXG_BUFFER state above */ - unsigned char CmdIndex; /* Command ring index */ - struct sk_buff *DumbPacket; /* Associated Packet */ - /* For asynchronous completions */ - u32 Direction; - u32 CurOffset; /* Current SGL offset */ - u32 SglRef; /* SGL reference count */ - struct vlan_hdr VlanTag; /* VLAN tag to be inserted into SGL */ - struct sxg_x64_sgl *pSgl; /* SGL Addr. Possibly &Sgl */ - struct sxg_x64_sgl Sgl; /* SGL handed to card */ -}; - -/* - * Note - the "- 1" is because struct sxg_scatter_gather=>struct sxg_x64_sgl - * includes 1 SGE.. - */ -#define SXG_SGL_SIZE(_Pool) \ - (sizeof(struct sxg_scatter_gather) + \ - ((SxgSglPoolProperties[_Pool].SGEntries - 1) * \ - sizeof(struct sxg_x64_sge))) - -/* Force NDIS to give us it's own buffer so we can reformat to our own */ -#define SXG_SGL_BUFFER(_SxgSgl) NULL -#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) 0 -#define SXG_SGL_BUF_SIZE 0 - -/* -#if defined(CONFIG_X86_64) -#define SXG_SGL_BUFFER(_SxgSgl) (&_SxgSgl->Sgl) -#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) ((_SxgSgl)->Entries * \ - sizeof(struct sxg_x64_sge)) -#define SXG_SGL_BUF_SIZE sizeof(struct sxg_x64_sgl) -#elif defined(CONFIG_X86) -// Force NDIS to give us it's own buffer so we can reformat to our own -#define SXG_SGL_BUFFER(_SxgSgl) NULL -#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) 0 -#define SXG_SGL_BUF_SIZE 0 -#else -#error staging: sxg: driver is for X86 only! -#endif -*/ -/* Microcode statistics */ -struct sxg_ucode_stats { - u32 RPDQOflow; /* PDQ overflow (unframed ie dq & drop 1st) */ - u32 XDrops; /* Xmt drops due to no xmt buffer */ - u32 ERDrops; /* Rcv drops due to ER full */ - u32 NBDrops; /* Rcv drops due to out of host buffers */ - u32 PQDrops; /* Rcv drops due to PDQ full */ - /* Rcv drops due to bad frame: no link addr match, frlen > max */ - u32 BFDrops; - u32 UPDrops; /* Rcv drops due to UPFq full */ - u32 XNoBufs; /* Xmt drop due to no DRAM Xmit buffer or PxyBuf */ -}; - -/* - * Macros for handling the Offload engine values - */ -/* Number of positions to shift Network Header Length before passing to card */ -#define SXG_NW_HDR_LEN_SHIFT 2 --- a/drivers/staging/sxg/sxghw.h +++ /dev/null @@ -1,1020 +0,0 @@ -/************************************************************* - * Copyright © 1997-2007 Alacritech, Inc. All rights reserved - * - * $Id: sxghw.h,v 1.2 2008/07/24 17:24:23 chris Exp $ - * - * sxghw.h: - * - * This file contains structures and definitions for the - * Alacritech Sahara hardware - * - **********************************************************/ - - -/* PCI Configuration space */ -/* PCI Vendor ID */ -#define SXG_VENDOR_ID 0x139A /* Alacritech's Vendor ID */ - -/* PCI Device ID */ -#define SXG_DEVICE_ID 0x0009 /* Sahara Device ID */ - - -/* Type of ASIC in use */ -enum asic_type { - SAHARA_REV_A, - SAHARA_REV_B -}; - -/* Type of Xcvr in fiber card */ -enum xcvr_type { - XCVR_UNKNOWN, - XCVR_NONE, - XCVR_SR, - XCVR_LR, - XCVR_LRM, - XCVR_CR -}; -/* - * Subsystem IDs. - * - * The subsystem ID value is broken into bit fields as follows: - * Bits [15:12] - Function - * Bits [11:8] - OEM and/or operating system. - * Bits [7:0] - Base SID. - */ - -/* SSID field (bit) masks */ -#define SSID_BASE_MASK 0x00FF /* Base subsystem ID mask */ -#define SSID_OEM_MASK 0x0F00 /* Subsystem OEM mask */ -#define SSID_FUNC_MASK 0xF000 /* Subsystem function mask */ - -/* Base SSID's */ -/* 100022 Sahara prototype (XenPak) board */ -#define SSID_SAHARA_PROTO 0x0018 -#define SSID_SAHARA_FIBER 0x0019 /* 100023 Sahara 1-port fiber board */ -#define SSID_SAHARA_COPPER 0x001A /* 100024 Sahara 1-port copper board */ - -/* Useful SSID macros */ -/* isolate base SSID bits */ -#define SSID_BASE(ssid) ((ssid) & SSID_BASE_MASK) -/* isolate SSID OEM bits */ -#define SSID_OEM(ssid) ((ssid) & SSID_OEM_MASK) -/* isolate SSID function bits */ -#define SSID_FUNC(ssid) ((ssid) & SSID_FUNC_MASK) - - -/* HW Register Space */ -#define SXG_HWREG_MEMSIZE 0x4000 /* 16k */ - -#pragma pack(push, 1) -struct sxg_hw_regs { - u32 Reset; /* Write 0xdead to invoke soft reset */ - u32 Pad1; /* No register defined at offset 4 */ - u32 InterruptMask0; /* Deassert legacy interrupt on function 0 */ - u32 InterruptMask1; /* Deassert legacy interrupt on function 1 */ - u32 UcodeDataLow; /* Store microcode instruction bits 31-0 */ - u32 UcodeDataMiddle; /* Store microcode instruction bits 63-32 */ - u32 UcodeDataHigh; /* Store microcode instruction bits 95-64 */ - u32 UcodeAddr; /* Store microcode address - See flags below */ - u32 PadTo0x80[24]; /* Pad to Xcv configuration registers */ - u32 MacConfig0; /* 0x80 - AXGMAC Configuration Register 0 */ - u32 MacConfig1; /* 0x84 - AXGMAC Configuration Register 1 */ - u32 MacConfig2; /* 0x88 - AXGMAC Configuration Register 2 */ - u32 MacConfig3; /* 0x8C - AXGMAC Configuration Register 3 */ - u32 MacAddressLow; /* 0x90 - AXGMAC MAC Station Address - octets 1-4 */ - u32 MacAddressHigh; /* 0x94 - AXGMAC MAC Station Address - octets 5-6 */ - u32 MacReserved1[2]; /* 0x98 - AXGMAC Reserved */ - u32 MacMaxFrameLen; /* 0xA0 - AXGMAC Maximum Frame Length */ - u32 MacReserved2[2]; /* 0xA4 - AXGMAC Reserved */ - u32 MacRevision; /* 0xAC - AXGMAC Revision Level Register */ - u32 MacReserved3[4]; /* 0xB0 - AXGMAC Reserved */ - u32 MacAmiimCmd; /* 0xC0 - AXGMAC AMIIM Command Register */ - u32 MacAmiimField; /* 0xC4 - AXGMAC AMIIM Field Register */ - u32 MacAmiimConfig; /* 0xC8 - AXGMAC AMIIM Configuration Register */ - u32 MacAmiimLink; /* 0xCC - AXGMAC AMIIM Link Fail Vector Register */ - u32 MacAmiimIndicator; /* 0xD0 - AXGMAC AMIIM Indicator Registor */ - u32 PadTo0x100[11]; /* 0xD4 - 0x100 - Pad */ - u32 XmtConfig; /* 0x100 - Transmit Configuration Register */ - u32 RcvConfig; /* 0x104 - Receive Configuration Register 1 */ - u32 LinkAddress0Low; /* 0x108 - Link address 0 */ - u32 LinkAddress0High; /* 0x10C - Link address 0 */ - u32 LinkAddress1Low; /* 0x110 - Link address 1 */ - u32 LinkAddress1High; /* 0x114 - Link address 1 */ - u32 LinkAddress2Low; /* 0x118 - Link address 2 */ - u32 LinkAddress2High; /* 0x11C - Link address 2 */ - u32 LinkAddress3Low; /* 0x120 - Link address 3 */ - u32 LinkAddress3High; /* 0x124 - Link address 3 */ - u32 ToeplitzKey[10]; /* 0x128 - 0x150 - Toeplitz key */ - u32 SocketKey[10]; /* 0x150 - 0x178 - Socket Key */ - u32 LinkStatus; /* 0x178 - Link status */ - u32 ClearStats; /* 0x17C - Clear Stats */ - u32 XmtErrorsLow; /* 0x180 - Transmit stats - errors */ - u32 XmtErrorsHigh; /* 0x184 - Transmit stats - errors */ - u32 XmtFramesLow; /* 0x188 - Transmit stats - frame count */ - u32 XmtFramesHigh; /* 0x18C - Transmit stats - frame count */ - u32 XmtBytesLow; /* 0x190 - Transmit stats - byte count */ - u32 XmtBytesHigh; /* 0x194 - Transmit stats - byte count */ - u32 XmtTcpSegmentsLow; /* 0x198 - Transmit stats - TCP segments */ - u32 XmtTcpSegmentsHigh; /* 0x19C - Transmit stats - TCP segments */ - u32 XmtTcpBytesLow; /* 0x1A0 - Transmit stats - TCP bytes */ - u32 XmtTcpBytesHigh; /* 0x1A4 - Transmit stats - TCP bytes */ - u32 RcvErrorsLow; /* 0x1A8 - Receive stats - errors */ - u32 RcvErrorsHigh; /* 0x1AC - Receive stats - errors */ - u32 RcvFramesLow; /* 0x1B0 - Receive stats - frame count */ - u32 RcvFramesHigh; /* 0x1B4 - Receive stats - frame count */ - u32 RcvBytesLow; /* 0x1B8 - Receive stats - byte count */ - u32 RcvBytesHigh; /* 0x1BC - Receive stats - byte count */ - u32 RcvTcpSegmentsLow; /* 0x1C0 - Receive stats - TCP segments */ - u32 RcvTcpSegmentsHigh; /* 0x1C4 - Receive stats - TCP segments */ - u32 RcvTcpBytesLow; /* 0x1C8 - Receive stats - TCP bytes */ - u32 RcvTcpBytesHigh; /* 0x1CC - Receive stats - TCP bytes */ - u32 PadTo0x200[12]; /* 0x1D0 - 0x200 - Pad */ - u32 Software[1920]; /* 0x200 - 0x2000 - Software defined (not used) */ - u32 MsixTable[1024]; /* 0x2000 - 0x3000 - MSIX Table */ - u32 MsixBitArray[1024]; /* 0x3000 - 0x4000 - MSIX Pending Bit Array */ -}; -#pragma pack(pop) - -/* Microcode Address Flags */ -#define MICROCODE_ADDRESS_GO 0x80000000 /* Start microcode */ -#define MICROCODE_ADDRESS_WRITE 0x40000000 /* Store microcode */ -#define MICROCODE_ADDRESS_READ 0x20000000 /* Read microcode */ -#define MICROCODE_ADDRESS_PARITY 0x10000000/* Parity error detected */ -#define MICROCODE_ADDRESS_MASK 0x00001FFF /* Address bits */ - -/* Link Address Registers */ -/* Applied to link address high */ -#define LINK_ADDRESS_ENABLE 0x80000000 - -/* Microsoft register space size */ -#define SXG_UCODEREG_MEMSIZE 0x40000 /* 256k */ - -/* - * Sahara microcode register address format. The command code, - * extended command code, and associated processor are encoded in - * the address bits as follows - */ -#define SXG_ADDRESS_CODE_SHIFT 2 /* Base command code */ -#define SXG_ADDRESS_CODE_MASK 0x0000003C -/* Extended (or sub) command code */ -#define SXG_ADDRESS_EXCODE_SHIFT 6 -#define SXG_ADDRESS_EXCODE_MASK 0x00001FC0 -#define SXG_ADDRESS_CPUID_SHIFT 13 /* CPU */ -#define SXG_ADDRESS_CPUID_MASK 0x0003E000 -/* Used to sanity check UCODE_REGS structure */ -#define SXG_REGISTER_SIZE_PER_CPU 0x00002000 - -/* Sahara receive sequencer status values */ -#define SXG_RCV_STATUS_ATTN 0x80000000 /* Attention */ -#define SXG_RCV_STATUS_TRANSPORT_MASK 0x3F000000 /* Transport mask */ -#define SXG_RCV_STATUS_TRANSPORT_ERROR 0x20000000 /* Transport error */ -/* Transport cksum error */ -#define SXG_RCV_STATUS_TRANSPORT_CSUM 0x23000000 -/* Transport underflow */ -#define SXG_RCV_STATUS_TRANSPORT_UFLOW 0x22000000 - /* Transport header length */ -#define SXG_RCV_STATUS_TRANSPORT_HDRLEN 0x20000000 -/* Transport flags detected */ -#define SXG_RCV_STATUS_TRANSPORT_FLAGS 0x10000000 - /* Transport options detected */ -#define SXG_RCV_STATUS_TRANSPORT_OPTS 0x08000000 -#define SXG_RCV_STATUS_TRANSPORT_SESS_MASK 0x07000000 /* Transport DDP */ -#define SXG_RCV_STATUS_TRANSPORT_DDP 0x06000000 /* Transport DDP */ -#define SXG_RCV_STATUS_TRANSPORT_iSCSI 0x05000000 /* Transport iSCSI */ -#define SXG_RCV_STATUS_TRANSPORT_NFS 0x04000000 /* Transport NFS */ -#define SXG_RCV_STATUS_TRANSPORT_FTP 0x03000000 /* Transport FTP */ -#define SXG_RCV_STATUS_TRANSPORT_HTTP 0x02000000 /* Transport HTTP */ -#define SXG_RCV_STATUS_TRANSPORT_SMB 0x01000000 /* Transport SMB */ -#define SXG_RCV_STATUS_NETWORK_MASK 0x00FF0000 /* Network mask */ -#define SXG_RCV_STATUS_NETWORK_ERROR 0x00800000 /* Network error */ -/* Network cksum error */ -#define SXG_RCV_STATUS_NETWORK_CSUM 0x00830000 -/* Network underflow error */ -#define SXG_RCV_STATUS_NETWORK_UFLOW 0x00820000 - /* Network header length */ -#define SXG_RCV_STATUS_NETWORK_HDRLEN 0x00800000 - /* Network overflow detected */ -#define SXG_RCV_STATUS_NETWORK_OFLOW 0x00400000 -/* Network multicast detected */ -#define SXG_RCV_STATUS_NETWORK_MCAST 0x00200000 -/* Network options detected */ -#define SXG_RCV_STATUS_NETWORK_OPTIONS 0x00100000 -/* Network offset detected */ -#define SXG_RCV_STATUS_NETWORK_OFFSET 0x00080000 -/* Network fragment detected */ -#define SXG_RCV_STATUS_NETWORK_FRAGMENT 0x00040000 -/* Network transport type mask */ -#define SXG_RCV_STATUS_NETWORK_TRANS_MASK 0x00030000 -#define SXG_RCV_STATUS_NETWORK_UDP 0x00020000 /* UDP */ -#define SXG_RCV_STATUS_NETWORK_TCP 0x00010000 /* TCP */ -#define SXG_RCV_STATUS_IPONLY 0x00008000 /* IP-only not TCP */ -/* Receive priority */ -#define SXG_RCV_STATUS_PKT_PRI 0x00006000 -/* Receive priority shift */ -#define SXG_RCV_STATUS_PKT_PRI_SHFT 13 -/* MAC Receive RAM parity error */ -#define SXG_RCV_STATUS_PARITY 0x00001000 -/* Link address detection mask */ -#define SXG_RCV_STATUS_ADDRESS_MASK 0x00000F00 - -#define SXG_RCV_STATUS_ADDRESS_D 0x00000B00 /* Link address D */ -#define SXG_RCV_STATUS_ADDRESS_C 0x00000A00 /* Link address C */ -#define SXG_RCV_STATUS_ADDRESS_B 0x00000900 /* Link address B */ -#define SXG_RCV_STATUS_ADDRESS_A 0x00000800 /* Link address A */ -/* Link address broadcast */ -#define SXG_RCV_STATUS_ADDRESS_BCAST 0x00000300 - /* Link address multicast */ -#define SXG_RCV_STATUS_ADDRESS_MCAST 0x00000200 -/* Link control multicast */ -#define SXG_RCV_STATUS_ADDRESS_CMCAST 0x00000100 -/* Link status mask */ -#define SXG_RCV_STATUS_LINK_MASK 0x000000FF -#define SXG_RCV_STATUS_LINK_ERROR 0x00000080 /* Link error */ -/* Link status mask */ -#define SXG_RCV_STATUS_LINK_MASK 0x000000FF -/* RcvMacQ parity error */ -#define SXG_RCV_STATUS_LINK_PARITY 0x00000087 -#define SXG_RCV_STATUS_LINK_EARLY 0x00000086 /* Data early */ -#define SXG_RCV_STATUS_LINK_BUFOFLOW 0x00000085 /* Buffer overflow */ -#define SXG_RCV_STATUS_LINK_CODE 0x00000084 /* Link code error */ -#define SXG_RCV_STATUS_LINK_DRIBBLE 0x00000083 /* Dribble nibble */ -#define SXG_RCV_STATUS_LINK_CRC 0x00000082 /* CRC error */ -#define SXG_RCV_STATUS_LINK_OFLOW 0x00000081 /* Link overflow */ -#define SXG_RCV_STATUS_LINK_UFLOW 0x00000080 /* Link underflow */ -#define SXG_RCV_STATUS_LINK_8023 0x00000020 /* 802.3 */ -#define SXG_RCV_STATUS_LINK_SNAP 0x00000010 /* Snap */ -#define SXG_RCV_STATUS_LINK_VLAN 0x00000008 /* VLAN */ -/* Network type mask */ -#define SXG_RCV_STATUS_LINK_TYPE_MASK 0x00000007 -#define SXG_RCV_STATUS_LINK_CONTROL 0x00000003 /* Control packet */ -#define SXG_RCV_STATUS_LINK_IPV6 0x00000002 /* IPv6 packet */ -#define SXG_RCV_STATUS_LINK_IPV4 0x00000001 /* IPv4 packet */ - -/* Sahara receive and transmit configuration registers */ -/* RcvConfig register reset */ -#define RCV_CONFIG_RESET 0x80000000 -/* Enable the receive logic */ -#define RCV_CONFIG_ENABLE 0x40000000 -/* Enable the receive parser */ -#define RCV_CONFIG_ENPARSE 0x20000000 -/* Enable the socket detector */ -#define RCV_CONFIG_SOCKET 0x10000000 -#define RCV_CONFIG_RCVBAD 0x08000000 /* Receive all bad frames */ -/* Receive all control frames */ -#define RCV_CONFIG_CONTROL 0x04000000 -/* Enable pause transmit when attn */ -#define RCV_CONFIG_RCVPAUSE 0x02000000 -/* Include TCP port w/ IPv6 toeplitz */ -#define RCV_CONFIG_TZIPV6 0x01000000 -/* Include TCP port w/ IPv4 toeplitz */ -#define RCV_CONFIG_TZIPV4 0x00800000 -#define RCV_CONFIG_FLUSH 0x00400000 /* Flush buffers */ -#define RCV_CONFIG_PRIORITY_MASK 0x00300000 /* Priority level */ -#define RCV_CONFIG_CONN_MASK 0x000C0000 /* Number of connections */ -#define RCV_CONFIG_CONN_4K 0x00000000 /* 4k connections */ -#define RCV_CONFIG_CONN_2K 0x00040000 /* 2k connections */ -#define RCV_CONFIG_CONN_1K 0x00080000 /* 1k connections */ -#define RCV_CONFIG_CONN_512 0x000C0000 /* 512 connections */ -#define RCV_CONFIG_HASH_MASK 0x00030000 /* Hash depth */ -#define RCV_CONFIG_HASH_8 0x00000000 /* Hash depth 8 */ -#define RCV_CONFIG_HASH_16 0x00010000 /* Hash depth 16 */ -#define RCV_CONFIG_HASH_4 0x00020000 /* Hash depth 4 */ -#define RCV_CONFIG_HASH_2 0x00030000 /* Hash depth 2 */ -/* Buffer length bits 15:4. ie multiple of 16. */ -#define RCV_CONFIG_BUFLEN_MASK 0x0000FFE0 -/* Disable socket detection on attn */ -#define RCV_CONFIG_SKT_DIS 0x00000008 -#define RCV_CONFIG_HIPRICTL 0x00000002 /* Ctrl frames on high-prioirty RcvQ */ -#define RCV_CONFIG_NEWSTATUSFMT 0x00000001 /* Use RevB status format */ -/* - * Macro to determine RCV_CONFIG_BUFLEN based on maximum frame size. - * We add 18 bytes for Sahara receive status and padding, plus 4 bytes for CRC, - * and round up to nearest 32 byte boundary - */ -#define RCV_CONFIG_BUFSIZE(_MaxFrame) \ - ((((_MaxFrame) + 22) + 31) & RCV_CONFIG_BUFLEN_MASK) - -/* XmtConfig register reset */ -#define XMT_CONFIG_RESET 0x80000000 -#define XMT_CONFIG_ENABLE 0x40000000 /* Enable transmit logic */ -/* Inhibit MAC RAM parity error */ -#define XMT_CONFIG_MAC_PARITY 0x20000000 -/* Inhibit D2F buffer parity error */ -#define XMT_CONFIG_BUF_PARITY 0x10000000 -/* Inhibit 1T SRAM parity error */ -#define XMT_CONFIG_MEM_PARITY 0x08000000 -#define XMT_CONFIG_INVERT_PARITY 0x04000000 /* Invert MAC RAM parity */ -#define XMT_CONFIG_INITIAL_IPID 0x0000FFFF /* Initial IPID */ - -/* - * A-XGMAC Registers - Occupy 0x80 - 0xD4 of the struct sxg_hw_regs - * - * Full register descriptions can be found in axgmac.pdf - */ -/* A-XGMAC Configuration Register 0 */ -#define AXGMAC_CFG0_SUB_RESET 0x80000000 /* Sub module reset */ -#define AXGMAC_CFG0_RCNTRL_RESET 0x00400000 /* Receive control reset */ -#define AXGMAC_CFG0_RFUNC_RESET 0x00200000 /* Receive function reset */ -#define AXGMAC_CFG0_TCNTRL_RESET 0x00040000 /* Transmit control reset */ -#define AXGMAC_CFG0_TFUNC_RESET 0x00020000 /* Transmit function reset */ -#define AXGMAC_CFG0_MII_RESET 0x00010000 /* MII Management reset */ - -/* A-XGMAC Configuration Register 1 */ -/* Allow the sending of Pause frames */ -#define AXGMAC_CFG1_XMT_PAUSE 0x80000000 -#define AXGMAC_CFG1_XMT_EN 0x40000000 /* Enable transmit */ -/* Allow the detection of Pause frames */ -#define AXGMAC_CFG1_RCV_PAUSE 0x20000000 -#define AXGMAC_CFG1_RCV_EN 0x10000000 /* Enable receive */ -/* Current transmit state - READ ONLY */ -#define AXGMAC_CFG1_XMT_STATE 0x04000000 -/* Current receive state - READ ONLY */ -#define AXGMAC_CFG1_RCV_STATE 0x01000000 -/* Only pause for 64 slot on XOFF */ -#define AXGMAC_CFG1_XOFF_SHORT 0x00001000 -/* Delay transmit FCS 1 4-byte word */ -#define AXGMAC_CFG1_XMG_FCS1 0x00000400 -/* Delay transmit FCS 2 4-byte words */ -#define AXGMAC_CFG1_XMG_FCS2 0x00000800 -/* Delay transmit FCS 3 4-byte words */ -#define AXGMAC_CFG1_XMG_FCS3 0x00000C00 -/* Delay receive FCS 1 4-byte word */ -#define AXGMAC_CFG1_RCV_FCS1 0x00000100 -/* Delay receive FCS 2 4-byte words */ -#define AXGMAC_CFG1_RCV_FCS2 0x00000200 -/* Delay receive FCS 3 4-byte words */ -#define AXGMAC_CFG1_RCV_FCS3 0x00000300 -/* Per-packet override enable */ -#define AXGMAC_CFG1_PKT_OVERRIDE 0x00000080 -#define AXGMAC_CFG1_SWAP 0x00000040 /* Byte swap enable */ -/* ASSERT srdrpfrm on short frame (<64) */ -#define AXGMAC_CFG1_SHORT_ASSERT 0x00000020 -/* RCV only 802.3AE when CLEAR */ -#define AXGMAC_CFG1_RCV_STRICT 0x00000010 -#define AXGMAC_CFG1_CHECK_LEN 0x00000008 /* Verify frame length */ -#define AXGMAC_CFG1_GEN_FCS 0x00000004 /* Generate FCS */ -#define AXGMAC_CFG1_PAD_MASK 0x00000003 /* Mask for pad bits */ -#define AXGMAC_CFG1_PAD_64 0x00000001 /* Pad frames to 64 bytes */ -/* Detect VLAN and pad to 68 bytes */ -#define AXGMAC_CFG1_PAD_VLAN 0x00000002 -#define AXGMAC_CFG1_PAD_68 0x00000003 /* Pad to 68 bytes */ - -/* A-XGMAC Configuration Register 2 */ -/* Generate single pause frame (test) */ -#define AXGMAC_CFG2_GEN_PAUSE 0x80000000 -/* Manual link fault sequence */ -#define AXGMAC_CFG2_LF_MANUAL 0x08000000 -/* Auto link fault sequence */ -#define AXGMAC_CFG2_LF_AUTO 0x04000000 -/* Remote link fault (READ ONLY) */ -#define AXGMAC_CFG2_LF_REMOTE 0x02000000 -/* Local link fault (READ ONLY) */ -#define AXGMAC_CFG2_LF_LOCAL 0x01000000 -#define AXGMAC_CFG2_IPG_MASK 0x001F0000 /* Inter packet gap */ -#define AXGMAC_CFG2_IPG_SHIFT 16 -#define AXGMAC_CFG2_PAUSE_XMT 0x00008000 /* Pause transmit module */ -/* Enable IPG extension algorithm */ -#define AXGMAC_CFG2_IPG_EXTEN 0x00000020 -#define AXGMAC_CFG2_IPGEX_MASK 0x0000001F /* IPG extension */ - -/* A-XGMAC Configuration Register 3 */ -/* Receive frame drop filter */ -#define AXGMAC_CFG3_RCV_DROP 0xFFFF0000 -/* Receive frame don't care filter */ -#define AXGMAC_CFG3_RCV_DONT_CARE 0x0000FFFF - -/* A-XGMAC Station Address Register - Octets 1-4 */ -#define AXGMAC_SARLOW_OCTET_ONE 0xFF000000 /* First octet */ -#define AXGMAC_SARLOW_OCTET_TWO 0x00FF0000 /* Second octet */ -#define AXGMAC_SARLOW_OCTET_THREE 0x0000FF00 /* Third octet */ -#define AXGMAC_SARLOW_OCTET_FOUR 0x000000FF /* Fourth octet */ - -/* A-XGMAC Station Address Register - Octets 5-6 */ -#define AXGMAC_SARHIGH_OCTET_FIVE 0xFF000000 /* Fifth octet */ -#define AXGMAC_SARHIGH_OCTET_SIX 0x00FF0000 /* Sixth octet */ - -/* A-XGMAC Maximum frame length register */ -/* Maximum transmit frame length */ -#define AXGMAC_MAXFRAME_XMT 0x3FFF0000 -#define AXGMAC_MAXFRAME_XMT_SHIFT 16 -/* Maximum receive frame length */ -#define AXGMAC_MAXFRAME_RCV 0x0000FFFF -/* - * This register doesn't need to be written for standard MTU. - * For jumbo, I'll just statically define the value here. This - * value sets the receive byte count to 9036 (0x234C) and the - * transmit WORD count to 2259 (0x8D3). These values include 22 - * bytes of padding beyond the jumbo MTU of 9014 - */ -#define AXGMAC_MAXFRAME_JUMBO 0x08D3234C - -/* A-XGMAC Revision level */ -#define AXGMAC_REVISION_MASK 0x0000FFFF /* Revision level */ - -/* A-XGMAC AMIIM Command Register */ -#define AXGMAC_AMIIM_CMD_START 0x00000008 /* Command start */ -#define AXGMAC_AMIIM_CMD_MASK 0x00000007 /* Command */ -/* 10/100/1000 Mbps Phy Write */ -#define AXGMAC_AMIIM_CMD_LEGACY_WRITE 1 -/* 10/100/1000 Mbps Phy Read */ -#define AXGMAC_AMIIM_CMD_LEGACY_READ 2 -#define AXGMAC_AMIIM_CMD_MONITOR_SINGLE 3 /* Monitor single PHY */ -/* Monitor multiple contiguous PHYs */ -#define AXGMAC_AMIIM_CMD_MONITOR_MULTIPLE 4 -/* Present AMIIM Field Reg */ -#define AXGMAC_AMIIM_CMD_10G_OPERATION 5 -/* Clear Link Fail Bit in MIIM */ -#define AXGMAC_AMIIM_CMD_CLEAR_LINK_FAIL 6 - -/* A-XGMAC AMIIM Field Register */ -#define AXGMAC_AMIIM_FIELD_ST 0xC0000000 /* 2-bit ST field */ -#define AXGMAC_AMIIM_FIELD_ST_SHIFT 30 -#define AXGMAC_AMIIM_FIELD_OP 0x30000000 /* 2-bit OP field */ -#define AXGMAC_AMIIM_FIELD_OP_SHIFT 28 -/* Port address field (hstphyadx in spec) */ -#define AXGMAC_AMIIM_FIELD_PORT_ADDR 0x0F800000 -#define AXGMAC_AMIIM_FIELD_PORT_SHIFT 23 -/* Device address field (hstregadx in spec) */ -#define AXGMAC_AMIIM_FIELD_DEV_ADDR 0x007C0000 -#define AXGMAC_AMIIM_FIELD_DEV_SHIFT 18 -#define AXGMAC_AMIIM_FIELD_TA 0x00030000 /* 2-bit TA field */ -#define AXGMAC_AMIIM_FIELD_TA_SHIFT 16 -#define AXGMAC_AMIIM_FIELD_DATA 0x0000FFFF /* Data field */ - -/* Values for the AXGMAC_AMIIM_FIELD_OP field in the A-XGMAC AMIIM Field Register */ -#define MIIM_OP_ADDR 0 /* MIIM Address set operation */ -#define MIIM_OP_WRITE 1 /* MIIM Write register operation */ -#define MIIM_OP_READ 2 /* MIIM Read register operation */ -#define MIIM_OP_ADDR_SHIFT (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) - -/* - * Values for the AXGMAC_AMIIM_FIELD_PORT_ADDR field in the A-XGMAC AMIIM - * Field Register - */ -#define MIIM_PORT_NUM 1 /* All Sahara MIIM modules use port 1 */ - -/* - * Values for the AXGMAC_AMIIM_FIELD_DEV_ADDR field in the A-XGMAC AMIIM - * Field Register - */ -/* PHY PMA/PMD module MIIM device number */ -#define MIIM_DEV_PHY_PMA 1 -/* PHY PCS module MIIM device number */ -#define MIIM_DEV_PHY_PCS 3 -/* PHY XS module MIIM device number */ -#define MIIM_DEV_PHY_XS 4 -#define MIIM_DEV_XGXS 5 /* XGXS MIIM device number */ - -/* - * Values for the AXGMAC_AMIIM_FIELD_TA field in the A-XGMAC AMIIM Field - * Register - */ -#define MIIM_TA_10GB 2 /* set to 2 for 10 GB operation */ - -/* A-XGMAC AMIIM Configuration Register */ -/* Bypass preamble of mngmt frame */ -#define AXGMAC_AMIIM_CFG_NOPREAM 0x00000080 -/* half-clock duration of MDC output */ -#define AXGMAC_AMIIM_CFG_HALF_CLOCK 0x0000007F - -/* A-XGMAC AMIIM Indicator Register */ -/* Link status from legacy PHY or MMD */ -#define AXGMAC_AMIIM_INDC_LINK 0x00000010 -/* Multiple phy operation in progress */ -#define AXGMAC_AMIIM_INDC_MPHY 0x00000008 -/* Single phy operation in progress */ -#define AXGMAC_AMIIM_INDC_SPHY 0x00000004 -/* Single or multiple monitor cmd */ -#define AXGMAC_AMIIM_INDC_MON 0x00000002 -/* Set until cmd operation complete */ -#define AXGMAC_AMIIM_INDC_BUSY 0x00000001 - -/* Link Status and Control Register */ -#define LS_PHY_CLR_RESET 0x80000000 /* Clear reset signal to PHY */ -#define LS_SERDES_POWER_DOWN 0x40000000 /* Power down the Sahara Serdes */ -#define LS_XGXS_ENABLE 0x20000000 /* Enable the XAUI XGXS logic */ -/* Hold XAUI XGXS logic reset until Serdes is up */ -#define LS_XGXS_CTL 0x10000000 -/* When 0, XAUI Serdes is up and initialization is complete */ -#define LS_SERDES_DOWN 0x08000000 -/* When 0, Trace Serdes is up and initialization is complete */ -#define LS_TRACE_DOWN 0x04000000 -/* Set PHY clock to 25 MHz (else 156.125 MHz) */ -#define LS_PHY_CLK_25MHZ 0x02000000 -#define LS_PHY_CLK_EN 0x01000000 /* Enable clock to PHY */ -#define LS_XAUI_LINK_UP 0x00000010 /* XAUI link is up */ -/* XAUI link status has changed */ -#define LS_XAUI_LINK_CHNG 0x00000008 -#define LS_LINK_ALARM 0x00000004 /* Link alarm pin */ -/* Mask link attention control bits */ -#define LS_ATTN_CTRL_MASK 0x00000003 -#define LS_ATTN_ALARM 0x00000000 /* 00 => Attn on link alarm */ -/* 01 => Attn on link alarm or status change */ -#define LS_ATTN_ALARM_OR_STAT_CHNG 0x00000001 -/* 10 => Attn on link status change */ -#define LS_ATTN_STAT_CHNG 0x00000002 -#define LS_ATTN_NONE 0x00000003 /* 11 => no Attn */ - -/* Link Address High Registers */ -#define LINK_ADDR_ENABLE 0x80000000 /* Enable this link address */ - - -/* - * XGXS XAUI XGMII Extender registers - * - * Full register descriptions can be found in mxgxs.pdf - */ -/* XGXS Register Map */ -#define XGXS_ADDRESS_CONTROL1 0x0000 /* XS Control 1 */ -#define XGXS_ADDRESS_STATUS1 0x0001 /* XS Status 1 */ -#define XGXS_ADDRESS_DEVID_LOW 0x0002 /* XS Device ID (low) */ -#define XGXS_ADDRESS_DEVID_HIGH 0x0003 /* XS Device ID (high) */ -#define XGXS_ADDRESS_SPEED 0x0004 /* XS Speed ability */ -#define XGXS_ADDRESS_DEV_LOW 0x0005 /* XS Devices in package */ -#define XGXS_ADDRESS_DEV_HIGH 0x0006 /* XS Devices in package */ -#define XGXS_ADDRESS_STATUS2 0x0008 /* XS Status 2 */ -#define XGXS_ADDRESS_PKGID_lOW 0x000E /* XS Package Identifier */ -#define XGXS_ADDRESS_PKGID_HIGH 0x000F /* XS Package Identifier */ -#define XGXS_ADDRESS_LANE_STATUS 0x0018 /* 10G XGXS Lane Status */ -#define XGXS_ADDRESS_TEST_CTRL 0x0019 /* 10G XGXS Test Control */ -#define XGXS_ADDRESS_RESET_LO1 0x8000 /* Vendor-Specific Reset Lo 1 */ -#define XGXS_ADDRESS_RESET_LO2 0x8001 /* Vendor-Specific Reset Lo 2 */ -#define XGXS_ADDRESS_RESET_HI1 0x8002 /* Vendor-Specific Reset Hi 1 */ -#define XGXS_ADDRESS_RESET_HI2 0x8003 /* Vendor-Specific Reset Hi 2 */ - -/* XS Control 1 register bit definitions */ -#define XGXS_CONTROL1_RESET 0x8000 /* Reset - self clearing */ -#define XGXS_CONTROL1_LOOPBACK 0x4000 /* Enable loopback */ -#define XGXS_CONTROL1_SPEED1 0x2000 /* 0 = unspecified, 1 = 10Gb+ */ -#define XGXS_CONTROL1_LOWPOWER 0x0400 /* 1 = Low power mode */ -#define XGXS_CONTROL1_SPEED2 0x0040 /* Same as SPEED1 (?) */ -/* Everything reserved except zero (?) */ -#define XGXS_CONTROL1_SPEED 0x003C - -/* XS Status 1 register bit definitions */ -#define XGXS_STATUS1_FAULT 0x0080 /* Fault detected */ -#define XGXS_STATUS1_LINK 0x0004 /* 1 = Link up */ -#define XGXS_STATUS1_LOWPOWER 0x0002 /* 1 = Low power supported */ - -/* XS Speed register bit definitions */ -#define XGXS_SPEED_10G 0x0001 /* 1 = 10G capable */ - -/* XS Devices register bit definitions */ -#define XGXS_DEVICES_DTE 0x0020 /* DTE XS Present */ -#define XGXS_DEVICES_PHY 0x0010 /* PHY XS Present */ -#define XGXS_DEVICES_PCS 0x0008 /* PCS Present */ -#define XGXS_DEVICES_WIS 0x0004 /* WIS Present */ -#define XGXS_DEVICES_PMD 0x0002 /* PMD/PMA Present */ -#define XGXS_DEVICES_CLAUSE22 0x0001 /* Clause 22 registers present*/ - -/* XS Devices High register bit definitions */ -#define XGXS_DEVICES_VENDOR2 0x8000 /* Vendor specific device 2 */ -#define XGXS_DEVICES_VENDOR1 0x4000 /* Vendor specific device 1 */ - -/* XS Status 2 register bit definitions */ -#define XGXS_STATUS2_DEV_MASK 0xC000 /* Device present mask */ -#define XGXS_STATUS2_DEV_RESPOND 0x8000 /* Device responding */ -#define XGXS_STATUS2_XMT_FAULT 0x0800 /* Transmit fault */ -#define XGXS_STATUS2_RCV_FAULT 0x0400 /* Receive fault */ - -/* XS Package ID High register bit definitions */ -#define XGXS_PKGID_HIGH_ORG 0xFC00 /* Organizationally Unique */ -#define XGXS_PKGID_HIGH_MFG 0x03F0 /* Manufacturer Model */ -#define XGXS_PKGID_HIGH_REV 0x000F /* Revision Number */ - -/* XS Lane Status register bit definitions */ -#define XGXS_LANE_PHY 0x1000 /* PHY/DTE lane alignment status */ -#define XGXS_LANE_PATTERN 0x0800 /* Pattern testing ability */ -#define XGXS_LANE_LOOPBACK 0x0400 /* PHY loopback ability */ -#define XGXS_LANE_SYNC3 0x0008 /* Lane 3 sync */ -#define XGXS_LANE_SYNC2 0x0004 /* Lane 2 sync */ -#define XGXS_LANE_SYNC1 0x0002 /* Lane 1 sync */ -#define XGXS_LANE_SYNC0 0x0001 /* Lane 0 sync */ - -/* XS Test Control register bit definitions */ -#define XGXS_TEST_PATTERN_ENABLE 0x0004 /* Test pattern enabled */ -#define XGXS_TEST_PATTERN_MASK 0x0003 /* Test patterns */ -#define XGXS_TEST_PATTERN_RSVD 0x0003 /* Test pattern - reserved */ -#define XGXS_TEST_PATTERN_MIX 0x0002 /* Test pattern - mixed */ -#define XGXS_TEST_PATTERN_LOW 0x0001 /* Test pattern - low */ -#define XGXS_TEST_PATTERN_HIGH 0x0001 /* Test pattern - high */ - -/* - * External MDIO Bus Registers - * - * Full register descriptions can be found in PHY/XENPAK/IEEE specs - */ -/* - * LASI (Link Alarm Status Interrupt) Registers (located in - * MIIM_DEV_PHY_PMA device) - */ -#define LASI_RX_ALARM_CONTROL 0x9000 /* LASI RX_ALARM Control */ -#define LASI_TX_ALARM_CONTROL 0x9001 /* LASI TX_ALARM Control */ -#define LASI_CONTROL 0x9002 /* LASI Control */ -#define LASI_RX_ALARM_STATUS 0x9003 /* LASI RX_ALARM Status */ -#define LASI_TX_ALARM_STATUS 0x9004 /* LASI TX_ALARM Status */ -#define LASI_STATUS 0x9005 /* LASI Status */ - -/* LASI_CONTROL bit definitions */ -/* Enable RX_ALARM interrupts */ -#define LASI_CTL_RX_ALARM_ENABLE 0x0004 -/* Enable TX_ALARM interrupts */ -#define LASI_CTL_TX_ALARM_ENABLE 0x0002 -/* Enable Link Status interrupts */ -#define LASI_CTL_LS_ALARM_ENABLE 0x0001 - -/* LASI_STATUS bit definitions */ -#define LASI_STATUS_RX_ALARM 0x0004 /* RX_ALARM status */ -#define LASI_STATUS_TX_ALARM 0x0002 /* TX_ALARM status */ -#define LASI_STATUS_LS_ALARM 0x0001 /* Link Status */ - -/* PHY registers - PMA/PMD (device 1) */ -#define PHY_PMA_CONTROL1 0x0000 /* PMA/PMD Control 1 */ -#define PHY_PMA_STATUS1 0x0001 /* PMA/PMD Status 1 */ -#define PHY_PMA_RCV_DET 0x000A /* PMA/PMD Receive Signal Detect */ - /* other PMA/PMD registers exist and can be defined as needed */ - -/* PHY registers - PCS (device 3) */ -#define PHY_PCS_CONTROL1 0x0000 /* PCS Control 1 */ -#define PHY_PCS_STATUS1 0x0001 /* PCS Status 1 */ -#define PHY_PCS_10G_STATUS1 0x0020 /* PCS 10GBASE-R Status 1 */ - /* other PCS registers exist and can be defined as needed */ - -/* PHY registers - XS (device 4) */ -#define PHY_XS_CONTROL1 0x0000 /* XS Control 1 */ -#define PHY_XS_STATUS1 0x0001 /* XS Status 1 */ -#define PHY_XS_LANE_STATUS 0x0018 /* XS Lane Status */ - /* other XS registers exist and can be defined as needed */ - -/* PHY_PMA_CONTROL1 register bit definitions */ -#define PMA_CONTROL1_RESET 0x8000 /* PMA/PMD reset */ - -/* PHY_PMA_RCV_DET register bit definitions */ -#define PMA_RCV_DETECT 0x0001 /* PMA/PMD receive signal detect */ - -/* PHY_PCS_10G_STATUS1 register bit definitions */ -#define PCS_10B_BLOCK_LOCK 0x0001 /* PCS 10GBASE-R locked to receive blocks */ - -/* PHY_XS_LANE_STATUS register bit definitions */ -#define XS_LANE_ALIGN 0x1000 /* XS transmit lanes aligned */ - -#define XCVR_VENDOR_LEN 16 /* xcvr vendor len */ -#define XCVR_MODEL_LEN 16 /* xcvr model len */ - -/* PHY Microcode download data structure */ -struct phy_ucode { - ushort Addr; - ushort Data; -}; - -/* Slow Bus Register Definitions */ - -/* Module 0 registers */ -#define GPIO_L_IN 0x15 /* GPIO input (low) */ -#define GPIO_L_OUT 0x16 /* GPIO output (low) */ -#define GPIO_L_DIR 0x17 /* GPIO direction (low) */ -#define GPIO_H_IN 0x19 /* GPIO input (high) */ -#define GPIO_H_OUT 0x1A /* GPIO output (high) */ -#define GPIO_H_DIR 0x1B /* GPIO direction (high) */ - -/* Definitions for other slow bus registers can be added as needed */ - - -/* - * Transmit Sequencer Command Descriptor definitions - * - * This descriptor must be placed in GRAM. The address of this descriptor - * (along with a couple of control bits) is pushed onto the PxhCmdQ or PxlCmdQ - * (Proxy high or low command queue). This data is read by the Proxy Sequencer, - * which pushes it onto the XmtCmdQ, which is (eventually) read by the Transmit - * Sequencer, causing a packet to be transmitted. Not all fields are valid for - * all commands - see the Sahara spec for details. Note that this structure is - * only valid when compiled on a little endian machine. - */ -#pragma pack(push, 1) -struct xmt_desc { - ushort XmtLen; /* word 0, bits [15:0] - transmit length */ - /* word 0, bits [23:16] - transmit control byte */ - unsigned char XmtCtl; - /* word 0, bits [31:24] - transmit command plus misc. */ - unsigned char Cmd; - /* word 1, bits [31:0] - transmit buffer ID */ - u32 XmtBufId; - /* word 2, bits [7:0] - byte address of TCP header */ - unsigned char TcpStrt; - /* word 2, bits [15:8] - byte address of IP header */ - unsigned char IpStrt; - /* word 2, bits [31:16] - partial IP checksum */ - ushort IpCkSum; - /* word 3, bits [15:0] - partial TCP checksum */ - ushort TcpCkSum; - ushort Rsvd1; /* word 3, bits [31:16] - PAD */ - u32 Rsvd2; /* word 4, bits [31:0] - PAD */ - u32 Rsvd3; /* word 5, bits [31:0] - PAD */ - u32 Rsvd4; /* word 6, bits [31:0] - PAD */ - u32 Rsvd5; /* word 7, bits [31:0] - PAD */ -}; -#pragma pack(pop) - -/* struct xmt_desc Cmd byte definitions */ - /* command codes */ -#define XMT_DESC_CMD_RAW_SEND 0 /* raw send descriptor */ -#define XMT_DESC_CMD_CSUM_INSERT 1 /* checksum insert descriptor */ -#define XMT_DESC_CMD_FORMAT 2 /* format descriptor */ -#define XMT_DESC_CMD_PRIME 3 /* prime descriptor */ -/* comand code shift (shift to bits [31:30] in word 0) */ -#define XMT_DESC_CMD_CODE_SHFT 6 - /* shifted command codes */ -#define XMT_RAW_SEND (XMT_DESC_CMD_RAW_SEND << XMT_DESC_CMD_CODE_SHFT) -#define XMT_CSUM_INSERT (XMT_DESC_CMD_CSUM_INSERT << XMT_DESC_CMD_CODE_SHFT) -#define XMT_FORMAT (XMT_DESC_CMD_FORMAT << XMT_DESC_CMD_CODE_SHFT) -#define XMT_PRIME (XMT_DESC_CMD_PRIME << XMT_DESC_CMD_CODE_SHFT) - -/* - * struct xmt_desc Control Byte (XmtCtl) definitions - * NOTE: These bits do not work on Sahara (Rev A)! - */ -/* current frame is a pause control frame (for statistics) */ -#define XMT_CTL_PAUSE_FRAME 0x80 -/* current frame is a control frame (for statistics) */ -#define XMT_CTL_CONTROL_FRAME 0x40 -#define XMT_CTL_PER_PKT_QUAL 0x20 /* per packet qualifier */ -#define XMT_CTL_PAD_MODE_NONE 0x00 /* do not pad frame */ -#define XMT_CTL_PAD_MODE_64 0x08 /* pad frame to 64 bytes */ -/* pad frame to 64 bytes, and VLAN frames to 68 bytes */ -#define XMT_CTL_PAD_MODE_VLAN_68 0x10 -#define XMT_CTL_PAD_MODE_68 0x18 /* pad frame to 68 bytes */ -/* generate FCS (CRC) for this frame */ -#define XMT_CTL_GEN_FCS 0x04 -#define XMT_CTL_DELAY_FCS_0 0x00 /* do not delay FCS calcution */ -/* delay FCS calculation by 1 (4-byte) word */ -#define XMT_CTL_DELAY_FCS_1 0x01 -/* delay FCS calculation by 2 (4-byte) words */ -#define XMT_CTL_DELAY_FCS_2 0x02 -/* delay FCS calculation by 3 (4-byte) words */ -#define XMT_CTL_DELAY_FCS_3 0x03 - -/* struct xmt_desc XmtBufId definition */ -/* - * The Xmt buffer ID is formed by dividing the buffer (DRAM) address - * by 256 (or << 8) - */ - -#define XMT_BUF_ID_SHFT 8 - -/* Receiver Sequencer Definitions */ - -/* Receive Event Queue (queues 3 - 6) bit definitions */ -/* bit mask for the Receive Buffer ID */ -#define RCV_EVTQ_RBFID_MASK 0x0000FFFF - -/* Receive Buffer ID definition */ -/* - * The Rcv buffer ID is formed by dividing the buffer (DRAM) address - * by 32 (or << 5) - */ -#define RCV_BUF_ID_SHFT 5 - -/* - * Format of the 18 byte Receive Buffer returned by the - * Receive Sequencer for received packets - */ -#pragma pack(push, 1) -struct rcv_buf_hdr { - u32 Status; /* Status word from Rcv Seq Parser */ - ushort Length; /* Rcv packet byte count */ - union { - ushort TcpCsum; /* TCP checksum */ - struct { - /* lower 8 bits of the TCP checksum */ - unsigned char TcpCsumL; - /* Link hash (multicast frames only) */ - unsigned char LinkHash; - }; - }; - ushort SktHash; /* Socket hash */ - unsigned char TcpHdrOffset; /* TCP header offset into packet */ - unsigned char IpHdrOffset; /* IP header offset into packet */ - u32 TpzHash; /* Toeplitz hash */ - ushort Reserved; /* Reserved */ -}; -#pragma pack(pop) - -/* Queue definitions */ - -/* Ingress (read only) queue numbers */ -#define PXY_BUF_Q 0 /* Proxy Buffer Queue */ -#define HST_EVT_Q 1 /* Host Event Queue */ -#define XMT_BUF_Q 2 /* Transmit Buffer Queue */ -#define SKT_EVL_Q 3 /* RcvSqr Socket Event Low Priority Queue */ -#define RCV_EVL_Q 4 /* RcvSqr Rcv Event Low Priority Queue */ -#define SKT_EVH_Q 5 /* RcvSqr Socket Event High Priority Queue */ -#define RCV_EVH_Q 6 /* RcvSqr Rcv Event High Priority Queue */ -#define DMA_RSP_Q 7 /* Dma Response Queue - one per CPU context */ -/* Local (read/write) queue numbers */ -#define LOCAL_A_Q 8 /* Spare local Queue */ -#define LOCAL_B_Q 9 /* Spare local Queue */ -#define LOCAL_C_Q 10 /* Spare local Queue */ -#define FSM_EVT_Q 11 /* Finite-State-Machine Event Queue */ -#define SBF_PAL_Q 12 /* System Buffer Physical Address (low) Queue */ -#define SBF_PAH_Q 13 /* System Buffer Physical Address (high) Queue*/ -#define SBF_VAL_Q 14 /* System Buffer Virtual Address (low) Queue */ -#define SBF_VAH_Q 15 /* System Buffer Virtual Address (high) Queue */ -/* Egress (write only) queue numbers */ -#define H2G_CMD_Q 16 /* Host to GlbRam DMA Command Queue */ -#define H2D_CMD_Q 17 /* Host to DRAM DMA Command Queue */ -#define G2H_CMD_Q 18 /* GlbRam to Host DMA Command Queue */ -#define G2D_CMD_Q 19 /* GlbRam to DRAM DMA Command Queue */ -#define D2H_CMD_Q 20 /* DRAM to Host DMA Command Queue */ -#define D2G_CMD_Q 21 /* DRAM to GlbRam DMA Command Queue */ -#define D2D_CMD_Q 22 /* DRAM to DRAM DMA Command Queue */ -#define PXL_CMD_Q 23 /* Low Priority Proxy Command Queue */ -#define PXH_CMD_Q 24 /* High Priority Proxy Command Queue */ -#define RSQ_CMD_Q 25 /* Receive Sequencer Command Queue */ -#define RCV_BUF_Q 26 /* Receive Buffer Queue */ - -/* Bit definitions for the Proxy Command queues (PXL_CMD_Q and PXH_CMD_Q) */ -/* enable copy of xmt descriptor to xmt command queue */ -#define PXY_COPY_EN 0x00200000 -#define PXY_SIZE_16 0x00000000 /* copy 16 bytes */ -#define PXY_SIZE_32 0x00100000 /* copy 32 bytes */ - -/* SXG EEPROM/Flash Configuration Definitions */ - -/* Location of configuration data in EEPROM or Flash */ -/* start addr for config info in EEPROM */ -#define EEPROM_CONFIG_START_ADDR 0x00 -/* start addr for config info in Flash */ -#define FLASH_CONFIG_START_ADDR 0x80 - -/* Configuration data section defines */ -#define HW_CFG_SECTION_SIZE 512 /* size of H/W section */ -#define HW_CFG_SECTION_SIZE_A 256 /* size of H/W section (Sahara rev A) */ -/* starting location (offset) of S/W section */ -#define SW_CFG_SECTION_START 512 -/* starting location (offset) of S/W section (Sahara rev A) */ -#define SW_CFG_SECTION_START_A 256 -#define SW_CFG_SECTION_SIZE 128 /* size of S/W section */ -/* - * H/W configuration data magic word Goes in Addr field of first - * struct hw_cfg_data entry - */ -#define HW_CFG_MAGIC_WORD 0xA5A5 -/* - * H/W configuration data terminator Goes in Addr field of last - * struct hw_cfg_data entry - */ -#define HW_CFG_TERMINATOR 0xFFFF - -#define SW_CFG_MAGIC_WORD 0x5A5A /* S/W configuration data magic word */ - -#pragma pack(push, 1) -/* - * Structure for an element of H/W configuration data. - * Read by the Sahara hardware - */ -struct hw_cfg_data { - ushort Addr; - ushort Data; -}; - -/* - * Number of struct hw_cfg_data structures to put in the configuration data - * data structure (struct sxg_config or struct sxg_config_a). The number is - * computed to fill the entire H/W config section of the structure. - */ -#define NUM_HW_CFG_ENTRIES \ - (HW_CFG_SECTION_SIZE / sizeof(struct hw_cfg_data)) -#define NUM_HW_CFG_ENTRIES_A \ - (HW_CFG_SECTION_SIZE_A / sizeof(struct hw_cfg_data)) - -/* MAC address structure */ -struct sxg_config_mac { - unsigned char MacAddr[6]; /* MAC Address */ -}; - -/* FRU data structure */ -struct atk_fru { - unsigned char PartNum[6]; - unsigned char Revision[2]; - unsigned char Serial[14]; -}; - -/* OEM FRU Format types */ -#define ATK_FRU_FORMAT 0x0000 -#define CPQ_FRU_FORMAT 0x0001 -#define DELL_FRU_FORMAT 0x0002 -#define HP_FRU_FORMAT 0x0003 -#define IBM_FRU_FORMAT 0x0004 -#define EMC_FRU_FORMAT 0x0005 -#define NO_FRU_FORMAT 0xFFFF - -#define ATK_OEM_ASSY_SIZE 10 /* assy num is 9 chars plus \0 */ - -/* OEM FRU structure for Alacritech */ -struct atk_oem { - unsigned char Assy[ATK_OEM_ASSY_SIZE]; -}; - -#define OEM_EEPROM_FRUSIZE 74 /* size of OEM fru info - size */ -/* chosen to fill out the S/W section */ - -union oem_fru { /* OEM FRU information */ - unsigned char OemFru[OEM_EEPROM_FRUSIZE]; - struct atk_oem AtkOem; -}; - -/* Structure to hold the S/W configuration data. */ -struct sw_cfg_data { - ushort MagicWord; /* Magic word for section 2 */ - ushort Version; /* Format version */ - struct sxg_config_mac MacAddr[4]; /* space for 4 MAC addresses */ - struct atk_fru AtkFru; /* FRU information */ - ushort OemFruFormat; /* OEM FRU format type */ - union oem_fru OemFru; /* OEM FRU information */ - ushort Checksum; /* Checksum of section 2 */ -}; - - -/* EEPROM/Flash Format */ -struct sxg_config { - /* H/W Section - Read by Sahara hardware (512 bytes) */ - struct hw_cfg_data HwCfg[NUM_HW_CFG_ENTRIES]; - /* S/W Section - Other configuration data (128 bytes) */ - struct sw_cfg_data SwCfg; -}; - -#ifdef WINDOWS_COMPILER -/* - * The following macro is something of a kludge, but it is the only way - * that I could find to catch certain programming errors at compile time. - * If the asserted condition is true, then nothing happens. If false, then - * the compiler tries to typedef an array with -1 members, which generates - * an error. Unfortunately, the error message is meaningless, but at least - * it catches the problem. This macro would be unnecessary if the compiler - * allowed the sizeof and offsetof macros to be used in the #if directive. - */ -#define compile_time_assert(cond) \ - typedef char comp_error[(cond) ? 1 : -1] - -/* - * A compiler error on either of the next two lines indicates that the struct sxg_config - * structure was built incorrectly. Unfortunately, the error message produced - * is meaningless. But this is apparently the only way to catch this problem - * at compile time. - */ -compile_time_assert (offsetof(struct sxg_config, SwCfg) == SW_CFG_SECTION_START); -compile_time_assert (sizeof(struct sxg_config) == HW_CFG_SECTION_SIZE - + SW_CFG_SECTION_SIZE); - -compile_time_assert (offsetof(struct sxg_config_a, SwCfg) - == SW_CFG_SECTION_START_A); -compile_time_assert (sizeof(struct sxg_config_a) == HW_CFG_SECTION_SIZE_A - + SW_CFG_SECTION_SIZE); -#endif -/* - * Structure used to pass information between driver and user-mode - * control application - */ -struct adapt_userinfo { - bool LinkUp; - /* use LinkUp - any need for other states? */ - /* u32 LinkState; */ - u32 LinkSpeed; /* not currently needed */ - u32 LinkDuplex; /* not currently needed */ - enum xcvr_type XcvrType; /* type of xcvr on fiber card */ - /* fiber card xcvr vendor */ - unsigned char XcvrVendor[XCVR_VENDOR_LEN]; - unsigned char XcvrMode[XCVR_MODEL_LEN]; - u32 Port; /* not currently needed */ - u32 PhysPort; /* not currently needed */ - ushort PciLanes; - unsigned char MacAddr[6]; - unsigned char CurrMacAddr[6]; - struct atk_fru AtkFru; - ushort OemFruFormat; - union oem_fru OemFru; -}; - -#pragma pack(pop) - -/* Miscellaneous Hardware definitions */ - -/* Hardware Type definitions */ - -/* Sahara (ASIC level) defines */ -#define SAHARA_GRAM_SIZE 0x020000 /* GRAM size - 128 KB */ -#define SAHARA_DRAM_SIZE 0x200000 /* DRAM size - 2 MB */ -/* QRAM size - 16K entries (64 KB) */ -#define SAHARA_QRAM_SIZE 0x004000 -/* WCS - 8K instructions (x 108 bits) */ -#define SAHARA_WCS_SIZE 0x002000 - -/* Arabia (board level) defines */ -#define FLASH_SIZE 0x080000 /* 512 KB (4 Mb) */ -/* EEPROM size (bytes), including xfmr area */ -#define EEPROM_SIZE_XFMR 1024 -/* EEPROM size excluding xfmr area (512 + 128) */ -#define EEPROM_SIZE_NO_XFMR 640 -/* EEPROM size for Sahara rev A */ -#define EEPROM_SIZE_REV_A 512 --- a/drivers/staging/sxg/sxg_os.h +++ /dev/null @@ -1,149 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2000-2008 Alacritech, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Alacritech, Inc. - * - **************************************************************************/ - -/* - * FILENAME: sxg_os.h - * - * These are the Linux-specific definitions required for the SLICOSS - * driver, which should allow for greater portability to other OSes. - */ -#ifndef _SLIC_OS_SPECIFIC_H_ -#define _SLIC_OS_SPECIFIC_H_ - -#define FALSE (0) -#define TRUE (1) - -struct list_entry { - struct list_entry *nle_flink; - struct list_entry *nle_blink; -}; - -#define InitializeListHead(l) \ - (l)->nle_flink = (l)->nle_blink = (l) - -#define IsListEmpty(h) \ - ((h)->nle_flink == (h)) - -#define RemoveEntryList(e) \ - do { \ - list_entry *b; \ - list_entry *f; \ - \ - f = (e)->nle_flink; \ - b = (e)->nle_blink; \ - b->nle_flink = f; \ - f->nle_blink = b; \ - } while (0) - -/* These two have to be inlined since they return things. */ - -static inline struct list_entry *RemoveHeadList(struct list_entry *l) -{ - struct list_entry *f; - struct list_entry *e; - - e = l->nle_flink; - f = e->nle_flink; - l->nle_flink = f; - f->nle_blink = l; - - return (e); -} - -static inline struct list_entry *RemoveTailList(struct list_entry *l) -{ - struct list_entry *b; - struct list_entry *e; - - e = l->nle_blink; - b = e->nle_blink; - l->nle_blink = b; - b->nle_flink = l; - - return (e); -} - -#define InsertTailList(l, e) \ - do { \ - struct list_entry *b; \ - \ - b = (l)->nle_blink; \ - (e)->nle_flink = (l); \ - (e)->nle_blink = b; \ - b->nle_flink = (e); \ - (l)->nle_blink = (e); \ - } while (0) - -#define InsertHeadList(l, e) \ - do { \ - struct list_entry *f; \ - \ - f = (l)->nle_flink; \ - (e)->nle_flink = f; \ - (e)->nle_blink = l; \ - f->nle_blink = (e); \ - (l)->nle_flink = (e); \ - } while (0) - -#define ATK_DEBUG 1 - -#if ATK_DEBUG -#define SLIC_TIMESTAMP(value) { \ - struct timeval timev; \ - do_gettimeofday(&timev); \ - value = timev.tv_sec*1000000 + timev.tv_usec; \ -} -#else -#define SLIC_TIMESTAMP(value) -#endif - -/* SXG DEFINES */ - -#ifdef ATKDBG -#define SXG_TIMESTAMP(value) { \ - struct timeval timev; \ - do_gettimeofday(&timev); \ - value = timev.tv_sec*1000000 + timev.tv_usec; \ -} -#else -#define SXG_TIMESTAMP(value) -#endif - -#define WRITE_REG(reg,value,flush) \ - sxg_reg32_write((®), (value), (flush)) -#define WRITE_REG64(a,reg,value,cpu) \ - sxg_reg64_write((a),(®),(value),(cpu)) -#define READ_REG(reg,value) (value) = readl((void __iomem *)(®)) - -#endif /* _SLIC_OS_SPECIFIC_H_ */ --- a/drivers/staging/sxg/sxgphycode-1.2.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright ? 1997-2008 Alacritech, Inc. All rights reserved - * - * $Id: sxgphycode.h,v 1.2 2008/10/02 01:44:07 Exp $ - * - * sxgphycode.h: - * - * This file PHY microcode and register initialization data. - */ - -/********************************************************************** - * PHY Microcode - **********************************************************************/ -// -// The following contains both PHY microcode and PHY register -// initialization data. It is specific to both the PHY and the -// type of transceiver. -// - -// Download for AEL2005C PHY with SR/LR transceiver (10GBASE-SR or 10GBASE-LR) -// AEL2005 SR firmware rev 18 (microInit_mdio_SR_AEL2005C_18.tx). -static struct phy_ucode PhyUcode[] = { - // NOTE: An address of 0 is a special case. When the download routine - // sees an address of 0, it does not write to the PHY. Instead, it delays - // the download. The length of the delay (in ms) is given in the data field. - // Delays are required at certain points. - - // Platform-specific MDIO Patches: - // (include patches for 10G RX polarity flip, 50Mhz Synth, etc) - // Addr Data - {0xc017, 0xfeb0}, // flip RX_LOS polarity (mandatory patch for SFP+ applications) - {0xC001, 0x0428}, // flip RX serial polarity - - {0xc013, 0xf341}, // invert lxmit clock (mandatory patch) - {0xc210, 0x8000}, // reset datapath (mandatory patch) - {0xc210, 0x8100}, // reset datapath (mandatory patch) - {0xc210, 0x8000}, // reset datapath (mandatory patch) - {0xc210, 0x0000}, // reset datapath (mandatory patch) - {0x0000, 0x0032}, // wait for 50ms for datapath reset to complete. (mandatory patch) - - // Transceiver-specific MDIO Patches: - {0xc003, 0x0181}, // (bit 7) enable the CDR inc setting in 1.C005 (mandatory patch for SR code) - {0xc010, 0x448a}, // (bit 14) mask out high BER input from the LOS signal in 1.000A (mandatory patch for SR code) - - // Transceiver-specific Microcontroller Initialization: - {0xc04a, 0x5200}, // activate microcontroller and pause - {0x0000, 0x0032}, // wait 50ms for microcontroller before writing in code. - - // code block starts here: - {0xcc00, 0x2ff4}, {0xcc01, 0x3cd4}, {0xcc02, 0x2015}, {0xcc03, 0x3125}, - {0xcc04, 0x6524}, {0xcc05, 0x27ff}, {0xcc06, 0x300f}, {0xcc07, 0x2c8b}, - {0xcc08, 0x300b}, {0xcc09, 0x4009}, {0xcc0a, 0x400e}, {0xcc0b, 0x2f12}, - {0xcc0c, 0x3002}, {0xcc0d, 0x1002}, {0xcc0e, 0x2112}, {0xcc0f, 0x3012}, - {0xcc10, 0x1002}, {0xcc11, 0x2572}, {0xcc12, 0x3012}, {0xcc13, 0x1002}, - {0xcc14, 0xd01e}, {0xcc15, 0x2772}, {0xcc16, 0x3012}, {0xcc17, 0x1002}, - {0xcc18, 0x2004}, {0xcc19, 0x3c84}, {0xcc1a, 0x6436}, {0xcc1b, 0x2007}, - {0xcc1c, 0x3f87}, {0xcc1d, 0x8676}, {0xcc1e, 0x40b7}, {0xcc1f, 0xa746}, - {0xcc20, 0x4047}, {0xcc21, 0x5673}, {0xcc22, 0x2982}, {0xcc23, 0x3002}, - {0xcc24, 0x13d2}, {0xcc25, 0x8bbd}, {0xcc26, 0x2802}, {0xcc27, 0x3012}, - {0xcc28, 0x1002}, {0xcc29, 0x2032}, {0xcc2a, 0x3012}, {0xcc2b, 0x1002}, - {0xcc2c, 0x5cc3}, {0xcc2d, 0x0314}, {0xcc2e, 0x2942}, {0xcc2f, 0x3002}, - {0xcc30, 0x1002}, {0xcc31, 0xd019}, {0xcc32, 0x2fd2}, {0xcc33, 0x3002}, - {0xcc34, 0x1002}, {0xcc35, 0x2a04}, {0xcc36, 0x3c74}, {0xcc37, 0x6435}, - {0xcc38, 0x2fa4}, {0xcc39, 0x3cd4}, {0xcc3a, 0x6624}, {0xcc3b, 0x5563}, - {0xcc3c, 0x2d42}, {0xcc3d, 0x3002}, {0xcc3e, 0x13d2}, {0xcc3f, 0x464d}, - {0xcc40, 0x2802}, {0xcc41, 0x3012}, {0xcc42, 0x1002}, {0xcc43, 0x2fd2}, - {0xcc44, 0x3002}, {0xcc45, 0x1002}, {0xcc46, 0x2fb4}, {0xcc47, 0x3cd4}, - {0xcc48, 0x6624}, {0xcc49, 0x5563}, {0xcc4a, 0x2d42}, {0xcc4b, 0x3002}, - {0xcc4c, 0x13d2}, {0xcc4d, 0x2e72}, {0xcc4e, 0x3002}, {0xcc4f, 0x1002}, - {0xcc50, 0x2f72}, {0xcc51, 0x3002}, {0xcc52, 0x1002}, {0xcc53, 0x0004}, - {0xcc54, 0x2942}, {0xcc55, 0x3002}, {0xcc56, 0x1002}, {0xcc57, 0x2032}, - {0xcc58, 0x3012}, {0xcc59, 0x1002}, {0xcc5a, 0x5cc3}, {0xcc5b, 0x0317}, - {0xcc5c, 0x2f12}, {0xcc5d, 0x3002}, {0xcc5e, 0x1002}, {0xcc5f, 0x2942}, - {0xcc60, 0x3002}, {0xcc61, 0x1002}, {0xcc62, 0x22cd}, {0xcc63, 0x301d}, - {0xcc64, 0x2802}, {0xcc65, 0x3012}, {0xcc66, 0x1002}, {0xcc67, 0x20b2}, - {0xcc68, 0x3012}, {0xcc69, 0x1002}, {0xcc6a, 0x5aa3}, {0xcc6b, 0x2dc2}, - {0xcc6c, 0x3002}, {0xcc6d, 0x1312}, {0xcc6e, 0x2d02}, {0xcc6f, 0x3002}, - {0xcc70, 0x1002}, {0xcc71, 0x2807}, {0xcc72, 0x31a7}, {0xcc73, 0x20c4}, - {0xcc74, 0x3c24}, {0xcc75, 0x6724}, {0xcc76, 0x1002}, {0xcc77, 0x2807}, - {0xcc78, 0x3187}, {0xcc79, 0x20c4}, {0xcc7a, 0x3c24}, {0xcc7b, 0x6724}, - {0xcc7c, 0x1002}, {0xcc7d, 0x2514}, {0xcc7e, 0x3c64}, {0xcc7f, 0x6436}, - {0xcc80, 0xdff4}, {0xcc81, 0x6436}, {0xcc82, 0x1002}, {0xcc83, 0x40a4}, - {0xcc84, 0x643c}, {0xcc85, 0x4016}, {0xcc86, 0x8c6c}, {0xcc87, 0x2b24}, - {0xcc88, 0x3c24}, {0xcc89, 0x6435}, {0xcc8a, 0x1002}, {0xcc8b, 0x2b24}, - {0xcc8c, 0x3c24}, {0xcc8d, 0x643a}, {0xcc8e, 0x4025}, {0xcc8f, 0x8a5a}, - {0xcc90, 0x1002}, {0xcc91, 0x26d1}, {0xcc92, 0x3011}, {0xcc93, 0x1001}, - {0xcc94, 0xc7a0}, {0xcc95, 0x0100}, {0xcc96, 0xc502}, {0xcc97, 0x53ac}, - {0xcc98, 0xc503}, {0xcc99, 0xd5d5}, {0xcc9a, 0xc600}, {0xcc9b, 0x2a6d}, - {0xcc9c, 0xc601}, {0xcc9d, 0x2a4c}, {0xcc9e, 0xc602}, {0xcc9f, 0x0111}, - {0xcca0, 0xc60c}, {0xcca1, 0x5900}, {0xcca2, 0xc710}, {0xcca3, 0x0700}, - {0xcca4, 0xc718}, {0xcca5, 0x0700}, {0xcca6, 0xc720}, {0xcca7, 0x4700}, - {0xcca8, 0xc801}, {0xcca9, 0x7f50}, {0xccaa, 0xc802}, {0xccab, 0x7760}, - {0xccac, 0xc803}, {0xccad, 0x7fce}, {0xccae, 0xc804}, {0xccaf, 0x5700}, - {0xccb0, 0xc805}, {0xccb1, 0x5f11}, {0xccb2, 0xc806}, {0xccb3, 0x4751}, - {0xccb4, 0xc807}, {0xccb5, 0x57e1}, {0xccb6, 0xc808}, {0xccb7, 0x2700}, - {0xccb8, 0xc809}, {0xccb9, 0x0000}, {0xccba, 0xc821}, {0xccbb, 0x0002}, - {0xccbc, 0xc822}, {0xccbd, 0x0014}, {0xccbe, 0xc832}, {0xccbf, 0x1186}, - {0xccc0, 0xc847}, {0xccc1, 0x1e02}, {0xccc2, 0xc013}, {0xccc3, 0xf341}, - {0xccc4, 0xc01a}, {0xccc5, 0x0446}, {0xccc6, 0xc024}, {0xccc7, 0x1000}, - {0xccc8, 0xc025}, {0xccc9, 0x0a00}, {0xccca, 0xc026}, {0xcccb, 0x0c0c}, - {0xcccc, 0xc027}, {0xcccd, 0x0c0c}, {0xccce, 0xc029}, {0xcccf, 0x00a0}, - {0xccd0, 0xc030}, {0xccd1, 0x0a00}, {0xccd2, 0xc03c}, {0xccd3, 0x001c}, - {0xccd4, 0xc005}, {0xccd5, 0x7a06}, {0xccd6, 0x0000}, {0xccd7, 0x26d1}, - {0xccd8, 0x3011}, {0xccd9, 0x1001}, {0xccda, 0xc620}, {0xccdb, 0x0000}, - {0xccdc, 0xc621}, {0xccdd, 0x003f}, {0xccde, 0xc622}, {0xccdf, 0x0000}, - {0xcce0, 0xc623}, {0xcce1, 0x0000}, {0xcce2, 0xc624}, {0xcce3, 0x0000}, - {0xcce4, 0xc625}, {0xcce5, 0x0000}, {0xcce6, 0xc627}, {0xcce7, 0x0000}, - {0xcce8, 0xc628}, {0xcce9, 0x0000}, {0xccea, 0xc62c}, {0xcceb, 0x0000}, - {0xccec, 0x0000}, {0xcced, 0x2806}, {0xccee, 0x3cb6}, {0xccef, 0xc161}, - {0xccf0, 0x6134}, {0xccf1, 0x6135}, {0xccf2, 0x5443}, {0xccf3, 0x0303}, - {0xccf4, 0x6524}, {0xccf5, 0x000b}, {0xccf6, 0x1002}, {0xccf7, 0x2104}, - {0xccf8, 0x3c24}, {0xccf9, 0x2105}, {0xccfa, 0x3805}, {0xccfb, 0x6524}, - {0xccfc, 0xdff4}, {0xccfd, 0x4005}, {0xccfe, 0x6524}, {0xccff, 0x1002}, - {0xcd00, 0x5dd3}, {0xcd01, 0x0306}, {0xcd02, 0x2ff7}, {0xcd03, 0x38f7}, - {0xcd04, 0x60b7}, {0xcd05, 0xdffd}, {0xcd06, 0x000a}, {0xcd07, 0x1002}, - {0xcd08, 0x0000}, - // end of code block - - // Unpause the microcontroller to start program - {0xca00, 0x0080}, - {0xca12, 0x0000}, - {0x0000, 0x000A}, // wait 10ms just to be safe - - // Configure the LED's - {0xc214, 0x0099}, // configure the LED drivers (for Sahara rev B) - {0xc216, 0x0400}, // configure the one LED - {0xc217, 0x0000}, // don't drive the 2nd LED (if it exists) - - {0xffff, 0xffff} // table terminator -};