Staging: sxg: SXG SGL related cleanup in data structures and code
* Cleanup in allocation of SXG_SGLs. * Locking issues related to SglQLock. * XmtCmd and XmtZeroLock consistency fixes. 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>
This commit is contained in:
parent
371d7a9e6f
commit
d9d578bff7
@ -95,13 +95,13 @@ 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_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_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_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb);
|
||||||
static void sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
||||||
struct sxg_scatter_gather *SxgSgl);
|
struct sxg_scatter_gather *SxgSgl);
|
||||||
|
|
||||||
static void sxg_handle_interrupt(struct adapter_t *adapter);
|
static void sxg_handle_interrupt(struct adapter_t *adapter);
|
||||||
static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId);
|
static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId);
|
||||||
static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId);
|
static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId);
|
||||||
static void sxg_complete_slow_send(struct adapter_t *adapter);
|
static void sxg_complete_slow_send(struct adapter_t *adapter, int irq_context);
|
||||||
static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
|
static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
|
||||||
struct sxg_event *Event);
|
struct sxg_event *Event);
|
||||||
static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus);
|
static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus);
|
||||||
@ -112,8 +112,12 @@ static bool sxg_mac_filter(struct adapter_t *adapter,
|
|||||||
static struct net_device_stats *sxg_get_stats(struct net_device *dev);
|
static struct net_device_stats *sxg_get_stats(struct net_device *dev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void SxgFreeResources(struct adapter_t *adapter);
|
void sxg_free_resources(struct adapter_t *adapter);
|
||||||
void SxgFreeRcvBlocks(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);
|
||||||
|
|
||||||
#define XXXTODO 0
|
#define XXXTODO 0
|
||||||
|
|
||||||
@ -505,6 +509,12 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
|
|||||||
goto per_tcb_allocation_failed;
|
goto per_tcb_allocation_failed;
|
||||||
}
|
}
|
||||||
memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1);
|
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;
|
break;
|
||||||
|
|
||||||
per_tcb_allocation_failed:
|
per_tcb_allocation_failed:
|
||||||
@ -524,6 +534,13 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
|
|||||||
adapter->RcvRings = NULL;
|
adapter->RcvRings = NULL;
|
||||||
}
|
}
|
||||||
/* Loop around and try again.... */
|
/* 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__);
|
DBG_ERROR("%s Initialize RCV ZERO and XMT ZERO rings\n", __func__);
|
||||||
@ -1213,7 +1230,7 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
|
|||||||
}
|
}
|
||||||
/* Slowpath send completions */
|
/* Slowpath send completions */
|
||||||
if (Isr & SXG_ISR_SPSEND) {
|
if (Isr & SXG_ISR_SPSEND) {
|
||||||
sxg_complete_slow_send(adapter);
|
sxg_complete_slow_send(adapter, 1);
|
||||||
}
|
}
|
||||||
/* Dump */
|
/* Dump */
|
||||||
if (Isr & SXG_ISR_UPC) {
|
if (Isr & SXG_ISR_UPC) {
|
||||||
@ -1400,27 +1417,37 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
|
|||||||
*
|
*
|
||||||
* Arguments -
|
* Arguments -
|
||||||
* adapter - A pointer to our adapter structure
|
* adapter - A pointer to our adapter structure
|
||||||
|
* irq_context - An integer to denote if we are in interrupt context
|
||||||
* Return
|
* Return
|
||||||
* None
|
* None
|
||||||
*/
|
*/
|
||||||
static void sxg_complete_slow_send(struct adapter_t *adapter)
|
static void sxg_complete_slow_send(struct adapter_t *adapter, int irq_context)
|
||||||
{
|
{
|
||||||
struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0];
|
struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0];
|
||||||
struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo;
|
struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo;
|
||||||
u32 *ContextType;
|
u32 *ContextType;
|
||||||
struct sxg_cmd *XmtCmd;
|
struct sxg_cmd *XmtCmd;
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long sgl_flags;
|
||||||
|
unsigned int processed_count = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE - This lock is dropped and regrabbed in this loop.
|
* NOTE - This lock is dropped and regrabbed in this loop.
|
||||||
* This means two different processors can both be running/
|
* This means two different processors can both be running/
|
||||||
* through this loop. Be *very* careful.
|
* through this loop. Be *very* careful.
|
||||||
*/
|
*/
|
||||||
spin_lock(&adapter->XmtZeroLock);
|
if(irq_context) {
|
||||||
|
if(!spin_trylock(&adapter->XmtZeroLock))
|
||||||
|
goto lock_busy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
spin_lock_irqsave(&adapter->XmtZeroLock, flags);
|
||||||
|
|
||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnds",
|
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnds",
|
||||||
adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
|
adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
|
||||||
|
|
||||||
while (XmtRingInfo->Tail != *adapter->XmtRingZeroIndex) {
|
while ((XmtRingInfo->Tail != *adapter->XmtRingZeroIndex)
|
||||||
|
&& processed_count++ < SXG_COMPLETE_SLOW_SEND_LIMIT) {
|
||||||
/*
|
/*
|
||||||
* Locate the current Cmd (ring descriptor entry), and
|
* Locate the current Cmd (ring descriptor entry), and
|
||||||
* associated SGL, and advance the tail
|
* associated SGL, and advance the tail
|
||||||
@ -1438,10 +1465,14 @@ static void sxg_complete_slow_send(struct adapter_t *adapter)
|
|||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct sxg_scatter_gather *SxgSgl =
|
struct sxg_scatter_gather *SxgSgl =
|
||||||
(struct sxg_scatter_gather *)ContextType;
|
(struct sxg_scatter_gather *)ContextType;
|
||||||
|
dma64_addr_t FirstSgeAddress;
|
||||||
|
u32 FirstSgeLength;
|
||||||
|
|
||||||
/* Dumb-nic send. Command context is the dumb-nic SGL */
|
/* Dumb-nic send. Command context is the dumb-nic SGL */
|
||||||
skb = (struct sk_buff *)ContextType;
|
skb = (struct sk_buff *)ContextType;
|
||||||
skb = SxgSgl->DumbPacket;
|
skb = SxgSgl->DumbPacket;
|
||||||
|
FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress;
|
||||||
|
FirstSgeLength = XmtCmd->Buffer.FirstSgeLength;
|
||||||
/* Complete the send */
|
/* Complete the send */
|
||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
|
SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
|
||||||
TRACE_IMPORTANT, "DmSndCmp", skb, 0,
|
TRACE_IMPORTANT, "DmSndCmp", skb, 0,
|
||||||
@ -1456,17 +1487,36 @@ static void sxg_complete_slow_send(struct adapter_t *adapter)
|
|||||||
* chimney send, which results in a double trip
|
* chimney send, which results in a double trip
|
||||||
* in SxgTcpOuput
|
* in SxgTcpOuput
|
||||||
*/
|
*/
|
||||||
spin_unlock(&adapter->XmtZeroLock);
|
if(irq_context)
|
||||||
SXG_COMPLETE_DUMB_SEND(adapter, skb);
|
spin_unlock(&adapter->XmtZeroLock);
|
||||||
|
else
|
||||||
|
spin_unlock_irqrestore(
|
||||||
|
&adapter->XmtZeroLock, flags);
|
||||||
|
|
||||||
|
SxgSgl->DumbPacket = NULL;
|
||||||
|
SXG_COMPLETE_DUMB_SEND(adapter, skb,
|
||||||
|
FirstSgeAddress,
|
||||||
|
FirstSgeLength);
|
||||||
|
SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL,
|
||||||
|
irq_context);
|
||||||
/* and reacquire.. */
|
/* and reacquire.. */
|
||||||
spin_lock(&adapter->XmtZeroLock);
|
if(irq_context) {
|
||||||
|
if(!spin_trylock(&adapter->XmtZeroLock))
|
||||||
|
goto lock_busy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
spin_lock_irqsave(&adapter->XmtZeroLock, flags);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock(&adapter->XmtZeroLock);
|
if(irq_context)
|
||||||
|
spin_unlock(&adapter->XmtZeroLock);
|
||||||
|
else
|
||||||
|
spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
|
||||||
|
lock_busy:
|
||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
|
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
|
||||||
adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
|
adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
|
||||||
}
|
}
|
||||||
@ -1486,8 +1536,14 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
|
|||||||
u32 BufferSize = adapter->ReceiveBufferSize;
|
u32 BufferSize = adapter->ReceiveBufferSize;
|
||||||
struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
|
struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
|
||||||
struct sk_buff *Packet;
|
struct sk_buff *Packet;
|
||||||
|
static int read_counter = 0;
|
||||||
|
|
||||||
RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) Event->HostHandle;
|
RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) Event->HostHandle;
|
||||||
|
if(read_counter++ & 0x100)
|
||||||
|
{
|
||||||
|
sxg_collect_statistics(adapter);
|
||||||
|
read_counter = 0;
|
||||||
|
}
|
||||||
ASSERT(RcvDataBufferHdr);
|
ASSERT(RcvDataBufferHdr);
|
||||||
ASSERT(RcvDataBufferHdr->State == SXG_BUFFER_ONCARD);
|
ASSERT(RcvDataBufferHdr->State == SXG_BUFFER_ONCARD);
|
||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event,
|
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event,
|
||||||
@ -1560,12 +1616,13 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
|
|||||||
RcvDataBufferHdr, Packet, Event->Length, 0);
|
RcvDataBufferHdr, Packet, Event->Length, 0);
|
||||||
/* Lastly adjust the receive packet length. */
|
/* Lastly adjust the receive packet length. */
|
||||||
RcvDataBufferHdr->SxgDumbRcvPacket = NULL;
|
RcvDataBufferHdr->SxgDumbRcvPacket = NULL;
|
||||||
|
RcvDataBufferHdr->PhysicalAddress = NULL;
|
||||||
SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize);
|
SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize);
|
||||||
if (RcvDataBufferHdr->skb)
|
if (RcvDataBufferHdr->skb)
|
||||||
{
|
{
|
||||||
spin_lock(&adapter->RcvQLock);
|
spin_lock(&adapter->RcvQLock);
|
||||||
SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
|
SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
|
||||||
adapter->RcvBuffersOnCard ++;
|
// adapter->RcvBuffersOnCard ++;
|
||||||
spin_unlock(&adapter->RcvQLock);
|
spin_unlock(&adapter->RcvQLock);
|
||||||
}
|
}
|
||||||
return (Packet);
|
return (Packet);
|
||||||
@ -1911,20 +1968,17 @@ static void __devexit sxg_entry_remove(struct pci_dev *pcidev)
|
|||||||
u32 mmio_start = 0;
|
u32 mmio_start = 0;
|
||||||
unsigned int mmio_len = 0;
|
unsigned int mmio_len = 0;
|
||||||
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
|
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
|
||||||
|
/*
|
||||||
set_bit(ADAPT_DOWN, &adapter->state);
|
set_bit(ADAPT_DOWN, &adapter->state);
|
||||||
flush_scheduled_work();
|
*/ flush_scheduled_work();
|
||||||
|
|
||||||
/* Deallocate Resources */
|
/* Deallocate Resources */
|
||||||
|
unregister_netdev(dev);
|
||||||
SxgFreeResources(adapter);
|
sxg_free_resources(adapter);
|
||||||
|
|
||||||
ASSERT(adapter);
|
ASSERT(adapter);
|
||||||
DBG_ERROR("sxg: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
|
DBG_ERROR("sxg: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
|
||||||
adapter);
|
adapter);
|
||||||
sxg_deregister_interrupt(adapter);
|
|
||||||
sxg_unmap_mmio_space(adapter);
|
|
||||||
DBG_ERROR("sxg: %s unregister_netdev\n", __func__);
|
|
||||||
|
|
||||||
mmio_start = pci_resource_start(pcidev, 0);
|
mmio_start = pci_resource_start(pcidev, 0);
|
||||||
mmio_len = pci_resource_len(pcidev, 0);
|
mmio_len = pci_resource_len(pcidev, 0);
|
||||||
@ -1933,11 +1987,6 @@ static void __devexit sxg_entry_remove(struct pci_dev *pcidev)
|
|||||||
mmio_start, mmio_len);
|
mmio_start, mmio_len);
|
||||||
release_mem_region(mmio_start, mmio_len);
|
release_mem_region(mmio_start, mmio_len);
|
||||||
|
|
||||||
/*
|
|
||||||
DBG_ERROR("sxg: %s iounmap dev->base_addr[%x]\n", __func__,
|
|
||||||
(unsigned int)dev->base_addr);
|
|
||||||
iounmap((char *)dev->base_addr);
|
|
||||||
*/
|
|
||||||
mmio_start = pci_resource_start(pcidev, 2);
|
mmio_start = pci_resource_start(pcidev, 2);
|
||||||
mmio_len = pci_resource_len(pcidev, 2);
|
mmio_len = pci_resource_len(pcidev, 2);
|
||||||
|
|
||||||
@ -1945,10 +1994,6 @@ static void __devexit sxg_entry_remove(struct pci_dev *pcidev)
|
|||||||
mmio_start, mmio_len);
|
mmio_start, mmio_len);
|
||||||
release_mem_region(mmio_start, mmio_len);
|
release_mem_region(mmio_start, mmio_len);
|
||||||
|
|
||||||
iounmap((char *)dev->base_addr);
|
|
||||||
unregister_netdev(dev);
|
|
||||||
//pci_release_regions(pcidev);
|
|
||||||
//free_netdev(dev);
|
|
||||||
pci_disable_device(pcidev);
|
pci_disable_device(pcidev);
|
||||||
|
|
||||||
DBG_ERROR("sxg: %s deallocate device\n", __func__);
|
DBG_ERROR("sxg: %s deallocate device\n", __func__);
|
||||||
@ -1978,6 +2023,7 @@ static int sxg_entry_halt(struct net_device *dev)
|
|||||||
|
|
||||||
spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
|
spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
|
||||||
|
|
||||||
|
sxg_deregister_interrupt(adapter);
|
||||||
return (STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2076,13 +2122,14 @@ static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev)
|
|||||||
#else
|
#else
|
||||||
SXG_DROP_DUMB_SEND(adapter, skb);
|
SXG_DROP_DUMB_SEND(adapter, skb);
|
||||||
adapter->stats.tx_dropped++;
|
adapter->stats.tx_dropped++;
|
||||||
|
return NETDEV_TX_BUSY;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __func__,
|
DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __func__,
|
||||||
status);
|
status);
|
||||||
|
|
||||||
xmit_done:
|
xmit_done:
|
||||||
return 0;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2100,6 +2147,7 @@ static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
|
|||||||
{
|
{
|
||||||
struct sxg_x64_sgl *pSgl;
|
struct sxg_x64_sgl *pSgl;
|
||||||
struct sxg_scatter_gather *SxgSgl;
|
struct sxg_scatter_gather *SxgSgl;
|
||||||
|
unsigned long sgl_flags;
|
||||||
/* void *SglBuffer; */
|
/* void *SglBuffer; */
|
||||||
/* u32 SglBufferLength; */
|
/* u32 SglBufferLength; */
|
||||||
|
|
||||||
@ -2111,7 +2159,7 @@ static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
|
|||||||
adapter, skb, 0, 0);
|
adapter, skb, 0, 0);
|
||||||
|
|
||||||
/* Allocate a SGL buffer */
|
/* Allocate a SGL buffer */
|
||||||
SXG_GET_SGL_BUFFER(adapter, SxgSgl);
|
SXG_GET_SGL_BUFFER(adapter, SxgSgl, 0);
|
||||||
if (!SxgSgl) {
|
if (!SxgSgl) {
|
||||||
adapter->Stats.NoSglBuf++;
|
adapter->Stats.NoSglBuf++;
|
||||||
adapter->Stats.XmtErrors++;
|
adapter->Stats.XmtErrors++;
|
||||||
@ -2129,9 +2177,7 @@ static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
|
|||||||
pSgl = NULL;
|
pSgl = NULL;
|
||||||
|
|
||||||
/* Call the common sxg_dumb_sgl routine to complete the send. */
|
/* Call the common sxg_dumb_sgl routine to complete the send. */
|
||||||
sxg_dumb_sgl(pSgl, SxgSgl);
|
return (sxg_dumb_sgl(pSgl, SxgSgl));
|
||||||
/* Return success sxg_dumb_sgl (or something later) will complete it.*/
|
|
||||||
return (STATUS_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2142,9 +2188,9 @@ static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
|
|||||||
* SxgSgl - struct sxg_scatter_gather
|
* SxgSgl - struct sxg_scatter_gather
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None.
|
* Status of send operation.
|
||||||
*/
|
*/
|
||||||
static void sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
||||||
struct sxg_scatter_gather *SxgSgl)
|
struct sxg_scatter_gather *SxgSgl)
|
||||||
{
|
{
|
||||||
struct adapter_t *adapter = SxgSgl->adapter;
|
struct adapter_t *adapter = SxgSgl->adapter;
|
||||||
@ -2158,6 +2204,7 @@ static void sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
|||||||
/* unsigned int BufLen; */
|
/* unsigned int BufLen; */
|
||||||
/* u32 SglOffset; */
|
/* u32 SglOffset; */
|
||||||
u64 phys_addr;
|
u64 phys_addr;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
|
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
|
||||||
pSgl, SxgSgl, 0, 0);
|
pSgl, SxgSgl, 0, 0);
|
||||||
@ -2179,16 +2226,17 @@ static void sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
|||||||
SxgSgl->Sgl.NumberOfElements = 1;
|
SxgSgl->Sgl.NumberOfElements = 1;
|
||||||
|
|
||||||
/* Grab the spinlock and acquire a command */
|
/* Grab the spinlock and acquire a command */
|
||||||
spin_lock(&adapter->XmtZeroLock);
|
spin_lock_irqsave(&adapter->XmtZeroLock, flags);
|
||||||
SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
|
SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
|
||||||
if (XmtCmd == NULL) {
|
if (XmtCmd == NULL) {
|
||||||
/*
|
/*
|
||||||
* Call sxg_complete_slow_send to see if we can
|
* Call sxg_complete_slow_send to see if we can
|
||||||
* free up any XmtRingZero entries and then try again
|
* free up any XmtRingZero entries and then try again
|
||||||
*/
|
*/
|
||||||
spin_unlock(&adapter->XmtZeroLock);
|
|
||||||
sxg_complete_slow_send(adapter);
|
spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
|
||||||
spin_lock(&adapter->XmtZeroLock);
|
sxg_complete_slow_send(adapter, 0);
|
||||||
|
spin_lock_irqsave(&adapter->XmtZeroLock, flags);
|
||||||
SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
|
SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
|
||||||
if (XmtCmd == NULL) {
|
if (XmtCmd == NULL) {
|
||||||
adapter->Stats.XmtZeroFull++;
|
adapter->Stats.XmtZeroFull++;
|
||||||
@ -2235,10 +2283,10 @@ static void sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
|||||||
*/
|
*/
|
||||||
WRITE_REG(adapter->UcodeRegs[0].XmtCmd, 1, TRUE);
|
WRITE_REG(adapter->UcodeRegs[0].XmtCmd, 1, TRUE);
|
||||||
adapter->Stats.XmtQLen++; /* Stats within lock */
|
adapter->Stats.XmtQLen++; /* Stats within lock */
|
||||||
spin_unlock(&adapter->XmtZeroLock);
|
spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
|
||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2",
|
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2",
|
||||||
XmtCmd, pSgl, SxgSgl, 0);
|
XmtCmd, pSgl, SxgSgl, 0);
|
||||||
return;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
abortcmd:
|
abortcmd:
|
||||||
/*
|
/*
|
||||||
@ -2249,7 +2297,8 @@ static void sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
|||||||
if (XmtCmd) {
|
if (XmtCmd) {
|
||||||
SXG_ABORT_CMD(XmtRingInfo);
|
SXG_ABORT_CMD(XmtRingInfo);
|
||||||
}
|
}
|
||||||
spin_unlock(&adapter->XmtZeroLock);
|
spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
|
||||||
|
return STATUS_FAILURE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* failsgl:
|
* failsgl:
|
||||||
@ -2260,7 +2309,7 @@ static void sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
|||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal",
|
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal",
|
||||||
pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail);
|
pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail);
|
||||||
/* SxgSgl->DumbPacket is the skb */
|
/* SxgSgl->DumbPacket is the skb */
|
||||||
SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket);
|
// SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3065,58 +3114,85 @@ static void sxg_unmap_mmio_space(struct adapter_t *adapter)
|
|||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void SxgFreeRcvBlocks(struct adapter_t *adapter)
|
void sxg_free_sgl_buffers(struct adapter_t *adapter)
|
||||||
{
|
{
|
||||||
u32 i;
|
|
||||||
struct list_entry *ple;
|
struct list_entry *ple;
|
||||||
struct sxg_rcv_block_hdr *Hdr;
|
struct sxg_scatter_gather *Sgl;
|
||||||
struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
|
|
||||||
u32 FreeBuffers = 0, FreeBlocks = 0;
|
|
||||||
|
|
||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FrRcvBlk",
|
while(!(IsListEmpty(&adapter->AllSglBuffers))) {
|
||||||
adapter, 0, 0, 0);
|
ple = RemoveHeadList(&adapter->AllSglBuffers);
|
||||||
|
Sgl = container_of(ple, struct sxg_scatter_gather, AllList);
|
||||||
ASSERT((adapter->State == SXG_STATE_INITIALIZING) ||
|
kfree(Sgl);
|
||||||
(pAdapt->State == SXG_STATE_HALTING));
|
adapter->AllSglBufferCount--;
|
||||||
|
|
||||||
for(i = 0; i < SXG_MAX_CPU; i++) {
|
|
||||||
FreeBuffers += pAdapt->PerCpuResources[i].FreeReceiveBuffers.Count;
|
|
||||||
FreeBlocks += pAdapt->PerCpuResources[i].FreeReceiveBlocks.Count;
|
|
||||||
pAdapt->PerCpuResources[i].FreeReceiveBuffers.Count = 0;
|
|
||||||
pAdapt->PerCpuResources[i].FreeReceiveBuffers.FreeList = NULL;
|
|
||||||
pAdapt->PerCpuResources[i].FreeReceiveBlocks.Count = 0;
|
|
||||||
pAdapt->PerCpuResources[i].FreeReceiveBlocks.FreeList = NULL;
|
|
||||||
}
|
}
|
||||||
FreeBuffers += pAdapt->GlobalResources.FreeReceiveBuffers.Count;
|
|
||||||
FreeBlocks += pAdapt->GlobalResources.FreeReceiveBlocks.Count;
|
|
||||||
pAdapt->GlobalResources.FreeReceiveBuffers.Count = 0;
|
|
||||||
pAdapt->GlobalResources.FreeReceiveBuffers.FreeList = NULL;
|
|
||||||
pAdapt->GlobalResources.FreeReceiveBlocks.Count = 0;
|
|
||||||
pAdapt->GlobalResources.FreeReceiveBlocks.FreeList = NULL;
|
|
||||||
ASSERT(FreeBlocks == pAdapt->AllRcvBlockCount); // See SXG_RCV_BLOCK
|
|
||||||
ASSERT(FreeBuffers ==
|
|
||||||
(pAdapt->AllRcvBlockCount * SXG_RCV_DESCRIPTORS_PER_BLOCK)); // See SXG_RCV_BLOCK
|
|
||||||
|
|
||||||
while(!(IsListEmpty(&pAdapt->AllRcvBlocks))) {
|
|
||||||
ple = RemoveHeadList(&pAdapt->AllRcvBlocks);
|
|
||||||
Hdr = CONTAINING_RECORD(ple, SXG_RCV_BLOCK_HDR, AllList);
|
|
||||||
NdisMFreeSharedMemory(pAdapt->MiniportHandle,
|
|
||||||
SXG_RCV_BLOCK_SIZE(pAdapt->ReceiveBufferSize),
|
|
||||||
TRUE,
|
|
||||||
Hdr->VirtualAddress,
|
|
||||||
Hdr->PhysicalAddress);
|
|
||||||
pAdapt->AllRcvBlockCount--;
|
|
||||||
}
|
|
||||||
ASSERT(pAdapt->AllRcvBlockCount == 0);
|
|
||||||
SLIC_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk",
|
|
||||||
pAdapt, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
//#if XXXTODO
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SxgFreeResources - Free everything allocated in SxgAllocateResources
|
* sxg_free_resources - Free everything allocated in SxgAllocateResources
|
||||||
*
|
*
|
||||||
* Arguments -
|
* Arguments -
|
||||||
* adapter - A pointer to our adapter structure
|
* adapter - A pointer to our adapter structure
|
||||||
@ -3124,14 +3200,10 @@ void SxgFreeRcvBlocks(struct adapter_t *adapter)
|
|||||||
* Return
|
* Return
|
||||||
* none
|
* none
|
||||||
*/
|
*/
|
||||||
void SxgFreeResources(struct adapter_t *adapter)
|
void sxg_free_resources(struct adapter_t *adapter)
|
||||||
{
|
{
|
||||||
u32 RssIds, IsrCount;
|
u32 RssIds, IsrCount;
|
||||||
u32 i;
|
u32 i;
|
||||||
/*
|
|
||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FreeRes",
|
|
||||||
adapter, adapter->MaxTcbs, 0, 0);
|
|
||||||
*/
|
|
||||||
RssIds = SXG_RSS_CPU_COUNT(adapter);
|
RssIds = SXG_RSS_CPU_COUNT(adapter);
|
||||||
IsrCount = adapter->MsiEnabled ? RssIds : 1;
|
IsrCount = adapter->MsiEnabled ? RssIds : 1;
|
||||||
|
|
||||||
@ -3142,14 +3214,13 @@ void SxgFreeResources(struct adapter_t *adapter)
|
|||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
|
if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
|
||||||
SxgFreeRcvBlocks(adapter);
|
sxg_free_rcvblocks(adapter);
|
||||||
}
|
}
|
||||||
if (!(IsListEmpty(&adapter->AllSglBuffers))) {
|
if (!(IsListEmpty(&adapter->AllSglBuffers))) {
|
||||||
SxgFreeSglBuffers(adapter);
|
sxg_free_sgl_buffers(adapter);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
if (adapter->XmtRingZeroIndex) {
|
if (adapter->XmtRingZeroIndex) {
|
||||||
pci_free_consistent(adapter->pcidev,
|
pci_free_consistent(adapter->pcidev,
|
||||||
@ -3157,82 +3228,49 @@ void SxgFreeResources(struct adapter_t *adapter)
|
|||||||
adapter->XmtRingZeroIndex,
|
adapter->XmtRingZeroIndex,
|
||||||
adapter->PXmtRingZeroIndex);
|
adapter->PXmtRingZeroIndex);
|
||||||
}
|
}
|
||||||
printk("VSS Free Isr\n");
|
|
||||||
if (adapter->Isr) {
|
if (adapter->Isr) {
|
||||||
pci_free_consistent(adapter->pcidev,
|
pci_free_consistent(adapter->pcidev,
|
||||||
sizeof(u32) * IsrCount,
|
sizeof(u32) * IsrCount,
|
||||||
adapter->Isr, adapter->PIsr);
|
adapter->Isr, adapter->PIsr);
|
||||||
}
|
}
|
||||||
|
|
||||||
printk("VSS Free EventRings\n");
|
|
||||||
if (adapter->EventRings) {
|
if (adapter->EventRings) {
|
||||||
pci_free_consistent(adapter->pcidev,
|
pci_free_consistent(adapter->pcidev,
|
||||||
sizeof(struct sxg_event_ring) * RssIds,
|
sizeof(struct sxg_event_ring) * RssIds,
|
||||||
adapter->EventRings, adapter->PEventRings);
|
adapter->EventRings, adapter->PEventRings);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
printk("VSS Free RcvRings\n");
|
|
||||||
if (adapter->RcvRings) {
|
if (adapter->RcvRings) {
|
||||||
pci_free_consistent(adapter->pcidev,
|
pci_free_consistent(adapter->pcidev,
|
||||||
sizeof(struct sxg_rcv_ring) * 4096,
|
sizeof(struct sxg_rcv_ring) * 1,
|
||||||
adapter->RcvRings,
|
adapter->RcvRings,
|
||||||
adapter->PRcvRings);
|
adapter->PRcvRings);
|
||||||
adapter->RcvRings = NULL;
|
adapter->RcvRings = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk("VSS Free XmtRings\n");
|
|
||||||
if(adapter->XmtRings) {
|
if(adapter->XmtRings) {
|
||||||
pci_free_consistent(adapter->pcidev,
|
pci_free_consistent(adapter->pcidev,
|
||||||
sizeof(struct sxg_xmt_ring) * 4096,
|
sizeof(struct sxg_xmt_ring) * 1,
|
||||||
adapter->XmtRings,
|
adapter->XmtRings,
|
||||||
adapter->PXmtRings);
|
adapter->PXmtRings);
|
||||||
adapter->XmtRings = NULL;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
SXG_FREE_PACKET_POOL(adapter->PacketPoolHandle);
|
|
||||||
SXG_FREE_BUFFER_POOL(adapter->BufferPoolHandle);
|
|
||||||
*/
|
|
||||||
/* Unmap register spaces */
|
/* Unmap register spaces */
|
||||||
// SxgUnmapResources(adapter);
|
sxg_unmap_resources(adapter);
|
||||||
|
|
||||||
/* Deregister DMA */
|
sxg_free_mcast_addrs(adapter);
|
||||||
/* if (adapter->DmaHandle) {
|
|
||||||
SXG_DEREGISTER_DMA(adapter->DmaHandle);
|
|
||||||
}
|
|
||||||
*/ /* Deregister interrupt */
|
|
||||||
// SxgDeregisterInterrupt(adapter);
|
|
||||||
|
|
||||||
/* Possibly free system info (5.2 only) */
|
|
||||||
// SXG_RELEASE_SYSTEM_INFO(adapter);
|
|
||||||
|
|
||||||
//SxgDiagFreeResources(adapter);
|
|
||||||
|
|
||||||
// SxgFreeMCastAddrs(adapter);
|
|
||||||
/*
|
|
||||||
if (SXG_TIMER_ALLOCATED(adapter->ResetTimer)) {
|
|
||||||
SXG_CANCEL_TIMER(adapter->ResetTimer, TimerCancelled);
|
|
||||||
SXG_FREE_TIMER(adapter->ResetTimer);
|
|
||||||
}
|
|
||||||
if (SXG_TIMER_ALLOCATED(adapter->RssTimer)) {
|
|
||||||
SXG_CANCEL_TIMER(adapter->RssTimer, TimerCancelled);
|
|
||||||
SXG_FREE_TIMER(adapter->RssTimer);
|
|
||||||
}
|
|
||||||
if (SXG_TIMER_ALLOCATED(adapter->OffloadTimer)) {
|
|
||||||
SXG_CANCEL_TIMER(adapter->OffloadTimer, TimerCancelled);
|
|
||||||
SXG_FREE_TIMER(adapter->OffloadTimer);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
adapter->BasicAllocations = FALSE;
|
adapter->BasicAllocations = FALSE;
|
||||||
|
|
||||||
/* SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFreeRes",
|
|
||||||
adapter, adapter->MaxTcbs, 0, 0);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
// #endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sxg_allocate_complete -
|
* sxg_allocate_complete -
|
||||||
@ -3311,8 +3349,12 @@ static int sxg_allocate_buffer_memory(struct adapter_t *adapter,
|
|||||||
++adapter->AllocationsPending;
|
++adapter->AllocationsPending;
|
||||||
spin_unlock(&adapter->AdapterLock);
|
spin_unlock(&adapter->AdapterLock);
|
||||||
|
|
||||||
/* At initialization time allocate resources synchronously. */
|
if(BufferType != SXG_BUFFER_TYPE_SGL)
|
||||||
Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer);
|
Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer);
|
||||||
|
else {
|
||||||
|
Buffer = kzalloc(Size, GFP_ATOMIC);
|
||||||
|
pBuffer = NULL;
|
||||||
|
}
|
||||||
if (Buffer == NULL) {
|
if (Buffer == NULL) {
|
||||||
spin_lock(&adapter->AdapterLock);
|
spin_lock(&adapter->AdapterLock);
|
||||||
/*
|
/*
|
||||||
@ -3468,19 +3510,25 @@ static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter,
|
|||||||
dma_addr_t PhysicalAddress,
|
dma_addr_t PhysicalAddress,
|
||||||
u32 Length)
|
u32 Length)
|
||||||
{
|
{
|
||||||
|
unsigned long sgl_flags;
|
||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlSglCmp",
|
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlSglCmp",
|
||||||
adapter, SxgSgl, Length, 0);
|
adapter, SxgSgl, Length, 0);
|
||||||
spin_lock(&adapter->SglQLock);
|
if(!in_irq())
|
||||||
|
spin_unlock_irqrestore(&adapter->SglQLock, sgl_flags);
|
||||||
|
else
|
||||||
|
spin_unlock(&adapter->SglQLock);
|
||||||
adapter->AllSglBufferCount++;
|
adapter->AllSglBufferCount++;
|
||||||
memset(SxgSgl, 0, sizeof(struct sxg_scatter_gather));
|
/* PhysicalAddress; */
|
||||||
/* *PhysicalAddress; */
|
|
||||||
SxgSgl->PhysicalAddress = PhysicalAddress;
|
SxgSgl->PhysicalAddress = PhysicalAddress;
|
||||||
/* Initialize backpointer once */
|
/* Initialize backpointer once */
|
||||||
SxgSgl->adapter = adapter;
|
SxgSgl->adapter = adapter;
|
||||||
InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList);
|
InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList);
|
||||||
spin_unlock(&adapter->SglQLock);
|
if(!in_irq())
|
||||||
|
spin_unlock_irqrestore(&adapter->SglQLock, sgl_flags);
|
||||||
|
else
|
||||||
|
spin_unlock(&adapter->SglQLock);
|
||||||
SxgSgl->State = SXG_BUFFER_BUSY;
|
SxgSgl->State = SXG_BUFFER_BUSY;
|
||||||
SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL);
|
SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL, in_irq());
|
||||||
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlSgl",
|
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlSgl",
|
||||||
adapter, SxgSgl, Length, 0);
|
adapter, SxgSgl, Length, 0);
|
||||||
}
|
}
|
||||||
@ -3702,6 +3750,15 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
|
|||||||
SXG_GET_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
|
SXG_GET_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
|
||||||
ASSERT(RcvDataBufferHdr);
|
ASSERT(RcvDataBufferHdr);
|
||||||
ASSERT(RcvDataBufferHdr->SxgDumbRcvPacket);
|
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);
|
SXG_REINIATIALIZE_PACKET(RcvDataBufferHdr->SxgDumbRcvPacket);
|
||||||
RcvDataBufferHdr->State = SXG_BUFFER_ONCARD;
|
RcvDataBufferHdr->State = SXG_BUFFER_ONCARD;
|
||||||
RcvDescriptorBlock->Descriptors[i].VirtualAddress =
|
RcvDescriptorBlock->Descriptors[i].VirtualAddress =
|
||||||
@ -3730,6 +3787,8 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
|
|||||||
adapter, adapter->RcvBuffersOnCard,
|
adapter, adapter->RcvBuffersOnCard,
|
||||||
adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
|
adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
|
||||||
return (STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
|
no_memory:
|
||||||
|
return (-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3823,7 +3882,8 @@ static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
|
|||||||
/* Now grab the RcvQLock lock and proceed */
|
/* Now grab the RcvQLock lock and proceed */
|
||||||
spin_lock(&adapter->RcvQLock);
|
spin_lock(&adapter->RcvQLock);
|
||||||
ASSERT(Index != RcvRingInfo->Tail);
|
ASSERT(Index != RcvRingInfo->Tail);
|
||||||
while (RcvRingInfo->Tail != Index) {
|
while (sxg_ring_get_forward_diff(RcvRingInfo, Index,
|
||||||
|
RcvRingInfo->Tail) > 3) {
|
||||||
/*
|
/*
|
||||||
* Locate the current Cmd (ring descriptor entry), and
|
* Locate the current Cmd (ring descriptor entry), and
|
||||||
* associated receive descriptor block, and advance
|
* associated receive descriptor block, and advance
|
||||||
@ -3854,6 +3914,15 @@ static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
|
|||||||
adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
static struct pci_driver sxg_driver = {
|
static struct pci_driver sxg_driver = {
|
||||||
.name = sxg_driver_name,
|
.name = sxg_driver_name,
|
||||||
.id_table = sxg_pci_tbl,
|
.id_table = sxg_pci_tbl,
|
||||||
|
@ -121,9 +121,10 @@ struct sxg_stats {
|
|||||||
|
|
||||||
/* DUMB-NIC Send path definitions */
|
/* DUMB-NIC Send path definitions */
|
||||||
|
|
||||||
#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb) { \
|
#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb, _phys_addr, _size) { \
|
||||||
ASSERT(_skb); \
|
ASSERT(_skb); \
|
||||||
dev_kfree_skb_irq(_skb); \
|
pci_unmap_single(_pAdapt->pcidev, _size, _phys_addr, PCI_DMA_TODEVICE); \
|
||||||
|
dev_kfree_skb_irq(_skb); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) { \
|
#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) { \
|
||||||
@ -262,14 +263,20 @@ struct sxg_stats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* SGL macros */
|
/* SGL macros */
|
||||||
#define SXG_FREE_SGL_BUFFER(_pAdapt, _Sgl, _NB) { \
|
#define SXG_FREE_SGL_BUFFER(_pAdapt, _Sgl, _NB, _irq) { \
|
||||||
spin_lock(&(_pAdapt)->SglQLock); \
|
if(!_irq) \
|
||||||
|
spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \
|
||||||
|
else \
|
||||||
|
spin_lock(&(_pAdapt)->SglQLock); \
|
||||||
(_pAdapt)->FreeSglBufferCount++; \
|
(_pAdapt)->FreeSglBufferCount++; \
|
||||||
ASSERT((_pAdapt)->AllSglBufferCount >= (_pAdapt)->FreeSglBufferCount); \
|
ASSERT((_pAdapt)->AllSglBufferCount >= (_pAdapt)->FreeSglBufferCount); \
|
||||||
ASSERT(!((_Sgl)->State & SXG_BUFFER_FREE)); \
|
ASSERT(!((_Sgl)->State & SXG_BUFFER_FREE)); \
|
||||||
(_Sgl)->State = SXG_BUFFER_FREE; \
|
(_Sgl)->State = SXG_BUFFER_FREE; \
|
||||||
InsertTailList(&(_pAdapt)->FreeSglBuffers, &(_Sgl)->FreeList); \
|
InsertTailList(&(_pAdapt)->FreeSglBuffers, &(_Sgl)->FreeList); \
|
||||||
spin_unlock(&(_pAdapt)->SglQLock); \
|
if(!_irq) \
|
||||||
|
spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags); \
|
||||||
|
else \
|
||||||
|
spin_unlock(&(_pAdapt)->SglQLock); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -279,7 +286,7 @@ struct sxg_stats {
|
|||||||
* until after that. We're dealing with round numbers here, so we don't need to,
|
* 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.
|
* and not grabbing it avoids a possible double-trip.
|
||||||
*/
|
*/
|
||||||
#define SXG_GET_SGL_BUFFER(_pAdapt, _Sgl) { \
|
#define SXG_GET_SGL_BUFFER(_pAdapt, _Sgl, _irq) { \
|
||||||
struct list_entry *_ple; \
|
struct list_entry *_ple; \
|
||||||
if ((_pAdapt->FreeSglBufferCount < SXG_MIN_SGL_BUFFERS) && \
|
if ((_pAdapt->FreeSglBufferCount < SXG_MIN_SGL_BUFFERS) && \
|
||||||
(_pAdapt->AllSglBufferCount < SXG_MAX_SGL_BUFFERS) && \
|
(_pAdapt->AllSglBufferCount < SXG_MAX_SGL_BUFFERS) && \
|
||||||
@ -289,7 +296,10 @@ struct sxg_stats {
|
|||||||
SXG_BUFFER_TYPE_SGL); \
|
SXG_BUFFER_TYPE_SGL); \
|
||||||
} \
|
} \
|
||||||
_Sgl = NULL; \
|
_Sgl = NULL; \
|
||||||
spin_lock(&(_pAdapt)->SglQLock); \
|
if(!_irq) \
|
||||||
|
spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \
|
||||||
|
else \
|
||||||
|
spin_lock(&(_pAdapt)->SglQLock); \
|
||||||
if((_pAdapt)->FreeSglBufferCount) { \
|
if((_pAdapt)->FreeSglBufferCount) { \
|
||||||
ASSERT(!(IsListEmpty(&(_pAdapt)->FreeSglBuffers))); \
|
ASSERT(!(IsListEmpty(&(_pAdapt)->FreeSglBuffers))); \
|
||||||
_ple = RemoveHeadList(&(_pAdapt)->FreeSglBuffers); \
|
_ple = RemoveHeadList(&(_pAdapt)->FreeSglBuffers); \
|
||||||
@ -300,7 +310,10 @@ struct sxg_stats {
|
|||||||
(_Sgl)->State = SXG_BUFFER_BUSY; \
|
(_Sgl)->State = SXG_BUFFER_BUSY; \
|
||||||
(_Sgl)->pSgl = NULL; \
|
(_Sgl)->pSgl = NULL; \
|
||||||
} \
|
} \
|
||||||
spin_unlock(&(_pAdapt)->SglQLock); \
|
if(!_irq) \
|
||||||
|
spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\
|
||||||
|
else \
|
||||||
|
spin_unlock(&(_pAdapt)->SglQLock); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -416,6 +429,7 @@ struct sxg_driver {
|
|||||||
#undef STATUS_SUCCESS
|
#undef STATUS_SUCCESS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* TODO: We need to try and use NETDEV_TX_* before posting this out */
|
||||||
#define STATUS_SUCCESS 0
|
#define STATUS_SUCCESS 0
|
||||||
#define STATUS_PENDING 0
|
#define STATUS_PENDING 0
|
||||||
#define STATUS_FAILURE -1
|
#define STATUS_FAILURE -1
|
||||||
@ -631,6 +645,10 @@ struct adapter_t {
|
|||||||
|
|
||||||
struct sxg_rcv_ring *RcvRings; /* Receive rings */
|
struct sxg_rcv_ring *RcvRings; /* Receive rings */
|
||||||
dma_addr_t PRcvRings; /* Receive rings - physical address */
|
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 */
|
struct sxg_ring_info RcvRingZeroInfo; /* Receive ring 0 info */
|
||||||
|
|
||||||
u32 * Isr; /* Interrupt status register */
|
u32 * Isr; /* Interrupt status register */
|
||||||
@ -765,4 +783,5 @@ struct slic_crash_info {
|
|||||||
#define SIOCSLICTRACEDUMP (SIOCDEVPRIVATE+11)
|
#define SIOCSLICTRACEDUMP (SIOCDEVPRIVATE+11)
|
||||||
|
|
||||||
extern struct ethtool_ops sxg_nic_ethtool_ops;
|
extern struct ethtool_ops sxg_nic_ethtool_ops;
|
||||||
|
#define SXG_COMPLETE_SLOW_SEND_LIMIT 128
|
||||||
#endif /* __SXG_DRIVER_H__ */
|
#endif /* __SXG_DRIVER_H__ */
|
||||||
|
@ -137,7 +137,7 @@ sxg_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
|
|||||||
struct adapter_t *adapter = netdev_priv(dev);
|
struct adapter_t *adapter = netdev_priv(dev);
|
||||||
strncpy(drvinfo->driver, sxg_driver_name, 32);
|
strncpy(drvinfo->driver, sxg_driver_name, 32);
|
||||||
strncpy(drvinfo->version, SXG_DRV_VERSION, 32);
|
strncpy(drvinfo->version, SXG_DRV_VERSION, 32);
|
||||||
strncpy(drvinfo->fw_version, SAHARA_UCODE_VERS_STRING, 32);
|
// strncpy(drvinfo->fw_version, SAHARA_UCODE_VERS_STRING, 32);
|
||||||
strncpy(drvinfo->bus_info, pci_name(adapter->pcidev), 32);
|
strncpy(drvinfo->bus_info, pci_name(adapter->pcidev), 32);
|
||||||
/* TODO : Read the major and minor number of firmware. Is this
|
/* TODO : Read the major and minor number of firmware. Is this
|
||||||
* from the FLASH/EEPROM or download file ?
|
* from the FLASH/EEPROM or download file ?
|
||||||
|
@ -486,6 +486,20 @@ struct sxg_ring_info {
|
|||||||
SXG_RING_ADVANCE_TAIL(_ringinfo); \
|
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
|
* Host Command Buffer - commands to INIC via the Cmd Rings
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user