瀏覽代碼

natsemi.c is workin

tags/v0.9.3
Udayan Kumar 18 年之前
父節點
當前提交
4f2fab2e14
共有 1 個文件被更改,包括 102 次插入155 次删除
  1. 102
    155
      src/drivers/net/natsemi.c

+ 102
- 155
src/drivers/net/natsemi.c 查看文件

@@ -107,10 +107,12 @@ struct natsemi_nic {
107 107
 	struct natsemi_rx rx[NUM_RX_DESC];
108 108
 	/* need to add iobuf as we cannot free iobuf->data in close without this 
109 109
 	 * alternatively substracting sizeof(head) and sizeof(list_head) can also 
110
-	 * give the same.*/
110
+	 * give the same.
111
+	 */
111 112
 	struct io_buffer *iobuf[NUM_RX_DESC];
112
-	/*netdev_tx_complete needs pointer to the iobuf of the data so as to free 
113
-	  it from the memory.*/
113
+	/* netdev_tx_complete needs pointer to the iobuf of the data so as to free 
114
+	 * it from the memory.
115
+	 */
114 116
 	struct io_buffer *tx_iobuf[TX_RING_SIZE];
115 117
 	struct spi_bit_basher spibit;
116 118
 	struct spi_device eeprom;
@@ -119,10 +121,10 @@ struct natsemi_nic {
119 121
 
120 122
 
121 123
 /* NATSEMI: Offsets to the device registers.
122
-   Unlike software-only systems, device drivers interact with complex hardware.
123
-   It's not useful to define symbolic names for every register bit in the
124
-   device.
125
-*/
124
+ * Unlike software-only systems, device drivers interact with complex hardware.
125
+ * It's not useful to define symbolic names for every register bit in the
126
+ * device.
127
+ */
126 128
 enum register_offsets {
127 129
     ChipCmd      = 0x00, 
128 130
     ChipConfig   = 0x04, 
@@ -258,25 +260,24 @@ static struct bit_basher_operations nat_basher_ops = {
258 260
 	.read = nat_spi_read_bit,
259 261
 	.write = nat_spi_write_bit,
260 262
 };
261
-/** Portion of EEPROM available for non-volatile stored options
262
- *
263
- * We use offset 0x40 (i.e. address 0x20), length 0x40.  This block is
264
- * marked as VPD in the rtl8139 datasheets, so we use it only if we
265
- * detect that the card is not supporting VPD.
263
+
264
+/* It looks that this portion of EEPROM can be used for 
265
+ * non-volatile stored options. Data sheet does not talk about this region.
266
+ * Currently it is not working. But with some efforts it can.
266 267
  */
267 268
 static struct nvo_fragment nat_nvo_fragments[] = {
268
-	{ 0x0c, 0x40 },
269
+	{ 0x0c, 0x68 },
269 270
 	{ 0, 0 }
270 271
 };
271 272
 
272
-/**
273
+/*
273 274
  * Set up for EEPROM access
274 275
  *
275 276
  * @v NAT		NATSEMI NIC
276 277
  */
277 278
  void nat_init_eeprom ( struct natsemi_nic *nat ) {
278 279
 
279
-	// Initialise three-wire bus 
280
+	/* Initialise three-wire bus  */
280 281
 	nat->spibit.basher.op = &nat_basher_ops;
281 282
 	nat->spibit.bus.mode = SPI_MODE_THREEWIRE;
282 283
 	nat->spibit.endianness = SPI_BIT_LITTLE_ENDIAN;
@@ -286,11 +287,11 @@ static struct nvo_fragment nat_nvo_fragments[] = {
286 287
 	init_at93c46 ( &nat->eeprom, 16 );
287 288
 	nat->eeprom.bus = &nat->spibit.bus;
288 289
 
289
-		nat->nvo.nvs = &nat->eeprom.nvs;
290
-		nat->nvo.fragments = nat_nvo_fragments;
290
+	nat->nvo.nvs = &nat->eeprom.nvs;
291
+	nat->nvo.fragments = nat_nvo_fragments;
291 292
 }
292 293
 
293
-/**
294
+/*
294 295
  * Reset NIC
295 296
  *
296 297
  * @v		NATSEMI NIC
@@ -305,8 +306,7 @@ static void nat_reset ( struct natsemi_nic *nat ) {
305 306
 	mdelay ( 10 );
306 307
 	nat->tx_dirty=0;
307 308
 	nat->tx_cur=0;
308
-	for(i=0;i<TX_RING_SIZE;i++)
309
-	{
309
+	for(i=0;i<TX_RING_SIZE;i++) {
310 310
 		nat->tx[i].link=0;
311 311
 		nat->tx[i].cmdsts=0;
312 312
 		nat->tx[i].bufptr=0;
@@ -321,7 +321,7 @@ static void nat_reset ( struct natsemi_nic *nat ) {
321 321
 	outl(SavedClkRun, nat->ioaddr + ClkRun);
322 322
 }
323 323
 
324
-/**
324
+/*
325 325
  * Open NIC
326 326
  *
327 327
  * @v netdev		Net device
@@ -333,50 +333,33 @@ static int nat_open ( struct net_device *netdev ) {
333 333
 	uint32_t tx_config,rx_config;
334 334
 	
335 335
 	/* Disable PME:
336
-        * The PME bit is initialized from the EEPROM contents.
337
-        * PCI cards probably have PME disabled, but motherboard
338
-        * implementations may have PME set to enable WakeOnLan. 
339
-        * With PME set the chip will scan incoming packets but
340
-        * nothing will be written to memory. */
336
+         * The PME bit is initialized from the EEPROM contents.
337
+         * PCI cards probably have PME disabled, but motherboard
338
+         * implementations may have PME set to enable WakeOnLan. 
339
+         * With PME set the chip will scan incoming packets but
340
+         * nothing will be written to memory. 
341
+         */
341 342
         SavedClkRun = inl(nat->ioaddr + ClkRun);
342 343
         outl(SavedClkRun & ~0x100, nat->ioaddr + ClkRun);
343 344
 
344
-		
345
-
346
-
347
-	 uint8_t last=0;
348
-	 uint8_t last1=0;
349
-	 for ( i = 0 ; i < ETH_ALEN ; i+=2 )
350
-	 {
345
+	/* Setting up Mac address in the NIC */
346
+	for ( i = 0 ; i < ETH_ALEN ; i+=2 ) {
351 347
 		outl(i,nat->ioaddr+RxFilterAddr);
352
-		last1=netdev->ll_addr[i]>>7;
353
-	 	netdev->ll_addr[i]=netdev->ll_addr[i]<<1|last;
354
-		last=(netdev->ll_addr[i+1]>>7);
355
-		netdev->ll_addr[i+1]=(netdev->ll_addr[i+1]<<1)+last1;
356
-
357 348
 		outw ( netdev->ll_addr[i] + (netdev->ll_addr[i+1]<<8), nat->ioaddr +RxFilterData);
358 349
 	}
359
-       
360
-
361 350
 
362 351
 	/*Set up the Tx Ring */
363 352
 	nat->tx_cur=0;
364 353
 	nat->tx_dirty=0;
365
-	for (i=0;i<TX_RING_SIZE;i++)
366
-	{
354
+	for (i=0;i<TX_RING_SIZE;i++) {
367 355
 		nat->tx[i].link   = virt_to_bus((i+1 < TX_RING_SIZE) ? &nat->tx[i+1] : &nat->tx[0]);
368 356
 		nat->tx[i].cmdsts = 0;
369 357
 		nat->tx[i].bufptr = 0;
370 358
 	}
371 359
 
372
-
373
-
374
-
375
-
376 360
 	/* Set up RX ring */
377 361
 	nat->rx_cur=0;
378
-	for (i=0;i<NUM_RX_DESC;i++)
379
-	{
362
+	for (i=0;i<NUM_RX_DESC;i++) {
380 363
 
381 364
 		nat->iobuf[i] = alloc_iob ( RX_BUF_SIZE );
382 365
 		if (!nat->iobuf[i])
@@ -386,8 +369,7 @@ static int nat_open ( struct net_device *netdev ) {
386 369
 		nat->rx[i].bufptr = virt_to_bus(nat->iobuf[i]->data);
387 370
 	}
388 371
 
389
-
390
-	 /* load Receive Descriptor Register */
372
+	/* load Receive Descriptor Register */
391 373
 	outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
392 374
 	DBG("Natsemi Rx descriptor loaded with: %X\n",(unsigned int)inl(nat->ioaddr+RxRingPtr));		
393 375
 
@@ -398,9 +380,10 @@ static int nat_open ( struct net_device *netdev ) {
398 380
 	/* Enables RX */
399 381
 	outl(RxFilterEnable|AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys, nat->ioaddr+RxFilterAddr);
400 382
 
401
-	/* Initialize other registers. */
402
-	/* Configure the PCI bus bursts and FIFO thresholds. */
403
-	/* Configure for standard, in-spec Ethernet. */
383
+	/* Initialize other registers. 
384
+	 * Configure the PCI bus bursts and FIFO thresholds. 
385
+	 * Configure for standard, in-spec Ethernet. 
386
+	 */
404 387
 	if (inl(nat->ioaddr + ChipConfig) & 0x20000000) {	/* Full duplex */
405 388
 		tx_config = 0xD0801002;
406 389
 		rx_config = 0x10000020;
@@ -411,17 +394,12 @@ static int nat_open ( struct net_device *netdev ) {
411 394
 	outl(tx_config, nat->ioaddr + TxConfig);
412 395
 	outl(rx_config, nat->ioaddr + RxConfig);
413 396
 
414
-
415
-
416 397
 	/*start the receiver  */
417 398
         outl(RxOn, nat->ioaddr + ChipCmd);
418 399
 
419 400
 	/*enable interrupts*/
420 401
 	outl((RxOk|RxErr|TxOk|TxErr),nat->ioaddr + IntrMask); 
421
-	outl(1,nat->ioaddr +IntrEnable);
422
-
423
-
424
-
402
+	//outl(1,nat->ioaddr +IntrEnable);
425 403
 
426 404
 	return 0;
427 405
 }
@@ -440,13 +418,12 @@ static void nat_close ( struct net_device *netdev ) {
440 418
 	nat_reset ( nat );
441 419
 
442 420
 	/* Free RX ring */
443
-	for (i=0;i<NUM_RX_DESC;i++)
444
-	{
421
+	for (i=0;i<NUM_RX_DESC;i++) {
445 422
 		
446 423
 		free_iob( nat->iobuf[i] );
447 424
 	}
448 425
 	/* disable interrupts */
449
-	outl(0,nat->ioaddr + IntrMask) ;
426
+	//outl(0,nat->ioaddr + IntrMask) ;
450 427
 }
451 428
 
452 429
 /** 
@@ -459,11 +436,9 @@ static void nat_close ( struct net_device *netdev ) {
459 436
 static int nat_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
460 437
 	struct natsemi_nic *nat = netdev->priv;
461 438
 
462
-       /* check for space in TX ring */
463
-
464
-	if (nat->tx[nat->tx_cur].cmdsts !=0)
465
-	{
466
-		printf ( "TX overflow\n" );
439
+        /* check for space in TX ring */
440
+	if (nat->tx[nat->tx_cur].cmdsts !=0) {
441
+		DBG( "TX overflow\n" );
467 442
 		return -ENOBUFS;
468 443
 	}
469 444
 
@@ -478,9 +453,8 @@ static int nat_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
478 453
 	      virt_to_bus ( &iobuf->data ), iob_len ( iobuf ) );
479 454
 
480 455
 	nat->tx[nat->tx_cur].bufptr = virt_to_bus(iobuf->data);
481
-	nat->tx[nat->tx_cur].cmdsts= (uint32_t) iob_len(iobuf)|OWN;
482
-
483
-
456
+	nat->tx[nat->tx_cur].cmdsts= iob_len(iobuf)|OWN;
457
+	/* increment the circular buffer pointer to the next buffer location */
484 458
 	nat->tx_cur=(nat->tx_cur+1) % TX_RING_SIZE;
485 459
 
486 460
 	/*start the transmitter  */
@@ -513,10 +487,8 @@ static void nat_poll ( struct net_device *netdev, unsigned int rx_quota ) {
513 487
 	/* check the status of packets given to card for transmission */	
514 488
 	DBG("Intr status %X\n",intr_status);
515 489
 
516
-
517 490
 	i=nat->tx_dirty;
518
-	while(i!=nat->tx_cur)
519
-	{
491
+	while(i!=nat->tx_cur) {
520 492
 		status=nat->tx[nat->tx_dirty].cmdsts;
521 493
 		DBG("value of tx_dirty = %d tx_cur=%d status=%X\n",
522 494
 			nat->tx_dirty,nat->tx_cur,status);
@@ -525,47 +497,37 @@ static void nat_poll ( struct net_device *netdev, unsigned int rx_quota ) {
525 497
 		if(status & OWN) 
526 498
 			break;
527 499
 		/* Check if any errors in transmission */
528
-		if (! (status & DescPktOK))
529
-		{
530
-			printf("Error in sending Packet status:%X\n",
500
+		if (! (status & DescPktOK)) {
501
+			DBG("Error in sending Packet status:%X\n",
531 502
 					(unsigned int)status);
503
+			netdev_tx_complete_err(netdev,nat->tx_iobuf[nat->tx_dirty],-EINVAL);
504
+		} else {
505
+			DBG("Success in transmitting Packet\n");
506
+			netdev_tx_complete(netdev,nat->tx_iobuf[nat->tx_dirty]);
532 507
 		}
533
-		else
534
-		{
535
-			DBG("Success in transmitting Packet with data\n");
536
-		//	DBG_HD(&nat->tx[nat->tx_dirty].bufptr,130);
537
-		}
538
-		netdev_tx_complete(netdev,nat->tx_iobuf[nat->tx_dirty]);
539 508
 		/* setting cmdsts zero, indicating that it can be reused */
540 509
 		nat->tx[nat->tx_dirty].cmdsts=0;
541 510
 		nat->tx_dirty=(nat->tx_dirty +1) % TX_RING_SIZE;
542 511
 		i=(i+1) % TX_RING_SIZE;
543
-
544 512
 	}
545
-			
546 513
 	
547
-	rx_status=(unsigned int)nat->rx[nat->rx_cur].cmdsts; 
548 514
 	/* Handle received packets */
549
-	while (rx_quota && (rx_status & OWN))
550
-	{
515
+	rx_status=(unsigned int)nat->rx[nat->rx_cur].cmdsts; 
516
+	while (rx_quota && (rx_status & OWN)) {
551 517
 		rx_len= (rx_status & DSIZE) - CRC_SIZE;
552
-
553 518
 		/*check for the corrupt packet */
554
-		if((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK)
555
-		{
556
-			 printf("natsemi_poll: Corrupted packet received, "
519
+		if((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK) {
520
+			 DBG("natsemi_poll: Corrupted packet received, "
557 521
 					"buffer status = %X ^ %X \n",rx_status,
558 522
 					(unsigned int) nat->rx[nat->rx_cur].cmdsts);
559
-		}
560
-		else
561
-		{
523
+			 netdev_rx_err(netdev,NULL,-EINVAL);
524
+		} else 	{
562 525
 			rx_iob = alloc_iob(rx_len);
563 526
 			if(!rx_iob) 
564 527
 				/* leave packet for next call to poll*/
565 528
 				goto end;
566 529
 			memcpy(iob_put(rx_iob,rx_len),
567
-					bus_to_virt(nat->rx[nat->rx_cur].bufptr),rx_len);
568
-
530
+					nat->iobuf[nat->rx_cur]->data,rx_len);
569 531
 			DBG("received packet\n");
570 532
 			/* add to the receive queue. */
571 533
 			netdev_rx(netdev,rx_iob);
@@ -573,22 +535,25 @@ static void nat_poll ( struct net_device *netdev, unsigned int rx_quota ) {
573 535
 		}
574 536
 		nat->rx[nat->rx_cur].cmdsts = RX_BUF_SIZE;
575 537
 		nat->rx_cur=(nat->rx_cur+1) % NUM_RX_DESC;
576
-		rx_status=(unsigned int)nat->rx[nat->rx_cur].cmdsts; 
538
+		rx_status=nat->rx[nat->rx_cur].cmdsts; 
577 539
 	}
578 540
 
579 541
 end:
580 542
 
581
-	 /* re-enable the potentially idle receive state machine */
543
+	/* re-enable the potentially idle receive state machine */
582 544
 	outl(RxOn, nat->ioaddr + ChipCmd);	
583 545
 //	outl(1,nat->ioaddr +IntrEnable);
584 546
 }				
585 547
 
548
+/** RTL8139 net device operations */
549
+static struct net_device_operations nat_operations = {
550
+        .open           = nat_open,
551
+        .close          = nat_close,
552
+        .transmit       = nat_transmit,
553
+        .poll           = nat_poll,
554
+};
586 555
 
587
-
588
-
589
-
590
-
591
-/**
556
+/*
592 557
  * Probe PCI device
593 558
  *
594 559
  * @v pci	PCI device
@@ -599,89 +564,71 @@ static int nat_probe ( struct pci_device *pci,
599 564
 		       const struct pci_device_id *id __unused ) {
600 565
 	struct net_device *netdev;
601 566
 	struct natsemi_nic *nat = NULL;
602
-	int registered_netdev = 0;
603 567
 	int rc;
604
-	uint32_t advertising;
605
-
606
-	/* Fix up PCI device */
607
-	adjust_pci_device ( pci );
568
+	int i;
569
+	uint8_t ll_addr_encoded[MAX_LL_ADDR_LEN];
570
+	uint8_t last=0;
571
+	uint8_t last1=0;
608 572
 
609 573
 	/* Allocate net device */
610 574
 	netdev = alloc_etherdev ( sizeof ( *nat ) );
611
-	if ( ! netdev ) {
612
-		rc = -ENOMEM;
613
-		goto err;
614
-	}
575
+	if ( ! netdev ) 
576
+		return -ENOMEM;
577
+	netdev_init(netdev,&nat_operations);
615 578
 	nat = netdev->priv;
616 579
 	pci_set_drvdata ( pci, netdev );
617 580
 	netdev->dev = &pci->dev;
618 581
 	memset ( nat, 0, sizeof ( *nat ) );
619 582
 	nat->ioaddr = pci->ioaddr;
620 583
 
621
-	/* getting the IRQ vector */
622
-	unsigned long vector_phys = IRQ_INT ( pci->irq ) * 4;
623
-	DBG_HDA ( vector_phys, phys_to_virt ( vector_phys ), 4 );
624
-	DBG_HD ( phys_to_virt ( 0xfaea5 ), 64 );
625
-	DBG (" PIC state %X\n", irq_enabled(pci->irq));
626
-	DBG (" IRQ Number %X\n",pci->irq);
627
-
628
-
584
+	/* Fix up PCI device */
585
+	adjust_pci_device ( pci );
629 586
 
630 587
 	/* Reset the NIC, set up EEPROM access and read MAC address */
631 588
 	nat_reset ( nat );
632 589
 	nat_init_eeprom ( nat );
633
-	nvs_read ( &nat->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
634
-	uint8_t  eetest[128];	
635
-	nvs_read ( &nat->eeprom.nvs, 0, eetest,128 );
590
+	nvs_read ( &nat->eeprom.nvs, EE_MAC, ll_addr_encoded, ETH_ALEN );
636 591
 	
637
-
638
-	/* mdio routine of etherboot-5.4.0 natsemi driver has been removed and 
639
-	 * statement to read from MII transceiver control section is used directly
640
-	 */
641
-
642
-        advertising = inl(nat->ioaddr + 0x80 + (4<<2)) & 0xffff; 
643
-        {
644
-	   	uint32_t chip_config = inl(nat->ioaddr + ChipConfig);
645
-		DBG("%s: Transceiver default autoneg. %s 10 %s %s duplex.\n",
646
-	      	pci->driver_name,
647
-	        chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
648
-	        chip_config & 0x4000 ? "0" : "",
649
-	        chip_config & 0x8000 ? "full" : "half");
650
-    	}
651
-	DBG("%s: Transceiver status %hX advertising %hX\n",pci->driver_name, (int)inl(nat->ioaddr + 0x84),(unsigned int) advertising);
652
-
653
-
654
-
655
-
592
+	/* decoding the MAC address read from NVS 
593
+	 * and save it in netdev->ll_addr
594
+         */
595
+	for ( i = 0 ; i < ETH_ALEN ; i+=2 ) {
596
+		last1=ll_addr_encoded[i]>>7;
597
+	 	netdev->ll_addr[i]=ll_addr_encoded[i]<<1|last;
598
+		last=(ll_addr_encoded[i+1]>>7);
599
+		netdev->ll_addr[i+1]=(ll_addr_encoded[i+1]<<1)+last1;
600
+	}
601
+	/* TODO remove the block below */
602
+	DBG("Contents of the EEPROM\n");
603
+	uint8_t eetest[108];
604
+	nvs_read(&nat->eeprom.nvs,0,eetest,108);
605
+	DBG_HD(&eetest,108);
656 606
 
657 607
 	/* Point to NIC specific routines */
608
+	/*
658 609
 	netdev->open	 = nat_open;
659 610
 	netdev->close	 = nat_close;
660 611
 	netdev->transmit = nat_transmit;
661 612
 	netdev->poll	 = nat_poll;
662
-
613
+	*/
663 614
 	/* Register network device */
664 615
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
665
-		goto err;
666
-	registered_netdev = 1;
616
+		goto err_register_netdev;
667 617
 
668
-	/* Register non-volatile storagei
669
-	 * uncomment lines below in final version*/
670
-	
671
-	 if ( nat->nvo.nvs ) {
618
+	/* Register non-volatile storage */
619
+	if ( nat->nvo.nvs ) {
672 620
 		if ( ( rc = nvo_register ( &nat->nvo ) ) != 0 )
673
-			goto err;
621
+			goto err_register_nvo;
674 622
 	}
675 623
 	
676 624
 
677 625
 	return 0;
678 626
 
679
- err:
627
+err_register_nvo:
628
+	unregister_netdev ( netdev );
629
+err_register_netdev:
680 630
 	/* Disable NIC */
681
-	if ( nat )
682
-		nat_reset ( nat );
683
-	if ( registered_netdev )
684
-		unregister_netdev ( netdev );
631
+	nat_reset ( nat );
685 632
 	/* Free net device */
686 633
 	netdev_put ( netdev );
687 634
 	return rc;

Loading…
取消
儲存