static int netxen_init_old_ctx(struct netxen_adapter *adapter) { struct netxen_recv_context *recv_ctx; struct nx_host_rds_ring *rds_ring; struct nx_host_sds_ring *sds_ring; struct nx_host_tx_ring *tx_ring; int ring; int port = adapter->portnum; struct netxen_ring_ctx *hwctx; u32 signature; tx_ring = adapter->tx_ring; recv_ctx = &adapter->recv_ctx; hwctx = recv_ctx->hwctx; hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr); hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc); for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; hwctx->rcv_rings[ring].addr = cpu_to_le64(rds_ring->phys_addr); hwctx->rcv_rings[ring].size = cpu_to_le32(rds_ring->num_desc); } for (ring = 0; ring < adapter->max_sds_rings; ring++) { sds_ring = &recv_ctx->sds_rings[ring]; if (ring == 0) { hwctx->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr); hwctx->sts_ring_size = cpu_to_le32(sds_ring->num_desc); } hwctx->sts_rings[ring].addr = cpu_to_le64(sds_ring->phys_addr); hwctx->sts_rings[ring].size = cpu_to_le32(sds_ring->num_desc); hwctx->sts_rings[ring].msi_index = cpu_to_le16(ring); } hwctx->sts_ring_count = cpu_to_le32(adapter->max_sds_rings); signature = (adapter->max_sds_rings > 1) ? NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE; NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port), lower32(recv_ctx->phys_addr)); NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port), upper32(recv_ctx->phys_addr)); NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), signature | port); return 0; }
static int netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct netxen_adapter *adapter = netdev_priv(dev); u32 wol_cfg = 0; if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) return -EOPNOTSUPP; if (wol->wolopts & ~WAKE_MAGIC) return -EOPNOTSUPP; wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV); if (!(wol_cfg & (1 << adapter->portnum))) return -EOPNOTSUPP; wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG); if (wol->wolopts & WAKE_MAGIC) wol_cfg |= 1UL << adapter->portnum; else wol_cfg &= ~(1UL << adapter->portnum); NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg); return 0; }
static int netxen_api_lock(struct netxen_adapter *adapter) { u32 done = 0, timeout = 0; for (;;) { /* Acquire PCIE HW semaphore5 */ done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_LOCK)); if (done == 1) break; if (++timeout >= NX_OS_CRB_RETRY_COUNT) { printk(KERN_ERR "%s: lock timeout.\n", __func__); return -1; } msleep(1); } #if 0 NXWR32(adapter, NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER); #endif return 0; }
static u32 netxen_issue_cmd(struct netxen_adapter *adapter, u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd) { u32 rsp; u32 signature = 0; u32 rcode = NX_RCODE_SUCCESS; signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version); /* Acquire semaphore before accessing CRB */ if (netxen_api_lock(adapter)) return NX_RCODE_TIMEOUT; NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature); NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1); NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2); NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3); NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd)); rsp = netxen_poll_rsp(adapter); if (rsp == NX_CDRP_RSP_TIMEOUT) { printk(KERN_ERR "%s: card response timeout.\n", netxen_nic_driver_name); rcode = NX_RCODE_TIMEOUT; } else if (rsp == NX_CDRP_RSP_FAIL) { rcode = NXRD32(adapter, NX_ARG1_CRB_OFFSET); printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); } /* Release semaphore */ netxen_api_unlock(adapter); return rcode; }
static int netxen_nic_reg_test(struct net_device *dev) { struct netxen_adapter *adapter = netdev_priv(dev); u32 data_read, data_written; data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0)); if ((data_read & 0xffff) != PHAN_VENDOR_ID) return 1; data_written = (u32)0xa5a5a5a5; NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written); data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST); if (data_written != data_read) return 1; return 0; }
static int unm_nic_reg_test(struct net_device *netdev) { struct unm_adapter_s *adapter = netdev_priv(netdev); uint32_t data_read, data_written; // Read test data_read = NXRD32(adapter, UNM_PCIX_PH_REG(0)); if ((data_read & 0xffff) != PHAN_VENDOR_ID) { return 1; } // write test data_written = (uint32_t) 0xa5a5a5a5; NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written); data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST); if (data_written != data_read) { return 1; } return 0; }
static int netxen_nic_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause) { struct netxen_adapter *adapter = netdev_priv(dev); __u32 val; int port = adapter->physical_port; /* read mode */ if (adapter->ahw.port_type == NETXEN_NIC_GBE) { if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EIO; /* set flow control */ val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port)); if (pause->rx_pause) netxen_gb_rx_flowctl(val); else netxen_gb_unset_rx_flowctl(val); NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), val); /* set autoneg */ val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL); switch (port) { case 0: if (pause->tx_pause) netxen_gb_unset_gb0_mask(val); else netxen_gb_set_gb0_mask(val); break; case 1: if (pause->tx_pause) netxen_gb_unset_gb1_mask(val); else netxen_gb_set_gb1_mask(val); break; case 2: if (pause->tx_pause) netxen_gb_unset_gb2_mask(val); else netxen_gb_set_gb2_mask(val); break; case 3: default: if (pause->tx_pause) netxen_gb_unset_gb3_mask(val); else netxen_gb_set_gb3_mask(val); break; } NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val); } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) return -EIO; val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL); if (port == 0) { if (pause->tx_pause) netxen_xg_unset_xg0_mask(val); else netxen_xg_set_xg0_mask(val); } else { if (pause->tx_pause) netxen_xg_unset_xg1_mask(val); else netxen_xg_set_xg1_mask(val); } NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val); } else { printk(KERN_ERR "%s: Unknown board type: %x\n", netxen_nic_driver_name, adapter->ahw.port_type); } return 0; }
void netxen_free_hw_resources(struct netxen_adapter *adapter) { struct netxen_recv_context *recv_ctx; struct nx_host_rds_ring *rds_ring; struct nx_host_sds_ring *sds_ring; struct nx_host_tx_ring *tx_ring; int ring; int port = adapter->portnum; if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { if (!test_and_clear_bit(__NX_FW_ATTACHED, &adapter->state)) goto done; nx_fw_cmd_destroy_rx_ctx(adapter); nx_fw_cmd_destroy_tx_ctx(adapter); } else { netxen_api_lock(adapter); NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), NETXEN_CTX_D3_RESET | port); netxen_api_unlock(adapter); } /* Allow dma queues to drain after context reset */ msleep(20); done: recv_ctx = &adapter->recv_ctx; if (recv_ctx->hwctx != NULL) { pci_free_consistent(adapter->pdev, sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), recv_ctx->hwctx, recv_ctx->phys_addr); recv_ctx->hwctx = NULL; } tx_ring = adapter->tx_ring; if (tx_ring->desc_head != NULL) { pci_free_consistent(adapter->pdev, TX_DESC_RINGSIZE(tx_ring), tx_ring->desc_head, tx_ring->phys_addr); tx_ring->desc_head = NULL; } for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; if (rds_ring->desc_head != NULL) { pci_free_consistent(adapter->pdev, RCV_DESC_RINGSIZE(rds_ring), rds_ring->desc_head, rds_ring->phys_addr); rds_ring->desc_head = NULL; } } for (ring = 0; ring < adapter->max_sds_rings; ring++) { sds_ring = &recv_ctx->sds_rings[ring]; if (sds_ring->desc_head != NULL) { pci_free_consistent(adapter->pdev, STATUS_DESC_RINGSIZE(sds_ring), sds_ring->desc_head, sds_ring->phys_addr); sds_ring->desc_head = NULL; } } }