|
@@ -22,6 +22,13 @@
|
22
|
22
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
23
|
23
|
*/
|
24
|
24
|
|
|
25
|
+#include <stdint.h>
|
|
26
|
+#include <string.h>
|
|
27
|
+#include <gpxe/netdevice.h>
|
|
28
|
+#include <gpxe/device.h>
|
|
29
|
+#include <gpxe/pci.h>
|
|
30
|
+#include <gpxe/isapnp.h>
|
|
31
|
+#include <gpxe/if_ether.h>
|
25
|
32
|
#include "pxe.h"
|
26
|
33
|
|
27
|
34
|
/* PXENV_UNDI_STARTUP
|
|
@@ -236,24 +243,49 @@ pxenv_undi_set_packet_filter ( struct s_PXENV_UNDI_SET_PACKET_FILTER
|
236
|
243
|
*/
|
237
|
244
|
PXENV_EXIT_t pxenv_undi_get_information ( struct s_PXENV_UNDI_GET_INFORMATION
|
238
|
245
|
*undi_get_information ) {
|
|
246
|
+ struct device *dev = pxe_netdev->dev;
|
|
247
|
+ struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
|
|
248
|
+ unsigned int ioaddr;
|
|
249
|
+ unsigned int irqno;
|
|
250
|
+
|
239
|
251
|
DBG ( "PXENV_UNDI_GET_INFORMATION" );
|
240
|
252
|
|
241
|
|
-#if 0
|
242
|
|
- undi_get_information->BaseIo = nic.ioaddr;
|
243
|
|
- undi_get_information->IntNumber = nic.irqno;
|
|
253
|
+ switch ( dev->desc.bus_type ) {
|
|
254
|
+ case BUS_TYPE_PCI: {
|
|
255
|
+ struct pci_device *pci =
|
|
256
|
+ container_of ( dev, struct pci_device, dev );
|
|
257
|
+
|
|
258
|
+ ioaddr = pci->ioaddr;
|
|
259
|
+ irqno = pci->irq;
|
|
260
|
+ break; }
|
|
261
|
+ case BUS_TYPE_ISAPNP: {
|
|
262
|
+ struct isapnp_device *isapnp =
|
|
263
|
+ container_of ( dev, struct isapnp_device, dev );
|
|
264
|
+
|
|
265
|
+ ioaddr = isapnp->ioaddr;
|
|
266
|
+ irqno = isapnp->irqno;
|
|
267
|
+ break; }
|
|
268
|
+ default:
|
|
269
|
+ undi_get_information->Status = PXENV_STATUS_FAILURE;
|
|
270
|
+ return PXENV_EXIT_FAILURE;
|
|
271
|
+ }
|
|
272
|
+
|
|
273
|
+ undi_get_information->BaseIo = ioaddr;
|
|
274
|
+ undi_get_information->IntNumber = irqno;
|
244
|
275
|
/* Cheat: assume all cards can cope with this */
|
245
|
276
|
undi_get_information->MaxTranUnit = ETH_MAX_MTU;
|
246
|
|
- /* Cheat: we only ever have Ethernet cards */
|
247
|
|
- undi_get_information->HwType = ETHER_TYPE;
|
248
|
|
- undi_get_information->HwAddrLen = ETH_ALEN;
|
|
277
|
+ undi_get_information->HwType = ntohs ( ll_protocol->ll_proto );
|
|
278
|
+ undi_get_information->HwAddrLen = ll_protocol->ll_addr_len;
|
249
|
279
|
/* Cheat: assume card is always configured with its permanent
|
250
|
280
|
* node address. This is a valid assumption within Etherboot
|
251
|
281
|
* at the time of writing.
|
252
|
282
|
*/
|
253
|
|
- memcpy ( &undi_get_information->CurrentNodeAddress, nic.node_addr,
|
254
|
|
- ETH_ALEN );
|
255
|
|
- memcpy ( &undi_get_information->PermNodeAddress, nic.node_addr,
|
256
|
|
- ETH_ALEN );
|
|
283
|
+ memcpy ( &undi_get_information->CurrentNodeAddress,
|
|
284
|
+ pxe_netdev->ll_addr,
|
|
285
|
+ sizeof ( undi_get_information->CurrentNodeAddress ) );
|
|
286
|
+ memcpy ( &undi_get_information->PermNodeAddress,
|
|
287
|
+ pxe_netdev->ll_addr,
|
|
288
|
+ sizeof ( undi_get_information->PermNodeAddress ) );
|
257
|
289
|
undi_get_information->ROMAddress = 0;
|
258
|
290
|
/* nic.rom_info->rom_segment; */
|
259
|
291
|
/* We only provide the ability to receive or transmit a single
|
|
@@ -261,7 +293,6 @@ PXENV_EXIT_t pxenv_undi_get_information ( struct s_PXENV_UNDI_GET_INFORMATION
|
261
|
293
|
*/
|
262
|
294
|
undi_get_information->RxBufCt = 1;
|
263
|
295
|
undi_get_information->TxBufCt = 1;
|
264
|
|
-#endif
|
265
|
296
|
|
266
|
297
|
undi_get_information->Status = PXENV_STATUS_SUCCESS;
|
267
|
298
|
return PXENV_EXIT_SUCCESS;
|
|
@@ -341,50 +372,52 @@ pxenv_undi_get_mcast_address ( struct s_PXENV_UNDI_GET_MCAST_ADDRESS
|
341
|
372
|
*/
|
342
|
373
|
PXENV_EXIT_t pxenv_undi_get_nic_type ( struct s_PXENV_UNDI_GET_NIC_TYPE
|
343
|
374
|
*undi_get_nic_type ) {
|
|
375
|
+ struct device *dev = pxe_netdev->dev;
|
|
376
|
+
|
344
|
377
|
DBG ( "PXENV_UNDI_GET_NIC_TYPE" );
|
345
|
378
|
|
346
|
|
-#warning "device probing mechanism has changed completely"
|
347
|
|
-#if 0
|
348
|
|
- struct dev *dev = &dev;
|
349
|
|
- if ( dev->to_probe == PROBE_PCI ) {
|
350
|
|
- struct pci_device *pci = &dev->state.pci.dev;
|
|
379
|
+ memset ( &undi_get_nic_type->info, 0,
|
|
380
|
+ sizeof ( undi_get_nic_type->info ) );
|
|
381
|
+
|
|
382
|
+ switch ( dev->desc.bus_type ) {
|
|
383
|
+ case BUS_TYPE_PCI: {
|
|
384
|
+ struct pci_device *pci =
|
|
385
|
+ container_of ( dev, struct pci_device, dev );
|
|
386
|
+ struct pci_nic_info *info = &undi_get_nic_type->info.pci;
|
351
|
387
|
|
352
|
388
|
undi_get_nic_type->NicType = PCI_NIC;
|
353
|
|
- undi_get_nic_type->info.pci.Vendor_ID = pci->vendor;
|
354
|
|
- undi_get_nic_type->info.pci.Dev_ID = pci->dev_id;
|
355
|
|
- undi_get_nic_type->info.pci.Base_Class = pci->class >> 8;
|
356
|
|
- undi_get_nic_type->info.pci.Sub_Class = pci->class & 0xff;
|
357
|
|
- undi_get_nic_type->info.pci.BusDevFunc =
|
358
|
|
- ( pci->bus << 8 ) | pci->devfn;
|
359
|
|
- /* Cheat: these fields are probably unnecessary, and
|
360
|
|
- * would require adding extra code to pci.c.
|
|
389
|
+ info->Vendor_ID = pci->vendor;
|
|
390
|
+ info->Dev_ID = pci->device;
|
|
391
|
+ info->Base_Class = PCI_BASE_CLASS ( pci->class );
|
|
392
|
+ info->Sub_Class = PCI_SUB_CLASS ( pci->class );
|
|
393
|
+ info->Prog_Intf = PCI_PROG_INTF ( pci->class );
|
|
394
|
+ info->BusDevFunc = PCI_BUSDEVFN ( pci->bus, pci->devfn );
|
|
395
|
+ /* Cheat: remaining fields are probably unnecessary,
|
|
396
|
+ * and would require adding extra code to pci.c.
|
361
|
397
|
*/
|
362
|
|
- undi_get_nic_type->info.pci.Prog_Intf = 0;
|
363
|
|
- undi_get_nic_type->info.pci.Rev = 0;
|
364
|
398
|
undi_get_nic_type->info.pci.SubVendor_ID = 0xffff;
|
365
|
399
|
undi_get_nic_type->info.pci.SubDevice_ID = 0xffff;
|
366
|
|
- } else if ( dev->to_probe == PROBE_ISA ) {
|
367
|
|
- /* const struct isa_driver *isa = dev->state.isa.driver; */
|
|
400
|
+ break; }
|
|
401
|
+ case BUS_TYPE_ISAPNP: {
|
|
402
|
+ struct isapnp_device *isapnp =
|
|
403
|
+ container_of ( dev, struct isapnp_device, dev );
|
|
404
|
+ struct pnp_nic_info *info = &undi_get_nic_type->info.pnp;
|
368
|
405
|
|
369
|
406
|
undi_get_nic_type->NicType = PnP_NIC;
|
370
|
|
- /* Don't think anything fills these fields in, and
|
371
|
|
- * probably no-one will ever be interested in them.
|
372
|
|
- */
|
373
|
|
- undi_get_nic_type->info.pnp.EISA_Dev_ID = 0;
|
374
|
|
- undi_get_nic_type->info.pnp.Base_Class = 0;
|
375
|
|
- undi_get_nic_type->info.pnp.Sub_Class = 0;
|
376
|
|
- undi_get_nic_type->info.pnp.Prog_Intf = 0;
|
377
|
|
- undi_get_nic_type->info.pnp.CardSelNum = 0;
|
378
|
|
- } else {
|
379
|
|
- /* PXESPEC: There doesn't seem to be an "unknown type"
|
380
|
|
- * defined.
|
|
407
|
+ info->EISA_Dev_ID = ( ( isapnp->vendor_id << 16 ) |
|
|
408
|
+ isapnp->prod_id );
|
|
409
|
+ info->CardSelNum = isapnp->csn;
|
|
410
|
+ /* Cheat: remaining fields are probably unnecessary,
|
|
411
|
+ * and would require adding extra code to isapnp.c.
|
381
|
412
|
*/
|
382
|
|
- undi_get_nic_type->NicType = 0;
|
|
413
|
+ break; }
|
|
414
|
+ default:
|
|
415
|
+ undi_get_nic_type->Status = PXENV_STATUS_FAILURE;
|
|
416
|
+ return PXENV_EXIT_FAILURE;
|
383
|
417
|
}
|
|
418
|
+
|
384
|
419
|
undi_get_nic_type->Status = PXENV_STATUS_SUCCESS;
|
385
|
420
|
return PXENV_EXIT_SUCCESS;
|
386
|
|
-
|
387
|
|
-#endif
|
388
|
421
|
}
|
389
|
422
|
|
390
|
423
|
/* PXENV_UNDI_GET_IFACE_INFO
|