aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/sxg/sxghif.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/sxg/sxghif.h')
-rw-r--r--drivers/staging/sxg/sxghif.h251
1 files changed, 168 insertions, 83 deletions
diff --git a/drivers/staging/sxg/sxghif.h b/drivers/staging/sxg/sxghif.h
index a4e94685c54..56378f1973f 100644
--- a/drivers/staging/sxg/sxghif.h
+++ b/drivers/staging/sxg/sxghif.h
@@ -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;
+
+