]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/net/ethernet/ibm/ibmvnic.c
ibmvnic: Reset long term map ID counter
[linux.git] / drivers / net / ethernet / ibm / ibmvnic.c
index 5caaa90338412fc5bb3cb7f3f87a926bf6ceb8e0..ce127a72cda23f8333bae11cedf8919e16480ce1 100644 (file)
@@ -354,6 +354,8 @@ static void release_stats_buffers(struct ibmvnic_adapter *adapter)
 {
        kfree(adapter->tx_stats_buffers);
        kfree(adapter->rx_stats_buffers);
+       adapter->tx_stats_buffers = NULL;
+       adapter->rx_stats_buffers = NULL;
 }
 
 static int init_stats_buffers(struct ibmvnic_adapter *adapter)
@@ -599,6 +601,8 @@ static void release_vpd_data(struct ibmvnic_adapter *adapter)
 
        kfree(adapter->vpd->buff);
        kfree(adapter->vpd);
+
+       adapter->vpd = NULL;
 }
 
 static void release_tx_pools(struct ibmvnic_adapter *adapter)
@@ -909,6 +913,7 @@ static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter)
        if (dma_mapping_error(dev, adapter->vpd->dma_addr)) {
                dev_err(dev, "Could not map VPD buffer\n");
                kfree(adapter->vpd->buff);
+               adapter->vpd->buff = NULL;
                return -ENOMEM;
        }
 
@@ -1639,6 +1644,7 @@ static int do_reset(struct ibmvnic_adapter *adapter,
                                return rc;
                } else if (adapter->req_rx_queues != old_num_rx_queues ||
                           adapter->req_tx_queues != old_num_tx_queues) {
+                       adapter->map_id = 1;
                        release_rx_pools(adapter);
                        release_tx_pools(adapter);
                        init_rx_pools(netdev);
@@ -1831,7 +1837,8 @@ static int ibmvnic_poll(struct napi_struct *napi, int budget)
                u16 offset;
                u8 flags = 0;
 
-               if (unlikely(adapter->resetting)) {
+               if (unlikely(adapter->resetting &&
+                            adapter->reset_reason != VNIC_RESET_NON_FATAL)) {
                        enable_scrq_irq(adapter, adapter->rx_scrq[scrq_num]);
                        napi_complete_done(napi, frames_processed);
                        return frames_processed;
@@ -2908,8 +2915,12 @@ static int ibmvnic_send_crq(struct ibmvnic_adapter *adapter,
                                cpu_to_be64(u64_crq[1]));
 
        if (rc) {
-               if (rc == H_CLOSED)
+               if (rc == H_CLOSED) {
                        dev_warn(dev, "CRQ Queue closed\n");
+                       if (adapter->resetting)
+                               ibmvnic_reset(adapter, VNIC_RESET_FATAL);
+               }
+
                dev_warn(dev, "Send error (rc=%d)\n", rc);
        }
 
@@ -3286,7 +3297,7 @@ static void handle_vpd_rsp(union ibmvnic_crq *crq,
                           struct ibmvnic_adapter *adapter)
 {
        struct device *dev = &adapter->vdev->dev;
-       unsigned char *substr = NULL, *ptr = NULL;
+       unsigned char *substr = NULL;
        u8 fw_level_len = 0;
 
        memset(adapter->fw_version, 0, 32);
@@ -3306,10 +3317,6 @@ static void handle_vpd_rsp(union ibmvnic_crq *crq,
        substr = strnstr(adapter->vpd->buff, "RM", adapter->vpd->len);
        if (!substr) {
                dev_info(dev, "Warning - No FW level has been provided in the VPD buffer by the VIOS Server\n");
-               ptr = strncpy((char *)adapter->fw_version, "N/A",
-                             3 * sizeof(char));
-               if (!ptr)
-                       dev_err(dev, "Failed to inform that firmware version is unavailable to the adapter\n");
                goto complete;
        }
 
@@ -3324,16 +3331,14 @@ static void handle_vpd_rsp(union ibmvnic_crq *crq,
        /* copy firmware version string from vpd into adapter */
        if ((substr + 3 + fw_level_len) <
            (adapter->vpd->buff + adapter->vpd->len)) {
-               ptr = strncpy((char *)adapter->fw_version,
-                             substr + 3, fw_level_len);
-
-               if (!ptr)
-                       dev_err(dev, "Failed to isolate FW level string\n");
+               strncpy((char *)adapter->fw_version, substr + 3, fw_level_len);
        } else {
                dev_info(dev, "FW substr extrapolated VPD buff\n");
        }
 
 complete:
+       if (adapter->fw_version[0] == '\0')
+               strncpy((char *)adapter->fw_version, "N/A", 3 * sizeof(char));
        complete(&adapter->fw_done);
 }