Преглед на файлове

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

tags/v0.9.3
Marty Connor преди 17 години
родител
ревизия
0297a63877

src/arch/i386/core/dhcp_basemem.c → src/arch/i386/core/basemem_packet.c Целия файл

@@ -19,11 +19,12 @@
19 19
 /**
20 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 Целия файл

@@ -22,6 +22,7 @@
22 22
 #include <pic8259.h>
23 23
 #include <biosint.h>
24 24
 #include <pnpbios.h>
25
+#include <basemem_packet.h>
25 26
 #include <gpxe/iobuf.h>
26 27
 #include <gpxe/netdevice.h>
27 28
 #include <gpxe/if_ether.h>
@@ -314,13 +315,6 @@ static int undinet_isr_triggered ( void ) {
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 318
 /** UNDI transmit buffer descriptor */
325 319
 static struct s_PXENV_UNDI_TBD __data16 ( undinet_tbd );
326 320
 #define undinet_tbd __use_data16 ( undinet_tbd )
@@ -340,9 +334,9 @@ static int undinet_transmit ( struct net_device *netdev,
340 334
 	int rc;
341 335
 
342 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 341
 	/* Create PXENV_UNDI_TRANSMIT data structure */
348 342
 	memset ( &undi_transmit, 0, sizeof ( undi_transmit ) );
@@ -357,7 +351,7 @@ static int undinet_transmit ( struct net_device *netdev,
357 351
 	undinet_tbd.ImmedLength = len;
358 352
 	undinet_tbd.Xmit.segment = rm_ds;
359 353
 	undinet_tbd.Xmit.offset 
360
-		= ( ( unsigned ) & __from_data16 ( undinet_iob ) );
354
+		= ( ( unsigned ) & __from_data16 ( basemem_packet ) );
361 355
 
362 356
 	/* Issue PXE API call */
363 357
 	if ( ( rc = undinet_call ( undinic, PXENV_UNDI_TRANSMIT,

+ 5
- 5
src/arch/i386/image/nbi.c Целия файл

@@ -3,7 +3,7 @@
3 3
 #include <realmode.h>
4 4
 #include <gateA20.h>
5 5
 #include <memsizes.h>
6
-#include <dhcp_basemem.h>
6
+#include <basemem_packet.h>
7 7
 #include <gpxe/uaccess.h>
8 8
 #include <gpxe/segment.h>
9 9
 #include <gpxe/shutdown.h>
@@ -321,7 +321,7 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
321 321
 		  "=b" ( discard_b )
322 322
 		: "D" ( imgheader->execaddr.segoff ),
323 323
 		  "S" ( imgheader->location ),
324
-		  "b" ( __from_data16 ( dhcp_basemem ) )
324
+		  "b" ( __from_data16 ( basemem_packet ) )
325 325
 		: "ecx", "edx", "ebp" );
326 326
 
327 327
 	gateA20_set();
@@ -356,7 +356,7 @@ static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) {
356 356
 		: "D" ( imgheader->execaddr.linear ),
357 357
 		  "S" ( ( imgheader->location.segment << 4 ) +
358 358
 			imgheader->location.offset ),
359
-		  "b" ( virt_to_phys ( dhcp_basemem ) ),
359
+		  "b" ( virt_to_phys ( basemem_packet ) ),
360 360
 		  "a" ( virt_to_phys ( &loaderinfo ) )
361 361
 		: "ecx", "edx", "ebp", "memory" );
362 362
 
@@ -397,8 +397,8 @@ static int nbi_prepare_dhcp ( struct image *image ) {
397 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 402
 					 &dhcppkt ) ) != 0 ) {
403 403
 		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
404 404
 		return rc;

+ 10
- 2
src/arch/i386/image/pxe_image.c Целия файл

@@ -40,6 +40,7 @@ struct image_type pxe_image_type __image_type ( PROBE_PXE );
40 40
  */
41 41
 static int pxe_exec ( struct image *image __unused ) {
42 42
 	struct net_device *netdev;
43
+	int rc;
43 44
 
44 45
 	/* Ensure that PXE stack is ready to use */
45 46
 	pxe_init_structures();
@@ -47,11 +48,18 @@ static int pxe_exec ( struct image *image __unused ) {
47 48
 
48 49
 	/* Arbitrarily pick the first open network device to use for PXE */
49 50
 	for_each_netdev ( netdev ) {
50
-		pxe_netdev = netdev;
51
+		pxe_set_netdev ( netdev );
51 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 Целия файл

@@ -0,0 +1,13 @@
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 Целия файл

@@ -1,13 +0,0 @@
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 Целия файл

@@ -705,6 +705,8 @@ static int isapnpbus_probe ( struct root_device *rootdev ) {
705 705
 			isapnp->dev.desc.bus_type = BUS_TYPE_ISAPNP;
706 706
 			isapnp->dev.desc.vendor = isapnp->vendor_id;
707 707
 			isapnp->dev.desc.device = isapnp->prod_id;
708
+			isapnp->dev.desc.ioaddr = isapnp->ioaddr;
709
+			isapnp->dev.desc.irq = isapnp->irqno;
708 710
 			isapnp->dev.parent = &rootdev->dev;
709 711
 			list_add ( &isapnp->dev.siblings,
710 712
 				   &rootdev->dev.children );

+ 3
- 0
src/drivers/bus/pci.c Целия файл

@@ -286,6 +286,9 @@ static int pcibus_probe ( struct root_device *rootdev ) {
286 286
 			pci->dev.desc.location = PCI_BUSDEVFN (bus, devfn);
287 287
 			pci->dev.desc.vendor = pci->vendor;
288 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 292
 			pci->dev.parent = &rootdev->dev;
290 293
 			list_add ( &pci->dev.siblings, &rootdev->dev.children);
291 294
 			INIT_LIST_HEAD ( &pci->dev.children );

+ 2
- 0
src/include/gpxe/arp.h Целия файл

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

+ 6
- 0
src/include/gpxe/device.h Целия файл

@@ -27,6 +27,12 @@ struct device_description {
27 27
 	unsigned int vendor;
28 28
 	/** Device ID */
29 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 38
 /** PCI bus type */

+ 2
- 0
src/include/gpxe/netdevice.h Целия файл

@@ -122,6 +122,8 @@ struct ll_protocol {
122 122
 	uint16_t ll_proto;
123 123
 	/** Link-layer address length */
124 124
 	uint8_t ll_addr_len;
125
+	/** Link-layer header length */
126
+	uint8_t ll_header_len;
125 127
 	/** Link-layer broadcast address */
126 128
 	const uint8_t *ll_broadcast;
127 129
 };

+ 14
- 0
src/include/gpxe/rarp.h Целия файл

@@ -0,0 +1,14 @@
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 Целия файл

@@ -137,4 +137,6 @@ struct pcir_header {
137 137
 
138 138
 extern struct net_device *pxe_netdev;
139 139
 
140
+extern void pxe_set_netdev ( struct net_device *netdev );
141
+
140 142
 #endif /* PXE_H */

+ 14
- 2
src/interface/pxe/pxe.c Целия файл

@@ -22,12 +22,24 @@
22 22
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 23
  */
24 24
 
25
-#include "dev.h"
25
+#include <gpxe/netdevice.h>
26 26
 #include "pxe.h"
27 27
 
28
-#warning "pxe_netdev should hold a persistent reference to the net device"
29 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 43
 #if 0
32 44
 
33 45
 /* Global pointer to currently installed PXE stack */

+ 3
- 3
src/interface/pxe/pxe_preboot.c Целия файл

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

+ 134
- 165
src/interface/pxe/pxe_undi.c Целия файл

@@ -23,12 +23,18 @@
23 23
  */
24 24
 
25 25
 #include <stdint.h>
26
+#include <stdio.h>
26 27
 #include <string.h>
28
+#include <byteswap.h>
29
+#include <basemem_packet.h>
27 30
 #include <gpxe/netdevice.h>
31
+#include <gpxe/iobuf.h>
28 32
 #include <gpxe/device.h>
29 33
 #include <gpxe/pci.h>
30
-#include <gpxe/isapnp.h>
31 34
 #include <gpxe/if_ether.h>
35
+#include <gpxe/ip.h>
36
+#include <gpxe/arp.h>
37
+#include <gpxe/rarp.h>
32 38
 #include <gpxe/shutdown.h>
33 39
 #include "pxe.h"
34 40
 
@@ -128,61 +134,76 @@ PXENV_EXIT_t pxenv_undi_close ( struct s_PXENV_UNDI_CLOSE *undi_close ) {
128 134
  */
129 135
 PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
130 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 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 156
 		undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
147 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 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 209
 /* PXENV_UNDI_SET_MCAST_ADDRESS
@@ -200,30 +221,30 @@ pxenv_undi_set_mcast_address ( struct s_PXENV_UNDI_SET_MCAST_ADDRESS
200 221
 
201 222
 /* PXENV_UNDI_SET_STATION_ADDRESS
202 223
  *
203
- * Status: working (deliberately incomplete)
224
+ * Status: working
204 225
  */
205 226
 PXENV_EXIT_t 
206 227
 pxenv_undi_set_station_address ( struct s_PXENV_UNDI_SET_STATION_ADDRESS
207 228
 				 *undi_set_station_address ) {
229
+
208 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 250
 /* PXENV_UNDI_SET_PACKET_FILTER
@@ -248,33 +269,11 @@ PXENV_EXIT_t pxenv_undi_get_information ( struct s_PXENV_UNDI_GET_INFORMATION
248 269
 					  *undi_get_information ) {
249 270
 	struct device *dev = pxe_netdev->dev;
250 271
 	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
251
-	unsigned int ioaddr;
252
-	unsigned int irqno;
253 272
 
254 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 277
 	/* Cheat: assume all cards can cope with this */
279 278
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
280 279
 	undi_get_information->HwType = ntohs ( ll_protocol->ll_proto );
@@ -384,17 +383,15 @@ PXENV_EXIT_t pxenv_undi_get_nic_type ( struct s_PXENV_UNDI_GET_NIC_TYPE
384 383
 
385 384
 	switch ( dev->desc.bus_type ) {
386 385
 	case BUS_TYPE_PCI: {
387
-		struct pci_device *pci =
388
-			container_of ( dev, struct pci_device, dev );
389 386
 		struct pci_nic_info *info = &undi_get_nic_type->info.pci;
390 387
 
391 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 395
 		/* Cheat: remaining fields are probably unnecessary,
399 396
 		 * and would require adding extra code to pci.c.
400 397
 		 */
@@ -402,14 +399,12 @@ PXENV_EXIT_t pxenv_undi_get_nic_type ( struct s_PXENV_UNDI_GET_NIC_TYPE
402 399
 		undi_get_nic_type->info.pci.SubDevice_ID = 0xffff;
403 400
 		break; }
404 401
 	case BUS_TYPE_ISAPNP: {
405
-		struct isapnp_device *isapnp =
406
-			container_of ( dev, struct isapnp_device, dev );
407 402
 		struct pnp_nic_info *info = &undi_get_nic_type->info.pnp;
408 403
 
409 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 408
 		/* Cheat: remaining fields are probably unnecessary,
414 409
 		 * and would require adding extra code to isapnp.c.
415 410
 		 */
@@ -431,16 +426,15 @@ PXENV_EXIT_t pxenv_undi_get_iface_info ( struct s_PXENV_UNDI_GET_IFACE_INFO
431 426
 					 *undi_get_iface_info ) {
432 427
 	DBG ( "PXENV_UNDI_GET_IFACE_INFO" );
433 428
 
434
-#if 0
435 429
 	/* Just hand back some info, doesn't really matter what it is.
436 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 434
 	undi_get_iface_info->LinkSpeed = 10000000; /* 10 Mbps */
440 435
 	undi_get_iface_info->ServiceFlags = 0;
441 436
 	memset ( undi_get_iface_info->Reserved, 0,
442 437
 		 sizeof(undi_get_iface_info->Reserved) );
443
-#endif
444 438
 
445 439
 	undi_get_iface_info->Status = PXENV_STATUS_SUCCESS;
446 440
 	return PXENV_EXIT_SUCCESS;
@@ -463,18 +457,11 @@ PXENV_EXIT_t pxenv_undi_get_state ( struct s_PXENV_UNDI_GET_STATE
463 457
  * Status: working
464 458
  */
465 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 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 465
 	/* Just in case some idiot actually looks at these fields when
479 466
 	 * we weren't meant to fill them in...
480 467
 	 */
@@ -486,18 +473,14 @@ PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
486 473
 
487 474
 	switch ( undi_isr->FuncFlag ) {
488 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 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 483
 			DBG ( " OURS" );
500
-			eth_irq ( DISABLE );
501 484
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_OURS;
502 485
 		} else {
503 486
 			DBG ( " NOT_OURS" );
@@ -505,62 +488,48 @@ PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
505 488
 		}
506 489
 		break;
507 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 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 524
 		break;
557 525
 	default :
526
+		DBG ( " INVALID(%04x)", undi_isr->FuncFlag );
527
+
558 528
 		/* Should never happen */
559 529
 		undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
560 530
 		undi_isr->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
561 531
 		return PXENV_EXIT_FAILURE;
562 532
 	}
563
-#endif
564 533
 
565 534
 	undi_isr->Status = PXENV_STATUS_SUCCESS;
566 535
 	return PXENV_EXIT_SUCCESS;

+ 1
- 2
src/net/arp.c Целия файл

@@ -281,8 +281,7 @@ static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev,
281 281
  *
282 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 285
 	return "<ARP>";
287 286
 }
288 287
 

+ 1
- 0
src/net/ethernet.c Целия файл

@@ -108,6 +108,7 @@ struct ll_protocol ethernet_protocol __ll_protocol = {
108 108
 	.name		= "Ethernet",
109 109
 	.ll_proto	= htons ( ARPHRD_ETHER ),
110 110
 	.ll_addr_len	= ETH_ALEN,
111
+	.ll_header_len	= ETH_HLEN,
111 112
 	.ll_broadcast	= eth_broadcast,
112 113
 	.tx		= eth_tx,
113 114
 	.rx		= eth_rx,

+ 68
- 0
src/net/rarp.c Целия файл

@@ -0,0 +1,68 @@
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…
Отказ
Запис