Commit 7e7eb4346329da3b9fd4b8d4a5a66d327d9fff6c
Committed by
Jeff Kirsher
1 parent
c27931da83
Exists in
master
and in
7 other branches
ixgbe: remove timer reset to 0 on timeout
The VF mailbox polling for acks and messages would reset the timer to zero on a timeout. Under heavy load a timeout may actually occur without being the result of an error and when this occurs it is not practical to perform a full VF driver reset on every message timeout. Instead, just return an error (which is already done) and the VF driver will have an opportunity to retry the operation. Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com> Acked-by: Greg Rose <gregory.v.rose@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Showing 1 changed file with 0 additions and 6 deletions Inline Diff
drivers/net/ixgbe/ixgbe_mbx.c
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2011 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
8 | version 2, as published by the Free Software Foundation. | 8 | version 2, as published by the Free Software Foundation. |
9 | 9 | ||
10 | This program is distributed in the hope it will be useful, but WITHOUT | 10 | This program is distributed in the hope it will be useful, but WITHOUT |
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
13 | more details. | 13 | more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU General Public License along with | 15 | You should have received a copy of the GNU General Public License along with |
16 | this program; if not, write to the Free Software Foundation, Inc., | 16 | this program; if not, write to the Free Software Foundation, Inc., |
17 | 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | 17 | 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
18 | 18 | ||
19 | The full GNU General Public License is included in this distribution in | 19 | The full GNU General Public License is included in this distribution in |
20 | the file called "COPYING". | 20 | the file called "COPYING". |
21 | 21 | ||
22 | Contact Information: | 22 | Contact Information: |
23 | e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | 23 | e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> |
24 | Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 24 | Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
25 | 25 | ||
26 | *******************************************************************************/ | 26 | *******************************************************************************/ |
27 | 27 | ||
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include "ixgbe_type.h" | 30 | #include "ixgbe_type.h" |
31 | #include "ixgbe_common.h" | 31 | #include "ixgbe_common.h" |
32 | #include "ixgbe_mbx.h" | 32 | #include "ixgbe_mbx.h" |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * ixgbe_read_mbx - Reads a message from the mailbox | 35 | * ixgbe_read_mbx - Reads a message from the mailbox |
36 | * @hw: pointer to the HW structure | 36 | * @hw: pointer to the HW structure |
37 | * @msg: The message buffer | 37 | * @msg: The message buffer |
38 | * @size: Length of buffer | 38 | * @size: Length of buffer |
39 | * @mbx_id: id of mailbox to read | 39 | * @mbx_id: id of mailbox to read |
40 | * | 40 | * |
41 | * returns SUCCESS if it successfuly read message from buffer | 41 | * returns SUCCESS if it successfuly read message from buffer |
42 | **/ | 42 | **/ |
43 | s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) | 43 | s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) |
44 | { | 44 | { |
45 | struct ixgbe_mbx_info *mbx = &hw->mbx; | 45 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
46 | s32 ret_val = IXGBE_ERR_MBX; | 46 | s32 ret_val = IXGBE_ERR_MBX; |
47 | 47 | ||
48 | /* limit read to size of mailbox */ | 48 | /* limit read to size of mailbox */ |
49 | if (size > mbx->size) | 49 | if (size > mbx->size) |
50 | size = mbx->size; | 50 | size = mbx->size; |
51 | 51 | ||
52 | if (mbx->ops.read) | 52 | if (mbx->ops.read) |
53 | ret_val = mbx->ops.read(hw, msg, size, mbx_id); | 53 | ret_val = mbx->ops.read(hw, msg, size, mbx_id); |
54 | 54 | ||
55 | return ret_val; | 55 | return ret_val; |
56 | } | 56 | } |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * ixgbe_write_mbx - Write a message to the mailbox | 59 | * ixgbe_write_mbx - Write a message to the mailbox |
60 | * @hw: pointer to the HW structure | 60 | * @hw: pointer to the HW structure |
61 | * @msg: The message buffer | 61 | * @msg: The message buffer |
62 | * @size: Length of buffer | 62 | * @size: Length of buffer |
63 | * @mbx_id: id of mailbox to write | 63 | * @mbx_id: id of mailbox to write |
64 | * | 64 | * |
65 | * returns SUCCESS if it successfully copied message into the buffer | 65 | * returns SUCCESS if it successfully copied message into the buffer |
66 | **/ | 66 | **/ |
67 | s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) | 67 | s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) |
68 | { | 68 | { |
69 | struct ixgbe_mbx_info *mbx = &hw->mbx; | 69 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
70 | s32 ret_val = 0; | 70 | s32 ret_val = 0; |
71 | 71 | ||
72 | if (size > mbx->size) | 72 | if (size > mbx->size) |
73 | ret_val = IXGBE_ERR_MBX; | 73 | ret_val = IXGBE_ERR_MBX; |
74 | 74 | ||
75 | else if (mbx->ops.write) | 75 | else if (mbx->ops.write) |
76 | ret_val = mbx->ops.write(hw, msg, size, mbx_id); | 76 | ret_val = mbx->ops.write(hw, msg, size, mbx_id); |
77 | 77 | ||
78 | return ret_val; | 78 | return ret_val; |
79 | } | 79 | } |
80 | 80 | ||
81 | /** | 81 | /** |
82 | * ixgbe_check_for_msg - checks to see if someone sent us mail | 82 | * ixgbe_check_for_msg - checks to see if someone sent us mail |
83 | * @hw: pointer to the HW structure | 83 | * @hw: pointer to the HW structure |
84 | * @mbx_id: id of mailbox to check | 84 | * @mbx_id: id of mailbox to check |
85 | * | 85 | * |
86 | * returns SUCCESS if the Status bit was found or else ERR_MBX | 86 | * returns SUCCESS if the Status bit was found or else ERR_MBX |
87 | **/ | 87 | **/ |
88 | s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) | 88 | s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) |
89 | { | 89 | { |
90 | struct ixgbe_mbx_info *mbx = &hw->mbx; | 90 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
91 | s32 ret_val = IXGBE_ERR_MBX; | 91 | s32 ret_val = IXGBE_ERR_MBX; |
92 | 92 | ||
93 | if (mbx->ops.check_for_msg) | 93 | if (mbx->ops.check_for_msg) |
94 | ret_val = mbx->ops.check_for_msg(hw, mbx_id); | 94 | ret_val = mbx->ops.check_for_msg(hw, mbx_id); |
95 | 95 | ||
96 | return ret_val; | 96 | return ret_val; |
97 | } | 97 | } |
98 | 98 | ||
99 | /** | 99 | /** |
100 | * ixgbe_check_for_ack - checks to see if someone sent us ACK | 100 | * ixgbe_check_for_ack - checks to see if someone sent us ACK |
101 | * @hw: pointer to the HW structure | 101 | * @hw: pointer to the HW structure |
102 | * @mbx_id: id of mailbox to check | 102 | * @mbx_id: id of mailbox to check |
103 | * | 103 | * |
104 | * returns SUCCESS if the Status bit was found or else ERR_MBX | 104 | * returns SUCCESS if the Status bit was found or else ERR_MBX |
105 | **/ | 105 | **/ |
106 | s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) | 106 | s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) |
107 | { | 107 | { |
108 | struct ixgbe_mbx_info *mbx = &hw->mbx; | 108 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
109 | s32 ret_val = IXGBE_ERR_MBX; | 109 | s32 ret_val = IXGBE_ERR_MBX; |
110 | 110 | ||
111 | if (mbx->ops.check_for_ack) | 111 | if (mbx->ops.check_for_ack) |
112 | ret_val = mbx->ops.check_for_ack(hw, mbx_id); | 112 | ret_val = mbx->ops.check_for_ack(hw, mbx_id); |
113 | 113 | ||
114 | return ret_val; | 114 | return ret_val; |
115 | } | 115 | } |
116 | 116 | ||
117 | /** | 117 | /** |
118 | * ixgbe_check_for_rst - checks to see if other side has reset | 118 | * ixgbe_check_for_rst - checks to see if other side has reset |
119 | * @hw: pointer to the HW structure | 119 | * @hw: pointer to the HW structure |
120 | * @mbx_id: id of mailbox to check | 120 | * @mbx_id: id of mailbox to check |
121 | * | 121 | * |
122 | * returns SUCCESS if the Status bit was found or else ERR_MBX | 122 | * returns SUCCESS if the Status bit was found or else ERR_MBX |
123 | **/ | 123 | **/ |
124 | s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id) | 124 | s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id) |
125 | { | 125 | { |
126 | struct ixgbe_mbx_info *mbx = &hw->mbx; | 126 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
127 | s32 ret_val = IXGBE_ERR_MBX; | 127 | s32 ret_val = IXGBE_ERR_MBX; |
128 | 128 | ||
129 | if (mbx->ops.check_for_rst) | 129 | if (mbx->ops.check_for_rst) |
130 | ret_val = mbx->ops.check_for_rst(hw, mbx_id); | 130 | ret_val = mbx->ops.check_for_rst(hw, mbx_id); |
131 | 131 | ||
132 | return ret_val; | 132 | return ret_val; |
133 | } | 133 | } |
134 | 134 | ||
135 | /** | 135 | /** |
136 | * ixgbe_poll_for_msg - Wait for message notification | 136 | * ixgbe_poll_for_msg - Wait for message notification |
137 | * @hw: pointer to the HW structure | 137 | * @hw: pointer to the HW structure |
138 | * @mbx_id: id of mailbox to write | 138 | * @mbx_id: id of mailbox to write |
139 | * | 139 | * |
140 | * returns SUCCESS if it successfully received a message notification | 140 | * returns SUCCESS if it successfully received a message notification |
141 | **/ | 141 | **/ |
142 | static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) | 142 | static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) |
143 | { | 143 | { |
144 | struct ixgbe_mbx_info *mbx = &hw->mbx; | 144 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
145 | int countdown = mbx->timeout; | 145 | int countdown = mbx->timeout; |
146 | 146 | ||
147 | if (!countdown || !mbx->ops.check_for_msg) | 147 | if (!countdown || !mbx->ops.check_for_msg) |
148 | goto out; | 148 | goto out; |
149 | 149 | ||
150 | while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) { | 150 | while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) { |
151 | countdown--; | 151 | countdown--; |
152 | if (!countdown) | 152 | if (!countdown) |
153 | break; | 153 | break; |
154 | udelay(mbx->usec_delay); | 154 | udelay(mbx->usec_delay); |
155 | } | 155 | } |
156 | 156 | ||
157 | /* if we failed, all future posted messages fail until reset */ | ||
158 | if (!countdown) | ||
159 | mbx->timeout = 0; | ||
160 | out: | 157 | out: |
161 | return countdown ? 0 : IXGBE_ERR_MBX; | 158 | return countdown ? 0 : IXGBE_ERR_MBX; |
162 | } | 159 | } |
163 | 160 | ||
164 | /** | 161 | /** |
165 | * ixgbe_poll_for_ack - Wait for message acknowledgement | 162 | * ixgbe_poll_for_ack - Wait for message acknowledgement |
166 | * @hw: pointer to the HW structure | 163 | * @hw: pointer to the HW structure |
167 | * @mbx_id: id of mailbox to write | 164 | * @mbx_id: id of mailbox to write |
168 | * | 165 | * |
169 | * returns SUCCESS if it successfully received a message acknowledgement | 166 | * returns SUCCESS if it successfully received a message acknowledgement |
170 | **/ | 167 | **/ |
171 | static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) | 168 | static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) |
172 | { | 169 | { |
173 | struct ixgbe_mbx_info *mbx = &hw->mbx; | 170 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
174 | int countdown = mbx->timeout; | 171 | int countdown = mbx->timeout; |
175 | 172 | ||
176 | if (!countdown || !mbx->ops.check_for_ack) | 173 | if (!countdown || !mbx->ops.check_for_ack) |
177 | goto out; | 174 | goto out; |
178 | 175 | ||
179 | while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) { | 176 | while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) { |
180 | countdown--; | 177 | countdown--; |
181 | if (!countdown) | 178 | if (!countdown) |
182 | break; | 179 | break; |
183 | udelay(mbx->usec_delay); | 180 | udelay(mbx->usec_delay); |
184 | } | 181 | } |
185 | 182 | ||
186 | /* if we failed, all future posted messages fail until reset */ | ||
187 | if (!countdown) | ||
188 | mbx->timeout = 0; | ||
189 | out: | 183 | out: |
190 | return countdown ? 0 : IXGBE_ERR_MBX; | 184 | return countdown ? 0 : IXGBE_ERR_MBX; |
191 | } | 185 | } |
192 | 186 | ||
193 | /** | 187 | /** |
194 | * ixgbe_read_posted_mbx - Wait for message notification and receive message | 188 | * ixgbe_read_posted_mbx - Wait for message notification and receive message |
195 | * @hw: pointer to the HW structure | 189 | * @hw: pointer to the HW structure |
196 | * @msg: The message buffer | 190 | * @msg: The message buffer |
197 | * @size: Length of buffer | 191 | * @size: Length of buffer |
198 | * @mbx_id: id of mailbox to write | 192 | * @mbx_id: id of mailbox to write |
199 | * | 193 | * |
200 | * returns SUCCESS if it successfully received a message notification and | 194 | * returns SUCCESS if it successfully received a message notification and |
201 | * copied it into the receive buffer. | 195 | * copied it into the receive buffer. |
202 | **/ | 196 | **/ |
203 | static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, | 197 | static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, |
204 | u16 mbx_id) | 198 | u16 mbx_id) |
205 | { | 199 | { |
206 | struct ixgbe_mbx_info *mbx = &hw->mbx; | 200 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
207 | s32 ret_val = IXGBE_ERR_MBX; | 201 | s32 ret_val = IXGBE_ERR_MBX; |
208 | 202 | ||
209 | if (!mbx->ops.read) | 203 | if (!mbx->ops.read) |
210 | goto out; | 204 | goto out; |
211 | 205 | ||
212 | ret_val = ixgbe_poll_for_msg(hw, mbx_id); | 206 | ret_val = ixgbe_poll_for_msg(hw, mbx_id); |
213 | 207 | ||
214 | /* if ack received read message, otherwise we timed out */ | 208 | /* if ack received read message, otherwise we timed out */ |
215 | if (!ret_val) | 209 | if (!ret_val) |
216 | ret_val = mbx->ops.read(hw, msg, size, mbx_id); | 210 | ret_val = mbx->ops.read(hw, msg, size, mbx_id); |
217 | out: | 211 | out: |
218 | return ret_val; | 212 | return ret_val; |
219 | } | 213 | } |
220 | 214 | ||
221 | /** | 215 | /** |
222 | * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack | 216 | * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack |
223 | * @hw: pointer to the HW structure | 217 | * @hw: pointer to the HW structure |
224 | * @msg: The message buffer | 218 | * @msg: The message buffer |
225 | * @size: Length of buffer | 219 | * @size: Length of buffer |
226 | * @mbx_id: id of mailbox to write | 220 | * @mbx_id: id of mailbox to write |
227 | * | 221 | * |
228 | * returns SUCCESS if it successfully copied message into the buffer and | 222 | * returns SUCCESS if it successfully copied message into the buffer and |
229 | * received an ack to that message within delay * timeout period | 223 | * received an ack to that message within delay * timeout period |
230 | **/ | 224 | **/ |
231 | static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, | 225 | static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, |
232 | u16 mbx_id) | 226 | u16 mbx_id) |
233 | { | 227 | { |
234 | struct ixgbe_mbx_info *mbx = &hw->mbx; | 228 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
235 | s32 ret_val = IXGBE_ERR_MBX; | 229 | s32 ret_val = IXGBE_ERR_MBX; |
236 | 230 | ||
237 | /* exit if either we can't write or there isn't a defined timeout */ | 231 | /* exit if either we can't write or there isn't a defined timeout */ |
238 | if (!mbx->ops.write || !mbx->timeout) | 232 | if (!mbx->ops.write || !mbx->timeout) |
239 | goto out; | 233 | goto out; |
240 | 234 | ||
241 | /* send msg */ | 235 | /* send msg */ |
242 | ret_val = mbx->ops.write(hw, msg, size, mbx_id); | 236 | ret_val = mbx->ops.write(hw, msg, size, mbx_id); |
243 | 237 | ||
244 | /* if msg sent wait until we receive an ack */ | 238 | /* if msg sent wait until we receive an ack */ |
245 | if (!ret_val) | 239 | if (!ret_val) |
246 | ret_val = ixgbe_poll_for_ack(hw, mbx_id); | 240 | ret_val = ixgbe_poll_for_ack(hw, mbx_id); |
247 | out: | 241 | out: |
248 | return ret_val; | 242 | return ret_val; |
249 | } | 243 | } |
250 | 244 | ||
251 | static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) | 245 | static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) |
252 | { | 246 | { |
253 | u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index)); | 247 | u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index)); |
254 | s32 ret_val = IXGBE_ERR_MBX; | 248 | s32 ret_val = IXGBE_ERR_MBX; |
255 | 249 | ||
256 | if (mbvficr & mask) { | 250 | if (mbvficr & mask) { |
257 | ret_val = 0; | 251 | ret_val = 0; |
258 | IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask); | 252 | IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask); |
259 | } | 253 | } |
260 | 254 | ||
261 | return ret_val; | 255 | return ret_val; |
262 | } | 256 | } |
263 | 257 | ||
264 | /** | 258 | /** |
265 | * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail | 259 | * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail |
266 | * @hw: pointer to the HW structure | 260 | * @hw: pointer to the HW structure |
267 | * @vf_number: the VF index | 261 | * @vf_number: the VF index |
268 | * | 262 | * |
269 | * returns SUCCESS if the VF has set the Status bit or else ERR_MBX | 263 | * returns SUCCESS if the VF has set the Status bit or else ERR_MBX |
270 | **/ | 264 | **/ |
271 | static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number) | 265 | static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number) |
272 | { | 266 | { |
273 | s32 ret_val = IXGBE_ERR_MBX; | 267 | s32 ret_val = IXGBE_ERR_MBX; |
274 | s32 index = IXGBE_MBVFICR_INDEX(vf_number); | 268 | s32 index = IXGBE_MBVFICR_INDEX(vf_number); |
275 | u32 vf_bit = vf_number % 16; | 269 | u32 vf_bit = vf_number % 16; |
276 | 270 | ||
277 | if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit, | 271 | if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit, |
278 | index)) { | 272 | index)) { |
279 | ret_val = 0; | 273 | ret_val = 0; |
280 | hw->mbx.stats.reqs++; | 274 | hw->mbx.stats.reqs++; |
281 | } | 275 | } |
282 | 276 | ||
283 | return ret_val; | 277 | return ret_val; |
284 | } | 278 | } |
285 | 279 | ||
286 | /** | 280 | /** |
287 | * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed | 281 | * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed |
288 | * @hw: pointer to the HW structure | 282 | * @hw: pointer to the HW structure |
289 | * @vf_number: the VF index | 283 | * @vf_number: the VF index |
290 | * | 284 | * |
291 | * returns SUCCESS if the VF has set the Status bit or else ERR_MBX | 285 | * returns SUCCESS if the VF has set the Status bit or else ERR_MBX |
292 | **/ | 286 | **/ |
293 | static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number) | 287 | static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number) |
294 | { | 288 | { |
295 | s32 ret_val = IXGBE_ERR_MBX; | 289 | s32 ret_val = IXGBE_ERR_MBX; |
296 | s32 index = IXGBE_MBVFICR_INDEX(vf_number); | 290 | s32 index = IXGBE_MBVFICR_INDEX(vf_number); |
297 | u32 vf_bit = vf_number % 16; | 291 | u32 vf_bit = vf_number % 16; |
298 | 292 | ||
299 | if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit, | 293 | if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit, |
300 | index)) { | 294 | index)) { |
301 | ret_val = 0; | 295 | ret_val = 0; |
302 | hw->mbx.stats.acks++; | 296 | hw->mbx.stats.acks++; |
303 | } | 297 | } |
304 | 298 | ||
305 | return ret_val; | 299 | return ret_val; |
306 | } | 300 | } |
307 | 301 | ||
308 | /** | 302 | /** |
309 | * ixgbe_check_for_rst_pf - checks to see if the VF has reset | 303 | * ixgbe_check_for_rst_pf - checks to see if the VF has reset |
310 | * @hw: pointer to the HW structure | 304 | * @hw: pointer to the HW structure |
311 | * @vf_number: the VF index | 305 | * @vf_number: the VF index |
312 | * | 306 | * |
313 | * returns SUCCESS if the VF has set the Status bit or else ERR_MBX | 307 | * returns SUCCESS if the VF has set the Status bit or else ERR_MBX |
314 | **/ | 308 | **/ |
315 | static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) | 309 | static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) |
316 | { | 310 | { |
317 | u32 reg_offset = (vf_number < 32) ? 0 : 1; | 311 | u32 reg_offset = (vf_number < 32) ? 0 : 1; |
318 | u32 vf_shift = vf_number % 32; | 312 | u32 vf_shift = vf_number % 32; |
319 | u32 vflre = 0; | 313 | u32 vflre = 0; |
320 | s32 ret_val = IXGBE_ERR_MBX; | 314 | s32 ret_val = IXGBE_ERR_MBX; |
321 | 315 | ||
322 | switch (hw->mac.type) { | 316 | switch (hw->mac.type) { |
323 | case ixgbe_mac_82599EB: | 317 | case ixgbe_mac_82599EB: |
324 | vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); | 318 | vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); |
325 | break; | 319 | break; |
326 | case ixgbe_mac_X540: | 320 | case ixgbe_mac_X540: |
327 | vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset)); | 321 | vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset)); |
328 | break; | 322 | break; |
329 | default: | 323 | default: |
330 | break; | 324 | break; |
331 | } | 325 | } |
332 | 326 | ||
333 | if (vflre & (1 << vf_shift)) { | 327 | if (vflre & (1 << vf_shift)) { |
334 | ret_val = 0; | 328 | ret_val = 0; |
335 | IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift)); | 329 | IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift)); |
336 | hw->mbx.stats.rsts++; | 330 | hw->mbx.stats.rsts++; |
337 | } | 331 | } |
338 | 332 | ||
339 | return ret_val; | 333 | return ret_val; |
340 | } | 334 | } |
341 | 335 | ||
342 | /** | 336 | /** |
343 | * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock | 337 | * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock |
344 | * @hw: pointer to the HW structure | 338 | * @hw: pointer to the HW structure |
345 | * @vf_number: the VF index | 339 | * @vf_number: the VF index |
346 | * | 340 | * |
347 | * return SUCCESS if we obtained the mailbox lock | 341 | * return SUCCESS if we obtained the mailbox lock |
348 | **/ | 342 | **/ |
349 | static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number) | 343 | static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number) |
350 | { | 344 | { |
351 | s32 ret_val = IXGBE_ERR_MBX; | 345 | s32 ret_val = IXGBE_ERR_MBX; |
352 | u32 p2v_mailbox; | 346 | u32 p2v_mailbox; |
353 | 347 | ||
354 | /* Take ownership of the buffer */ | 348 | /* Take ownership of the buffer */ |
355 | IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU); | 349 | IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU); |
356 | 350 | ||
357 | /* reserve mailbox for vf use */ | 351 | /* reserve mailbox for vf use */ |
358 | p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number)); | 352 | p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number)); |
359 | if (p2v_mailbox & IXGBE_PFMAILBOX_PFU) | 353 | if (p2v_mailbox & IXGBE_PFMAILBOX_PFU) |
360 | ret_val = 0; | 354 | ret_val = 0; |
361 | 355 | ||
362 | return ret_val; | 356 | return ret_val; |
363 | } | 357 | } |
364 | 358 | ||
365 | /** | 359 | /** |
366 | * ixgbe_write_mbx_pf - Places a message in the mailbox | 360 | * ixgbe_write_mbx_pf - Places a message in the mailbox |
367 | * @hw: pointer to the HW structure | 361 | * @hw: pointer to the HW structure |
368 | * @msg: The message buffer | 362 | * @msg: The message buffer |
369 | * @size: Length of buffer | 363 | * @size: Length of buffer |
370 | * @vf_number: the VF index | 364 | * @vf_number: the VF index |
371 | * | 365 | * |
372 | * returns SUCCESS if it successfully copied message into the buffer | 366 | * returns SUCCESS if it successfully copied message into the buffer |
373 | **/ | 367 | **/ |
374 | static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, | 368 | static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, |
375 | u16 vf_number) | 369 | u16 vf_number) |
376 | { | 370 | { |
377 | s32 ret_val; | 371 | s32 ret_val; |
378 | u16 i; | 372 | u16 i; |
379 | 373 | ||
380 | /* lock the mailbox to prevent pf/vf race condition */ | 374 | /* lock the mailbox to prevent pf/vf race condition */ |
381 | ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); | 375 | ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); |
382 | if (ret_val) | 376 | if (ret_val) |
383 | goto out_no_write; | 377 | goto out_no_write; |
384 | 378 | ||
385 | /* flush msg and acks as we are overwriting the message buffer */ | 379 | /* flush msg and acks as we are overwriting the message buffer */ |
386 | ixgbe_check_for_msg_pf(hw, vf_number); | 380 | ixgbe_check_for_msg_pf(hw, vf_number); |
387 | ixgbe_check_for_ack_pf(hw, vf_number); | 381 | ixgbe_check_for_ack_pf(hw, vf_number); |
388 | 382 | ||
389 | /* copy the caller specified message to the mailbox memory buffer */ | 383 | /* copy the caller specified message to the mailbox memory buffer */ |
390 | for (i = 0; i < size; i++) | 384 | for (i = 0; i < size; i++) |
391 | IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]); | 385 | IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]); |
392 | 386 | ||
393 | /* Interrupt VF to tell it a message has been sent and release buffer*/ | 387 | /* Interrupt VF to tell it a message has been sent and release buffer*/ |
394 | IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS); | 388 | IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS); |
395 | 389 | ||
396 | /* update stats */ | 390 | /* update stats */ |
397 | hw->mbx.stats.msgs_tx++; | 391 | hw->mbx.stats.msgs_tx++; |
398 | 392 | ||
399 | out_no_write: | 393 | out_no_write: |
400 | return ret_val; | 394 | return ret_val; |
401 | 395 | ||
402 | } | 396 | } |
403 | 397 | ||
404 | /** | 398 | /** |
405 | * ixgbe_read_mbx_pf - Read a message from the mailbox | 399 | * ixgbe_read_mbx_pf - Read a message from the mailbox |
406 | * @hw: pointer to the HW structure | 400 | * @hw: pointer to the HW structure |
407 | * @msg: The message buffer | 401 | * @msg: The message buffer |
408 | * @size: Length of buffer | 402 | * @size: Length of buffer |
409 | * @vf_number: the VF index | 403 | * @vf_number: the VF index |
410 | * | 404 | * |
411 | * This function copies a message from the mailbox buffer to the caller's | 405 | * This function copies a message from the mailbox buffer to the caller's |
412 | * memory buffer. The presumption is that the caller knows that there was | 406 | * memory buffer. The presumption is that the caller knows that there was |
413 | * a message due to a VF request so no polling for message is needed. | 407 | * a message due to a VF request so no polling for message is needed. |
414 | **/ | 408 | **/ |
415 | static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, | 409 | static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, |
416 | u16 vf_number) | 410 | u16 vf_number) |
417 | { | 411 | { |
418 | s32 ret_val; | 412 | s32 ret_val; |
419 | u16 i; | 413 | u16 i; |
420 | 414 | ||
421 | /* lock the mailbox to prevent pf/vf race condition */ | 415 | /* lock the mailbox to prevent pf/vf race condition */ |
422 | ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); | 416 | ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); |
423 | if (ret_val) | 417 | if (ret_val) |
424 | goto out_no_read; | 418 | goto out_no_read; |
425 | 419 | ||
426 | /* copy the message to the mailbox memory buffer */ | 420 | /* copy the message to the mailbox memory buffer */ |
427 | for (i = 0; i < size; i++) | 421 | for (i = 0; i < size; i++) |
428 | msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i); | 422 | msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i); |
429 | 423 | ||
430 | /* Acknowledge the message and release buffer */ | 424 | /* Acknowledge the message and release buffer */ |
431 | IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK); | 425 | IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK); |
432 | 426 | ||
433 | /* update stats */ | 427 | /* update stats */ |
434 | hw->mbx.stats.msgs_rx++; | 428 | hw->mbx.stats.msgs_rx++; |
435 | 429 | ||
436 | out_no_read: | 430 | out_no_read: |
437 | return ret_val; | 431 | return ret_val; |
438 | } | 432 | } |
439 | 433 | ||
440 | #ifdef CONFIG_PCI_IOV | 434 | #ifdef CONFIG_PCI_IOV |
441 | /** | 435 | /** |
442 | * ixgbe_init_mbx_params_pf - set initial values for pf mailbox | 436 | * ixgbe_init_mbx_params_pf - set initial values for pf mailbox |
443 | * @hw: pointer to the HW structure | 437 | * @hw: pointer to the HW structure |
444 | * | 438 | * |
445 | * Initializes the hw->mbx struct to correct values for pf mailbox | 439 | * Initializes the hw->mbx struct to correct values for pf mailbox |
446 | */ | 440 | */ |
447 | void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) | 441 | void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) |
448 | { | 442 | { |
449 | struct ixgbe_mbx_info *mbx = &hw->mbx; | 443 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
450 | 444 | ||
451 | if (hw->mac.type != ixgbe_mac_82599EB && | 445 | if (hw->mac.type != ixgbe_mac_82599EB && |
452 | hw->mac.type != ixgbe_mac_X540) | 446 | hw->mac.type != ixgbe_mac_X540) |
453 | return; | 447 | return; |
454 | 448 | ||
455 | mbx->timeout = 0; | 449 | mbx->timeout = 0; |
456 | mbx->usec_delay = 0; | 450 | mbx->usec_delay = 0; |
457 | 451 | ||
458 | mbx->stats.msgs_tx = 0; | 452 | mbx->stats.msgs_tx = 0; |
459 | mbx->stats.msgs_rx = 0; | 453 | mbx->stats.msgs_rx = 0; |
460 | mbx->stats.reqs = 0; | 454 | mbx->stats.reqs = 0; |
461 | mbx->stats.acks = 0; | 455 | mbx->stats.acks = 0; |
462 | mbx->stats.rsts = 0; | 456 | mbx->stats.rsts = 0; |
463 | 457 | ||
464 | mbx->size = IXGBE_VFMAILBOX_SIZE; | 458 | mbx->size = IXGBE_VFMAILBOX_SIZE; |
465 | } | 459 | } |
466 | #endif /* CONFIG_PCI_IOV */ | 460 | #endif /* CONFIG_PCI_IOV */ |
467 | 461 | ||
468 | struct ixgbe_mbx_operations mbx_ops_generic = { | 462 | struct ixgbe_mbx_operations mbx_ops_generic = { |
469 | .read = ixgbe_read_mbx_pf, | 463 | .read = ixgbe_read_mbx_pf, |
470 | .write = ixgbe_write_mbx_pf, | 464 | .write = ixgbe_write_mbx_pf, |
471 | .read_posted = ixgbe_read_posted_mbx, | 465 | .read_posted = ixgbe_read_posted_mbx, |
472 | .write_posted = ixgbe_write_posted_mbx, | 466 | .write_posted = ixgbe_write_posted_mbx, |
473 | .check_for_msg = ixgbe_check_for_msg_pf, | 467 | .check_for_msg = ixgbe_check_for_msg_pf, |
474 | .check_for_ack = ixgbe_check_for_ack_pf, | 468 | .check_for_ack = ixgbe_check_for_ack_pf, |
475 | .check_for_rst = ixgbe_check_for_rst_pf, | 469 | .check_for_rst = ixgbe_check_for_rst_pf, |
476 | }; | 470 | }; |
477 | 471 | ||
478 | 472 |