Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
e1000_mbx.c
Go to the documentation of this file.
1 /*******************************************************************************
2 
3  Intel(R) Gigabit Ethernet Linux driver
4  Copyright(c) 2007-2012 Intel Corporation.
5 
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,
8  version 2, as published by the Free Software Foundation.
9 
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
12  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  more details.
14 
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.,
17  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 
19  The full GNU General Public License is included in this distribution in
20  the file called "COPYING".
21 
22  Contact Information:
23  e1000-devel Mailing List <[email protected]>
24  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25 
26 *******************************************************************************/
27 
28 #include "e1000_mbx.h"
29 
39 s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
40 {
41  struct e1000_mbx_info *mbx = &hw->mbx;
42  s32 ret_val = -E1000_ERR_MBX;
43 
44  /* limit read to size of mailbox */
45  if (size > mbx->size)
46  size = mbx->size;
47 
48  if (mbx->ops.read)
49  ret_val = mbx->ops.read(hw, msg, size, mbx_id);
50 
51  return ret_val;
52 }
53 
63 s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
64 {
65  struct e1000_mbx_info *mbx = &hw->mbx;
66  s32 ret_val = 0;
67 
68  if (size > mbx->size)
69  ret_val = -E1000_ERR_MBX;
70 
71  else if (mbx->ops.write)
72  ret_val = mbx->ops.write(hw, msg, size, mbx_id);
73 
74  return ret_val;
75 }
76 
85 {
86  struct e1000_mbx_info *mbx = &hw->mbx;
87  s32 ret_val = -E1000_ERR_MBX;
88 
89  if (mbx->ops.check_for_msg)
90  ret_val = mbx->ops.check_for_msg(hw, mbx_id);
91 
92  return ret_val;
93 }
94 
103 {
104  struct e1000_mbx_info *mbx = &hw->mbx;
105  s32 ret_val = -E1000_ERR_MBX;
106 
107  if (mbx->ops.check_for_ack)
108  ret_val = mbx->ops.check_for_ack(hw, mbx_id);
109 
110  return ret_val;
111 }
112 
121 {
122  struct e1000_mbx_info *mbx = &hw->mbx;
123  s32 ret_val = -E1000_ERR_MBX;
124 
125  if (mbx->ops.check_for_rst)
126  ret_val = mbx->ops.check_for_rst(hw, mbx_id);
127 
128  return ret_val;
129 }
130 
138 static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
139 {
140  struct e1000_mbx_info *mbx = &hw->mbx;
141  int countdown = mbx->timeout;
142 
143  if (!countdown || !mbx->ops.check_for_msg)
144  goto out;
145 
146  while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
147  countdown--;
148  if (!countdown)
149  break;
150  udelay(mbx->usec_delay);
151  }
152 
153  /* if we failed, all future posted messages fail until reset */
154  if (!countdown)
155  mbx->timeout = 0;
156 out:
157  return countdown ? 0 : -E1000_ERR_MBX;
158 }
159 
167 static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
168 {
169  struct e1000_mbx_info *mbx = &hw->mbx;
170  int countdown = mbx->timeout;
171 
172  if (!countdown || !mbx->ops.check_for_ack)
173  goto out;
174 
175  while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
176  countdown--;
177  if (!countdown)
178  break;
179  udelay(mbx->usec_delay);
180  }
181 
182  /* if we failed, all future posted messages fail until reset */
183  if (!countdown)
184  mbx->timeout = 0;
185 out:
186  return countdown ? 0 : -E1000_ERR_MBX;
187 }
188 
199 static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
200 {
201  struct e1000_mbx_info *mbx = &hw->mbx;
202  s32 ret_val = -E1000_ERR_MBX;
203 
204  if (!mbx->ops.read)
205  goto out;
206 
207  ret_val = igb_poll_for_msg(hw, mbx_id);
208 
209  if (!ret_val)
210  ret_val = mbx->ops.read(hw, msg, size, mbx_id);
211 out:
212  return ret_val;
213 }
214 
225 static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
226 {
227  struct e1000_mbx_info *mbx = &hw->mbx;
228  s32 ret_val = -E1000_ERR_MBX;
229 
230  /* exit if either we can't write or there isn't a defined timeout */
231  if (!mbx->ops.write || !mbx->timeout)
232  goto out;
233 
234  /* send msg */
235  ret_val = mbx->ops.write(hw, msg, size, mbx_id);
236 
237  /* if msg sent wait until we receive an ack */
238  if (!ret_val)
239  ret_val = igb_poll_for_ack(hw, mbx_id);
240 out:
241  return ret_val;
242 }
243 
244 static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
245 {
246  u32 mbvficr = rd32(E1000_MBVFICR);
247  s32 ret_val = -E1000_ERR_MBX;
248 
249  if (mbvficr & mask) {
250  ret_val = 0;
251  wr32(E1000_MBVFICR, mask);
252  }
253 
254  return ret_val;
255 }
256 
264 static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
265 {
266  s32 ret_val = -E1000_ERR_MBX;
267 
268  if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
269  ret_val = 0;
270  hw->mbx.stats.reqs++;
271  }
272 
273  return ret_val;
274 }
275 
283 static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
284 {
285  s32 ret_val = -E1000_ERR_MBX;
286 
287  if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
288  ret_val = 0;
289  hw->mbx.stats.acks++;
290  }
291 
292  return ret_val;
293 }
294 
302 static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
303 {
304  u32 vflre = rd32(E1000_VFLRE);
305  s32 ret_val = -E1000_ERR_MBX;
306 
307  if (vflre & (1 << vf_number)) {
308  ret_val = 0;
309  wr32(E1000_VFLRE, (1 << vf_number));
310  hw->mbx.stats.rsts++;
311  }
312 
313  return ret_val;
314 }
315 
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 */
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 
349 static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
350  u16 vf_number)
351 {
352  s32 ret_val;
353  u16 i;
354 
355  /* lock the mailbox to prevent pf/vf race condition */
356  ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
357  if (ret_val)
358  goto out_no_write;
359 
360  /* flush msg and acks as we are overwriting the message buffer */
361  igb_check_for_msg_pf(hw, vf_number);
362  igb_check_for_ack_pf(hw, vf_number);
363 
364  /* copy the caller specified message to the mailbox memory buffer */
365  for (i = 0; i < size; i++)
366  array_wr32(E1000_VMBMEM(vf_number), i, msg[i]);
367 
368  /* Interrupt VF to tell it a message has been sent and release buffer*/
370 
371  /* update stats */
372  hw->mbx.stats.msgs_tx++;
373 
374 out_no_write:
375  return ret_val;
376 
377 }
378 
390 static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
391  u16 vf_number)
392 {
393  s32 ret_val;
394  u16 i;
395 
396  /* lock the mailbox to prevent pf/vf race condition */
397  ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
398  if (ret_val)
399  goto out_no_read;
400 
401  /* copy the message to the mailbox memory buffer */
402  for (i = 0; i < size; i++)
403  msg[i] = array_rd32(E1000_VMBMEM(vf_number), i);
404 
405  /* Acknowledge the message and release buffer */
407 
408  /* update stats */
409  hw->mbx.stats.msgs_rx++;
410 
411 out_no_read:
412  return ret_val;
413 }
414 
422 {
423  struct e1000_mbx_info *mbx = &hw->mbx;
424 
425  mbx->timeout = 0;
426  mbx->usec_delay = 0;
427 
428  mbx->size = E1000_VFMAILBOX_SIZE;
429 
430  mbx->ops.read = igb_read_mbx_pf;
431  mbx->ops.write = igb_write_mbx_pf;
432  mbx->ops.read_posted = igb_read_posted_mbx;
433  mbx->ops.write_posted = igb_write_posted_mbx;
434  mbx->ops.check_for_msg = igb_check_for_msg_pf;
435  mbx->ops.check_for_ack = igb_check_for_ack_pf;
436  mbx->ops.check_for_rst = igb_check_for_rst_pf;
437 
438  mbx->stats.msgs_tx = 0;
439  mbx->stats.msgs_rx = 0;
440  mbx->stats.reqs = 0;
441  mbx->stats.acks = 0;
442  mbx->stats.rsts = 0;
443 
444  return 0;
445 }
446