int netxen_alloc_hw_resources(struct netxen_adapter *adapter) { void *addr; int err = 0; int ring; 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; struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; int port = adapter->portnum; recv_ctx = &adapter->recv_ctx; tx_ring = adapter->tx_ring; addr = pci_alloc_consistent(pdev, sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), &recv_ctx->phys_addr); if (addr == NULL) { dev_err(&pdev->dev, "failed to allocate hw context\n"); return -ENOMEM; } memset(addr, 0, sizeof(struct netxen_ring_ctx)); recv_ctx->hwctx = (struct netxen_ring_ctx *)addr; recv_ctx->hwctx->ctx_id = cpu_to_le32(port); recv_ctx->hwctx->cmd_consumer_offset = cpu_to_le64(recv_ctx->phys_addr + sizeof(struct netxen_ring_ctx)); tx_ring->hw_consumer = (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx)); /* cmd desc ring */ addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring), &tx_ring->phys_addr); if (addr == NULL) { dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n", netdev->name); err = -ENOMEM; goto err_out_free; } tx_ring->desc_head = (struct cmd_desc_type0 *)addr; for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; addr = pci_alloc_consistent(adapter->pdev, RCV_DESC_RINGSIZE(rds_ring), &rds_ring->phys_addr); if (addr == NULL) { dev_err(&pdev->dev, "%s: failed to allocate rds ring [%d]\n", netdev->name, ring); err = -ENOMEM; goto err_out_free; } rds_ring->desc_head = (struct rcv_desc *)addr; if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) rds_ring->crb_rcv_producer = netxen_get_ioaddr(adapter, recv_crb_registers[port].crb_rcv_producer[ring]); } for (ring = 0; ring < adapter->max_sds_rings; ring++) { sds_ring = &recv_ctx->sds_rings[ring]; addr = pci_alloc_consistent(adapter->pdev, STATUS_DESC_RINGSIZE(sds_ring), &sds_ring->phys_addr); if (addr == NULL) { dev_err(&pdev->dev, "%s: failed to allocate sds ring [%d]\n", netdev->name, ring); err = -ENOMEM; goto err_out_free; } sds_ring->desc_head = (struct status_desc *)addr; if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { sds_ring->crb_sts_consumer = netxen_get_ioaddr(adapter, recv_crb_registers[port].crb_sts_consumer[ring]); sds_ring->crb_intr_mask = netxen_get_ioaddr(adapter, recv_crb_registers[port].sw_int_mask[ring]); } } if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state)) goto done; if (reset_devices) nx_fw_cmd_reset_ctx(adapter); err = nx_fw_cmd_create_rx_ctx(adapter); if (err) goto err_out_free; err = nx_fw_cmd_create_tx_ctx(adapter); if (err) goto err_out_free; } else { err = netxen_init_old_ctx(adapter); if (err) goto err_out_free; } done: return 0; err_out_free: netxen_free_hw_resources(adapter); return err; }
int netxen_alloc_hw_resources(struct netxen_adapter *adapter) { struct netxen_hardware_context *hw = &adapter->ahw; u32 state = 0; void *addr; int err = 0; int ctx, ring; struct netxen_recv_context *recv_ctx; struct nx_host_rds_ring *rds_ring; err = netxen_receive_peg_ready(adapter); if (err) { printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n", state); return err; } addr = pci_alloc_consistent(adapter->pdev, sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), &adapter->ctx_desc_phys_addr); if (addr == NULL) { DPRINTK(ERR, "failed to allocate hw context\n"); return -ENOMEM; } memset(addr, 0, sizeof(struct netxen_ring_ctx)); adapter->ctx_desc = (struct netxen_ring_ctx *)addr; adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum); adapter->ctx_desc->cmd_consumer_offset = cpu_to_le64(adapter->ctx_desc_phys_addr + sizeof(struct netxen_ring_ctx)); adapter->cmd_consumer = (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx)); /* cmd desc ring */ addr = pci_alloc_consistent(adapter->pdev, sizeof(struct cmd_desc_type0) * adapter->max_tx_desc_count, &hw->cmd_desc_phys_addr); if (addr == NULL) { printk(KERN_ERR "%s failed to allocate tx desc ring\n", netxen_nic_driver_name); return -ENOMEM; } hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { recv_ctx = &adapter->recv_ctx[ctx]; for (ring = 0; ring < adapter->max_rds_rings; ring++) { /* rx desc ring */ rds_ring = &recv_ctx->rds_rings[ring]; addr = pci_alloc_consistent(adapter->pdev, RCV_DESC_RINGSIZE, &rds_ring->phys_addr); if (addr == NULL) { printk(KERN_ERR "%s failed to allocate rx " "desc ring[%d]\n", netxen_nic_driver_name, ring); err = -ENOMEM; goto err_out_free; } rds_ring->desc_head = (struct rcv_desc *)addr; if (adapter->fw_major < 4) rds_ring->crb_rcv_producer = recv_crb_registers[adapter->portnum]. crb_rcv_producer[ring]; } /* status desc ring */ addr = pci_alloc_consistent(adapter->pdev, STATUS_DESC_RINGSIZE, &recv_ctx->rcv_status_desc_phys_addr); if (addr == NULL) { printk(KERN_ERR "%s failed to allocate sts desc ring\n", netxen_nic_driver_name); err = -ENOMEM; goto err_out_free; } recv_ctx->rcv_status_desc_head = (struct status_desc *)addr; if (adapter->fw_major < 4) recv_ctx->crb_sts_consumer = recv_crb_registers[adapter->portnum]. crb_sts_consumer; } if (adapter->fw_major >= 4) { adapter->intr_scheme = INTR_SCHEME_PERPORT; adapter->msi_mode = MSI_MODE_MULTIFUNC; err = nx_fw_cmd_create_rx_ctx(adapter); if (err) goto err_out_free; err = nx_fw_cmd_create_tx_ctx(adapter); if (err) goto err_out_free; } else { adapter->intr_scheme = adapter->pci_read_normalize(adapter, CRB_NIC_CAPABILITIES_FW); adapter->msi_mode = adapter->pci_read_normalize(adapter, CRB_NIC_MSI_MODE_FW); adapter->crb_intr_mask = sw_int_mask[adapter->portnum]; err = netxen_init_old_ctx(adapter); if (err) { netxen_free_hw_resources(adapter); return err; } } return 0; err_out_free: netxen_free_hw_resources(adapter); return err; }