Browse Source

Merge branch 'master' of ssh://rom.etherboot.org/pub/scm/gpxe

tags/v0.9.3
Marty Connor 17 years ago
parent
commit
0297a63877

src/arch/i386/core/dhcp_basemem.c → src/arch/i386/core/basemem_packet.c View File

19
 /**
19
 /**
20
  * @file
20
  * @file
21
  *
21
  *
22
- * DHCP parameter block provided to external programs in base memory
22
+ * Packet buffer in base memory.  Used by various components which
23
+ * need to pass packets to and from external real-mode code.
23
  *
24
  *
24
  */
25
  */
25
 
26
 
26
-#include <dhcp_basemem.h>
27
+#include <basemem_packet.h>
27
 
28
 
28
-#undef dhcp_basemem
29
-char __data16_array ( dhcp_basemem, [DHCP_BASEMEM_LEN] );
29
+#undef basemem_packet
30
+char __data16_array ( basemem_packet, [BASEMEM_PACKET_LEN] );

+ 5
- 11
src/arch/i386/drivers/net/undinet.c View File

22
 #include <pic8259.h>
22
 #include <pic8259.h>
23
 #include <biosint.h>
23
 #include <biosint.h>
24
 #include <pnpbios.h>
24
 #include <pnpbios.h>
25
+#include <basemem_packet.h>
25
 #include <gpxe/iobuf.h>
26
 #include <gpxe/iobuf.h>
26
 #include <gpxe/netdevice.h>
27
 #include <gpxe/netdevice.h>
27
 #include <gpxe/if_ether.h>
28
 #include <gpxe/if_ether.h>
314
  *****************************************************************************
315
  *****************************************************************************
315
  */
316
  */
316
 
317
 
317
-/** Maximum length of a packet transmitted via the UNDI API */
318
-#define UNDI_IOB_LEN 1514
319
-
320
-/** UNDI I/O buffer */
321
-static char __data16_array ( undinet_iob, [UNDI_IOB_LEN] );
322
-#define undinet_iob __use_data16 ( undinet_iob )
323
-
324
 /** UNDI transmit buffer descriptor */
318
 /** UNDI transmit buffer descriptor */
325
 static struct s_PXENV_UNDI_TBD __data16 ( undinet_tbd );
319
 static struct s_PXENV_UNDI_TBD __data16 ( undinet_tbd );
326
 #define undinet_tbd __use_data16 ( undinet_tbd )
320
 #define undinet_tbd __use_data16 ( undinet_tbd )
340
 	int rc;
334
 	int rc;
341
 
335
 
342
 	/* Copy packet to UNDI I/O buffer */
336
 	/* Copy packet to UNDI I/O buffer */
343
-	if ( len > sizeof ( undinet_iob ) )
344
-		len = sizeof ( undinet_iob );
345
-	memcpy ( &undinet_iob, iobuf->data, len );
337
+	if ( len > sizeof ( basemem_packet ) )
338
+		len = sizeof ( basemem_packet );
339
+	memcpy ( &basemem_packet, iobuf->data, len );
346
 
340
 
347
 	/* Create PXENV_UNDI_TRANSMIT data structure */
341
 	/* Create PXENV_UNDI_TRANSMIT data structure */
348
 	memset ( &undi_transmit, 0, sizeof ( undi_transmit ) );
342
 	memset ( &undi_transmit, 0, sizeof ( undi_transmit ) );
357
 	undinet_tbd.ImmedLength = len;
351
 	undinet_tbd.ImmedLength = len;
358
 	undinet_tbd.Xmit.segment = rm_ds;
352
 	undinet_tbd.Xmit.segment = rm_ds;
359
 	undinet_tbd.Xmit.offset 
353
 	undinet_tbd.Xmit.offset 
360
-		= ( ( unsigned ) & __from_data16 ( undinet_iob ) );
354
+		= ( ( unsigned ) & __from_data16 ( basemem_packet ) );
361
 
355
 
362
 	/* Issue PXE API call */
356
 	/* Issue PXE API call */
363
 	if ( ( rc = undinet_call ( undinic, PXENV_UNDI_TRANSMIT,
357
 	if ( ( rc = undinet_call ( undinic, PXENV_UNDI_TRANSMIT,

+ 5
- 5
src/arch/i386/image/nbi.c View File

3
 #include <realmode.h>
3
 #include <realmode.h>
4
 #include <gateA20.h>
4
 #include <gateA20.h>
5
 #include <memsizes.h>
5
 #include <memsizes.h>
6
-#include <dhcp_basemem.h>
6
+#include <basemem_packet.h>
7
 #include <gpxe/uaccess.h>
7
 #include <gpxe/uaccess.h>
8
 #include <gpxe/segment.h>
8
 #include <gpxe/segment.h>
9
 #include <gpxe/shutdown.h>
9
 #include <gpxe/shutdown.h>
321
 		  "=b" ( discard_b )
321
 		  "=b" ( discard_b )
322
 		: "D" ( imgheader->execaddr.segoff ),
322
 		: "D" ( imgheader->execaddr.segoff ),
323
 		  "S" ( imgheader->location ),
323
 		  "S" ( imgheader->location ),
324
-		  "b" ( __from_data16 ( dhcp_basemem ) )
324
+		  "b" ( __from_data16 ( basemem_packet ) )
325
 		: "ecx", "edx", "ebp" );
325
 		: "ecx", "edx", "ebp" );
326
 
326
 
327
 	gateA20_set();
327
 	gateA20_set();
356
 		: "D" ( imgheader->execaddr.linear ),
356
 		: "D" ( imgheader->execaddr.linear ),
357
 		  "S" ( ( imgheader->location.segment << 4 ) +
357
 		  "S" ( ( imgheader->location.segment << 4 ) +
358
 			imgheader->location.offset ),
358
 			imgheader->location.offset ),
359
-		  "b" ( virt_to_phys ( dhcp_basemem ) ),
359
+		  "b" ( virt_to_phys ( basemem_packet ) ),
360
 		  "a" ( virt_to_phys ( &loaderinfo ) )
360
 		  "a" ( virt_to_phys ( &loaderinfo ) )
361
 		: "ecx", "edx", "ebp", "memory" );
361
 		: "ecx", "edx", "ebp", "memory" );
362
 
362
 
397
 		return -ENODEV;
397
 		return -ENODEV;
398
 	}
398
 	}
399
 
399
 
400
-	if ( ( rc = create_dhcp_packet ( boot_netdev, DHCPACK,
401
-					 dhcp_basemem, sizeof ( dhcp_basemem ),
400
+	if ( ( rc = create_dhcp_packet ( boot_netdev, DHCPACK, basemem_packet,
401
+					 sizeof ( basemem_packet ),
402
 					 &dhcppkt ) ) != 0 ) {
402
 					 &dhcppkt ) ) != 0 ) {
403
 		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
403
 		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
404
 		return rc;
404
 		return rc;

+ 10
- 2
src/arch/i386/image/pxe_image.c View File

40
  */
40
  */
41
 static int pxe_exec ( struct image *image __unused ) {
41
 static int pxe_exec ( struct image *image __unused ) {
42
 	struct net_device *netdev;
42
 	struct net_device *netdev;
43
+	int rc;
43
 
44
 
44
 	/* Ensure that PXE stack is ready to use */
45
 	/* Ensure that PXE stack is ready to use */
45
 	pxe_init_structures();
46
 	pxe_init_structures();
47
 
48
 
48
 	/* Arbitrarily pick the first open network device to use for PXE */
49
 	/* Arbitrarily pick the first open network device to use for PXE */
49
 	for_each_netdev ( netdev ) {
50
 	for_each_netdev ( netdev ) {
50
-		pxe_netdev = netdev;
51
+		pxe_set_netdev ( netdev );
51
 		break;
52
 		break;
52
 	}
53
 	}
53
 
54
 
54
-	return pxe_start_nbp();
55
+	/* Start PXE NBP */
56
+	rc = pxe_start_nbp();
57
+
58
+	/* Deactivate PXE */
59
+	pxe_set_netdev ( NULL );
60
+	pxe_unhook_int1a();
61
+
62
+	return rc;
55
 }
63
 }
56
 
64
 
57
 /**
65
 /**

+ 13
- 0
src/arch/i386/include/basemem_packet.h View File

1
+#ifndef BASEMEM_PACKET_H
2
+#define BASEMEM_PACKET_H
3
+
4
+#include <realmode.h>
5
+
6
+/** Maximum length of base memory packet buffer */
7
+#define BASEMEM_PACKET_LEN 1514
8
+
9
+/** Base memory packet buffer */
10
+extern char __data16_array ( basemem_packet, [BASEMEM_PACKET_LEN] );
11
+#define basemem_packet __use_data16 ( basemem_packet )
12
+
13
+#endif /* BASEMEM_PACKET_H */

+ 0
- 13
src/arch/i386/include/dhcp_basemem.h View File

1
-#ifndef DHCP_BASEMEM_H
2
-#define DHCP_BASEMEM_H
3
-
4
-#include <realmode.h>
5
-
6
-/** Maximum length of a DHCP data buffer */
7
-#define DHCP_BASEMEM_LEN 1514
8
-
9
-/** DHCP data buffer */
10
-extern char __data16_array ( dhcp_basemem, [DHCP_BASEMEM_LEN] );
11
-#define dhcp_basemem __use_data16 ( dhcp_basemem )
12
-
13
-#endif /* DHCP_BASEMEM_H */

+ 2
- 0
src/drivers/bus/isapnp.c View File

705
 			isapnp->dev.desc.bus_type = BUS_TYPE_ISAPNP;
705
 			isapnp->dev.desc.bus_type = BUS_TYPE_ISAPNP;
706
 			isapnp->dev.desc.vendor = isapnp->vendor_id;
706
 			isapnp->dev.desc.vendor = isapnp->vendor_id;
707
 			isapnp->dev.desc.device = isapnp->prod_id;
707
 			isapnp->dev.desc.device = isapnp->prod_id;
708
+			isapnp->dev.desc.ioaddr = isapnp->ioaddr;
709
+			isapnp->dev.desc.irq = isapnp->irqno;
708
 			isapnp->dev.parent = &rootdev->dev;
710
 			isapnp->dev.parent = &rootdev->dev;
709
 			list_add ( &isapnp->dev.siblings,
711
 			list_add ( &isapnp->dev.siblings,
710
 				   &rootdev->dev.children );
712
 				   &rootdev->dev.children );

+ 3
- 0
src/drivers/bus/pci.c View File

286
 			pci->dev.desc.location = PCI_BUSDEVFN (bus, devfn);
286
 			pci->dev.desc.location = PCI_BUSDEVFN (bus, devfn);
287
 			pci->dev.desc.vendor = pci->vendor;
287
 			pci->dev.desc.vendor = pci->vendor;
288
 			pci->dev.desc.device = pci->device;
288
 			pci->dev.desc.device = pci->device;
289
+			pci->dev.desc.class = pci->class;
290
+			pci->dev.desc.ioaddr = pci->ioaddr;
291
+			pci->dev.desc.irq = pci->irq;
289
 			pci->dev.parent = &rootdev->dev;
292
 			pci->dev.parent = &rootdev->dev;
290
 			list_add ( &pci->dev.siblings, &rootdev->dev.children);
293
 			list_add ( &pci->dev.siblings, &rootdev->dev.children);
291
 			INIT_LIST_HEAD ( &pci->dev.children );
294
 			INIT_LIST_HEAD ( &pci->dev.children );

+ 2
- 0
src/include/gpxe/arp.h View File

30
 #define __arp_net_protocol \
30
 #define __arp_net_protocol \
31
 	__table ( struct arp_net_protocol, arp_net_protocols, 01 )
31
 	__table ( struct arp_net_protocol, arp_net_protocols, 01 )
32
 
32
 
33
+extern struct net_protocol arp_protocol;
34
+
33
 extern int arp_resolve ( struct net_device *netdev,
35
 extern int arp_resolve ( struct net_device *netdev,
34
 			 struct net_protocol *net_protocol,
36
 			 struct net_protocol *net_protocol,
35
 			 const void *dest_net_addr,
37
 			 const void *dest_net_addr,

+ 6
- 0
src/include/gpxe/device.h View File

27
 	unsigned int vendor;
27
 	unsigned int vendor;
28
 	/** Device ID */
28
 	/** Device ID */
29
 	unsigned int device;
29
 	unsigned int device;
30
+	/** Device class */
31
+	unsigned long class;
32
+	/** I/O address */
33
+	unsigned long ioaddr;
34
+	/** IRQ */
35
+	unsigned int irq;
30
 };
36
 };
31
 
37
 
32
 /** PCI bus type */
38
 /** PCI bus type */

+ 2
- 0
src/include/gpxe/netdevice.h View File

122
 	uint16_t ll_proto;
122
 	uint16_t ll_proto;
123
 	/** Link-layer address length */
123
 	/** Link-layer address length */
124
 	uint8_t ll_addr_len;
124
 	uint8_t ll_addr_len;
125
+	/** Link-layer header length */
126
+	uint8_t ll_header_len;
125
 	/** Link-layer broadcast address */
127
 	/** Link-layer broadcast address */
126
 	const uint8_t *ll_broadcast;
128
 	const uint8_t *ll_broadcast;
127
 };
129
 };

+ 14
- 0
src/include/gpxe/rarp.h View File

1
+#ifndef _GPXE_RARP_H
2
+#define _GPXE_RARP_H
3
+
4
+/** @file
5
+ *
6
+ * Reverse Address Resolution Protocol
7
+ *
8
+ */
9
+
10
+struct net_protocol;
11
+
12
+extern struct net_protocol rarp_protocol;
13
+
14
+#endif /* _GPXE_RARP_H */

+ 2
- 0
src/include/pxe.h View File

137
 
137
 
138
 extern struct net_device *pxe_netdev;
138
 extern struct net_device *pxe_netdev;
139
 
139
 
140
+extern void pxe_set_netdev ( struct net_device *netdev );
141
+
140
 #endif /* PXE_H */
142
 #endif /* PXE_H */

+ 14
- 2
src/interface/pxe/pxe.c View File

22
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
  */
23
  */
24
 
24
 
25
-#include "dev.h"
25
+#include <gpxe/netdevice.h>
26
 #include "pxe.h"
26
 #include "pxe.h"
27
 
27
 
28
-#warning "pxe_netdev should hold a persistent reference to the net device"
29
 struct net_device *pxe_netdev = NULL;
28
 struct net_device *pxe_netdev = NULL;
30
 
29
 
30
+/**
31
+ * Set network device as current PXE network device
32
+ *
33
+ * @v netdev		Network device, or NULL
34
+ */
35
+void pxe_set_netdev ( struct net_device *netdev ) {
36
+	if ( pxe_netdev )
37
+		netdev_put ( pxe_netdev );
38
+	pxe_netdev = NULL;
39
+	if ( netdev )
40
+		pxe_netdev = netdev_get ( netdev );
41
+}
42
+
31
 #if 0
43
 #if 0
32
 
44
 
33
 /* Global pointer to currently installed PXE stack */
45
 /* Global pointer to currently installed PXE stack */

+ 3
- 3
src/interface/pxe/pxe_preboot.c View File

28
 #include <stdlib.h>
28
 #include <stdlib.h>
29
 #include <gpxe/uaccess.h>
29
 #include <gpxe/uaccess.h>
30
 #include <gpxe/dhcp.h>
30
 #include <gpxe/dhcp.h>
31
-#include <dhcp_basemem.h>
31
+#include <basemem_packet.h>
32
 #include "pxe.h"
32
 #include "pxe.h"
33
 #include "pxe_call.h"
33
 #include "pxe_call.h"
34
 
34
 
99
 	 */
99
 	 */
100
 	len = get_cached_info->BufferSize;
100
 	len = get_cached_info->BufferSize;
101
 	if ( len == 0 ) {
101
 	if ( len == 0 ) {
102
-		len = sizeof ( dhcp_basemem );
102
+		len = sizeof ( basemem_packet );
103
 		get_cached_info->Buffer.segment = rm_ds;
103
 		get_cached_info->Buffer.segment = rm_ds;
104
 		get_cached_info->Buffer.offset =
104
 		get_cached_info->Buffer.offset =
105
-			( unsigned int ) ( & __from_data16 ( dhcp_basemem ) );
105
+			( unsigned int ) ( & __from_data16 ( basemem_packet ) );
106
 		get_cached_info->BufferLimit = len;
106
 		get_cached_info->BufferLimit = len;
107
 	}
107
 	}
108
 
108
 

+ 134
- 165
src/interface/pxe/pxe_undi.c View File

23
  */
23
  */
24
 
24
 
25
 #include <stdint.h>
25
 #include <stdint.h>
26
+#include <stdio.h>
26
 #include <string.h>
27
 #include <string.h>
28
+#include <byteswap.h>
29
+#include <basemem_packet.h>
27
 #include <gpxe/netdevice.h>
30
 #include <gpxe/netdevice.h>
31
+#include <gpxe/iobuf.h>
28
 #include <gpxe/device.h>
32
 #include <gpxe/device.h>
29
 #include <gpxe/pci.h>
33
 #include <gpxe/pci.h>
30
-#include <gpxe/isapnp.h>
31
 #include <gpxe/if_ether.h>
34
 #include <gpxe/if_ether.h>
35
+#include <gpxe/ip.h>
36
+#include <gpxe/arp.h>
37
+#include <gpxe/rarp.h>
32
 #include <gpxe/shutdown.h>
38
 #include <gpxe/shutdown.h>
33
 #include "pxe.h"
39
 #include "pxe.h"
34
 
40
 
128
  */
134
  */
129
 PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
135
 PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
130
 				   *undi_transmit ) {
136
 				   *undi_transmit ) {
131
-	struct s_PXENV_UNDI_TBD *tbd;
132
-	const char *dest;
133
-	unsigned int type;
134
-	unsigned int length;
135
-	const char *data;
137
+	struct s_PXENV_UNDI_TBD tbd;
138
+	struct DataBlk *datablk;
139
+	struct io_buffer *iobuf;
140
+	struct net_protocol *net_protocol;
141
+	char destaddr[MAX_LL_ADDR_LEN];
142
+	const void *ll_dest;
143
+	size_t len;
144
+	unsigned int i;
145
+	int rc;
136
 
146
 
137
 	DBG ( "PXENV_UNDI_TRANSMIT" );
147
 	DBG ( "PXENV_UNDI_TRANSMIT" );
138
 
148
 
139
-#if 0
140
-	/* We support only the "immediate" portion of the TBD.  Who
141
-	 * knows what Intel's "engineers" were smoking when they came
142
-	 * up with the array of transmit data blocks...
143
-	 */
144
-	tbd = SEGOFF16_TO_PTR ( undi_transmit->TBD );
145
-	if ( tbd->DataBlkCount > 0 ) {
149
+	/* Identify network-layer protocol */
150
+	switch ( undi_transmit->Protocol ) {
151
+	case P_IP:	net_protocol = &ipv4_protocol;	break;
152
+	case P_ARP:	net_protocol = &arp_protocol;	break;
153
+	case P_RARP:	net_protocol = &rarp_protocol;	break;
154
+	case P_UNKNOWN:	net_protocol = NULL;		break;
155
+	default:
146
 		undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
156
 		undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
147
 		return PXENV_EXIT_FAILURE;
157
 		return PXENV_EXIT_FAILURE;
148
 	}
158
 	}
149
-	data = SEGOFF16_TO_PTR ( tbd->Xmit );
150
-	length = tbd->ImmedLength;
151
 
159
 
152
-	/* If destination is broadcast, we need to supply the MAC address */
153
-	if ( undi_transmit->XmitFlag == XMT_BROADCAST ) {
154
-		dest = broadcast_mac;
155
-	} else {
156
-		dest = SEGOFF16_TO_PTR ( undi_transmit->DestAddr );
160
+	/* Calculate total packet length */
161
+	copy_from_real ( &tbd, undi_transmit->TBD.segment,
162
+			 undi_transmit->TBD.offset, sizeof ( tbd ) );
163
+	len = tbd.ImmedLength;
164
+	for ( i = 0 ; i < tbd.DataBlkCount ; i++ ) {
165
+		datablk = &tbd.DataBlock[i];
166
+		len += datablk->TDDataLen;
157
 	}
167
 	}
158
 
168
 
159
-	/* We can't properly support P_UNKNOWN without rewriting all
160
-	 * the driver transmit() methods, so we cheat: if P_UNKNOWN is
161
-	 * specified we rip the destination address and type out of
162
-	 * the pre-assembled packet, then skip over the header.
163
-	 */
164
-	switch ( undi_transmit->Protocol ) {
165
-	case P_IP:	type = ETH_P_IP;	break;
166
-	case P_ARP:	type = ETH_P_ARP;	break;
167
-	case P_RARP:	type = ETH_P_RARP;	break;
168
-	case P_UNKNOWN:
169
-		media_header = (media_header_t*)data;
170
-		dest = media_header->dest;
171
-		type = ntohs ( media_header->nstype );
172
-		data += ETH_HLEN;
173
-		length -= ETH_HLEN;
174
-		break;
175
-	default:
176
-		undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
169
+	/* Allocate and fill I/O buffer */
170
+	iobuf = alloc_iob ( len );
171
+	if ( ! iobuf ) {
172
+		undi_transmit->Status = PXENV_STATUS_OUT_OF_RESOURCES;
177
 		return PXENV_EXIT_FAILURE;
173
 		return PXENV_EXIT_FAILURE;
178
 	}
174
 	}
175
+	copy_from_real ( iob_put ( iobuf, tbd.ImmedLength ), tbd.Xmit.segment,
176
+			 tbd.Xmit.offset, tbd.ImmedLength );
177
+	for ( i = 0 ; i < tbd.DataBlkCount ; i++ ) {
178
+		datablk = &tbd.DataBlock[i];
179
+		copy_from_real ( iob_put ( iobuf, datablk->TDDataLen ),
180
+				 datablk->TDDataPtr.segment,
181
+				 datablk->TDDataPtr.offset,
182
+				 datablk->TDDataLen );
183
+	}
179
 
184
 
180
-	/* Send the packet */
181
-	eth_transmit ( dest, type, length, data );
182
-#endif
183
-	
184
-	undi_transmit->Status = PXENV_STATUS_SUCCESS;
185
-	return PXENV_EXIT_SUCCESS;
185
+	/* Transmit packet */
186
+	if ( net_protocol == NULL ) {
187
+		/* Link-layer header already present */
188
+		rc = netdev_tx ( pxe_netdev, iobuf );
189
+	} else {
190
+		/* Calculate destination address */
191
+		if ( undi_transmit->XmitFlag == XMT_DESTADDR ) {
192
+			copy_from_real ( destaddr,
193
+					 undi_transmit->DestAddr.segment,
194
+					 undi_transmit->DestAddr.offset,
195
+					 pxe_netdev->ll_protocol->ll_addr_len );
196
+			ll_dest = destaddr;
197
+		} else {
198
+			ll_dest = pxe_netdev->ll_protocol->ll_broadcast;
199
+		}
200
+		rc = net_tx ( iobuf, pxe_netdev, net_protocol, ll_dest );
201
+	}
202
+
203
+#warning "TX completion?"
204
+
205
+	undi_transmit->Status = PXENV_STATUS ( rc );
206
+	return ( ( rc == 0 ) ? PXENV_EXIT_SUCCESS : PXENV_EXIT_FAILURE );
186
 }
207
 }
187
 
208
 
188
 /* PXENV_UNDI_SET_MCAST_ADDRESS
209
 /* PXENV_UNDI_SET_MCAST_ADDRESS
200
 
221
 
201
 /* PXENV_UNDI_SET_STATION_ADDRESS
222
 /* PXENV_UNDI_SET_STATION_ADDRESS
202
  *
223
  *
203
- * Status: working (deliberately incomplete)
224
+ * Status: working
204
  */
225
  */
205
 PXENV_EXIT_t 
226
 PXENV_EXIT_t 
206
 pxenv_undi_set_station_address ( struct s_PXENV_UNDI_SET_STATION_ADDRESS
227
 pxenv_undi_set_station_address ( struct s_PXENV_UNDI_SET_STATION_ADDRESS
207
 				 *undi_set_station_address ) {
228
 				 *undi_set_station_address ) {
229
+
208
 	DBG ( "PXENV_UNDI_SET_STATION_ADDRESS" );
230
 	DBG ( "PXENV_UNDI_SET_STATION_ADDRESS" );
209
 
231
 
210
-#if 0
211
-	/* We don't offer a facility to set the MAC address; this
212
-	 * would require adding extra code to all the Etherboot
213
-	 * drivers, for very little benefit.  If we're setting it to
214
-	 * the current value anyway then return success, otherwise
215
-	 * return UNSUPPORTED.
232
+	/* If adapter is open, the change will have no effect; return
233
+	 * an error
216
 	 */
234
 	 */
217
-	if ( memcmp ( nic.node_addr,
218
-		      &undi_set_station_address->StationAddress,
219
-		      ETH_ALEN ) == 0 ) {
220
-		undi_set_station_address->Status = PXENV_STATUS_SUCCESS;
221
-		return PXENV_EXIT_SUCCESS;
235
+	if ( pxe_netdev->state & NETDEV_OPEN ) {
236
+		undi_set_station_address->Status =
237
+			PXENV_STATUS_UNDI_INVALID_STATE;
238
+		return PXENV_EXIT_FAILURE;
222
 	}
239
 	}
223
-#endif
224
 
240
 
225
-	undi_set_station_address->Status = PXENV_STATUS_UNSUPPORTED;
226
-	return PXENV_EXIT_FAILURE;
241
+	/* Update MAC address */
242
+	memcpy ( pxe_netdev->ll_addr,
243
+		 &undi_set_station_address->StationAddress,
244
+		 pxe_netdev->ll_protocol->ll_addr_len );
245
+
246
+	undi_set_station_address = PXENV_STATUS_SUCCESS;
247
+	return PXENV_EXIT_SUCCESS;
227
 }
248
 }
228
 
249
 
229
 /* PXENV_UNDI_SET_PACKET_FILTER
250
 /* PXENV_UNDI_SET_PACKET_FILTER
248
 					  *undi_get_information ) {
269
 					  *undi_get_information ) {
249
 	struct device *dev = pxe_netdev->dev;
270
 	struct device *dev = pxe_netdev->dev;
250
 	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
271
 	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
251
-	unsigned int ioaddr;
252
-	unsigned int irqno;
253
 
272
 
254
 	DBG ( "PXENV_UNDI_GET_INFORMATION" );
273
 	DBG ( "PXENV_UNDI_GET_INFORMATION" );
255
 
274
 
256
-	switch ( dev->desc.bus_type ) {
257
-	case BUS_TYPE_PCI: {
258
-		struct pci_device *pci =
259
-			container_of ( dev, struct pci_device, dev );
260
-
261
-		ioaddr = pci->ioaddr;
262
-		irqno = pci->irq;
263
-		break; }
264
-	case BUS_TYPE_ISAPNP: {
265
-		struct isapnp_device *isapnp =
266
-			container_of ( dev, struct isapnp_device, dev );
267
-
268
-		ioaddr = isapnp->ioaddr;
269
-		irqno = isapnp->irqno;
270
-		break; }
271
-	default:
272
-		undi_get_information->Status = PXENV_STATUS_FAILURE;
273
-		return PXENV_EXIT_FAILURE;
274
-	}
275
-
276
-	undi_get_information->BaseIo = ioaddr;
277
-	undi_get_information->IntNumber = irqno;
275
+	undi_get_information->BaseIo = dev->desc.ioaddr;
276
+	undi_get_information->IntNumber = dev->desc.irq;
278
 	/* Cheat: assume all cards can cope with this */
277
 	/* Cheat: assume all cards can cope with this */
279
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
278
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
280
 	undi_get_information->HwType = ntohs ( ll_protocol->ll_proto );
279
 	undi_get_information->HwType = ntohs ( ll_protocol->ll_proto );
384
 
383
 
385
 	switch ( dev->desc.bus_type ) {
384
 	switch ( dev->desc.bus_type ) {
386
 	case BUS_TYPE_PCI: {
385
 	case BUS_TYPE_PCI: {
387
-		struct pci_device *pci =
388
-			container_of ( dev, struct pci_device, dev );
389
 		struct pci_nic_info *info = &undi_get_nic_type->info.pci;
386
 		struct pci_nic_info *info = &undi_get_nic_type->info.pci;
390
 
387
 
391
 		undi_get_nic_type->NicType = PCI_NIC;
388
 		undi_get_nic_type->NicType = PCI_NIC;
392
-		info->Vendor_ID = pci->vendor;
393
-		info->Dev_ID = pci->device;
394
-		info->Base_Class = PCI_BASE_CLASS ( pci->class );
395
-		info->Sub_Class = PCI_SUB_CLASS ( pci->class );
396
-		info->Prog_Intf = PCI_PROG_INTF ( pci->class );
397
-		info->BusDevFunc = PCI_BUSDEVFN ( pci->bus, pci->devfn );
389
+		info->Vendor_ID = dev->desc.vendor;
390
+		info->Dev_ID = dev->desc.device;
391
+		info->Base_Class = PCI_BASE_CLASS ( dev->desc.class );
392
+		info->Sub_Class = PCI_SUB_CLASS ( dev->desc.class );
393
+		info->Prog_Intf = PCI_PROG_INTF ( dev->desc.class );
394
+		info->BusDevFunc = dev->desc.location;
398
 		/* Cheat: remaining fields are probably unnecessary,
395
 		/* Cheat: remaining fields are probably unnecessary,
399
 		 * and would require adding extra code to pci.c.
396
 		 * and would require adding extra code to pci.c.
400
 		 */
397
 		 */
402
 		undi_get_nic_type->info.pci.SubDevice_ID = 0xffff;
399
 		undi_get_nic_type->info.pci.SubDevice_ID = 0xffff;
403
 		break; }
400
 		break; }
404
 	case BUS_TYPE_ISAPNP: {
401
 	case BUS_TYPE_ISAPNP: {
405
-		struct isapnp_device *isapnp =
406
-			container_of ( dev, struct isapnp_device, dev );
407
 		struct pnp_nic_info *info = &undi_get_nic_type->info.pnp;
402
 		struct pnp_nic_info *info = &undi_get_nic_type->info.pnp;
408
 
403
 
409
 		undi_get_nic_type->NicType = PnP_NIC;
404
 		undi_get_nic_type->NicType = PnP_NIC;
410
-		info->EISA_Dev_ID = ( ( isapnp->vendor_id << 16 ) |
411
-				      isapnp->prod_id );
412
-		info->CardSelNum = isapnp->csn;
405
+		info->EISA_Dev_ID = ( ( dev->desc.vendor << 16 ) |
406
+				      dev->desc.device );
407
+		info->CardSelNum = dev->desc.location;
413
 		/* Cheat: remaining fields are probably unnecessary,
408
 		/* Cheat: remaining fields are probably unnecessary,
414
 		 * and would require adding extra code to isapnp.c.
409
 		 * and would require adding extra code to isapnp.c.
415
 		 */
410
 		 */
431
 					 *undi_get_iface_info ) {
426
 					 *undi_get_iface_info ) {
432
 	DBG ( "PXENV_UNDI_GET_IFACE_INFO" );
427
 	DBG ( "PXENV_UNDI_GET_IFACE_INFO" );
433
 
428
 
434
-#if 0
435
 	/* Just hand back some info, doesn't really matter what it is.
429
 	/* Just hand back some info, doesn't really matter what it is.
436
 	 * Most PXE stacks seem to take this approach.
430
 	 * Most PXE stacks seem to take this approach.
437
 	 */
431
 	 */
438
-	sprintf ( undi_get_iface_info->IfaceType, "Etherboot" );
432
+	snprintf ( ( char * ) undi_get_iface_info->IfaceType,
433
+		   sizeof ( undi_get_iface_info->IfaceType ), "Etherboot" );
439
 	undi_get_iface_info->LinkSpeed = 10000000; /* 10 Mbps */
434
 	undi_get_iface_info->LinkSpeed = 10000000; /* 10 Mbps */
440
 	undi_get_iface_info->ServiceFlags = 0;
435
 	undi_get_iface_info->ServiceFlags = 0;
441
 	memset ( undi_get_iface_info->Reserved, 0,
436
 	memset ( undi_get_iface_info->Reserved, 0,
442
 		 sizeof(undi_get_iface_info->Reserved) );
437
 		 sizeof(undi_get_iface_info->Reserved) );
443
-#endif
444
 
438
 
445
 	undi_get_iface_info->Status = PXENV_STATUS_SUCCESS;
439
 	undi_get_iface_info->Status = PXENV_STATUS_SUCCESS;
446
 	return PXENV_EXIT_SUCCESS;
440
 	return PXENV_EXIT_SUCCESS;
463
  * Status: working
457
  * Status: working
464
  */
458
  */
465
 PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
459
 PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
460
+	struct io_buffer *iobuf;
461
+	size_t len;
462
+
466
 	DBG ( "PXENV_UNDI_ISR" );
463
 	DBG ( "PXENV_UNDI_ISR" );
467
 
464
 
468
-#if 0
469
-	/* We can't call ENSURE_READY, because this could be being
470
-	 * called as part of an interrupt service routine.  Instead,
471
-	 * we should simply die if we're not READY.
472
-	 */
473
-	if ( ( pxe_stack == NULL ) || ( pxe_stack->state < READY ) ) {
474
-		undi_isr->Status = PXENV_STATUS_UNDI_INVALID_STATE;
475
-		return PXENV_EXIT_FAILURE;
476
-	}
477
-	
478
 	/* Just in case some idiot actually looks at these fields when
465
 	/* Just in case some idiot actually looks at these fields when
479
 	 * we weren't meant to fill them in...
466
 	 * we weren't meant to fill them in...
480
 	 */
467
 	 */
486
 
473
 
487
 	switch ( undi_isr->FuncFlag ) {
474
 	switch ( undi_isr->FuncFlag ) {
488
 	case PXENV_UNDI_ISR_IN_START :
475
 	case PXENV_UNDI_ISR_IN_START :
489
-		/* Is there a packet waiting?  If so, disable
490
-		 * interrupts on the NIC and return "it's ours".  Do
491
-		 * *not* necessarily acknowledge the interrupt; this
492
-		 * can happen later when eth_poll(1) is called.  As
493
-		 * long as the interrupt is masked off so that it
494
-		 * doesn't immediately retrigger the 8259A then all
495
-		 * should be well.
496
-		 */
497
 		DBG ( " START" );
476
 		DBG ( " START" );
498
-		if ( eth_poll ( 0 ) ) {
477
+
478
+		/* Call poll().  This should acknowledge the device
479
+		 * interrupt and queue up any received packet.
480
+		 */
481
+		if ( netdev_poll ( pxe_netdev, -1U ) ) {
482
+			/* Packet waiting in queue */
499
 			DBG ( " OURS" );
483
 			DBG ( " OURS" );
500
-			eth_irq ( DISABLE );
501
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_OURS;
484
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_OURS;
502
 		} else {
485
 		} else {
503
 			DBG ( " NOT_OURS" );
486
 			DBG ( " NOT_OURS" );
505
 		}
488
 		}
506
 		break;
489
 		break;
507
 	case PXENV_UNDI_ISR_IN_PROCESS :
490
 	case PXENV_UNDI_ISR_IN_PROCESS :
508
-		/* Call poll(), return packet.  If no packet, return "done".
509
-		 */
510
-		DBG ( " PROCESS" );
511
-		if ( eth_poll ( 1 ) ) {
512
-			DBG ( " RECEIVE %d", nic.packetlen );
513
-			if ( nic.packetlen > sizeof(pxe_stack->packet) ) {
514
-				/* Should never happen */
515
-				undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
516
-				undi_isr->Status =
517
-					PXENV_STATUS_OUT_OF_RESOURCES;
518
-				return PXENV_EXIT_FAILURE;
519
-			}
520
-			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_RECEIVE;
521
-			undi_isr->BufferLength = nic.packetlen;
522
-			undi_isr->FrameLength = nic.packetlen;
523
-			undi_isr->FrameHeaderLength = ETH_HLEN;
524
-			memcpy ( pxe_stack->packet, nic.packet, nic.packetlen);
525
-			PTR_TO_SEGOFF16 ( pxe_stack->packet, undi_isr->Frame );
526
-			switch ( ntohs(media_header->nstype) ) {
527
-			case ETH_P_IP:	undi_isr->ProtType = P_IP;	break;
528
-			case ETH_P_ARP:	undi_isr->ProtType = P_ARP;	break;
529
-			case ETH_P_RARP: undi_isr->ProtType = P_RARP;	break;
530
-			default :	undi_isr->ProtType = P_UNKNOWN;
531
-			}
532
-			if ( memcmp ( media_header->dest, broadcast_mac,
533
-				      sizeof(broadcast_mac) ) ) {
534
-				undi_isr->PktType = XMT_BROADCAST;
535
-			} else {
536
-				undi_isr->PktType = XMT_DESTADDR;
537
-			}
491
+	case PXENV_UNDI_ISR_IN_GET_NEXT :
492
+		DBG ( " PROCESS/GET_NEXT" );
493
+		
494
+		/* Remove first packet from netdev RX queue */
495
+		iobuf = netdev_rx_dequeue ( pxe_netdev );
496
+		if ( ! iobuf ) {
497
+			/* No more packets remaining */
498
+			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
538
 			break;
499
 			break;
539
-		} else {
540
-			/* No break - fall through to IN_GET_NEXT */
541
 		}
500
 		}
542
-	case PXENV_UNDI_ISR_IN_GET_NEXT :
543
-		/* We only ever return one frame at a time */
544
-		DBG ( " GET_NEXT DONE" );
545
-		/* Re-enable interrupts */
546
-		eth_irq ( ENABLE );
547
-		/* Force an interrupt if there's a packet still
548
-		 * waiting, since we only handle one packet per
549
-		 * interrupt.
550
-		 */
551
-		if ( eth_poll ( 0 ) ) {
552
-			DBG ( " (RETRIGGER)" );
553
-			eth_irq ( FORCE );
501
+
502
+		/* Copy packet to base memory buffer */
503
+		len = iob_len ( iobuf );
504
+		DBG ( " RECEIVE %zd", len );
505
+		if ( len > sizeof ( basemem_packet ) ) {
506
+			/* Should never happen */
507
+			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
508
+			undi_isr->Status = PXENV_STATUS_OUT_OF_RESOURCES;
509
+			return PXENV_EXIT_FAILURE;
554
 		}
510
 		}
555
-		undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
511
+		memcpy ( basemem_packet, iobuf->data, len );
512
+
513
+		undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_RECEIVE;
514
+		undi_isr->BufferLength = len;
515
+		undi_isr->FrameLength = len;
516
+		undi_isr->FrameHeaderLength =
517
+			pxe_netdev->ll_protocol->ll_header_len;
518
+		undi_isr->Frame.segment = rm_ds;
519
+		undi_isr->Frame.offset =
520
+			( ( unsigned ) & __from_data16 ( basemem_packet ) );
521
+		/* Probably ought to fill in packet type */
522
+		undi_isr->ProtType = P_UNKNOWN;
523
+		undi_isr->PktType = XMT_DESTADDR;
556
 		break;
524
 		break;
557
 	default :
525
 	default :
526
+		DBG ( " INVALID(%04x)", undi_isr->FuncFlag );
527
+
558
 		/* Should never happen */
528
 		/* Should never happen */
559
 		undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
529
 		undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
560
 		undi_isr->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
530
 		undi_isr->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
561
 		return PXENV_EXIT_FAILURE;
531
 		return PXENV_EXIT_FAILURE;
562
 	}
532
 	}
563
-#endif
564
 
533
 
565
 	undi_isr->Status = PXENV_STATUS_SUCCESS;
534
 	undi_isr->Status = PXENV_STATUS_SUCCESS;
566
 	return PXENV_EXIT_SUCCESS;
535
 	return PXENV_EXIT_SUCCESS;

+ 1
- 2
src/net/arp.c View File

281
  *
281
  *
282
  * This operation is meaningless for the ARP protocol.
282
  * This operation is meaningless for the ARP protocol.
283
  */
283
  */
284
-static const char *
285
-arp_ntoa ( const void *net_addr __attribute__ (( unused )) ) {
284
+static const char * arp_ntoa ( const void *net_addr __unused ) {
286
 	return "<ARP>";
285
 	return "<ARP>";
287
 }
286
 }
288
 
287
 

+ 1
- 0
src/net/ethernet.c View File

108
 	.name		= "Ethernet",
108
 	.name		= "Ethernet",
109
 	.ll_proto	= htons ( ARPHRD_ETHER ),
109
 	.ll_proto	= htons ( ARPHRD_ETHER ),
110
 	.ll_addr_len	= ETH_ALEN,
110
 	.ll_addr_len	= ETH_ALEN,
111
+	.ll_header_len	= ETH_HLEN,
111
 	.ll_broadcast	= eth_broadcast,
112
 	.ll_broadcast	= eth_broadcast,
112
 	.tx		= eth_tx,
113
 	.tx		= eth_tx,
113
 	.rx		= eth_rx,
114
 	.rx		= eth_rx,

+ 68
- 0
src/net/rarp.c View File

1
+/*
2
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdint.h>
20
+#include <byteswap.h>
21
+#include <gpxe/netdevice.h>
22
+#include <gpxe/iobuf.h>
23
+#include <gpxe/if_ether.h>
24
+#include <gpxe/rarp.h>
25
+
26
+/** @file
27
+ *
28
+ * Reverse Address Resolution Protocol
29
+ *
30
+ */
31
+
32
+/**
33
+ * Process incoming ARP packets
34
+ *
35
+ * @v iobuf		I/O buffer
36
+ * @v netdev		Network device
37
+ * @v ll_source		Link-layer source address
38
+ * @ret rc		Return status code
39
+ *
40
+ * This is a dummy method which simply discards RARP packets.
41
+ */
42
+static int rarp_rx ( struct io_buffer *iobuf,
43
+		     struct net_device *netdev __unused,
44
+		     const void *ll_source __unused ) {
45
+	free_iob ( iobuf );
46
+	return 0;
47
+}
48
+
49
+
50
+/**
51
+ * Transcribe RARP address
52
+ *
53
+ * @v net_addr	RARP address
54
+ * @ret string	"<RARP>"
55
+ *
56
+ * This operation is meaningless for the RARP protocol.
57
+ */
58
+static const char * rarp_ntoa ( const void *net_addr __unused ) {
59
+	return "<RARP>";
60
+}
61
+
62
+/** RARP protocol */
63
+struct net_protocol rarp_protocol __net_protocol = {
64
+	.name = "RARP",
65
+	.net_proto = htons ( ETH_P_RARP ),
66
+	.rx = rarp_rx,
67
+	.ntoa = rarp_ntoa,
68
+};

Loading…
Cancel
Save