summaryrefslogtreecommitdiff
path: root/drivers/net/netxen/netxen_nic_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen/netxen_nic_init.c')
-rw-r--r--drivers/net/netxen/netxen_nic_init.c123
1 files changed, 102 insertions, 21 deletions
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 055bb61d6e77..7acf204e38c9 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -184,6 +184,13 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
kfree(recv_ctx->rds_rings);
skip_rds:
+ if (recv_ctx->sds_rings == NULL)
+ goto skip_sds;
+
+ for(ring = 0; ring < adapter->max_sds_rings; ring++)
+ recv_ctx->sds_rings[ring].consumer = 0;
+
+skip_sds:
if (adapter->tx_ring == NULL)
return;
@@ -214,6 +221,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
adapter->tx_ring = tx_ring;
tx_ring->num_desc = adapter->num_txd;
+ tx_ring->txq = netdev_get_tx_queue(netdev, 0);
cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring));
if (cmd_buf_arr == NULL) {
@@ -684,11 +692,84 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
}
int
+netxen_need_fw_reset(struct netxen_adapter *adapter)
+{
+ u32 count, old_count;
+ u32 val, version, major, minor, build;
+ int i, timeout;
+ u8 fw_type;
+
+ /* NX2031 firmware doesn't support heartbit */
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return 1;
+
+ /* last attempt had failed */
+ if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED)
+ return 1;
+
+ old_count = count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+
+ for (i = 0; i < 10; i++) {
+
+ timeout = msleep_interruptible(200);
+ if (timeout) {
+ NXWR32(adapter, CRB_CMDPEG_STATE,
+ PHAN_INITIALIZE_FAILED);
+ return -EINTR;
+ }
+
+ count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+ if (count != old_count)
+ break;
+ }
+
+ /* firmware is dead */
+ if (count == old_count)
+ return 1;
+
+ /* check if we have got newer or different file firmware */
+ if (adapter->fw) {
+
+ const struct firmware *fw = adapter->fw;
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
+ version = NETXEN_DECODE_VERSION(val);
+
+ major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+ minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+ build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
+
+ if (version > NETXEN_VERSION_CODE(major, minor, build))
+ return 1;
+
+ if (version == NETXEN_VERSION_CODE(major, minor, build)) {
+
+ val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL);
+ fw_type = (val & 0x4) ?
+ NX_P3_CT_ROMIMAGE : NX_P3_MN_ROMIMAGE;
+
+ if (adapter->fw_type != fw_type)
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static char *fw_name[] = {
+ "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin", "flash",
+};
+
+int
netxen_load_firmware(struct netxen_adapter *adapter)
{
u64 *ptr64;
u32 i, flashaddr, size;
const struct firmware *fw = adapter->fw;
+ struct pci_dev *pdev = adapter->pdev;
+
+ dev_info(&pdev->dev, "loading firmware from %s\n",
+ fw_name[adapter->fw_type]);
if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1);
@@ -756,7 +837,7 @@ static int
netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
{
__le32 val;
- u32 major, minor, build, ver, min_ver, bios;
+ u32 ver, min_ver, bios;
struct pci_dev *pdev = adapter->pdev;
const struct firmware *fw = adapter->fw;
@@ -768,21 +849,18 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
return -EINVAL;
val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
- major = (__force u32)val & 0xff;
- minor = ((__force u32)val >> 8) & 0xff;
- build = (__force u32)val >> 16;
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
min_ver = NETXEN_VERSION_CODE(4, 0, 216);
else
min_ver = NETXEN_VERSION_CODE(3, 4, 216);
- ver = NETXEN_VERSION_CODE(major, minor, build);
+ ver = NETXEN_DECODE_VERSION(val);
- if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
+ if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
dev_err(&pdev->dev,
"%s: firmware version %d.%d.%d unsupported\n",
- fwname, major, minor, build);
+ fwname, _major(ver), _minor(ver), _build(ver));
return -EINVAL;
}
@@ -798,22 +876,21 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
if (netxen_rom_fast_read(adapter,
NX_FW_VERSION_OFFSET, (int *)&val))
return -EIO;
- major = (__force u32)val & 0xff;
- minor = ((__force u32)val >> 8) & 0xff;
- build = (__force u32)val >> 16;
- if (NETXEN_VERSION_CODE(major, minor, build) > ver)
+ val = NETXEN_DECODE_VERSION(val);
+ if (val > ver) {
+ dev_info(&pdev->dev, "%s: firmware is older than flash\n",
+ fwname);
return -EINVAL;
+ }
NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
return 0;
}
-static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
-
void netxen_request_firmware(struct netxen_adapter *adapter)
{
u32 capability, flashed_ver;
- int fw_type;
+ u8 fw_type;
struct pci_dev *pdev = adapter->pdev;
int rc = 0;
@@ -830,6 +907,8 @@ request_mn:
netxen_rom_fast_read(adapter,
NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
+ flashed_ver = NETXEN_DECODE_VERSION(flashed_ver);
+
if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY);
if (capability & NX_PEG_TUNE_MN_PRESENT) {
@@ -838,6 +917,10 @@ request_mn:
}
}
+ fw_type = NX_FLASH_ROMIMAGE;
+ adapter->fw = NULL;
+ goto done;
+
request_fw:
rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev);
if (rc != 0) {
@@ -846,6 +929,7 @@ request_fw:
goto request_mn;
}
+ fw_type = NX_FLASH_ROMIMAGE;
adapter->fw = NULL;
goto done;
}
@@ -859,16 +943,13 @@ request_fw:
goto request_mn;
}
+ fw_type = NX_FLASH_ROMIMAGE;
adapter->fw = NULL;
goto done;
}
done:
- if (adapter->fw)
- dev_info(&pdev->dev, "loading firmware from file %s\n",
- fw_name[fw_type]);
- else
- dev_info(&pdev->dev, "loading firmware from flash\n");
+ adapter->fw_type = fw_type;
}
@@ -1327,10 +1408,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
smp_mb();
if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
- netif_tx_lock(netdev);
+ __netif_tx_lock(tx_ring->txq, smp_processor_id());
if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH)
netif_wake_queue(netdev);
- netif_tx_unlock(netdev);
+ __netif_tx_unlock(tx_ring->txq);
}
}
/*