]> pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Staging: sxg: New SXG_SGL design and MAC Header changes
authorMithlesh Thukral <mithlesh@linsyssoft.com>
Mon, 5 Jan 2009 15:43:23 +0000 (21:13 +0530)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 3 Apr 2009 21:53:08 +0000 (14:53 -0700)
* This patch introduces the new SXG_SGL design.
* Related changes to sxg_scatter_gather structure.
* Introduced PSXG_X64_SGL changes which are x64 friendly
* Setting the MAC HEADER pointer properly in skb before giving to higher
  layers.

Signed-off-by: Michael Miles <mmiles@alacritech.com>
Signed-off-by: LinSysSoft Sahara Team <saharaproj@linsyssoft.com>
Signed-off-by: Christopher Harrer <charrer@alacritech.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/sxg/sxg.c
drivers/staging/sxg/sxg.h
drivers/staging/sxg/sxgdbg.h
drivers/staging/sxg/sxghif.h
drivers/staging/sxg/sxghw.h

index 1e0cfcd7f0f3dc1af90e9364f0a236d286facbb1..b110f56ce266d058e1e495c2f7a946c1657efb9b 100644 (file)
@@ -97,7 +97,7 @@ static int sxg_entry_halt(p_net_device dev);
 static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd);
 static int sxg_send_packets(struct sk_buff *skb, p_net_device dev);
 static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb);
-static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GATHER *SxgSgl);
+static void sxg_dumb_sgl(struct SXG_X64_SGL *pSgl, struct SXG_SCATTER_GATHER *SxgSgl);
 
 static void sxg_handle_interrupt(struct adapter_t *adapter);
 static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId);
@@ -114,10 +114,8 @@ static struct net_device_stats *sxg_get_stats(p_net_device dev);
 
 #define XXXTODO 0
 
-#if XXXTODO
 static int sxg_mac_set_address(p_net_device dev, void *ptr);
 static void sxg_mcast_set_list(p_net_device dev);
-#endif
 
 static void sxg_adapter_set_hwaddr(struct adapter_t *adapter);
 
@@ -622,6 +620,66 @@ static void sxg_config_pci(struct pci_dev *pcidev)
        }
 }
 
+static unsigned char temp_mac_address[6] = { 0x00, 0xab, 0xcd, 0xef, 0x12, 0x69 };
+/*
+ * 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 SW_CFG_DATA      *data;
+       dma_addr_t              p_addr;
+       unsigned long           status;
+       unsigned long           i;
+
+       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", __FUNCTION__);
+               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 */
+       }
+
+       switch(status) {
+               case SXG_CFG_LOAD_EEPROM:       /*Config read from EEPROM succeeded */
+               case SXG_CFG_LOAD_FLASH:        /* onfig read from Flash succeeded */
+                       /* Copy the MAC address to adapter structure */
+                       memcpy(temp_mac_address, data->MacAddr[0].MacAddr, 6);
+                       /* TODO: We are not doing the remaining part : FRU, etc */
+                       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", __FUNCTION__, 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);
+       }
+       printk("LINSYS : These are the new MAC address\n");
+       sxg_dbg_macaddrs(adapter);
+
+       return status;
+}
+
 static int sxg_entry_probe(struct pci_dev *pcidev,
                           const struct pci_device_id *pci_tbl_entry)
 {
@@ -774,16 +832,13 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
        adapter->vendid = pci_tbl_entry->vendor;
        adapter->devid = pci_tbl_entry->device;
        adapter->subsysid = pci_tbl_entry->subdevice;
-       adapter->busnumber = pcidev->bus->number;
        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->chipid = chip_idx; */
        adapter->port = 0;      /*adapter->functionnumber; */
-       adapter->cardindex = adapter->port;
 
        /* Allocate memory and other resources */
        DBG_ERROR("sxg: %s ENTER sxg_allocate_resources\n", __func__);
@@ -798,6 +853,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
        if (sxg_download_microcode(adapter, SXG_UCODE_SAHARA)) {
                DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
                          __func__);
+               sxg_read_config(adapter);
                sxg_adapter_set_hwaddr(adapter);
        } else {
                adapter->state = ADAPT_FAIL;
@@ -816,8 +872,8 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
 #if SLIC_GET_STATS_ENABLED
        netdev->get_stats = sxg_get_stats;
 #endif
-       netdev->set_multicast_list = sxg_mcast_set_list;
 #endif
+       netdev->set_multicast_list = sxg_mcast_set_list;
 
        strcpy(netdev->name, "eth%d");
 /*  strcpy(netdev->name, pci_name(pcidev)); */
@@ -992,12 +1048,14 @@ static irqreturn_t sxg_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+int debug_inthandler = 0;
+
 static void sxg_handle_interrupt(struct adapter_t *adapter)
 {
 /*    unsigned char           RssId   = 0; */
        u32 NewIsr;
 
-       if (adapter->Stats.RcvNoBuffer < 5) {
+       if (++debug_inthandler  < 20) {
                DBG_ERROR("Enter sxg_handle_interrupt ISR[%x]\n",
                          adapter->IsrCopy[0]);
        }
@@ -1033,7 +1091,7 @@ static void sxg_handle_interrupt(struct adapter_t *adapter)
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ClearIsr",
                  adapter, NewIsr, 0, 0);
 
-       if (adapter->Stats.RcvNoBuffer < 5) {
+       if (debug_inthandler < 20) {
                DBG_ERROR
                    ("Exit sxg_handle_interrupt2 after enabling interrupt\n");
        }
@@ -1205,14 +1263,12 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
 #else
 /* CHECK            skb_pull(skb, INIC_RCVBUF_HEADSIZE); */
                                rx_bytes = Event->Length;       /* (rcvbuf->length & IRHDDR_FLEN_MSK); */
-                               skb_put(skb, rx_bytes);
                                adapter->stats.rx_packets++;
                                adapter->stats.rx_bytes += rx_bytes;
 #if SXG_OFFLOAD_IP_CHECKSUM
                                skb->ip_summed = CHECKSUM_UNNECESSARY;
 #endif
                                skb->dev = adapter->netdev;
-                               skb->protocol = eth_type_trans(skb, skb->dev);
                                netif_rx(skb);
 #endif
                        }
@@ -1321,12 +1377,16 @@ static void sxg_complete_slow_send(struct adapter_t *adapter)
                case SXG_SGL_DUMB:
                        {
                                struct sk_buff *skb;
+                               struct SXG_SCATTER_GATHER *SxgSgl = (struct SXG_SCATTER_GATHER *)ContextType;
+
                                /* Dumb-nic send.  Command context is the dumb-nic SGL */
                                skb = (struct sk_buff *)ContextType;
+                               skb = SxgSgl->DumbPacket;
                                /* Complete the send */
                                SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
                                          TRACE_IMPORTANT, "DmSndCmp", skb, 0,
                                          0, 0);
+                               printk("ASK:sxg_complete_slow_send: freeing an skb [%p]\n", skb);
                                ASSERT(adapter->Stats.XmtQLen);
                                adapter->Stats.XmtQLen--;       /* within XmtZeroLock */
                                adapter->Stats.XmtOk++;
@@ -1363,12 +1423,14 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
 {
        struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
        struct sk_buff *Packet;
+       unsigned char*data;
+       int i;
+       char dstr[128];
+       char *dptr = dstr;
 
        RcvDataBufferHdr = (struct SXG_RCV_DATA_BUFFER_HDR*) Event->HostHandle;
        ASSERT(RcvDataBufferHdr);
        ASSERT(RcvDataBufferHdr->State == SXG_BUFFER_ONCARD);
-       ASSERT(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr) ==
-              RcvDataBufferHdr->VirtualAddress);
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event,
                  RcvDataBufferHdr, RcvDataBufferHdr->State,
                  RcvDataBufferHdr->VirtualAddress);
@@ -1385,6 +1447,13 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
                goto drop;
        }
 
+       printk("ASK:sxg_slow_receive: event host handle %p\n", RcvDataBufferHdr);
+       data = SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr);
+       for (i = 0; i < 32; i++)
+               dptr += sprintf(dptr, "%02x ", (unsigned)data[i]);
+       printk("ASK:sxg_slow_receive: data %s\n", dstr);
+       //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) {
@@ -1415,24 +1484,28 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
        /* */
        /* Dumb-nic frame.  See if it passes our mac filter and update stats */
        /* */
-       if (!sxg_mac_filter(adapter, (struct ether_header*)
+       /* ASK if (!sxg_mac_filter(adapter,
                            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);
+       printk("ASK:sxg_slow_receive: protocol %x\n", (unsigned) Packet->protocol);
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumbRcv",
                  RcvDataBufferHdr, Packet, Event->Length, 0);
        /* */
        /* Lastly adjust the receive packet length. */
        /* */
-       SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
+       RcvDataBufferHdr->SxgDumbRcvPacket = NULL;
 
+       SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
        return (Packet);
 
       drop:
@@ -1666,9 +1739,9 @@ static int sxg_if_init(struct adapter_t *adapter)
        p_net_device dev = adapter->netdev;
        int status = 0;
 
-       DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d:%d] flags[%x]\n",
+       DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d] flags[%x]\n",
                  __func__, adapter->netdev->name,
-                 adapter->queues_initialized, adapter->state,
+                 adapter->state,
                  adapter->linkstate, dev->flags);
 
        /* adapter should be down at this point */
@@ -1871,8 +1944,10 @@ static int sxg_send_packets(struct sk_buff *skb, p_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);
+       //DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __FUNCTION__,
+       //        skb);
+       printk("ASK:sxg_send_packets: skb[%p]\n", skb);
+
        /* Check the adapter state */
        switch (adapter->State) {
        case SXG_STATE_INITIALIZING:
@@ -1936,8 +2011,8 @@ static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
  */
 static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
 {
-       struct SCATTER_GATHER_LIST *pSgl;
-       struct SXG_SCATTER_GATHER *SxgSgl;
+       struct SXG_X64_SGL         *pSgl;
+       struct SXG_SCATTER_GATHER  *SxgSgl;
        void *SglBuffer;
        u32 SglBufferLength;
 
@@ -1980,7 +2055,7 @@ static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
  * Return Value:
  *     None.
  */
-static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GATHER *SxgSgl)
+static void 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;
@@ -1993,15 +2068,23 @@ static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GA
 /*  unsigned int                                BufLen; */
 /*      u32                         SglOffset; */
        u64 phys_addr;
+       unsigned char*data;
+       int i;
+       char dstr[128];
+       char *dptr = dstr;
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
                  pSgl, SxgSgl, 0, 0);
+       data = skb->data;
+       for (i = 0; i < 32; i++)
+               dptr += sprintf(dptr, "%02x ", (unsigned)data[i]);
+       printk("ASK:sxg_dumb_sgl: data %s\n", dstr);
 
        /* Set aside a pointer to the sgl */
        SxgSgl->pSgl = pSgl;
 
        /* Sanity check that our SGL format is as we expect. */
-       ASSERT(sizeof(SXG_X64_SGE) == sizeof(SCATTER_GATHER_ELEMENT));
+       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);
@@ -2050,25 +2133,14 @@ static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GA
        phys_addr =
            pci_map_single(adapter->pcidev, skb->data, skb->len,
                           PCI_DMA_TODEVICE);
-       XmtCmd->Buffer.FirstSgeAddress = SXG_GET_ADDR_HIGH(phys_addr);
-       XmtCmd->Buffer.FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress << 32;
-       XmtCmd->Buffer.FirstSgeAddress =
-           XmtCmd->Buffer.FirstSgeAddress | SXG_GET_ADDR_LOW(phys_addr);
-/*      XmtCmd->Buffer.FirstSgeAddress = SxgSgl->Sgl.Elements[Index].Address; */
-/*      XmtCmd->Buffer.FirstSgeAddress.LowPart += MdlOffset; */
+       memset(XmtCmd, '\0', sizeof(*XmtCmd));
+       XmtCmd->Buffer.FirstSgeAddress = phys_addr;
        XmtCmd->Buffer.FirstSgeLength = DataLength;
-       /* Set a pointer to the remaining SGL entries */
-/*      XmtCmd->Sgl = SxgSgl->PhysicalAddress; */
-       /* Advance the physical address of the SxgSgl structure to */
-       /* the second SGE */
-/*      SglOffset = (u32)((u32 *)(&SxgSgl->Sgl.Elements[Index+1]) - */
-/*                                              (u32 *)SxgSgl); */
-/*      XmtCmd->Sgl.LowPart += SglOffset; */
        XmtCmd->Buffer.SgeOffset = 0;
-       /* Note - TotalLength might be overwritten with MSS below.. */
        XmtCmd->Buffer.TotalLength = DataLength;
-       XmtCmd->SgEntries = 1;  /*(ushort)(SxgSgl->Sgl.NumberOfElements - Index); */
+       XmtCmd->SgEntries = 1;
        XmtCmd->Flags = 0;
+       printk("ASK:sxg_dumb_sgl: wrote to xmit register\n");
        /* */
        /* Advance transmit cmd descripter by 1. */
        /* NOTE - See comments in SxgTcpOutput where we write */
@@ -2144,11 +2216,11 @@ static int sxg_initialize_link(struct adapter_t *adapter)
        /* 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;
+       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);
+       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);
@@ -2208,6 +2280,7 @@ static int sxg_initialize_link(struct adapter_t *adapter)
        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 */
@@ -2600,7 +2673,7 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
                  adapter, 0, 0, 0);
-/*  DBG_ERROR("ENTER %s\n", __func__); */
+    DBG_ERROR("ENTER %s\n", __FUNCTION__);
 
        /* Ensure values don't exceed field width */
        DevAddr &= 0x001F;      /* 5-bit field */
@@ -2636,6 +2709,8 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
                udelay(100);    /* Timeout in 100us units */
                READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
                if (--Timeout == 0) {
+            DBG_ERROR("EXIT %s with STATUS_FAILURE 1\n", __FUNCTION__);
+
                        return (STATUS_FAILURE);
                }
        } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
@@ -2655,6 +2730,8 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
                udelay(100);    /* Timeout in 100us units */
                READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
                if (--Timeout == 0) {
+            DBG_ERROR("EXIT %s with STATUS_FAILURE 2\n", __FUNCTION__);
+
                        return (STATUS_FAILURE);
                }
        } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
@@ -2663,7 +2740,7 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
        READ_REG(HwRegs->MacAmiimField, *pValue);
        *pValue &= 0xFFFF;      /* data is in the lower 16 bits */
 
-/*  DBG_ERROR("EXIT %s\n", __func__); */
+    DBG_ERROR("EXIT %s\n", __FUNCTION__);
 
        return (STATUS_SUCCESS);
 }
@@ -2705,7 +2782,6 @@ static void sxg_mcast_init_crc32(void)
        }
 }
 
-#if XXXTODO
 static u32 sxg_crc_init;       /* Is table initialized */
 /*
  *  Return the MAC hast as described above.
@@ -2777,7 +2853,7 @@ static void sxg_mcast_set_mask(struct adapter_t *adapter)
  */
 static int sxg_mcast_add_list(struct adapter_t *adapter, char *address)
 {
-       p_mcast_address_t mcaddr, mlist;
+       struct mcast_address_t *mcaddr, *mlist;
        bool equaladdr;
 
        /* Check to see if it already exists */
@@ -2791,7 +2867,7 @@ static int sxg_mcast_add_list(struct adapter_t *adapter, char *address)
        }
 
        /* Doesn't already exist.  Allocate a structure to hold it */
-       mcaddr = kmalloc(sizeof(mcast_address_t), GFP_ATOMIC);
+       mcaddr = kmalloc(sizeof(struct mcast_address_t), GFP_ATOMIC);
        if (mcaddr == NULL)
                return 1;
 
@@ -2829,6 +2905,13 @@ static void sxg_mcast_set_list(p_net_device dev)
        int mc_count = dev->mc_count;
 
        ASSERT(adapter);
+       if (dev->flags & IFF_PROMISC) {
+               adapter->MacFilter |= MAC_PROMISC;
+       }
+       //XXX handle other flags as well
+       sxg_mcast_set_mask(adapter);
+
+#if 0
 
        for (i = 1; i <= mc_count; i++) {
                addresses = (char *)&mc_list->dmi_addr;
@@ -2873,8 +2956,8 @@ static void sxg_mcast_set_list(p_net_device dev)
                }
        }
        return;
-}
 #endif
+}
 
 static void sxg_unmap_mmio_space(struct adapter_t *adapter)
 {
@@ -3133,12 +3216,16 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
                                                        SXG_RCV_DATA_BUFFER_HDR_OFFSET
                                                        (BufferSize));
                        RcvDataBufferHdr->VirtualAddress = RcvDataBuffer;
-                       RcvDataBufferHdr->PhysicalAddress = Paddr;
                        RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;  /* For FREE macro assertion */
                        RcvDataBufferHdr->Size =
                            SXG_RCV_BUFFER_DATA_SIZE(BufferSize);
 
                        SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr);
+                       //ASK hardcoded 2048
+                       RcvDataBufferHdr->PhysicalAddress = pci_map_single(adapter->pcidev,
+                               RcvDataBufferHdr->SxgDumbRcvPacket->data,
+                               2048,
+                               PCI_DMA_FROMDEVICE);
                        if (RcvDataBufferHdr->SxgDumbRcvPacket == NULL)
                                goto fail;
 
@@ -3240,8 +3327,6 @@ static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter,
                  adapter, SxgSgl, Length, 0);
 }
 
-static unsigned char temp_mac_address[6] =
-    { 0x00, 0xab, 0xcd, 0xef, 0x12, 0x69 };
 
 static void sxg_adapter_set_hwaddr(struct adapter_t *adapter)
 {
@@ -3262,6 +3347,7 @@ static void sxg_adapter_set_hwaddr(struct adapter_t *adapter)
        }
        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);
@@ -3395,6 +3481,7 @@ static int sxg_initialize_adapter(struct adapter_t *adapter)
        /* SlicCheckForHang or SlicDumpThread will take it from here. */
        adapter->Dead = FALSE;
        adapter->PingOutstanding = FALSE;
+       adapter->State = SXG_STATE_RUNNING;
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInit",
                  adapter, 0, 0, 0);
@@ -3448,10 +3535,16 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
        for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; i++) {
                SXG_GET_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
                ASSERT(RcvDataBufferHdr);
+               ASSERT(RcvDataBufferHdr->SxgDumbRcvPacket);
                SXG_REINIATIALIZE_PACKET(RcvDataBufferHdr->SxgDumbRcvPacket);
                RcvDataBufferHdr->State = SXG_BUFFER_ONCARD;
                RcvDescriptorBlock->Descriptors[i].VirtualAddress =
                    (void *)RcvDataBufferHdr;
+               if (i == 0)
+                       printk("ASK:sxg_fill_descriptor_block: first virt address %p\n", RcvDataBufferHdr);
+               if (i == (SXG_RCV_DESCRIPTORS_PER_BLOCK - 1))
+                       printk("ASK:sxg_fill_descriptor_block: last virt address %p\n", RcvDataBufferHdr);
+
                RcvDescriptorBlock->Descriptors[i].PhysicalAddress =
                    RcvDataBufferHdr->PhysicalAddress;
        }
@@ -3503,6 +3596,7 @@ static void sxg_stock_rcv_buffers(struct adapter_t *adapter)
                                                              ReceiveBufferSize),
                                           SXG_BUFFER_TYPE_RCV);
        }
+       printk("ASK:sxg_stock_rcv_buffers: RcvBuffersOnCard %d\n", adapter->RcvBuffersOnCard);
        /* Now grab the RcvQLock lock and proceed */
        spin_lock(&adapter->RcvQLock);
        while (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
index 653cf3ba0c4c7aefb59aa59ee2268ada3192ef36..77a689ed5d721423b29dd496233dff45a51e1aca 100644 (file)
@@ -141,7 +141,7 @@ struct SXG_STATS {
 
 #define SXG_ALLOCATE_RCV_PACKET(_pAdapt, _RcvDataBufferHdr) {                          \
        struct sk_buff * skb;                                                                                               \
-    skb = alloc_skb(2048, GFP_ATOMIC);                                      \
+    skb = netdev_alloc_skb(_pAdapt->netdev, 2048);                                 \
     if (skb) {                                                              \
        (_RcvDataBufferHdr)->skb = skb;                                     \
         skb->next = NULL;                                                   \
@@ -207,7 +207,7 @@ struct SXG_STATS {
                           (_RcvDataBufferHdr), (_Packet),                                                              \
                           (_Event)->Status, 0);                                                        \
        ASSERT((_Event)->Length <= (_RcvDataBufferHdr)->Size);                                  \
-    Packet->len = (_Event)->Length;                                         \
+    skb_put(Packet, (_Event)->Length);                                         \
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -503,10 +503,6 @@ struct adapter_t {
        unsigned int                port;
        struct physcard_t        *physcard;
        unsigned int                physport;
-       unsigned int                cardindex;
-       unsigned int                card_size;
-       unsigned int                chipid;
-       unsigned int                busnumber;
        unsigned int                slotnumber;
        unsigned int                functionnumber;
        ushort              vendid;
@@ -514,25 +510,15 @@ struct adapter_t {
        ushort              subsysid;
        u32             irq;
 
-       void *               sxg_adapter;
-       u32             nBusySend;
-
        void __iomem *  base_addr;
        u32             memorylength;
        u32             drambase;
        u32             dramlength;
-       unsigned int                queues_initialized;
-       unsigned int                allocated;
        unsigned int                activated;
        u32             intrregistered;
        unsigned int                isp_initialized;
-       unsigned int                gennumber;
-       u32             curaddrupper;
-       u32             isrcopy;
        unsigned char               state;
        unsigned char               linkstate;
-       unsigned char               linkspeed;
-       unsigned char               linkduplex;
        unsigned int                flags;
        unsigned char               macaddr[6];
        unsigned char               currmacaddr[6];
@@ -581,8 +567,6 @@ struct adapter_t {
        u32                                             PowerState;                     // NDIS power state
        struct adapter_t                *Next;                          // Linked list
        ushort                                          AdapterID;                      // 1..n
-       unsigned char                                           MacAddr[6];                     // Our permanent HW mac address
-       unsigned char                                           CurrMacAddr[6];         // Our Current mac address
        p_net_device                netdev;
        p_net_device                next_netdevice;
        struct pci_dev            * pcidev;
@@ -597,17 +581,11 @@ struct adapter_t {
        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                                          ResetDpcCount;          // For timeout
-       ushort                                          RssDpcCount;            // For timeout
-       ushort                                          VendorID;                       // Vendor ID
-       ushort                                          DeviceID;                       // Device ID
-       ushort                                          SubSystemID;            // Sub-System ID
-       ushort                                          FrameSize;                      // Maximum frame size
+       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
-       ushort                                          IpId;                           // For slowpath
        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
@@ -690,9 +668,6 @@ struct adapter_t {
        // Put preprocessor-conditional fields at the end so we don't
        // have to recompile sxgdbg everytime we reconfigure the driver
        /////////////////////////////////////////////////////////////////////
-       void *                                          PendingSetRss;          // Pending RSS parameter change
-       u32                                             IPv4HdrSize;            // Shared 5.2/6.0 encap param
-       unsigned char *                                 InterruptInfo;          // Allocated by us during AddDevice
 #if defined(CONFIG_X86)
        u32                                             AddrUpper;                      // Upper 32 bits of 64-bit register
 #endif
index bb58ddf39f3058ed938e63c8e0b0fc12b5d6b8b1..ce9e3cd13d878b2c0396c6ff07a106084a1bcf74 100644 (file)
 #define ATKDBG  1
 #define ATK_TRACE_ENABLED 1
 
-#define DBG_ERROR(n, args...)  printk(KERN_EMERG n, ##args)
+#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)                                                                 \
index a4e94685c544f7f66533ff6fffca521daf537c36..56378f1973fe06df61ba7de80bc5cd5646fd184c 100644 (file)
@@ -22,7 +22,9 @@ struct SXG_UCODE_REGS {
        u32 RsvdReg5;           // Code = 5 - TOE -NA
        u32 CardUp;             // Code = 6 - Microcode initialized when 1
        u32 RsvdReg7;           // Code = 7 - TOE -NA
-       u32 CodeNotUsed[8];     // Codes 8-15 not used.  ExCode = 0
+    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
@@ -53,7 +55,7 @@ struct SXG_UCODE_REGS {
        // ExCode 10 = Receive ring size
        u32 RcvSize;            // Code = 0 (extended), ExCode = 10
        u32 PadEx10[15];
-       // ExCode 11 = Read EEPROM Config
+       // ExCode 11 = Read EEPROM/Flash Config
        u32 Config;             // Code = 0 (extended), ExCode = 11
        u32 PadEx11[15];
        // ExCode 12 = Multicast bits 31:0
@@ -77,15 +79,16 @@ struct SXG_UCODE_REGS {
        // ExCode 18 = Slowpath Send Index Address
        u32 SPSendIndex;        // Code = 0 (extended), ExCode = 18
        u32 PadEx18[15];
-       u32 RsvdXF;             // Code = 0 (extended), ExCode = 19
+       // ExCode 19 = Get ucode statistics
+       u32             GetUcodeStats;                  // Code = 0 (extended), ExCode = 19
        u32 PadEx19[15];
-       // ExCode 20 = Aggregation
+       // 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 = TOE NA
+       // ExCode 22 = ACK Frequency
        u32 AckFrequency;       // Code = 0 (extended), ExCode = 22
        u32 PadEx22[15];
        // ExCode 23 = TOE NA
@@ -139,8 +142,14 @@ struct SXG_UCODE_REGS {
        ((((_MessageId) << SXG_ICR_MSGID_SHIFT) &       \
          SXG_ICR_MSGID_MASK) | (_Data))
 
-// The Microcode supports up to 16 RSS queues
-#define SXG_MAX_RSS                            16
+#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
+#define SXG_AGG_XMT_DISABLE                    0x80000000      // Disable interrupt aggregation on xmt
+
+// The Microcode supports up to 8 RSS queues
+#define SXG_MAX_RSS                            8
+
 #define SXG_MAX_RSS_TABLE_SIZE 256     // 256-byte max
 
 #define SXG_RSS_TCP6                           0x00000001      // RSS TCP over IPv6
@@ -156,11 +165,15 @@ struct SXG_UCODE_REGS {
 
 #define SXG_XMT_CPUID_SHIFT                    16
 
-#if VPCI
-#define SXG_CHECK_FOR_HANG_TIME                3000
-#else
+// 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
-#endif
 
 /*
  * TCB registers - This is really the same register memory area as UCODE_REGS
@@ -176,10 +189,11 @@ struct SXG_TCB_REGS {
        u32 Rsvd1;              /* Code = 3 - TOE NA */
        u32 Rsvd2;              /* Code = 4 - TOE NA */
        u32 Rsvd3;              /* Code = 5 - TOE NA */
-       u32 Invalid           /* Code = 6 - Reserved for "CardUp" see above */
+       u32 Invalid1;           /* Code = 6 - Reserved for "CardUp" see above */
        u32 Rsvd4;              /* Code = 7 - TOE NA */
-       u32 Rsvd5;              /* Code = 8 - TOE NA */
-       u32 Pad[7];             /* Codes 8-15 - Not used. */
+       u32 Invalid2;           /* Code = 8 - Reserved for "ConfigStat" see above */
+       u32 Rsvd5;              /* Code = 9 - TOE NA */
+       u32 Pad[6];             /* Codes 10-15 - Not used. */
 };
 
 /***************************************************************************
@@ -319,7 +333,7 @@ struct SXG_EVENT {
 // 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.
-#define EVENT_BATCH_LIMIT      256     // Stop processing events after 256 (16 * 16)
+#define EVENT_BATCH_LIMIT      256         // Stop processing events after 4096 (256 * 16)
 
 struct SXG_EVENT_RING {
        struct SXG_EVENT Ring[EVENT_RING_SIZE];
@@ -664,23 +678,22 @@ enum SXG_BUFFER_TYPE {
  *    => Total = ~1282k/block
  *
  ***************************************************************************/
-#define SXG_RCV_DATA_BUFFERS                   4096    // Amount to give to the card
-#define SXG_INITIAL_RCV_DATA_BUFFERS   8192    // Initial pool of buffers
-#define SXG_MIN_RCV_DATA_BUFFERS               2048    // Minimum amount and when to get more
-#define SXG_MAX_RCV_BLOCKS                             128     // = 16384 receive buffers
+#define SXG_RCV_DATA_BUFFERS                   8192    // Amount to give to the card
+#define SXG_INITIAL_RCV_DATA_BUFFERS   16384   // Initial pool of buffers
+#define SXG_MIN_RCV_DATA_BUFFERS               4096    // Minimum amount and when to get more
+#define SXG_MAX_RCV_BLOCKS                             256             // = 32k receive buffers
 
 // Receive buffer header
 struct SXG_RCV_DATA_BUFFER_HDR {
        dma_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.
-       void *VirtualAddress;   // Start of buffer
-       struct LIST_ENTRY FreeList;     // Free queue of buffers
+       void                            *VirtualAddress;        // Start of buffer
+       u32                             Size;                   // Buffer size
        struct SXG_RCV_DATA_BUFFER_HDR *Next;   // Fastpath data buffer queue
-       u32 Size;               // Buffer size
-       u32 ByteOffset;         // See SXG_RESTORE_MDL_OFFSET
-       unsigned char State;    // See SXG_BUFFER state above
-       unsigned char Status;   // Event status (to log PUSH)
+       struct LIST_ENTRY               FreeList;               // Free queue of buffers
+       unsigned char                   State;                  // See SXG_BUFFER state above
+       unsigned char                   Status;                 // Event status (to log PUSH)
        struct sk_buff *skb;    // Double mapped (nbl and pkt)
 };
 
@@ -744,15 +757,6 @@ struct SXG_RCV_BLOCK_HDR {
         (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK))              +               \
         (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK_HDR)))
 
-// Use the miniport reserved portion of the NBL to locate
-// our SXG_RCV_DATA_BUFFER_HDR structure.
-struct SXG_RCV_NBL_RESERVED {
-       struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
-       void *Available;
-};
-
-#define SXG_RCV_NBL_BUFFER_HDR(_NBL) (((PSXG_RCV_NBL_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(_NBL))->RcvDataBufferHdr)
-
 /***************************************************************************
  * Scatter gather list buffer
  ***************************************************************************/
@@ -760,6 +764,102 @@ struct SXG_RCV_NBL_RESERVED {
 #define SXG_MIN_SGL_BUFFERS                    2048    // Minimum amount and when to get more
 #define SXG_MAX_SGL_BUFFERS                    16384   // Maximum to allocate (note ADAPT:ushort)
 
+// 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..??).
+typedef 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
+} SXG_SGL_POOL_PROPERTIES, *PSXG_SGL_POOL_PROPERTIES;
+
+// 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                                                         \
+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 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(_SxgSgl)                                                                               \
+       (((_SxgSgl)->PhysicalAddress.LowPart & 0xFFFF0000) !=                           \
+        (((_SxgSgl)->PhysicalAddress.LowPart +                                                         \
+          SXG_SGL_SIZE((_SxgSgl)->Pool)) & 0xFFFF0000))
+
+// Allocate SGLs in blocks so we can skip over invalid entries.
+// We allocation 64k worth of SGL buffers, including the
+// 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)
+
+typedef struct _SXG_SGL_BLOCK_HDR {
+       ushort                                                  Pool;                   // Associated SGL pool
+       struct LIST_ENTRY                                       List;                   // SXG_SCATTER_GATHER blocks
+       dma64_addr_t                            PhysicalAddress;// physical address
+} SXG_SGL_BLOCK_HDR, *PSXG_SGL_BLOCK_HDR;
+
+
+// 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
@@ -767,32 +867,6 @@ enum SXG_SGL_TYPE {
        SXG_SGL_CHIMNEY         // Chimney offload SGL
 };
 
-// Note - the description below is Microsoft specific
-//
-// The following definition specifies the amount of shared memory to allocate
-// for the SCATTER_GATHER_LIST portion of the SXG_SCATTER_GATHER data structure.
-// The following considerations apply when setting this value:
-// - First, the Sahara card is designed to read the Microsoft SGL structure
-//       straight out of host memory.  This means that the SGL must reside in
-//       shared memory.  If the length here is smaller than the SGL for the
-//       NET_BUFFER, then NDIS will allocate its own buffer.  The buffer
-//       that NDIS allocates is not in shared memory, so when this happens,
-//       the SGL will need to be copied to a set of SXG_SCATTER_GATHER buffers.
-//       In other words.. we don't want this value to be too small.
-// - On the other hand.. we're allocating up to 16k of these things.  If
-//       we make this too big, we start to consume a ton of memory..
-// At the moment, I'm going to limit the number of SG entries to 150.
-// If each entry maps roughly 4k, then this should cover roughly 600kB
-// NET_BUFFERs.  Furthermore, since each entry is 24 bytes, the total
-// SGE portion of the structure consumes 3600 bytes, which should allow
-// the entire SXG_SCATTER_GATHER structure to reside comfortably within
-// a 4k block, providing the remaining fields stay under 500 bytes.
-//
-// So with 150 entries, the SXG_SCATTER_GATHER structure becomes roughly
-// 4k.  At 16k of them, that amounts to 64M of shared memory.  A ton, but
-// manageable.
-#define SXG_SGL_ENTRIES                150
-
 // 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
@@ -806,31 +880,19 @@ struct SXG_X64_SGE {
        u64 Reserved;           // u32 * in wdm.h.  Force to 8 bytes
 };
 
-struct SCATTER_GATHER_ELEMENT {
-       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
-};
-
-struct SCATTER_GATHER_LIST {
-       u32 NumberOfElements;
-       u32 *Reserved;
-       struct SCATTER_GATHER_ELEMENT Elements[];
-};
-
-// The card doesn't care about anything except elements, so
-// we can leave the u32 * reserved field alone in the following
-// SGL structure.  But redefine from wdm.h:SCATTER_GATHER_LIST so
-// we can specify SXG_X64_SGE and define a fixed number of elements
+// 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[SXG_SGL_ENTRIES];
+       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
        struct LIST_ENTRY FreeList;     // Free SXG_SCATTER_GATHER blocks
        struct LIST_ENTRY AllList;      // All SXG_SCATTER_GATHER blocks
@@ -842,17 +904,40 @@ struct SXG_SCATTER_GATHER {
        u32 CurOffset;          // Current SGL offset
        u32 SglRef;             // SGL reference count
        struct VLAN_HDR VlanTag;        // VLAN tag to be inserted into SGL
-       struct SCATTER_GATHER_LIST *pSgl;       // SGL Addr. Possibly &Sgl
-       struct SXG_X64_SGL Sgl; // SGL handed to card
+       struct SXG_X64_SGL *pSgl;               // SGL Addr. Possibly &Sgl
+       struct SXG_X64_SGL Sgl;         // SGL handed to card
 };
 
+// Note - the "- 1" is because SXG_SCATTER_GATHER=>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)))
+
 #if defined(CONFIG_X86_64)
-#define SXG_SGL_BUFFER(_SxgSgl)                (&_SxgSgl->Sgl)
-#define SXG_SGL_BUF_SIZE                       sizeof(struct SXG_X64_SGL)
+#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(_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
+ ***************************************************************************/
+typedef 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
+       u32  BFDrops;                           // Rcv drops due to bad frame: no link addr match, frlen > max
+       u32  UPDrops;                           // Rcv drops due to UPFq full
+       u32  XNoBufs;                           // Xmt drop due to no DRAM Xmit buffer or PxyBuf
+} SXG_UCODE_STATS, *PSXG_UCODE_STATS;
+
+
index b0efff9ff1178ad58968c9e9b64fb101e8f2db54..bac0cdf24ab0ed119ef8978261b3259d53bbb0cf 100644 (file)
@@ -11,7 +11,7 @@
 
 
 /*******************************************************************************
- * Configuration space
+ * PCI Configuration space
  *******************************************************************************/
 /*  PCI Vendor ID */
 #define SXG_VENDOR_ID                  0x139A  /* Alacritech's Vendor ID */
@@ -214,6 +214,11 @@ struct SXG_HW_REGS {
 #define        RCV_CONFIG_TZIPV4               0x00800000      // Include TCP port w/ IPv4 toeplitz
 #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
@@ -525,6 +530,21 @@ struct PHY_UCODE {
 };
 
 
+/*****************************************************************************
+ * 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
  *****************************************************************************/
@@ -613,8 +633,8 @@ struct RCV_BUF_HDR {
        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
+       u32                 TpzHash;                    // Toeplitz hash
+       ushort          Reserved;                       // Reserved
 };
 #pragma pack(pop)
 
@@ -662,26 +682,43 @@ struct RCV_BUF_HDR {
 /*****************************************************************************
  * SXG EEPROM/Flash Configuration Definitions
  *****************************************************************************/
-#pragma pack(push, 1)
+// Location of configuration data in EEPROM or Flash
+#define        EEPROM_CONFIG_START_ADDR        0x00    // start addr for config info in EEPROM
+#define        FLASH_CONFIG_START_ADDR         0x80    // start addr for config info in Flash
+
+// 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)
+#define        SW_CFG_SECTION_START    512             // starting location (offset) of S/W section
+#define        SW_CFG_SECTION_START_A  256             // starting location (offset) of S/W section (Sahara rev A)
+#define        SW_CFG_SECTION_SIZE     128             // size of S/W section
+
+#define        HW_CFG_MAGIC_WORD       0xA5A5          // H/W configuration data magic word
+//    Goes in Addr field of first HW_CFG_DATA entry
+#define        HW_CFG_TERMINATOR       0xFFFF          // H/W configuration data terminator
+//    Goes in Addr field of last HW_CFG_DATA entry
+#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;
-       union {
-               ushort  Data;
-               ushort  Checksum;
-       };
+       ushort      Data;
 };
 
-/* */
-#define        NUM_HW_CFG_ENTRIES      ((128/sizeof(struct HW_CFG_DATA)) - 4)
+// Number of HW_CFG_DATA structures to put in the configuration data
+// data structure (SXG_CONFIG or 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 */
+/* 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];
@@ -697,31 +734,110 @@ struct ATK_FRU {
 #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 {
-       /* */
-       /* Section 1 (128 bytes) */
-       /* */
-       ushort                  MagicWord;                      /* EEPROM/FLASH Magic code 'A5A5' */
-       ushort                  SpiClks;                        /* SPI bus clock dividers */
+       /*
+       * H/W Section - Read by Sahara hardware (512 bytes)
+       */
        struct HW_CFG_DATA              HwCfg[NUM_HW_CFG_ENTRIES];
-       /* */
-       /* */
-       /* */
-       ushort                  Version;                        /* EEPROM 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 */
-       unsigned char                   OemFru[76];                     /* OEM FRU information (optional) */
-       ushort                  Checksum;                       /* Checksum of section 2 */
-       /* CS info XXXTODO */
+       /*
+        * S/W Section - Other configuration data (128 bytes)
+        */
+       struct SW_CFG_DATA      SwCfg;
+};
+
+// EEPROM/Flash Format (Sahara rev A)
+struct SXG_CONFIG_A {
+       /*
+        * H/W Section - Read by Sahara hardware (256 bytes)
+        */
+       struct HW_CFG_DATA              HwCfg[NUM_HW_CFG_ENTRIES_A];
+
+       /*
+        * 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 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(SXG_CONFIG, SwCfg) == SW_CFG_SECTION_START);
+compile_time_assert (sizeof(SXG_CONFIG) == HW_CFG_SECTION_SIZE + SW_CFG_SECTION_SIZE);
+
+compile_time_assert (offsetof(SXG_CONFIG_A, SwCfg) == SW_CFG_SECTION_START_A);
+compile_time_assert (sizeof(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;
+       // u32              LinkState;          // use LinkUp - any need for other states?
+       u32                 LinkSpeed;          // not currently needed
+       u32                 LinkDuplex;         // not currently needed
+       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
  *****************************************************************************/
 
+// Type of ASIC in use
+enum ASIC_TYPE{
+       SAHARA_REV_A,
+       SAHARA_REV_B
+};
+
 // Sahara (ASIC level) defines
 #define SAHARA_GRAM_SIZE               0x020000                // GRAM size - 128 KB
 #define SAHARA_DRAM_SIZE               0x200000                // DRAM size - 2 MB
@@ -730,5 +846,6 @@ struct SXG_CONFIG {
 
 // Arabia (board level) defines
 #define        FLASH_SIZE                      0x080000                // 512 KB (4 Mb)
-#define        EEPROM_SIZE_XFMR                512                     // true EEPROM size (bytes), including xfmr area
-#define        EEPROM_SIZE_NO_XFMR             256                     // EEPROM size excluding xfmr area
+#define        EEPROM_SIZE_XFMR                1024                    // EEPROM size (bytes), including xfmr area
+#define        EEPROM_SIZE_NO_XFMR             640                             // EEPROM size excluding xfmr area (512 + 128)
+#define        EEPROM_SIZE_REV_A               512                             // EEPROM size for Sahara rev A