aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmit S. Kale <amitkale@netxen.com>2007-02-05 10:40:49 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-06 19:08:03 -0500
commit27d2ab54bdfaffdbdc1a81100dc53c6479c9db35 (patch)
tree27817bbfeb065a2a75ecce6f331596f002ddae7d
parent1fcca1a5fc81689d191b7132318970c969b4b635 (diff)
NetXen: Added ethtool support for user level tools.
NetXen: Added ethtool support for user level firmware management utilities. Signed-off-by: Amit S. Kale <amitkale@netxen.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/netxen/netxen_nic.h17
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c96
-rw-r--r--drivers/net/netxen/netxen_nic_init.c267
3 files changed, 361 insertions, 19 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index e8598b809228..3f3896e98879 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -63,11 +63,14 @@
63 63
64#include "netxen_nic_hw.h" 64#include "netxen_nic_hw.h"
65 65
66#define NETXEN_NIC_BUILD_NO "2"
67#define _NETXEN_NIC_LINUX_MAJOR 3 66#define _NETXEN_NIC_LINUX_MAJOR 3
68#define _NETXEN_NIC_LINUX_MINOR 3 67#define _NETXEN_NIC_LINUX_MINOR 3
69#define _NETXEN_NIC_LINUX_SUBVERSION 3 68#define _NETXEN_NIC_LINUX_SUBVERSION 3
70#define NETXEN_NIC_LINUX_VERSIONID "3.3.3" "-" NETXEN_NIC_BUILD_NO 69#define NETXEN_NIC_LINUX_VERSIONID "3.3.3"
70
71#define NUM_FLASH_SECTORS (64)
72#define FLASH_SECTOR_SIZE (64 * 1024)
73#define FLASH_TOTAL_SIZE (NUM_FLASH_SECTORS * FLASH_SECTOR_SIZE)
71 74
72#define RCV_DESC_RINGSIZE \ 75#define RCV_DESC_RINGSIZE \
73 (sizeof(struct rcv_desc) * adapter->max_rx_desc_count) 76 (sizeof(struct rcv_desc) * adapter->max_rx_desc_count)
@@ -85,6 +88,7 @@
85#define NETXEN_RCV_PRODUCER_OFFSET 0 88#define NETXEN_RCV_PRODUCER_OFFSET 0
86#define NETXEN_RCV_PEG_DB_ID 2 89#define NETXEN_RCV_PEG_DB_ID 2
87#define NETXEN_HOST_DUMMY_DMA_SIZE 1024 90#define NETXEN_HOST_DUMMY_DMA_SIZE 1024
91#define FLASH_SUCCESS 0
88 92
89#define ADDR_IN_WINDOW1(off) \ 93#define ADDR_IN_WINDOW1(off) \
90 ((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0 94 ((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0
@@ -1028,6 +1032,15 @@ void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
1028void netxen_load_firmware(struct netxen_adapter *adapter); 1032void netxen_load_firmware(struct netxen_adapter *adapter);
1029int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); 1033int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
1030int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); 1034int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp);
1035int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
1036 u8 *bytes, size_t size);
1037int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr,
1038 u8 *bytes, size_t size);
1039int netxen_flash_unlock(struct netxen_adapter *adapter);
1040int netxen_backup_crbinit(struct netxen_adapter *adapter);
1041int netxen_flash_erase_secondary(struct netxen_adapter *adapter);
1042int netxen_flash_erase_primary(struct netxen_adapter *adapter);
1043
1031int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data); 1044int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data);
1032int netxen_rom_se(struct netxen_adapter *adapter, int addr); 1045int netxen_rom_se(struct netxen_adapter *adapter, int addr);
1033int netxen_do_rom_se(struct netxen_adapter *adapter, int addr); 1046int netxen_do_rom_se(struct netxen_adapter *adapter, int addr);
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index c381d77a7336..cc0efe213e01 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -32,6 +32,7 @@
32 */ 32 */
33 33
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/delay.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36#include <linux/pci.h> 37#include <linux/pci.h>
37#include <asm/io.h> 38#include <asm/io.h>
@@ -94,17 +95,7 @@ static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
94 95
95static int netxen_nic_get_eeprom_len(struct net_device *dev) 96static int netxen_nic_get_eeprom_len(struct net_device *dev)
96{ 97{
97 struct netxen_port *port = netdev_priv(dev); 98 return FLASH_TOTAL_SIZE;
98 struct netxen_adapter *adapter = port->adapter;
99 int n;
100
101 if ((netxen_rom_fast_read(adapter, 0, &n) == 0)
102 && (n & NETXEN_ROM_ROUNDUP)) {
103 n &= ~NETXEN_ROM_ROUNDUP;
104 if (n < NETXEN_MAX_EEPROM_LEN)
105 return n;
106 }
107 return 0;
108} 99}
109 100
110static void 101static void
@@ -440,18 +431,92 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
440 struct netxen_port *port = netdev_priv(dev); 431 struct netxen_port *port = netdev_priv(dev);
441 struct netxen_adapter *adapter = port->adapter; 432 struct netxen_adapter *adapter = port->adapter;
442 int offset; 433 int offset;
434 int ret;
443 435
444 if (eeprom->len == 0) 436 if (eeprom->len == 0)
445 return -EINVAL; 437 return -EINVAL;
446 438
447 eeprom->magic = (port->pdev)->vendor | ((port->pdev)->device << 16); 439 eeprom->magic = (port->pdev)->vendor | ((port->pdev)->device << 16);
448 for (offset = 0; offset < eeprom->len; offset++) 440 offset = eeprom->offset;
449 if (netxen_rom_fast_read 441
450 (adapter, (8 * offset) + 8, (int *)eeprom->data) == -1) 442 ret = netxen_rom_fast_read_words(adapter, offset, bytes,
451 return -EIO; 443 eeprom->len);
444 if (ret < 0)
445 return ret;
446
452 return 0; 447 return 0;
453} 448}
454 449
450static int
451netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
452 u8 * bytes)
453{
454 struct netxen_port *port = netdev_priv(dev);
455 struct netxen_adapter *adapter = port->adapter;
456 int offset = eeprom->offset;
457 static int flash_start;
458 static int ready_to_flash;
459 int ret;
460
461 if (flash_start == 0) {
462 ret = netxen_flash_unlock(adapter);
463 if (ret < 0) {
464 printk(KERN_ERR "%s: Flash unlock failed.\n",
465 netxen_nic_driver_name);
466 return ret;
467 }
468 printk(KERN_INFO "%s: flash unlocked. \n",
469 netxen_nic_driver_name);
470 ret = netxen_flash_erase_secondary(adapter);
471 if (ret != FLASH_SUCCESS) {
472 printk(KERN_ERR "%s: Flash erase failed.\n",
473 netxen_nic_driver_name);
474 return ret;
475 }
476 printk(KERN_INFO "%s: secondary flash erased successfully.\n",
477 netxen_nic_driver_name);
478 flash_start = 1;
479 return 0;
480 }
481
482 if (offset == BOOTLD_START) {
483 ret = netxen_flash_erase_primary(adapter);
484 if (ret != FLASH_SUCCESS) {
485 printk(KERN_ERR "%s: Flash erase failed.\n",
486 netxen_nic_driver_name);
487 return ret;
488 }
489
490 ret = netxen_rom_se(adapter, USER_START);
491 if (ret != FLASH_SUCCESS)
492 return ret;
493 ret = netxen_rom_se(adapter, FIXED_START);
494 if (ret != FLASH_SUCCESS)
495 return ret;
496
497 printk(KERN_INFO "%s: primary flash erased successfully\n",
498 netxen_nic_driver_name);
499
500 ret = netxen_backup_crbinit(adapter);
501 if (ret != FLASH_SUCCESS) {
502 printk(KERN_ERR "%s: CRBinit backup failed.\n",
503 netxen_nic_driver_name);
504 return ret;
505 }
506 printk(KERN_INFO "%s: CRBinit backup done.\n",
507 netxen_nic_driver_name);
508 ready_to_flash = 1;
509 }
510
511 if (!ready_to_flash) {
512 printk(KERN_ERR "%s: Invalid write sequence, returning...\n",
513 netxen_nic_driver_name);
514 return -EINVAL;
515 }
516
517 return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len);
518}
519
455static void 520static void
456netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) 521netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
457{ 522{
@@ -721,6 +786,7 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
721 .get_link = netxen_nic_get_link, 786 .get_link = netxen_nic_get_link,
722 .get_eeprom_len = netxen_nic_get_eeprom_len, 787 .get_eeprom_len = netxen_nic_get_eeprom_len,
723 .get_eeprom = netxen_nic_get_eeprom, 788 .get_eeprom = netxen_nic_get_eeprom,
789 .set_eeprom = netxen_nic_set_eeprom,
724 .get_ringparam = netxen_nic_get_ringparam, 790 .get_ringparam = netxen_nic_get_ringparam,
725 .get_pauseparam = netxen_nic_get_pauseparam, 791 .get_pauseparam = netxen_nic_get_pauseparam,
726 .set_pauseparam = netxen_nic_set_pauseparam, 792 .set_pauseparam = netxen_nic_set_pauseparam,
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 00d0524fef13..f7bb8c90537c 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -277,6 +277,7 @@ unsigned long netxen_decode_crb_addr(unsigned long addr)
277 277
278static long rom_max_timeout = 10000; 278static long rom_max_timeout = 10000;
279static long rom_lock_timeout = 1000000; 279static long rom_lock_timeout = 1000000;
280static long rom_write_timeout = 700;
280 281
281static inline int rom_lock(struct netxen_adapter *adapter) 282static inline int rom_lock(struct netxen_adapter *adapter)
282{ 283{
@@ -405,7 +406,7 @@ do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
405{ 406{
406 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); 407 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
407 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); 408 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
408 udelay(100); /* prevent bursting on CRB */ 409 udelay(70); /* prevent bursting on CRB */
409 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); 410 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
410 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb); 411 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
411 if (netxen_wait_rom_done(adapter)) { 412 if (netxen_wait_rom_done(adapter)) {
@@ -414,13 +415,46 @@ do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
414 } 415 }
415 /* reset abyte_cnt and dummy_byte_cnt */ 416 /* reset abyte_cnt and dummy_byte_cnt */
416 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); 417 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
417 udelay(100); /* prevent bursting on CRB */ 418 udelay(70); /* prevent bursting on CRB */
418 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); 419 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
419 420
420 *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA); 421 *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
421 return 0; 422 return 0;
422} 423}
423 424
425static inline int
426do_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
427 u8 *bytes, size_t size)
428{
429 int addridx;
430 int ret = 0;
431
432 for (addridx = addr; addridx < (addr + size); addridx += 4) {
433 ret = do_rom_fast_read(adapter, addridx, (int *)bytes);
434 if (ret != 0)
435 break;
436 bytes += 4;
437 }
438
439 return ret;
440}
441
442int
443netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
444 u8 *bytes, size_t size)
445{
446 int ret;
447
448 ret = rom_lock(adapter);
449 if (ret < 0)
450 return ret;
451
452 ret = do_rom_fast_read_words(adapter, addr, bytes, size);
453
454 netxen_rom_unlock(adapter);
455 return ret;
456}
457
424int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) 458int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
425{ 459{
426 int ret; 460 int ret;
@@ -444,6 +478,152 @@ int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data)
444 netxen_rom_unlock(adapter); 478 netxen_rom_unlock(adapter);
445 return ret; 479 return ret;
446} 480}
481
482static inline int do_rom_fast_write_words(struct netxen_adapter *adapter,
483 int addr, u8 *bytes, size_t size)
484{
485 int addridx = addr;
486 int ret = 0;
487
488 while (addridx < (addr + size)) {
489 int last_attempt = 0;
490 int timeout = 0;
491 int data;
492
493 data = *(u32*)bytes;
494
495 ret = do_rom_fast_write(adapter, addridx, data);
496 if (ret < 0)
497 return ret;
498
499 while(1) {
500 int data1;
501
502 do_rom_fast_read(adapter, addridx, &data1);
503 if (data1 == data)
504 break;
505
506 if (timeout++ >= rom_write_timeout) {
507 if (last_attempt++ < 4) {
508 ret = do_rom_fast_write(adapter,
509 addridx, data);
510 if (ret < 0)
511 return ret;
512 }
513 else {
514 printk(KERN_INFO "Data write did not "
515 "succeed at address 0x%x\n", addridx);
516 break;
517 }
518 }
519 }
520
521 bytes += 4;
522 addridx += 4;
523 }
524
525 return ret;
526}
527
528int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr,
529 u8 *bytes, size_t size)
530{
531 int ret = 0;
532
533 ret = rom_lock(adapter);
534 if (ret < 0)
535 return ret;
536
537 ret = do_rom_fast_write_words(adapter, addr, bytes, size);
538 netxen_rom_unlock(adapter);
539
540 return ret;
541}
542
543int netxen_rom_wrsr(struct netxen_adapter *adapter, int data)
544{
545 int ret;
546
547 ret = netxen_rom_wren(adapter);
548 if (ret < 0)
549 return ret;
550
551 netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_WDATA, data);
552 netxen_crb_writelit_adapter(adapter,
553 NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0x1);
554
555 ret = netxen_wait_rom_done(adapter);
556 if (ret < 0)
557 return ret;
558
559 return netxen_rom_wip_poll(adapter);
560}
561
562int netxen_rom_rdsr(struct netxen_adapter *adapter)
563{
564 int ret;
565
566 ret = rom_lock(adapter);
567 if (ret < 0)
568 return ret;
569
570 ret = netxen_do_rom_rdsr(adapter);
571 netxen_rom_unlock(adapter);
572 return ret;
573}
574
575int netxen_backup_crbinit(struct netxen_adapter *adapter)
576{
577 int ret = FLASH_SUCCESS;
578 int val;
579 char *buffer = kmalloc(FLASH_SECTOR_SIZE, GFP_KERNEL);
580
581 if (!buffer)
582 return -ENOMEM;
583 /* unlock sector 63 */
584 val = netxen_rom_rdsr(adapter);
585 val = val & 0xe3;
586 ret = netxen_rom_wrsr(adapter, val);
587 if (ret != FLASH_SUCCESS)
588 goto out_kfree;
589
590 ret = netxen_rom_wip_poll(adapter);
591 if (ret != FLASH_SUCCESS)
592 goto out_kfree;
593
594 /* copy sector 0 to sector 63 */
595 ret = netxen_rom_fast_read_words(adapter, CRBINIT_START,
596 buffer, FLASH_SECTOR_SIZE);
597 if (ret != FLASH_SUCCESS)
598 goto out_kfree;
599
600 ret = netxen_rom_fast_write_words(adapter, FIXED_START,
601 buffer, FLASH_SECTOR_SIZE);
602 if (ret != FLASH_SUCCESS)
603 goto out_kfree;
604
605 /* lock sector 63 */
606 val = netxen_rom_rdsr(adapter);
607 if (!(val & 0x8)) {
608 val |= (0x1 << 2);
609 /* lock sector 63 */
610 if (netxen_rom_wrsr(adapter, val) == 0) {
611 ret = netxen_rom_wip_poll(adapter);
612 if (ret != FLASH_SUCCESS)
613 goto out_kfree;
614
615 /* lock SR writes */
616 ret = netxen_rom_wip_poll(adapter);
617 if (ret != FLASH_SUCCESS)
618 goto out_kfree;
619 }
620 }
621
622out_kfree:
623 kfree(buffer);
624 return ret;
625}
626
447int netxen_do_rom_se(struct netxen_adapter *adapter, int addr) 627int netxen_do_rom_se(struct netxen_adapter *adapter, int addr)
448{ 628{
449 netxen_rom_wren(adapter); 629 netxen_rom_wren(adapter);
@@ -458,6 +638,27 @@ int netxen_do_rom_se(struct netxen_adapter *adapter, int addr)
458 return netxen_rom_wip_poll(adapter); 638 return netxen_rom_wip_poll(adapter);
459} 639}
460 640
641void check_erased_flash(struct netxen_adapter *adapter, int addr)
642{
643 int i;
644 int val;
645 int count = 0, erased_errors = 0;
646 int range;
647
648 range = (addr == USER_START) ? FIXED_START : addr + FLASH_SECTOR_SIZE;
649
650 for (i = addr; i < range; i += 4) {
651 netxen_rom_fast_read(adapter, i, &val);
652 if (val != 0xffffffff)
653 erased_errors++;
654 count++;
655 }
656
657 if (erased_errors)
658 printk(KERN_INFO "0x%x out of 0x%x words fail to be erased "
659 "for sector address: %x\n", erased_errors, count, addr);
660}
661
461int netxen_rom_se(struct netxen_adapter *adapter, int addr) 662int netxen_rom_se(struct netxen_adapter *adapter, int addr)
462{ 663{
463 int ret = 0; 664 int ret = 0;
@@ -466,6 +667,68 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr)
466 } 667 }
467 ret = netxen_do_rom_se(adapter, addr); 668 ret = netxen_do_rom_se(adapter, addr);
468 netxen_rom_unlock(adapter); 669 netxen_rom_unlock(adapter);
670 msleep(30);
671 check_erased_flash(adapter, addr);
672
673 return ret;
674}
675
676int
677netxen_flash_erase_sections(struct netxen_adapter *adapter, int start, int end)
678{
679 int ret = FLASH_SUCCESS;
680 int i;
681
682 for (i = start; i < end; i++) {
683 ret = netxen_rom_se(adapter, i * FLASH_SECTOR_SIZE);
684 if (ret)
685 break;
686 ret = netxen_rom_wip_poll(adapter);
687 if (ret < 0)
688 return ret;
689 }
690
691 return ret;
692}
693
694int
695netxen_flash_erase_secondary(struct netxen_adapter *adapter)
696{
697 int ret = FLASH_SUCCESS;
698 int start, end;
699
700 start = SECONDARY_START / FLASH_SECTOR_SIZE;
701 end = USER_START / FLASH_SECTOR_SIZE;
702 ret = netxen_flash_erase_sections(adapter, start, end);
703
704 return ret;
705}
706
707int
708netxen_flash_erase_primary(struct netxen_adapter *adapter)
709{
710 int ret = FLASH_SUCCESS;
711 int start, end;
712
713 start = PRIMARY_START / FLASH_SECTOR_SIZE;
714 end = SECONDARY_START / FLASH_SECTOR_SIZE;
715 ret = netxen_flash_erase_sections(adapter, start, end);
716
717 return ret;
718}
719
720int netxen_flash_unlock(struct netxen_adapter *adapter)
721{
722 int ret = 0;
723
724 ret = netxen_rom_wrsr(adapter, 0);
725 if (ret < 0)
726 return ret;
727
728 ret = netxen_rom_wren(adapter);
729 if (ret < 0)
730 return ret;
731
469 return ret; 732 return ret;
470} 733}
471 734