1209616Sjfv/****************************************************************************** 2209616Sjfv 3294958Smarius Copyright (c) 2001-2015, Intel Corporation 4209616Sjfv All rights reserved. 5209616Sjfv 6209616Sjfv Redistribution and use in source and binary forms, with or without 7209616Sjfv modification, are permitted provided that the following conditions are met: 8209616Sjfv 9209616Sjfv 1. Redistributions of source code must retain the above copyright notice, 10209616Sjfv this list of conditions and the following disclaimer. 11209616Sjfv 12209616Sjfv 2. Redistributions in binary form must reproduce the above copyright 13209616Sjfv notice, this list of conditions and the following disclaimer in the 14209616Sjfv documentation and/or other materials provided with the distribution. 15209616Sjfv 16209616Sjfv 3. Neither the name of the Intel Corporation nor the names of its 17209616Sjfv contributors may be used to endorse or promote products derived from 18209616Sjfv this software without specific prior written permission. 19209616Sjfv 20209616Sjfv THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21209616Sjfv AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22209616Sjfv IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23209616Sjfv ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24209616Sjfv LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25209616Sjfv CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26209616Sjfv SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27209616Sjfv INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28209616Sjfv CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29209616Sjfv ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30209616Sjfv POSSIBILITY OF SUCH DAMAGE. 31209616Sjfv 32209616Sjfv******************************************************************************/ 33209616Sjfv/*$FreeBSD: releng/10.3/sys/dev/e1000/e1000_mbx.c 296055 2016-02-25 19:15:06Z erj $*/ 34209616Sjfv 35209616Sjfv#include "e1000_mbx.h" 36209616Sjfv 37209616Sjfv/** 38209616Sjfv * e1000_null_mbx_check_for_flag - No-op function, return 0 39209616Sjfv * @hw: pointer to the HW structure 40209616Sjfv **/ 41269196Sjfvstatic s32 e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG *hw, 42269196Sjfv u16 E1000_UNUSEDARG mbx_id) 43209616Sjfv{ 44209616Sjfv DEBUGFUNC("e1000_null_mbx_check_flag"); 45209616Sjfv 46209616Sjfv return E1000_SUCCESS; 47209616Sjfv} 48209616Sjfv 49209616Sjfv/** 50209616Sjfv * e1000_null_mbx_transact - No-op function, return 0 51209616Sjfv * @hw: pointer to the HW structure 52209616Sjfv **/ 53269196Sjfvstatic s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw, 54269196Sjfv u32 E1000_UNUSEDARG *msg, 55269196Sjfv u16 E1000_UNUSEDARG size, 56269196Sjfv u16 E1000_UNUSEDARG mbx_id) 57209616Sjfv{ 58209616Sjfv DEBUGFUNC("e1000_null_mbx_rw_msg"); 59209616Sjfv 60209616Sjfv return E1000_SUCCESS; 61209616Sjfv} 62209616Sjfv 63209616Sjfv/** 64209616Sjfv * e1000_read_mbx - Reads a message from the mailbox 65209616Sjfv * @hw: pointer to the HW structure 66209616Sjfv * @msg: The message buffer 67209616Sjfv * @size: Length of buffer 68209616Sjfv * @mbx_id: id of mailbox to read 69209616Sjfv * 70209616Sjfv * returns SUCCESS if it successfuly read message from buffer 71209616Sjfv **/ 72209616Sjfvs32 e1000_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) 73209616Sjfv{ 74209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 75209616Sjfv s32 ret_val = -E1000_ERR_MBX; 76209616Sjfv 77209616Sjfv DEBUGFUNC("e1000_read_mbx"); 78209616Sjfv 79209616Sjfv /* limit read to size of mailbox */ 80209616Sjfv if (size > mbx->size) 81209616Sjfv size = mbx->size; 82209616Sjfv 83209616Sjfv if (mbx->ops.read) 84209616Sjfv ret_val = mbx->ops.read(hw, msg, size, mbx_id); 85209616Sjfv 86209616Sjfv return ret_val; 87209616Sjfv} 88209616Sjfv 89209616Sjfv/** 90209616Sjfv * e1000_write_mbx - Write a message to the mailbox 91209616Sjfv * @hw: pointer to the HW structure 92209616Sjfv * @msg: The message buffer 93209616Sjfv * @size: Length of buffer 94209616Sjfv * @mbx_id: id of mailbox to write 95209616Sjfv * 96209616Sjfv * returns SUCCESS if it successfully copied message into the buffer 97209616Sjfv **/ 98209616Sjfvs32 e1000_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) 99209616Sjfv{ 100209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 101209616Sjfv s32 ret_val = E1000_SUCCESS; 102209616Sjfv 103209616Sjfv DEBUGFUNC("e1000_write_mbx"); 104209616Sjfv 105209616Sjfv if (size > mbx->size) 106209616Sjfv ret_val = -E1000_ERR_MBX; 107209616Sjfv 108209616Sjfv else if (mbx->ops.write) 109209616Sjfv ret_val = mbx->ops.write(hw, msg, size, mbx_id); 110209616Sjfv 111209616Sjfv return ret_val; 112209616Sjfv} 113209616Sjfv 114209616Sjfv/** 115209616Sjfv * e1000_check_for_msg - checks to see if someone sent us mail 116209616Sjfv * @hw: pointer to the HW structure 117209616Sjfv * @mbx_id: id of mailbox to check 118209616Sjfv * 119209616Sjfv * returns SUCCESS if the Status bit was found or else ERR_MBX 120209616Sjfv **/ 121209616Sjfvs32 e1000_check_for_msg(struct e1000_hw *hw, u16 mbx_id) 122209616Sjfv{ 123209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 124209616Sjfv s32 ret_val = -E1000_ERR_MBX; 125209616Sjfv 126209616Sjfv DEBUGFUNC("e1000_check_for_msg"); 127209616Sjfv 128209616Sjfv if (mbx->ops.check_for_msg) 129209616Sjfv ret_val = mbx->ops.check_for_msg(hw, mbx_id); 130209616Sjfv 131209616Sjfv return ret_val; 132209616Sjfv} 133209616Sjfv 134209616Sjfv/** 135209616Sjfv * e1000_check_for_ack - checks to see if someone sent us ACK 136209616Sjfv * @hw: pointer to the HW structure 137209616Sjfv * @mbx_id: id of mailbox to check 138209616Sjfv * 139209616Sjfv * returns SUCCESS if the Status bit was found or else ERR_MBX 140209616Sjfv **/ 141209616Sjfvs32 e1000_check_for_ack(struct e1000_hw *hw, u16 mbx_id) 142209616Sjfv{ 143209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 144209616Sjfv s32 ret_val = -E1000_ERR_MBX; 145209616Sjfv 146209616Sjfv DEBUGFUNC("e1000_check_for_ack"); 147209616Sjfv 148209616Sjfv if (mbx->ops.check_for_ack) 149209616Sjfv ret_val = mbx->ops.check_for_ack(hw, mbx_id); 150209616Sjfv 151209616Sjfv return ret_val; 152209616Sjfv} 153209616Sjfv 154209616Sjfv/** 155209616Sjfv * e1000_check_for_rst - checks to see if other side has reset 156209616Sjfv * @hw: pointer to the HW structure 157209616Sjfv * @mbx_id: id of mailbox to check 158209616Sjfv * 159209616Sjfv * returns SUCCESS if the Status bit was found or else ERR_MBX 160209616Sjfv **/ 161209616Sjfvs32 e1000_check_for_rst(struct e1000_hw *hw, u16 mbx_id) 162209616Sjfv{ 163209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 164209616Sjfv s32 ret_val = -E1000_ERR_MBX; 165209616Sjfv 166209616Sjfv DEBUGFUNC("e1000_check_for_rst"); 167209616Sjfv 168209616Sjfv if (mbx->ops.check_for_rst) 169209616Sjfv ret_val = mbx->ops.check_for_rst(hw, mbx_id); 170209616Sjfv 171209616Sjfv return ret_val; 172209616Sjfv} 173209616Sjfv 174209616Sjfv/** 175209616Sjfv * e1000_poll_for_msg - Wait for message notification 176209616Sjfv * @hw: pointer to the HW structure 177209616Sjfv * @mbx_id: id of mailbox to write 178209616Sjfv * 179209616Sjfv * returns SUCCESS if it successfully received a message notification 180209616Sjfv **/ 181209616Sjfvstatic s32 e1000_poll_for_msg(struct e1000_hw *hw, u16 mbx_id) 182209616Sjfv{ 183209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 184209616Sjfv int countdown = mbx->timeout; 185209616Sjfv 186209616Sjfv DEBUGFUNC("e1000_poll_for_msg"); 187209616Sjfv 188209616Sjfv if (!countdown || !mbx->ops.check_for_msg) 189209616Sjfv goto out; 190209616Sjfv 191209616Sjfv while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) { 192209616Sjfv countdown--; 193209616Sjfv if (!countdown) 194209616Sjfv break; 195209616Sjfv usec_delay(mbx->usec_delay); 196209616Sjfv } 197209616Sjfv 198209616Sjfv /* if we failed, all future posted messages fail until reset */ 199209616Sjfv if (!countdown) 200209616Sjfv mbx->timeout = 0; 201209616Sjfvout: 202209616Sjfv return countdown ? E1000_SUCCESS : -E1000_ERR_MBX; 203209616Sjfv} 204209616Sjfv 205209616Sjfv/** 206209616Sjfv * e1000_poll_for_ack - Wait for message acknowledgement 207209616Sjfv * @hw: pointer to the HW structure 208209616Sjfv * @mbx_id: id of mailbox to write 209209616Sjfv * 210209616Sjfv * returns SUCCESS if it successfully received a message acknowledgement 211209616Sjfv **/ 212209616Sjfvstatic s32 e1000_poll_for_ack(struct e1000_hw *hw, u16 mbx_id) 213209616Sjfv{ 214209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 215209616Sjfv int countdown = mbx->timeout; 216209616Sjfv 217209616Sjfv DEBUGFUNC("e1000_poll_for_ack"); 218209616Sjfv 219209616Sjfv if (!countdown || !mbx->ops.check_for_ack) 220209616Sjfv goto out; 221209616Sjfv 222209616Sjfv while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) { 223209616Sjfv countdown--; 224209616Sjfv if (!countdown) 225209616Sjfv break; 226209616Sjfv usec_delay(mbx->usec_delay); 227209616Sjfv } 228209616Sjfv 229209616Sjfv /* if we failed, all future posted messages fail until reset */ 230209616Sjfv if (!countdown) 231209616Sjfv mbx->timeout = 0; 232209616Sjfvout: 233209616Sjfv return countdown ? E1000_SUCCESS : -E1000_ERR_MBX; 234209616Sjfv} 235209616Sjfv 236209616Sjfv/** 237209616Sjfv * e1000_read_posted_mbx - Wait for message notification and receive message 238209616Sjfv * @hw: pointer to the HW structure 239209616Sjfv * @msg: The message buffer 240209616Sjfv * @size: Length of buffer 241209616Sjfv * @mbx_id: id of mailbox to write 242209616Sjfv * 243209616Sjfv * returns SUCCESS if it successfully received a message notification and 244209616Sjfv * copied it into the receive buffer. 245209616Sjfv **/ 246209616Sjfvs32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) 247209616Sjfv{ 248209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 249209616Sjfv s32 ret_val = -E1000_ERR_MBX; 250209616Sjfv 251209616Sjfv DEBUGFUNC("e1000_read_posted_mbx"); 252209616Sjfv 253209616Sjfv if (!mbx->ops.read) 254209616Sjfv goto out; 255209616Sjfv 256209616Sjfv ret_val = e1000_poll_for_msg(hw, mbx_id); 257209616Sjfv 258209616Sjfv /* if ack received read message, otherwise we timed out */ 259209616Sjfv if (!ret_val) 260209616Sjfv ret_val = mbx->ops.read(hw, msg, size, mbx_id); 261209616Sjfvout: 262209616Sjfv return ret_val; 263209616Sjfv} 264209616Sjfv 265209616Sjfv/** 266209616Sjfv * e1000_write_posted_mbx - Write a message to the mailbox, wait for ack 267209616Sjfv * @hw: pointer to the HW structure 268209616Sjfv * @msg: The message buffer 269209616Sjfv * @size: Length of buffer 270209616Sjfv * @mbx_id: id of mailbox to write 271209616Sjfv * 272209616Sjfv * returns SUCCESS if it successfully copied message into the buffer and 273209616Sjfv * received an ack to that message within delay * timeout period 274209616Sjfv **/ 275209616Sjfvs32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) 276209616Sjfv{ 277209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 278209616Sjfv s32 ret_val = -E1000_ERR_MBX; 279209616Sjfv 280209616Sjfv DEBUGFUNC("e1000_write_posted_mbx"); 281209616Sjfv 282209616Sjfv /* exit if either we can't write or there isn't a defined timeout */ 283209616Sjfv if (!mbx->ops.write || !mbx->timeout) 284209616Sjfv goto out; 285209616Sjfv 286209616Sjfv /* send msg */ 287209616Sjfv ret_val = mbx->ops.write(hw, msg, size, mbx_id); 288209616Sjfv 289209616Sjfv /* if msg sent wait until we receive an ack */ 290209616Sjfv if (!ret_val) 291209616Sjfv ret_val = e1000_poll_for_ack(hw, mbx_id); 292209616Sjfvout: 293209616Sjfv return ret_val; 294209616Sjfv} 295209616Sjfv 296209616Sjfv/** 297209616Sjfv * e1000_init_mbx_ops_generic - Initialize mbx function pointers 298209616Sjfv * @hw: pointer to the HW structure 299209616Sjfv * 300209616Sjfv * Sets the function pointers to no-op functions 301209616Sjfv **/ 302209616Sjfvvoid e1000_init_mbx_ops_generic(struct e1000_hw *hw) 303209616Sjfv{ 304209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 305209616Sjfv mbx->ops.init_params = e1000_null_ops_generic; 306209616Sjfv mbx->ops.read = e1000_null_mbx_transact; 307209616Sjfv mbx->ops.write = e1000_null_mbx_transact; 308209616Sjfv mbx->ops.check_for_msg = e1000_null_mbx_check_for_flag; 309209616Sjfv mbx->ops.check_for_ack = e1000_null_mbx_check_for_flag; 310209616Sjfv mbx->ops.check_for_rst = e1000_null_mbx_check_for_flag; 311209616Sjfv mbx->ops.read_posted = e1000_read_posted_mbx; 312209616Sjfv mbx->ops.write_posted = e1000_write_posted_mbx; 313209616Sjfv} 314209616Sjfv 315209616Sjfv/** 316209616Sjfv * e1000_read_v2p_mailbox - read v2p mailbox 317209616Sjfv * @hw: pointer to the HW structure 318209616Sjfv * 319209616Sjfv * This function is used to read the v2p mailbox without losing the read to 320209616Sjfv * clear status bits. 321209616Sjfv **/ 322209616Sjfvstatic u32 e1000_read_v2p_mailbox(struct e1000_hw *hw) 323209616Sjfv{ 324209616Sjfv u32 v2p_mailbox = E1000_READ_REG(hw, E1000_V2PMAILBOX(0)); 325209616Sjfv 326209616Sjfv v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox; 327209616Sjfv hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS; 328209616Sjfv 329209616Sjfv return v2p_mailbox; 330209616Sjfv} 331209616Sjfv 332209616Sjfv/** 333209616Sjfv * e1000_check_for_bit_vf - Determine if a status bit was set 334209616Sjfv * @hw: pointer to the HW structure 335209616Sjfv * @mask: bitmask for bits to be tested and cleared 336209616Sjfv * 337209616Sjfv * This function is used to check for the read to clear bits within 338209616Sjfv * the V2P mailbox. 339209616Sjfv **/ 340209616Sjfvstatic s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask) 341209616Sjfv{ 342209616Sjfv u32 v2p_mailbox = e1000_read_v2p_mailbox(hw); 343209616Sjfv s32 ret_val = -E1000_ERR_MBX; 344209616Sjfv 345209616Sjfv if (v2p_mailbox & mask) 346209616Sjfv ret_val = E1000_SUCCESS; 347209616Sjfv 348209616Sjfv hw->dev_spec.vf.v2p_mailbox &= ~mask; 349209616Sjfv 350209616Sjfv return ret_val; 351209616Sjfv} 352209616Sjfv 353209616Sjfv/** 354209616Sjfv * e1000_check_for_msg_vf - checks to see if the PF has sent mail 355209616Sjfv * @hw: pointer to the HW structure 356209616Sjfv * @mbx_id: id of mailbox to check 357209616Sjfv * 358209616Sjfv * returns SUCCESS if the PF has set the Status bit or else ERR_MBX 359209616Sjfv **/ 360269196Sjfvstatic s32 e1000_check_for_msg_vf(struct e1000_hw *hw, 361269196Sjfv u16 E1000_UNUSEDARG mbx_id) 362209616Sjfv{ 363209616Sjfv s32 ret_val = -E1000_ERR_MBX; 364209616Sjfv 365209616Sjfv DEBUGFUNC("e1000_check_for_msg_vf"); 366209616Sjfv 367209616Sjfv if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) { 368209616Sjfv ret_val = E1000_SUCCESS; 369209616Sjfv hw->mbx.stats.reqs++; 370209616Sjfv } 371209616Sjfv 372209616Sjfv return ret_val; 373209616Sjfv} 374209616Sjfv 375209616Sjfv/** 376209616Sjfv * e1000_check_for_ack_vf - checks to see if the PF has ACK'd 377209616Sjfv * @hw: pointer to the HW structure 378209616Sjfv * @mbx_id: id of mailbox to check 379209616Sjfv * 380209616Sjfv * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX 381209616Sjfv **/ 382269196Sjfvstatic s32 e1000_check_for_ack_vf(struct e1000_hw *hw, 383269196Sjfv u16 E1000_UNUSEDARG mbx_id) 384209616Sjfv{ 385209616Sjfv s32 ret_val = -E1000_ERR_MBX; 386209616Sjfv 387209616Sjfv DEBUGFUNC("e1000_check_for_ack_vf"); 388209616Sjfv 389209616Sjfv if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) { 390209616Sjfv ret_val = E1000_SUCCESS; 391209616Sjfv hw->mbx.stats.acks++; 392209616Sjfv } 393209616Sjfv 394209616Sjfv return ret_val; 395209616Sjfv} 396209616Sjfv 397209616Sjfv/** 398209616Sjfv * e1000_check_for_rst_vf - checks to see if the PF has reset 399209616Sjfv * @hw: pointer to the HW structure 400209616Sjfv * @mbx_id: id of mailbox to check 401209616Sjfv * 402209616Sjfv * returns TRUE if the PF has set the reset done bit or else FALSE 403209616Sjfv **/ 404269196Sjfvstatic s32 e1000_check_for_rst_vf(struct e1000_hw *hw, 405269196Sjfv u16 E1000_UNUSEDARG mbx_id) 406209616Sjfv{ 407209616Sjfv s32 ret_val = -E1000_ERR_MBX; 408209616Sjfv 409209616Sjfv DEBUGFUNC("e1000_check_for_rst_vf"); 410209616Sjfv 411209616Sjfv if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD | 412269196Sjfv E1000_V2PMAILBOX_RSTI))) { 413209616Sjfv ret_val = E1000_SUCCESS; 414209616Sjfv hw->mbx.stats.rsts++; 415209616Sjfv } 416209616Sjfv 417209616Sjfv return ret_val; 418209616Sjfv} 419209616Sjfv 420209616Sjfv/** 421209616Sjfv * e1000_obtain_mbx_lock_vf - obtain mailbox lock 422209616Sjfv * @hw: pointer to the HW structure 423209616Sjfv * 424209616Sjfv * return SUCCESS if we obtained the mailbox lock 425209616Sjfv **/ 426209616Sjfvstatic s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw) 427209616Sjfv{ 428209616Sjfv s32 ret_val = -E1000_ERR_MBX; 429296055Serj int count = 10; 430209616Sjfv 431209616Sjfv DEBUGFUNC("e1000_obtain_mbx_lock_vf"); 432209616Sjfv 433296055Serj do { 434296055Serj /* Take ownership of the buffer */ 435296055Serj E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU); 436209616Sjfv 437296055Serj /* reserve mailbox for vf use */ 438296055Serj if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) { 439296055Serj ret_val = E1000_SUCCESS; 440296055Serj break; 441296055Serj } 442296055Serj usec_delay(1000); 443296055Serj } while (count-- > 0); 444209616Sjfv 445209616Sjfv return ret_val; 446209616Sjfv} 447209616Sjfv 448209616Sjfv/** 449209616Sjfv * e1000_write_mbx_vf - Write a message to the mailbox 450209616Sjfv * @hw: pointer to the HW structure 451209616Sjfv * @msg: The message buffer 452209616Sjfv * @size: Length of buffer 453209616Sjfv * @mbx_id: id of mailbox to write 454209616Sjfv * 455209616Sjfv * returns SUCCESS if it successfully copied message into the buffer 456209616Sjfv **/ 457209616Sjfvstatic s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size, 458269196Sjfv u16 E1000_UNUSEDARG mbx_id) 459209616Sjfv{ 460209616Sjfv s32 ret_val; 461209616Sjfv u16 i; 462209616Sjfv 463209616Sjfv 464209616Sjfv DEBUGFUNC("e1000_write_mbx_vf"); 465209616Sjfv 466209616Sjfv /* lock the mailbox to prevent pf/vf race condition */ 467209616Sjfv ret_val = e1000_obtain_mbx_lock_vf(hw); 468209616Sjfv if (ret_val) 469209616Sjfv goto out_no_write; 470209616Sjfv 471209616Sjfv /* flush msg and acks as we are overwriting the message buffer */ 472209616Sjfv e1000_check_for_msg_vf(hw, 0); 473209616Sjfv e1000_check_for_ack_vf(hw, 0); 474209616Sjfv 475209616Sjfv /* copy the caller specified message to the mailbox memory buffer */ 476209616Sjfv for (i = 0; i < size; i++) 477209616Sjfv E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(0), i, msg[i]); 478209616Sjfv 479209616Sjfv /* update stats */ 480209616Sjfv hw->mbx.stats.msgs_tx++; 481209616Sjfv 482209616Sjfv /* Drop VFU and interrupt the PF to tell it a message has been sent */ 483209616Sjfv E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_REQ); 484209616Sjfv 485209616Sjfvout_no_write: 486209616Sjfv return ret_val; 487209616Sjfv} 488209616Sjfv 489209616Sjfv/** 490209616Sjfv * e1000_read_mbx_vf - Reads a message from the inbox intended for vf 491209616Sjfv * @hw: pointer to the HW structure 492209616Sjfv * @msg: The message buffer 493209616Sjfv * @size: Length of buffer 494209616Sjfv * @mbx_id: id of mailbox to read 495209616Sjfv * 496209616Sjfv * returns SUCCESS if it successfuly read message from buffer 497209616Sjfv **/ 498209616Sjfvstatic s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size, 499269196Sjfv u16 E1000_UNUSEDARG mbx_id) 500209616Sjfv{ 501209616Sjfv s32 ret_val = E1000_SUCCESS; 502209616Sjfv u16 i; 503209616Sjfv 504209616Sjfv DEBUGFUNC("e1000_read_mbx_vf"); 505209616Sjfv 506209616Sjfv /* lock the mailbox to prevent pf/vf race condition */ 507209616Sjfv ret_val = e1000_obtain_mbx_lock_vf(hw); 508209616Sjfv if (ret_val) 509209616Sjfv goto out_no_read; 510209616Sjfv 511209616Sjfv /* copy the message from the mailbox memory buffer */ 512209616Sjfv for (i = 0; i < size; i++) 513209616Sjfv msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(0), i); 514209616Sjfv 515209616Sjfv /* Acknowledge receipt and release mailbox, then we're done */ 516209616Sjfv E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_ACK); 517209616Sjfv 518209616Sjfv /* update stats */ 519209616Sjfv hw->mbx.stats.msgs_rx++; 520209616Sjfv 521209616Sjfvout_no_read: 522209616Sjfv return ret_val; 523209616Sjfv} 524209616Sjfv 525209616Sjfv/** 526209616Sjfv * e1000_init_mbx_params_vf - set initial values for vf mailbox 527209616Sjfv * @hw: pointer to the HW structure 528209616Sjfv * 529209616Sjfv * Initializes the hw->mbx struct to correct values for vf mailbox 530209616Sjfv */ 531209616Sjfvs32 e1000_init_mbx_params_vf(struct e1000_hw *hw) 532209616Sjfv{ 533209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 534209616Sjfv 535209616Sjfv /* start mailbox as timed out and let the reset_hw call set the timeout 536209616Sjfv * value to begin communications */ 537209616Sjfv mbx->timeout = 0; 538209616Sjfv mbx->usec_delay = E1000_VF_MBX_INIT_DELAY; 539209616Sjfv 540209616Sjfv mbx->size = E1000_VFMAILBOX_SIZE; 541209616Sjfv 542209616Sjfv mbx->ops.read = e1000_read_mbx_vf; 543209616Sjfv mbx->ops.write = e1000_write_mbx_vf; 544209616Sjfv mbx->ops.read_posted = e1000_read_posted_mbx; 545209616Sjfv mbx->ops.write_posted = e1000_write_posted_mbx; 546209616Sjfv mbx->ops.check_for_msg = e1000_check_for_msg_vf; 547209616Sjfv mbx->ops.check_for_ack = e1000_check_for_ack_vf; 548209616Sjfv mbx->ops.check_for_rst = e1000_check_for_rst_vf; 549209616Sjfv 550209616Sjfv mbx->stats.msgs_tx = 0; 551209616Sjfv mbx->stats.msgs_rx = 0; 552209616Sjfv mbx->stats.reqs = 0; 553209616Sjfv mbx->stats.acks = 0; 554209616Sjfv mbx->stats.rsts = 0; 555209616Sjfv 556209616Sjfv return E1000_SUCCESS; 557209616Sjfv} 558209616Sjfv 559209616Sjfvstatic s32 e1000_check_for_bit_pf(struct e1000_hw *hw, u32 mask) 560209616Sjfv{ 561209616Sjfv u32 mbvficr = E1000_READ_REG(hw, E1000_MBVFICR); 562209616Sjfv s32 ret_val = -E1000_ERR_MBX; 563209616Sjfv 564209616Sjfv if (mbvficr & mask) { 565209616Sjfv ret_val = E1000_SUCCESS; 566209616Sjfv E1000_WRITE_REG(hw, E1000_MBVFICR, mask); 567209616Sjfv } 568209616Sjfv 569209616Sjfv return ret_val; 570209616Sjfv} 571209616Sjfv 572209616Sjfv/** 573209616Sjfv * e1000_check_for_msg_pf - checks to see if the VF has sent mail 574209616Sjfv * @hw: pointer to the HW structure 575209616Sjfv * @vf_number: the VF index 576209616Sjfv * 577209616Sjfv * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 578209616Sjfv **/ 579209616Sjfvstatic s32 e1000_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number) 580209616Sjfv{ 581209616Sjfv s32 ret_val = -E1000_ERR_MBX; 582209616Sjfv 583209616Sjfv DEBUGFUNC("e1000_check_for_msg_pf"); 584209616Sjfv 585209616Sjfv if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) { 586209616Sjfv ret_val = E1000_SUCCESS; 587209616Sjfv hw->mbx.stats.reqs++; 588209616Sjfv } 589209616Sjfv 590209616Sjfv return ret_val; 591209616Sjfv} 592209616Sjfv 593209616Sjfv/** 594209616Sjfv * e1000_check_for_ack_pf - checks to see if the VF has ACKed 595209616Sjfv * @hw: pointer to the HW structure 596209616Sjfv * @vf_number: the VF index 597209616Sjfv * 598209616Sjfv * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 599209616Sjfv **/ 600209616Sjfvstatic s32 e1000_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number) 601209616Sjfv{ 602209616Sjfv s32 ret_val = -E1000_ERR_MBX; 603209616Sjfv 604209616Sjfv DEBUGFUNC("e1000_check_for_ack_pf"); 605209616Sjfv 606209616Sjfv if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) { 607209616Sjfv ret_val = E1000_SUCCESS; 608209616Sjfv hw->mbx.stats.acks++; 609209616Sjfv } 610209616Sjfv 611209616Sjfv return ret_val; 612209616Sjfv} 613209616Sjfv 614209616Sjfv/** 615209616Sjfv * e1000_check_for_rst_pf - checks to see if the VF has reset 616209616Sjfv * @hw: pointer to the HW structure 617209616Sjfv * @vf_number: the VF index 618209616Sjfv * 619209616Sjfv * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 620209616Sjfv **/ 621209616Sjfvstatic s32 e1000_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number) 622209616Sjfv{ 623209616Sjfv u32 vflre = E1000_READ_REG(hw, E1000_VFLRE); 624209616Sjfv s32 ret_val = -E1000_ERR_MBX; 625209616Sjfv 626209616Sjfv DEBUGFUNC("e1000_check_for_rst_pf"); 627209616Sjfv 628209616Sjfv if (vflre & (1 << vf_number)) { 629209616Sjfv ret_val = E1000_SUCCESS; 630209616Sjfv E1000_WRITE_REG(hw, E1000_VFLRE, (1 << vf_number)); 631209616Sjfv hw->mbx.stats.rsts++; 632209616Sjfv } 633209616Sjfv 634209616Sjfv return ret_val; 635209616Sjfv} 636209616Sjfv 637209616Sjfv/** 638209616Sjfv * e1000_obtain_mbx_lock_pf - obtain mailbox lock 639209616Sjfv * @hw: pointer to the HW structure 640209616Sjfv * @vf_number: the VF index 641209616Sjfv * 642209616Sjfv * return SUCCESS if we obtained the mailbox lock 643209616Sjfv **/ 644209616Sjfvstatic s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number) 645209616Sjfv{ 646209616Sjfv s32 ret_val = -E1000_ERR_MBX; 647209616Sjfv u32 p2v_mailbox; 648296055Serj int count = 10; 649209616Sjfv 650209616Sjfv DEBUGFUNC("e1000_obtain_mbx_lock_pf"); 651209616Sjfv 652296055Serj do { 653296055Serj /* Take ownership of the buffer */ 654296055Serj E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), 655296055Serj E1000_P2VMAILBOX_PFU); 656209616Sjfv 657296055Serj /* reserve mailbox for pf use */ 658296055Serj p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number)); 659296055Serj if (p2v_mailbox & E1000_P2VMAILBOX_PFU) { 660296055Serj ret_val = E1000_SUCCESS; 661296055Serj break; 662296055Serj } 663296055Serj usec_delay(1000); 664296055Serj } while (count-- > 0); 665209616Sjfv 666209616Sjfv return ret_val; 667296055Serj 668209616Sjfv} 669209616Sjfv 670209616Sjfv/** 671209616Sjfv * e1000_write_mbx_pf - Places a message in the mailbox 672209616Sjfv * @hw: pointer to the HW structure 673209616Sjfv * @msg: The message buffer 674209616Sjfv * @size: Length of buffer 675209616Sjfv * @vf_number: the VF index 676209616Sjfv * 677209616Sjfv * returns SUCCESS if it successfully copied message into the buffer 678209616Sjfv **/ 679209616Sjfvstatic s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, 680269196Sjfv u16 vf_number) 681209616Sjfv{ 682209616Sjfv s32 ret_val; 683209616Sjfv u16 i; 684209616Sjfv 685209616Sjfv DEBUGFUNC("e1000_write_mbx_pf"); 686209616Sjfv 687209616Sjfv /* lock the mailbox to prevent pf/vf race condition */ 688209616Sjfv ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number); 689209616Sjfv if (ret_val) 690209616Sjfv goto out_no_write; 691209616Sjfv 692209616Sjfv /* flush msg and acks as we are overwriting the message buffer */ 693209616Sjfv e1000_check_for_msg_pf(hw, vf_number); 694209616Sjfv e1000_check_for_ack_pf(hw, vf_number); 695209616Sjfv 696209616Sjfv /* copy the caller specified message to the mailbox memory buffer */ 697209616Sjfv for (i = 0; i < size; i++) 698209616Sjfv E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i, msg[i]); 699209616Sjfv 700209616Sjfv /* Interrupt VF to tell it a message has been sent and release buffer*/ 701209616Sjfv E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS); 702209616Sjfv 703209616Sjfv /* update stats */ 704209616Sjfv hw->mbx.stats.msgs_tx++; 705209616Sjfv 706209616Sjfvout_no_write: 707209616Sjfv return ret_val; 708209616Sjfv 709209616Sjfv} 710209616Sjfv 711209616Sjfv/** 712209616Sjfv * e1000_read_mbx_pf - Read a message from the mailbox 713209616Sjfv * @hw: pointer to the HW structure 714209616Sjfv * @msg: The message buffer 715209616Sjfv * @size: Length of buffer 716209616Sjfv * @vf_number: the VF index 717209616Sjfv * 718209616Sjfv * This function copies a message from the mailbox buffer to the caller's 719209616Sjfv * memory buffer. The presumption is that the caller knows that there was 720209616Sjfv * a message due to a VF request so no polling for message is needed. 721209616Sjfv **/ 722209616Sjfvstatic s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, 723269196Sjfv u16 vf_number) 724209616Sjfv{ 725209616Sjfv s32 ret_val; 726209616Sjfv u16 i; 727209616Sjfv 728209616Sjfv DEBUGFUNC("e1000_read_mbx_pf"); 729209616Sjfv 730209616Sjfv /* lock the mailbox to prevent pf/vf race condition */ 731209616Sjfv ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number); 732209616Sjfv if (ret_val) 733209616Sjfv goto out_no_read; 734209616Sjfv 735209616Sjfv /* copy the message to the mailbox memory buffer */ 736209616Sjfv for (i = 0; i < size; i++) 737209616Sjfv msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i); 738209616Sjfv 739209616Sjfv /* Acknowledge the message and release buffer */ 740209616Sjfv E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK); 741209616Sjfv 742209616Sjfv /* update stats */ 743209616Sjfv hw->mbx.stats.msgs_rx++; 744209616Sjfv 745209616Sjfvout_no_read: 746209616Sjfv return ret_val; 747209616Sjfv} 748209616Sjfv 749209616Sjfv/** 750209616Sjfv * e1000_init_mbx_params_pf - set initial values for pf mailbox 751209616Sjfv * @hw: pointer to the HW structure 752209616Sjfv * 753209616Sjfv * Initializes the hw->mbx struct to correct values for pf mailbox 754209616Sjfv */ 755209616Sjfvs32 e1000_init_mbx_params_pf(struct e1000_hw *hw) 756209616Sjfv{ 757209616Sjfv struct e1000_mbx_info *mbx = &hw->mbx; 758209616Sjfv 759218530Sjfv switch (hw->mac.type) { 760218530Sjfv case e1000_82576: 761218530Sjfv case e1000_i350: 762269196Sjfv case e1000_i354: 763209616Sjfv mbx->timeout = 0; 764209616Sjfv mbx->usec_delay = 0; 765209616Sjfv 766209616Sjfv mbx->size = E1000_VFMAILBOX_SIZE; 767209616Sjfv 768209616Sjfv mbx->ops.read = e1000_read_mbx_pf; 769209616Sjfv mbx->ops.write = e1000_write_mbx_pf; 770209616Sjfv mbx->ops.read_posted = e1000_read_posted_mbx; 771209616Sjfv mbx->ops.write_posted = e1000_write_posted_mbx; 772209616Sjfv mbx->ops.check_for_msg = e1000_check_for_msg_pf; 773209616Sjfv mbx->ops.check_for_ack = e1000_check_for_ack_pf; 774209616Sjfv mbx->ops.check_for_rst = e1000_check_for_rst_pf; 775209616Sjfv 776209616Sjfv mbx->stats.msgs_tx = 0; 777209616Sjfv mbx->stats.msgs_rx = 0; 778209616Sjfv mbx->stats.reqs = 0; 779209616Sjfv mbx->stats.acks = 0; 780209616Sjfv mbx->stats.rsts = 0; 781218530Sjfv default: 782218530Sjfv return E1000_SUCCESS; 783209616Sjfv } 784209616Sjfv} 785209616Sjfv 786