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; netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, signature); netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, arg1); netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, arg2); netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, arg3); netxen_nic_write_w1(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) { netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode); printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); } /* Release semaphore */ netxen_api_unlock(adapter); return rcode; }
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; } } }