*/
#include <linux/types.h>
+#include <linux/delay.h>
#include <asm/uaccess.h>
#include <linux/pci.h>
#include <asm/io.h>
#define NETXEN_NIC_STATS_LEN ARRAY_SIZE(netxen_nic_gstrings_stats)
static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
- "Register_Test_offline", "EEPROM_Test_offline",
- "Interrupt_Test_offline", "Loopback_Test_offline",
+ "Register_Test_on_offline",
"Link_Test_on_offline"
};
static int netxen_nic_get_eeprom_len(struct net_device *dev)
{
- struct netxen_port *port = netdev_priv(dev);
- struct netxen_adapter *adapter = port->adapter;
- int n;
-
- if ((netxen_rom_fast_read(adapter, 0, &n) == 0)
- && (n & NETXEN_ROM_ROUNDUP)) {
- n &= ~NETXEN_ROM_ROUNDUP;
- if (n < NETXEN_MAX_EEPROM_LEN)
- return n;
- }
- return 0;
+ return FLASH_TOTAL_SIZE;
}
static void
}
}
-static void
-netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
- /* options can be added depending upon the mode */
- wol->wolopts = 0;
-}
-
-static u32 netxen_nic_get_link(struct net_device *dev)
+static u32 netxen_nic_test_link(struct net_device *dev)
{
struct netxen_port *port = netdev_priv(dev);
struct netxen_adapter *adapter = port->adapter;
__u32 status;
+ int val;
/* read which mode */
if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
&status) != 0)
return -EIO;
- else
- return (netxen_get_phy_link(status));
+ else {
+ val = netxen_get_phy_link(status);
+ return !val;
+ }
} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
- int val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
- return val == XG_LINK_UP;
+ val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
+ return (val == XG_LINK_UP) ? 0 : 1;
}
return -EIO;
}
struct netxen_port *port = netdev_priv(dev);
struct netxen_adapter *adapter = port->adapter;
int offset;
+ int ret;
if (eeprom->len == 0)
return -EINVAL;
eeprom->magic = (port->pdev)->vendor | ((port->pdev)->device << 16);
- for (offset = 0; offset < eeprom->len; offset++)
- if (netxen_rom_fast_read
- (adapter, (8 * offset) + 8, (int *)eeprom->data) == -1)
- return -EIO;
+ offset = eeprom->offset;
+
+ ret = netxen_rom_fast_read_words(adapter, offset, bytes,
+ eeprom->len);
+ if (ret < 0)
+ return ret;
+
return 0;
}
+static int
+netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+ u8 * bytes)
+{
+ struct netxen_port *port = netdev_priv(dev);
+ struct netxen_adapter *adapter = port->adapter;
+ int offset = eeprom->offset;
+ static int flash_start;
+ static int ready_to_flash;
+ int ret;
+
+ if (flash_start == 0) {
+ netxen_halt_pegs(adapter);
+ ret = netxen_flash_unlock(adapter);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: Flash unlock failed.\n",
+ netxen_nic_driver_name);
+ return ret;
+ }
+ printk(KERN_INFO "%s: flash unlocked. \n",
+ netxen_nic_driver_name);
+ last_schedule_time = jiffies;
+ ret = netxen_flash_erase_secondary(adapter);
+ if (ret != FLASH_SUCCESS) {
+ printk(KERN_ERR "%s: Flash erase failed.\n",
+ netxen_nic_driver_name);
+ return ret;
+ }
+ printk(KERN_INFO "%s: secondary flash erased successfully.\n",
+ netxen_nic_driver_name);
+ flash_start = 1;
+ return 0;
+ }
+
+ if (offset == BOOTLD_START) {
+ ret = netxen_flash_erase_primary(adapter);
+ if (ret != FLASH_SUCCESS) {
+ printk(KERN_ERR "%s: Flash erase failed.\n",
+ netxen_nic_driver_name);
+ return ret;
+ }
+
+ ret = netxen_rom_se(adapter, USER_START);
+ if (ret != FLASH_SUCCESS)
+ return ret;
+ ret = netxen_rom_se(adapter, FIXED_START);
+ if (ret != FLASH_SUCCESS)
+ return ret;
+
+ printk(KERN_INFO "%s: primary flash erased successfully\n",
+ netxen_nic_driver_name);
+
+ ret = netxen_backup_crbinit(adapter);
+ if (ret != FLASH_SUCCESS) {
+ printk(KERN_ERR "%s: CRBinit backup failed.\n",
+ netxen_nic_driver_name);
+ return ret;
+ }
+ printk(KERN_INFO "%s: CRBinit backup done.\n",
+ netxen_nic_driver_name);
+ ready_to_flash = 1;
+ }
+
+ if (!ready_to_flash) {
+ printk(KERN_ERR "%s: Invalid write sequence, returning...\n",
+ netxen_nic_driver_name);
+ return -EINVAL;
+ }
+
+ return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len);
+}
+
static void
netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
{
static int netxen_nic_reg_test(struct net_device *dev)
{
- struct netxen_port *port = netdev_priv(dev);
- struct netxen_adapter *adapter = port->adapter;
- u32 data_read, data_written, save;
- __u32 mode;
-
- /*
- * first test the "Read Only" registers by writing which mode
- */
- netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode);
- if (netxen_get_niu_enable_ge(mode)) { /* GB Mode */
- netxen_nic_read_w0(adapter,
- NETXEN_NIU_GB_MII_MGMT_STATUS(port->portnum),
- &data_read);
-
- save = data_read;
- if (data_read)
- data_written = data_read & NETXEN_NIC_INVALID_DATA;
- else
- data_written = NETXEN_NIC_INVALID_DATA;
- netxen_nic_write_w0(adapter,
- NETXEN_NIU_GB_MII_MGMT_STATUS(port->
- portnum),
- data_written);
- netxen_nic_read_w0(adapter,
- NETXEN_NIU_GB_MII_MGMT_STATUS(port->portnum),
- &data_read);
-
- if (data_written == data_read) {
- netxen_nic_write_w0(adapter,
- NETXEN_NIU_GB_MII_MGMT_STATUS(port->
- portnum),
- save);
-
- return 0;
- }
-
- /* netxen_niu_gb_mii_mgmt_indicators is read only */
- netxen_nic_read_w0(adapter,
- NETXEN_NIU_GB_MII_MGMT_INDICATE(port->
- portnum),
- &data_read);
-
- save = data_read;
- if (data_read)
- data_written = data_read & NETXEN_NIC_INVALID_DATA;
- else
- data_written = NETXEN_NIC_INVALID_DATA;
- netxen_nic_write_w0(adapter,
- NETXEN_NIU_GB_MII_MGMT_INDICATE(port->
- portnum),
- data_written);
-
- netxen_nic_read_w0(adapter,
- NETXEN_NIU_GB_MII_MGMT_INDICATE(port->
- portnum),
- &data_read);
-
- if (data_written == data_read) {
- netxen_nic_write_w0(adapter,
- NETXEN_NIU_GB_MII_MGMT_INDICATE
- (port->portnum), save);
- return 0;
- }
+ struct netxen_adapter *adapter = netdev_priv(dev);
+ u32 data_read, data_written;
- /* netxen_niu_gb_interface_status is read only */
- netxen_nic_read_w0(adapter,
- NETXEN_NIU_GB_INTERFACE_STATUS(port->
- portnum),
- &data_read);
-
- save = data_read;
- if (data_read)
- data_written = data_read & NETXEN_NIC_INVALID_DATA;
- else
- data_written = NETXEN_NIC_INVALID_DATA;
- netxen_nic_write_w0(adapter,
- NETXEN_NIU_GB_INTERFACE_STATUS(port->
- portnum),
- data_written);
+ netxen_nic_read_w0(adapter, NETXEN_PCIX_PH_REG(0), &data_read);
+ if ((data_read & 0xffff) != PHAN_VENDOR_ID)
+ return 1;
- netxen_nic_read_w0(adapter,
- NETXEN_NIU_GB_INTERFACE_STATUS(port->
- portnum),
- &data_read);
+ data_written = (u32)0xa5a5a5a5;
- if (data_written == data_read) {
- netxen_nic_write_w0(adapter,
- NETXEN_NIU_GB_INTERFACE_STATUS
- (port->portnum), save);
+ netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written);
+ data_read = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_SCRATCHPAD_TEST));
+ if (data_written != data_read)
+ return 1;
- return 0;
- }
- } /* GB Mode */
- return 1;
+ return 0;
}
static int netxen_nic_diag_test_count(struct net_device *dev)
{
if (eth_test->flags == ETH_TEST_FL_OFFLINE) { /* offline tests */
/* link test */
- if (!(data[4] = (u64) netxen_nic_get_link(dev)))
+ if ((data[1] = (u64) netxen_nic_test_link(dev)))
eth_test->flags |= ETH_TEST_FL_FAILED;
- if (netif_running(dev))
- dev->stop(dev);
-
/* register tests */
- if (!(data[0] = netxen_nic_reg_test(dev)))
+ if ((data[0] = netxen_nic_reg_test(dev)))
eth_test->flags |= ETH_TEST_FL_FAILED;
- /* other tests pass as of now */
- data[1] = data[2] = data[3] = 1;
- if (netif_running(dev))
- dev->open(dev);
} else { /* online tests */
- /* link test */
- if (!(data[4] = (u64) netxen_nic_get_link(dev)))
+ /* register tests */
+ if((data[0] = netxen_nic_reg_test(dev)))
eth_test->flags |= ETH_TEST_FL_FAILED;
- /* other tests pass by default */
- data[0] = data[1] = data[2] = data[3] = 1;
+ /* link test */
+ if ((data[1] = (u64) netxen_nic_test_link(dev)))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
}
}
.get_drvinfo = netxen_nic_get_drvinfo,
.get_regs_len = netxen_nic_get_regs_len,
.get_regs = netxen_nic_get_regs,
- .get_wol = netxen_nic_get_wol,
- .get_link = netxen_nic_get_link,
+ .get_link = ethtool_op_get_link,
.get_eeprom_len = netxen_nic_get_eeprom_len,
.get_eeprom = netxen_nic_get_eeprom,
+ .set_eeprom = netxen_nic_set_eeprom,
.get_ringparam = netxen_nic_get_ringparam,
.get_pauseparam = netxen_nic_get_pauseparam,
.set_pauseparam = netxen_nic_set_pauseparam,