1 /* netdrv_init.c: Initialization for network devices. */
2 /*
3 Written 1993,1994,1995 by Donald Becker.
4
5 The author may be reached as becker@cesdis.gsfc.nasa.gov or
6 C/O Center of Excellence in Space Data and Information Sciences
7 Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
8
9 This file contains the initialization for the "pl14+" style ethernet
10 drivers. It should eventually replace most of drivers/net/Space.c.
11 It's primary advantage is that it's able to allocate low-memory buffers.
12 A secondary advantage is that the dangerous NE*000 netcards can reserve
13 their I/O port region before the SCSI probes start.
14
15 Modifications/additions by Bjorn Ekwall <bj0rn@blox.se>:
16 ethdev_index[MAX_ETH_CARDS]
17 register_netdev() / unregister_netdev()
18 */
19
20 #include <linux/config.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/types.h>
24 #include <linux/fs.h>
25 #include <linux/malloc.h>
26 #include <linux/if_ether.h>
27 #include <linux/string.h>
28 #include <linux/netdevice.h>
29 #include <linux/etherdevice.h>
30 #include <linux/trdevice.h>
31
32 /* The network devices currently exist only in the socket namespace, so these
33 entries are unused. The only ones that make sense are
34 open start the ethercard
35 close stop the ethercard
36 ioctl To get statistics, perhaps set the interface port (AUI, BNC, etc.)
37 One can also imagine getting raw packets using
38 read & write
39 but this is probably better handled by a raw packet socket.
40
41 Given that almost all of these functions are handled in the current
42 socket-based scheme, putting ethercard devices in /dev/ seems pointless.
43
44 [Removed all support for /dev network devices. When someone adds
45 streams then by magic we get them, but otherwise they are un-needed
46 and a space waste]
47 */
48
49 /* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */
50 #define MAX_ETH_CARDS 16 /* same as the number if irq's in irq2dev[] */
51 static struct device *ethdev_index[MAX_ETH_CARDS];
52
53 unsigned long lance_init(unsigned long mem_start, unsigned long mem_end);
54 unsigned long pi_init(unsigned long mem_start, unsigned long mem_end);
55 unsigned long apricot_init(unsigned long mem_start, unsigned long mem_end);
56 unsigned long dec21040_init(unsigned long mem_start, unsigned long mem_end);
57
58 /*
59 net_dev_init() is our network device initialization routine.
60 It's called from init/main.c with the start and end of free memory,
61 and returns the new start of free memory.
62 */
63
64 unsigned long net_dev_init (unsigned long mem_start, unsigned long mem_end)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
65 {
66
67 /* Network device initialization for devices that must allocate
68 low-memory or contiguous DMA buffers.
69 */
70 #if defined(CONFIG_LANCE)
71 mem_start = lance_init(mem_start, mem_end);
72 #endif
73 #if defined(CONFIG_PI)
74 mem_start = pi_init(mem_start, mem_end);
75 #endif
76 #if defined(CONFIG_DEC_ELCP)
77 mem_start = dec21040_init(mem_start, mem_end);
78 #endif
79 return mem_start;
80 }
81
82 /* Fill in the fields of the device structure with ethernet-generic values.
83
84 If no device structure is passed, a new one is constructed, complete with
85 a SIZEOF_PRIVATE private data area.
86
87 If an empty string area is passed as dev->name, or a new structure is made,
88 a new name string is constructed. The passed string area should be 8 bytes
89 long.
90 */
91
92 struct device *
93 init_etherdev(struct device *dev, int sizeof_priv, unsigned long *mem_startp)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
94 {
95 int new_device = 0;
96 int i;
97
98 /* Use an existing correctly named device in Space.c:dev_base. */
99 if (dev == NULL) {
100 int alloc_size = sizeof(struct device) + sizeof("eth%d ")
101 + sizeof_priv + 3;
102 struct device *cur_dev;
103 char pname[8]; /* Putative name for the device. */
104
105 for (i = 0; i < MAX_ETH_CARDS; ++i)
106 if (ethdev_index[i] == NULL) {
107 sprintf(pname, "eth%d", i);
108 for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next)
109 if (strcmp(pname, cur_dev->name) == 0) {
110 dev = cur_dev;
111 dev->init = NULL;
112 sizeof_priv = (sizeof_priv + 3) & ~3;
113 if (mem_startp && *mem_startp ) {
114 dev->priv = (void*) *mem_startp;
115 *mem_startp += sizeof_priv;
116 } else
117 dev->priv = kmalloc(sizeof_priv, GFP_KERNEL);
118 memset(dev->priv, 0, sizeof_priv);
119 goto found;
120 }
121 }
122
123 alloc_size &= ~3; /* Round to dword boundary. */
124
125 if (mem_startp && *mem_startp ) {
126 dev = (struct device *)*mem_startp;
127 *mem_startp += alloc_size;
128 } else
129 dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
130 memset(dev, 0, alloc_size);
131 if (sizeof_priv)
132 dev->priv = (void *) (dev + 1);
133 dev->name = sizeof_priv + (char *)(dev + 1);
134 new_device = 1;
135 }
136
137 found: /* From the double loop above. */
138
139 if (dev->name &&
140 ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
141 for (i = 0; i < MAX_ETH_CARDS; ++i)
142 if (ethdev_index[i] == NULL) {
143 sprintf(dev->name, "eth%d", i);
144 ethdev_index[i] = dev;
145 break;
146 }
147 }
148
149 ether_setup(dev); /* Hmmm, should this be called here? */
150
151 if (new_device) {
152 /* Append the device to the device queue. */
153 struct device **old_devp = &dev_base;
154 while ((*old_devp)->next)
155 old_devp = & (*old_devp)->next;
156 (*old_devp)->next = dev;
157 dev->next = 0;
158 }
159 return dev;
160 }
161
162 void ether_setup(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
163 {
164 int i;
165 /* Fill in the fields of the device structure with ethernet-generic values.
166 This should be in a common file instead of per-driver. */
167 for (i = 0; i < DEV_NUMBUFFS; i++)
168 skb_queue_head_init(&dev->buffs[i]);
169
170 /* register boot-defined "eth" devices */
171 if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) {
172 i = simple_strtoul(dev->name + 3, NULL, 0);
173 if (ethdev_index[i] == NULL) {
174 ethdev_index[i] = dev;
175 }
176 else if (dev != ethdev_index[i]) {
177 /* Really shouldn't happen! */
178 printk("ether_setup: Ouch! Someone else took %s\n",
179 dev->name);
180 }
181 }
182
183 dev->hard_header = eth_header;
184 dev->rebuild_header = eth_rebuild_header;
185
186 dev->type = ARPHRD_ETHER;
187 dev->hard_header_len = ETH_HLEN;
188 dev->mtu = 1500; /* eth_mtu */
189 dev->addr_len = ETH_ALEN;
190 for (i = 0; i < ETH_ALEN; i++) {
191 dev->broadcast[i]=0xff;
192 }
193
194 /* New-style flags. */
195 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
196 dev->family = AF_INET;
197 dev->pa_addr = 0;
198 dev->pa_brdaddr = 0;
199 dev->pa_mask = 0;
200 dev->pa_alen = sizeof(unsigned long);
201 }
202
203 #ifdef CONFIG_TR
204
205 void tr_setup(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
206 {
207 int i;
208 /* Fill in the fields of the device structure with ethernet-generic values.
209 This should be in a common file instead of per-driver. */
210 for (i = 0; i < DEV_NUMBUFFS; i++)
211 skb_queue_head_init(&dev->buffs[i]);
212
213 dev->hard_header = tr_header;
214 dev->rebuild_header = tr_rebuild_header;
215
216 dev->type = ARPHRD_IEEE802;
217 dev->hard_header_len = TR_HLEN;
218 dev->mtu = 2000; /* bug in fragmenter...*/
219 dev->addr_len = TR_ALEN;
220 for (i = 0; i < TR_ALEN; i++) {
221 dev->broadcast[i]=0xff;
222 }
223
224 /* New-style flags. */
225 dev->flags = IFF_BROADCAST;
226 dev->family = AF_INET;
227 dev->pa_addr = 0;
228 dev->pa_brdaddr = 0;
229 dev->pa_mask = 0;
230 dev->pa_alen = sizeof(unsigned long);
231 }
232
233 #endif
234
235 int ether_config(struct device *dev, struct ifmap *map)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
236 {
237 if (map->mem_start != (u_long)(-1))
238 dev->mem_start = map->mem_start;
239 if (map->mem_end != (u_long)(-1))
240 dev->mem_end = map->mem_end;
241 if (map->base_addr != (u_short)(-1))
242 dev->base_addr = map->base_addr;
243 if (map->irq != (u_char)(-1))
244 dev->irq = map->irq;
245 if (map->dma != (u_char)(-1))
246 dev->dma = map->dma;
247 if (map->port != (u_char)(-1))
248 dev->if_port = map->port;
249 return 0;
250 }
251
252 int register_netdev(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
253 {
254 struct device *d = dev_base;
255 unsigned long flags;
256 int i=MAX_ETH_CARDS;
257
258 save_flags(flags);
259 cli();
260
261 if (dev && dev->init) {
262 if (dev->name &&
263 ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
264 for (i = 0; i < MAX_ETH_CARDS; ++i)
265 if (ethdev_index[i] == NULL) {
266 sprintf(dev->name, "eth%d", i);
267 printk("loading device '%s'...\n", dev->name);
268 ethdev_index[i] = dev;
269 break;
270 }
271 }
272
273 if (dev->init(dev) != 0) {
274 if (i < MAX_ETH_CARDS) ethdev_index[i] = NULL;
275 restore_flags(flags);
276 return -EIO;
277 }
278
279 /* Add device to end of chain */
280 if (dev_base) {
281 while (d->next)
282 d = d->next;
283 d->next = dev;
284 }
285 else
286 dev_base = dev;
287 dev->next = NULL;
288 }
289 restore_flags(flags);
290 return 0;
291 }
292
293 void unregister_netdev(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
294 {
295 struct device *d = dev_base;
296 unsigned long flags;
297 int i;
298
299 save_flags(flags);
300 cli();
301
302 printk("unregister_netdev: device ");
303
304 if (dev == NULL) {
305 printk("was NULL\n");
306 restore_flags(flags);
307 return;
308 }
309 /* else */
310 if (dev->start)
311 printk("'%s' busy\n", dev->name);
312 else {
313 if (dev_base == dev)
314 dev_base = dev->next;
315 else {
316 while (d && (d->next != dev))
317 d = d->next;
318
319 if (d && (d->next == dev)) {
320 d->next = dev->next;
321 printk("'%s' unlinked\n", dev->name);
322 }
323 else {
324 printk("'%s' not found\n", dev->name);
325 restore_flags(flags);
326 return;
327 }
328 }
329 for (i = 0; i < MAX_ETH_CARDS; ++i) {
330 if (ethdev_index[i] == dev) {
331 ethdev_index[i] = NULL;
332 break;
333 }
334 }
335 }
336 restore_flags(flags);
337 }
338
339
340
341 /*
342 * Local variables:
343 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
344 * version-control: t
345 * kept-new-versions: 5
346 * tab-width: 4
347 * End:
348 */