Home | History | Annotate | Line # | Download | only in ixgbe
if_sriov.c revision 1.12
      1 /* $NetBSD: if_sriov.c,v 1.12 2021/12/10 11:18:30 msaitoh Exp $ */
      2 /******************************************************************************
      3 
      4   Copyright (c) 2001-2017, Intel Corporation
      5   All rights reserved.
      6 
      7   Redistribution and use in source and binary forms, with or without
      8   modification, are permitted provided that the following conditions are met:
      9 
     10    1. Redistributions of source code must retain the above copyright notice,
     11       this list of conditions and the following disclaimer.
     12 
     13    2. Redistributions in binary form must reproduce the above copyright
     14       notice, this list of conditions and the following disclaimer in the
     15       documentation and/or other materials provided with the distribution.
     16 
     17    3. Neither the name of the Intel Corporation nor the names of its
     18       contributors may be used to endorse or promote products derived from
     19       this software without specific prior written permission.
     20 
     21   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     22   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     25   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     26   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     27   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     28   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     29   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     31   POSSIBILITY OF SUCH DAMAGE.
     32 
     33 ******************************************************************************/
     34 /*$FreeBSD: head/sys/dev/ixgbe/if_sriov.c 327031 2017-12-20 18:15:06Z erj $*/
     35 
     36 #include <sys/cdefs.h>
     37 __KERNEL_RCSID(0, "$NetBSD: if_sriov.c,v 1.12 2021/12/10 11:18:30 msaitoh Exp $");
     38 
     39 #include "ixgbe.h"
     40 #include "ixgbe_sriov.h"
     41 
     42 #ifdef PCI_IOV
     43 
     44 MALLOC_DEFINE(M_IXGBE_SRIOV, "ix_sriov", "ix SR-IOV allocations");
     45 
     46 /************************************************************************
     47  * ixgbe_pci_iov_detach
     48  ************************************************************************/
     49 int
     50 ixgbe_pci_iov_detach(device_t dev)
     51 {
     52 	return pci_iov_detach(dev);
     53 }
     54 
     55 /************************************************************************
     56  * ixgbe_define_iov_schemas
     57  ************************************************************************/
     58 void
     59 ixgbe_define_iov_schemas(device_t dev, int *error)
     60 {
     61 	nvlist_t *pf_schema, *vf_schema;
     62 
     63 	pf_schema = pci_iov_schema_alloc_node();
     64 	vf_schema = pci_iov_schema_alloc_node();
     65 	pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL);
     66 	pci_iov_schema_add_bool(vf_schema, "mac-anti-spoof",
     67 	    IOV_SCHEMA_HASDEFAULT, TRUE);
     68 	pci_iov_schema_add_bool(vf_schema, "allow-set-mac",
     69 	    IOV_SCHEMA_HASDEFAULT, FALSE);
     70 	pci_iov_schema_add_bool(vf_schema, "allow-promisc",
     71 	    IOV_SCHEMA_HASDEFAULT, FALSE);
     72 	*error = pci_iov_attach(dev, pf_schema, vf_schema);
     73 	if (*error != 0) {
     74 		device_printf(dev,
     75 		    "Error %d setting up SR-IOV\n", *error);
     76 	}
     77 } /* ixgbe_define_iov_schemas */
     78 
     79 /************************************************************************
     80  * ixgbe_align_all_queue_indices
     81  ************************************************************************/
     82 inline void
     83 ixgbe_align_all_queue_indices(struct adapter *adapter)
     84 {
     85 	int i;
     86 	int index;
     87 
     88 	for (i = 0; i < adapter->num_queues; i++) {
     89 		index = ixgbe_vf_que_index(adapter->iov_mode, adapter->pool, i);
     90 		adapter->rx_rings[i].me = index;
     91 		adapter->tx_rings[i].me = index;
     92 	}
     93 }
     94 
     95 /* Support functions for SR-IOV/VF management */
     96 static inline void
     97 ixgbe_send_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg)
     98 {
     99 	if (vf->flags & IXGBE_VF_CTS)
    100 		msg |= IXGBE_VT_MSGTYPE_CTS;
    101 
    102 	adapter->hw.mbx.ops.write(&adapter->hw, &msg, 1, vf->pool);
    103 }
    104 
    105 static inline void
    106 ixgbe_send_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg)
    107 {
    108 	msg &= IXGBE_VT_MSG_MASK;
    109 	ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_ACK);
    110 }
    111 
    112 static inline void
    113 ixgbe_send_vf_nack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg)
    114 {
    115 	msg &= IXGBE_VT_MSG_MASK;
    116 	ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_NACK);
    117 }
    118 
    119 static inline void
    120 ixgbe_process_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf)
    121 {
    122 	if (!(vf->flags & IXGBE_VF_CTS))
    123 		ixgbe_send_vf_nack(adapter, vf, 0);
    124 }
    125 
    126 static inline bool
    127 ixgbe_vf_mac_changed(struct ixgbe_vf *vf, const uint8_t *mac)
    128 {
    129 	return (bcmp(mac, vf->ether_addr, ETHER_ADDR_LEN) != 0);
    130 }
    131 
    132 static inline int
    133 ixgbe_vf_queues(int mode)
    134 {
    135 	switch (mode) {
    136 	case IXGBE_64_VM:
    137 		return (2);
    138 	case IXGBE_32_VM:
    139 		return (4);
    140 	case IXGBE_NO_VM:
    141 	default:
    142 		return (0);
    143 	}
    144 }
    145 
    146 inline int
    147 ixgbe_vf_que_index(int mode, int vfnum, int num)
    148 {
    149 	return ((vfnum * ixgbe_vf_queues(mode)) + num);
    150 }
    151 
    152 static inline void
    153 ixgbe_update_max_frame(struct adapter * adapter, int max_frame)
    154 {
    155 	if (adapter->max_frame_size < max_frame)
    156 		adapter->max_frame_size = max_frame;
    157 }
    158 
    159 inline u32
    160 ixgbe_get_mrqc(int iov_mode)
    161 {
    162 	u32 mrqc;
    163 
    164 	switch (iov_mode) {
    165 	case IXGBE_64_VM:
    166 		mrqc = IXGBE_MRQC_VMDQRSS64EN;
    167 		break;
    168 	case IXGBE_32_VM:
    169 		mrqc = IXGBE_MRQC_VMDQRSS32EN;
    170 		break;
    171 	case IXGBE_NO_VM:
    172 		mrqc = 0;
    173 		break;
    174 	default:
    175 		panic("Unexpected SR-IOV mode %d", iov_mode);
    176 	}
    177 
    178 	return mrqc;
    179 }
    180 
    181 
    182 inline u32
    183 ixgbe_get_mtqc(int iov_mode)
    184 {
    185 	uint32_t mtqc;
    186 
    187 	switch (iov_mode) {
    188 	case IXGBE_64_VM:
    189 		mtqc = IXGBE_MTQC_64VF | IXGBE_MTQC_VT_ENA;
    190 		break;
    191 	case IXGBE_32_VM:
    192 		mtqc = IXGBE_MTQC_32VF | IXGBE_MTQC_VT_ENA;
    193 		break;
    194 	case IXGBE_NO_VM:
    195 		mtqc = IXGBE_MTQC_64Q_1PB;
    196 		break;
    197 	default:
    198 		panic("Unexpected SR-IOV mode %d", iov_mode);
    199 	}
    200 
    201 	return mtqc;
    202 }
    203 
    204 void
    205 ixgbe_ping_all_vfs(struct adapter *adapter)
    206 {
    207 	struct ixgbe_vf *vf;
    208 
    209 	for (int i = 0; i < adapter->num_vfs; i++) {
    210 		vf = &adapter->vfs[i];
    211 		if (vf->flags & IXGBE_VF_ACTIVE)
    212 			ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG);
    213 	}
    214 } /* ixgbe_ping_all_vfs */
    215 
    216 
    217 static void
    218 ixgbe_vf_set_default_vlan(struct adapter *adapter, struct ixgbe_vf *vf,
    219                           uint16_t tag)
    220 {
    221 	struct ixgbe_hw *hw;
    222 	uint32_t vmolr, vmvir;
    223 
    224 	hw = &adapter->hw;
    225 
    226 	vf->vlan_tag = tag;
    227 
    228 	vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf->pool));
    229 
    230 	/* Do not receive packets that pass inexact filters. */
    231 	vmolr &= ~(IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_ROPE);
    232 
    233 	/* Disable Multicast Promicuous Mode. */
    234 	vmolr &= ~IXGBE_VMOLR_MPE;
    235 
    236 	/* Accept broadcasts. */
    237 	vmolr |= IXGBE_VMOLR_BAM;
    238 
    239 	if (tag == 0) {
    240 		/* Accept non-vlan tagged traffic. */
    241 		vmolr |= IXGBE_VMOLR_AUPE;
    242 
    243 		/* Allow VM to tag outgoing traffic; no default tag. */
    244 		vmvir = 0;
    245 	} else {
    246 		/* Require vlan-tagged traffic. */
    247 		vmolr &= ~IXGBE_VMOLR_AUPE;
    248 
    249 		/* Tag all traffic with provided vlan tag. */
    250 		vmvir = (tag | IXGBE_VMVIR_VLANA_DEFAULT);
    251 	}
    252 	IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf->pool), vmolr);
    253 	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf->pool), vmvir);
    254 } /* ixgbe_vf_set_default_vlan */
    255 
    256 
    257 static void
    258 ixgbe_clear_vfmbmem(struct ixgbe_hw *hw, struct ixgbe_vf *vf)
    259 {
    260 	uint32_t vf_index = IXGBE_VF_INDEX(vf->pool);
    261 	uint16_t mbx_size = hw->mbx.size;
    262 	uint16_t i;
    263 
    264 	IXGBE_CORE_LOCK_ASSERT(adapter);
    265 
    266 	for (i = 0; i < mbx_size; ++i)
    267 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_index), i, 0x0);
    268 } /* ixgbe_clear_vfmbmem */
    269 
    270 
    271 static bool
    272 ixgbe_vf_frame_size_compatible(struct adapter *adapter, struct ixgbe_vf *vf)
    273 {
    274 
    275 	/*
    276 	 * Frame size compatibility between PF and VF is only a problem on
    277 	 * 82599-based cards.  X540 and later support any combination of jumbo
    278 	 * frames on PFs and VFs.
    279 	 */
    280 	if (adapter->hw.mac.type != ixgbe_mac_82599EB)
    281 		return (TRUE);
    282 
    283 	switch (vf->api_ver) {
    284 	case IXGBE_API_VER_1_0:
    285 	case IXGBE_API_VER_UNKNOWN:
    286 		/*
    287 		 * On legacy (1.0 and older) VF versions, we don't support jumbo
    288 		 * frames on either the PF or the VF.
    289 		 */
    290 		if (adapter->max_frame_size > ETHER_MAX_LEN ||
    291 		    vf->max_frame_size > ETHER_MAX_LEN)
    292 			return (FALSE);
    293 
    294 		return (TRUE);
    295 
    296 		break;
    297 	case IXGBE_API_VER_1_1:
    298 	default:
    299 		/*
    300 		 * 1.1 or later VF versions always work if they aren't using
    301 		 * jumbo frames.
    302 		 */
    303 		if (vf->max_frame_size <= ETHER_MAX_LEN)
    304 			return (TRUE);
    305 
    306 		/*
    307 		 * Jumbo frames only work with VFs if the PF is also using jumbo
    308 		 * frames.
    309 		 */
    310 		if (adapter->max_frame_size <= ETHER_MAX_LEN)
    311 			return (TRUE);
    312 
    313 		return (FALSE);
    314 	}
    315 } /* ixgbe_vf_frame_size_compatible */
    316 
    317 
    318 static void
    319 ixgbe_process_vf_reset(struct adapter *adapter, struct ixgbe_vf *vf)
    320 {
    321 	ixgbe_vf_set_default_vlan(adapter, vf, vf->default_vlan);
    322 
    323 	// XXX clear multicast addresses
    324 
    325 	ixgbe_clear_rar(&adapter->hw, vf->rar_index);
    326 	ixgbe_clear_vfmbmem(&adapter->hw, vf);
    327 	ixgbe_toggle_txdctl(&adapter->hw, IXGBE_VF_INDEX(vf->pool));
    328 
    329 	vf->api_ver = IXGBE_API_VER_UNKNOWN;
    330 } /* ixgbe_process_vf_reset */
    331 
    332 
    333 static void
    334 ixgbe_vf_enable_transmit(struct adapter *adapter, struct ixgbe_vf *vf)
    335 {
    336 	struct ixgbe_hw *hw;
    337 	uint32_t vf_index, vfte;
    338 
    339 	hw = &adapter->hw;
    340 
    341 	vf_index = IXGBE_VF_INDEX(vf->pool);
    342 	vfte = IXGBE_READ_REG(hw, IXGBE_VFTE(vf_index));
    343 	vfte |= IXGBE_VF_BIT(vf->pool);
    344 	IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_index), vfte);
    345 } /* ixgbe_vf_enable_transmit */
    346 
    347 
    348 static void
    349 ixgbe_vf_enable_receive(struct adapter *adapter, struct ixgbe_vf *vf)
    350 {
    351 	struct ixgbe_hw *hw;
    352 	uint32_t vf_index, vfre;
    353 
    354 	hw = &adapter->hw;
    355 
    356 	vf_index = IXGBE_VF_INDEX(vf->pool);
    357 	vfre = IXGBE_READ_REG(hw, IXGBE_VFRE(vf_index));
    358 	if (ixgbe_vf_frame_size_compatible(adapter, vf))
    359 		vfre |= IXGBE_VF_BIT(vf->pool);
    360 	else
    361 		vfre &= ~IXGBE_VF_BIT(vf->pool);
    362 	IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_index), vfre);
    363 } /* ixgbe_vf_enable_receive */
    364 
    365 
    366 static void
    367 ixgbe_vf_reset_msg(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
    368 {
    369 	struct ixgbe_hw *hw;
    370 	uint32_t ack;
    371 	uint32_t resp[IXGBE_VF_PERMADDR_MSG_LEN];
    372 
    373 	hw = &adapter->hw;
    374 
    375 	ixgbe_process_vf_reset(adapter, vf);
    376 
    377 	if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) {
    378 		ixgbe_set_rar(&adapter->hw, vf->rar_index, vf->ether_addr,
    379 		    vf->pool, TRUE);
    380 		ack = IXGBE_VT_MSGTYPE_ACK;
    381 	} else
    382 		ack = IXGBE_VT_MSGTYPE_NACK;
    383 
    384 	ixgbe_vf_enable_transmit(adapter, vf);
    385 	ixgbe_vf_enable_receive(adapter, vf);
    386 
    387 	vf->flags |= IXGBE_VF_CTS;
    388 
    389 	resp[0] = IXGBE_VF_RESET | ack;
    390 	bcopy(vf->ether_addr, &resp[1], ETHER_ADDR_LEN);
    391 	resp[3] = hw->mac.mc_filter_type;
    392 	hw->mbx.ops.write(hw, resp, IXGBE_VF_PERMADDR_MSG_LEN, vf->pool);
    393 } /* ixgbe_vf_reset_msg */
    394 
    395 
    396 static void
    397 ixgbe_vf_set_mac(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
    398 {
    399 	uint8_t *mac;
    400 
    401 	mac = (uint8_t*)&msg[1];
    402 
    403 	/* Check that the VF has permission to change the MAC address. */
    404 	if (!(vf->flags & IXGBE_VF_CAP_MAC) && ixgbe_vf_mac_changed(vf, mac)) {
    405 		ixgbe_send_vf_nack(adapter, vf, msg[0]);
    406 		return;
    407 	}
    408 
    409 	if (ixgbe_validate_mac_addr(mac) != 0) {
    410 		ixgbe_send_vf_nack(adapter, vf, msg[0]);
    411 		return;
    412 	}
    413 
    414 	bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN);
    415 
    416 	ixgbe_set_rar(&adapter->hw, vf->rar_index, vf->ether_addr, vf->pool,
    417 	    TRUE);
    418 
    419 	ixgbe_send_vf_ack(adapter, vf, msg[0]);
    420 } /* ixgbe_vf_set_mac */
    421 
    422 
    423 /*
    424  * VF multicast addresses are set by using the appropriate bit in
    425  * 1 of 128 32 bit addresses (4096 possible).
    426  */
    427 static void
    428 ixgbe_vf_set_mc_addr(struct adapter *adapter, struct ixgbe_vf *vf, u32 *msg)
    429 {
    430 	u16	*list = (u16*)&msg[1];
    431 	int	entries;
    432 	u32	vmolr, vec_bit, vec_reg, mta_reg;
    433 
    434 	entries = (msg[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
    435 	entries = uimin(entries, IXGBE_MAX_VF_MC);
    436 
    437 	vmolr = IXGBE_READ_REG(&adapter->hw, IXGBE_VMOLR(vf->pool));
    438 
    439 	vf->num_mc_hashes = entries;
    440 
    441 	/* Set the appropriate MTA bit */
    442 	for (int i = 0; i < entries; i++) {
    443 		vf->mc_hash[i] = list[i];
    444 		vec_reg = (vf->mc_hash[i] >> 5) & 0x7F;
    445 		vec_bit = vf->mc_hash[i] & 0x1F;
    446 		mta_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_MTA(vec_reg));
    447 		mta_reg |= (1 << vec_bit);
    448 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_MTA(vec_reg), mta_reg);
    449 	}
    450 
    451 	vmolr |= IXGBE_VMOLR_ROMPE;
    452 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_VMOLR(vf->pool), vmolr);
    453 	ixgbe_send_vf_ack(adapter, vf, msg[0]);
    454 } /* ixgbe_vf_set_mc_addr */
    455 
    456 
    457 static void
    458 ixgbe_vf_set_vlan(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
    459 {
    460 	struct ixgbe_hw *hw;
    461 	int enable;
    462 	uint16_t tag;
    463 
    464 	hw = &adapter->hw;
    465 	enable = IXGBE_VT_MSGINFO(msg[0]);
    466 	tag = msg[1] & IXGBE_VLVF_VLANID_MASK;
    467 
    468 	if (!(vf->flags & IXGBE_VF_CAP_VLAN)) {
    469 		ixgbe_send_vf_nack(adapter, vf, msg[0]);
    470 		return;
    471 	}
    472 
    473 	/* It is illegal to enable vlan tag 0. */
    474 	if (tag == 0 && enable != 0) {
    475 		ixgbe_send_vf_nack(adapter, vf, msg[0]);
    476 		return;
    477 	}
    478 
    479 	ixgbe_set_vfta(hw, tag, vf->pool, enable, false);
    480 	ixgbe_send_vf_ack(adapter, vf, msg[0]);
    481 } /* ixgbe_vf_set_vlan */
    482 
    483 
    484 static void
    485 ixgbe_vf_set_lpe(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
    486 {
    487 	struct ixgbe_hw *hw;
    488 	uint32_t vf_max_size, pf_max_size, mhadd;
    489 
    490 	hw = &adapter->hw;
    491 	vf_max_size = msg[1];
    492 
    493 	if (vf_max_size < ETHER_CRC_LEN) {
    494 		/* We intentionally ACK invalid LPE requests. */
    495 		ixgbe_send_vf_ack(adapter, vf, msg[0]);
    496 		return;
    497 	}
    498 
    499 	vf_max_size -= ETHER_CRC_LEN;
    500 
    501 	if (vf_max_size > IXGBE_MAX_FRAME_SIZE) {
    502 		/* We intentionally ACK invalid LPE requests. */
    503 		ixgbe_send_vf_ack(adapter, vf, msg[0]);
    504 		return;
    505 	}
    506 
    507 	vf->max_frame_size = vf_max_size;
    508 	ixgbe_update_max_frame(adapter, vf->max_frame_size);
    509 
    510 	/*
    511 	 * We might have to disable reception to this VF if the frame size is
    512 	 * not compatible with the config on the PF.
    513 	 */
    514 	ixgbe_vf_enable_receive(adapter, vf);
    515 
    516 	mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
    517 	pf_max_size = (mhadd & IXGBE_MHADD_MFS_MASK) >> IXGBE_MHADD_MFS_SHIFT;
    518 
    519 	if (pf_max_size < adapter->max_frame_size) {
    520 		mhadd &= ~IXGBE_MHADD_MFS_MASK;
    521 		mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT;
    522 		IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd);
    523 	}
    524 
    525 	ixgbe_send_vf_ack(adapter, vf, msg[0]);
    526 } /* ixgbe_vf_set_lpe */
    527 
    528 
    529 static void
    530 ixgbe_vf_set_macvlan(struct adapter *adapter, struct ixgbe_vf *vf,
    531                      uint32_t *msg)
    532 {
    533 	//XXX implement this
    534 	ixgbe_send_vf_nack(adapter, vf, msg[0]);
    535 } /* ixgbe_vf_set_macvlan */
    536 
    537 
    538 static void
    539 ixgbe_vf_api_negotiate(struct adapter *adapter, struct ixgbe_vf *vf,
    540     uint32_t *msg)
    541 {
    542 
    543 	switch (msg[1]) {
    544 	case IXGBE_API_VER_1_0:
    545 	case IXGBE_API_VER_1_1:
    546 		vf->api_ver = msg[1];
    547 		ixgbe_send_vf_ack(adapter, vf, msg[0]);
    548 		break;
    549 	default:
    550 		vf->api_ver = IXGBE_API_VER_UNKNOWN;
    551 		ixgbe_send_vf_nack(adapter, vf, msg[0]);
    552 		break;
    553 	}
    554 } /* ixgbe_vf_api_negotiate */
    555 
    556 
    557 static void
    558 ixgbe_vf_get_queues(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
    559 {
    560 	struct ixgbe_hw *hw;
    561 	uint32_t resp[IXGBE_VF_GET_QUEUES_RESP_LEN];
    562 	int num_queues;
    563 
    564 	hw = &adapter->hw;
    565 
    566 	/* GET_QUEUES is not supported on pre-1.1 APIs. */
    567 	switch (msg[0]) {
    568 	case IXGBE_API_VER_1_0:
    569 	case IXGBE_API_VER_UNKNOWN:
    570 		ixgbe_send_vf_nack(adapter, vf, msg[0]);
    571 		return;
    572 	}
    573 
    574 	resp[0] = IXGBE_VF_GET_QUEUES | IXGBE_VT_MSGTYPE_ACK |
    575 	    IXGBE_VT_MSGTYPE_CTS;
    576 
    577 	num_queues = ixgbe_vf_queues(adapter->iov_mode);
    578 	resp[IXGBE_VF_TX_QUEUES] = num_queues;
    579 	resp[IXGBE_VF_RX_QUEUES] = num_queues;
    580 	resp[IXGBE_VF_TRANS_VLAN] = (vf->default_vlan != 0);
    581 	resp[IXGBE_VF_DEF_QUEUE] = 0;
    582 
    583 	hw->mbx.ops.write(hw, resp, IXGBE_VF_GET_QUEUES_RESP_LEN, vf->pool);
    584 } /* ixgbe_vf_get_queues */
    585 
    586 
    587 static void
    588 ixgbe_process_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf)
    589 {
    590 	struct ixgbe_hw *hw;
    591 	uint32_t msg[IXGBE_VFMAILBOX_SIZE];
    592 	int error;
    593 
    594 	hw = &adapter->hw;
    595 
    596 	error = hw->mbx.ops.read(hw, msg, IXGBE_VFMAILBOX_SIZE, vf->pool);
    597 
    598 	if (error != 0)
    599 		return;
    600 
    601 	CTR3(KTR_MALLOC, "%s: received msg %x from %d", adapter->ifp->if_xname,
    602 	    msg[0], vf->pool);
    603 	if (msg[0] == IXGBE_VF_RESET) {
    604 		ixgbe_vf_reset_msg(adapter, vf, msg);
    605 		return;
    606 	}
    607 
    608 	if (!(vf->flags & IXGBE_VF_CTS)) {
    609 		ixgbe_send_vf_nack(adapter, vf, msg[0]);
    610 		return;
    611 	}
    612 
    613 	switch (msg[0] & IXGBE_VT_MSG_MASK) {
    614 	case IXGBE_VF_SET_MAC_ADDR:
    615 		ixgbe_vf_set_mac(adapter, vf, msg);
    616 		break;
    617 	case IXGBE_VF_SET_MULTICAST:
    618 		ixgbe_vf_set_mc_addr(adapter, vf, msg);
    619 		break;
    620 	case IXGBE_VF_SET_VLAN:
    621 		ixgbe_vf_set_vlan(adapter, vf, msg);
    622 		break;
    623 	case IXGBE_VF_SET_LPE:
    624 		ixgbe_vf_set_lpe(adapter, vf, msg);
    625 		break;
    626 	case IXGBE_VF_SET_MACVLAN:
    627 		ixgbe_vf_set_macvlan(adapter, vf, msg);
    628 		break;
    629 	case IXGBE_VF_API_NEGOTIATE:
    630 		ixgbe_vf_api_negotiate(adapter, vf, msg);
    631 		break;
    632 	case IXGBE_VF_GET_QUEUES:
    633 		ixgbe_vf_get_queues(adapter, vf, msg);
    634 		break;
    635 	default:
    636 		ixgbe_send_vf_nack(adapter, vf, msg[0]);
    637 	}
    638 } /* ixgbe_process_vf_msg */
    639 
    640 
    641 /* Tasklet for handling VF -> PF mailbox messages */
    642 void
    643 ixgbe_handle_mbx(void *context)
    644 {
    645 	struct adapter *adapter = context;
    646 	struct ixgbe_hw *hw;
    647 	struct ixgbe_vf *vf;
    648 	int i;
    649 
    650 	KASSERT(mutex_owned(&adapter->core_mtx));
    651 
    652 	hw = &adapter->hw;
    653 
    654 	for (i = 0; i < adapter->num_vfs; i++) {
    655 		vf = &adapter->vfs[i];
    656 
    657 		if (vf->flags & IXGBE_VF_ACTIVE) {
    658 			if (hw->mbx.ops.check_for_rst(hw, vf->pool) == 0)
    659 				ixgbe_process_vf_reset(adapter, vf);
    660 
    661 			if (hw->mbx.ops.check_for_msg(hw, vf->pool) == 0)
    662 				ixgbe_process_vf_msg(adapter, vf);
    663 
    664 			if (hw->mbx.ops.check_for_ack(hw, vf->pool) == 0)
    665 				ixgbe_process_vf_ack(adapter, vf);
    666 		}
    667 	}
    668 } /* ixgbe_handle_mbx */
    669 
    670 int
    671 ixgbe_init_iov(device_t dev, u16 num_vfs, const nvlist_t *config)
    672 {
    673 	struct adapter *adapter;
    674 	int retval = 0;
    675 
    676 	adapter = device_get_softc(dev);
    677 	adapter->iov_mode = IXGBE_NO_VM;
    678 
    679 	if (num_vfs == 0) {
    680 		/* Would we ever get num_vfs = 0? */
    681 		retval = EINVAL;
    682 		goto err_init_iov;
    683 	}
    684 
    685 	/*
    686 	 * We've got to reserve a VM's worth of queues for the PF,
    687 	 * thus we go into "64 VF mode" if 32+ VFs are requested.
    688 	 * With 64 VFs, you can only have two queues per VF.
    689 	 * With 32 VFs, you can have up to four queues per VF.
    690 	 */
    691 	if (num_vfs >= IXGBE_32_VM)
    692 		adapter->iov_mode = IXGBE_64_VM;
    693 	else
    694 		adapter->iov_mode = IXGBE_32_VM;
    695 
    696 	/* Again, reserving 1 VM's worth of queues for the PF */
    697 	adapter->pool = adapter->iov_mode - 1;
    698 
    699 	if ((num_vfs > adapter->pool) || (num_vfs >= IXGBE_64_VM)) {
    700 		retval = ENOSPC;
    701 		goto err_init_iov;
    702 	}
    703 
    704 	IXGBE_CORE_LOCK(adapter);
    705 
    706 	adapter->vfs = malloc(sizeof(*adapter->vfs) * num_vfs, M_IXGBE_SRIOV,
    707 	    M_NOWAIT | M_ZERO);
    708 
    709 	if (adapter->vfs == NULL) {
    710 		retval = ENOMEM;
    711 		IXGBE_CORE_UNLOCK(adapter);
    712 		goto err_init_iov;
    713 	}
    714 
    715 	adapter->num_vfs = num_vfs;
    716 
    717 	/* set the SRIOV flag now as it's needed
    718 	 * by ixgbe_init_locked() */
    719 	adapter->feat_en |= IXGBE_FEATURE_SRIOV;
    720 	adapter->init_locked(adapter);
    721 
    722 	IXGBE_CORE_UNLOCK(adapter);
    723 
    724 	return (retval);
    725 
    726 err_init_iov:
    727 	adapter->num_vfs = 0;
    728 	adapter->pool = 0;
    729 	adapter->iov_mode = IXGBE_NO_VM;
    730 
    731 	return (retval);
    732 } /* ixgbe_init_iov */
    733 
    734 void
    735 ixgbe_uninit_iov(device_t dev)
    736 {
    737 	struct ixgbe_hw *hw;
    738 	struct adapter *adapter;
    739 	uint32_t pf_reg, vf_reg;
    740 
    741 	adapter = device_get_softc(dev);
    742 	hw = &adapter->hw;
    743 
    744 	IXGBE_CORE_LOCK(adapter);
    745 
    746 	/* Enable rx/tx for the PF and disable it for all VFs. */
    747 	pf_reg = IXGBE_VF_INDEX(adapter->pool);
    748 	IXGBE_WRITE_REG(hw, IXGBE_VFRE(pf_reg), IXGBE_VF_BIT(adapter->pool));
    749 	IXGBE_WRITE_REG(hw, IXGBE_VFTE(pf_reg), IXGBE_VF_BIT(adapter->pool));
    750 
    751 	if (pf_reg == 0)
    752 		vf_reg = 1;
    753 	else
    754 		vf_reg = 0;
    755 	IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), 0);
    756 	IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), 0);
    757 
    758 	IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, 0);
    759 
    760 	free(adapter->vfs, M_IXGBE_SRIOV);
    761 	adapter->vfs = NULL;
    762 	adapter->num_vfs = 0;
    763 	adapter->feat_en &= ~IXGBE_FEATURE_SRIOV;
    764 
    765 	IXGBE_CORE_UNLOCK(adapter);
    766 } /* ixgbe_uninit_iov */
    767 
    768 static void
    769 ixgbe_init_vf(struct adapter *adapter, struct ixgbe_vf *vf)
    770 {
    771 	struct ixgbe_hw *hw;
    772 	uint32_t vf_index, pfmbimr;
    773 
    774 	IXGBE_CORE_LOCK_ASSERT(adapter);
    775 
    776 	hw = &adapter->hw;
    777 
    778 	if (!(vf->flags & IXGBE_VF_ACTIVE))
    779 		return;
    780 
    781 	vf_index = IXGBE_VF_INDEX(vf->pool);
    782 	pfmbimr = IXGBE_READ_REG(hw, IXGBE_PFMBIMR(vf_index));
    783 	pfmbimr |= IXGBE_VF_BIT(vf->pool);
    784 	IXGBE_WRITE_REG(hw, IXGBE_PFMBIMR(vf_index), pfmbimr);
    785 
    786 	ixgbe_vf_set_default_vlan(adapter, vf, vf->vlan_tag);
    787 
    788 	// XXX multicast addresses
    789 
    790 	if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) {
    791 		ixgbe_set_rar(&adapter->hw, vf->rar_index,
    792 		    vf->ether_addr, vf->pool, TRUE);
    793 	}
    794 
    795 	ixgbe_vf_enable_transmit(adapter, vf);
    796 	ixgbe_vf_enable_receive(adapter, vf);
    797 
    798 	ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG);
    799 } /* ixgbe_init_vf */
    800 
    801 void
    802 ixgbe_initialize_iov(struct adapter *adapter)
    803 {
    804 	struct ixgbe_hw *hw = &adapter->hw;
    805 	uint32_t mrqc, mtqc, vt_ctl, vf_reg, gcr_ext, gpie;
    806 	int i;
    807 
    808 	if (adapter->iov_mode == IXGBE_NO_VM)
    809 		return;
    810 
    811 	IXGBE_CORE_LOCK_ASSERT(adapter);
    812 
    813 	/* RMW appropriate registers based on IOV mode */
    814 	/* Read... */
    815 	mrqc    = IXGBE_READ_REG(hw, IXGBE_MRQC);
    816 	gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
    817 	gpie    = IXGBE_READ_REG(hw, IXGBE_GPIE);
    818 	/* Modify... */
    819 	mrqc    &= ~IXGBE_MRQC_MRQE_MASK;
    820 	mtqc     =  IXGBE_MTQC_VT_ENA;      /* No initial MTQC read needed */
    821 	gcr_ext |=  IXGBE_GCR_EXT_MSIX_EN;
    822 	gcr_ext &= ~IXGBE_GCR_EXT_VT_MODE_MASK;
    823 	gpie    &= ~IXGBE_GPIE_VTMODE_MASK;
    824 	switch (adapter->iov_mode) {
    825 	case IXGBE_64_VM:
    826 		mrqc    |= IXGBE_MRQC_VMDQRSS64EN;
    827 		mtqc    |= IXGBE_MTQC_64VF;
    828 		gcr_ext |= IXGBE_GCR_EXT_VT_MODE_64;
    829 		gpie    |= IXGBE_GPIE_VTMODE_64;
    830 		break;
    831 	case IXGBE_32_VM:
    832 		mrqc    |= IXGBE_MRQC_VMDQRSS32EN;
    833 		mtqc    |= IXGBE_MTQC_32VF;
    834 		gcr_ext |= IXGBE_GCR_EXT_VT_MODE_32;
    835 		gpie    |= IXGBE_GPIE_VTMODE_32;
    836 		break;
    837 	default:
    838 		panic("Unexpected SR-IOV mode %d", adapter->iov_mode);
    839 	}
    840 	/* Write... */
    841 	IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
    842 	IXGBE_WRITE_REG(hw, IXGBE_MTQC, mtqc);
    843 	IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
    844 	IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
    845 
    846 	/* Enable rx/tx for the PF. */
    847 	vf_reg = IXGBE_VF_INDEX(adapter->pool);
    848 	IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), IXGBE_VF_BIT(adapter->pool));
    849 	IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), IXGBE_VF_BIT(adapter->pool));
    850 
    851 	/* Allow VM-to-VM communication. */
    852 	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
    853 
    854 	vt_ctl = IXGBE_VT_CTL_VT_ENABLE | IXGBE_VT_CTL_REPLEN;
    855 	vt_ctl |= (adapter->pool << IXGBE_VT_CTL_POOL_SHIFT);
    856 	IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vt_ctl);
    857 
    858 	for (i = 0; i < adapter->num_vfs; i++)
    859 		ixgbe_init_vf(adapter, &adapter->vfs[i]);
    860 } /* ixgbe_initialize_iov */
    861 
    862 
    863 /* Check the max frame setting of all active VF's */
    864 void
    865 ixgbe_recalculate_max_frame(struct adapter *adapter)
    866 {
    867 	struct ixgbe_vf *vf;
    868 
    869 	IXGBE_CORE_LOCK_ASSERT(adapter);
    870 
    871 	for (int i = 0; i < adapter->num_vfs; i++) {
    872 		vf = &adapter->vfs[i];
    873 		if (vf->flags & IXGBE_VF_ACTIVE)
    874 			ixgbe_update_max_frame(adapter, vf->max_frame_size);
    875 	}
    876 } /* ixgbe_recalculate_max_frame */
    877 
    878 int
    879 ixgbe_add_vf(device_t dev, u16 vfnum, const nvlist_t *config)
    880 {
    881 	struct adapter *adapter;
    882 	struct ixgbe_vf *vf;
    883 	const void *mac;
    884 
    885 	adapter = device_get_softc(dev);
    886 
    887 	KASSERT(vfnum < adapter->num_vfs, ("VF index %d is out of range %d",
    888 	    vfnum, adapter->num_vfs));
    889 
    890 	IXGBE_CORE_LOCK(adapter);
    891 	vf = &adapter->vfs[vfnum];
    892 	vf->pool= vfnum;
    893 
    894 	/* RAR[0] is used by the PF so use vfnum + 1 for VF RAR. */
    895 	vf->rar_index = vfnum + 1;
    896 	vf->default_vlan = 0;
    897 	vf->max_frame_size = ETHER_MAX_LEN;
    898 	ixgbe_update_max_frame(adapter, vf->max_frame_size);
    899 
    900 	if (nvlist_exists_binary(config, "mac-addr")) {
    901 		mac = nvlist_get_binary(config, "mac-addr", NULL);
    902 		bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN);
    903 		if (nvlist_get_bool(config, "allow-set-mac"))
    904 			vf->flags |= IXGBE_VF_CAP_MAC;
    905 	} else
    906 		/*
    907 		 * If the administrator has not specified a MAC address then
    908 		 * we must allow the VF to choose one.
    909 		 */
    910 		vf->flags |= IXGBE_VF_CAP_MAC;
    911 
    912 	vf->flags |= IXGBE_VF_ACTIVE;
    913 
    914 	ixgbe_init_vf(adapter, vf);
    915 	IXGBE_CORE_UNLOCK(adapter);
    916 
    917 	return (0);
    918 } /* ixgbe_add_vf */
    919 
    920 #else
    921 
    922 void
    923 ixgbe_handle_mbx(void *context)
    924 {
    925 	UNREFERENCED_1PARAMETER(context);
    926 } /* ixgbe_handle_mbx */
    927 
    928 inline int
    929 ixgbe_vf_que_index(int mode, int vfnum, int num)
    930 {
    931 	UNREFERENCED_2PARAMETER(mode, vfnum);
    932 
    933 	return num;
    934 } /* ixgbe_vf_que_index */
    935 
    936 #endif
    937