浏览代码

added polling and transmit. eeprom access still remaining

tags/v0.9.3
Udayan Kumar 18 年前
父节点
当前提交
c8f6207e7e
共有 1 个文件被更改,包括 167 次插入134 次删除
  1. 167
    134
      src/drivers/net/natsemi.c

+ 167
- 134
src/drivers/net/natsemi.c 查看文件

@@ -36,9 +36,15 @@ struct natsemi_rx {
36 36
 
37 37
 struct natsemi_nic {
38 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 42
 	struct natsemi_tx tx[TX_RING_SIZE];
41 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 48
 	struct spi_bit_basher spibit;
43 49
 	struct spi_device eeprom;
44 50
 	struct nvo_block nvo;
@@ -54,7 +60,9 @@ struct natsemi_nic {
54 60
 #define RX_BUF_LEN    8192   /*buffer size should be multiple of 32 */ 
55 61
 #define RX_BUF_PAD 4
56 62
 #define RX_BUF_SIZE 1536
57
-
63
+#define OWN       0x80000000
64
+#define DSIZE     0x00000FFF
65
+#define CRC_SIZE  4
58 66
 
59 67
 /* NATSEMI: Offsets to the device registers.
60 68
    Unlike software-only systems, device drivers interact with complex hardware.
@@ -208,12 +216,12 @@ static struct nvo_fragment rtl_nvo_fragments[] = {
208 216
  *
209 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 220
 	int ee9356;
213 221
 	int vpd;
214 222
 
215 223
 	/* Initialise three-wire bus */
216
-	nat->spibit.basher.op = &rtl_basher_ops;
224
+	rtl->spibit.basher.op = &rtl_basher_ops;
217 225
 	rtl->spibit.bus.mode = SPI_MODE_THREEWIRE;
218 226
 	init_spi_bit_basher ( &rtl->spibit );
219 227
 
@@ -241,17 +249,29 @@ static struct nvo_fragment rtl_nvo_fragments[] = {
241 249
 /**
242 250
  * Reset NIC
243 251
  *
244
- * @v rtl		NATSEMI NIC
252
+ * @v		NATSEMI NIC
245 253
  *
246 254
  * Issues a hardware reset and waits for the reset to complete.
247 255
  */
248 256
 static void nat_reset ( struct nat_nic *nat ) {
249 257
 
258
+	int i;
250 259
 	/* Reset chip */
251 260
 	outb ( ChipReset, nat->ioaddr + ChipCmd );
252 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 276
 	/* Restore PME enable bit */
257 277
 	outl(SavedClkRun, nat->ioaddr + ClkRun);
@@ -265,7 +285,7 @@ static void nat_reset ( struct nat_nic *nat ) {
265 285
  */
266 286
 static int nat_open ( struct net_device *netdev ) {
267 287
 	struct natsemi_nic *nat = netdev->priv;
268
-	struct io_buffer *iobuf;
288
+	//struct io_buffer *iobuf;
269 289
 	int i;
270 290
 	
271 291
 	/* Disable PME:
@@ -285,22 +305,38 @@ static int nat_open ( struct net_device *netdev ) {
285 305
 	 for ( i = 0 ; i < ETH_ALEN ; i++ )
286 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 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 331
 		       return -ENOMEM;	
296 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 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 340
 	DBG("Natsemi Rx descriptor loaded with: %X\n",inl(nat->ioaddr+RingPtr));		
305 341
 
306 342
 	/* setup Tx ring */
@@ -325,8 +361,8 @@ static int nat_open ( struct net_device *netdev ) {
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 368
 	return 0;
@@ -337,15 +373,18 @@ static int nat_open ( struct net_device *netdev ) {
337 373
  *
338 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 379
 	/* Reset the hardware to disable everything in one go */
344
-	rtl_reset ( rtl );
380
+	nat_reset ( nat );
345 381
 
346 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,24 +397,29 @@ static void rtl_close ( struct net_device *netdev ) {
358 397
 static int natsemi_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
359 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 404
 		printf ( "TX overflow\n" );
364 405
 		return -ENOBUFS;
365 406
 	}
366 407
 
408
+
367 409
 	/* Pad and align packet */
368 410
 	iob_pad ( iobuf, ETH_ZLEN );
369 411
 
370 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 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 424
 	return 0;
381 425
 }
@@ -386,98 +430,77 @@ static int natsemi_transmit ( struct net_device *netdev, struct io_buffer *iobuf
386 430
  * @v netdev	Network device
387 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 435
 	unsigned int status;
392
-	unsigned int tsad;
393 436
 	unsigned int rx_status;
394 437
 	unsigned int rx_len;
395 438
 	struct io_buffer *rx_iob;
396
-	int wrapped_len;
397 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 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 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 506
  * Probe PCI device
@@ -492,6 +515,7 @@ static int nat_probe ( struct pci_device *pci,
492 515
 	struct natsemi_nic *nat = NULL;
493 516
 	int registered_netdev = 0;
494 517
 	int rc;
518
+	uint32_t advertising;
495 519
 
496 520
 	/* Fix up PCI device */
497 521
 	adjust_pci_device ( pci );
@@ -517,6 +541,26 @@ static int nat_probe ( struct 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 564
 	/* Point to NIC specific routines */
521 565
 	netdev->open	 = nat_open;
522 566
 	netdev->close	 = nat_close;
@@ -542,7 +586,7 @@ static int nat_probe ( struct pci_device *pci,
542 586
  err:
543 587
 	/* Disable NIC */
544 588
 	if ( nat )
545
-		nat_reset ( rtl );
589
+		nat_reset ( nat );
546 590
 	if ( registered_netdev )
547 591
 		unregister_netdev ( netdev );
548 592
 	/* Free net device */
@@ -555,37 +599,26 @@ static int nat_probe ( struct pci_device *pci,
555 599
  *
556 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 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 606
 	if ( rtl->nvo.nvs )
563 607
 		nvo_unregister ( &rtl->nvo );
608
+		*/
564 609
 	unregister_netdev ( netdev );
565
-	rtl_reset ( rtl );
610
+	nat_reset ( nat );
566 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
 };

正在加载...
取消
保存