netxen: refactor netdev open close
[linux-2.6] / drivers / net / mipsnet.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  */
6
7 #include <linux/init.h>
8 #include <linux/io.h>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/netdevice.h>
12 #include <linux/etherdevice.h>
13 #include <linux/platform_device.h>
14 #include <asm/mips-boards/simint.h>
15
16 #define MIPSNET_VERSION "2007-11-17"
17
18 /*
19  * Net status/control block as seen by sw in the core.
20  */
21 struct mipsnet_regs {
22         /*
23          * Device info for probing, reads as MIPSNET%d where %d is some
24          * form of version.
25          */
26         u64 devId;              /*0x00 */
27
28         /*
29          * read only busy flag.
30          * Set and cleared by the Net Device to indicate that an rx or a tx
31          * is in progress.
32          */
33         u32 busy;               /*0x08 */
34
35         /*
36          * Set by the Net Device.
37          * The device will set it once data has been received.
38          * The value is the number of bytes that should be read from
39          * rxDataBuffer.  The value will decrease till 0 until all the data
40          * from rxDataBuffer has been read.
41          */
42         u32 rxDataCount;        /*0x0c */
43 #define MIPSNET_MAX_RXTX_DATACOUNT (1 << 16)
44
45         /*
46          * Settable from the MIPS core, cleared by the Net Device.
47          * The core should set the number of bytes it wants to send,
48          * then it should write those bytes of data to txDataBuffer.
49          * The device will clear txDataCount has been processed (not
50          * necessarily sent).
51          */
52         u32 txDataCount;        /*0x10 */
53
54         /*
55          * Interrupt control
56          *
57          * Used to clear the interrupted generated by this dev.
58          * Write a 1 to clear the interrupt. (except bit31).
59          *
60          * Bit0 is set if it was a tx-done interrupt.
61          * Bit1 is set when new rx-data is available.
62          *    Until this bit is cleared there will be no other RXs.
63          *
64          * Bit31 is used for testing, it clears after a read.
65          *    Writing 1 to this bit will cause an interrupt to be generated.
66          *    To clear the test interrupt, write 0 to this register.
67          */
68         u32 interruptControl;   /*0x14 */
69 #define MIPSNET_INTCTL_TXDONE     (1u << 0)
70 #define MIPSNET_INTCTL_RXDONE     (1u << 1)
71 #define MIPSNET_INTCTL_TESTBIT    (1u << 31)
72
73         /*
74          * Readonly core-specific interrupt info for the device to signal
75          * the core. The meaning of the contents of this field might change.
76          */
77         /* XXX: the whole memIntf interrupt scheme is messy: the device
78          * should have no control what so ever of what VPE/register set is
79          * being used.
80          * The MemIntf should only expose interrupt lines, and something in
81          * the config should be responsible for the line<->core/vpe bindings.
82          */
83         u32 interruptInfo;      /*0x18 */
84
85         /*
86          * This is where the received data is read out.
87          * There is more data to read until rxDataReady is 0.
88          * Only 1 byte at this regs offset is used.
89          */
90         u32 rxDataBuffer;       /*0x1c */
91
92         /*
93          * This is where the data to transmit is written.
94          * Data should be written for the amount specified in the
95          * txDataCount register.
96          * Only 1 byte at this regs offset is used.
97          */
98         u32 txDataBuffer;       /*0x20 */
99 };
100
101 #define regaddr(dev, field) \
102   (dev->base_addr + offsetof(struct mipsnet_regs, field))
103
104 static char mipsnet_string[] = "mipsnet";
105
106 /*
107  * Copy data from the MIPSNET rx data port
108  */
109 static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
110                         int len)
111 {
112         for (; len > 0; len--, kdata++)
113                 *kdata = inb(regaddr(dev, rxDataBuffer));
114
115         return inl(regaddr(dev, rxDataCount));
116 }
117
118 static inline void mipsnet_put_todevice(struct net_device *dev,
119         struct sk_buff *skb)
120 {
121         int count_to_go = skb->len;
122         char *buf_ptr = skb->data;
123
124         outl(skb->len, regaddr(dev, txDataCount));
125
126         for (; count_to_go; buf_ptr++, count_to_go--)
127                 outb(*buf_ptr, regaddr(dev, txDataBuffer));
128
129         dev->stats.tx_packets++;
130         dev->stats.tx_bytes += skb->len;
131
132         dev_kfree_skb(skb);
133 }
134
135 static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
136 {
137         /*
138          * Only one packet at a time. Once TXDONE interrupt is serviced, the
139          * queue will be restarted.
140          */
141         netif_stop_queue(dev);
142         mipsnet_put_todevice(dev, skb);
143
144         return 0;
145 }
146
147 static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t len)
148 {
149         struct sk_buff *skb;
150
151         if (!len)
152                 return len;
153
154         skb = dev_alloc_skb(len + NET_IP_ALIGN);
155         if (!skb) {
156                 dev->stats.rx_dropped++;
157                 return -ENOMEM;
158         }
159
160         skb_reserve(skb, NET_IP_ALIGN);
161         if (ioiocpy_frommipsnet(dev, skb_put(skb, len), len))
162                 return -EFAULT;
163
164         skb->protocol = eth_type_trans(skb, dev);
165         skb->ip_summed = CHECKSUM_UNNECESSARY;
166
167         netif_rx(skb);
168
169         dev->stats.rx_packets++;
170         dev->stats.rx_bytes += len;
171
172         return len;
173 }
174
175 static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
176 {
177         struct net_device *dev = dev_id;
178         u32 int_flags;
179         irqreturn_t ret = IRQ_NONE;
180
181         if (irq != dev->irq)
182                 goto out_badirq;
183
184         /* TESTBIT is cleared on read. */
185         int_flags = inl(regaddr(dev, interruptControl));
186         if (int_flags & MIPSNET_INTCTL_TESTBIT) {
187                 /* TESTBIT takes effect after a write with 0. */
188                 outl(0, regaddr(dev, interruptControl));
189                 ret = IRQ_HANDLED;
190         } else if (int_flags & MIPSNET_INTCTL_TXDONE) {
191                 /* Only one packet at a time, we are done. */
192                 dev->stats.tx_packets++;
193                 netif_wake_queue(dev);
194                 outl(MIPSNET_INTCTL_TXDONE,
195                      regaddr(dev, interruptControl));
196                 ret = IRQ_HANDLED;
197         } else if (int_flags & MIPSNET_INTCTL_RXDONE) {
198                 mipsnet_get_fromdev(dev, inl(regaddr(dev, rxDataCount)));
199                 outl(MIPSNET_INTCTL_RXDONE, regaddr(dev, interruptControl));
200                 ret = IRQ_HANDLED;
201         }
202         return ret;
203
204 out_badirq:
205         printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
206                dev->name, __func__, irq);
207         return ret;
208 }
209
210 static int mipsnet_open(struct net_device *dev)
211 {
212         int err;
213
214         err = request_irq(dev->irq, &mipsnet_interrupt,
215                           IRQF_SHARED, dev->name, (void *) dev);
216         if (err) {
217                 release_region(dev->base_addr, sizeof(struct mipsnet_regs));
218                 return err;
219         }
220
221         netif_start_queue(dev);
222
223         /* test interrupt handler */
224         outl(MIPSNET_INTCTL_TESTBIT, regaddr(dev, interruptControl));
225
226         return 0;
227 }
228
229 static int mipsnet_close(struct net_device *dev)
230 {
231         netif_stop_queue(dev);
232         free_irq(dev->irq, dev);
233         return 0;
234 }
235
236 static void mipsnet_set_mclist(struct net_device *dev)
237 {
238 }
239
240 static int __init mipsnet_probe(struct device *dev)
241 {
242         struct net_device *netdev;
243         int err;
244
245         netdev = alloc_etherdev(0);
246         if (!netdev) {
247                 err = -ENOMEM;
248                 goto out;
249         }
250
251         dev_set_drvdata(dev, netdev);
252
253         netdev->open                    = mipsnet_open;
254         netdev->stop                    = mipsnet_close;
255         netdev->hard_start_xmit         = mipsnet_xmit;
256         netdev->set_multicast_list      = mipsnet_set_mclist;
257
258         /*
259          * TODO: probe for these or load them from PARAM
260          */
261         netdev->base_addr = 0x4200;
262         netdev->irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB0 +
263                       inl(regaddr(netdev, interruptInfo));
264
265         /* Get the io region now, get irq on open() */
266         if (!request_region(netdev->base_addr, sizeof(struct mipsnet_regs),
267                             "mipsnet")) {
268                 err = -EBUSY;
269                 goto out_free_netdev;
270         }
271
272         /*
273          * Lacking any better mechanism to allocate a MAC address we use a
274          * random one ...
275          */
276         random_ether_addr(netdev->dev_addr);
277
278         err = register_netdev(netdev);
279         if (err) {
280                 printk(KERN_ERR "MIPSNet: failed to register netdev.\n");
281                 goto out_free_region;
282         }
283
284         return 0;
285
286 out_free_region:
287         release_region(netdev->base_addr, sizeof(struct mipsnet_regs));
288
289 out_free_netdev:
290         free_netdev(netdev);
291
292 out:
293         return err;
294 }
295
296 static int __devexit mipsnet_device_remove(struct device *device)
297 {
298         struct net_device *dev = dev_get_drvdata(device);
299
300         unregister_netdev(dev);
301         release_region(dev->base_addr, sizeof(struct mipsnet_regs));
302         free_netdev(dev);
303         dev_set_drvdata(device, NULL);
304
305         return 0;
306 }
307
308 static struct device_driver mipsnet_driver = {
309         .name   = mipsnet_string,
310         .bus    = &platform_bus_type,
311         .probe  = mipsnet_probe,
312         .remove = __devexit_p(mipsnet_device_remove),
313 };
314
315 static int __init mipsnet_init_module(void)
316 {
317         int err;
318
319         printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
320                "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
321
322         err = driver_register(&mipsnet_driver);
323         if (err)
324                 printk(KERN_ERR "Driver registration failed\n");
325
326         return err;
327 }
328
329 static void __exit mipsnet_exit_module(void)
330 {
331         driver_unregister(&mipsnet_driver);
332 }
333
334 module_init(mipsnet_init_module);
335 module_exit(mipsnet_exit_module);