diff options
Diffstat (limited to 'drivers/net/igb/e1000_mbx.c')
-rw-r--r-- | drivers/net/igb/e1000_mbx.c | 82 |
1 files changed, 48 insertions, 34 deletions
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c index ed9058eca45c..c474cdb70047 100644 --- a/drivers/net/igb/e1000_mbx.c +++ b/drivers/net/igb/e1000_mbx.c | |||
@@ -143,12 +143,16 @@ static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id) | |||
143 | if (!countdown || !mbx->ops.check_for_msg) | 143 | if (!countdown || !mbx->ops.check_for_msg) |
144 | goto out; | 144 | goto out; |
145 | 145 | ||
146 | while (mbx->ops.check_for_msg(hw, mbx_id)) { | 146 | while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) { |
147 | countdown--; | 147 | countdown--; |
148 | if (!countdown) | 148 | if (!countdown) |
149 | break; | 149 | break; |
150 | udelay(mbx->usec_delay); | 150 | udelay(mbx->usec_delay); |
151 | } | 151 | } |
152 | |||
153 | /* if we failed, all future posted messages fail until reset */ | ||
154 | if (!countdown) | ||
155 | mbx->timeout = 0; | ||
152 | out: | 156 | out: |
153 | return countdown ? 0 : -E1000_ERR_MBX; | 157 | return countdown ? 0 : -E1000_ERR_MBX; |
154 | } | 158 | } |
@@ -168,12 +172,16 @@ static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id) | |||
168 | if (!countdown || !mbx->ops.check_for_ack) | 172 | if (!countdown || !mbx->ops.check_for_ack) |
169 | goto out; | 173 | goto out; |
170 | 174 | ||
171 | while (mbx->ops.check_for_ack(hw, mbx_id)) { | 175 | while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) { |
172 | countdown--; | 176 | countdown--; |
173 | if (!countdown) | 177 | if (!countdown) |
174 | break; | 178 | break; |
175 | udelay(mbx->usec_delay); | 179 | udelay(mbx->usec_delay); |
176 | } | 180 | } |
181 | |||
182 | /* if we failed, all future posted messages fail until reset */ | ||
183 | if (!countdown) | ||
184 | mbx->timeout = 0; | ||
177 | out: | 185 | out: |
178 | return countdown ? 0 : -E1000_ERR_MBX; | 186 | return countdown ? 0 : -E1000_ERR_MBX; |
179 | } | 187 | } |
@@ -217,12 +225,13 @@ out: | |||
217 | static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) | 225 | static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) |
218 | { | 226 | { |
219 | struct e1000_mbx_info *mbx = &hw->mbx; | 227 | struct e1000_mbx_info *mbx = &hw->mbx; |
220 | s32 ret_val = 0; | 228 | s32 ret_val = -E1000_ERR_MBX; |
221 | 229 | ||
222 | if (!mbx->ops.write) | 230 | /* exit if either we can't write or there isn't a defined timeout */ |
231 | if (!mbx->ops.write || !mbx->timeout) | ||
223 | goto out; | 232 | goto out; |
224 | 233 | ||
225 | /* send msg*/ | 234 | /* send msg */ |
226 | ret_val = mbx->ops.write(hw, msg, size, mbx_id); | 235 | ret_val = mbx->ops.write(hw, msg, size, mbx_id); |
227 | 236 | ||
228 | /* if msg sent wait until we receive an ack */ | 237 | /* if msg sent wait until we receive an ack */ |
@@ -305,6 +314,30 @@ static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number) | |||
305 | } | 314 | } |
306 | 315 | ||
307 | /** | 316 | /** |
317 | * igb_obtain_mbx_lock_pf - obtain mailbox lock | ||
318 | * @hw: pointer to the HW structure | ||
319 | * @vf_number: the VF index | ||
320 | * | ||
321 | * return SUCCESS if we obtained the mailbox lock | ||
322 | **/ | ||
323 | static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number) | ||
324 | { | ||
325 | s32 ret_val = -E1000_ERR_MBX; | ||
326 | u32 p2v_mailbox; | ||
327 | |||
328 | |||
329 | /* Take ownership of the buffer */ | ||
330 | wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU); | ||
331 | |||
332 | /* reserve mailbox for vf use */ | ||
333 | p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number)); | ||
334 | if (p2v_mailbox & E1000_P2VMAILBOX_PFU) | ||
335 | ret_val = 0; | ||
336 | |||
337 | return ret_val; | ||
338 | } | ||
339 | |||
340 | /** | ||
308 | * igb_write_mbx_pf - Places a message in the mailbox | 341 | * igb_write_mbx_pf - Places a message in the mailbox |
309 | * @hw: pointer to the HW structure | 342 | * @hw: pointer to the HW structure |
310 | * @msg: The message buffer | 343 | * @msg: The message buffer |
@@ -316,27 +349,17 @@ static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number) | |||
316 | static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, | 349 | static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, |
317 | u16 vf_number) | 350 | u16 vf_number) |
318 | { | 351 | { |
319 | u32 p2v_mailbox; | 352 | s32 ret_val; |
320 | s32 ret_val = 0; | ||
321 | u16 i; | 353 | u16 i; |
322 | 354 | ||
323 | /* Take ownership of the buffer */ | 355 | /* lock the mailbox to prevent pf/vf race condition */ |
324 | wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU); | 356 | ret_val = igb_obtain_mbx_lock_pf(hw, vf_number); |
325 | 357 | if (ret_val) | |
326 | /* Make sure we have ownership now... */ | ||
327 | p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number)); | ||
328 | if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) { | ||
329 | /* failed to grab ownership */ | ||
330 | ret_val = -E1000_ERR_MBX; | ||
331 | goto out_no_write; | 358 | goto out_no_write; |
332 | } | ||
333 | 359 | ||
334 | /* | 360 | /* flush msg and acks as we are overwriting the message buffer */ |
335 | * flush any ack or msg which may already be in the queue | ||
336 | * as they are likely the result of an error | ||
337 | */ | ||
338 | igb_check_for_ack_pf(hw, vf_number); | ||
339 | igb_check_for_msg_pf(hw, vf_number); | 361 | igb_check_for_msg_pf(hw, vf_number); |
362 | igb_check_for_ack_pf(hw, vf_number); | ||
340 | 363 | ||
341 | /* copy the caller specified message to the mailbox memory buffer */ | 364 | /* copy the caller specified message to the mailbox memory buffer */ |
342 | for (i = 0; i < size; i++) | 365 | for (i = 0; i < size; i++) |
@@ -367,20 +390,13 @@ out_no_write: | |||
367 | static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, | 390 | static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, |
368 | u16 vf_number) | 391 | u16 vf_number) |
369 | { | 392 | { |
370 | u32 p2v_mailbox; | 393 | s32 ret_val; |
371 | s32 ret_val = 0; | ||
372 | u16 i; | 394 | u16 i; |
373 | 395 | ||
374 | /* Take ownership of the buffer */ | 396 | /* lock the mailbox to prevent pf/vf race condition */ |
375 | wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU); | 397 | ret_val = igb_obtain_mbx_lock_pf(hw, vf_number); |
376 | 398 | if (ret_val) | |
377 | /* Make sure we have ownership now... */ | ||
378 | p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number)); | ||
379 | if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) { | ||
380 | /* failed to grab ownership */ | ||
381 | ret_val = -E1000_ERR_MBX; | ||
382 | goto out_no_read; | 399 | goto out_no_read; |
383 | } | ||
384 | 400 | ||
385 | /* copy the message to the mailbox memory buffer */ | 401 | /* copy the message to the mailbox memory buffer */ |
386 | for (i = 0; i < size; i++) | 402 | for (i = 0; i < size; i++) |
@@ -392,8 +408,6 @@ static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, | |||
392 | /* update stats */ | 408 | /* update stats */ |
393 | hw->mbx.stats.msgs_rx++; | 409 | hw->mbx.stats.msgs_rx++; |
394 | 410 | ||
395 | ret_val = 0; | ||
396 | |||
397 | out_no_read: | 411 | out_no_read: |
398 | return ret_val; | 412 | return ret_val; |
399 | } | 413 | } |