Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-microblaze.git] / drivers / net / ethernet / ibm / ibmvnic.c
index ffb2a91..5788bb9 100644 (file)
@@ -827,6 +827,30 @@ static void release_napi(struct ibmvnic_adapter *adapter)
        adapter->napi_enabled = false;
 }
 
+static const char *adapter_state_to_string(enum vnic_state state)
+{
+       switch (state) {
+       case VNIC_PROBING:
+               return "PROBING";
+       case VNIC_PROBED:
+               return "PROBED";
+       case VNIC_OPENING:
+               return "OPENING";
+       case VNIC_OPEN:
+               return "OPEN";
+       case VNIC_CLOSING:
+               return "CLOSING";
+       case VNIC_CLOSED:
+               return "CLOSED";
+       case VNIC_REMOVING:
+               return "REMOVING";
+       case VNIC_REMOVED:
+               return "REMOVED";
+       default:
+               return "UNKNOWN";
+       }
+}
+
 static int ibmvnic_login(struct net_device *netdev)
 {
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -905,7 +929,7 @@ static int ibmvnic_login(struct net_device *netdev)
 
        __ibmvnic_set_mac(netdev, adapter->mac_addr);
 
-       netdev_dbg(netdev, "[S:%d] Login succeeded\n", adapter->state);
+       netdev_dbg(netdev, "[S:%s] Login succeeded\n", adapter_state_to_string(adapter->state));
        return 0;
 }
 
@@ -1179,8 +1203,9 @@ static int ibmvnic_open(struct net_device *netdev)
         * honor our setting below.
         */
        if (adapter->failover_pending || (test_bit(0, &adapter->resetting))) {
-               netdev_dbg(netdev, "[S:%d FOP:%d] Resetting, deferring open\n",
-                          adapter->state, adapter->failover_pending);
+               netdev_dbg(netdev, "[S:%s FOP:%d] Resetting, deferring open\n",
+                          adapter_state_to_string(adapter->state),
+                          adapter->failover_pending);
                adapter->state = VNIC_OPEN;
                rc = 0;
                goto out;
@@ -1344,8 +1369,9 @@ static int ibmvnic_close(struct net_device *netdev)
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
        int rc;
 
-       netdev_dbg(netdev, "[S:%d FOP:%d FRR:%d] Closing\n",
-                  adapter->state, adapter->failover_pending,
+       netdev_dbg(netdev, "[S:%s FOP:%d FRR:%d] Closing\n",
+                  adapter_state_to_string(adapter->state),
+                  adapter->failover_pending,
                   adapter->force_reset_recovery);
 
        /* If device failover is pending, just set device state and return.
@@ -1672,9 +1698,8 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                        const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
-                       memcpy(dst + cur,
-                              page_address(skb_frag_page(frag)) +
-                              skb_frag_off(frag), skb_frag_size(frag));
+                       memcpy(dst + cur, skb_frag_address(frag),
+                              skb_frag_size(frag));
                        cur += skb_frag_size(frag);
                }
        } else {
@@ -1906,6 +1931,26 @@ static int ibmvnic_set_mac(struct net_device *netdev, void *p)
        return rc;
 }
 
+static const char *reset_reason_to_string(enum ibmvnic_reset_reason reason)
+{
+       switch (reason) {
+       case VNIC_RESET_FAILOVER:
+               return "FAILOVER";
+       case VNIC_RESET_MOBILITY:
+               return "MOBILITY";
+       case VNIC_RESET_FATAL:
+               return "FATAL";
+       case VNIC_RESET_NON_FATAL:
+               return "NON_FATAL";
+       case VNIC_RESET_TIMEOUT:
+               return "TIMEOUT";
+       case VNIC_RESET_CHANGE_PARAM:
+               return "CHANGE_PARAM";
+       default:
+               return "UNKNOWN";
+       }
+}
+
 /*
  * do_reset returns zero if we are able to keep processing reset events, or
  * non-zero if we hit a fatal error and must halt.
@@ -1919,9 +1964,11 @@ static int do_reset(struct ibmvnic_adapter *adapter,
        int rc;
 
        netdev_dbg(adapter->netdev,
-                  "[S:%d FOP:%d] Reset reason %d, reset_state %d\n",
-                  adapter->state, adapter->failover_pending,
-                  rwi->reset_reason, reset_state);
+                  "[S:%s FOP:%d] Reset reason: %s, reset_state: %s\n",
+                  adapter_state_to_string(adapter->state),
+                  adapter->failover_pending,
+                  reset_reason_to_string(rwi->reset_reason),
+                  adapter_state_to_string(reset_state));
 
        adapter->reset_reason = rwi->reset_reason;
        /* requestor of VNIC_RESET_CHANGE_PARAM already has the rtnl lock */
@@ -1981,8 +2028,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
                                 * from VNIC_CLOSING state.
                                 */
                                netdev_dbg(netdev,
-                                          "Open changed state from %d, updating.\n",
-                                          reset_state);
+                                          "Open changed state from %s, updating.\n",
+                                          adapter_state_to_string(reset_state));
                                reset_state = VNIC_OPEN;
                                adapter->state = VNIC_CLOSING;
                        }
@@ -2119,8 +2166,9 @@ out:
        if (!(adapter->reset_reason == VNIC_RESET_CHANGE_PARAM))
                rtnl_unlock();
 
-       netdev_dbg(adapter->netdev, "[S:%d FOP:%d] Reset done, rc %d\n",
-                  adapter->state, adapter->failover_pending, rc);
+       netdev_dbg(adapter->netdev, "[S:%s FOP:%d] Reset done, rc %d\n",
+                  adapter_state_to_string(adapter->state),
+                  adapter->failover_pending, rc);
        return rc;
 }
 
@@ -2130,8 +2178,8 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter,
        struct net_device *netdev = adapter->netdev;
        int rc;
 
-       netdev_dbg(adapter->netdev, "Hard resetting driver (%d)\n",
-                  rwi->reset_reason);
+       netdev_dbg(adapter->netdev, "Hard resetting driver (%s)\n",
+                  reset_reason_to_string(rwi->reset_reason));
 
        /* read the state and check (again) after getting rtnl */
        reset_state = adapter->state;
@@ -2197,8 +2245,9 @@ out:
        /* restore adapter state if reset failed */
        if (rc)
                adapter->state = reset_state;
-       netdev_dbg(adapter->netdev, "[S:%d FOP:%d] Hard reset done, rc %d\n",
-                  adapter->state, adapter->failover_pending, rc);
+       netdev_dbg(adapter->netdev, "[S:%s FOP:%d] Hard reset done, rc %d\n",
+                  adapter_state_to_string(adapter->state),
+                  adapter->failover_pending, rc);
        return rc;
 }
 
@@ -2233,8 +2282,9 @@ static void __ibmvnic_reset(struct work_struct *work)
        adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset);
 
        if (test_and_set_bit_lock(0, &adapter->resetting)) {
-               schedule_delayed_work(&adapter->ibmvnic_delayed_reset,
-                                     IBMVNIC_RESET_DELAY);
+               queue_delayed_work(system_long_wq,
+                                  &adapter->ibmvnic_delayed_reset,
+                                  IBMVNIC_RESET_DELAY);
                return;
        }
 
@@ -2277,8 +2327,8 @@ static void __ibmvnic_reset(struct work_struct *work)
                        if (rc) {
                                /* give backing device time to settle down */
                                netdev_dbg(adapter->netdev,
-                                          "[S:%d] Hard reset failed, waiting 60 secs\n",
-                                          adapter->state);
+                                          "[S:%s] Hard reset failed, waiting 60 secs\n",
+                                          adapter_state_to_string(adapter->state));
                                set_current_state(TASK_UNINTERRUPTIBLE);
                                schedule_timeout(60 * HZ);
                        }
@@ -2306,8 +2356,9 @@ static void __ibmvnic_reset(struct work_struct *work)
        clear_bit_unlock(0, &adapter->resetting);
 
        netdev_dbg(adapter->netdev,
-                  "[S:%d FRR:%d WFR:%d] Done processing resets\n",
-                  adapter->state, adapter->force_reset_recovery,
+                  "[S:%s FRR:%d WFR:%d] Done processing resets\n",
+                  adapter_state_to_string(adapter->state),
+                  adapter->force_reset_recovery,
                   adapter->wait_for_reset);
 }
 
@@ -2354,8 +2405,8 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
        list_for_each(entry, &adapter->rwi_list) {
                tmp = list_entry(entry, struct ibmvnic_rwi, list);
                if (tmp->reset_reason == reason) {
-                       netdev_dbg(netdev, "Skipping matching reset, reason=%d\n",
-                                  reason);
+                       netdev_dbg(netdev, "Skipping matching reset, reason=%s\n",
+                                  reset_reason_to_string(reason));
                        ret = EBUSY;
                        goto err;
                }
@@ -2375,8 +2426,9 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
        }
        rwi->reset_reason = reason;
        list_add_tail(&rwi->list, &adapter->rwi_list);
-       netdev_dbg(adapter->netdev, "Scheduling reset (reason %d)\n", reason);
-       schedule_work(&adapter->ibmvnic_reset);
+       netdev_dbg(adapter->netdev, "Scheduling reset (reason %s)\n",
+                  reset_reason_to_string(reason));
+       queue_work(system_long_wq, &adapter->ibmvnic_reset);
 
        ret = 0;
 err:
@@ -5445,7 +5497,7 @@ static ssize_t failover_store(struct device *dev, struct device_attribute *attr,
        if (rc) {
                netdev_err(netdev, "Couldn't retrieve session token, rc %ld\n",
                           rc);
-               return -EINVAL;
+               goto last_resort;
        }
 
        session_token = (__be64)retbuf[0];
@@ -5453,15 +5505,17 @@ static ssize_t failover_store(struct device *dev, struct device_attribute *attr,
                   be64_to_cpu(session_token));
        rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
                                H_SESSION_ERR_DETECTED, session_token, 0, 0);
-       if (rc) {
-               netdev_err(netdev, "Client initiated failover failed, rc %ld\n",
+       if (rc)
+               netdev_err(netdev,
+                          "H_VIOCTL initiated failover failed, rc %ld\n",
                           rc);
-               return -EINVAL;
-       }
+
+last_resort:
+       netdev_dbg(netdev, "Trying to send CRQ_CMD, the last resort\n");
+       ibmvnic_reset(adapter, VNIC_RESET_FAILOVER);
 
        return count;
 }
-
 static DEVICE_ATTR_WO(failover);
 
 static unsigned long ibmvnic_get_desired_dma(struct vio_dev *vdev)