1 /* netdrv_init.c: Initialization for network devices. */
2 /*
3 Written 1993,1994 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
31 /* The network devices currently exist only in the socket namespace, so these
32 entries are unused. The only ones that make sense are
33 open start the ethercard
34 close stop the ethercard
35 ioctl To get statistics, perhaps set the interface port (AUI, BNC, etc.)
36 One can also imagine getting raw packets using
37 read & write
38 but this is probably better handled by a raw packet socket.
39
40 Given that almost all of these functions are handled in the current
41 socket-based scheme, putting ethercard devices in /dev/ seems pointless.
42
43 [Removed all support for /dev network devices. When someone adds streams then
44 by magic we get them, but otherwise they are un-needed and a space waste]
45 */
46
47 /* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */
48 #define MAX_ETH_CARDS 16 /* same as the number if irq's in irq2dev[] */
49 static struct device *ethdev_index[MAX_ETH_CARDS];
50
51 unsigned long lance_init(unsigned long mem_start, unsigned long mem_end);
52 unsigned long pi_init(unsigned long mem_start, unsigned long mem_end);
53 unsigned long apricot_init(unsigned long mem_start, unsigned long mem_end);
54
55
56 /*
57 net_dev_init() is our network device initialization routine.
58 It's called from init/main.c with the start and end of free memory,
59 and returns the new start of free memory.
60 */
61
62 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)
*/
63 {
64
65 #if defined(CONFIG_LANCE) /* Note this is _not_ CONFIG_AT1500. */
66 mem_start = lance_init(mem_start, mem_end);
67 #endif
68 #if defined(CONFIG_PI)
69 mem_start = pi_init(mem_start, mem_end);
70 #endif
71 #if defined(CONFIG_APRICOT)
72 mem_start = apricot_init(mem_start, mem_end);
73 #endif
74 return mem_start;
75 }
76
77 /* Fill in the fields of the device structure with ethernet-generic values.
78
79 If no device structure is passed, a new one is constructed, complete with
80 a SIZEOF_PRIVATE private data area.
81
82 If an empty string area is passed as dev->name, or a new structure is made,
83 a new name string is constructed. The passed string area should be 8 bytes
84 long.
85 */
86
87 struct device *
88 init_etherdev(struct device *dev, int sizeof_private, 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)
*/
89 {
90 int new_device = 0;
91 int i;
92
93 if (dev == NULL) {
94 int alloc_size = sizeof(struct device) + sizeof("eth%d ")
95 + sizeof_private + 3;
96
97 alloc_size &= ~3; /* Round to dword boundary. */
98
99 if (mem_startp && *mem_startp ) {
100 dev = (struct device *)*mem_startp;
101 *mem_startp += alloc_size;
102 } else
103 dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
104 memset(dev, 0, alloc_size);
105 if (sizeof_private)
106 dev->priv = (void *) (dev + 1);
107 dev->name = sizeof_private + (char *)(dev + 1);
108 new_device = 1;
109 }
110
111 if (dev->name &&
112 ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
113 for (i = 0; i < MAX_ETH_CARDS; ++i)
114 if (ethdev_index[i] == NULL) {
115 sprintf(dev->name, "eth%d", i);
116 ethdev_index[i] = dev;
117 break;
118 }
119 }
120
121 ether_setup(dev); /* should this be called here? */
122
123 if (new_device) {
124 /* Append the device to the device queue. */
125 struct device **old_devp = &dev_base;
126 while ((*old_devp)->next)
127 old_devp = & (*old_devp)->next;
128 (*old_devp)->next = dev;
129 dev->next = 0;
130 }
131 return dev;
132 }
133
134 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)
*/
135 {
136 int i;
137 /* Fill in the fields of the device structure with ethernet-generic values.
138 This should be in a common file instead of per-driver. */
139 for (i = 0; i < DEV_NUMBUFFS; i++)
140 skb_queue_head_init(&dev->buffs[i]);
141
142 /* register boot-defined "eth" devices */
143 if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) {
144 i = simple_strtoul(dev->name + 3, NULL, 0);
145 if (ethdev_index[i] == NULL) {
146 ethdev_index[i] = dev;
147 }
148 else if (dev != ethdev_index[i]) {
149 /* Really shouldn't happen! */
150 printk("ether_setup: Ouch! Someone else took %s\n",
151 dev->name);
152 }
153 }
154
155 dev->hard_header = eth_header;
156 dev->rebuild_header = eth_rebuild_header;
157 dev->type_trans = eth_type_trans;
158
159 dev->type = ARPHRD_ETHER;
160 dev->hard_header_len = ETH_HLEN;
161 dev->mtu = 1500; /* eth_mtu */
162 dev->addr_len = ETH_ALEN;
163 for (i = 0; i < ETH_ALEN; i++) {
164 dev->broadcast[i]=0xff;
165 }
166
167 /* New-style flags. */
168 dev->flags = IFF_BROADCAST;
169 dev->family = AF_INET;
170 dev->pa_addr = 0;
171 dev->pa_brdaddr = 0;
172 dev->pa_mask = 0;
173 dev->pa_alen = sizeof(unsigned long);
174 }
175
176 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)
*/
177 {
178 if (map->mem_start != (u_long)(-1))
179 dev->mem_start = map->mem_start;
180 if (map->mem_end != (u_long)(-1))
181 dev->mem_end = map->mem_end;
182 if (map->base_addr != (u_short)(-1))
183 dev->base_addr = map->base_addr;
184 if (map->irq != (u_char)(-1))
185 dev->irq = map->irq;
186 if (map->dma != (u_char)(-1))
187 dev->dma = map->dma;
188 if (map->port != (u_char)(-1))
189 dev->if_port = map->port;
190 return 0;
191 }
192
193 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)
*/
194 {
195 struct device *d = dev_base;
196 unsigned long flags;
197 int i=MAX_ETH_CARDS;
198
199 save_flags(flags);
200 cli();
201
202 if (dev && dev->init) {
203 if (dev->name &&
204 ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
205 for (i = 0; i < MAX_ETH_CARDS; ++i)
206 if (ethdev_index[i] == NULL) {
207 sprintf(dev->name, "eth%d", i);
208 printk("loading device '%s'...\n", dev->name);
209 ethdev_index[i] = dev;
210 break;
211 }
212 }
213
214 if (dev->init(dev) != 0) {
215 if (i < MAX_ETH_CARDS) ethdev_index[i] = NULL;
216 restore_flags(flags);
217 return -EIO;
218 }
219
220 /* Add device to end of chain */
221 if (dev_base) {
222 while (d->next)
223 d = d->next;
224 d->next = dev;
225 }
226 else
227 dev_base = dev;
228 dev->next = NULL;
229 }
230 restore_flags(flags);
231 return 0;
232 }
233
234 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)
*/
235 {
236 struct device *d = dev_base;
237 unsigned long flags;
238 int i;
239
240 save_flags(flags);
241 cli();
242
243 printk("unregister_netdev: device ");
244
245 if (dev == NULL) {
246 printk("was NULL\n");
247 restore_flags(flags);
248 return;
249 }
250 /* else */
251 if (dev->start)
252 printk("'%s' busy\n", dev->name);
253 else {
254 if (dev_base == dev)
255 dev_base = dev->next;
256 else {
257 while (d && (d->next != dev))
258 d = d->next;
259
260 if (d && (d->next == dev)) {
261 d->next = dev->next;
262 printk("'%s' unlinked\n", dev->name);
263 }
264 else {
265 printk("'%s' not found\n", dev->name);
266 restore_flags(flags);
267 return;
268 }
269 }
270 for (i = 0; i < MAX_ETH_CARDS; ++i) {
271 if (ethdev_index[i] == dev) {
272 ethdev_index[i] = NULL;
273 break;
274 }
275 }
276 }
277 restore_flags(flags);
278 }
279
280
281
282 /*
283 * Local variables:
284 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
285 * version-control: t
286 * kept-new-versions: 5
287 * tab-width: 4
288 * End:
289 */