|
1 /* Intel(R) Gigabit Ethernet Linux driver |
|
2 * Copyright(c) 2007-2014 Intel Corporation. |
|
3 * |
|
4 * This program is free software; you can redistribute it and/or modify it |
|
5 * under the terms and conditions of the GNU General Public License, |
|
6 * version 2, as published by the Free Software Foundation. |
|
7 * |
|
8 * This program is distributed in the hope it will be useful, but WITHOUT |
|
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|
11 * more details. |
|
12 * |
|
13 * You should have received a copy of the GNU General Public License along with |
|
14 * this program; if not, see <http://www.gnu.org/licenses/>. |
|
15 * |
|
16 * The full GNU General Public License is included in this distribution in |
|
17 * the file called "COPYING". |
|
18 * |
|
19 * Contact Information: |
|
20 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> |
|
21 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
|
22 */ |
|
23 |
|
24 #include "e1000_mbx.h" |
|
25 |
|
26 /** |
|
27 * igb_read_mbx - Reads a message from the mailbox |
|
28 * @hw: pointer to the HW structure |
|
29 * @msg: The message buffer |
|
30 * @size: Length of buffer |
|
31 * @mbx_id: id of mailbox to read |
|
32 * |
|
33 * returns SUCCESS if it successfully read message from buffer |
|
34 **/ |
|
35 s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) |
|
36 { |
|
37 struct e1000_mbx_info *mbx = &hw->mbx; |
|
38 s32 ret_val = -E1000_ERR_MBX; |
|
39 |
|
40 /* limit read to size of mailbox */ |
|
41 if (size > mbx->size) |
|
42 size = mbx->size; |
|
43 |
|
44 if (mbx->ops.read) |
|
45 ret_val = mbx->ops.read(hw, msg, size, mbx_id); |
|
46 |
|
47 return ret_val; |
|
48 } |
|
49 |
|
50 /** |
|
51 * igb_write_mbx - Write a message to the mailbox |
|
52 * @hw: pointer to the HW structure |
|
53 * @msg: The message buffer |
|
54 * @size: Length of buffer |
|
55 * @mbx_id: id of mailbox to write |
|
56 * |
|
57 * returns SUCCESS if it successfully copied message into the buffer |
|
58 **/ |
|
59 s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) |
|
60 { |
|
61 struct e1000_mbx_info *mbx = &hw->mbx; |
|
62 s32 ret_val = 0; |
|
63 |
|
64 if (size > mbx->size) |
|
65 ret_val = -E1000_ERR_MBX; |
|
66 |
|
67 else if (mbx->ops.write) |
|
68 ret_val = mbx->ops.write(hw, msg, size, mbx_id); |
|
69 |
|
70 return ret_val; |
|
71 } |
|
72 |
|
73 /** |
|
74 * igb_check_for_msg - checks to see if someone sent us mail |
|
75 * @hw: pointer to the HW structure |
|
76 * @mbx_id: id of mailbox to check |
|
77 * |
|
78 * returns SUCCESS if the Status bit was found or else ERR_MBX |
|
79 **/ |
|
80 s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id) |
|
81 { |
|
82 struct e1000_mbx_info *mbx = &hw->mbx; |
|
83 s32 ret_val = -E1000_ERR_MBX; |
|
84 |
|
85 if (mbx->ops.check_for_msg) |
|
86 ret_val = mbx->ops.check_for_msg(hw, mbx_id); |
|
87 |
|
88 return ret_val; |
|
89 } |
|
90 |
|
91 /** |
|
92 * igb_check_for_ack - checks to see if someone sent us ACK |
|
93 * @hw: pointer to the HW structure |
|
94 * @mbx_id: id of mailbox to check |
|
95 * |
|
96 * returns SUCCESS if the Status bit was found or else ERR_MBX |
|
97 **/ |
|
98 s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id) |
|
99 { |
|
100 struct e1000_mbx_info *mbx = &hw->mbx; |
|
101 s32 ret_val = -E1000_ERR_MBX; |
|
102 |
|
103 if (mbx->ops.check_for_ack) |
|
104 ret_val = mbx->ops.check_for_ack(hw, mbx_id); |
|
105 |
|
106 return ret_val; |
|
107 } |
|
108 |
|
109 /** |
|
110 * igb_check_for_rst - checks to see if other side has reset |
|
111 * @hw: pointer to the HW structure |
|
112 * @mbx_id: id of mailbox to check |
|
113 * |
|
114 * returns SUCCESS if the Status bit was found or else ERR_MBX |
|
115 **/ |
|
116 s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id) |
|
117 { |
|
118 struct e1000_mbx_info *mbx = &hw->mbx; |
|
119 s32 ret_val = -E1000_ERR_MBX; |
|
120 |
|
121 if (mbx->ops.check_for_rst) |
|
122 ret_val = mbx->ops.check_for_rst(hw, mbx_id); |
|
123 |
|
124 return ret_val; |
|
125 } |
|
126 |
|
127 /** |
|
128 * igb_poll_for_msg - Wait for message notification |
|
129 * @hw: pointer to the HW structure |
|
130 * @mbx_id: id of mailbox to write |
|
131 * |
|
132 * returns SUCCESS if it successfully received a message notification |
|
133 **/ |
|
134 static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id) |
|
135 { |
|
136 struct e1000_mbx_info *mbx = &hw->mbx; |
|
137 int countdown = mbx->timeout; |
|
138 |
|
139 if (!countdown || !mbx->ops.check_for_msg) |
|
140 goto out; |
|
141 |
|
142 while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) { |
|
143 countdown--; |
|
144 if (!countdown) |
|
145 break; |
|
146 udelay(mbx->usec_delay); |
|
147 } |
|
148 |
|
149 /* if we failed, all future posted messages fail until reset */ |
|
150 if (!countdown) |
|
151 mbx->timeout = 0; |
|
152 out: |
|
153 return countdown ? 0 : -E1000_ERR_MBX; |
|
154 } |
|
155 |
|
156 /** |
|
157 * igb_poll_for_ack - Wait for message acknowledgement |
|
158 * @hw: pointer to the HW structure |
|
159 * @mbx_id: id of mailbox to write |
|
160 * |
|
161 * returns SUCCESS if it successfully received a message acknowledgement |
|
162 **/ |
|
163 static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id) |
|
164 { |
|
165 struct e1000_mbx_info *mbx = &hw->mbx; |
|
166 int countdown = mbx->timeout; |
|
167 |
|
168 if (!countdown || !mbx->ops.check_for_ack) |
|
169 goto out; |
|
170 |
|
171 while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) { |
|
172 countdown--; |
|
173 if (!countdown) |
|
174 break; |
|
175 udelay(mbx->usec_delay); |
|
176 } |
|
177 |
|
178 /* if we failed, all future posted messages fail until reset */ |
|
179 if (!countdown) |
|
180 mbx->timeout = 0; |
|
181 out: |
|
182 return countdown ? 0 : -E1000_ERR_MBX; |
|
183 } |
|
184 |
|
185 /** |
|
186 * igb_read_posted_mbx - Wait for message notification and receive message |
|
187 * @hw: pointer to the HW structure |
|
188 * @msg: The message buffer |
|
189 * @size: Length of buffer |
|
190 * @mbx_id: id of mailbox to write |
|
191 * |
|
192 * returns SUCCESS if it successfully received a message notification and |
|
193 * copied it into the receive buffer. |
|
194 **/ |
|
195 static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, |
|
196 u16 mbx_id) |
|
197 { |
|
198 struct e1000_mbx_info *mbx = &hw->mbx; |
|
199 s32 ret_val = -E1000_ERR_MBX; |
|
200 |
|
201 if (!mbx->ops.read) |
|
202 goto out; |
|
203 |
|
204 ret_val = igb_poll_for_msg(hw, mbx_id); |
|
205 |
|
206 if (!ret_val) |
|
207 ret_val = mbx->ops.read(hw, msg, size, mbx_id); |
|
208 out: |
|
209 return ret_val; |
|
210 } |
|
211 |
|
212 /** |
|
213 * igb_write_posted_mbx - Write a message to the mailbox, wait for ack |
|
214 * @hw: pointer to the HW structure |
|
215 * @msg: The message buffer |
|
216 * @size: Length of buffer |
|
217 * @mbx_id: id of mailbox to write |
|
218 * |
|
219 * returns SUCCESS if it successfully copied message into the buffer and |
|
220 * received an ack to that message within delay * timeout period |
|
221 **/ |
|
222 static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, |
|
223 u16 mbx_id) |
|
224 { |
|
225 struct e1000_mbx_info *mbx = &hw->mbx; |
|
226 s32 ret_val = -E1000_ERR_MBX; |
|
227 |
|
228 /* exit if either we can't write or there isn't a defined timeout */ |
|
229 if (!mbx->ops.write || !mbx->timeout) |
|
230 goto out; |
|
231 |
|
232 /* send msg */ |
|
233 ret_val = mbx->ops.write(hw, msg, size, mbx_id); |
|
234 |
|
235 /* if msg sent wait until we receive an ack */ |
|
236 if (!ret_val) |
|
237 ret_val = igb_poll_for_ack(hw, mbx_id); |
|
238 out: |
|
239 return ret_val; |
|
240 } |
|
241 |
|
242 static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask) |
|
243 { |
|
244 u32 mbvficr = rd32(E1000_MBVFICR); |
|
245 s32 ret_val = -E1000_ERR_MBX; |
|
246 |
|
247 if (mbvficr & mask) { |
|
248 ret_val = 0; |
|
249 wr32(E1000_MBVFICR, mask); |
|
250 } |
|
251 |
|
252 return ret_val; |
|
253 } |
|
254 |
|
255 /** |
|
256 * igb_check_for_msg_pf - checks to see if the VF has sent mail |
|
257 * @hw: pointer to the HW structure |
|
258 * @vf_number: the VF index |
|
259 * |
|
260 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX |
|
261 **/ |
|
262 static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number) |
|
263 { |
|
264 s32 ret_val = -E1000_ERR_MBX; |
|
265 |
|
266 if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) { |
|
267 ret_val = 0; |
|
268 hw->mbx.stats.reqs++; |
|
269 } |
|
270 |
|
271 return ret_val; |
|
272 } |
|
273 |
|
274 /** |
|
275 * igb_check_for_ack_pf - checks to see if the VF has ACKed |
|
276 * @hw: pointer to the HW structure |
|
277 * @vf_number: the VF index |
|
278 * |
|
279 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX |
|
280 **/ |
|
281 static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number) |
|
282 { |
|
283 s32 ret_val = -E1000_ERR_MBX; |
|
284 |
|
285 if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) { |
|
286 ret_val = 0; |
|
287 hw->mbx.stats.acks++; |
|
288 } |
|
289 |
|
290 return ret_val; |
|
291 } |
|
292 |
|
293 /** |
|
294 * igb_check_for_rst_pf - checks to see if the VF has reset |
|
295 * @hw: pointer to the HW structure |
|
296 * @vf_number: the VF index |
|
297 * |
|
298 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX |
|
299 **/ |
|
300 static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number) |
|
301 { |
|
302 u32 vflre = rd32(E1000_VFLRE); |
|
303 s32 ret_val = -E1000_ERR_MBX; |
|
304 |
|
305 if (vflre & (1 << vf_number)) { |
|
306 ret_val = 0; |
|
307 wr32(E1000_VFLRE, (1 << vf_number)); |
|
308 hw->mbx.stats.rsts++; |
|
309 } |
|
310 |
|
311 return ret_val; |
|
312 } |
|
313 |
|
314 /** |
|
315 * igb_obtain_mbx_lock_pf - obtain mailbox lock |
|
316 * @hw: pointer to the HW structure |
|
317 * @vf_number: the VF index |
|
318 * |
|
319 * return SUCCESS if we obtained the mailbox lock |
|
320 **/ |
|
321 static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number) |
|
322 { |
|
323 s32 ret_val = -E1000_ERR_MBX; |
|
324 u32 p2v_mailbox; |
|
325 |
|
326 /* Take ownership of the buffer */ |
|
327 wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU); |
|
328 |
|
329 /* reserve mailbox for vf use */ |
|
330 p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number)); |
|
331 if (p2v_mailbox & E1000_P2VMAILBOX_PFU) |
|
332 ret_val = 0; |
|
333 |
|
334 return ret_val; |
|
335 } |
|
336 |
|
337 /** |
|
338 * igb_write_mbx_pf - Places a message in the mailbox |
|
339 * @hw: pointer to the HW structure |
|
340 * @msg: The message buffer |
|
341 * @size: Length of buffer |
|
342 * @vf_number: the VF index |
|
343 * |
|
344 * returns SUCCESS if it successfully copied message into the buffer |
|
345 **/ |
|
346 static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, |
|
347 u16 vf_number) |
|
348 { |
|
349 s32 ret_val; |
|
350 u16 i; |
|
351 |
|
352 /* lock the mailbox to prevent pf/vf race condition */ |
|
353 ret_val = igb_obtain_mbx_lock_pf(hw, vf_number); |
|
354 if (ret_val) |
|
355 goto out_no_write; |
|
356 |
|
357 /* flush msg and acks as we are overwriting the message buffer */ |
|
358 igb_check_for_msg_pf(hw, vf_number); |
|
359 igb_check_for_ack_pf(hw, vf_number); |
|
360 |
|
361 /* copy the caller specified message to the mailbox memory buffer */ |
|
362 for (i = 0; i < size; i++) |
|
363 array_wr32(E1000_VMBMEM(vf_number), i, msg[i]); |
|
364 |
|
365 /* Interrupt VF to tell it a message has been sent and release buffer*/ |
|
366 wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS); |
|
367 |
|
368 /* update stats */ |
|
369 hw->mbx.stats.msgs_tx++; |
|
370 |
|
371 out_no_write: |
|
372 return ret_val; |
|
373 |
|
374 } |
|
375 |
|
376 /** |
|
377 * igb_read_mbx_pf - Read a message from the mailbox |
|
378 * @hw: pointer to the HW structure |
|
379 * @msg: The message buffer |
|
380 * @size: Length of buffer |
|
381 * @vf_number: the VF index |
|
382 * |
|
383 * This function copies a message from the mailbox buffer to the caller's |
|
384 * memory buffer. The presumption is that the caller knows that there was |
|
385 * a message due to a VF request so no polling for message is needed. |
|
386 **/ |
|
387 static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, |
|
388 u16 vf_number) |
|
389 { |
|
390 s32 ret_val; |
|
391 u16 i; |
|
392 |
|
393 /* lock the mailbox to prevent pf/vf race condition */ |
|
394 ret_val = igb_obtain_mbx_lock_pf(hw, vf_number); |
|
395 if (ret_val) |
|
396 goto out_no_read; |
|
397 |
|
398 /* copy the message to the mailbox memory buffer */ |
|
399 for (i = 0; i < size; i++) |
|
400 msg[i] = array_rd32(E1000_VMBMEM(vf_number), i); |
|
401 |
|
402 /* Acknowledge the message and release buffer */ |
|
403 wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK); |
|
404 |
|
405 /* update stats */ |
|
406 hw->mbx.stats.msgs_rx++; |
|
407 |
|
408 out_no_read: |
|
409 return ret_val; |
|
410 } |
|
411 |
|
412 /** |
|
413 * e1000_init_mbx_params_pf - set initial values for pf mailbox |
|
414 * @hw: pointer to the HW structure |
|
415 * |
|
416 * Initializes the hw->mbx struct to correct values for pf mailbox |
|
417 */ |
|
418 s32 igb_init_mbx_params_pf(struct e1000_hw *hw) |
|
419 { |
|
420 struct e1000_mbx_info *mbx = &hw->mbx; |
|
421 |
|
422 mbx->timeout = 0; |
|
423 mbx->usec_delay = 0; |
|
424 |
|
425 mbx->size = E1000_VFMAILBOX_SIZE; |
|
426 |
|
427 mbx->ops.read = igb_read_mbx_pf; |
|
428 mbx->ops.write = igb_write_mbx_pf; |
|
429 mbx->ops.read_posted = igb_read_posted_mbx; |
|
430 mbx->ops.write_posted = igb_write_posted_mbx; |
|
431 mbx->ops.check_for_msg = igb_check_for_msg_pf; |
|
432 mbx->ops.check_for_ack = igb_check_for_ack_pf; |
|
433 mbx->ops.check_for_rst = igb_check_for_rst_pf; |
|
434 |
|
435 mbx->stats.msgs_tx = 0; |
|
436 mbx->stats.msgs_rx = 0; |
|
437 mbx->stats.reqs = 0; |
|
438 mbx->stats.acks = 0; |
|
439 mbx->stats.rsts = 0; |
|
440 |
|
441 return 0; |
|
442 } |
|
443 |