diff options
Diffstat (limited to 'drivers/net/sis190.c')
-rw-r--r-- | drivers/net/sis190.c | 102 |
1 files changed, 74 insertions, 28 deletions
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 2229698debbd..3c33b2d14852 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c | |||
@@ -64,8 +64,8 @@ | |||
64 | 64 | ||
65 | #define MAC_ADDR_LEN 6 | 65 | #define MAC_ADDR_LEN 6 |
66 | 66 | ||
67 | #define NUM_TX_DESC 64 | 67 | #define NUM_TX_DESC 64 /* [8..1024] */ |
68 | #define NUM_RX_DESC 64 | 68 | #define NUM_RX_DESC 64 /* [8..8192] */ |
69 | #define TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) | 69 | #define TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) |
70 | #define RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) | 70 | #define RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) |
71 | #define RX_BUF_SIZE 1536 | 71 | #define RX_BUF_SIZE 1536 |
@@ -149,12 +149,6 @@ enum sis190_register_content { | |||
149 | RxHalt = 0x00000002, | 149 | RxHalt = 0x00000002, |
150 | TxHalt = 0x00000001, | 150 | TxHalt = 0x00000001, |
151 | 151 | ||
152 | /* RxStatusDesc */ | ||
153 | RxRES = 0x00200000, // unused | ||
154 | RxCRC = 0x00080000, | ||
155 | RxRUNT = 0x00100000, // unused | ||
156 | RxRWT = 0x00400000, // unused | ||
157 | |||
158 | /* {Rx/Tx}CmdBits */ | 152 | /* {Rx/Tx}CmdBits */ |
159 | CmdReset = 0x10, | 153 | CmdReset = 0x10, |
160 | CmdRxEnb = 0x08, // unused | 154 | CmdRxEnb = 0x08, // unused |
@@ -212,15 +206,55 @@ struct RxDesc { | |||
212 | 206 | ||
213 | enum _DescStatusBit { | 207 | enum _DescStatusBit { |
214 | /* _Desc.status */ | 208 | /* _Desc.status */ |
215 | OWNbit = 0x80000000, | 209 | OWNbit = 0x80000000, // RXOWN/TXOWN |
216 | INTbit = 0x40000000, | 210 | INTbit = 0x40000000, // RXINT/TXINT |
217 | DEFbit = 0x00200000, | 211 | CRCbit = 0x00020000, // CRCOFF/CRCEN |
218 | CRCbit = 0x00020000, | 212 | PADbit = 0x00010000, // PREADD/PADEN |
219 | PADbit = 0x00010000, | ||
220 | /* _Desc.size */ | 213 | /* _Desc.size */ |
221 | RingEnd = (1 << 31), | 214 | RingEnd = 0x80000000, |
222 | /* _Desc.PSize */ | 215 | /* TxDesc.status */ |
216 | LSEN = 0x08000000, // TSO ? -- FR | ||
217 | IPCS = 0x04000000, | ||
218 | TCPCS = 0x02000000, | ||
219 | UDPCS = 0x01000000, | ||
220 | BSTEN = 0x00800000, | ||
221 | EXTEN = 0x00400000, | ||
222 | DEFEN = 0x00200000, | ||
223 | BKFEN = 0x00100000, | ||
224 | CRSEN = 0x00080000, | ||
225 | COLEN = 0x00040000, | ||
226 | THOL3 = 0x30000000, | ||
227 | THOL2 = 0x20000000, | ||
228 | THOL1 = 0x10000000, | ||
229 | THOL0 = 0x00000000, | ||
230 | /* RxDesc.status */ | ||
231 | IPON = 0x20000000, | ||
232 | TCPON = 0x10000000, | ||
233 | UDPON = 0x08000000, | ||
234 | Wakup = 0x00400000, | ||
235 | Magic = 0x00200000, | ||
236 | Pause = 0x00100000, | ||
237 | DEFbit = 0x00200000, | ||
238 | BCAST = 0x000c0000, | ||
239 | MCAST = 0x00080000, | ||
240 | UCAST = 0x00040000, | ||
241 | /* RxDesc.PSize */ | ||
242 | TAGON = 0x80000000, | ||
243 | RxDescCountMask = 0x7f000000, // multi-desc pkt when > 1 ? -- FR | ||
244 | ABORT = 0x00800000, | ||
245 | SHORT = 0x00400000, | ||
246 | LIMIT = 0x00200000, | ||
247 | MIIER = 0x00100000, | ||
248 | OVRUN = 0x00080000, | ||
249 | NIBON = 0x00040000, | ||
250 | COLON = 0x00020000, | ||
251 | CRCOK = 0x00010000, | ||
223 | RxSizeMask = 0x0000ffff | 252 | RxSizeMask = 0x0000ffff |
253 | /* | ||
254 | * The asic could apparently do vlan, TSO, jumbo (sis191 only) and | ||
255 | * provide two (unused with Linux) Tx queues. No publically | ||
256 | * available documentation alas. | ||
257 | */ | ||
224 | }; | 258 | }; |
225 | 259 | ||
226 | enum sis190_eeprom_access_register_bits { | 260 | enum sis190_eeprom_access_register_bits { |
@@ -487,6 +521,26 @@ static inline int sis190_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, | |||
487 | return ret; | 521 | return ret; |
488 | } | 522 | } |
489 | 523 | ||
524 | static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats) | ||
525 | { | ||
526 | #define ErrMask (OVRUN | SHORT | LIMIT | MIIER | NIBON | COLON | ABORT) | ||
527 | |||
528 | if ((status & CRCOK) && !(status & ErrMask)) | ||
529 | return 0; | ||
530 | |||
531 | if (!(status & CRCOK)) | ||
532 | stats->rx_crc_errors++; | ||
533 | else if (status & OVRUN) | ||
534 | stats->rx_over_errors++; | ||
535 | else if (status & (SHORT | LIMIT)) | ||
536 | stats->rx_length_errors++; | ||
537 | else if (status & (MIIER | NIBON | COLON)) | ||
538 | stats->rx_frame_errors++; | ||
539 | |||
540 | stats->rx_errors++; | ||
541 | return -1; | ||
542 | } | ||
543 | |||
490 | static int sis190_rx_interrupt(struct net_device *dev, | 544 | static int sis190_rx_interrupt(struct net_device *dev, |
491 | struct sis190_private *tp, void __iomem *ioaddr) | 545 | struct sis190_private *tp, void __iomem *ioaddr) |
492 | { | 546 | { |
@@ -510,19 +564,9 @@ static int sis190_rx_interrupt(struct net_device *dev, | |||
510 | // net_intr(tp, KERN_INFO "%s: Rx PSize = %08x.\n", dev->name, | 564 | // net_intr(tp, KERN_INFO "%s: Rx PSize = %08x.\n", dev->name, |
511 | // status); | 565 | // status); |
512 | 566 | ||
513 | if (status & RxCRC) { | 567 | if (sis190_rx_pkt_err(status, stats) < 0) |
514 | net_intr(tp, KERN_INFO "%s: bad crc. status = %08x.\n", | ||
515 | dev->name, status); | ||
516 | stats->rx_errors++; | ||
517 | stats->rx_crc_errors++; | ||
518 | sis190_give_to_asic(desc, tp->rx_buf_sz); | 568 | sis190_give_to_asic(desc, tp->rx_buf_sz); |
519 | } else if (!(status & PADbit)) { | 569 | else { |
520 | net_intr(tp, KERN_INFO "%s: bad pad. status = %08x.\n", | ||
521 | dev->name, status); | ||
522 | stats->rx_errors++; | ||
523 | stats->rx_length_errors++; | ||
524 | sis190_give_to_asic(desc, tp->rx_buf_sz); | ||
525 | } else { | ||
526 | struct sk_buff *skb = tp->Rx_skbuff[entry]; | 570 | struct sk_buff *skb = tp->Rx_skbuff[entry]; |
527 | int pkt_size = (status & RxSizeMask) - 4; | 571 | int pkt_size = (status & RxSizeMask) - 4; |
528 | void (*pci_action)(struct pci_dev *, dma_addr_t, | 572 | void (*pci_action)(struct pci_dev *, dma_addr_t, |
@@ -559,8 +603,10 @@ static int sis190_rx_interrupt(struct net_device *dev, | |||
559 | sis190_rx_skb(skb); | 603 | sis190_rx_skb(skb); |
560 | 604 | ||
561 | dev->last_rx = jiffies; | 605 | dev->last_rx = jiffies; |
562 | stats->rx_bytes += pkt_size; | ||
563 | stats->rx_packets++; | 606 | stats->rx_packets++; |
607 | stats->rx_bytes += pkt_size; | ||
608 | if ((status & BCAST) == MCAST) | ||
609 | stats->multicast++; | ||
564 | } | 610 | } |
565 | } | 611 | } |
566 | count = cur_rx - tp->cur_rx; | 612 | count = cur_rx - tp->cur_rx; |