summaryrefslogtreecommitdiffstats
path: root/drivers/net/sk98lin/skge.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-24 00:12:35 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-24 00:12:35 +0000
commit482368b1a8e45430672c58c9a42e7d2004367126 (patch)
treece2a1a567d4d62dee7c2e71a46a99cf72cf1d606 /drivers/net/sk98lin/skge.c
parente4d0251c6f56ab2e191afb70f80f382793e23f74 (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.c79
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;