14 #include <linux/kernel.h>
15 #include <linux/module.h>
17 #include <linux/slab.h>
18 #include <linux/errno.h>
19 #include <linux/types.h>
23 #include <linux/in6.h>
24 #include <linux/device.h>
25 #include <linux/netdevice.h>
28 #include <linux/tcp.h>
30 #include <linux/mii.h>
45 #define DPRINTK(str,args...) printk(KERN_DEBUG "meth: %s: " str, __func__ , ## args)
46 #define MFE_RX_DEBUG 2
48 #define DPRINTK(str,args...)
49 #define MFE_RX_DEBUG 0
53 static const char *meth_str=
"SGI O2 Fast Ethernet";
56 #define TX_TIMEOUT (400*HZ/1000)
65 #define METH_MCF_LIMIT 32
109 for (i = 0; i < 6; i++)
118 #define WAIT_FOR_PHY(___rval) \
119 while ((___rval = mace->eth.phy_data) & MDIO_BUSY) { \
123 static unsigned long mdio_read(
struct meth_private *
priv,
unsigned long phyreg)
127 mace->eth.phy_regs = (priv->
phy_addr << 5) | (phyreg & 0x1f);
129 mace->eth.phy_trans_go = 1;
138 unsigned long p2, p3,
flags;
145 p2=mdio_read(priv,2);
146 p3=mdio_read(priv,3);
148 switch ((p2<<12)|(p3>>4)){
163 if(p2!=0xffff&&p2!=0x0000){
164 DPRINTK(
"PHY code: %x\n",(p2<<12)|(p3>>4));
168 spin_unlock_irqrestore(&priv->
meth_lock, flags);
172 DPRINTK(
"Oopsie! PHY is not known!\n");
177 static void meth_check_link(
struct net_device *dev)
180 unsigned long mii_advertising = mdio_read(priv, 4);
181 unsigned long mii_partner = mdio_read(priv, 5);
182 unsigned long negotiated = mii_advertising & mii_partner;
185 if (mii_partner == 0xffff)
189 duplex = ((negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040) ?
193 DPRINTK(
"Setting %s-duplex\n", duplex ?
"full" :
"half");
202 DPRINTK(
"Setting %dMbs mode\n", speed ? 100 : 10);
247 static void meth_free_tx_ring(
struct meth_private *priv)
254 dev_kfree_skb(priv->
tx_skbs[i]);
262 static void meth_free_rx_ring(
struct meth_private *priv)
282 mace->eth.mac_ctrl = 0;
290 if (mdio_probe(priv) < 0) {
291 DPRINTK(
"Unable to find PHY\n");
302 meth_check_link(dev);
330 ret = meth_init_tx_ring(priv);
333 ret = meth_init_rx_ring(priv);
335 goto out_free_tx_ring;
340 goto out_free_rx_ring;
348 DPRINTK(
"About to start queue\n");
349 netif_start_queue(dev);
354 meth_free_rx_ring(priv);
356 meth_free_tx_ring(priv);
361 static int meth_release(
struct net_device *dev)
366 netif_stop_queue(dev);
372 meth_free_tx_ring(priv);
373 meth_free_rx_ring(priv);
391 spin_unlock_irqrestore(&priv->
meth_lock, flags);
394 fifo_rptr = (fifo_rptr - 1) & 0x0f;
396 while (priv->
rx_write != fifo_rptr) {
402 DPRINTK(
"Not received? status=%016lx\n",status);
406 int len = (status & 0xffff) - 4;
408 if (len < 60 || len > 1518) {
412 dev->
stats.rx_errors++;
413 dev->
stats.rx_length_errors++;
419 DPRINTK(
"No mem: dropping packet\n");
420 dev->
stats.rx_dropped++;
431 dev->
stats.rx_packets++;
437 dev->
stats.rx_errors++;
468 spin_unlock_irqrestore(&priv->
meth_lock, flags);
471 static int meth_tx_full(
struct net_device *dev)
475 return priv->
tx_count >= TX_RING_ENTRIES - 1;
478 static void meth_tx_cleanup(
struct net_device* dev,
unsigned long int_status)
491 while (priv->
tx_read != rptr) {
500 dev->
stats.tx_packets++;
503 dev->
stats.tx_errors++;
505 DPRINTK(
"TX error: status=%016lx <",status);
506 if(status & METH_TX_ST_SUCCESS)
522 DPRINTK(
"RPTR points us here, but packet not done?\n");
533 if (netif_queue_stopped(dev) && !meth_tx_full(dev)) {
534 netif_wake_queue(dev);
538 spin_unlock_irqrestore(&priv->
meth_lock, flags);
541 static void meth_error(
struct net_device* dev,
unsigned status)
557 if (status & (METH_INT_RX_UNDERFLOW)) {
566 DPRINTK(
"Disabled meth Rx DMA temporarily\n");
567 spin_unlock_irqrestore(&priv->
meth_lock, flags);
581 status =
mace->eth.int_stat;
582 while (status & 0xff) {
588 meth_error(dev, status);
592 meth_tx_cleanup(dev, status);
598 meth_rx(dev, status);
600 status =
mace->eth.int_stat;
609 static void meth_tx_short_prepare(
struct meth_private *priv,
617 skb_copy_from_linear_data(skb, desc->
data.
dt + (120 - len), skb->
len);
621 #define TX_CATBUF1 BIT(25)
622 static void meth_tx_1page_prepare(
struct meth_private *priv,
626 void *buffer_data = (
void *)(((
unsigned long)skb->
data + 7) & ~7);
627 int unaligned_len = (
int)((
unsigned long)buffer_data - (
unsigned long)skb->
data);
628 int buffer_len = skb->
len - unaligned_len;
635 skb_copy_from_linear_data(skb, desc->
data.
dt + (120 - unaligned_len),
637 desc->
header.raw |= (128 - unaligned_len) << 16;
646 #define TX_CATBUF2 BIT(26)
647 static void meth_tx_2page_prepare(
struct meth_private *priv,
651 void *buffer1_data = (
void *)(((
unsigned long)skb->
data + 7) & ~7);
652 void *buffer2_data = (
void *)
PAGE_ALIGN((
unsigned long)skb->
data);
653 int unaligned_len = (
int)((
unsigned long)buffer1_data - (
unsigned long)skb->
data);
654 int buffer1_len = (
int)((
unsigned long)buffer2_data - (
unsigned long)buffer1_data);
655 int buffer2_len = skb->
len - buffer1_len - unaligned_len;
661 skb_copy_from_linear_data(skb, desc->
data.
dt + (120 - unaligned_len),
663 desc->
header.raw |= (128 - unaligned_len) << 16;
682 if (skb->
len <= 120) {
684 meth_tx_short_prepare(priv, skb);
688 meth_tx_2page_prepare(priv, skb);
691 meth_tx_1page_prepare(priv, skb);
711 meth_add_to_tx_ring(priv, skb);
715 if (meth_tx_full(dev)) {
717 netif_stop_queue(dev);
724 spin_unlock_irqrestore(&priv->
meth_lock, flags);
732 static void meth_tx_timeout(
struct net_device *dev)
745 dev->
stats.tx_errors++;
748 meth_free_tx_ring(priv);
749 meth_free_rx_ring(priv);
750 meth_init_tx_ring(priv);
751 meth_init_rx_ring(priv);
758 spin_unlock_irqrestore(&priv->
meth_lock, flags);
761 netif_wake_queue(dev);
779 static void meth_set_rx_mode(
struct net_device *dev)
784 netif_stop_queue(dev);
801 (volatile
unsigned long *)&priv->mcast_filter);
805 mace->eth.mac_ctrl = priv->mac_ctrl;
806 mace->eth.mcast_filter = priv->mcast_filter;
809 spin_unlock_irqrestore(&priv->meth_lock, flags);
810 netif_wake_queue(dev);
815 .ndo_stop = meth_release,
816 .ndo_start_xmit = meth_tx,
817 .ndo_do_ioctl = meth_ioctl,
818 .ndo_tx_timeout = meth_tx_timeout,
822 .ndo_set_rx_mode = meth_set_rx_mode,
844 priv = netdev_priv(dev);
855 dev->
name, (
unsigned int)(
mace->eth.mac_ctrl >> 29));
861 struct net_device *dev = platform_get_drvdata(pdev);
865 platform_set_drvdata(pdev,
NULL);