aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-04-15 17:29:00 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-15 17:29:00 -0400
commit6b9107d6a10b69cc0a675447bde9383dff8a1d4f (patch)
treece579f705e65eebb447204c3e8c3166ade049ed1 /drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
parent074975d0374333f656c48487aa046a21a9b9d7a1 (diff)
parent2aea6dcb7864e174dada15728c43c5330637d424 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== Intel Wired LAN Driver Updates 2015-04-14 This series contains updates to i40e and i40evf. Mitch provides a fix for i40e, where VFs were gone and the associated VSI's had been removed and the rings were not stopped, which in some circumstances cased memory corruption or DMAR errors. So stop all the rings associated with each VF before releasing its resources. Also cleaned up a poorly indented piece of code. Fixes VF link state, where VF devices were assuming link is up unless told otherwise, which means that VFs instantiated on a PF with no link, would report the wrong state. Anjali adds support to add Flow director Sideband rules for a VF from it's PF. Fixes a recently discovered hardware issue, where after a VFLR hardware might be indicating to us a reset completion little too early, so wait another 10 msec for cache to be cleaned up. Jesse enables the user to dump the internal hardware state for better debugging by allowing a bash script to acquire information about the internal hardware state. The data output to the kernel log is collected by the script and can then be sent to Intel. Also fixed a possible failure path to allocate memory that was found by smatch. Cleaned up unused local variables. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c244
1 files changed, 132 insertions, 112 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 4d69e1f04901..78d1c4ff565e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -26,6 +26,129 @@
26 26
27#include "i40e.h" 27#include "i40e.h"
28 28
29/*********************notification routines***********************/
30
31/**
32 * i40e_vc_vf_broadcast
33 * @pf: pointer to the PF structure
34 * @opcode: operation code
35 * @retval: return value
36 * @msg: pointer to the msg buffer
37 * @msglen: msg length
38 *
39 * send a message to all VFs on a given PF
40 **/
41static void i40e_vc_vf_broadcast(struct i40e_pf *pf,
42 enum i40e_virtchnl_ops v_opcode,
43 i40e_status v_retval, u8 *msg,
44 u16 msglen)
45{
46 struct i40e_hw *hw = &pf->hw;
47 struct i40e_vf *vf = pf->vf;
48 int i;
49
50 for (i = 0; i < pf->num_alloc_vfs; i++, vf++) {
51 int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
52 /* Not all vfs are enabled so skip the ones that are not */
53 if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
54 !test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
55 continue;
56
57 /* Ignore return value on purpose - a given VF may fail, but
58 * we need to keep going and send to all of them
59 */
60 i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval,
61 msg, msglen, NULL);
62 }
63}
64
65/**
66 * i40e_vc_notify_link_state
67 * @vf: pointer to the VF structure
68 *
69 * send a link status message to a single VF
70 **/
71static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf)
72{
73 struct i40e_virtchnl_pf_event pfe;
74 struct i40e_pf *pf = vf->pf;
75 struct i40e_hw *hw = &pf->hw;
76 struct i40e_link_status *ls = &pf->hw.phy.link_info;
77 int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
78
79 pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
80 pfe.severity = I40E_PF_EVENT_SEVERITY_INFO;
81 if (vf->link_forced) {
82 pfe.event_data.link_event.link_status = vf->link_up;
83 pfe.event_data.link_event.link_speed =
84 (vf->link_up ? I40E_LINK_SPEED_40GB : 0);
85 } else {
86 pfe.event_data.link_event.link_status =
87 ls->link_info & I40E_AQ_LINK_UP;
88 pfe.event_data.link_event.link_speed = ls->link_speed;
89 }
90 i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
91 0, (u8 *)&pfe, sizeof(pfe), NULL);
92}
93
94/**
95 * i40e_vc_notify_link_state
96 * @pf: pointer to the PF structure
97 *
98 * send a link status message to all VFs on a given PF
99 **/
100void i40e_vc_notify_link_state(struct i40e_pf *pf)
101{
102 int i;
103
104 for (i = 0; i < pf->num_alloc_vfs; i++)
105 i40e_vc_notify_vf_link_state(&pf->vf[i]);
106}
107
108/**
109 * i40e_vc_notify_reset
110 * @pf: pointer to the PF structure
111 *
112 * indicate a pending reset to all VFs on a given PF
113 **/
114void i40e_vc_notify_reset(struct i40e_pf *pf)
115{
116 struct i40e_virtchnl_pf_event pfe;
117
118 pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
119 pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
120 i40e_vc_vf_broadcast(pf, I40E_VIRTCHNL_OP_EVENT, 0,
121 (u8 *)&pfe, sizeof(struct i40e_virtchnl_pf_event));
122}
123
124/**
125 * i40e_vc_notify_vf_reset
126 * @vf: pointer to the VF structure
127 *
128 * indicate a pending reset to the given VF
129 **/
130void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
131{
132 struct i40e_virtchnl_pf_event pfe;
133 int abs_vf_id;
134
135 /* validate the request */
136 if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs)
137 return;
138
139 /* verify if the VF is in either init or active before proceeding */
140 if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
141 !test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
142 return;
143
144 abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id;
145
146 pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
147 pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
148 i40e_aq_send_msg_to_vf(&vf->pf->hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
149 0, (u8 *)&pfe,
150 sizeof(struct i40e_virtchnl_pf_event), NULL);
151}
29/***********************misc routines*****************************/ 152/***********************misc routines*****************************/
30 153
31/** 154/**
@@ -689,6 +812,9 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
689 } 812 }
690 } 813 }
691 814
815 if (flr)
816 usleep_range(10000, 20000);
817
692 if (!rsd) 818 if (!rsd)
693 dev_err(&pf->pdev->dev, "VF reset check timeout on VF %d\n", 819 dev_err(&pf->pdev->dev, "VF reset check timeout on VF %d\n",
694 vf->vf_id); 820 vf->vf_id);
@@ -733,6 +859,11 @@ void i40e_free_vfs(struct i40e_pf *pf)
733 while (test_and_set_bit(__I40E_VF_DISABLE, &pf->state)) 859 while (test_and_set_bit(__I40E_VF_DISABLE, &pf->state))
734 usleep_range(1000, 2000); 860 usleep_range(1000, 2000);
735 861
862 for (i = 0; i < pf->num_alloc_vfs; i++)
863 if (test_bit(I40E_VF_STAT_INIT, &pf->vf[i].vf_states))
864 i40e_vsi_control_rings(pf->vsi[pf->vf[i].lan_vsi_idx],
865 false);
866
736 /* Disable IOV before freeing resources. This lets any VF drivers 867 /* Disable IOV before freeing resources. This lets any VF drivers
737 * running in the host get themselves cleaned up before we yank 868 * running in the host get themselves cleaned up before we yank
738 * the carpet out from underneath their feet. 869 * the carpet out from underneath their feet.
@@ -1762,6 +1893,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode,
1762 break; 1893 break;
1763 case I40E_VIRTCHNL_OP_ENABLE_QUEUES: 1894 case I40E_VIRTCHNL_OP_ENABLE_QUEUES:
1764 ret = i40e_vc_enable_queues_msg(vf, msg, msglen); 1895 ret = i40e_vc_enable_queues_msg(vf, msg, msglen);
1896 i40e_vc_notify_vf_link_state(vf);
1765 break; 1897 break;
1766 case I40E_VIRTCHNL_OP_DISABLE_QUEUES: 1898 case I40E_VIRTCHNL_OP_DISABLE_QUEUES:
1767 ret = i40e_vc_disable_queues_msg(vf, msg, msglen); 1899 ret = i40e_vc_disable_queues_msg(vf, msg, msglen);
@@ -1835,118 +1967,6 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf)
1835} 1967}
1836 1968
1837/** 1969/**
1838 * i40e_vc_vf_broadcast
1839 * @pf: pointer to the PF structure
1840 * @opcode: operation code
1841 * @retval: return value
1842 * @msg: pointer to the msg buffer
1843 * @msglen: msg length
1844 *
1845 * send a message to all VFs on a given PF
1846 **/
1847static void i40e_vc_vf_broadcast(struct i40e_pf *pf,
1848 enum i40e_virtchnl_ops v_opcode,
1849 i40e_status v_retval, u8 *msg,
1850 u16 msglen)
1851{
1852 struct i40e_hw *hw = &pf->hw;
1853 struct i40e_vf *vf = pf->vf;
1854 int i;
1855
1856 for (i = 0; i < pf->num_alloc_vfs; i++, vf++) {
1857 int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
1858 /* Not all VFs are enabled so skip the ones that are not */
1859 if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
1860 !test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
1861 continue;
1862
1863 /* Ignore return value on purpose - a given VF may fail, but
1864 * we need to keep going and send to all of them
1865 */
1866 i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval,
1867 msg, msglen, NULL);
1868 }
1869}
1870
1871/**
1872 * i40e_vc_notify_link_state
1873 * @pf: pointer to the PF structure
1874 *
1875 * send a link status message to all VFs on a given PF
1876 **/
1877void i40e_vc_notify_link_state(struct i40e_pf *pf)
1878{
1879 struct i40e_virtchnl_pf_event pfe;
1880 struct i40e_hw *hw = &pf->hw;
1881 struct i40e_vf *vf = pf->vf;
1882 struct i40e_link_status *ls = &pf->hw.phy.link_info;
1883 int i;
1884
1885 pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
1886 pfe.severity = I40E_PF_EVENT_SEVERITY_INFO;
1887 for (i = 0; i < pf->num_alloc_vfs; i++, vf++) {
1888 int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
1889 if (vf->link_forced) {
1890 pfe.event_data.link_event.link_status = vf->link_up;
1891 pfe.event_data.link_event.link_speed =
1892 (vf->link_up ? I40E_LINK_SPEED_40GB : 0);
1893 } else {
1894 pfe.event_data.link_event.link_status =
1895 ls->link_info & I40E_AQ_LINK_UP;
1896 pfe.event_data.link_event.link_speed = ls->link_speed;
1897 }
1898 i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
1899 0, (u8 *)&pfe, sizeof(pfe),
1900 NULL);
1901 }
1902}
1903
1904/**
1905 * i40e_vc_notify_reset
1906 * @pf: pointer to the PF structure
1907 *
1908 * indicate a pending reset to all VFs on a given PF
1909 **/
1910void i40e_vc_notify_reset(struct i40e_pf *pf)
1911{
1912 struct i40e_virtchnl_pf_event pfe;
1913
1914 pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
1915 pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
1916 i40e_vc_vf_broadcast(pf, I40E_VIRTCHNL_OP_EVENT, I40E_SUCCESS,
1917 (u8 *)&pfe, sizeof(struct i40e_virtchnl_pf_event));
1918}
1919
1920/**
1921 * i40e_vc_notify_vf_reset
1922 * @vf: pointer to the VF structure
1923 *
1924 * indicate a pending reset to the given VF
1925 **/
1926void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
1927{
1928 struct i40e_virtchnl_pf_event pfe;
1929 int abs_vf_id;
1930
1931 /* validate the request */
1932 if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs)
1933 return;
1934
1935 /* verify if the VF is in either init or active before proceeding */
1936 if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
1937 !test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
1938 return;
1939
1940 abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id;
1941
1942 pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
1943 pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
1944 i40e_aq_send_msg_to_vf(&vf->pf->hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
1945 I40E_SUCCESS, (u8 *)&pfe,
1946 sizeof(struct i40e_virtchnl_pf_event), NULL);
1947}
1948
1949/**
1950 * i40e_ndo_set_vf_mac 1970 * i40e_ndo_set_vf_mac
1951 * @netdev: network interface device structure 1971 * @netdev: network interface device structure
1952 * @vf_id: VF identifier 1972 * @vf_id: VF identifier