Browse Source

struct nic is now part of struct dev, rather than the other way around.

Tie into new boot device framework.
tags/v0.9.3
Michael Brown 19 years ago
parent
commit
1434e8d68d
1 changed files with 87 additions and 111 deletions
  1. 87
    111
      src/core/nic.c

+ 87
- 111
src/core/nic.c View File

15
 
15
 
16
 **************************************************************************/
16
 **************************************************************************/
17
 #include "etherboot.h"
17
 #include "etherboot.h"
18
+#include "console.h"
19
+#include "dev.h"
18
 #include "nic.h"
20
 #include "nic.h"
19
 #include "elf.h" /* FOR EM_CURRENT */
21
 #include "elf.h" /* FOR EM_CURRENT */
20
 
22
 
221
 #endif
223
 #endif
222
 #endif	/* NO_DHCP_SUPPORT */
224
 #endif	/* NO_DHCP_SUPPORT */
223
 
225
 
224
-static int dummy(void *unused __unused)
225
-{
226
-	return (0);
227
-}
228
-
229
-/* Careful.  We need an aligned buffer to avoid problems on machines
230
- * that care about alignment.  To trivally align the ethernet data
231
- * (the ip hdr and arp requests) we offset the packet by 2 bytes.
232
- * leaving the ethernet data 16 byte aligned.  Beyond this
233
- * we use memmove but this makes the common cast simple and fast.
234
- */
235
-static char	packet[ETH_FRAME_LEN + ETH_DATA_ALIGN] __aligned;
236
-
237
-struct nic	nic =
238
-{
239
-	{
240
-		0,				/* dev.disable */
241
-		{
242
-			0,
243
-			0,
244
-			PCI_BUS_TYPE,
245
-		},				/* dev.devid */
246
-		0,				/* index */
247
-		0,				/* type */
248
-		PROBE_FIRST,			/* how_pobe */
249
-		PROBE_NONE,			/* to_probe */
250
-		0,				/* failsafe */
251
-		0,				/* type_index */
252
-		{},				/* state */
253
-	},
254
-	(int (*)(struct nic *, int))dummy,	/* poll */
255
-	(void (*)(struct nic *, const char *,
256
-		unsigned int, unsigned int,
257
-		const char *))dummy,		/* transmit */
258
-	(void (*)(struct nic *,
259
-		 irq_action_t))dummy,		/* irq */
260
-	0,					/* flags */
261
-	&rom,					/* rom_info */
262
-	arptable[ARP_CLIENT].node,		/* node_addr */
263
-	packet + ETH_DATA_ALIGN,		/* packet */
264
-	0,					/* packetlen */
265
-	0,					/* ioaddr */
266
-	0,					/* irqno */
267
-	0,					/* priv_data */
268
-};
269
-
270
 #ifdef RARP_NOT_BOOTP
226
 #ifdef RARP_NOT_BOOTP
271
 static int rarp(void);
227
 static int rarp(void);
272
 #else
228
 #else
275
 static unsigned short tcpudpchksum(struct iphdr *ip);
231
 static unsigned short tcpudpchksum(struct iphdr *ip);
276
 
232
 
277
 
233
 
278
-int eth_probe(struct dev *dev)
279
-{
280
-	return probe(dev);
281
-}
282
-
283
-int eth_poll(int retrieve)
284
-{
285
-	return ((*nic.poll)(&nic, retrieve));
286
-}
287
-
288
-void eth_transmit(const char *d, unsigned int t, unsigned int s, const void *p)
289
-{
290
-	(*nic.transmit)(&nic, d, t, s, p);
291
-	if (t == ETH_P_IP) twiddle();
292
-}
293
-
294
-void eth_disable(void)
295
-{
296
-#ifdef MULTICAST_LEVEL2
297
-	int i;
298
-	for(i = 0; i < MAX_IGMP; i++) {
299
-		leave_group(i);
300
-	}
301
-#endif
302
-	disable(&nic.dev);
303
-}
304
-
305
-void eth_irq (irq_action_t action)
306
-{
307
-	(*nic.irq)(&nic,action);
308
-}
234
+struct nic *nic = &dev.nic;
309
 
235
 
310
 /*
236
 /*
311
  * Find out what our boot parameters are
237
  * Find out what our boot parameters are
312
  */
238
  */
313
-int eth_load_configuration(struct dev *dev __unused)
239
+static int nic_load_configuration(struct dev *dev __unused)
314
 {
240
 {
315
 	int server_found;
241
 	int server_found;
316
 	/* Find a server to get BOOTP reply from */
242
 	/* Find a server to get BOOTP reply from */
340
 /**************************************************************************
266
 /**************************************************************************
341
 LOAD - Try to get booted
267
 LOAD - Try to get booted
342
 **************************************************************************/
268
 **************************************************************************/
343
-int eth_load(struct dev *dev __unused)
269
+static int nic_load(struct dev *dev __unused)
344
 {
270
 {
345
 	const char	*kernel;
271
 	const char	*kernel;
346
 	printf("\nMe: %@", arptable[ARP_CLIENT].ipaddr.s_addr );
272
 	printf("\nMe: %@", arptable[ARP_CLIENT].ipaddr.s_addr );
390
 }
316
 }
391
 
317
 
392
 
318
 
319
+static void nic_disable ( struct dev *dev ) {
320
+	struct nic *nic = &dev->nic;
321
+
322
+#ifdef MULTICAST_LEVEL2
323
+	int i;
324
+	for(i = 0; i < MAX_IGMP; i++) {
325
+		leave_group(i);
326
+	}
327
+#endif
328
+	
329
+	nic->nic_op->disable ( nic );
330
+}
331
+
332
+/* 
333
+ * Device operations tables
334
+ *
335
+ */
336
+static struct dev_operations nic_operations = {
337
+	.disable = nic_disable,
338
+	.load_configuration = nic_load_configuration,
339
+	.load = nic_load,
340
+};
341
+
342
+/* Careful.  We need an aligned buffer to avoid problems on machines
343
+ * that care about alignment.  To trivally align the ethernet data
344
+ * (the ip hdr and arp requests) we offset the packet by 2 bytes.
345
+ * leaving the ethernet data 16 byte aligned.  Beyond this
346
+ * we use memmove but this makes the common cast simple and fast.
347
+ */
348
+static char	packet[ETH_FRAME_LEN + ETH_DATA_ALIGN] __aligned;
349
+
350
+/*
351
+ * Set up a struct dev to operate as a NIC, return the struct nic *
352
+ *
353
+ */
354
+struct nic * nic_device ( struct dev *dev ) {
355
+	struct nic *nic = &dev->nic;
356
+
357
+	memset ( nic, 0, sizeof ( *nic ) );
358
+	nic->node_addr = arptable[ARP_CLIENT].node;
359
+	nic->packet = packet + ETH_DATA_ALIGN;
360
+	dev->dev_op = &nic_operations;
361
+	return nic;
362
+}
363
+
364
+
365
+
366
+
367
+
368
+
393
 /**************************************************************************
369
 /**************************************************************************
394
 DEFAULT_NETMASK - Return default netmask for IP address
370
 DEFAULT_NETMASK - Return default netmask for IP address
395
 **************************************************************************/
371
 **************************************************************************/
414
 	struct	arprequest *arpreply;
390
 	struct	arprequest *arpreply;
415
 	if (ptype != ETH_P_ARP)
391
 	if (ptype != ETH_P_ARP)
416
 		return 0;
392
 		return 0;
417
-	if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
393
+	if (nic->packetlen < ETH_HLEN + sizeof(struct arprequest))
418
 		return 0;
394
 		return 0;
419
-	arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
395
+	arpreply = (struct arprequest *)&nic->packet[ETH_HLEN];
420
 
396
 
421
 	if (arpreply->opcode != htons(ARP_REPLY)) 
397
 	if (arpreply->opcode != htons(ARP_REPLY)) 
422
 		return 0;
398
 		return 0;
703
 			continue; /* Back to waiting for packet */
679
 			continue; /* Back to waiting for packet */
704
 		}
680
 		}
705
 		/* Packet has been received */
681
 		/* Packet has been received */
706
-		rcvd = (struct tftp_t *)&nic.packet[ETH_HLEN];
682
+		rcvd = (struct tftp_t *)&nic->packet[ETH_HLEN];
707
 		recvlen = ntohs(rcvd->udp.len) - sizeof(struct udphdr)
683
 		recvlen = ntohs(rcvd->udp.len) - sizeof(struct udphdr)
708
 			- sizeof(rcvd->opcode);
684
 			- sizeof(rcvd->opcode);
709
 		rport = ntohs(rcvd->udp.src);
685
 		rport = ntohs(rcvd->udp.src);
783
 	struct arprequest *arpreply;
759
 	struct arprequest *arpreply;
784
 	if (ptype != ETH_P_RARP)
760
 	if (ptype != ETH_P_RARP)
785
 		return 0;
761
 		return 0;
786
-	if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
762
+	if (nic->packetlen < ETH_HLEN + sizeof(struct arprequest))
787
 		return 0;
763
 		return 0;
788
-	arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
764
+	arpreply = (struct arprequest *)&nic->packet[ETH_HLEN];
789
 	if (arpreply->opcode != htons(RARP_REPLY))
765
 	if (arpreply->opcode != htons(RARP_REPLY))
790
 		return 0;
766
 		return 0;
791
 	if ((arpreply->opcode == htons(RARP_REPLY)) &&
767
 	if ((arpreply->opcode == htons(RARP_REPLY)) &&
847
 	if (!udp) {
823
 	if (!udp) {
848
 		return 0;
824
 		return 0;
849
 	}
825
 	}
850
-	bootpreply = (struct bootp_t *)&nic.packet[ETH_HLEN + 
826
+	bootpreply = (struct bootp_t *)&nic->packet[ETH_HLEN + 
851
 		sizeof(struct iphdr) + sizeof(struct udphdr)];
827
 		sizeof(struct iphdr) + sizeof(struct udphdr)];
852
-	if (nic.packetlen < ETH_HLEN + sizeof(struct iphdr) + 
828
+	if (nic->packetlen < ETH_HLEN + sizeof(struct iphdr) + 
853
 		sizeof(struct udphdr) + 
829
 		sizeof(struct udphdr) + 
854
 #ifdef NO_DHCP_SUPPORT
830
 #ifdef NO_DHCP_SUPPORT
855
 		sizeof(struct bootp_t)
831
 		sizeof(struct bootp_t)
922
 	unsigned char *bp_vend;
898
 	unsigned char *bp_vend;
923
 
899
 
924
 #ifndef	NO_DHCP_SUPPORT
900
 #ifndef	NO_DHCP_SUPPORT
925
-	dhcp_machine_info[4] = nic.dev.devid.bus_type;
926
-	dhcp_machine_info[5] = nic.dev.devid.vendor_id & 0xff;
927
-	dhcp_machine_info[6] = ((nic.dev.devid.vendor_id) >> 8) & 0xff;
928
-	dhcp_machine_info[7] = nic.dev.devid.device_id & 0xff;
929
-	dhcp_machine_info[8] = ((nic.dev.devid.device_id) >> 8) & 0xff;
901
+	dhcp_machine_info[4] = dev.devid.bus_type;
902
+	dhcp_machine_info[5] = dev.devid.vendor_id & 0xff;
903
+	dhcp_machine_info[6] = ((dev.devid.vendor_id) >> 8) & 0xff;
904
+	dhcp_machine_info[7] = dev.devid.device_id & 0xff;
905
+	dhcp_machine_info[8] = ((dev.devid.device_id) >> 8) & 0xff;
930
 #endif	/* NO_DHCP_SUPPORT */
906
 #endif	/* NO_DHCP_SUPPORT */
931
 	memset(&ip, 0, sizeof(struct bootpip_t));
907
 	memset(&ip, 0, sizeof(struct bootpip_t));
932
 	ip.bp.bp_op = BOOTP_REQUEST;
908
 	ip.bp.bp_op = BOOTP_REQUEST;
1092
 	int i;
1068
 	int i;
1093
 	unsigned iplen;
1069
 	unsigned iplen;
1094
 	if (!ip || (ip->protocol == IP_IGMP) ||
1070
 	if (!ip || (ip->protocol == IP_IGMP) ||
1095
-		(nic.packetlen < sizeof(struct iphdr) + sizeof(struct igmp))) {
1071
+		(nic->packetlen < sizeof(struct iphdr) + sizeof(struct igmp))) {
1096
 		return;
1072
 		return;
1097
 	}
1073
 	}
1098
 	iplen = (ip->verhdrlen & 0xf)*4;
1074
 	iplen = (ip->verhdrlen & 0xf)*4;
1099
-	igmp = (struct igmp *)&nic.packet[sizeof(struct iphdr)];
1075
+	igmp = (struct igmp *)&nic->packet[sizeof(struct iphdr)];
1100
 	if (ipchksum(igmp, ntohs(ip->len) - iplen) != 0)
1076
 	if (ipchksum(igmp, ntohs(ip->len) - iplen) != 0)
1101
 		return;
1077
 		return;
1102
 	if ((igmp->type == IGMP_QUERY) && 
1078
 	if ((igmp->type == IGMP_QUERY) && 
1303
 	       syn_ack = state == CLOSED || state == SYN_RCVD;
1279
 	       syn_ack = state == CLOSED || state == SYN_RCVD;
1304
 	       consumed = ntohl(tcp->ack) - send_seq - syn_ack;
1280
 	       consumed = ntohl(tcp->ack) - send_seq - syn_ack;
1305
 	       if (consumed < 0 || consumed > can_send) {
1281
 	       if (consumed < 0 || consumed > can_send) {
1306
-		       tcp_reset((struct iphdr *)&nic.packet[ETH_HLEN]);
1282
+		       tcp_reset((struct iphdr *)&nic->packet[ETH_HLEN]);
1307
 		       goto recv_data;
1283
 		       goto recv_data;
1308
 	       }
1284
 	       }
1309
 
1285
 
1345
        }
1321
        }
1346
 
1322
 
1347
  consume_data:
1323
  consume_data:
1348
-       ip  = (struct iphdr *)&nic.packet[ETH_HLEN];
1324
+       ip  = (struct iphdr *)&nic->packet[ETH_HLEN];
1349
        header_size = sizeof(struct iphdr) + ((ntohs(tcp->ctrl)>>10)&0x3C);
1325
        header_size = sizeof(struct iphdr) + ((ntohs(tcp->ctrl)>>10)&0x3C);
1350
        payload = ntohs(ip->len) - header_size;
1326
        payload = ntohs(ip->len) - header_size;
1351
        if (payload > 0 && state == ESTABLISHED) {
1327
        if (payload > 0 && state == ESTABLISHED) {
1354
 		       recv_seq += payload - old_bytes;
1330
 		       recv_seq += payload - old_bytes;
1355
 		       if (state != FIN_WAIT_1 && state != FIN_WAIT_2 &&
1331
 		       if (state != FIN_WAIT_1 && state != FIN_WAIT_2 &&
1356
 			   !recv(payload - old_bytes,
1332
 			   !recv(payload - old_bytes,
1357
-				 &nic.packet[ETH_HLEN+header_size+old_bytes],
1333
+				 &nic->packet[ETH_HLEN+header_size+old_bytes],
1358
 				 ptr)) {
1334
 				 ptr)) {
1359
 			       goto close;
1335
 			       goto close;
1360
 		       }
1336
 		       }
1466
 		/* We have something! */
1442
 		/* We have something! */
1467
 
1443
 
1468
 		/* Find the Ethernet packet type */
1444
 		/* Find the Ethernet packet type */
1469
-		if (nic.packetlen >= ETH_HLEN) {
1470
-			ptype = ((unsigned short) nic.packet[12]) << 8
1471
-				| ((unsigned short) nic.packet[13]);
1445
+		if (nic->packetlen >= ETH_HLEN) {
1446
+			ptype = ((unsigned short) nic->packet[12]) << 8
1447
+				| ((unsigned short) nic->packet[13]);
1472
 		} else continue; /* what else could we do with it? */
1448
 		} else continue; /* what else could we do with it? */
1473
 		/* Verify an IP header */
1449
 		/* Verify an IP header */
1474
 		ip = 0;
1450
 		ip = 0;
1475
-		if ((ptype == ETH_P_IP) && (nic.packetlen >= ETH_HLEN + sizeof(struct iphdr))) {
1451
+		if ((ptype == ETH_P_IP) && (nic->packetlen >= ETH_HLEN + sizeof(struct iphdr))) {
1476
 			unsigned ipoptlen;
1452
 			unsigned ipoptlen;
1477
-			ip = (struct iphdr *)&nic.packet[ETH_HLEN];
1453
+			ip = (struct iphdr *)&nic->packet[ETH_HLEN];
1478
 			if ((ip->verhdrlen < 0x45) || (ip->verhdrlen > 0x4F)) 
1454
 			if ((ip->verhdrlen < 0x45) || (ip->verhdrlen > 0x4F)) 
1479
 				continue;
1455
 				continue;
1480
 			iplen = (ip->verhdrlen & 0xf) * 4;
1456
 			iplen = (ip->verhdrlen & 0xf) * 4;
1496
 				/* Delete the ip options, to guarantee
1472
 				/* Delete the ip options, to guarantee
1497
 				 * good alignment, and make etherboot simpler.
1473
 				 * good alignment, and make etherboot simpler.
1498
 				 */
1474
 				 */
1499
-				memmove(&nic.packet[ETH_HLEN + sizeof(struct iphdr)], 
1500
-					&nic.packet[ETH_HLEN + iplen],
1501
-					nic.packetlen - ipoptlen);
1502
-				nic.packetlen -= ipoptlen;
1475
+				memmove(&nic->packet[ETH_HLEN + sizeof(struct iphdr)], 
1476
+					&nic->packet[ETH_HLEN + iplen],
1477
+					nic->packetlen - ipoptlen);
1478
+				nic->packetlen -= ipoptlen;
1503
 			}
1479
 			}
1504
 		}
1480
 		}
1505
 		udp = 0;
1481
 		udp = 0;
1506
 		if (ip && (ip->protocol == IP_UDP) && 
1482
 		if (ip && (ip->protocol == IP_UDP) && 
1507
-			(nic.packetlen >= 
1483
+			(nic->packetlen >= 
1508
 			ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr))) {
1484
 			ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr))) {
1509
-			udp = (struct udphdr *)&nic.packet[ETH_HLEN + sizeof(struct iphdr)];
1485
+			udp = (struct udphdr *)&nic->packet[ETH_HLEN + sizeof(struct iphdr)];
1510
 
1486
 
1511
 			/* Make certain we have a reasonable packet length */
1487
 			/* Make certain we have a reasonable packet length */
1512
 			if (ntohs(udp->len) > (ntohs(ip->len) - iplen))
1488
 			if (ntohs(udp->len) > (ntohs(ip->len) - iplen))
1520
 		tcp = 0;
1496
 		tcp = 0;
1521
 #ifdef DOWNLOAD_PROTO_HTTP
1497
 #ifdef DOWNLOAD_PROTO_HTTP
1522
 		if (ip && (ip->protocol == IP_TCP) &&
1498
 		if (ip && (ip->protocol == IP_TCP) &&
1523
-		    (nic.packetlen >=
1499
+		    (nic->packetlen >=
1524
 		     ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr))){
1500
 		     ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr))){
1525
-			tcp = (struct tcphdr *)&nic.packet[ETH_HLEN +
1501
+			tcp = (struct tcphdr *)&nic->packet[ETH_HLEN +
1526
 							 sizeof(struct iphdr)];
1502
 							 sizeof(struct iphdr)];
1527
 			/* Make certain we have a reasonable packet length */
1503
 			/* Make certain we have a reasonable packet length */
1528
 			if (((ntohs(tcp->ctrl) >> 10) & 0x3C) >
1504
 			if (((ntohs(tcp->ctrl) >> 10) & 0x3C) >
1544
 		 * action.  This allows us reply to arp, igmp, and lacp queries.
1520
 		 * action.  This allows us reply to arp, igmp, and lacp queries.
1545
 		 */
1521
 		 */
1546
 		if ((ptype == ETH_P_ARP) &&
1522
 		if ((ptype == ETH_P_ARP) &&
1547
-			(nic.packetlen >= ETH_HLEN + sizeof(struct arprequest))) {
1523
+			(nic->packetlen >= ETH_HLEN + sizeof(struct arprequest))) {
1548
 			struct	arprequest *arpreply;
1524
 			struct	arprequest *arpreply;
1549
 			unsigned long tmp;
1525
 			unsigned long tmp;
1550
 		
1526
 		
1551
-			arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
1527
+			arpreply = (struct arprequest *)&nic->packet[ETH_HLEN];
1552
 			memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
1528
 			memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
1553
 			if ((arpreply->opcode == htons(ARP_REQUEST)) &&
1529
 			if ((arpreply->opcode == htons(ARP_REQUEST)) &&
1554
 				(tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
1530
 				(tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {

Loading…
Cancel
Save