diff options
author | Amit S. Kale <amitkale@netxen.com> | 2007-02-05 10:40:49 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-06 19:08:03 -0500 |
commit | 27d2ab54bdfaffdbdc1a81100dc53c6479c9db35 (patch) | |
tree | 27817bbfeb065a2a75ecce6f331596f002ddae7d /drivers/net | |
parent | 1fcca1a5fc81689d191b7132318970c969b4b635 (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>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 17 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 96 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 267 |
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); | |||
1028 | void netxen_load_firmware(struct netxen_adapter *adapter); | 1032 | void netxen_load_firmware(struct netxen_adapter *adapter); |
1029 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); | 1033 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); |
1030 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); | 1034 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); |
1035 | int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, | ||
1036 | u8 *bytes, size_t size); | ||
1037 | int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, | ||
1038 | u8 *bytes, size_t size); | ||
1039 | int netxen_flash_unlock(struct netxen_adapter *adapter); | ||
1040 | int netxen_backup_crbinit(struct netxen_adapter *adapter); | ||
1041 | int netxen_flash_erase_secondary(struct netxen_adapter *adapter); | ||
1042 | int netxen_flash_erase_primary(struct netxen_adapter *adapter); | ||
1043 | |||
1031 | int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data); | 1044 | int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data); |
1032 | int netxen_rom_se(struct netxen_adapter *adapter, int addr); | 1045 | int netxen_rom_se(struct netxen_adapter *adapter, int addr); |
1033 | int netxen_do_rom_se(struct netxen_adapter *adapter, int addr); | 1046 | int 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 | ||
95 | static int netxen_nic_get_eeprom_len(struct net_device *dev) | 96 | static 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 | ||
110 | static void | 101 | static 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 | ||
450 | static int | ||
451 | netxen_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 | |||
455 | static void | 520 | static void |
456 | netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) | 521 | netxen_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 | ||
278 | static long rom_max_timeout = 10000; | 278 | static long rom_max_timeout = 10000; |
279 | static long rom_lock_timeout = 1000000; | 279 | static long rom_lock_timeout = 1000000; |
280 | static long rom_write_timeout = 700; | ||
280 | 281 | ||
281 | static inline int rom_lock(struct netxen_adapter *adapter) | 282 | static 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 | ||
425 | static inline int | ||
426 | do_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 | |||
442 | int | ||
443 | netxen_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 | |||
424 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) | 458 | int 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 | |||
482 | static 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 | |||
528 | int 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 | |||
543 | int 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 | |||
562 | int 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 | |||
575 | int 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 | |||
622 | out_kfree: | ||
623 | kfree(buffer); | ||
624 | return ret; | ||
625 | } | ||
626 | |||
447 | int netxen_do_rom_se(struct netxen_adapter *adapter, int addr) | 627 | int 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 | ||
641 | void 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 | |||
461 | int netxen_rom_se(struct netxen_adapter *adapter, int addr) | 662 | int 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 | |||
676 | int | ||
677 | netxen_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 | |||
694 | int | ||
695 | netxen_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 | |||
707 | int | ||
708 | netxen_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 | |||
720 | int 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 | ||