Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.31-rc7 434 lines 11 kB view raw
1/******************************************************************************* 2 3 Intel(R) Gigabit Ethernet Linux driver 4 Copyright(c) 2007-2009 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 <e1000-devel@lists.sourceforge.net> 24 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 25 26*******************************************************************************/ 27 28#include "e1000_mbx.h" 29 30/** 31 * igb_read_mbx - Reads a message from the mailbox 32 * @hw: pointer to the HW structure 33 * @msg: The message buffer 34 * @size: Length of buffer 35 * @mbx_id: id of mailbox to read 36 * 37 * returns SUCCESS if it successfuly read message from buffer 38 **/ 39s32 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 54/** 55 * igb_write_mbx - Write a message to the mailbox 56 * @hw: pointer to the HW structure 57 * @msg: The message buffer 58 * @size: Length of buffer 59 * @mbx_id: id of mailbox to write 60 * 61 * returns SUCCESS if it successfully copied message into the buffer 62 **/ 63s32 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 77/** 78 * igb_check_for_msg - checks to see if someone sent us mail 79 * @hw: pointer to the HW structure 80 * @mbx_id: id of mailbox to check 81 * 82 * returns SUCCESS if the Status bit was found or else ERR_MBX 83 **/ 84s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id) 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 95/** 96 * igb_check_for_ack - checks to see if someone sent us ACK 97 * @hw: pointer to the HW structure 98 * @mbx_id: id of mailbox to check 99 * 100 * returns SUCCESS if the Status bit was found or else ERR_MBX 101 **/ 102s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id) 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 113/** 114 * igb_check_for_rst - checks to see if other side has reset 115 * @hw: pointer to the HW structure 116 * @mbx_id: id of mailbox to check 117 * 118 * returns SUCCESS if the Status bit was found or else ERR_MBX 119 **/ 120s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id) 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 131/** 132 * igb_poll_for_msg - Wait for message notification 133 * @hw: pointer to the HW structure 134 * @mbx_id: id of mailbox to write 135 * 136 * returns SUCCESS if it successfully received a message notification 137 **/ 138static 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 (mbx->ops.check_for_msg(hw, mbx_id)) { 147 countdown--; 148 if (!countdown) 149 break; 150 udelay(mbx->usec_delay); 151 } 152out: 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 **/ 163static 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 (mbx->ops.check_for_ack(hw, mbx_id)) { 172 countdown--; 173 if (!countdown) 174 break; 175 udelay(mbx->usec_delay); 176 } 177out: 178 return countdown ? 0 : -E1000_ERR_MBX; 179} 180 181/** 182 * igb_read_posted_mbx - Wait for message notification and receive message 183 * @hw: pointer to the HW structure 184 * @msg: The message buffer 185 * @size: Length of buffer 186 * @mbx_id: id of mailbox to write 187 * 188 * returns SUCCESS if it successfully received a message notification and 189 * copied it into the receive buffer. 190 **/ 191static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) 192{ 193 struct e1000_mbx_info *mbx = &hw->mbx; 194 s32 ret_val = -E1000_ERR_MBX; 195 196 if (!mbx->ops.read) 197 goto out; 198 199 ret_val = igb_poll_for_msg(hw, mbx_id); 200 201 if (!ret_val) 202 ret_val = mbx->ops.read(hw, msg, size, mbx_id); 203out: 204 return ret_val; 205} 206 207/** 208 * igb_write_posted_mbx - Write a message to the mailbox, wait for ack 209 * @hw: pointer to the HW structure 210 * @msg: The message buffer 211 * @size: Length of buffer 212 * @mbx_id: id of mailbox to write 213 * 214 * returns SUCCESS if it successfully copied message into the buffer and 215 * received an ack to that message within delay * timeout period 216 **/ 217static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) 218{ 219 struct e1000_mbx_info *mbx = &hw->mbx; 220 s32 ret_val = 0; 221 222 if (!mbx->ops.write) 223 goto out; 224 225 /* send msg*/ 226 ret_val = mbx->ops.write(hw, msg, size, mbx_id); 227 228 /* if msg sent wait until we receive an ack */ 229 if (!ret_val) 230 ret_val = igb_poll_for_ack(hw, mbx_id); 231out: 232 return ret_val; 233} 234 235static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask) 236{ 237 u32 mbvficr = rd32(E1000_MBVFICR); 238 s32 ret_val = -E1000_ERR_MBX; 239 240 if (mbvficr & mask) { 241 ret_val = 0; 242 wr32(E1000_MBVFICR, mask); 243 } 244 245 return ret_val; 246} 247 248/** 249 * igb_check_for_msg_pf - checks to see if the VF has sent mail 250 * @hw: pointer to the HW structure 251 * @vf_number: the VF index 252 * 253 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 254 **/ 255static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number) 256{ 257 s32 ret_val = -E1000_ERR_MBX; 258 259 if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) { 260 ret_val = 0; 261 hw->mbx.stats.reqs++; 262 } 263 264 return ret_val; 265} 266 267/** 268 * igb_check_for_ack_pf - checks to see if the VF has ACKed 269 * @hw: pointer to the HW structure 270 * @vf_number: the VF index 271 * 272 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 273 **/ 274static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number) 275{ 276 s32 ret_val = -E1000_ERR_MBX; 277 278 if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) { 279 ret_val = 0; 280 hw->mbx.stats.acks++; 281 } 282 283 return ret_val; 284} 285 286/** 287 * igb_check_for_rst_pf - checks to see if the VF has reset 288 * @hw: pointer to the HW structure 289 * @vf_number: the VF index 290 * 291 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 292 **/ 293static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number) 294{ 295 u32 vflre = rd32(E1000_VFLRE); 296 s32 ret_val = -E1000_ERR_MBX; 297 298 if (vflre & (1 << vf_number)) { 299 ret_val = 0; 300 wr32(E1000_VFLRE, (1 << vf_number)); 301 hw->mbx.stats.rsts++; 302 } 303 304 return ret_val; 305} 306 307/** 308 * igb_write_mbx_pf - Places a message in the mailbox 309 * @hw: pointer to the HW structure 310 * @msg: The message buffer 311 * @size: Length of buffer 312 * @vf_number: the VF index 313 * 314 * returns SUCCESS if it successfully copied message into the buffer 315 **/ 316static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, 317 u16 vf_number) 318{ 319 u32 p2v_mailbox; 320 s32 ret_val = 0; 321 u16 i; 322 323 /* Take ownership of the buffer */ 324 wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU); 325 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; 332 } 333 334 /* 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); 340 341 /* copy the caller specified message to the mailbox memory buffer */ 342 for (i = 0; i < size; i++) 343 array_wr32(E1000_VMBMEM(vf_number), i, msg[i]); 344 345 /* Interrupt VF to tell it a message has been sent and release buffer*/ 346 wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS); 347 348 /* update stats */ 349 hw->mbx.stats.msgs_tx++; 350 351out_no_write: 352 return ret_val; 353 354} 355 356/** 357 * igb_read_mbx_pf - Read a message from the mailbox 358 * @hw: pointer to the HW structure 359 * @msg: The message buffer 360 * @size: Length of buffer 361 * @vf_number: the VF index 362 * 363 * This function copies a message from the mailbox buffer to the caller's 364 * memory buffer. The presumption is that the caller knows that there was 365 * a message due to a VF request so no polling for message is needed. 366 **/ 367static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, 368 u16 vf_number) 369{ 370 u32 p2v_mailbox; 371 s32 ret_val = 0; 372 u16 i; 373 374 /* Take ownership of the buffer */ 375 wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU); 376 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; 383 } 384 385 /* copy the message to the mailbox memory buffer */ 386 for (i = 0; i < size; i++) 387 msg[i] = array_rd32(E1000_VMBMEM(vf_number), i); 388 389 /* Acknowledge the message and release buffer */ 390 wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK); 391 392 /* update stats */ 393 hw->mbx.stats.msgs_rx++; 394 395 ret_val = 0; 396 397out_no_read: 398 return ret_val; 399} 400 401/** 402 * e1000_init_mbx_params_pf - set initial values for pf mailbox 403 * @hw: pointer to the HW structure 404 * 405 * Initializes the hw->mbx struct to correct values for pf mailbox 406 */ 407s32 igb_init_mbx_params_pf(struct e1000_hw *hw) 408{ 409 struct e1000_mbx_info *mbx = &hw->mbx; 410 411 if (hw->mac.type == e1000_82576) { 412 mbx->timeout = 0; 413 mbx->usec_delay = 0; 414 415 mbx->size = E1000_VFMAILBOX_SIZE; 416 417 mbx->ops.read = igb_read_mbx_pf; 418 mbx->ops.write = igb_write_mbx_pf; 419 mbx->ops.read_posted = igb_read_posted_mbx; 420 mbx->ops.write_posted = igb_write_posted_mbx; 421 mbx->ops.check_for_msg = igb_check_for_msg_pf; 422 mbx->ops.check_for_ack = igb_check_for_ack_pf; 423 mbx->ops.check_for_rst = igb_check_for_rst_pf; 424 425 mbx->stats.msgs_tx = 0; 426 mbx->stats.msgs_rx = 0; 427 mbx->stats.reqs = 0; 428 mbx->stats.acks = 0; 429 mbx->stats.rsts = 0; 430 } 431 432 return 0; 433} 434