11a4e3449SJack F Vogel /******************************************************************************
27282444bSPedro F. Giffuni SPDX-License-Identifier: BSD-3-Clause
31a4e3449SJack F Vogel
48455e365SKevin Bowling Copyright (c) 2001-2020, Intel Corporation
51a4e3449SJack F Vogel All rights reserved.
61a4e3449SJack F Vogel
71a4e3449SJack F Vogel Redistribution and use in source and binary forms, with or without
81a4e3449SJack F Vogel modification, are permitted provided that the following conditions are met:
91a4e3449SJack F Vogel
101a4e3449SJack F Vogel 1. Redistributions of source code must retain the above copyright notice,
111a4e3449SJack F Vogel this list of conditions and the following disclaimer.
121a4e3449SJack F Vogel
131a4e3449SJack F Vogel 2. Redistributions in binary form must reproduce the above copyright
141a4e3449SJack F Vogel notice, this list of conditions and the following disclaimer in the
151a4e3449SJack F Vogel documentation and/or other materials provided with the distribution.
161a4e3449SJack F Vogel
171a4e3449SJack F Vogel 3. Neither the name of the Intel Corporation nor the names of its
181a4e3449SJack F Vogel contributors may be used to endorse or promote products derived from
191a4e3449SJack F Vogel this software without specific prior written permission.
201a4e3449SJack F Vogel
211a4e3449SJack F Vogel THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
221a4e3449SJack F Vogel AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231a4e3449SJack F Vogel IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241a4e3449SJack F Vogel ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
251a4e3449SJack F Vogel LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
261a4e3449SJack F Vogel CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
271a4e3449SJack F Vogel SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
281a4e3449SJack F Vogel INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
291a4e3449SJack F Vogel CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
301a4e3449SJack F Vogel ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
311a4e3449SJack F Vogel POSSIBILITY OF SUCH DAMAGE.
321a4e3449SJack F Vogel
331a4e3449SJack F Vogel ******************************************************************************/
341a4e3449SJack F Vogel
351a4e3449SJack F Vogel
368eb6488eSEric Joyner #include "ixgbe.h"
371a4e3449SJack F Vogel
381a4e3449SJack F Vogel #define IXGBE_VFWRITE_REG IXGBE_WRITE_REG
391a4e3449SJack F Vogel #define IXGBE_VFREAD_REG IXGBE_READ_REG
401a4e3449SJack F Vogel
411a4e3449SJack F Vogel /**
421a4e3449SJack F Vogel * ixgbe_init_ops_vf - Initialize the pointers for vf
431a4e3449SJack F Vogel * @hw: pointer to hardware structure
441a4e3449SJack F Vogel *
451a4e3449SJack F Vogel * This will assign function pointers, adapter-specific functions can
461a4e3449SJack F Vogel * override the assignment of generic function pointers by assigning
471a4e3449SJack F Vogel * their own adapter-specific function pointers.
481a4e3449SJack F Vogel * Does not touch the hardware.
491a4e3449SJack F Vogel **/
ixgbe_init_ops_vf(struct ixgbe_hw * hw)501a4e3449SJack F Vogel s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw)
511a4e3449SJack F Vogel {
52*7234c309SJakub Chylkowski u16 i;
53*7234c309SJakub Chylkowski
541a4e3449SJack F Vogel /* MAC */
551a4e3449SJack F Vogel hw->mac.ops.init_hw = ixgbe_init_hw_vf;
561a4e3449SJack F Vogel hw->mac.ops.reset_hw = ixgbe_reset_hw_vf;
571a4e3449SJack F Vogel hw->mac.ops.start_hw = ixgbe_start_hw_vf;
581a4e3449SJack F Vogel /* Cannot clear stats on VF */
591a4e3449SJack F Vogel hw->mac.ops.clear_hw_cntrs = NULL;
601a4e3449SJack F Vogel hw->mac.ops.get_media_type = NULL;
611a4e3449SJack F Vogel hw->mac.ops.get_mac_addr = ixgbe_get_mac_addr_vf;
6285d0a26eSJack F Vogel hw->mac.ops.stop_adapter = ixgbe_stop_adapter_vf;
631a4e3449SJack F Vogel hw->mac.ops.get_bus_info = NULL;
648eb6488eSEric Joyner hw->mac.ops.negotiate_api_version = ixgbevf_negotiate_api_version;
651a4e3449SJack F Vogel
661a4e3449SJack F Vogel /* Link */
671a4e3449SJack F Vogel hw->mac.ops.setup_link = ixgbe_setup_mac_link_vf;
681a4e3449SJack F Vogel hw->mac.ops.check_link = ixgbe_check_mac_link_vf;
691a4e3449SJack F Vogel hw->mac.ops.get_link_capabilities = NULL;
701a4e3449SJack F Vogel
711a4e3449SJack F Vogel /* RAR, Multicast, VLAN */
721a4e3449SJack F Vogel hw->mac.ops.set_rar = ixgbe_set_rar_vf;
7385d0a26eSJack F Vogel hw->mac.ops.set_uc_addr = ixgbevf_set_uc_addr_vf;
741a4e3449SJack F Vogel hw->mac.ops.init_rx_addrs = NULL;
751a4e3449SJack F Vogel hw->mac.ops.update_mc_addr_list = ixgbe_update_mc_addr_list_vf;
768eb6488eSEric Joyner hw->mac.ops.update_xcast_mode = ixgbevf_update_xcast_mode;
77a3e719bbSPiotr Pietruszewski hw->mac.ops.get_link_state = ixgbe_get_link_state_vf;
781a4e3449SJack F Vogel hw->mac.ops.enable_mc = NULL;
791a4e3449SJack F Vogel hw->mac.ops.disable_mc = NULL;
801a4e3449SJack F Vogel hw->mac.ops.clear_vfta = NULL;
811a4e3449SJack F Vogel hw->mac.ops.set_vfta = ixgbe_set_vfta_vf;
828eb6488eSEric Joyner hw->mac.ops.set_rlpml = ixgbevf_rlpml_set_vf;
831a4e3449SJack F Vogel
841a4e3449SJack F Vogel hw->mac.max_tx_queues = 1;
851a4e3449SJack F Vogel hw->mac.max_rx_queues = 1;
861a4e3449SJack F Vogel
87*7234c309SJakub Chylkowski for (i = 0; i < 64; i++)
88*7234c309SJakub Chylkowski hw->mbx.ops[i].init_params = ixgbe_init_mbx_params_vf;
891a4e3449SJack F Vogel
901a4e3449SJack F Vogel return IXGBE_SUCCESS;
911a4e3449SJack F Vogel }
921a4e3449SJack F Vogel
93758cc3dcSJack F Vogel /* ixgbe_virt_clr_reg - Set register to default (power on) state.
94758cc3dcSJack F Vogel * @hw: pointer to hardware structure
95758cc3dcSJack F Vogel */
ixgbe_virt_clr_reg(struct ixgbe_hw * hw)96758cc3dcSJack F Vogel static void ixgbe_virt_clr_reg(struct ixgbe_hw *hw)
97758cc3dcSJack F Vogel {
98758cc3dcSJack F Vogel int i;
99758cc3dcSJack F Vogel u32 vfsrrctl;
100758cc3dcSJack F Vogel u32 vfdca_rxctrl;
101758cc3dcSJack F Vogel u32 vfdca_txctrl;
102758cc3dcSJack F Vogel
103758cc3dcSJack F Vogel /* VRSRRCTL default values (BSIZEPACKET = 2048, BSIZEHEADER = 256) */
104758cc3dcSJack F Vogel vfsrrctl = 0x100 << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT;
105758cc3dcSJack F Vogel vfsrrctl |= 0x800 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
106758cc3dcSJack F Vogel
107758cc3dcSJack F Vogel /* DCA_RXCTRL default value */
108758cc3dcSJack F Vogel vfdca_rxctrl = IXGBE_DCA_RXCTRL_DESC_RRO_EN |
109758cc3dcSJack F Vogel IXGBE_DCA_RXCTRL_DATA_WRO_EN |
110758cc3dcSJack F Vogel IXGBE_DCA_RXCTRL_HEAD_WRO_EN;
111758cc3dcSJack F Vogel
112758cc3dcSJack F Vogel /* DCA_TXCTRL default value */
113758cc3dcSJack F Vogel vfdca_txctrl = IXGBE_DCA_TXCTRL_DESC_RRO_EN |
114758cc3dcSJack F Vogel IXGBE_DCA_TXCTRL_DESC_WRO_EN |
115758cc3dcSJack F Vogel IXGBE_DCA_TXCTRL_DATA_RRO_EN;
116758cc3dcSJack F Vogel
117758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, 0);
118758cc3dcSJack F Vogel
1197165504aSSimon Ellmann for (i = 0; i < 8; i++) {
120758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFRDH(i), 0);
121758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFRDT(i), 0);
122758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), 0);
123758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(i), vfsrrctl);
124758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTDH(i), 0);
125758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTDT(i), 0);
126758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), 0);
127758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTDWBAH(i), 0);
128758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTDWBAL(i), 0);
129758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFDCA_RXCTRL(i), vfdca_rxctrl);
130758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFDCA_TXCTRL(i), vfdca_txctrl);
131758cc3dcSJack F Vogel }
132758cc3dcSJack F Vogel
133758cc3dcSJack F Vogel IXGBE_WRITE_FLUSH(hw);
134758cc3dcSJack F Vogel }
135758cc3dcSJack F Vogel
1361a4e3449SJack F Vogel /**
1371a4e3449SJack F Vogel * ixgbe_start_hw_vf - Prepare hardware for Tx/Rx
1381a4e3449SJack F Vogel * @hw: pointer to hardware structure
1391a4e3449SJack F Vogel *
1401a4e3449SJack F Vogel * Starts the hardware by filling the bus info structure and media type, clears
1411a4e3449SJack F Vogel * all on chip counters, initializes receive address registers, multicast
1421a4e3449SJack F Vogel * table, VLAN filter table, calls routine to set up link and flow control
1431a4e3449SJack F Vogel * settings, and leaves transmit and receive units disabled and uninitialized
1441a4e3449SJack F Vogel **/
ixgbe_start_hw_vf(struct ixgbe_hw * hw)1451a4e3449SJack F Vogel s32 ixgbe_start_hw_vf(struct ixgbe_hw *hw)
1461a4e3449SJack F Vogel {
1471a4e3449SJack F Vogel /* Clear adapter stopped flag */
14879b36ec9SKevin Bowling hw->adapter_stopped = false;
1491a4e3449SJack F Vogel
1501a4e3449SJack F Vogel return IXGBE_SUCCESS;
1511a4e3449SJack F Vogel }
1521a4e3449SJack F Vogel
1531a4e3449SJack F Vogel /**
1541a4e3449SJack F Vogel * ixgbe_init_hw_vf - virtual function hardware initialization
1551a4e3449SJack F Vogel * @hw: pointer to hardware structure
1561a4e3449SJack F Vogel *
1571a4e3449SJack F Vogel * Initialize the hardware by resetting the hardware and then starting
1581a4e3449SJack F Vogel * the hardware
1591a4e3449SJack F Vogel **/
ixgbe_init_hw_vf(struct ixgbe_hw * hw)1601a4e3449SJack F Vogel s32 ixgbe_init_hw_vf(struct ixgbe_hw *hw)
1611a4e3449SJack F Vogel {
1621a4e3449SJack F Vogel s32 status = hw->mac.ops.start_hw(hw);
1631a4e3449SJack F Vogel
1641a4e3449SJack F Vogel hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
1651a4e3449SJack F Vogel
1661a4e3449SJack F Vogel return status;
1671a4e3449SJack F Vogel }
1681a4e3449SJack F Vogel
1691a4e3449SJack F Vogel /**
1701a4e3449SJack F Vogel * ixgbe_reset_hw_vf - Performs hardware reset
1711a4e3449SJack F Vogel * @hw: pointer to hardware structure
1721a4e3449SJack F Vogel *
17346981e90SGuinan Sun * Resets the hardware by resetting the transmit and receive units, masks and
1741a4e3449SJack F Vogel * clears all interrupts.
1751a4e3449SJack F Vogel **/
ixgbe_reset_hw_vf(struct ixgbe_hw * hw)1761a4e3449SJack F Vogel s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
1771a4e3449SJack F Vogel {
1781a4e3449SJack F Vogel struct ixgbe_mbx_info *mbx = &hw->mbx;
1791a4e3449SJack F Vogel u32 timeout = IXGBE_VF_INIT_TIMEOUT;
1801a4e3449SJack F Vogel s32 ret_val = IXGBE_ERR_INVALID_MAC_ADDR;
181758cc3dcSJack F Vogel u32 msgbuf[IXGBE_VF_PERMADDR_MSG_LEN];
1821a4e3449SJack F Vogel u8 *addr = (u8 *)(&msgbuf[1]);
1831a4e3449SJack F Vogel
1841a4e3449SJack F Vogel DEBUGFUNC("ixgbevf_reset_hw_vf");
1851a4e3449SJack F Vogel
1861a4e3449SJack F Vogel /* Call adapter stop to disable tx/rx and clear interrupts */
1871a4e3449SJack F Vogel hw->mac.ops.stop_adapter(hw);
1881a4e3449SJack F Vogel
18948056c88SJack F Vogel /* reset the api version */
19048056c88SJack F Vogel hw->api_version = ixgbe_mbox_api_10;
191*7234c309SJakub Chylkowski ixgbe_init_mbx_params_vf(hw);
1920ecc2ff0SJack F Vogel
1931a4e3449SJack F Vogel DEBUGOUT("Issuing a function level reset to MAC\n");
19485d0a26eSJack F Vogel
195758cc3dcSJack F Vogel IXGBE_VFWRITE_REG(hw, IXGBE_VFCTRL, IXGBE_CTRL_RST);
1961a4e3449SJack F Vogel IXGBE_WRITE_FLUSH(hw);
1971a4e3449SJack F Vogel
19885d0a26eSJack F Vogel msec_delay(50);
1991a4e3449SJack F Vogel
2001a4e3449SJack F Vogel /* we cannot reset while the RSTI / RSTD bits are asserted */
201*7234c309SJakub Chylkowski while (!mbx->ops[0].check_for_rst(hw, 0) && timeout) {
2021a4e3449SJack F Vogel timeout--;
2031a4e3449SJack F Vogel usec_delay(5);
2041a4e3449SJack F Vogel }
2051a4e3449SJack F Vogel
206fd75b91dSJack F Vogel if (!timeout)
207fd75b91dSJack F Vogel return IXGBE_ERR_RESET_FAILED;
208fd75b91dSJack F Vogel
209758cc3dcSJack F Vogel /* Reset VF registers to initial values */
210758cc3dcSJack F Vogel ixgbe_virt_clr_reg(hw);
211758cc3dcSJack F Vogel
2121a4e3449SJack F Vogel /* mailbox timeout can now become active */
2131a4e3449SJack F Vogel mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
2141a4e3449SJack F Vogel
2151a4e3449SJack F Vogel msgbuf[0] = IXGBE_VF_RESET;
216*7234c309SJakub Chylkowski ixgbe_write_mbx(hw, msgbuf, 1, 0);
2171a4e3449SJack F Vogel
2181a4e3449SJack F Vogel msec_delay(10);
2191a4e3449SJack F Vogel
22085d0a26eSJack F Vogel /*
22185d0a26eSJack F Vogel * set our "perm_addr" based on info provided by PF
22285d0a26eSJack F Vogel * also set up the mc_filter_type which is piggy backed
22385d0a26eSJack F Vogel * on the mac address in word 3
22485d0a26eSJack F Vogel */
225*7234c309SJakub Chylkowski ret_val = ixgbe_poll_mbx(hw, msgbuf,
2261a4e3449SJack F Vogel IXGBE_VF_PERMADDR_MSG_LEN, 0);
227fd75b91dSJack F Vogel if (ret_val)
228fd75b91dSJack F Vogel return ret_val;
229fd75b91dSJack F Vogel
23010746040SJakub Chylkowski if (msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_SUCCESS) &&
23110746040SJakub Chylkowski msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_FAILURE))
232fd75b91dSJack F Vogel return IXGBE_ERR_INVALID_MAC_ADDR;
233fd75b91dSJack F Vogel
23410746040SJakub Chylkowski if (msgbuf[0] == (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_SUCCESS))
235fd75b91dSJack F Vogel memcpy(hw->mac.perm_addr, addr, IXGBE_ETH_LENGTH_OF_ADDRESS);
2368eb6488eSEric Joyner
237fd75b91dSJack F Vogel hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD];
2381a4e3449SJack F Vogel
2391a4e3449SJack F Vogel return ret_val;
2401a4e3449SJack F Vogel }
2411a4e3449SJack F Vogel
2421a4e3449SJack F Vogel /**
24385d0a26eSJack F Vogel * ixgbe_stop_adapter_vf - Generic stop Tx/Rx units
2441a4e3449SJack F Vogel * @hw: pointer to hardware structure
2451a4e3449SJack F Vogel *
2461a4e3449SJack F Vogel * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
2471a4e3449SJack F Vogel * disables transmit and receive units. The adapter_stopped flag is used by
2481a4e3449SJack F Vogel * the shared code and drivers to determine if the adapter is in a stopped
2491a4e3449SJack F Vogel * state and should not touch the hardware.
2501a4e3449SJack F Vogel **/
ixgbe_stop_adapter_vf(struct ixgbe_hw * hw)25185d0a26eSJack F Vogel s32 ixgbe_stop_adapter_vf(struct ixgbe_hw *hw)
2521a4e3449SJack F Vogel {
2531a4e3449SJack F Vogel u32 reg_val;
2541a4e3449SJack F Vogel u16 i;
2551a4e3449SJack F Vogel
2561a4e3449SJack F Vogel /*
2571a4e3449SJack F Vogel * Set the adapter_stopped flag so other driver functions stop touching
2581a4e3449SJack F Vogel * the hardware
2591a4e3449SJack F Vogel */
26079b36ec9SKevin Bowling hw->adapter_stopped = true;
2611a4e3449SJack F Vogel
2621a4e3449SJack F Vogel /* Clear interrupt mask to stop from interrupts being generated */
2631a4e3449SJack F Vogel IXGBE_VFWRITE_REG(hw, IXGBE_VTEIMC, IXGBE_VF_IRQ_CLEAR_MASK);
2641a4e3449SJack F Vogel
26585d0a26eSJack F Vogel /* Clear any pending interrupts, flush previous writes */
2661a4e3449SJack F Vogel IXGBE_VFREAD_REG(hw, IXGBE_VTEICR);
2671a4e3449SJack F Vogel
2681a4e3449SJack F Vogel /* Disable the transmit unit. Each queue must be disabled. */
26985d0a26eSJack F Vogel for (i = 0; i < hw->mac.max_tx_queues; i++)
27085d0a26eSJack F Vogel IXGBE_VFWRITE_REG(hw, IXGBE_VFTXDCTL(i), IXGBE_TXDCTL_SWFLSH);
27185d0a26eSJack F Vogel
27285d0a26eSJack F Vogel /* Disable the receive unit by stopping each queue */
27385d0a26eSJack F Vogel for (i = 0; i < hw->mac.max_rx_queues; i++) {
27485d0a26eSJack F Vogel reg_val = IXGBE_VFREAD_REG(hw, IXGBE_VFRXDCTL(i));
27585d0a26eSJack F Vogel reg_val &= ~IXGBE_RXDCTL_ENABLE;
27685d0a26eSJack F Vogel IXGBE_VFWRITE_REG(hw, IXGBE_VFRXDCTL(i), reg_val);
2771a4e3449SJack F Vogel }
278758cc3dcSJack F Vogel /* Clear packet split and pool config */
279758cc3dcSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, 0);
28085d0a26eSJack F Vogel
28185d0a26eSJack F Vogel /* flush all queues disables */
28285d0a26eSJack F Vogel IXGBE_WRITE_FLUSH(hw);
28385d0a26eSJack F Vogel msec_delay(2);
2841a4e3449SJack F Vogel
2851a4e3449SJack F Vogel return IXGBE_SUCCESS;
2861a4e3449SJack F Vogel }
2871a4e3449SJack F Vogel
2881a4e3449SJack F Vogel /**
2891a4e3449SJack F Vogel * ixgbe_mta_vector - Determines bit-vector in multicast table to set
2901a4e3449SJack F Vogel * @hw: pointer to hardware structure
2911a4e3449SJack F Vogel * @mc_addr: the multicast address
2921a4e3449SJack F Vogel *
2931a4e3449SJack F Vogel * Extracts the 12 bits, from a multicast address, to determine which
2941a4e3449SJack F Vogel * bit-vector to set in the multicast table. The hardware uses 12 bits, from
2951a4e3449SJack F Vogel * incoming rx multicast addresses, to determine the bit-vector to check in
2961a4e3449SJack F Vogel * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
2971a4e3449SJack F Vogel * by the MO field of the MCSTCTRL. The MO field is set during initialization
2981a4e3449SJack F Vogel * to mc_filter_type.
2991a4e3449SJack F Vogel **/
ixgbe_mta_vector(struct ixgbe_hw * hw,u8 * mc_addr)3001a4e3449SJack F Vogel static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
3011a4e3449SJack F Vogel {
3021a4e3449SJack F Vogel u32 vector = 0;
3031a4e3449SJack F Vogel
3041a4e3449SJack F Vogel switch (hw->mac.mc_filter_type) {
3051a4e3449SJack F Vogel case 0: /* use bits [47:36] of the address */
3061a4e3449SJack F Vogel vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
3071a4e3449SJack F Vogel break;
3081a4e3449SJack F Vogel case 1: /* use bits [46:35] of the address */
3091a4e3449SJack F Vogel vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
3101a4e3449SJack F Vogel break;
3111a4e3449SJack F Vogel case 2: /* use bits [45:34] of the address */
3121a4e3449SJack F Vogel vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
3131a4e3449SJack F Vogel break;
3141a4e3449SJack F Vogel case 3: /* use bits [43:32] of the address */
3151a4e3449SJack F Vogel vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
3161a4e3449SJack F Vogel break;
3171a4e3449SJack F Vogel default: /* Invalid mc_filter_type */
3181a4e3449SJack F Vogel DEBUGOUT("MC filter type param set incorrectly\n");
3191a4e3449SJack F Vogel ASSERT(0);
3201a4e3449SJack F Vogel break;
3211a4e3449SJack F Vogel }
3221a4e3449SJack F Vogel
3231a4e3449SJack F Vogel /* vector can only be 12-bits or boundary will be exceeded */
3241a4e3449SJack F Vogel vector &= 0xFFF;
3251a4e3449SJack F Vogel return vector;
3261a4e3449SJack F Vogel }
3271a4e3449SJack F Vogel
ixgbevf_write_msg_read_ack(struct ixgbe_hw * hw,u32 * msg,u32 * retmsg,u16 size)3288eb6488eSEric Joyner static s32 ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, u32 *msg,
3298eb6488eSEric Joyner u32 *retmsg, u16 size)
3300ecc2ff0SJack F Vogel {
331*7234c309SJakub Chylkowski s32 retval = ixgbe_write_mbx(hw, msg, size, 0);
3320ecc2ff0SJack F Vogel
3338eb6488eSEric Joyner if (retval)
3348eb6488eSEric Joyner return retval;
3358eb6488eSEric Joyner
336*7234c309SJakub Chylkowski return ixgbe_poll_mbx(hw, retmsg, size, 0);
3370ecc2ff0SJack F Vogel }
3380ecc2ff0SJack F Vogel
3391a4e3449SJack F Vogel /**
3401a4e3449SJack F Vogel * ixgbe_set_rar_vf - set device MAC address
3411a4e3449SJack F Vogel * @hw: pointer to hardware structure
3421a4e3449SJack F Vogel * @index: Receive address register to write
3431a4e3449SJack F Vogel * @addr: Address to put into receive address register
3441a4e3449SJack F Vogel * @vmdq: VMDq "set" or "pool" index
3451a4e3449SJack F Vogel * @enable_addr: set flag that address is active
3461a4e3449SJack F Vogel **/
ixgbe_set_rar_vf(struct ixgbe_hw * hw,u32 index,u8 * addr,u32 vmdq,u32 enable_addr)3471a4e3449SJack F Vogel s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
3481a4e3449SJack F Vogel u32 enable_addr)
3491a4e3449SJack F Vogel {
3501a4e3449SJack F Vogel u32 msgbuf[3];
3511a4e3449SJack F Vogel u8 *msg_addr = (u8 *)(&msgbuf[1]);
3521a4e3449SJack F Vogel s32 ret_val;
35385d0a26eSJack F Vogel UNREFERENCED_3PARAMETER(vmdq, enable_addr, index);
3541a4e3449SJack F Vogel
3551a4e3449SJack F Vogel memset(msgbuf, 0, 12);
3561a4e3449SJack F Vogel msgbuf[0] = IXGBE_VF_SET_MAC_ADDR;
3571a4e3449SJack F Vogel memcpy(msg_addr, addr, 6);
3588eb6488eSEric Joyner ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3);
3591a4e3449SJack F Vogel
3601a4e3449SJack F Vogel msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
3611a4e3449SJack F Vogel
36210746040SJakub Chylkowski /* if we had failure, the address was rejected, use "perm_addr" */
3631a4e3449SJack F Vogel if (!ret_val &&
36410746040SJakub Chylkowski (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_FAILURE))) {
3651a4e3449SJack F Vogel ixgbe_get_mac_addr_vf(hw, hw->mac.addr);
3668eb6488eSEric Joyner return IXGBE_ERR_MBX;
3678eb6488eSEric Joyner }
3681a4e3449SJack F Vogel
3691a4e3449SJack F Vogel return ret_val;
3701a4e3449SJack F Vogel }
3711a4e3449SJack F Vogel
3721a4e3449SJack F Vogel /**
3731a4e3449SJack F Vogel * ixgbe_update_mc_addr_list_vf - Update Multicast addresses
3741a4e3449SJack F Vogel * @hw: pointer to the HW structure
3751a4e3449SJack F Vogel * @mc_addr_list: array of multicast addresses to program
3761a4e3449SJack F Vogel * @mc_addr_count: number of multicast addresses to program
3771a4e3449SJack F Vogel * @next: caller supplied function to return next address in list
3787d48aa4cSEric Joyner * @clear: unused
3791a4e3449SJack F Vogel *
3801a4e3449SJack F Vogel * Updates the Multicast Table Array.
3811a4e3449SJack F Vogel **/
ixgbe_update_mc_addr_list_vf(struct ixgbe_hw * hw,u8 * mc_addr_list,u32 mc_addr_count,ixgbe_mc_addr_itr next,bool clear)3821a4e3449SJack F Vogel s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,
38385d0a26eSJack F Vogel u32 mc_addr_count, ixgbe_mc_addr_itr next,
38485d0a26eSJack F Vogel bool clear)
3851a4e3449SJack F Vogel {
3861a4e3449SJack F Vogel u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
3871a4e3449SJack F Vogel u16 *vector_list = (u16 *)&msgbuf[1];
3881a4e3449SJack F Vogel u32 vector;
3891a4e3449SJack F Vogel u32 cnt, i;
3901a4e3449SJack F Vogel u32 vmdq;
3911a4e3449SJack F Vogel
39285d0a26eSJack F Vogel UNREFERENCED_1PARAMETER(clear);
39385d0a26eSJack F Vogel
3941a4e3449SJack F Vogel DEBUGFUNC("ixgbe_update_mc_addr_list_vf");
3951a4e3449SJack F Vogel
3961a4e3449SJack F Vogel /* Each entry in the list uses 1 16 bit word. We have 30
3971a4e3449SJack F Vogel * 16 bit words available in our HW msg buffer (minus 1 for the
3981a4e3449SJack F Vogel * msg type). That's 30 hash values if we pack 'em right. If
3991a4e3449SJack F Vogel * there are more than 30 MC addresses to add then punt the
4001a4e3449SJack F Vogel * extras for now and then add code to handle more than 30 later.
4011a4e3449SJack F Vogel * It would be unusual for a server to request that many multi-cast
4021a4e3449SJack F Vogel * addresses except for in large enterprise network environments.
4031a4e3449SJack F Vogel */
4041a4e3449SJack F Vogel
4051a4e3449SJack F Vogel DEBUGOUT1("MC Addr Count = %d\n", mc_addr_count);
4061a4e3449SJack F Vogel
4071a4e3449SJack F Vogel cnt = (mc_addr_count > 30) ? 30 : mc_addr_count;
4081a4e3449SJack F Vogel msgbuf[0] = IXGBE_VF_SET_MULTICAST;
4091a4e3449SJack F Vogel msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT;
4101a4e3449SJack F Vogel
4111a4e3449SJack F Vogel for (i = 0; i < cnt; i++) {
4121a4e3449SJack F Vogel vector = ixgbe_mta_vector(hw, next(hw, &mc_addr_list, &vmdq));
4131a4e3449SJack F Vogel DEBUGOUT1("Hash value = 0x%03X\n", vector);
4141a4e3449SJack F Vogel vector_list[i] = (u16)vector;
4151a4e3449SJack F Vogel }
4161a4e3449SJack F Vogel
417*7234c309SJakub Chylkowski return ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, IXGBE_VFMAILBOX_SIZE);
4181a4e3449SJack F Vogel }
4191a4e3449SJack F Vogel
4201a4e3449SJack F Vogel /**
4218eb6488eSEric Joyner * ixgbevf_update_xcast_mode - Update Multicast mode
4228eb6488eSEric Joyner * @hw: pointer to the HW structure
4238eb6488eSEric Joyner * @xcast_mode: new multicast mode
4248eb6488eSEric Joyner *
4258eb6488eSEric Joyner * Updates the Multicast Mode of VF.
4268eb6488eSEric Joyner **/
ixgbevf_update_xcast_mode(struct ixgbe_hw * hw,int xcast_mode)4278eb6488eSEric Joyner s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
4288eb6488eSEric Joyner {
4298eb6488eSEric Joyner u32 msgbuf[2];
4308eb6488eSEric Joyner s32 err;
4318eb6488eSEric Joyner
4328eb6488eSEric Joyner switch (hw->api_version) {
4338eb6488eSEric Joyner case ixgbe_mbox_api_12:
4348eb6488eSEric Joyner /* New modes were introduced in 1.3 version */
4358eb6488eSEric Joyner if (xcast_mode > IXGBEVF_XCAST_MODE_ALLMULTI)
4368eb6488eSEric Joyner return IXGBE_ERR_FEATURE_NOT_SUPPORTED;
4378eb6488eSEric Joyner /* Fall through */
4388eb6488eSEric Joyner case ixgbe_mbox_api_13:
439*7234c309SJakub Chylkowski case ixgbe_mbox_api_15:
4408eb6488eSEric Joyner break;
4418eb6488eSEric Joyner default:
4428eb6488eSEric Joyner return IXGBE_ERR_FEATURE_NOT_SUPPORTED;
4438eb6488eSEric Joyner }
4448eb6488eSEric Joyner
4458eb6488eSEric Joyner msgbuf[0] = IXGBE_VF_UPDATE_XCAST_MODE;
4468eb6488eSEric Joyner msgbuf[1] = xcast_mode;
4478eb6488eSEric Joyner
4488eb6488eSEric Joyner err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
4498eb6488eSEric Joyner if (err)
4508eb6488eSEric Joyner return err;
4518eb6488eSEric Joyner
4528eb6488eSEric Joyner msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
45310746040SJakub Chylkowski if (msgbuf[0] == (IXGBE_VF_UPDATE_XCAST_MODE | IXGBE_VT_MSGTYPE_FAILURE))
4548eb6488eSEric Joyner return IXGBE_ERR_FEATURE_NOT_SUPPORTED;
4558eb6488eSEric Joyner return IXGBE_SUCCESS;
4568eb6488eSEric Joyner }
4578eb6488eSEric Joyner
4588eb6488eSEric Joyner /**
459a3e719bbSPiotr Pietruszewski * ixgbe_get_link_state_vf - Get VF link state from PF
460a3e719bbSPiotr Pietruszewski * @hw: pointer to the HW structure
461a3e719bbSPiotr Pietruszewski * @link_state: link state storage
462a3e719bbSPiotr Pietruszewski *
463a3e719bbSPiotr Pietruszewski * Returns state of the operation error or success.
464a3e719bbSPiotr Pietruszewski **/
ixgbe_get_link_state_vf(struct ixgbe_hw * hw,bool * link_state)465a3e719bbSPiotr Pietruszewski s32 ixgbe_get_link_state_vf(struct ixgbe_hw *hw, bool *link_state)
466a3e719bbSPiotr Pietruszewski {
467a3e719bbSPiotr Pietruszewski u32 msgbuf[2];
468a3e719bbSPiotr Pietruszewski s32 err;
469a3e719bbSPiotr Pietruszewski s32 ret_val;
470a3e719bbSPiotr Pietruszewski
471a3e719bbSPiotr Pietruszewski msgbuf[0] = IXGBE_VF_GET_LINK_STATE;
472a3e719bbSPiotr Pietruszewski msgbuf[1] = 0x0;
473a3e719bbSPiotr Pietruszewski
474a3e719bbSPiotr Pietruszewski err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
475a3e719bbSPiotr Pietruszewski
47610746040SJakub Chylkowski if (err || (msgbuf[0] & IXGBE_VT_MSGTYPE_FAILURE)) {
477a3e719bbSPiotr Pietruszewski ret_val = IXGBE_ERR_MBX;
478a3e719bbSPiotr Pietruszewski } else {
479a3e719bbSPiotr Pietruszewski ret_val = IXGBE_SUCCESS;
480a3e719bbSPiotr Pietruszewski *link_state = msgbuf[1];
481a3e719bbSPiotr Pietruszewski }
482a3e719bbSPiotr Pietruszewski
483a3e719bbSPiotr Pietruszewski return ret_val;
484a3e719bbSPiotr Pietruszewski }
485a3e719bbSPiotr Pietruszewski
486a3e719bbSPiotr Pietruszewski /**
4871a4e3449SJack F Vogel * ixgbe_set_vfta_vf - Set/Unset vlan filter table address
4881a4e3449SJack F Vogel * @hw: pointer to the HW structure
4891a4e3449SJack F Vogel * @vlan: 12 bit VLAN ID
4901a4e3449SJack F Vogel * @vind: unused by VF drivers
49179b36ec9SKevin Bowling * @vlan_on: if true then set bit, else clear bit
4928eb6488eSEric Joyner * @vlvf_bypass: boolean flag indicating updating default pool is okay
4938eb6488eSEric Joyner *
4948eb6488eSEric Joyner * Turn on/off specified VLAN in the VLAN filter table.
4951a4e3449SJack F Vogel **/
ixgbe_set_vfta_vf(struct ixgbe_hw * hw,u32 vlan,u32 vind,bool vlan_on,bool vlvf_bypass)4968eb6488eSEric Joyner s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
4978eb6488eSEric Joyner bool vlan_on, bool vlvf_bypass)
4981a4e3449SJack F Vogel {
4991a4e3449SJack F Vogel u32 msgbuf[2];
500a621e3c8SJack F Vogel s32 ret_val;
5018eb6488eSEric Joyner UNREFERENCED_2PARAMETER(vind, vlvf_bypass);
5021a4e3449SJack F Vogel
5031a4e3449SJack F Vogel msgbuf[0] = IXGBE_VF_SET_VLAN;
5041a4e3449SJack F Vogel msgbuf[1] = vlan;
50579b36ec9SKevin Bowling /* Setting the 8 bit field MSG INFO to true indicates "add" */
5061a4e3449SJack F Vogel msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT;
5071a4e3449SJack F Vogel
5088eb6488eSEric Joyner ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
50910746040SJakub Chylkowski if (!ret_val && (msgbuf[0] & IXGBE_VT_MSGTYPE_SUCCESS))
510a621e3c8SJack F Vogel return IXGBE_SUCCESS;
511a621e3c8SJack F Vogel
51210746040SJakub Chylkowski return ret_val | (msgbuf[0] & IXGBE_VT_MSGTYPE_FAILURE);
5131a4e3449SJack F Vogel }
5141a4e3449SJack F Vogel
5151a4e3449SJack F Vogel /**
5161a4e3449SJack F Vogel * ixgbe_get_num_of_tx_queues_vf - Get number of TX queues
5171a4e3449SJack F Vogel * @hw: pointer to hardware structure
5181a4e3449SJack F Vogel *
5191a4e3449SJack F Vogel * Returns the number of transmit queues for the given adapter.
5201a4e3449SJack F Vogel **/
ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw * hw)5211a4e3449SJack F Vogel u32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw)
5221a4e3449SJack F Vogel {
52385d0a26eSJack F Vogel UNREFERENCED_1PARAMETER(hw);
5241a4e3449SJack F Vogel return IXGBE_VF_MAX_TX_QUEUES;
5251a4e3449SJack F Vogel }
5261a4e3449SJack F Vogel
5271a4e3449SJack F Vogel /**
5281a4e3449SJack F Vogel * ixgbe_get_num_of_rx_queues_vf - Get number of RX queues
5291a4e3449SJack F Vogel * @hw: pointer to hardware structure
5301a4e3449SJack F Vogel *
5311a4e3449SJack F Vogel * Returns the number of receive queues for the given adapter.
5321a4e3449SJack F Vogel **/
ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw * hw)5331a4e3449SJack F Vogel u32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw)
5341a4e3449SJack F Vogel {
53585d0a26eSJack F Vogel UNREFERENCED_1PARAMETER(hw);
5361a4e3449SJack F Vogel return IXGBE_VF_MAX_RX_QUEUES;
5371a4e3449SJack F Vogel }
5381a4e3449SJack F Vogel
5391a4e3449SJack F Vogel /**
5401a4e3449SJack F Vogel * ixgbe_get_mac_addr_vf - Read device MAC address
5411a4e3449SJack F Vogel * @hw: pointer to the HW structure
5427d48aa4cSEric Joyner * @mac_addr: the MAC address
5431a4e3449SJack F Vogel **/
ixgbe_get_mac_addr_vf(struct ixgbe_hw * hw,u8 * mac_addr)5441a4e3449SJack F Vogel s32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
5451a4e3449SJack F Vogel {
5461a4e3449SJack F Vogel int i;
5471a4e3449SJack F Vogel
5481a4e3449SJack F Vogel for (i = 0; i < IXGBE_ETH_LENGTH_OF_ADDRESS; i++)
5491a4e3449SJack F Vogel mac_addr[i] = hw->mac.perm_addr[i];
5501a4e3449SJack F Vogel
5511a4e3449SJack F Vogel return IXGBE_SUCCESS;
5521a4e3449SJack F Vogel }
5531a4e3449SJack F Vogel
ixgbevf_set_uc_addr_vf(struct ixgbe_hw * hw,u32 index,u8 * addr)55485d0a26eSJack F Vogel s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
55585d0a26eSJack F Vogel {
5568eb6488eSEric Joyner u32 msgbuf[3], msgbuf_chk;
55785d0a26eSJack F Vogel u8 *msg_addr = (u8 *)(&msgbuf[1]);
55885d0a26eSJack F Vogel s32 ret_val;
55985d0a26eSJack F Vogel
56085d0a26eSJack F Vogel memset(msgbuf, 0, sizeof(msgbuf));
56185d0a26eSJack F Vogel /*
56285d0a26eSJack F Vogel * If index is one then this is the start of a new list and needs
56385d0a26eSJack F Vogel * indication to the PF so it can do it's own list management.
56485d0a26eSJack F Vogel * If it is zero then that tells the PF to just clear all of
56585d0a26eSJack F Vogel * this VF's macvlans and there is no new list.
56685d0a26eSJack F Vogel */
56785d0a26eSJack F Vogel msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
56885d0a26eSJack F Vogel msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
5698eb6488eSEric Joyner msgbuf_chk = msgbuf[0];
57085d0a26eSJack F Vogel if (addr)
57185d0a26eSJack F Vogel memcpy(msg_addr, addr, 6);
57285d0a26eSJack F Vogel
5738eb6488eSEric Joyner ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3);
5748eb6488eSEric Joyner if (!ret_val) {
57585d0a26eSJack F Vogel msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
57685d0a26eSJack F Vogel
57710746040SJakub Chylkowski if (msgbuf[0] == (msgbuf_chk | IXGBE_VT_MSGTYPE_FAILURE))
5788eb6488eSEric Joyner return IXGBE_ERR_OUT_OF_MEM;
5798eb6488eSEric Joyner }
58085d0a26eSJack F Vogel
58185d0a26eSJack F Vogel return ret_val;
58285d0a26eSJack F Vogel }
58385d0a26eSJack F Vogel
5841a4e3449SJack F Vogel /**
5851a4e3449SJack F Vogel * ixgbe_setup_mac_link_vf - Setup MAC link settings
5861a4e3449SJack F Vogel * @hw: pointer to hardware structure
5871a4e3449SJack F Vogel * @speed: new link speed
58879b36ec9SKevin Bowling * @autoneg_wait_to_complete: true when waiting for completion is needed
5891a4e3449SJack F Vogel *
5901a4e3449SJack F Vogel * Set the link speed in the AUTOC register and restarts link.
5911a4e3449SJack F Vogel **/
ixgbe_setup_mac_link_vf(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)5920ecc2ff0SJack F Vogel s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed,
5931a4e3449SJack F Vogel bool autoneg_wait_to_complete)
5941a4e3449SJack F Vogel {
5950ecc2ff0SJack F Vogel UNREFERENCED_3PARAMETER(hw, speed, autoneg_wait_to_complete);
5961a4e3449SJack F Vogel return IXGBE_SUCCESS;
5971a4e3449SJack F Vogel }
5981a4e3449SJack F Vogel
5991a4e3449SJack F Vogel /**
6001a4e3449SJack F Vogel * ixgbe_check_mac_link_vf - Get link/speed status
6011a4e3449SJack F Vogel * @hw: pointer to hardware structure
6021a4e3449SJack F Vogel * @speed: pointer to link speed
60379b36ec9SKevin Bowling * @link_up: true is link is up, false otherwise
60479b36ec9SKevin Bowling * @autoneg_wait_to_complete: true when waiting for completion is needed
6051a4e3449SJack F Vogel *
6061a4e3449SJack F Vogel * Reads the links register to determine if link is up and the current speed
6071a4e3449SJack F Vogel **/
ixgbe_check_mac_link_vf(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up,bool autoneg_wait_to_complete)6081a4e3449SJack F Vogel s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
6091a4e3449SJack F Vogel bool *link_up, bool autoneg_wait_to_complete)
6101a4e3449SJack F Vogel {
6110ecc2ff0SJack F Vogel struct ixgbe_mbx_info *mbx = &hw->mbx;
6120ecc2ff0SJack F Vogel struct ixgbe_mac_info *mac = &hw->mac;
6130ecc2ff0SJack F Vogel s32 ret_val = IXGBE_SUCCESS;
614d80c12baSKevin Bowling u32 in_msg = 0;
615*7234c309SJakub Chylkowski u32 links_reg;
616*7234c309SJakub Chylkowski
61785d0a26eSJack F Vogel UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
6181a4e3449SJack F Vogel
6190ecc2ff0SJack F Vogel /* If we were hit with a reset drop the link */
620*7234c309SJakub Chylkowski if (!mbx->ops[0].check_for_rst(hw, 0) || !mbx->timeout)
62179b36ec9SKevin Bowling mac->get_link_status = true;
6221a4e3449SJack F Vogel
6230ecc2ff0SJack F Vogel if (!mac->get_link_status)
6240ecc2ff0SJack F Vogel goto out;
6251a4e3449SJack F Vogel
6260ecc2ff0SJack F Vogel /* if link status is down no point in checking to see if pf is up */
6270ecc2ff0SJack F Vogel links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
6280ecc2ff0SJack F Vogel if (!(links_reg & IXGBE_LINKS_UP))
6290ecc2ff0SJack F Vogel goto out;
6301a4e3449SJack F Vogel
631758cc3dcSJack F Vogel /* for SFP+ modules and DA cables on 82599 it can take up to 500usecs
632758cc3dcSJack F Vogel * before the link status is correct
633758cc3dcSJack F Vogel */
634758cc3dcSJack F Vogel if (mac->type == ixgbe_mac_82599_vf) {
635758cc3dcSJack F Vogel int i;
636758cc3dcSJack F Vogel
637758cc3dcSJack F Vogel for (i = 0; i < 5; i++) {
638758cc3dcSJack F Vogel usec_delay(100);
639758cc3dcSJack F Vogel links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
640758cc3dcSJack F Vogel
641758cc3dcSJack F Vogel if (!(links_reg & IXGBE_LINKS_UP))
642758cc3dcSJack F Vogel goto out;
643758cc3dcSJack F Vogel }
644758cc3dcSJack F Vogel }
645758cc3dcSJack F Vogel
6460ecc2ff0SJack F Vogel switch (links_reg & IXGBE_LINKS_SPEED_82599) {
647a621e3c8SJack F Vogel case IXGBE_LINKS_SPEED_10G_82599:
6481a4e3449SJack F Vogel *speed = IXGBE_LINK_SPEED_10GB_FULL;
649ab92cab0SPiotr Skajewski if (hw->mac.type >= ixgbe_mac_X550_vf) {
6508eb6488eSEric Joyner if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
6518eb6488eSEric Joyner *speed = IXGBE_LINK_SPEED_2_5GB_FULL;
6528eb6488eSEric Joyner }
653a621e3c8SJack F Vogel break;
654a621e3c8SJack F Vogel case IXGBE_LINKS_SPEED_1G_82599:
6551a4e3449SJack F Vogel *speed = IXGBE_LINK_SPEED_1GB_FULL;
656a621e3c8SJack F Vogel break;
657a621e3c8SJack F Vogel case IXGBE_LINKS_SPEED_100_82599:
658a621e3c8SJack F Vogel *speed = IXGBE_LINK_SPEED_100_FULL;
659ab92cab0SPiotr Skajewski if (hw->mac.type == ixgbe_mac_X550_vf) {
6608eb6488eSEric Joyner if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
6618eb6488eSEric Joyner *speed = IXGBE_LINK_SPEED_5GB_FULL;
6628eb6488eSEric Joyner }
663a621e3c8SJack F Vogel break;
6648eb6488eSEric Joyner case IXGBE_LINKS_SPEED_10_X550EM_A:
6658eb6488eSEric Joyner *speed = IXGBE_LINK_SPEED_UNKNOWN;
6668eb6488eSEric Joyner /* Since Reserved in older MAC's */
667ab92cab0SPiotr Skajewski if (hw->mac.type >= ixgbe_mac_X550_vf)
6688eb6488eSEric Joyner *speed = IXGBE_LINK_SPEED_10_FULL;
6698eb6488eSEric Joyner break;
6708eb6488eSEric Joyner default:
6718eb6488eSEric Joyner *speed = IXGBE_LINK_SPEED_UNKNOWN;
672a621e3c8SJack F Vogel }
6731a4e3449SJack F Vogel
6740ecc2ff0SJack F Vogel /* if the read failed it could just be a mailbox collision, best wait
6750ecc2ff0SJack F Vogel * until we are called again and don't report an error
6760ecc2ff0SJack F Vogel */
677*7234c309SJakub Chylkowski if (ixgbe_read_mbx(hw, &in_msg, 1, 0)) {
678*7234c309SJakub Chylkowski if (hw->api_version >= ixgbe_mbox_api_15)
679*7234c309SJakub Chylkowski mac->get_link_status = false;
6800ecc2ff0SJack F Vogel goto out;
681*7234c309SJakub Chylkowski }
6820ecc2ff0SJack F Vogel
6830ecc2ff0SJack F Vogel if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) {
684*7234c309SJakub Chylkowski /* msg is not CTS and is FAILURE we must have lost CTS status */
68510746040SJakub Chylkowski if (in_msg & IXGBE_VT_MSGTYPE_FAILURE)
686*7234c309SJakub Chylkowski ret_val = IXGBE_ERR_MBX;
6870ecc2ff0SJack F Vogel goto out;
6880ecc2ff0SJack F Vogel }
6890ecc2ff0SJack F Vogel
6900ecc2ff0SJack F Vogel /* the pf is talking, if we timed out in the past we reinit */
6910ecc2ff0SJack F Vogel if (!mbx->timeout) {
692*7234c309SJakub Chylkowski ret_val = IXGBE_ERR_TIMEOUT;
6930ecc2ff0SJack F Vogel goto out;
6940ecc2ff0SJack F Vogel }
6950ecc2ff0SJack F Vogel
6960ecc2ff0SJack F Vogel /* if we passed all the tests above then the link is up and we no
6970ecc2ff0SJack F Vogel * longer need to check for link
6980ecc2ff0SJack F Vogel */
69979b36ec9SKevin Bowling mac->get_link_status = false;
7000ecc2ff0SJack F Vogel
7010ecc2ff0SJack F Vogel out:
7020ecc2ff0SJack F Vogel *link_up = !mac->get_link_status;
7030ecc2ff0SJack F Vogel return ret_val;
7040ecc2ff0SJack F Vogel }
7050ecc2ff0SJack F Vogel
7060ecc2ff0SJack F Vogel /**
7070ecc2ff0SJack F Vogel * ixgbevf_rlpml_set_vf - Set the maximum receive packet length
7080ecc2ff0SJack F Vogel * @hw: pointer to the HW structure
7090ecc2ff0SJack F Vogel * @max_size: value to assign to max frame size
7100ecc2ff0SJack F Vogel **/
ixgbevf_rlpml_set_vf(struct ixgbe_hw * hw,u16 max_size)7118eb6488eSEric Joyner s32 ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size)
7120ecc2ff0SJack F Vogel {
7130ecc2ff0SJack F Vogel u32 msgbuf[2];
7148eb6488eSEric Joyner s32 retval;
7150ecc2ff0SJack F Vogel
7160ecc2ff0SJack F Vogel msgbuf[0] = IXGBE_VF_SET_LPE;
7170ecc2ff0SJack F Vogel msgbuf[1] = max_size;
7188eb6488eSEric Joyner
7198eb6488eSEric Joyner retval = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
7208eb6488eSEric Joyner if (retval)
7218eb6488eSEric Joyner return retval;
7228eb6488eSEric Joyner if ((msgbuf[0] & IXGBE_VF_SET_LPE) &&
72310746040SJakub Chylkowski (msgbuf[0] & IXGBE_VT_MSGTYPE_FAILURE))
7248eb6488eSEric Joyner return IXGBE_ERR_MBX;
7258eb6488eSEric Joyner
7268eb6488eSEric Joyner return 0;
7270ecc2ff0SJack F Vogel }
7280ecc2ff0SJack F Vogel
7290ecc2ff0SJack F Vogel /**
7300ecc2ff0SJack F Vogel * ixgbevf_negotiate_api_version - Negotiate supported API version
7310ecc2ff0SJack F Vogel * @hw: pointer to the HW structure
7320ecc2ff0SJack F Vogel * @api: integer containing requested API version
7330ecc2ff0SJack F Vogel **/
ixgbevf_negotiate_api_version(struct ixgbe_hw * hw,int api)7340ecc2ff0SJack F Vogel int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api)
7350ecc2ff0SJack F Vogel {
7360ecc2ff0SJack F Vogel int err;
7370ecc2ff0SJack F Vogel u32 msg[3];
7380ecc2ff0SJack F Vogel
7390ecc2ff0SJack F Vogel /* Negotiate the mailbox API version */
7400ecc2ff0SJack F Vogel msg[0] = IXGBE_VF_API_NEGOTIATE;
7410ecc2ff0SJack F Vogel msg[1] = api;
7420ecc2ff0SJack F Vogel msg[2] = 0;
7430ecc2ff0SJack F Vogel
7448eb6488eSEric Joyner err = ixgbevf_write_msg_read_ack(hw, msg, msg, 3);
7450ecc2ff0SJack F Vogel if (!err) {
7460ecc2ff0SJack F Vogel msg[0] &= ~IXGBE_VT_MSGTYPE_CTS;
7470ecc2ff0SJack F Vogel
7480ecc2ff0SJack F Vogel /* Store value and return 0 on success */
74910746040SJakub Chylkowski if (msg[0] == (IXGBE_VF_API_NEGOTIATE | IXGBE_VT_MSGTYPE_SUCCESS)) {
7500ecc2ff0SJack F Vogel hw->api_version = api;
7510ecc2ff0SJack F Vogel return 0;
7520ecc2ff0SJack F Vogel }
7530ecc2ff0SJack F Vogel
7540ecc2ff0SJack F Vogel err = IXGBE_ERR_INVALID_ARGUMENT;
7550ecc2ff0SJack F Vogel }
7560ecc2ff0SJack F Vogel
7570ecc2ff0SJack F Vogel return err;
7580ecc2ff0SJack F Vogel }
7590ecc2ff0SJack F Vogel
ixgbevf_get_queues(struct ixgbe_hw * hw,unsigned int * num_tcs,unsigned int * default_tc)7600ecc2ff0SJack F Vogel int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
7610ecc2ff0SJack F Vogel unsigned int *default_tc)
7620ecc2ff0SJack F Vogel {
76348056c88SJack F Vogel int err;
76448056c88SJack F Vogel u32 msg[5];
76548056c88SJack F Vogel
76648056c88SJack F Vogel /* do nothing if API doesn't support ixgbevf_get_queues */
76748056c88SJack F Vogel switch (hw->api_version) {
76848056c88SJack F Vogel case ixgbe_mbox_api_11:
7698eb6488eSEric Joyner case ixgbe_mbox_api_12:
7708eb6488eSEric Joyner case ixgbe_mbox_api_13:
771*7234c309SJakub Chylkowski case ixgbe_mbox_api_15:
77248056c88SJack F Vogel break;
77348056c88SJack F Vogel default:
77448056c88SJack F Vogel return 0;
77548056c88SJack F Vogel }
77648056c88SJack F Vogel
77748056c88SJack F Vogel /* Fetch queue configuration from the PF */
77848056c88SJack F Vogel msg[0] = IXGBE_VF_GET_QUEUES;
77948056c88SJack F Vogel msg[1] = msg[2] = msg[3] = msg[4] = 0;
78048056c88SJack F Vogel
7818eb6488eSEric Joyner err = ixgbevf_write_msg_read_ack(hw, msg, msg, 5);
78248056c88SJack F Vogel if (!err) {
78348056c88SJack F Vogel msg[0] &= ~IXGBE_VT_MSGTYPE_CTS;
78448056c88SJack F Vogel
78548056c88SJack F Vogel /*
78610746040SJakub Chylkowski * if we we didn't get a SUCCESS there must have been
78748056c88SJack F Vogel * some sort of mailbox error so we should treat it
78848056c88SJack F Vogel * as such
78948056c88SJack F Vogel */
79010746040SJakub Chylkowski if (msg[0] != (IXGBE_VF_GET_QUEUES | IXGBE_VT_MSGTYPE_SUCCESS))
79148056c88SJack F Vogel return IXGBE_ERR_MBX;
79248056c88SJack F Vogel
79348056c88SJack F Vogel /* record and validate values from message */
79448056c88SJack F Vogel hw->mac.max_tx_queues = msg[IXGBE_VF_TX_QUEUES];
79548056c88SJack F Vogel if (hw->mac.max_tx_queues == 0 ||
79648056c88SJack F Vogel hw->mac.max_tx_queues > IXGBE_VF_MAX_TX_QUEUES)
79748056c88SJack F Vogel hw->mac.max_tx_queues = IXGBE_VF_MAX_TX_QUEUES;
79848056c88SJack F Vogel
79948056c88SJack F Vogel hw->mac.max_rx_queues = msg[IXGBE_VF_RX_QUEUES];
80048056c88SJack F Vogel if (hw->mac.max_rx_queues == 0 ||
80148056c88SJack F Vogel hw->mac.max_rx_queues > IXGBE_VF_MAX_RX_QUEUES)
80248056c88SJack F Vogel hw->mac.max_rx_queues = IXGBE_VF_MAX_RX_QUEUES;
80348056c88SJack F Vogel
80448056c88SJack F Vogel *num_tcs = msg[IXGBE_VF_TRANS_VLAN];
80548056c88SJack F Vogel /* in case of unknown state assume we cannot tag frames */
80648056c88SJack F Vogel if (*num_tcs > hw->mac.max_rx_queues)
80748056c88SJack F Vogel *num_tcs = 1;
80848056c88SJack F Vogel
80948056c88SJack F Vogel *default_tc = msg[IXGBE_VF_DEF_QUEUE];
81048056c88SJack F Vogel /* default to queue 0 on out-of-bounds queue number */
81148056c88SJack F Vogel if (*default_tc >= hw->mac.max_tx_queues)
81248056c88SJack F Vogel *default_tc = 0;
81348056c88SJack F Vogel }
81448056c88SJack F Vogel
81548056c88SJack F Vogel return err;
8161a4e3449SJack F Vogel }
817