aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/mipsnet.c63
-rw-r--r--drivers/net/mipsnet.h83
2 files changed, 75 insertions, 71 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 }
diff --git a/drivers/net/mipsnet.h b/drivers/net/mipsnet.h
index 026c732024c9..0132c6714a40 100644
--- a/drivers/net/mipsnet.h
+++ b/drivers/net/mipsnet.h
@@ -9,32 +9,34 @@
9/* 9/*
10 * Id of this Net device, as seen by the core. 10 * Id of this Net device, as seen by the core.
11 */ 11 */
12#define MIPS_NET_DEV_ID ((uint64_t) \ 12#define MIPS_NET_DEV_ID ((uint64_t) \
13 ((uint64_t)'M'<< 0)| \ 13 ((uint64_t) 'M' << 0)| \
14 ((uint64_t)'I'<< 8)| \ 14 ((uint64_t) 'I' << 8)| \
15 ((uint64_t)'P'<<16)| \ 15 ((uint64_t) 'P' << 16)| \
16 ((uint64_t)'S'<<24)| \ 16 ((uint64_t) 'S' << 24)| \
17 ((uint64_t)'N'<<32)| \ 17 ((uint64_t) 'N' << 32)| \
18 ((uint64_t)'E'<<40)| \ 18 ((uint64_t) 'E' << 40)| \
19 ((uint64_t)'T'<<48)| \ 19 ((uint64_t) 'T' << 48)| \
20 ((uint64_t)'0'<<56)) 20 ((uint64_t) '0' << 56))
21 21
22/* 22/*
23 * Net status/control block as seen by sw in the core. 23 * Net status/control block as seen by sw in the core.
24 * (Why not use bit fields? can't be bothered with cross-platform struct 24 * (Why not use bit fields? can't be bothered with cross-platform struct
25 * packing.) 25 * packing.)
26 */ 26 */
27typedef struct _net_control_block { 27struct net_control_block {
28 /// dev info for probing 28 /*
29 /// reads as MIPSNET%d where %d is some form of version 29 * dev info for probing
30 uint64_t devId; /*0x00 */ 30 * reads as MIPSNET%d where %d is some form of version
31 */
32 uint64_t devId; /* 0x00 */
31 33
32 /* 34 /*
33 * read only busy flag. 35 * read only busy flag.
34 * Set and cleared by the Net Device to indicate that an rx or a tx 36 * Set and cleared by the Net Device to indicate that an rx or a tx
35 * is in progress. 37 * is in progress.
36 */ 38 */
37 uint32_t busy; /*0x08 */ 39 uint32_t busy; /* 0x08 */
38 40
39 /* 41 /*
40 * Set by the Net Device. 42 * Set by the Net Device.
@@ -43,16 +45,16 @@ typedef struct _net_control_block {
43 * rxDataBuffer. The value will decrease till 0 until all the data 45 * rxDataBuffer. The value will decrease till 0 until all the data
44 * from rxDataBuffer has been read. 46 * from rxDataBuffer has been read.
45 */ 47 */
46 uint32_t rxDataCount; /*0x0c */ 48 uint32_t rxDataCount; /* 0x0c */
47#define MIPSNET_MAX_RXTX_DATACOUNT (1<<16) 49#define MIPSNET_MAX_RXTX_DATACOUNT (1<<16)
48 50
49 /* 51 /*
50 * Settable from the MIPS core, cleared by the Net Device. 52 * Settable from the MIPS core, cleared by the Net Device. The core
51 * The core should set the number of bytes it wants to send, 53 * should set the number of bytes it wants to send, then it should
52 * then it should write those bytes of data to txDataBuffer. 54 * write those bytes of data to txDataBuffer. The device will clear
53 * The device will clear txDataCount has been processed (not necessarily sent). 55 * txDataCount has been processed (not necessarily sent).
54 */ 56 */
55 uint32_t txDataCount; /*0x10 */ 57 uint32_t txDataCount; /* 0x10 */
56 58
57 /* 59 /*
58 * Interrupt control 60 * Interrupt control
@@ -69,39 +71,42 @@ typedef struct _net_control_block {
69 * To clear the test interrupt, write 0 to this register. 71 * To clear the test interrupt, write 0 to this register.
70 */ 72 */
71 uint32_t interruptControl; /*0x14 */ 73 uint32_t interruptControl; /*0x14 */
72#define MIPSNET_INTCTL_TXDONE ((uint32_t)(1<< 0)) 74#define MIPSNET_INTCTL_TXDONE ((uint32_t)(1 << 0))
73#define MIPSNET_INTCTL_RXDONE ((uint32_t)(1<< 1)) 75#define MIPSNET_INTCTL_RXDONE ((uint32_t)(1 << 1))
74#define MIPSNET_INTCTL_TESTBIT ((uint32_t)(1<<31)) 76#define MIPSNET_INTCTL_TESTBIT ((uint32_t)(1 << 31))
75#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE|MIPSNET_INTCTL_RXDONE|MIPSNET_INTCTL_TESTBIT) 77#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE | \
78 MIPSNET_INTCTL_RXDONE | \
79 MIPSNET_INTCTL_TESTBIT)
76 80
77 /* 81 /*
78 * Readonly core-specific interrupt info for the device to signal the core. 82 * Readonly core-specific interrupt info for the device to signal the
79 * The meaning of the contents of this field might change. 83 * core. The meaning of the contents of this field might change.
80 */ 84 *
81 /*###\todo: the whole memIntf interrupt scheme is messy: the device should have 85 * TODO: the whole memIntf interrupt scheme is messy: the device should
82 * no control what so ever of what VPE/register set is being used. 86 * have no control what so ever of what VPE/register set is being
83 * The MemIntf should only expose interrupt lines, and something in the 87 * used. The MemIntf should only expose interrupt lines, and
84 * config should be responsible for the line<->core/vpe bindings. 88 * something in the config should be responsible for the
89 * line<->core/vpe bindings.
85 */ 90 */
86 uint32_t interruptInfo; /*0x18 */ 91 uint32_t interruptInfo; /* 0x18 */
87 92
88 /* 93 /*
89 * This is where the received data is read out. 94 * This is where the received data is read out.
90 * There is more data to read until rxDataReady is 0. 95 * There is more data to read until rxDataReady is 0.
91 * Only 1 byte at this regs offset is used. 96 * Only 1 byte at this regs offset is used.
92 */ 97 */
93 uint32_t rxDataBuffer; /*0x1c */ 98 uint32_t rxDataBuffer; /* 0x1c */
94 99
95 /* 100 /*
96 * This is where the data to transmit is written. 101 * This is where the data to transmit is written. Data should be
97 * Data should be written for the amount specified in the txDataCount register. 102 * written for the amount specified in the txDataCount register. Only
98 * Only 1 byte at this regs offset is used. 103 * 1 byte at this regs offset is used.
99 */ 104 */
100 uint32_t txDataBuffer; /*0x20 */ 105 uint32_t txDataBuffer; /* 0x20 */
101} MIPS_T_NetControl; 106};
102 107
103#define MIPSNET_IO_EXTENT 0x40 /* being generous */ 108#define MIPSNET_IO_EXTENT 0x40 /* being generous */
104 109
105#define field_offset(field) ((int)&((MIPS_T_NetControl*)(0))->field) 110#define field_offset(field) (offsetof(struct net_control_block, field))
106 111
107#endif /* __MIPSNET_H */ 112#endif /* __MIPSNET_H */