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
163 static int eth_mac_addr(struct device *dev, void * addr)
/* ![[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)
*/
164 {
165 struct ifreq * ifr = (struct ifreq *) addr;
166
167 if(dev->start)
168 return -EBUSY;
169 memcpy(dev->dev_addr, ifr->ifr_hwaddr.sa_data,dev->hard_header_len);
170 return 0;
171 }
172
173 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)
*/
174 {
175 int i;
176 /* Fill in the fields of the device structure with ethernet-generic values.
177 This should be in a common file instead of per-driver. */
178 for (i = 0; i < DEV_NUMBUFFS; i++)
179 skb_queue_head_init(&dev->buffs[i]);
180
181 /* register boot-defined "eth" devices */
182 if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) {
183 i = simple_strtoul(dev->name + 3, NULL, 0);
184 if (ethdev_index[i] == NULL) {
185 ethdev_index[i] = dev;
186 }
187 else if (dev != ethdev_index[i]) {
188 /* Really shouldn't happen! */
189 printk("ether_setup: Ouch! Someone else took %s\n",
190 dev->name);
191 }
192 }
193
194 dev->hard_header = eth_header;
195 dev->rebuild_header = eth_rebuild_header;
196 dev->set_mac_address = eth_mac_addr;
197 dev->header_cache = eth_header_cache;
198
199 dev->type = ARPHRD_ETHER;
200 dev->hard_header_len = ETH_HLEN;
201 dev->mtu = 1500; /* eth_mtu */
202 dev->addr_len = ETH_ALEN;
203 for (i = 0; i < ETH_ALEN; i++) {
204 dev->broadcast[i]=0xff;
205 }
206
207 /* New-style flags. */
208 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
209 dev->family = AF_INET;
210 dev->pa_addr = 0;
211 dev->pa_brdaddr = 0;
212 dev->pa_mask = 0;
213 dev->pa_alen = 4;
214 }
215
216 #ifdef CONFIG_TR
217
218 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)
*/
219 {
220 int i;
221 /* Fill in the fields of the device structure with ethernet-generic values.
222 This should be in a common file instead of per-driver. */
223 for (i = 0; i < DEV_NUMBUFFS; i++)
224 skb_queue_head_init(&dev->buffs[i]);
225
226 dev->hard_header = tr_header;
227 dev->rebuild_header = tr_rebuild_header;
228
229 dev->type = ARPHRD_IEEE802;
230 dev->hard_header_len = TR_HLEN;
231 dev->mtu = 2000; /* bug in fragmenter...*/
232 dev->addr_len = TR_ALEN;
233 for (i = 0; i < TR_ALEN; i++) {
234 dev->broadcast[i]=0xff;
235 }
236
237 /* New-style flags. */
238 dev->flags = IFF_BROADCAST;
239 dev->family = AF_INET;
240 dev->pa_addr = 0;
241 dev->pa_brdaddr = 0;
242 dev->pa_mask = 0;
243 dev->pa_alen = 4;
244 }
245
246 #endif
247
248 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)
*/
249 {
250 if (map->mem_start != (u_long)(-1))
251 dev->mem_start = map->mem_start;
252 if (map->mem_end != (u_long)(-1))
253 dev->mem_end = map->mem_end;
254 if (map->base_addr != (u_short)(-1))
255 dev->base_addr = map->base_addr;
256 if (map->irq != (u_char)(-1))
257 dev->irq = map->irq;
258 if (map->dma != (u_char)(-1))
259 dev->dma = map->dma;
260 if (map->port != (u_char)(-1))
261 dev->if_port = map->port;
262 return 0;
263 }
264
265 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)
*/
266 {
267 struct device *d = dev_base;
268 unsigned long flags;
269 int i=MAX_ETH_CARDS;
270
271 save_flags(flags);
272 cli();
273
274 if (dev && dev->init) {
275 if (dev->name &&
276 ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
277 for (i = 0; i < MAX_ETH_CARDS; ++i)
278 if (ethdev_index[i] == NULL) {
279 sprintf(dev->name, "eth%d", i);
280 printk("loading device '%s'...\n", dev->name);
281 ethdev_index[i] = dev;
282 break;
283 }
284 }
285
286 if (dev->init(dev) != 0) {
287 if (i < MAX_ETH_CARDS) ethdev_index[i] = NULL;
288 restore_flags(flags);
289 return -EIO;
290 }
291
292 /* Add device to end of chain */
293 if (dev_base) {
294 while (d->next)
295 d = d->next;
296 d->next = dev;
297 }
298 else
299 dev_base = dev;
300 dev->next = NULL;
301 }
302 restore_flags(flags);
303 return 0;
304 }
305
306 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)
*/
307 {
308 struct device *d = dev_base;
309 unsigned long flags;
310 int i;
311
312 save_flags(flags);
313 cli();
314
315 printk("unregister_netdev: device ");
316
317 if (dev == NULL) {
318 printk("was NULL\n");
319 restore_flags(flags);
320 return;
321 }
322 /* else */
323 if (dev->start)
324 printk("'%s' busy\n", dev->name);
325 else {
326 if (dev_base == dev)
327 dev_base = dev->next;
328 else {
329 while (d && (d->next != dev))
330 d = d->next;
331
332 if (d && (d->next == dev)) {
333 d->next = dev->next;
334 printk("'%s' unlinked\n", dev->name);
335 }
336 else {
337 printk("'%s' not found\n", dev->name);
338 restore_flags(flags);
339 return;
340 }
341 }
342 for (i = 0; i < MAX_ETH_CARDS; ++i) {
343 if (ethdev_index[i] == dev) {
344 ethdev_index[i] = NULL;
345 break;
346 }
347 }
348 }
349 restore_flags(flags);
350 }
351
352
353
354 /*
355 * Local variables:
356 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
357 * version-control: t
358 * kept-new-versions: 5
359 * tab-width: 4
360 * End:
361 */