aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mipsnet.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mipsnet.c')
-rw-r--r--drivers/net/mipsnet.c63
1 files changed, 31 insertions, 32 deletions
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index d593175ab6f0..37707a0c0498 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -7,12 +7,12 @@
7#define DEBUG 7#define DEBUG
8 8
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/io.h>
10#include <linux/kernel.h> 11#include <linux/kernel.h>
11#include <linux/module.h> 12#include <linux/module.h>
12#include <linux/netdevice.h> 13#include <linux/netdevice.h>
13#include <linux/etherdevice.h> 14#include <linux/etherdevice.h>
14#include <linux/platform_device.h> 15#include <linux/platform_device.h>
15#include <asm/io.h>
16#include <asm/mips-boards/simint.h> 16#include <asm/mips-boards/simint.h>
17 17
18#include "mipsnet.h" /* actual device IO mapping */ 18#include "mipsnet.h" /* actual device IO mapping */
@@ -33,9 +33,8 @@ static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
33 if (available_len < len) 33 if (available_len < len)
34 return -EFAULT; 34 return -EFAULT;
35 35
36 for (; len > 0; len--, kdata++) { 36 for (; len > 0; len--, kdata++)
37 *kdata = inb(mipsnet_reg_address(dev, rxDataBuffer)); 37 *kdata = inb(mipsnet_reg_address(dev, rxDataBuffer));
38 }
39 38
40 return inl(mipsnet_reg_address(dev, rxDataCount)); 39 return inl(mipsnet_reg_address(dev, rxDataCount));
41} 40}
@@ -47,16 +46,15 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
47 char *buf_ptr = skb->data; 46 char *buf_ptr = skb->data;
48 47
49 pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n", 48 pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n",
50 dev->name, __FUNCTION__, skb->len); 49 dev->name, __FUNCTION__, skb->len);
51 50
52 outl(skb->len, mipsnet_reg_address(dev, txDataCount)); 51 outl(skb->len, mipsnet_reg_address(dev, txDataCount));
53 52
54 pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n", 53 pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n",
55 dev->name, __FUNCTION__, skb->len); 54 dev->name, __FUNCTION__, skb->len);
56 55
57 for (; count_to_go; buf_ptr++, count_to_go--) { 56 for (; count_to_go; buf_ptr++, count_to_go--)
58 outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer)); 57 outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer));
59 }
60 58
61 dev->stats.tx_packets++; 59 dev->stats.tx_packets++;
62 dev->stats.tx_bytes += skb->len; 60 dev->stats.tx_bytes += skb->len;
@@ -67,7 +65,7 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
67static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev) 65static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
68{ 66{
69 pr_debug("%s:%s(): transmitting %d bytes\n", 67 pr_debug("%s:%s(): transmitting %d bytes\n",
70 dev->name, __FUNCTION__, skb->len); 68 dev->name, __FUNCTION__, skb->len);
71 69
72 /* Only one packet at a time. Once TXDONE interrupt is serviced, the 70 /* Only one packet at a time. Once TXDONE interrupt is serviced, the
73 * queue will be restarted. 71 * queue will be restarted.
@@ -83,7 +81,8 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
83 struct sk_buff *skb; 81 struct sk_buff *skb;
84 size_t len = count; 82 size_t len = count;
85 83
86 if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) { 84 skb = alloc_skb(len + 2, GFP_KERNEL);
85 if (!skb) {
87 dev->stats.rx_dropped++; 86 dev->stats.rx_dropped++;
88 return -ENOMEM; 87 return -ENOMEM;
89 } 88 }
@@ -96,7 +95,7 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
96 skb->ip_summed = CHECKSUM_UNNECESSARY; 95 skb->ip_summed = CHECKSUM_UNNECESSARY;
97 96
98 pr_debug("%s:%s(): pushing RXed data to kernel\n", 97 pr_debug("%s:%s(): pushing RXed data to kernel\n",
99 dev->name, __FUNCTION__); 98 dev->name, __FUNCTION__);
100 netif_rx(skb); 99 netif_rx(skb);
101 100
102 dev->stats.rx_packets++; 101 dev->stats.rx_packets++;
@@ -114,42 +113,44 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
114 113
115 if (irq == dev->irq) { 114 if (irq == dev->irq) {
116 pr_debug("%s:%s(): irq %d for device\n", 115 pr_debug("%s:%s(): irq %d for device\n",
117 dev->name, __FUNCTION__, irq); 116 dev->name, __FUNCTION__, irq);
118 117
119 retval = IRQ_HANDLED; 118 retval = IRQ_HANDLED;
120 119
121 interruptFlags = 120 interruptFlags =
122 inl(mipsnet_reg_address(dev, interruptControl)); 121 inl(mipsnet_reg_address(dev, interruptControl));
123 pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name, 122 pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
124 __FUNCTION__, interruptFlags); 123 __FUNCTION__, interruptFlags);
125 124
126 if (interruptFlags & MIPSNET_INTCTL_TXDONE) { 125 if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
127 pr_debug("%s:%s(): got TXDone\n", 126 pr_debug("%s:%s(): got TXDone\n",
128 dev->name, __FUNCTION__); 127 dev->name, __FUNCTION__);
129 outl(MIPSNET_INTCTL_TXDONE, 128 outl(MIPSNET_INTCTL_TXDONE,
130 mipsnet_reg_address(dev, interruptControl)); 129 mipsnet_reg_address(dev, interruptControl));
131 // only one packet at a time, we are done. 130 /* only one packet at a time, we are done. */
132 netif_wake_queue(dev); 131 netif_wake_queue(dev);
133 } else if (interruptFlags & MIPSNET_INTCTL_RXDONE) { 132 } else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
134 pr_debug("%s:%s(): got RX data\n", 133 pr_debug("%s:%s(): got RX data\n",
135 dev->name, __FUNCTION__); 134 dev->name, __FUNCTION__);
136 mipsnet_get_fromdev(dev, 135 mipsnet_get_fromdev(dev,
137 inl(mipsnet_reg_address(dev, rxDataCount))); 136 inl(mipsnet_reg_address(dev, rxDataCount)));
138 pr_debug("%s:%s(): clearing RX int\n", 137 pr_debug("%s:%s(): clearing RX int\n",
139 dev->name, __FUNCTION__); 138 dev->name, __FUNCTION__);
140 outl(MIPSNET_INTCTL_RXDONE, 139 outl(MIPSNET_INTCTL_RXDONE,
141 mipsnet_reg_address(dev, interruptControl)); 140 mipsnet_reg_address(dev, interruptControl));
142 141
143 } else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) { 142 } else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
144 pr_debug("%s:%s(): got test interrupt\n", 143 pr_debug("%s:%s(): got test interrupt\n",
145 dev->name, __FUNCTION__); 144 dev->name, __FUNCTION__);
146 // TESTBIT is cleared on read. 145 /*
147 // And takes effect after a write with 0 146 * TESTBIT is cleared on read.
147 * And takes effect after a write with 0
148 */
148 outl(0, mipsnet_reg_address(dev, interruptControl)); 149 outl(0, mipsnet_reg_address(dev, interruptControl));
149 } else { 150 } else {
150 pr_debug("%s:%s(): no valid fags 0x%016llx\n", 151 pr_debug("%s:%s(): no valid fags 0x%016llx\n",
151 dev->name, __FUNCTION__, interruptFlags); 152 dev->name, __FUNCTION__, interruptFlags);
152 // Maybe shared IRQ, just ignore, no clearing. 153 /* Maybe shared IRQ, just ignore, no clearing. */
153 retval = IRQ_NONE; 154 retval = IRQ_NONE;
154 } 155 }
155 156
@@ -159,7 +160,7 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
159 retval = IRQ_NONE; 160 retval = IRQ_NONE;
160 } 161 }
161 return retval; 162 return retval;
162} //mipsnet_interrupt() 163}
163 164
164static int mipsnet_open(struct net_device *dev) 165static int mipsnet_open(struct net_device *dev)
165{ 166{
@@ -171,18 +172,18 @@ static int mipsnet_open(struct net_device *dev)
171 172
172 if (err) { 173 if (err) {
173 pr_debug("%s: %s(): can't get irq %d\n", 174 pr_debug("%s: %s(): can't get irq %d\n",
174 dev->name, __FUNCTION__, dev->irq); 175 dev->name, __FUNCTION__, dev->irq);
175 release_region(dev->base_addr, MIPSNET_IO_EXTENT); 176 release_region(dev->base_addr, MIPSNET_IO_EXTENT);
176 return err; 177 return err;
177 } 178 }
178 179
179 pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n", 180 pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n",
180 dev->name, __FUNCTION__, dev->base_addr, dev->irq); 181 dev->name, __FUNCTION__, dev->base_addr, dev->irq);
181 182
182 183
183 netif_start_queue(dev); 184 netif_start_queue(dev);
184 185
185 // test interrupt handler 186 /* test interrupt handler */
186 outl(MIPSNET_INTCTL_TESTBIT, 187 outl(MIPSNET_INTCTL_TESTBIT,
187 mipsnet_reg_address(dev, interruptControl)); 188 mipsnet_reg_address(dev, interruptControl));
188 189
@@ -199,8 +200,6 @@ static int mipsnet_close(struct net_device *dev)
199 200
200static void mipsnet_set_mclist(struct net_device *dev) 201static void mipsnet_set_mclist(struct net_device *dev)
201{ 202{
202 // we don't do anything
203 return;
204} 203}
205 204
206static int __init mipsnet_probe(struct device *dev) 205static int __init mipsnet_probe(struct device *dev)
@@ -226,13 +225,13 @@ static int __init mipsnet_probe(struct device *dev)
226 */ 225 */
227 netdev->base_addr = 0x4200; 226 netdev->base_addr = 0x4200;
228 netdev->irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB0 + 227 netdev->irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB0 +
229 inl(mipsnet_reg_address(netdev, interruptInfo)); 228 inl(mipsnet_reg_address(netdev, interruptInfo));
230 229
231 // Get the io region now, get irq on open() 230 /* Get the io region now, get irq on open() */
232 if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) { 231 if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) {
233 pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} " 232 pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} "
234 "for dev is not availble.\n", netdev->name, 233 "for dev is not availble.\n", netdev->name,
235 __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT); 234 __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
236 err = -EBUSY; 235 err = -EBUSY;
237 goto out_free_netdev; 236 goto out_free_netdev;
238 } 237 }