| 1 | /****************************************************************************** |
| 2 | |
| 3 | Copyright (c) 2001-2013, Intel Corporation |
| 4 | All rights reserved. |
| 5 | |
| 6 | Redistribution and use in source and binary forms, with or without |
| 7 | modification, are permitted provided that the following conditions are met: |
| 8 | |
| 9 | 1. Redistributions of source code must retain the above copyright notice, |
| 10 | this list of conditions and the following disclaimer. |
| 11 | |
| 12 | 2. Redistributions in binary form must reproduce the above copyright |
| 13 | notice, this list of conditions and the following disclaimer in the |
| 14 | documentation and/or other materials provided with the distribution. |
| 15 | |
| 16 | 3. Neither the name of the Intel Corporation nor the names of its |
| 17 | contributors may be used to endorse or promote products derived from |
| 18 | this software without specific prior written permission. |
| 19 | |
| 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 23 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| 24 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 26 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 28 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 29 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 30 | POSSIBILITY OF SUCH DAMAGE. |
| 31 | |
| 32 | ******************************************************************************/ |
| 33 | /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_vf.c 251964 2013-06-18 21:28:19Z jfv $*/ |
| 34 | /*$NetBSD: ixgbe_vf.c,v 1.6 2016/02/06 02:39:51 riastradh Exp $*/ |
| 35 | |
| 36 | |
| 37 | #include "ixgbe_api.h" |
| 38 | #include "ixgbe_type.h" |
| 39 | #include "ixgbe_vf.h" |
| 40 | |
| 41 | #ifndef IXGBE_VFWRITE_REG |
| 42 | #define IXGBE_VFWRITE_REG IXGBE_WRITE_REG |
| 43 | #endif |
| 44 | #ifndef IXGBE_VFREAD_REG |
| 45 | #define IXGBE_VFREAD_REG IXGBE_READ_REG |
| 46 | #endif |
| 47 | |
| 48 | /** |
| 49 | * ixgbe_init_ops_vf - Initialize the pointers for vf |
| 50 | * @hw: pointer to hardware structure |
| 51 | * |
| 52 | * This will assign function pointers, adapter-specific functions can |
| 53 | * override the assignment of generic function pointers by assigning |
| 54 | * their own adapter-specific function pointers. |
| 55 | * Does not touch the hardware. |
| 56 | **/ |
| 57 | s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw) |
| 58 | { |
| 59 | /* MAC */ |
| 60 | hw->mac.ops.init_hw = ixgbe_init_hw_vf; |
| 61 | hw->mac.ops.reset_hw = ixgbe_reset_hw_vf; |
| 62 | hw->mac.ops.start_hw = ixgbe_start_hw_vf; |
| 63 | /* Cannot clear stats on VF */ |
| 64 | hw->mac.ops.clear_hw_cntrs = NULL; |
| 65 | hw->mac.ops.get_media_type = NULL; |
| 66 | hw->mac.ops.get_mac_addr = ixgbe_get_mac_addr_vf; |
| 67 | hw->mac.ops.stop_adapter = ixgbe_stop_adapter_vf; |
| 68 | hw->mac.ops.get_bus_info = NULL; |
| 69 | |
| 70 | /* Link */ |
| 71 | hw->mac.ops.setup_link = ixgbe_setup_mac_link_vf; |
| 72 | hw->mac.ops.check_link = ixgbe_check_mac_link_vf; |
| 73 | hw->mac.ops.get_link_capabilities = NULL; |
| 74 | |
| 75 | /* RAR, Multicast, VLAN */ |
| 76 | hw->mac.ops.set_rar = ixgbe_set_rar_vf; |
| 77 | hw->mac.ops.set_uc_addr = ixgbevf_set_uc_addr_vf; |
| 78 | hw->mac.ops.init_rx_addrs = NULL; |
| 79 | hw->mac.ops.update_mc_addr_list = ixgbe_update_mc_addr_list_vf; |
| 80 | hw->mac.ops.enable_mc = NULL; |
| 81 | hw->mac.ops.disable_mc = NULL; |
| 82 | hw->mac.ops.clear_vfta = NULL; |
| 83 | hw->mac.ops.set_vfta = ixgbe_set_vfta_vf; |
| 84 | |
| 85 | hw->mac.max_tx_queues = 1; |
| 86 | hw->mac.max_rx_queues = 1; |
| 87 | |
| 88 | hw->mbx.ops.init_params = ixgbe_init_mbx_params_vf; |
| 89 | |
| 90 | return IXGBE_SUCCESS; |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * ixgbe_start_hw_vf - Prepare hardware for Tx/Rx |
| 95 | * @hw: pointer to hardware structure |
| 96 | * |
| 97 | * Starts the hardware by filling the bus info structure and media type, clears |
| 98 | * all on chip counters, initializes receive address registers, multicast |
| 99 | * table, VLAN filter table, calls routine to set up link and flow control |
| 100 | * settings, and leaves transmit and receive units disabled and uninitialized |
| 101 | **/ |
| 102 | s32 ixgbe_start_hw_vf(struct ixgbe_hw *hw) |
| 103 | { |
| 104 | /* Clear adapter stopped flag */ |
| 105 | hw->adapter_stopped = FALSE; |
| 106 | |
| 107 | return IXGBE_SUCCESS; |
| 108 | } |
| 109 | |
| 110 | /** |
| 111 | * ixgbe_init_hw_vf - virtual function hardware initialization |
| 112 | * @hw: pointer to hardware structure |
| 113 | * |
| 114 | * Initialize the hardware by resetting the hardware and then starting |
| 115 | * the hardware |
| 116 | **/ |
| 117 | s32 ixgbe_init_hw_vf(struct ixgbe_hw *hw) |
| 118 | { |
| 119 | s32 status = hw->mac.ops.start_hw(hw); |
| 120 | |
| 121 | hw->mac.ops.get_mac_addr(hw, hw->mac.addr); |
| 122 | |
| 123 | return status; |
| 124 | } |
| 125 | |
| 126 | /** |
| 127 | * ixgbe_reset_hw_vf - Performs hardware reset |
| 128 | * @hw: pointer to hardware structure |
| 129 | * |
| 130 | * Resets the hardware by reseting the transmit and receive units, masks and |
| 131 | * clears all interrupts. |
| 132 | **/ |
| 133 | s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw) |
| 134 | { |
| 135 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
| 136 | u32 timeout = IXGBE_VF_INIT_TIMEOUT; |
| 137 | s32 ret_val = IXGBE_ERR_INVALID_MAC_ADDR; |
| 138 | u32 ctrl, msgbuf[IXGBE_VF_PERMADDR_MSG_LEN]; |
| 139 | u8 *addr = (u8 *)(&msgbuf[1]); |
| 140 | |
| 141 | DEBUGFUNC("ixgbevf_reset_hw_vf" ); |
| 142 | |
| 143 | /* Call adapter stop to disable tx/rx and clear interrupts */ |
| 144 | hw->mac.ops.stop_adapter(hw); |
| 145 | |
| 146 | |
| 147 | DEBUGOUT("Issuing a function level reset to MAC\n" ); |
| 148 | |
| 149 | ctrl = IXGBE_VFREAD_REG(hw, IXGBE_VFCTRL) | IXGBE_CTRL_RST; |
| 150 | IXGBE_VFWRITE_REG(hw, IXGBE_VFCTRL, ctrl); |
| 151 | IXGBE_WRITE_FLUSH(hw); |
| 152 | |
| 153 | msec_delay(50); |
| 154 | |
| 155 | /* we cannot reset while the RSTI / RSTD bits are asserted */ |
| 156 | while (!mbx->ops.check_for_rst(hw, 0) && timeout) { |
| 157 | timeout--; |
| 158 | usec_delay(5); |
| 159 | } |
| 160 | |
| 161 | if (!timeout) |
| 162 | return IXGBE_ERR_RESET_FAILED; |
| 163 | |
| 164 | /* mailbox timeout can now become active */ |
| 165 | mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; |
| 166 | |
| 167 | msgbuf[0] = IXGBE_VF_RESET; |
| 168 | mbx->ops.write_posted(hw, msgbuf, 1, 0); |
| 169 | |
| 170 | msec_delay(10); |
| 171 | |
| 172 | /* |
| 173 | * set our "perm_addr" based on info provided by PF |
| 174 | * also set up the mc_filter_type which is piggy backed |
| 175 | * on the mac address in word 3 |
| 176 | */ |
| 177 | ret_val = mbx->ops.read_posted(hw, msgbuf, |
| 178 | IXGBE_VF_PERMADDR_MSG_LEN, 0); |
| 179 | if (ret_val) |
| 180 | return ret_val; |
| 181 | |
| 182 | if (msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK) && |
| 183 | msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_NACK)) |
| 184 | return IXGBE_ERR_INVALID_MAC_ADDR; |
| 185 | |
| 186 | memcpy(hw->mac.perm_addr, addr, IXGBE_ETH_LENGTH_OF_ADDRESS); |
| 187 | hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD]; |
| 188 | |
| 189 | return ret_val; |
| 190 | } |
| 191 | |
| 192 | /** |
| 193 | * ixgbe_stop_adapter_vf - Generic stop Tx/Rx units |
| 194 | * @hw: pointer to hardware structure |
| 195 | * |
| 196 | * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, |
| 197 | * disables transmit and receive units. The adapter_stopped flag is used by |
| 198 | * the shared code and drivers to determine if the adapter is in a stopped |
| 199 | * state and should not touch the hardware. |
| 200 | **/ |
| 201 | s32 ixgbe_stop_adapter_vf(struct ixgbe_hw *hw) |
| 202 | { |
| 203 | u32 reg_val; |
| 204 | u16 i; |
| 205 | |
| 206 | /* |
| 207 | * Set the adapter_stopped flag so other driver functions stop touching |
| 208 | * the hardware |
| 209 | */ |
| 210 | hw->adapter_stopped = TRUE; |
| 211 | |
| 212 | /* Clear interrupt mask to stop from interrupts being generated */ |
| 213 | IXGBE_VFWRITE_REG(hw, IXGBE_VTEIMC, IXGBE_VF_IRQ_CLEAR_MASK); |
| 214 | |
| 215 | /* Clear any pending interrupts, flush previous writes */ |
| 216 | IXGBE_VFREAD_REG(hw, IXGBE_VTEICR); |
| 217 | |
| 218 | /* Disable the transmit unit. Each queue must be disabled. */ |
| 219 | for (i = 0; i < hw->mac.max_tx_queues; i++) |
| 220 | IXGBE_VFWRITE_REG(hw, IXGBE_VFTXDCTL(i), IXGBE_TXDCTL_SWFLSH); |
| 221 | |
| 222 | /* Disable the receive unit by stopping each queue */ |
| 223 | for (i = 0; i < hw->mac.max_rx_queues; i++) { |
| 224 | reg_val = IXGBE_VFREAD_REG(hw, IXGBE_VFRXDCTL(i)); |
| 225 | reg_val &= ~IXGBE_RXDCTL_ENABLE; |
| 226 | IXGBE_VFWRITE_REG(hw, IXGBE_VFRXDCTL(i), reg_val); |
| 227 | } |
| 228 | |
| 229 | /* flush all queues disables */ |
| 230 | IXGBE_WRITE_FLUSH(hw); |
| 231 | msec_delay(2); |
| 232 | |
| 233 | return IXGBE_SUCCESS; |
| 234 | } |
| 235 | |
| 236 | /** |
| 237 | * ixgbe_mta_vector - Determines bit-vector in multicast table to set |
| 238 | * @hw: pointer to hardware structure |
| 239 | * @mc_addr: the multicast address |
| 240 | * |
| 241 | * Extracts the 12 bits, from a multicast address, to determine which |
| 242 | * bit-vector to set in the multicast table. The hardware uses 12 bits, from |
| 243 | * incoming rx multicast addresses, to determine the bit-vector to check in |
| 244 | * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set |
| 245 | * by the MO field of the MCSTCTRL. The MO field is set during initialization |
| 246 | * to mc_filter_type. |
| 247 | **/ |
| 248 | static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) |
| 249 | { |
| 250 | u32 vector = 0; |
| 251 | |
| 252 | switch (hw->mac.mc_filter_type) { |
| 253 | case 0: /* use bits [47:36] of the address */ |
| 254 | vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); |
| 255 | break; |
| 256 | case 1: /* use bits [46:35] of the address */ |
| 257 | vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); |
| 258 | break; |
| 259 | case 2: /* use bits [45:34] of the address */ |
| 260 | vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); |
| 261 | break; |
| 262 | case 3: /* use bits [43:32] of the address */ |
| 263 | vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); |
| 264 | break; |
| 265 | default: /* Invalid mc_filter_type */ |
| 266 | DEBUGOUT("MC filter type param set incorrectly\n" ); |
| 267 | ASSERT(0); |
| 268 | break; |
| 269 | } |
| 270 | |
| 271 | /* vector can only be 12-bits or boundary will be exceeded */ |
| 272 | vector &= 0xFFF; |
| 273 | return vector; |
| 274 | } |
| 275 | |
| 276 | static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, |
| 277 | u32 *msg, u16 size) |
| 278 | { |
| 279 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
| 280 | u32 retmsg[IXGBE_VFMAILBOX_SIZE]; |
| 281 | s32 retval = mbx->ops.write_posted(hw, msg, size, 0); |
| 282 | |
| 283 | if (!retval) |
| 284 | mbx->ops.read_posted(hw, retmsg, size, 0); |
| 285 | } |
| 286 | |
| 287 | /** |
| 288 | * ixgbe_set_rar_vf - set device MAC address |
| 289 | * @hw: pointer to hardware structure |
| 290 | * @index: Receive address register to write |
| 291 | * @addr: Address to put into receive address register |
| 292 | * @vmdq: VMDq "set" or "pool" index |
| 293 | * @enable_addr: set flag that address is active |
| 294 | **/ |
| 295 | s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, |
| 296 | u32 enable_addr) |
| 297 | { |
| 298 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
| 299 | u32 msgbuf[3]; |
| 300 | u8 *msg_addr = (u8 *)(&msgbuf[1]); |
| 301 | s32 ret_val; |
| 302 | UNREFERENCED_3PARAMETER(vmdq, enable_addr, index); |
| 303 | |
| 304 | memset(msgbuf, 0, 12); |
| 305 | msgbuf[0] = IXGBE_VF_SET_MAC_ADDR; |
| 306 | memcpy(msg_addr, addr, 6); |
| 307 | ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0); |
| 308 | |
| 309 | if (!ret_val) |
| 310 | ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0); |
| 311 | |
| 312 | msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; |
| 313 | |
| 314 | /* if nacked the address was rejected, use "perm_addr" */ |
| 315 | if (!ret_val && |
| 316 | (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_NACK))) |
| 317 | ixgbe_get_mac_addr_vf(hw, hw->mac.addr); |
| 318 | |
| 319 | return ret_val; |
| 320 | } |
| 321 | |
| 322 | /** |
| 323 | * ixgbe_update_mc_addr_list_vf - Update Multicast addresses |
| 324 | * @hw: pointer to the HW structure |
| 325 | * @mc_addr_list: array of multicast addresses to program |
| 326 | * @mc_addr_count: number of multicast addresses to program |
| 327 | * @next: caller supplied function to return next address in list |
| 328 | * |
| 329 | * Updates the Multicast Table Array. |
| 330 | **/ |
| 331 | s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list, |
| 332 | u32 mc_addr_count, ixgbe_mc_addr_itr next, |
| 333 | bool clear) |
| 334 | { |
| 335 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
| 336 | u32 msgbuf[IXGBE_VFMAILBOX_SIZE]; |
| 337 | u16 *vector_list = (u16 *)&msgbuf[1]; |
| 338 | u32 vector; |
| 339 | u32 cnt, i; |
| 340 | u32 vmdq; |
| 341 | |
| 342 | UNREFERENCED_1PARAMETER(clear); |
| 343 | |
| 344 | DEBUGFUNC("ixgbe_update_mc_addr_list_vf" ); |
| 345 | |
| 346 | /* Each entry in the list uses 1 16 bit word. We have 30 |
| 347 | * 16 bit words available in our HW msg buffer (minus 1 for the |
| 348 | * msg type). That's 30 hash values if we pack 'em right. If |
| 349 | * there are more than 30 MC addresses to add then punt the |
| 350 | * extras for now and then add code to handle more than 30 later. |
| 351 | * It would be unusual for a server to request that many multi-cast |
| 352 | * addresses except for in large enterprise network environments. |
| 353 | */ |
| 354 | |
| 355 | DEBUGOUT1("MC Addr Count = %d\n" , mc_addr_count); |
| 356 | |
| 357 | cnt = (mc_addr_count > 30) ? 30 : mc_addr_count; |
| 358 | msgbuf[0] = IXGBE_VF_SET_MULTICAST; |
| 359 | msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT; |
| 360 | |
| 361 | for (i = 0; i < cnt; i++) { |
| 362 | vector = ixgbe_mta_vector(hw, next(hw, &mc_addr_list, &vmdq)); |
| 363 | DEBUGOUT1("Hash value = 0x%03X\n" , vector); |
| 364 | vector_list[i] = (u16)vector; |
| 365 | } |
| 366 | |
| 367 | return mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE, 0); |
| 368 | } |
| 369 | |
| 370 | /** |
| 371 | * ixgbe_set_vfta_vf - Set/Unset vlan filter table address |
| 372 | * @hw: pointer to the HW structure |
| 373 | * @vlan: 12 bit VLAN ID |
| 374 | * @vind: unused by VF drivers |
| 375 | * @vlan_on: if TRUE then set bit, else clear bit |
| 376 | **/ |
| 377 | s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on) |
| 378 | { |
| 379 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
| 380 | u32 msgbuf[2]; |
| 381 | s32 ret_val; |
| 382 | UNREFERENCED_1PARAMETER(vind); |
| 383 | |
| 384 | msgbuf[0] = IXGBE_VF_SET_VLAN; |
| 385 | msgbuf[1] = vlan; |
| 386 | /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */ |
| 387 | msgbuf[0] |= (u32)vlan_on << IXGBE_VT_MSGINFO_SHIFT; |
| 388 | |
| 389 | ret_val = mbx->ops.write_posted(hw, msgbuf, 2, 0); |
| 390 | if (!ret_val) |
| 391 | ret_val = mbx->ops.read_posted(hw, msgbuf, 1, 0); |
| 392 | |
| 393 | if (!ret_val && (msgbuf[0] & IXGBE_VT_MSGTYPE_ACK)) |
| 394 | return IXGBE_SUCCESS; |
| 395 | |
| 396 | return ret_val | (msgbuf[0] & IXGBE_VT_MSGTYPE_NACK); |
| 397 | } |
| 398 | |
| 399 | /** |
| 400 | * ixgbe_get_num_of_tx_queues_vf - Get number of TX queues |
| 401 | * @hw: pointer to hardware structure |
| 402 | * |
| 403 | * Returns the number of transmit queues for the given adapter. |
| 404 | **/ |
| 405 | u32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw) |
| 406 | { |
| 407 | UNREFERENCED_1PARAMETER(hw); |
| 408 | return IXGBE_VF_MAX_TX_QUEUES; |
| 409 | } |
| 410 | |
| 411 | /** |
| 412 | * ixgbe_get_num_of_rx_queues_vf - Get number of RX queues |
| 413 | * @hw: pointer to hardware structure |
| 414 | * |
| 415 | * Returns the number of receive queues for the given adapter. |
| 416 | **/ |
| 417 | u32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw) |
| 418 | { |
| 419 | UNREFERENCED_1PARAMETER(hw); |
| 420 | return IXGBE_VF_MAX_RX_QUEUES; |
| 421 | } |
| 422 | |
| 423 | /** |
| 424 | * ixgbe_get_mac_addr_vf - Read device MAC address |
| 425 | * @hw: pointer to the HW structure |
| 426 | **/ |
| 427 | s32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) |
| 428 | { |
| 429 | int i; |
| 430 | |
| 431 | for (i = 0; i < IXGBE_ETH_LENGTH_OF_ADDRESS; i++) |
| 432 | mac_addr[i] = hw->mac.perm_addr[i]; |
| 433 | |
| 434 | return IXGBE_SUCCESS; |
| 435 | } |
| 436 | |
| 437 | s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) |
| 438 | { |
| 439 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
| 440 | u32 msgbuf[3]; |
| 441 | u8 *msg_addr = (u8 *)(&msgbuf[1]); |
| 442 | s32 ret_val; |
| 443 | |
| 444 | memset(msgbuf, 0, sizeof(msgbuf)); |
| 445 | /* |
| 446 | * If index is one then this is the start of a new list and needs |
| 447 | * indication to the PF so it can do it's own list management. |
| 448 | * If it is zero then that tells the PF to just clear all of |
| 449 | * this VF's macvlans and there is no new list. |
| 450 | */ |
| 451 | msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT; |
| 452 | msgbuf[0] |= IXGBE_VF_SET_MACVLAN; |
| 453 | if (addr) |
| 454 | memcpy(msg_addr, addr, 6); |
| 455 | ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0); |
| 456 | |
| 457 | if (!ret_val) |
| 458 | ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0); |
| 459 | |
| 460 | msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; |
| 461 | |
| 462 | if (!ret_val) |
| 463 | if (msgbuf[0] == (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK)) |
| 464 | ret_val = IXGBE_ERR_OUT_OF_MEM; |
| 465 | |
| 466 | return ret_val; |
| 467 | } |
| 468 | |
| 469 | /** |
| 470 | * ixgbe_setup_mac_link_vf - Setup MAC link settings |
| 471 | * @hw: pointer to hardware structure |
| 472 | * @speed: new link speed |
| 473 | * @autoneg: TRUE if autonegotiation enabled |
| 474 | * @autoneg_wait_to_complete: TRUE when waiting for completion is needed |
| 475 | * |
| 476 | * Set the link speed in the AUTOC register and restarts link. |
| 477 | **/ |
| 478 | s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed, |
| 479 | bool autoneg_wait_to_complete) |
| 480 | { |
| 481 | UNREFERENCED_3PARAMETER(hw, speed, autoneg_wait_to_complete); |
| 482 | return IXGBE_SUCCESS; |
| 483 | } |
| 484 | |
| 485 | /** |
| 486 | * ixgbe_check_mac_link_vf - Get link/speed status |
| 487 | * @hw: pointer to hardware structure |
| 488 | * @speed: pointer to link speed |
| 489 | * @link_up: TRUE is link is up, FALSE otherwise |
| 490 | * @autoneg_wait_to_complete: TRUE when waiting for completion is needed |
| 491 | * |
| 492 | * Reads the links register to determine if link is up and the current speed |
| 493 | **/ |
| 494 | s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, |
| 495 | bool *link_up, bool autoneg_wait_to_complete) |
| 496 | { |
| 497 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
| 498 | struct ixgbe_mac_info *mac = &hw->mac; |
| 499 | s32 ret_val = IXGBE_SUCCESS; |
| 500 | u32 links_reg; |
| 501 | u32 in_msg = 0; |
| 502 | UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); |
| 503 | |
| 504 | /* If we were hit with a reset drop the link */ |
| 505 | if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout) |
| 506 | mac->get_link_status = TRUE; |
| 507 | |
| 508 | if (!mac->get_link_status) |
| 509 | goto out; |
| 510 | |
| 511 | /* if link status is down no point in checking to see if pf is up */ |
| 512 | links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS); |
| 513 | if (!(links_reg & IXGBE_LINKS_UP)) |
| 514 | goto out; |
| 515 | |
| 516 | switch (links_reg & IXGBE_LINKS_SPEED_82599) { |
| 517 | case IXGBE_LINKS_SPEED_10G_82599: |
| 518 | *speed = IXGBE_LINK_SPEED_10GB_FULL; |
| 519 | break; |
| 520 | case IXGBE_LINKS_SPEED_1G_82599: |
| 521 | *speed = IXGBE_LINK_SPEED_1GB_FULL; |
| 522 | break; |
| 523 | case IXGBE_LINKS_SPEED_100_82599: |
| 524 | *speed = IXGBE_LINK_SPEED_100_FULL; |
| 525 | break; |
| 526 | } |
| 527 | |
| 528 | /* if the read failed it could just be a mailbox collision, best wait |
| 529 | * until we are called again and don't report an error |
| 530 | */ |
| 531 | if (mbx->ops.read(hw, &in_msg, 1, 0)) |
| 532 | goto out; |
| 533 | |
| 534 | if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) { |
| 535 | /* msg is not CTS and is NACK we must have lost CTS status */ |
| 536 | if (in_msg & IXGBE_VT_MSGTYPE_NACK) |
| 537 | ret_val = -1; |
| 538 | goto out; |
| 539 | } |
| 540 | |
| 541 | /* the pf is talking, if we timed out in the past we reinit */ |
| 542 | if (!mbx->timeout) { |
| 543 | ret_val = -1; |
| 544 | goto out; |
| 545 | } |
| 546 | |
| 547 | /* if we passed all the tests above then the link is up and we no |
| 548 | * longer need to check for link |
| 549 | */ |
| 550 | mac->get_link_status = FALSE; |
| 551 | |
| 552 | out: |
| 553 | *link_up = !mac->get_link_status; |
| 554 | return ret_val; |
| 555 | } |
| 556 | |
| 557 | /** |
| 558 | * ixgbevf_rlpml_set_vf - Set the maximum receive packet length |
| 559 | * @hw: pointer to the HW structure |
| 560 | * @max_size: value to assign to max frame size |
| 561 | **/ |
| 562 | void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size) |
| 563 | { |
| 564 | u32 msgbuf[2]; |
| 565 | |
| 566 | msgbuf[0] = IXGBE_VF_SET_LPE; |
| 567 | msgbuf[1] = max_size; |
| 568 | ixgbevf_write_msg_read_ack(hw, msgbuf, 2); |
| 569 | } |
| 570 | |
| 571 | /** |
| 572 | * ixgbevf_negotiate_api_version - Negotiate supported API version |
| 573 | * @hw: pointer to the HW structure |
| 574 | * @api: integer containing requested API version |
| 575 | **/ |
| 576 | int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api) |
| 577 | { |
| 578 | int err; |
| 579 | u32 msg[3]; |
| 580 | |
| 581 | /* Negotiate the mailbox API version */ |
| 582 | msg[0] = IXGBE_VF_API_NEGOTIATE; |
| 583 | msg[1] = api; |
| 584 | msg[2] = 0; |
| 585 | err = hw->mbx.ops.write_posted(hw, msg, 3, 0); |
| 586 | |
| 587 | if (!err) |
| 588 | err = hw->mbx.ops.read_posted(hw, msg, 3, 0); |
| 589 | |
| 590 | if (!err) { |
| 591 | msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; |
| 592 | |
| 593 | /* Store value and return 0 on success */ |
| 594 | if (msg[0] == (IXGBE_VF_API_NEGOTIATE | IXGBE_VT_MSGTYPE_ACK)) { |
| 595 | hw->api_version = api; |
| 596 | return 0; |
| 597 | } |
| 598 | |
| 599 | err = IXGBE_ERR_INVALID_ARGUMENT; |
| 600 | } |
| 601 | |
| 602 | return err; |
| 603 | } |
| 604 | |
| 605 | int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, |
| 606 | unsigned int *default_tc) |
| 607 | { |
| 608 | UNREFERENCED_3PARAMETER(hw, num_tcs, default_tc); |
| 609 | return IXGBE_SUCCESS; |
| 610 | } |
| 611 | |
| 612 | |