Browse Source

added polling and transmit. eeprom access still remaining

tags/v0.9.3
Udayan Kumar 18 years ago
parent
commit
c8f6207e7e
1 changed files with 167 additions and 134 deletions
  1. 167
    134
      src/drivers/net/natsemi.c

+ 167
- 134
src/drivers/net/natsemi.c View File

36
 
36
 
37
 struct natsemi_nic {
37
 struct natsemi_nic {
38
 	unsigned short ioaddr;
38
 	unsigned short ioaddr;
39
-	unsigned short tx_next;
39
+	unsigned short tx_cur;
40
+	unsigned short tx_dirty;
41
+	unsigned short rx_cur;
40
 	struct natsemi_tx tx[TX_RING_SIZE];
42
 	struct natsemi_tx tx[TX_RING_SIZE];
41
 	struct natsemi_rx rx[NUM_RX_DESC];
43
 	struct natsemi_rx rx[NUM_RX_DESC];
44
+	/* need to add iobuf as we cannot free iobuf->data in close without this 
45
+	 * alternatively substracting sizeof(head) and sizeof(list_head) can also 
46
+	 * give the same.*/
47
+	struct io_buffer *iobuf[NUM_RX_DESC];
42
 	struct spi_bit_basher spibit;
48
 	struct spi_bit_basher spibit;
43
 	struct spi_device eeprom;
49
 	struct spi_device eeprom;
44
 	struct nvo_block nvo;
50
 	struct nvo_block nvo;
54
 #define RX_BUF_LEN    8192   /*buffer size should be multiple of 32 */ 
60
 #define RX_BUF_LEN    8192   /*buffer size should be multiple of 32 */ 
55
 #define RX_BUF_PAD 4
61
 #define RX_BUF_PAD 4
56
 #define RX_BUF_SIZE 1536
62
 #define RX_BUF_SIZE 1536
57
-
63
+#define OWN       0x80000000
64
+#define DSIZE     0x00000FFF
65
+#define CRC_SIZE  4
58
 
66
 
59
 /* NATSEMI: Offsets to the device registers.
67
 /* NATSEMI: Offsets to the device registers.
60
    Unlike software-only systems, device drivers interact with complex hardware.
68
    Unlike software-only systems, device drivers interact with complex hardware.
208
  *
216
  *
209
  * @v NAT		NATSEMI NIC
217
  * @v NAT		NATSEMI NIC
210
  */
218
  */
211
- void nat_init_eeprom ( struct natsemi_nic *nat ) {
219
+ void rtl_init_eeprom ( struct natsemi_nic *rtl ) {
212
 	int ee9356;
220
 	int ee9356;
213
 	int vpd;
221
 	int vpd;
214
 
222
 
215
 	/* Initialise three-wire bus */
223
 	/* Initialise three-wire bus */
216
-	nat->spibit.basher.op = &rtl_basher_ops;
224
+	rtl->spibit.basher.op = &rtl_basher_ops;
217
 	rtl->spibit.bus.mode = SPI_MODE_THREEWIRE;
225
 	rtl->spibit.bus.mode = SPI_MODE_THREEWIRE;
218
 	init_spi_bit_basher ( &rtl->spibit );
226
 	init_spi_bit_basher ( &rtl->spibit );
219
 
227
 
241
 /**
249
 /**
242
  * Reset NIC
250
  * Reset NIC
243
  *
251
  *
244
- * @v rtl		NATSEMI NIC
252
+ * @v		NATSEMI NIC
245
  *
253
  *
246
  * Issues a hardware reset and waits for the reset to complete.
254
  * Issues a hardware reset and waits for the reset to complete.
247
  */
255
  */
248
 static void nat_reset ( struct nat_nic *nat ) {
256
 static void nat_reset ( struct nat_nic *nat ) {
249
 
257
 
258
+	int i;
250
 	/* Reset chip */
259
 	/* Reset chip */
251
 	outb ( ChipReset, nat->ioaddr + ChipCmd );
260
 	outb ( ChipReset, nat->ioaddr + ChipCmd );
252
 	mdelay ( 10 );
261
 	mdelay ( 10 );
253
-	memset ( &nat->tx, 0, sizeof ( nat->tx ) );
254
-	nat->rx.offset = 0;
262
+	nat->tx_dirty=0;
263
+	nat->tx_cur=0;
264
+	for(i=0;i<TX_RING_SIZE;i++)
265
+	{
266
+		nat->tx[i].link=0;
267
+		nat->tx[i].cmdsts=0;
268
+		nat->tx[i].bufptr=0;
269
+	}
270
+	nat->rx_cur = 0;
271
+	outl(virt_to_bus(&nat->tx[0]),nat->ioaddr+TxRingPtr);
272
+	outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
273
+
274
+	outl(TxOff|RxOff, nat->ioaddr + ChipCmd);
255
 
275
 
256
 	/* Restore PME enable bit */
276
 	/* Restore PME enable bit */
257
 	outl(SavedClkRun, nat->ioaddr + ClkRun);
277
 	outl(SavedClkRun, nat->ioaddr + ClkRun);
265
  */
285
  */
266
 static int nat_open ( struct net_device *netdev ) {
286
 static int nat_open ( struct net_device *netdev ) {
267
 	struct natsemi_nic *nat = netdev->priv;
287
 	struct natsemi_nic *nat = netdev->priv;
268
-	struct io_buffer *iobuf;
288
+	//struct io_buffer *iobuf;
269
 	int i;
289
 	int i;
270
 	
290
 	
271
 	/* Disable PME:
291
 	/* Disable PME:
285
 	 for ( i = 0 ; i < ETH_ALEN ; i++ )
305
 	 for ( i = 0 ; i < ETH_ALEN ; i++ )
286
 		outb ( netdev->ll_addr[i], rtl->ioaddr + MAC0 + i );
306
 		outb ( netdev->ll_addr[i], rtl->ioaddr + MAC0 + i );
287
         */
307
         */
288
-	/* Set up RX ring */
289
 
308
 
309
+
310
+	/*Set up the Tx Ring */
311
+	nat->tx_cur=0;
312
+	nat->tx_dirty=0;
313
+	for (i=0;i<TX_RING_SIZE;i++)
314
+	{
315
+		nat->tx[i].link   = virt_to_bus((i+1 < TX_RING_SIZE) ? &nat->tx[i+1] : &nat->tx[0]);
316
+		nat->tx[i].cmdsts = 0;
317
+		nat->tx[i].bufptr = 0;
318
+	}
319
+
320
+
321
+
322
+
323
+
324
+	/* Set up RX ring */
325
+	nat->rx_cur=0;
290
 	for (i=0;i<NUM_RX_DESC;i++)
326
 	for (i=0;i<NUM_RX_DESC;i++)
291
 	{
327
 	{
292
 
328
 
293
-		iobuf = alloc_iob ( RX_BUF_SIZE );
294
-		if (!iobuf)
329
+		nat->iobuf[i] = alloc_iob ( RX_BUF_SIZE );
330
+		if (!nat->iobuf[i])
295
 		       return -ENOMEM;	
331
 		       return -ENOMEM;	
296
 		nat->rx[i].link   = virt_to_bus((i+1 < NUM_RX_DESC) ? &nat->rx[i+1] : &nat->rx[0]);
332
 		nat->rx[i].link   = virt_to_bus((i+1 < NUM_RX_DESC) ? &nat->rx[i+1] : &nat->rx[0]);
297
-		nat->rx[i].cmdsts = (u32) RX_BUF_SIZE;
298
-		nat->rx[i].bufptr = virt_to_bus(iobuf->data);
333
+		nat->rx[i].cmdsts = (uint32_t) RX_BUF_SIZE;
334
+		nat->rx[i].bufptr = virt_to_bus(nat->iobuf[i]->data);
299
 	}
335
 	}
300
 
336
 
301
 
337
 
302
 	 /* load Receive Descriptor Register */
338
 	 /* load Receive Descriptor Register */
303
-	outl(virt_to_bus(&nat->rx[0]), ioaddr + RxRingPtr);
339
+	outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
304
 	DBG("Natsemi Rx descriptor loaded with: %X\n",inl(nat->ioaddr+RingPtr));		
340
 	DBG("Natsemi Rx descriptor loaded with: %X\n",inl(nat->ioaddr+RingPtr));		
305
 
341
 
306
 	/* setup Tx ring */
342
 	/* setup Tx ring */
325
 
361
 
326
 
362
 
327
 
363
 
328
-	/*start the receiver and transmitter */
329
-        outl(RxOn|TxOn, nat->ioaddr + ChipCmd);
364
+	/*start the receiver  */
365
+        outl(RxOn, nat->ioaddr + ChipCmd);
330
 
366
 
331
 
367
 
332
 	return 0;
368
 	return 0;
337
  *
373
  *
338
  * @v netdev		Net device
374
  * @v netdev		Net device
339
  */
375
  */
340
-static void rtl_close ( struct net_device *netdev ) {
341
-	struct rtl8139_nic *rtl = netdev->priv;
376
+static void nat_close ( struct net_device *netdev ) {
377
+	struct natsemi_nic *nat = netdev->priv;
342
 
378
 
343
 	/* Reset the hardware to disable everything in one go */
379
 	/* Reset the hardware to disable everything in one go */
344
-	rtl_reset ( rtl );
380
+	nat_reset ( nat );
345
 
381
 
346
 	/* Free RX ring */
382
 	/* Free RX ring */
347
-	free ( rtl->rx.ring );
348
-	rtl->rx.ring = NULL;
383
+	for (i=0;i<NUM_RX_DESC;i++)
384
+	{
385
+		
386
+		free_iob( nat->iobuf[i] );
387
+	}
349
 }
388
 }
350
 
389
 
351
 /** 
390
 /** 
358
 static int natsemi_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
397
 static int natsemi_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
359
 	struct natsemi_nic *nat = netdev->priv;
398
 	struct natsemi_nic *nat = netdev->priv;
360
 
399
 
361
-	/* Check for space in TX ring */
362
-	if ( nat->tx.iobuf[nat->tx.next] != NULL ) {
400
+       /* check for space in TX ring */
401
+
402
+	if (nat->tx[nat->tx_cur].cmdsts !=0)
403
+	{
363
 		printf ( "TX overflow\n" );
404
 		printf ( "TX overflow\n" );
364
 		return -ENOBUFS;
405
 		return -ENOBUFS;
365
 	}
406
 	}
366
 
407
 
408
+
367
 	/* Pad and align packet */
409
 	/* Pad and align packet */
368
 	iob_pad ( iobuf, ETH_ZLEN );
410
 	iob_pad ( iobuf, ETH_ZLEN );
369
 
411
 
370
 	/* Add to TX ring */
412
 	/* Add to TX ring */
371
-	DBG ( "TX id %d at %lx+%x\n", rtl->tx.next,
413
+	DBG ( "TX id %d at %lx+%x\n", nat->tx_cur,
372
 	      virt_to_bus ( iobuf->data ), iob_len ( iobuf ) );
414
 	      virt_to_bus ( iobuf->data ), iob_len ( iobuf ) );
373
-	rtl->tx.iobuf[rtl->tx.next] = iobuf;
374
-	outl ( virt_to_bus ( iobuf->data ),
375
-	       rtl->ioaddr + TxAddr0 + 4 * rtl->tx.next );
376
-	outl ( ( ( ( TX_FIFO_THRESH & 0x7e0 ) << 11 ) | iob_len ( iobuf ) ),
377
-	       rtl->ioaddr + TxStatus0 + 4 * rtl->tx.next );
378
-	rtl->tx.next = ( rtl->tx.next + 1 ) % TX_RING_SIZE;
415
+
416
+	nat->tx[nat->tx_cur].bufptr = virt_to_bus(iobuf->data);
417
+	nat->tx[nat->tx_cur].cmdsts= (uint32_t) iob_len(iobuf)|OWN;
418
+
419
+	nat->tx_cur=(nat->tx_cur+1) % TX_RING_SIZE;
420
+
421
+	/*start the transmitter  */
422
+        outl(TxOn, nat->ioaddr + ChipCmd);
379
 
423
 
380
 	return 0;
424
 	return 0;
381
 }
425
 }
386
  * @v netdev	Network device
430
  * @v netdev	Network device
387
  * @v rx_quota	Maximum number of packets to receive
431
  * @v rx_quota	Maximum number of packets to receive
388
  */
432
  */
389
-static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) {
390
-	struct rtl8139_nic *rtl = netdev->priv;
433
+static void nat_poll ( struct net_device *netdev, unsigned int rx_quota ) {
434
+	struct natsemi_nic *nat = netdev->priv;
391
 	unsigned int status;
435
 	unsigned int status;
392
-	unsigned int tsad;
393
 	unsigned int rx_status;
436
 	unsigned int rx_status;
394
 	unsigned int rx_len;
437
 	unsigned int rx_len;
395
 	struct io_buffer *rx_iob;
438
 	struct io_buffer *rx_iob;
396
-	int wrapped_len;
397
 	int i;
439
 	int i;
398
 
440
 
399
-	/* Acknowledge interrupts */
400
-	status = inw ( rtl->ioaddr + IntrStatus );
401
-	if ( ! status )
402
-		return;
403
-	outw ( status, rtl->ioaddr + IntrStatus );
404
-
405
-	/* Handle TX completions */
406
-	tsad = inw ( rtl->ioaddr + TxSummary );
407
-	for ( i = 0 ; i < TX_RING_SIZE ; i++ ) {
408
-		if ( ( rtl->tx.iobuf[i] != NULL ) && ( tsad & ( 1 << i ) ) ) {
409
-			DBG ( "TX id %d complete\n", i );
410
-			netdev_tx_complete ( netdev, rtl->tx.iobuf[i] );
411
-			rtl->tx.iobuf[i] = NULL;
441
+	
442
+	/* check the status of packets given to card for transmission */	
443
+	for ( i = 0 ; i < TX_RING_SIZE ; i++ ) 
444
+	{
445
+		status=bus_to_virt(nat->tx[nat->tx_dirty].cmdsts);
446
+		/* check if current packet has been transmitted or not */
447
+		if(status & own) 
448
+			break;
449
+		/* Check if any errors in transmission */
450
+		if (! (status & DescPktOK))
451
+		{
452
+			printf("Error in sending Packet with data: %s\n and status:%X\n",
453
+					bus_to_virt(nat->tx[nat->tx_dirty].bufptr),
454
+					status);
412
 		}
455
 		}
456
+		else
457
+		{
458
+			DBG("Success in transmitting Packet with data: %s",
459
+					bus_to_virt(nat->tx[nat->tx_dirty].bufptr));
460
+		}
461
+		/* setting cmdsts zero, indicating that it can be reused */
462
+		nat->tx[nat->tx_dirty].cmdsts=0;
463
+		nat->tx_dirty=(nat->tx_dirty +1) % TX_RING_SIZE;
413
 	}
464
 	}
414
-
465
+			
466
+	
467
+	rx_status=bus_to_virt(nat->rx[nat->rx_cur].cmdsts); 
415
 	/* Handle received packets */
468
 	/* Handle received packets */
416
-	while ( rx_quota && ! ( inw ( rtl->ioaddr + ChipCmd ) & RxBufEmpty ) ){
417
-		rx_status = * ( ( uint16_t * )
418
-				( rtl->rx.ring + rtl->rx.offset ) );
419
-		rx_len = * ( ( uint16_t * )
420
-			     ( rtl->rx.ring + rtl->rx.offset + 2 ) );
421
-		if ( rx_status & RxOK ) {
422
-			DBG ( "RX packet at offset %x+%x\n", rtl->rx.offset,
423
-			      rx_len );
424
-
425
-			rx_iob = alloc_iob ( rx_len );
426
-			if ( ! rx_iob ) {
427
-				/* Leave packet for next call to poll() */
428
-				break;
429
-			}
430
-
431
-			wrapped_len = ( ( rtl->rx.offset + 4 + rx_len )
432
-					- RX_BUF_LEN );
433
-			if ( wrapped_len < 0 )
434
-				wrapped_len = 0;
435
-
436
-			memcpy ( iob_put ( rx_iob, rx_len - wrapped_len ),
437
-				 rtl->rx.ring + rtl->rx.offset + 4,
438
-				 rx_len - wrapped_len );
439
-			memcpy ( iob_put ( rx_iob, wrapped_len ),
440
-				 rtl->rx.ring, wrapped_len );
441
-
442
-			netdev_rx ( netdev, rx_iob );
469
+	while (rx_quota && (rx_status & OWN))
470
+	{
471
+		rx_len= (rx_status & DSIZE) - CRC_SIZE;
472
+
473
+		/*check for the corrupt packet */
474
+		if((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK)
475
+		{
476
+			 printf("natsemi_poll: Corrupted packet received, 
477
+					 buffer status = %X\n",rx_status);
478
+		}
479
+		else
480
+		{
481
+			rx_iob = alloc_iob(rx_len);
482
+			if(!rx_iob) 
483
+				/* leave packet for next call to poll*/
484
+				return;
485
+			memcpy(iob_put(rx_iob,rx_len),
486
+					nat->rx[nat->rx_cur].bufptr,rxlen);
487
+			/* add to the receive queue. */
488
+			netdev_rx(netdev,rx_iob);
443
 			rx_quota--;
489
 			rx_quota--;
444
-		} else {
445
-			DBG ( "RX bad packet (status %#04x len %d)\n",
446
-			      rx_status, rx_len );
447
 		}
490
 		}
448
-		rtl->rx.offset = ( ( ( rtl->rx.offset + 4 + rx_len + 3 ) & ~3 )
449
-				   % RX_BUF_LEN );
450
-		outw ( rtl->rx.offset - 16, rtl->ioaddr + RxBufPtr );
491
+		nat->rx[nat->rx_cur].cmdsts = RX_BUF_SIZE;
492
+		nat->rx_cur=(nat->rx_cur+1) % NUM_RX_DESC;
451
 	}
493
 	}
452
-}
453
 
494
 
454
-#if 0
455
-static void rtl_irq(struct nic *nic, irq_action_t action)
456
-{
457
-	unsigned int mask;
458
-	/* Bit of a guess as to which interrupts we should allow */
459
-	unsigned int interested = ROK | RER | RXOVW | FOVW | SERR;
460
-
461
-	switch ( action ) {
462
-	case DISABLE :
463
-	case ENABLE :
464
-		mask = inw(rtl->ioaddr + IntrMask);
465
-		mask = mask & ~interested;
466
-		if ( action == ENABLE ) mask = mask | interested;
467
-		outw(mask, rtl->ioaddr + IntrMask);
468
-		break;
469
-	case FORCE :
470
-		/* Apparently writing a 1 to this read-only bit of a
471
-		 * read-only and otherwise unrelated register will
472
-		 * force an interrupt.  If you ever want to see how
473
-		 * not to write a datasheet, read the one for the
474
-		 * RTL8139...
475
-		 */
476
-		outb(EROK, rtl->ioaddr + RxEarlyStatus);
477
-		break;
478
-	}
479
-}
480
-#endif
495
+
496
+	 /* re-enable the potentially idle receive state machine */
497
+	    outl(RxOn, ioaddr + ChipCmd);	
498
+}				
499
+
500
+
501
+
502
+
503
+
481
 
504
 
482
 /**
505
 /**
483
  * Probe PCI device
506
  * Probe PCI device
492
 	struct natsemi_nic *nat = NULL;
515
 	struct natsemi_nic *nat = NULL;
493
 	int registered_netdev = 0;
516
 	int registered_netdev = 0;
494
 	int rc;
517
 	int rc;
518
+	uint32_t advertising;
495
 
519
 
496
 	/* Fix up PCI device */
520
 	/* Fix up PCI device */
497
 	adjust_pci_device ( pci );
521
 	adjust_pci_device ( pci );
517
 	
541
 	
518
 	*/
542
 	*/
519
 	
543
 	
544
+
545
+	/* mdio routine of etherboot-5.4.0 natsemi driver has been removed and 
546
+	 * statement to read from MII transceiver control section is used directly
547
+	 */
548
+
549
+        advertising = inl(nat->ioaddr + 0x80 + (4<<2)) & 0xffff; 
550
+        {
551
+	   	uint32_t chip_config = inl(ioaddr + ChipConfig);
552
+		DBG("%s: Transceiver default autoneg. %s 10 %s %s duplex.\n",
553
+	      	pci->driver_name,
554
+	        chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
555
+	        chip_config & 0x4000 ? "0" : "",
556
+	        chip_config & 0x8000 ? "full" : "half");
557
+    	}
558
+	DBG("%s: Transceiver status %hX advertising %hX\n",pci->driver_name, (int)inl(nat->ioaddr + 0x84), advertising);
559
+
560
+
561
+
562
+
563
+
520
 	/* Point to NIC specific routines */
564
 	/* Point to NIC specific routines */
521
 	netdev->open	 = nat_open;
565
 	netdev->open	 = nat_open;
522
 	netdev->close	 = nat_close;
566
 	netdev->close	 = nat_close;
542
  err:
586
  err:
543
 	/* Disable NIC */
587
 	/* Disable NIC */
544
 	if ( nat )
588
 	if ( nat )
545
-		nat_reset ( rtl );
589
+		nat_reset ( nat );
546
 	if ( registered_netdev )
590
 	if ( registered_netdev )
547
 		unregister_netdev ( netdev );
591
 		unregister_netdev ( netdev );
548
 	/* Free net device */
592
 	/* Free net device */
555
  *
599
  *
556
  * @v pci	PCI device
600
  * @v pci	PCI device
557
  */
601
  */
558
-static void rtl_remove ( struct pci_device *pci ) {
602
+static void nat_remove ( struct pci_device *pci ) {
559
 	struct net_device *netdev = pci_get_drvdata ( pci );
603
 	struct net_device *netdev = pci_get_drvdata ( pci );
560
-	struct rtl8139_nic *rtl = netdev->priv;
561
-
604
+	struct natsemi_nic *nat = netdev->priv;
605
+/* TODO 
562
 	if ( rtl->nvo.nvs )
606
 	if ( rtl->nvo.nvs )
563
 		nvo_unregister ( &rtl->nvo );
607
 		nvo_unregister ( &rtl->nvo );
608
+		*/
564
 	unregister_netdev ( netdev );
609
 	unregister_netdev ( netdev );
565
-	rtl_reset ( rtl );
610
+	nat_reset ( nat );
566
 	free_netdev ( netdev );
611
 	free_netdev ( netdev );
567
 }
612
 }
568
 
613
 
569
-static struct pci_device_id rtl8139_nics[] = {
570
-PCI_ROM(0x10ec, 0x8129, "rtl8129",       "Realtek 8129"),
571
-PCI_ROM(0x10ec, 0x8139, "rtl8139",       "Realtek 8139"),
572
-PCI_ROM(0x10ec, 0x8138, "rtl8139b",      "Realtek 8139B"),
573
-PCI_ROM(0x1186, 0x1300, "dfe538",        "DFE530TX+/DFE538TX"),
574
-PCI_ROM(0x1113, 0x1211, "smc1211-1",     "SMC EZ10/100"),
575
-PCI_ROM(0x1112, 0x1211, "smc1211",       "SMC EZ10/100"),
576
-PCI_ROM(0x1500, 0x1360, "delta8139",     "Delta Electronics 8139"),
577
-PCI_ROM(0x4033, 0x1360, "addtron8139",   "Addtron Technology 8139"),
578
-PCI_ROM(0x1186, 0x1340, "dfe690txd",     "D-Link DFE690TXD"),
579
-PCI_ROM(0x13d1, 0xab06, "fe2000vx",      "AboCom FE2000VX"),
580
-PCI_ROM(0x1259, 0xa117, "allied8139",    "Allied Telesyn 8139"),
581
-PCI_ROM(0x14ea, 0xab06, "fnw3603tx",     "Planex FNW-3603-TX"),
582
-PCI_ROM(0x14ea, 0xab07, "fnw3800tx",     "Planex FNW-3800-TX"),
583
-PCI_ROM(0xffff, 0x8139, "clone-rtl8139", "Cloned 8139"),
614
+static struct pci_device_id natsemi_nics[] = {
615
+	PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
616
+
584
 };
617
 };
585
 
618
 
586
-struct pci_driver rtl8139_driver __pci_driver = {
587
-	.ids = rtl8139_nics,
588
-	.id_count = ( sizeof ( rtl8139_nics ) / sizeof ( rtl8139_nics[0] ) ),
589
-	.probe = rtl_probe,
590
-	.remove = rtl_remove,
619
+struct pci_driver natsemi_driver __pci_driver = {
620
+	.ids = natsemi_nics,
621
+	.id_count = ( sizeof ( natsemi_nics ) / sizeof ( natsemi_nics[0] ) ),
622
+	.probe = nat_probe,
623
+	.remove = nat_remove,
591
 };
624
 };

Loading…
Cancel
Save