1215911Sjfv/****************************************************************************** 2215911Sjfv 3247822Sjfv Copyright (c) 2001-2013, Intel Corporation 4215911Sjfv All rights reserved. 5215911Sjfv 6215911Sjfv Redistribution and use in source and binary forms, with or without 7215911Sjfv modification, are permitted provided that the following conditions are met: 8215911Sjfv 9215911Sjfv 1. Redistributions of source code must retain the above copyright notice, 10215911Sjfv this list of conditions and the following disclaimer. 11215911Sjfv 12215911Sjfv 2. Redistributions in binary form must reproduce the above copyright 13215911Sjfv notice, this list of conditions and the following disclaimer in the 14215911Sjfv documentation and/or other materials provided with the distribution. 15215911Sjfv 16215911Sjfv 3. Neither the name of the Intel Corporation nor the names of its 17215911Sjfv contributors may be used to endorse or promote products derived from 18215911Sjfv this software without specific prior written permission. 19215911Sjfv 20215911Sjfv THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21215911Sjfv AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22215911Sjfv IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23215911Sjfv ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24215911Sjfv LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25215911Sjfv CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26215911Sjfv SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27215911Sjfv INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28215911Sjfv CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29215911Sjfv ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30215911Sjfv POSSIBILITY OF SUCH DAMAGE. 31215911Sjfv 32215911Sjfv******************************************************************************/ 33215911Sjfv/*$FreeBSD$*/ 34215911Sjfv 35215911Sjfv 36215911Sjfv#include "ixgbe_api.h" 37215911Sjfv#include "ixgbe_type.h" 38215911Sjfv#include "ixgbe_vf.h" 39215911Sjfv 40215911Sjfv#ifndef IXGBE_VFWRITE_REG 41215911Sjfv#define IXGBE_VFWRITE_REG IXGBE_WRITE_REG 42215911Sjfv#endif 43215911Sjfv#ifndef IXGBE_VFREAD_REG 44215911Sjfv#define IXGBE_VFREAD_REG IXGBE_READ_REG 45215911Sjfv#endif 46215911Sjfv 47215911Sjfv/** 48215911Sjfv * ixgbe_init_ops_vf - Initialize the pointers for vf 49215911Sjfv * @hw: pointer to hardware structure 50215911Sjfv * 51215911Sjfv * This will assign function pointers, adapter-specific functions can 52215911Sjfv * override the assignment of generic function pointers by assigning 53215911Sjfv * their own adapter-specific function pointers. 54215911Sjfv * Does not touch the hardware. 55215911Sjfv **/ 56215911Sjfvs32 ixgbe_init_ops_vf(struct ixgbe_hw *hw) 57215911Sjfv{ 58215911Sjfv /* MAC */ 59215911Sjfv hw->mac.ops.init_hw = ixgbe_init_hw_vf; 60215911Sjfv hw->mac.ops.reset_hw = ixgbe_reset_hw_vf; 61215911Sjfv hw->mac.ops.start_hw = ixgbe_start_hw_vf; 62215911Sjfv /* Cannot clear stats on VF */ 63215911Sjfv hw->mac.ops.clear_hw_cntrs = NULL; 64215911Sjfv hw->mac.ops.get_media_type = NULL; 65215911Sjfv hw->mac.ops.get_mac_addr = ixgbe_get_mac_addr_vf; 66230775Sjfv hw->mac.ops.stop_adapter = ixgbe_stop_adapter_vf; 67215911Sjfv hw->mac.ops.get_bus_info = NULL; 68215911Sjfv 69215911Sjfv /* Link */ 70215911Sjfv hw->mac.ops.setup_link = ixgbe_setup_mac_link_vf; 71215911Sjfv hw->mac.ops.check_link = ixgbe_check_mac_link_vf; 72215911Sjfv hw->mac.ops.get_link_capabilities = NULL; 73215911Sjfv 74215911Sjfv /* RAR, Multicast, VLAN */ 75215911Sjfv hw->mac.ops.set_rar = ixgbe_set_rar_vf; 76230775Sjfv hw->mac.ops.set_uc_addr = ixgbevf_set_uc_addr_vf; 77215911Sjfv hw->mac.ops.init_rx_addrs = NULL; 78215911Sjfv hw->mac.ops.update_mc_addr_list = ixgbe_update_mc_addr_list_vf; 79215911Sjfv hw->mac.ops.enable_mc = NULL; 80215911Sjfv hw->mac.ops.disable_mc = NULL; 81215911Sjfv hw->mac.ops.clear_vfta = NULL; 82215911Sjfv hw->mac.ops.set_vfta = ixgbe_set_vfta_vf; 83215911Sjfv 84215911Sjfv hw->mac.max_tx_queues = 1; 85215911Sjfv hw->mac.max_rx_queues = 1; 86215911Sjfv 87215911Sjfv hw->mbx.ops.init_params = ixgbe_init_mbx_params_vf; 88215911Sjfv 89215911Sjfv return IXGBE_SUCCESS; 90215911Sjfv} 91215911Sjfv 92215911Sjfv/** 93215911Sjfv * ixgbe_start_hw_vf - Prepare hardware for Tx/Rx 94215911Sjfv * @hw: pointer to hardware structure 95215911Sjfv * 96215911Sjfv * Starts the hardware by filling the bus info structure and media type, clears 97215911Sjfv * all on chip counters, initializes receive address registers, multicast 98215911Sjfv * table, VLAN filter table, calls routine to set up link and flow control 99215911Sjfv * settings, and leaves transmit and receive units disabled and uninitialized 100215911Sjfv **/ 101215911Sjfvs32 ixgbe_start_hw_vf(struct ixgbe_hw *hw) 102215911Sjfv{ 103215911Sjfv /* Clear adapter stopped flag */ 104215911Sjfv hw->adapter_stopped = FALSE; 105215911Sjfv 106215911Sjfv return IXGBE_SUCCESS; 107215911Sjfv} 108215911Sjfv 109215911Sjfv/** 110215911Sjfv * ixgbe_init_hw_vf - virtual function hardware initialization 111215911Sjfv * @hw: pointer to hardware structure 112215911Sjfv * 113215911Sjfv * Initialize the hardware by resetting the hardware and then starting 114215911Sjfv * the hardware 115215911Sjfv **/ 116215911Sjfvs32 ixgbe_init_hw_vf(struct ixgbe_hw *hw) 117215911Sjfv{ 118215911Sjfv s32 status = hw->mac.ops.start_hw(hw); 119215911Sjfv 120215911Sjfv hw->mac.ops.get_mac_addr(hw, hw->mac.addr); 121215911Sjfv 122215911Sjfv return status; 123215911Sjfv} 124215911Sjfv 125215911Sjfv/** 126215911Sjfv * ixgbe_reset_hw_vf - Performs hardware reset 127215911Sjfv * @hw: pointer to hardware structure 128215911Sjfv * 129215911Sjfv * Resets the hardware by reseting the transmit and receive units, masks and 130215911Sjfv * clears all interrupts. 131215911Sjfv **/ 132215911Sjfvs32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw) 133215911Sjfv{ 134215911Sjfv struct ixgbe_mbx_info *mbx = &hw->mbx; 135215911Sjfv u32 timeout = IXGBE_VF_INIT_TIMEOUT; 136215911Sjfv s32 ret_val = IXGBE_ERR_INVALID_MAC_ADDR; 137215911Sjfv u32 ctrl, msgbuf[IXGBE_VF_PERMADDR_MSG_LEN]; 138215911Sjfv u8 *addr = (u8 *)(&msgbuf[1]); 139215911Sjfv 140215911Sjfv DEBUGFUNC("ixgbevf_reset_hw_vf"); 141215911Sjfv 142215911Sjfv /* Call adapter stop to disable tx/rx and clear interrupts */ 143215911Sjfv hw->mac.ops.stop_adapter(hw); 144215911Sjfv 145247822Sjfv 146215911Sjfv DEBUGOUT("Issuing a function level reset to MAC\n"); 147215911Sjfv 148230775Sjfv ctrl = IXGBE_VFREAD_REG(hw, IXGBE_VFCTRL) | IXGBE_CTRL_RST; 149230775Sjfv IXGBE_VFWRITE_REG(hw, IXGBE_VFCTRL, ctrl); 150230775Sjfv IXGBE_WRITE_FLUSH(hw); 151215911Sjfv 152230775Sjfv msec_delay(50); 153230775Sjfv 154215911Sjfv /* we cannot reset while the RSTI / RSTD bits are asserted */ 155215911Sjfv while (!mbx->ops.check_for_rst(hw, 0) && timeout) { 156215911Sjfv timeout--; 157215911Sjfv usec_delay(5); 158215911Sjfv } 159215911Sjfv 160251964Sjfv if (!timeout) 161251964Sjfv return IXGBE_ERR_RESET_FAILED; 162215911Sjfv 163251964Sjfv /* mailbox timeout can now become active */ 164251964Sjfv mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; 165215911Sjfv 166251964Sjfv msgbuf[0] = IXGBE_VF_RESET; 167251964Sjfv mbx->ops.write_posted(hw, msgbuf, 1, 0); 168215911Sjfv 169251964Sjfv msec_delay(10); 170215911Sjfv 171251964Sjfv /* 172251964Sjfv * set our "perm_addr" based on info provided by PF 173251964Sjfv * also set up the mc_filter_type which is piggy backed 174251964Sjfv * on the mac address in word 3 175251964Sjfv */ 176251964Sjfv ret_val = mbx->ops.read_posted(hw, msgbuf, 177251964Sjfv IXGBE_VF_PERMADDR_MSG_LEN, 0); 178251964Sjfv if (ret_val) 179251964Sjfv return ret_val; 180251964Sjfv 181251964Sjfv if (msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK) && 182251964Sjfv msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_NACK)) 183251964Sjfv return IXGBE_ERR_INVALID_MAC_ADDR; 184251964Sjfv 185251964Sjfv memcpy(hw->mac.perm_addr, addr, IXGBE_ETH_LENGTH_OF_ADDRESS); 186251964Sjfv hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD]; 187251964Sjfv 188215911Sjfv return ret_val; 189215911Sjfv} 190215911Sjfv 191215911Sjfv/** 192230775Sjfv * ixgbe_stop_adapter_vf - Generic stop Tx/Rx units 193215911Sjfv * @hw: pointer to hardware structure 194215911Sjfv * 195215911Sjfv * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, 196215911Sjfv * disables transmit and receive units. The adapter_stopped flag is used by 197215911Sjfv * the shared code and drivers to determine if the adapter is in a stopped 198215911Sjfv * state and should not touch the hardware. 199215911Sjfv **/ 200230775Sjfvs32 ixgbe_stop_adapter_vf(struct ixgbe_hw *hw) 201215911Sjfv{ 202215911Sjfv u32 reg_val; 203215911Sjfv u16 i; 204215911Sjfv 205215911Sjfv /* 206215911Sjfv * Set the adapter_stopped flag so other driver functions stop touching 207215911Sjfv * the hardware 208215911Sjfv */ 209215911Sjfv hw->adapter_stopped = TRUE; 210215911Sjfv 211215911Sjfv /* Clear interrupt mask to stop from interrupts being generated */ 212215911Sjfv IXGBE_VFWRITE_REG(hw, IXGBE_VTEIMC, IXGBE_VF_IRQ_CLEAR_MASK); 213215911Sjfv 214230775Sjfv /* Clear any pending interrupts, flush previous writes */ 215215911Sjfv IXGBE_VFREAD_REG(hw, IXGBE_VTEICR); 216215911Sjfv 217215911Sjfv /* Disable the transmit unit. Each queue must be disabled. */ 218230775Sjfv for (i = 0; i < hw->mac.max_tx_queues; i++) 219230775Sjfv IXGBE_VFWRITE_REG(hw, IXGBE_VFTXDCTL(i), IXGBE_TXDCTL_SWFLSH); 220230775Sjfv 221230775Sjfv /* Disable the receive unit by stopping each queue */ 222230775Sjfv for (i = 0; i < hw->mac.max_rx_queues; i++) { 223230775Sjfv reg_val = IXGBE_VFREAD_REG(hw, IXGBE_VFRXDCTL(i)); 224230775Sjfv reg_val &= ~IXGBE_RXDCTL_ENABLE; 225230775Sjfv IXGBE_VFWRITE_REG(hw, IXGBE_VFRXDCTL(i), reg_val); 226215911Sjfv } 227215911Sjfv 228230775Sjfv /* flush all queues disables */ 229230775Sjfv IXGBE_WRITE_FLUSH(hw); 230230775Sjfv msec_delay(2); 231230775Sjfv 232215911Sjfv return IXGBE_SUCCESS; 233215911Sjfv} 234215911Sjfv 235215911Sjfv/** 236215911Sjfv * ixgbe_mta_vector - Determines bit-vector in multicast table to set 237215911Sjfv * @hw: pointer to hardware structure 238215911Sjfv * @mc_addr: the multicast address 239215911Sjfv * 240215911Sjfv * Extracts the 12 bits, from a multicast address, to determine which 241215911Sjfv * bit-vector to set in the multicast table. The hardware uses 12 bits, from 242215911Sjfv * incoming rx multicast addresses, to determine the bit-vector to check in 243215911Sjfv * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set 244215911Sjfv * by the MO field of the MCSTCTRL. The MO field is set during initialization 245215911Sjfv * to mc_filter_type. 246215911Sjfv **/ 247215911Sjfvstatic s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) 248215911Sjfv{ 249215911Sjfv u32 vector = 0; 250215911Sjfv 251215911Sjfv switch (hw->mac.mc_filter_type) { 252215911Sjfv case 0: /* use bits [47:36] of the address */ 253215911Sjfv vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); 254215911Sjfv break; 255215911Sjfv case 1: /* use bits [46:35] of the address */ 256215911Sjfv vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); 257215911Sjfv break; 258215911Sjfv case 2: /* use bits [45:34] of the address */ 259215911Sjfv vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); 260215911Sjfv break; 261215911Sjfv case 3: /* use bits [43:32] of the address */ 262215911Sjfv vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); 263215911Sjfv break; 264215911Sjfv default: /* Invalid mc_filter_type */ 265215911Sjfv DEBUGOUT("MC filter type param set incorrectly\n"); 266215911Sjfv ASSERT(0); 267215911Sjfv break; 268215911Sjfv } 269215911Sjfv 270215911Sjfv /* vector can only be 12-bits or boundary will be exceeded */ 271215911Sjfv vector &= 0xFFF; 272215911Sjfv return vector; 273215911Sjfv} 274215911Sjfv 275247822Sjfvstatic void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, 276247822Sjfv u32 *msg, u16 size) 277247822Sjfv{ 278247822Sjfv struct ixgbe_mbx_info *mbx = &hw->mbx; 279247822Sjfv u32 retmsg[IXGBE_VFMAILBOX_SIZE]; 280247822Sjfv s32 retval = mbx->ops.write_posted(hw, msg, size, 0); 281247822Sjfv 282247822Sjfv if (!retval) 283247822Sjfv mbx->ops.read_posted(hw, retmsg, size, 0); 284247822Sjfv} 285247822Sjfv 286215911Sjfv/** 287215911Sjfv * ixgbe_set_rar_vf - set device MAC address 288215911Sjfv * @hw: pointer to hardware structure 289215911Sjfv * @index: Receive address register to write 290215911Sjfv * @addr: Address to put into receive address register 291215911Sjfv * @vmdq: VMDq "set" or "pool" index 292215911Sjfv * @enable_addr: set flag that address is active 293215911Sjfv **/ 294215911Sjfvs32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, 295230775Sjfv u32 enable_addr) 296215911Sjfv{ 297215911Sjfv struct ixgbe_mbx_info *mbx = &hw->mbx; 298215911Sjfv u32 msgbuf[3]; 299215911Sjfv u8 *msg_addr = (u8 *)(&msgbuf[1]); 300215911Sjfv s32 ret_val; 301230775Sjfv UNREFERENCED_3PARAMETER(vmdq, enable_addr, index); 302215911Sjfv 303215911Sjfv memset(msgbuf, 0, 12); 304215911Sjfv msgbuf[0] = IXGBE_VF_SET_MAC_ADDR; 305215911Sjfv memcpy(msg_addr, addr, 6); 306215911Sjfv ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0); 307215911Sjfv 308215911Sjfv if (!ret_val) 309215911Sjfv ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0); 310215911Sjfv 311215911Sjfv msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; 312215911Sjfv 313215911Sjfv /* if nacked the address was rejected, use "perm_addr" */ 314215911Sjfv if (!ret_val && 315215911Sjfv (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_NACK))) 316215911Sjfv ixgbe_get_mac_addr_vf(hw, hw->mac.addr); 317215911Sjfv 318215911Sjfv return ret_val; 319215911Sjfv} 320215911Sjfv 321215911Sjfv/** 322215911Sjfv * ixgbe_update_mc_addr_list_vf - Update Multicast addresses 323215911Sjfv * @hw: pointer to the HW structure 324215911Sjfv * @mc_addr_list: array of multicast addresses to program 325215911Sjfv * @mc_addr_count: number of multicast addresses to program 326215911Sjfv * @next: caller supplied function to return next address in list 327215911Sjfv * 328215911Sjfv * Updates the Multicast Table Array. 329215911Sjfv **/ 330215911Sjfvs32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list, 331230775Sjfv u32 mc_addr_count, ixgbe_mc_addr_itr next, 332230775Sjfv bool clear) 333215911Sjfv{ 334215911Sjfv struct ixgbe_mbx_info *mbx = &hw->mbx; 335215911Sjfv u32 msgbuf[IXGBE_VFMAILBOX_SIZE]; 336215911Sjfv u16 *vector_list = (u16 *)&msgbuf[1]; 337215911Sjfv u32 vector; 338215911Sjfv u32 cnt, i; 339215911Sjfv u32 vmdq; 340215911Sjfv 341230775Sjfv UNREFERENCED_1PARAMETER(clear); 342230775Sjfv 343215911Sjfv DEBUGFUNC("ixgbe_update_mc_addr_list_vf"); 344215911Sjfv 345215911Sjfv /* Each entry in the list uses 1 16 bit word. We have 30 346215911Sjfv * 16 bit words available in our HW msg buffer (minus 1 for the 347215911Sjfv * msg type). That's 30 hash values if we pack 'em right. If 348215911Sjfv * there are more than 30 MC addresses to add then punt the 349215911Sjfv * extras for now and then add code to handle more than 30 later. 350215911Sjfv * It would be unusual for a server to request that many multi-cast 351215911Sjfv * addresses except for in large enterprise network environments. 352215911Sjfv */ 353215911Sjfv 354215911Sjfv DEBUGOUT1("MC Addr Count = %d\n", mc_addr_count); 355215911Sjfv 356215911Sjfv cnt = (mc_addr_count > 30) ? 30 : mc_addr_count; 357215911Sjfv msgbuf[0] = IXGBE_VF_SET_MULTICAST; 358215911Sjfv msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT; 359215911Sjfv 360215911Sjfv for (i = 0; i < cnt; i++) { 361215911Sjfv vector = ixgbe_mta_vector(hw, next(hw, &mc_addr_list, &vmdq)); 362215911Sjfv DEBUGOUT1("Hash value = 0x%03X\n", vector); 363215911Sjfv vector_list[i] = (u16)vector; 364215911Sjfv } 365215911Sjfv 366215911Sjfv return mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE, 0); 367215911Sjfv} 368215911Sjfv 369215911Sjfv/** 370215911Sjfv * ixgbe_set_vfta_vf - Set/Unset vlan filter table address 371215911Sjfv * @hw: pointer to the HW structure 372215911Sjfv * @vlan: 12 bit VLAN ID 373215911Sjfv * @vind: unused by VF drivers 374215911Sjfv * @vlan_on: if TRUE then set bit, else clear bit 375215911Sjfv **/ 376215911Sjfvs32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on) 377215911Sjfv{ 378215911Sjfv struct ixgbe_mbx_info *mbx = &hw->mbx; 379215911Sjfv u32 msgbuf[2]; 380238149Sjfv s32 ret_val; 381230775Sjfv UNREFERENCED_1PARAMETER(vind); 382215911Sjfv 383215911Sjfv msgbuf[0] = IXGBE_VF_SET_VLAN; 384215911Sjfv msgbuf[1] = vlan; 385215911Sjfv /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */ 386215911Sjfv msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT; 387215911Sjfv 388238149Sjfv ret_val = mbx->ops.write_posted(hw, msgbuf, 2, 0); 389238149Sjfv if (!ret_val) 390238149Sjfv ret_val = mbx->ops.read_posted(hw, msgbuf, 1, 0); 391238149Sjfv 392238149Sjfv if (!ret_val && (msgbuf[0] & IXGBE_VT_MSGTYPE_ACK)) 393238149Sjfv return IXGBE_SUCCESS; 394238149Sjfv 395238149Sjfv return ret_val | (msgbuf[0] & IXGBE_VT_MSGTYPE_NACK); 396215911Sjfv} 397215911Sjfv 398215911Sjfv/** 399215911Sjfv * ixgbe_get_num_of_tx_queues_vf - Get number of TX queues 400215911Sjfv * @hw: pointer to hardware structure 401215911Sjfv * 402215911Sjfv * Returns the number of transmit queues for the given adapter. 403215911Sjfv **/ 404215911Sjfvu32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw) 405215911Sjfv{ 406230775Sjfv UNREFERENCED_1PARAMETER(hw); 407215911Sjfv return IXGBE_VF_MAX_TX_QUEUES; 408215911Sjfv} 409215911Sjfv 410215911Sjfv/** 411215911Sjfv * ixgbe_get_num_of_rx_queues_vf - Get number of RX queues 412215911Sjfv * @hw: pointer to hardware structure 413215911Sjfv * 414215911Sjfv * Returns the number of receive queues for the given adapter. 415215911Sjfv **/ 416215911Sjfvu32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw) 417215911Sjfv{ 418230775Sjfv UNREFERENCED_1PARAMETER(hw); 419215911Sjfv return IXGBE_VF_MAX_RX_QUEUES; 420215911Sjfv} 421215911Sjfv 422215911Sjfv/** 423215911Sjfv * ixgbe_get_mac_addr_vf - Read device MAC address 424215911Sjfv * @hw: pointer to the HW structure 425215911Sjfv **/ 426215911Sjfvs32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) 427215911Sjfv{ 428215911Sjfv int i; 429215911Sjfv 430215911Sjfv for (i = 0; i < IXGBE_ETH_LENGTH_OF_ADDRESS; i++) 431215911Sjfv mac_addr[i] = hw->mac.perm_addr[i]; 432215911Sjfv 433215911Sjfv return IXGBE_SUCCESS; 434215911Sjfv} 435215911Sjfv 436230775Sjfvs32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) 437230775Sjfv{ 438230775Sjfv struct ixgbe_mbx_info *mbx = &hw->mbx; 439230775Sjfv u32 msgbuf[3]; 440230775Sjfv u8 *msg_addr = (u8 *)(&msgbuf[1]); 441230775Sjfv s32 ret_val; 442230775Sjfv 443230775Sjfv memset(msgbuf, 0, sizeof(msgbuf)); 444230775Sjfv /* 445230775Sjfv * If index is one then this is the start of a new list and needs 446230775Sjfv * indication to the PF so it can do it's own list management. 447230775Sjfv * If it is zero then that tells the PF to just clear all of 448230775Sjfv * this VF's macvlans and there is no new list. 449230775Sjfv */ 450230775Sjfv msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT; 451230775Sjfv msgbuf[0] |= IXGBE_VF_SET_MACVLAN; 452230775Sjfv if (addr) 453230775Sjfv memcpy(msg_addr, addr, 6); 454230775Sjfv ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0); 455230775Sjfv 456230775Sjfv if (!ret_val) 457230775Sjfv ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0); 458230775Sjfv 459230775Sjfv msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; 460230775Sjfv 461230775Sjfv if (!ret_val) 462230775Sjfv if (msgbuf[0] == (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK)) 463230775Sjfv ret_val = IXGBE_ERR_OUT_OF_MEM; 464230775Sjfv 465230775Sjfv return ret_val; 466230775Sjfv} 467230775Sjfv 468215911Sjfv/** 469215911Sjfv * ixgbe_setup_mac_link_vf - Setup MAC link settings 470215911Sjfv * @hw: pointer to hardware structure 471215911Sjfv * @speed: new link speed 472215911Sjfv * @autoneg: TRUE if autonegotiation enabled 473215911Sjfv * @autoneg_wait_to_complete: TRUE when waiting for completion is needed 474215911Sjfv * 475215911Sjfv * Set the link speed in the AUTOC register and restarts link. 476215911Sjfv **/ 477247822Sjfvs32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed, 478230775Sjfv bool autoneg_wait_to_complete) 479215911Sjfv{ 480247822Sjfv UNREFERENCED_3PARAMETER(hw, speed, autoneg_wait_to_complete); 481215911Sjfv return IXGBE_SUCCESS; 482215911Sjfv} 483215911Sjfv 484215911Sjfv/** 485215911Sjfv * ixgbe_check_mac_link_vf - Get link/speed status 486215911Sjfv * @hw: pointer to hardware structure 487215911Sjfv * @speed: pointer to link speed 488215911Sjfv * @link_up: TRUE is link is up, FALSE otherwise 489215911Sjfv * @autoneg_wait_to_complete: TRUE when waiting for completion is needed 490215911Sjfv * 491215911Sjfv * Reads the links register to determine if link is up and the current speed 492215911Sjfv **/ 493215911Sjfvs32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, 494230775Sjfv bool *link_up, bool autoneg_wait_to_complete) 495215911Sjfv{ 496247822Sjfv struct ixgbe_mbx_info *mbx = &hw->mbx; 497247822Sjfv struct ixgbe_mac_info *mac = &hw->mac; 498247822Sjfv s32 ret_val = IXGBE_SUCCESS; 499215911Sjfv u32 links_reg; 500247822Sjfv u32 in_msg = 0; 501230775Sjfv UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); 502215911Sjfv 503247822Sjfv /* If we were hit with a reset drop the link */ 504247822Sjfv if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout) 505247822Sjfv mac->get_link_status = TRUE; 506215911Sjfv 507247822Sjfv if (!mac->get_link_status) 508247822Sjfv goto out; 509215911Sjfv 510247822Sjfv /* if link status is down no point in checking to see if pf is up */ 511247822Sjfv links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS); 512247822Sjfv if (!(links_reg & IXGBE_LINKS_UP)) 513247822Sjfv goto out; 514215911Sjfv 515247822Sjfv switch (links_reg & IXGBE_LINKS_SPEED_82599) { 516238149Sjfv case IXGBE_LINKS_SPEED_10G_82599: 517215911Sjfv *speed = IXGBE_LINK_SPEED_10GB_FULL; 518238149Sjfv break; 519238149Sjfv case IXGBE_LINKS_SPEED_1G_82599: 520215911Sjfv *speed = IXGBE_LINK_SPEED_1GB_FULL; 521238149Sjfv break; 522238149Sjfv case IXGBE_LINKS_SPEED_100_82599: 523238149Sjfv *speed = IXGBE_LINK_SPEED_100_FULL; 524238149Sjfv break; 525238149Sjfv } 526215911Sjfv 527247822Sjfv /* if the read failed it could just be a mailbox collision, best wait 528247822Sjfv * until we are called again and don't report an error 529247822Sjfv */ 530247822Sjfv if (mbx->ops.read(hw, &in_msg, 1, 0)) 531247822Sjfv goto out; 532247822Sjfv 533247822Sjfv if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) { 534247822Sjfv /* msg is not CTS and is NACK we must have lost CTS status */ 535247822Sjfv if (in_msg & IXGBE_VT_MSGTYPE_NACK) 536247822Sjfv ret_val = -1; 537247822Sjfv goto out; 538247822Sjfv } 539247822Sjfv 540247822Sjfv /* the pf is talking, if we timed out in the past we reinit */ 541247822Sjfv if (!mbx->timeout) { 542247822Sjfv ret_val = -1; 543247822Sjfv goto out; 544247822Sjfv } 545247822Sjfv 546247822Sjfv /* if we passed all the tests above then the link is up and we no 547247822Sjfv * longer need to check for link 548247822Sjfv */ 549247822Sjfv mac->get_link_status = FALSE; 550247822Sjfv 551247822Sjfvout: 552247822Sjfv *link_up = !mac->get_link_status; 553247822Sjfv return ret_val; 554247822Sjfv} 555247822Sjfv 556247822Sjfv/** 557247822Sjfv * ixgbevf_rlpml_set_vf - Set the maximum receive packet length 558247822Sjfv * @hw: pointer to the HW structure 559247822Sjfv * @max_size: value to assign to max frame size 560247822Sjfv **/ 561247822Sjfvvoid ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size) 562247822Sjfv{ 563247822Sjfv u32 msgbuf[2]; 564247822Sjfv 565247822Sjfv msgbuf[0] = IXGBE_VF_SET_LPE; 566247822Sjfv msgbuf[1] = max_size; 567247822Sjfv ixgbevf_write_msg_read_ack(hw, msgbuf, 2); 568247822Sjfv} 569247822Sjfv 570247822Sjfv/** 571247822Sjfv * ixgbevf_negotiate_api_version - Negotiate supported API version 572247822Sjfv * @hw: pointer to the HW structure 573247822Sjfv * @api: integer containing requested API version 574247822Sjfv **/ 575247822Sjfvint ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api) 576247822Sjfv{ 577247822Sjfv int err; 578247822Sjfv u32 msg[3]; 579247822Sjfv 580247822Sjfv /* Negotiate the mailbox API version */ 581247822Sjfv msg[0] = IXGBE_VF_API_NEGOTIATE; 582247822Sjfv msg[1] = api; 583247822Sjfv msg[2] = 0; 584247822Sjfv err = hw->mbx.ops.write_posted(hw, msg, 3, 0); 585247822Sjfv 586247822Sjfv if (!err) 587247822Sjfv err = hw->mbx.ops.read_posted(hw, msg, 3, 0); 588247822Sjfv 589247822Sjfv if (!err) { 590247822Sjfv msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; 591247822Sjfv 592247822Sjfv /* Store value and return 0 on success */ 593247822Sjfv if (msg[0] == (IXGBE_VF_API_NEGOTIATE | IXGBE_VT_MSGTYPE_ACK)) { 594247822Sjfv hw->api_version = api; 595247822Sjfv return 0; 596247822Sjfv } 597247822Sjfv 598247822Sjfv err = IXGBE_ERR_INVALID_ARGUMENT; 599247822Sjfv } 600247822Sjfv 601247822Sjfv return err; 602247822Sjfv} 603247822Sjfv 604247822Sjfvint ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, 605247822Sjfv unsigned int *default_tc) 606247822Sjfv{ 607247822Sjfv UNREFERENCED_3PARAMETER(hw, num_tcs, default_tc); 608215911Sjfv return IXGBE_SUCCESS; 609215911Sjfv} 610215911Sjfv 611