]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/qlcnic/qlcnic_ctx.c
qlcnic: restore NPAR config data after recovery
[net-next-2.6.git] / drivers / net / qlcnic / qlcnic_ctx.c
index 1e1dc58cddca38105ec3b56cd0039de4112cd67f..cc5d861d9a128bfc932da00a6bb0917a7ac26931 100644 (file)
@@ -152,9 +152,14 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
 
        prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr);
 
-       cap = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN);
+       cap = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN
+                                               | QLCNIC_CAP0_VALIDOFF);
        cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS);
 
+       prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx,
+                                                        msix_handler);
+       prq->txrx_sds_binding = nsds_rings - 1;
+
        prq->capabilities[0] = cpu_to_le32(cap);
        prq->host_int_crb_mode =
                cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED);
@@ -175,6 +180,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
        for (i = 0; i < nrds_rings; i++) {
 
                rds_ring = &recv_ctx->rds_rings[i];
+               rds_ring->producer = 0;
 
                prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
                prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
@@ -188,6 +194,8 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
        for (i = 0; i < nsds_rings; i++) {
 
                sds_ring = &recv_ctx->sds_rings[i];
+               sds_ring->consumer = 0;
+               memset(sds_ring->desc_head, 0, STATUS_DESC_RINGSIZE(sds_ring));
 
                prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
                prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
@@ -216,12 +224,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
                rds_ring = &recv_ctx->rds_rings[i];
 
                reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
-               if (adapter->fw_hal_version == QLCNIC_FW_BASE)
-                       rds_ring->crb_rcv_producer = qlcnic_get_ioaddr(adapter,
-                               QLCNIC_REG(reg - 0x200));
-               else
-                       rds_ring->crb_rcv_producer = adapter->ahw.pci_base0 +
-                               reg;
+               rds_ring->crb_rcv_producer = adapter->ahw.pci_base0 + reg;
        }
 
        prsp_sds = ((struct qlcnic_cardrsp_sds_ring *)
@@ -233,16 +236,8 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
                reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
                reg2 = le32_to_cpu(prsp_sds[i].interrupt_crb);
 
-               if (adapter->fw_hal_version == QLCNIC_FW_BASE) {
-                       sds_ring->crb_sts_consumer = qlcnic_get_ioaddr(adapter,
-                               QLCNIC_REG(reg - 0x200));
-                       sds_ring->crb_intr_mask = qlcnic_get_ioaddr(adapter,
-                               QLCNIC_REG(reg2 - 0x200));
-               } else {
-                       sds_ring->crb_sts_consumer = adapter->ahw.pci_base0 +
-                               reg;
-                       sds_ring->crb_intr_mask = adapter->ahw.pci_base0 + reg2;
-               }
+               sds_ring->crb_sts_consumer = adapter->ahw.pci_base0 + reg;
+               sds_ring->crb_intr_mask = adapter->ahw.pci_base0 + reg2;
        }
 
        recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
@@ -272,6 +267,8 @@ qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter)
                dev_err(&adapter->pdev->dev,
                        "Failed to destroy rx ctx in firmware\n");
        }
+
+       recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED;
 }
 
 static int
@@ -288,6 +285,11 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
        dma_addr_t      rq_phys_addr, rsp_phys_addr;
        struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
 
+       /* reset host resources */
+       tx_ring->producer = 0;
+       tx_ring->sw_consumer = 0;
+       *(tx_ring->hw_consumer) = 0;
+
        rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx);
        rq_addr = pci_alloc_consistent(adapter->pdev,
                rq_size, &rq_phys_addr);
@@ -337,12 +339,7 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
 
        if (err == QLCNIC_RCODE_SUCCESS) {
                temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
-               if (adapter->fw_hal_version == QLCNIC_FW_BASE)
-                       tx_ring->crb_cmd_producer = qlcnic_get_ioaddr(adapter,
-                               QLCNIC_REG(temp - 0x200));
-               else
-                       tx_ring->crb_cmd_producer = adapter->ahw.pci_base0 +
-                               temp;
+               tx_ring->crb_cmd_producer = adapter->ahw.pci_base0 + temp;
 
                adapter->tx_context_id =
                        le16_to_cpu(prsp->context_id);
@@ -471,15 +468,6 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
                sds_ring->desc_head = (struct status_desc *)addr;
        }
 
-
-       err = qlcnic_fw_cmd_create_rx_ctx(adapter);
-       if (err)
-               goto err_out_free;
-       err = qlcnic_fw_cmd_create_tx_ctx(adapter);
-       if (err)
-               goto err_out_free;
-
-       set_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
        return 0;
 
 err_out_free:
@@ -487,15 +475,27 @@ err_out_free:
        return err;
 }
 
-void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
+
+int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter)
 {
-       struct qlcnic_recv_context *recv_ctx;
-       struct qlcnic_host_rds_ring *rds_ring;
-       struct qlcnic_host_sds_ring *sds_ring;
-       struct qlcnic_host_tx_ring *tx_ring;
-       int ring;
+       int err;
+
+       err = qlcnic_fw_cmd_create_rx_ctx(adapter);
+       if (err)
+               return err;
+
+       err = qlcnic_fw_cmd_create_tx_ctx(adapter);
+       if (err) {
+               qlcnic_fw_cmd_destroy_rx_ctx(adapter);
+               return err;
+       }
 
+       set_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
+       return 0;
+}
 
+void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter)
+{
        if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) {
                qlcnic_fw_cmd_destroy_rx_ctx(adapter);
                qlcnic_fw_cmd_destroy_tx_ctx(adapter);
@@ -503,6 +503,15 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
                /* Allow dma queues to drain after context reset */
                msleep(20);
        }
+}
+
+void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
+{
+       struct qlcnic_recv_context *recv_ctx;
+       struct qlcnic_host_rds_ring *rds_ring;
+       struct qlcnic_host_sds_ring *sds_ring;
+       struct qlcnic_host_tx_ring *tx_ring;
+       int ring;
 
        recv_ctx = &adapter->recv_ctx;
 
@@ -589,11 +598,10 @@ int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
                        0,
                        QLCNIC_CDRP_CMD_MAC_ADDRESS);
 
-       if (err == QLCNIC_RCODE_SUCCESS) {
+       if (err == QLCNIC_RCODE_SUCCESS)
                qlcnic_fetch_mac(adapter, QLCNIC_ARG1_CRB_OFFSET,
                                QLCNIC_ARG2_CRB_OFFSET, 0, mac);
-               dev_info(&adapter->pdev->dev, "MAC address: %pM\n", mac);
-       } else {
+       else {
                dev_err(&adapter->pdev->dev,
                        "Failed to get mac address%d\n", err);
                err = -EIO;
@@ -603,7 +611,8 @@ int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
 }
 
 /* Get info of a NIC partition */
-int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, u8 func_id)
+int qlcnic_get_nic_info(struct qlcnic_adapter *adapter,
+                               struct qlcnic_info *npar_info, u8 func_id)
 {
        int     err;
        dma_addr_t nic_dma_t;
@@ -627,24 +636,25 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, u8 func_id)
                        QLCNIC_CDRP_CMD_GET_NIC_INFO);
 
        if (err == QLCNIC_RCODE_SUCCESS) {
-               adapter->physical_port = le16_to_cpu(nic_info->phys_port);
-               adapter->switch_mode = le16_to_cpu(nic_info->switch_mode);
-               adapter->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques);
-               adapter->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques);
-               adapter->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw);
-               adapter->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw);
-               adapter->max_mtu = le16_to_cpu(nic_info->max_mtu);
-               adapter->capabilities = le32_to_cpu(nic_info->capabilities);
-               adapter->max_mac_filters = nic_info->max_mac_filters;
+               npar_info->pci_func = le16_to_cpu(nic_info->pci_func);
+               npar_info->op_mode = le16_to_cpu(nic_info->op_mode);
+               npar_info->phys_port = le16_to_cpu(nic_info->phys_port);
+               npar_info->switch_mode = le16_to_cpu(nic_info->switch_mode);
+               npar_info->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques);
+               npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques);
+               npar_info->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw);
+               npar_info->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw);
+               npar_info->capabilities = le32_to_cpu(nic_info->capabilities);
+               npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu);
 
                dev_info(&adapter->pdev->dev,
                        "phy port: %d switch_mode: %d,\n"
                        "\tmax_tx_q: %d max_rx_q: %d min_tx_bw: 0x%x,\n"
                        "\tmax_tx_bw: 0x%x max_mtu:0x%x, capabilities: 0x%x\n",
-                       adapter->physical_port, adapter->switch_mode,
-                       adapter->max_tx_ques, adapter->max_rx_ques,
-                       adapter->min_tx_bw, adapter->max_tx_bw,
-                       adapter->max_mtu, adapter->capabilities);
+                       npar_info->phys_port, npar_info->switch_mode,
+                       npar_info->max_tx_ques, npar_info->max_rx_ques,
+                       npar_info->min_tx_bw, npar_info->max_tx_bw,
+                       npar_info->max_mtu, npar_info->capabilities);
        } else {
                dev_err(&adapter->pdev->dev,
                        "Failed to get nic info%d\n", err);
@@ -659,7 +669,6 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, u8 func_id)
 int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic)
 {
        int err = -EIO;
-       u32 func_state;
        dma_addr_t nic_dma_t;
        void *nic_info_addr;
        struct qlcnic_info *nic_info;
@@ -668,17 +677,6 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic)
        if (adapter->op_mode != QLCNIC_MGMT_FUNC)
                return err;
 
-       if (qlcnic_api_lock(adapter))
-               return err;
-
-       func_state = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
-       if (QLC_DEV_CHECK_ACTIVE(func_state, nic->pci_func)) {
-               qlcnic_api_unlock(adapter);
-               return err;
-       }
-
-       qlcnic_api_unlock(adapter);
-
        nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size,
                        &nic_dma_t);
        if (!nic_info_addr)
@@ -703,7 +701,7 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic)
                        adapter->fw_hal_version,
                        MSD(nic_dma_t),
                        LSD(nic_dma_t),
-                       nic_size,
+                       ((nic->pci_func << 16) | nic_size),
                        QLCNIC_CDRP_CMD_SET_NIC_INFO);
 
        if (err != QLCNIC_RCODE_SUCCESS) {
@@ -717,7 +715,8 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic)
 }
 
 /* Get PCI Info of a partition */
-int qlcnic_get_pci_info(struct qlcnic_adapter *adapter)
+int qlcnic_get_pci_info(struct qlcnic_adapter *adapter,
+                               struct qlcnic_pci_info *pci_info)
 {
        int err = 0, i;
        dma_addr_t pci_info_dma_t;
@@ -732,21 +731,6 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter)
                return -ENOMEM;
        memset(pci_info_addr, 0, pci_size);
 
-       if (!adapter->npars)
-               adapter->npars = kzalloc(pci_size, GFP_KERNEL);
-       if (!adapter->npars) {
-               err = -ENOMEM;
-               goto err_npar;
-       }
-
-       if (!adapter->eswitch)
-               adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) *
-                               QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL);
-       if (!adapter->eswitch) {
-               err = -ENOMEM;
-               goto err_eswitch;
-       }
-
        npar = (struct qlcnic_pci_info *) pci_info_addr;
        err = qlcnic_issue_cmd(adapter,
                        adapter->ahw.pci_func,
@@ -757,31 +741,24 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter)
                        QLCNIC_CDRP_CMD_GET_PCI_INFO);
 
        if (err == QLCNIC_RCODE_SUCCESS) {
-               for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++) {
-                       adapter->npars[i].id = le32_to_cpu(npar->id);
-                       adapter->npars[i].active = le32_to_cpu(npar->active);
-                       adapter->npars[i].type = le32_to_cpu(npar->type);
-                       adapter->npars[i].default_port =
+               for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) {
+                       pci_info->id = le32_to_cpu(npar->id);
+                       pci_info->active = le32_to_cpu(npar->active);
+                       pci_info->type = le32_to_cpu(npar->type);
+                       pci_info->default_port =
                                le32_to_cpu(npar->default_port);
-                       adapter->npars[i].tx_min_bw =
+                       pci_info->tx_min_bw =
                                le32_to_cpu(npar->tx_min_bw);
-                       adapter->npars[i].tx_max_bw =
+                       pci_info->tx_max_bw =
                                le32_to_cpu(npar->tx_max_bw);
-                       memcpy(adapter->npars[i].mac, npar->mac, ETH_ALEN);
+                       memcpy(pci_info->mac, npar->mac, ETH_ALEN);
                }
        } else {
                dev_err(&adapter->pdev->dev,
                        "Failed to get PCI Info%d\n", err);
-               kfree(adapter->npars);
                err = -EIO;
        }
-       goto err_npar;
-
-err_eswitch:
-       kfree(adapter->npars);
-       adapter->npars = NULL;
 
-err_npar:
        pci_free_consistent(adapter->pdev, pci_size, pci_info_addr,
                pci_info_dma_t);
        return err;
@@ -999,9 +976,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id,
        if (err != QLCNIC_RCODE_SUCCESS) {
                dev_err(&adapter->pdev->dev,
                        "Failed to configure eswitch port%d\n", eswitch->port);
-               eswitch->flags |= QLCNIC_SWITCH_ENABLE;
        } else {
-               eswitch->flags &= ~QLCNIC_SWITCH_ENABLE;
                dev_info(&adapter->pdev->dev,
                        "Configured eSwitch for port %d\n", eswitch->port);
        }