diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-24 00:12:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-24 00:12:35 +0000 |
commit | 482368b1a8e45430672c58c9a42e7d2004367126 (patch) | |
tree | ce2a1a567d4d62dee7c2e71a46a99cf72cf1d606 /drivers/net/sk98lin/skge.c | |
parent | e4d0251c6f56ab2e191afb70f80f382793e23f74 (diff) |
Merge with 2.3.47. Guys, this is buggy as shit. You've been warned.
Diffstat (limited to 'drivers/net/sk98lin/skge.c')
-rw-r--r-- | drivers/net/sk98lin/skge.c | 79 |
1 files changed, 54 insertions, 25 deletions
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c index d7ed239a4..f6710a0b5 100644 --- a/drivers/net/sk98lin/skge.c +++ b/drivers/net/sk98lin/skge.c @@ -276,7 +276,9 @@ static const char SysKonnectBuildNumber[] = // #define RLMT_MODE {"CheckLink", } -#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb); +#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb) +#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb) +#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb) /* function prototypes ******************************************************/ static void FreeResources(struct net_device *dev); @@ -410,6 +412,21 @@ static int __init skge_probe (void) pci_set_master(pdev); +#ifdef __sparc__ + /* Set the proper cache line size value, plus enable + * write-invalidate and fast back-to-back on Sparc. + */ + { + SK_U16 pci_command; + + SkPciWriteCfgByte(pAC, PCI_CACHE_LINE_SIZE, 0x10); + + SkPciReadCfgWord(pAC, PCI_COMMAND, &pci_command); + pci_command |= (PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK); + SkPciWriteCfgWord(pAC, PCI_COMMAND, pci_command); + } +#endif + base_address = pdev->resource[0].start; #ifdef SK_BIG_ENDIAN @@ -1507,13 +1524,16 @@ int Rc; /* return code of XmitFrame */ Rc = XmitFrame(pAC, &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], skb); - if (Rc == 0) { - /* transmitter out of resources */ + /* Transmitter out of resources? */ + if (Rc <= 0) netif_stop_queue(dev); - /* give buffer ownership back to the queueing layer */ + /* If not taken, give buffer ownership back to the + * queueing layer. + */ + if (Rc < 0) return (1); - } + dev->trans_start = jiffies; return (0); } /* SkGeXmit */ @@ -1539,7 +1559,7 @@ int Rc; /* return code of XmitFrame */ * > 0 - on succes: the number of bytes in the message * = 0 - on resource shortage: this frame sent or dropped, now * the ring is full ( -> set tbusy) - * < 0 - on failure: other problems (not used) + * < 0 - on failure: other problems ( -> return failure to upper layers) */ static int XmitFrame( SK_AC *pAC, /* pointer to adapter context */ @@ -1566,7 +1586,7 @@ int BytesSend; SK_DBGCAT_DRV_TX_PROGRESS, ("XmitFrame failed\n")); /* this message can not be sent now */ - return (0); + return (-1); } } /* advance head counter behind descriptor needed for this frame */ @@ -1586,7 +1606,8 @@ int BytesSend; /* set up descriptor and CONTROL dword */ PhysAddr = (SK_U64) pci_map_single(&pAC->PciDev, pMessage->data, - pMessage->len); + pMessage->len, + PCI_DMA_TODEVICE); pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); pTxd->pMBuf = pMessage; @@ -1679,9 +1700,11 @@ SK_U64 PhysAddr; /* address of DMA mapping */ PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32; PhysAddr |= (SK_U64) pTxd->VDataLow; pci_unmap_single(&pAC->PciDev, PhysAddr, - pTxd->pMBuf->len); + pTxd->pMBuf->len, + PCI_DMA_TODEVICE); - DEV_KFREE_SKB(pTxd->pMBuf); /* free message */ + /* free message */ + DEV_KFREE_SKB_ANY(pTxd->pMBuf); pTxPort->TxdRingFree++; pTxd->TBControl &= ~TX_CTRL_SOFTWARE; pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */ @@ -1759,7 +1782,8 @@ SK_U64 PhysAddr; /* physical address of a rx buffer */ Length = pAC->RxBufSize; PhysAddr = (SK_U64) pci_map_single(&pAC->PciDev, pMsgBlock->data, - pAC->RxBufSize - 2); + pAC->RxBufSize - 2, + PCI_DMA_FROMDEVICE); pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32); pRxd->pMBuf = pMsgBlock; @@ -1882,7 +1906,8 @@ rx_start: skb_put(pNewMsg, FrameLength); pci_dma_sync_single(&pAC->PciDev, (dma_addr_t) PhysAddr, - FrameLength); + FrameLength, + PCI_DMA_FROMDEVICE); eth_copy_and_sum(pNewMsg, pMsg->data, FrameLength, 0); ReQueueRxBuffer(pAC, pRxPort, pMsg, @@ -1902,15 +1927,16 @@ rx_start: /* release the DMA mapping */ pci_unmap_single(&pAC->PciDev, PhysAddr, - pAC->RxBufSize - 2); + pAC->RxBufSize - 2, + PCI_DMA_FROMDEVICE); /* set length in message */ skb_put(pMsg, FrameLength); /* hardware checksum */ Type = ntohs(*((short*)&pMsg->data[12])); if (Type == 0x800) { - Csum1= pRxd->TcpSums & 0xffff; - Csum2=(pRxd->TcpSums >> 16) & 0xffff; + Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff); + Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff); if ((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) { Result = SkCsGetReceiveInfo(pAC, &pMsg->data[14], @@ -1980,7 +2006,7 @@ rx_start: SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ("D")); - DEV_KFREE_SKB(pMsg); + DEV_KFREE_SKB_IRQ(pMsg); } } /* if not for rlmt */ else { @@ -2016,7 +2042,7 @@ rx_start: pAC->dev->last_rx = jiffies; } else { - DEV_KFREE_SKB(pMsg); + DEV_KFREE_SKB_IRQ(pMsg); } } /* if packet for rlmt */ @@ -2040,7 +2066,7 @@ rx_start: ("skge: Error in received frame, dropped!\n" "Control: %x\nRxStat: %x\n", Control, FrameStat)); - DEV_KFREE_SKB(pMsg); + DEV_KFREE_SKB_IRQ(pMsg); } } /* while */ FillRxRing(pAC, pRxPort); @@ -2060,8 +2086,9 @@ rx_failed: PhysAddr |= (SK_U64) pRxd->VDataLow; pci_unmap_single(&pAC->PciDev, PhysAddr, - pAC->RxBufSize - 2); - DEV_KFREE_SKB(pRxd->pMBuf); + pAC->RxBufSize - 2, + PCI_DMA_FROMDEVICE); + DEV_KFREE_SKB_IRQ(pRxd->pMBuf); pRxd->pMBuf = NULL; pRxPort->RxdRingFree++; pRxPort->pRxdRingHead = pRxd->pNextRxd; @@ -2139,7 +2166,8 @@ unsigned int Flags; PhysAddr |= (SK_U64) pRxd->VDataLow; pci_unmap_single(&pAC->PciDev, PhysAddr, - pAC->RxBufSize - 2); + pAC->RxBufSize - 2, + PCI_DMA_FROMDEVICE); DEV_KFREE_SKB(pRxd->pMBuf); pRxd->pMBuf = NULL; } @@ -2276,7 +2304,7 @@ unsigned int Flags; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeSetMacAddr starts now...\n")); - if(test_bit(LINK_STATE_START, &dev->state)) { + if(netif_running(dev)) { return -EBUSY; } memcpy(dev->dev_addr, addr->sa_data,dev->addr_len); @@ -3120,7 +3148,7 @@ SK_MBUF *pNextMbuf; pFreeMbuf = pMbuf; do { pNextMbuf = pFreeMbuf->pNext; - DEV_KFREE_SKB(pFreeMbuf->pOs); + DEV_KFREE_SKB_ANY(pFreeMbuf->pOs); pFreeMbuf = pNextMbuf; } while ( pFreeMbuf != NULL ); } /* SkDrvFreeRlmtMbuf */ @@ -3489,8 +3517,9 @@ unsigned int Flags; pRlmtMbuf = (SK_MBUF*) Param.pParaPtr; pMsg = (struct sk_buff*) pRlmtMbuf->pOs; skb_put(pMsg, pRlmtMbuf->Length); - XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW], - pMsg); + if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW], + pMsg) < 0) + DEV_KFREE_SKB_ANY(pMsg); break; default: break; |