cxgb4vf: add call to Firmware to reset VF State.
authorCasey Leedom <leedom@chelsio.com>
Thu, 11 Nov 2010 09:06:53 +0000 (09:06 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 12 Nov 2010 20:31:01 +0000 (12:31 -0800)
Add call to Firmware to reset its VF State when we first attach to the VF.

Signed-off-by: Casey Leedom <leedom@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/cxgb4vf/cxgb4vf_main.c
drivers/net/cxgb4vf/t4vf_common.h
drivers/net/cxgb4vf/t4vf_hw.c

index 8da3bda13f334bccd82f93f288e8c44f5d020282..c3449bbc585a682b57a39b306f251f9691e27e0b 100644 (file)
@@ -2064,6 +2064,22 @@ static int adap_init0(struct adapter *adapter)
                return err;
        }
 
+       /*
+        * Some environments do not properly handle PCIE FLRs -- e.g. in Linux
+        * 2.6.31 and later we can't call pci_reset_function() in order to
+        * issue an FLR because of a self- deadlock on the device semaphore.
+        * Meanwhile, the OS infrastructure doesn't issue FLRs in all the
+        * cases where they're needed -- for instance, some versions of KVM
+        * fail to reset "Assigned Devices" when the VM reboots.  Therefore we
+        * use the firmware based reset in order to reset any per function
+        * state.
+        */
+       err = t4vf_fw_reset(adapter);
+       if (err < 0) {
+               dev_err(adapter->pdev_dev, "FW reset failed: err=%d\n", err);
+               return err;
+       }
+
        /*
         * Grab basic operational parameters.  These will predominantly have
         * been set up by the Physical Function Driver or will be hard coded
index 873cb7d86c57fc50ae3c71d6638c5e2b58e2ca07..a65c80aed1f2a214d99e520a2125755e2c16ecec 100644 (file)
@@ -235,6 +235,7 @@ static inline int t4vf_wr_mbox_ns(struct adapter *adapter, const void *cmd,
 int __devinit t4vf_wait_dev_ready(struct adapter *);
 int __devinit t4vf_port_init(struct adapter *, int);
 
+int t4vf_fw_reset(struct adapter *);
 int t4vf_query_params(struct adapter *, unsigned int, const u32 *, u32 *);
 int t4vf_set_params(struct adapter *, unsigned int, const u32 *, const u32 *);
 
index ea1c123f0cb4b9e44eeac857920622aa9d51e8b5..e306c20dfaee3fd2c54a7d4e3497ddd8ba787d19 100644 (file)
@@ -325,6 +325,25 @@ int __devinit t4vf_port_init(struct adapter *adapter, int pidx)
        return 0;
 }
 
+/**
+ *      t4vf_fw_reset - issue a reset to FW
+ *      @adapter: the adapter
+ *
+ *     Issues a reset command to FW.  For a Physical Function this would
+ *     result in the Firmware reseting all of its state.  For a Virtual
+ *     Function this just resets the state associated with the VF.
+ */
+int t4vf_fw_reset(struct adapter *adapter)
+{
+       struct fw_reset_cmd cmd;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RESET_CMD) |
+                                     FW_CMD_WRITE);
+       cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
+       return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
+}
+
 /**
  *     t4vf_query_params - query FW or device parameters
  *     @adapter: the adapter