/* On Hyper-V, to reset, we need to read from this offset *fromthePCIconfigspace.Thisisthemechanismusedon *Hyper-VtosupportPF/VFcommunication.
*/ #define IXGBE_HV_RESET_OFFSET 0x201
/* Call adapter stop to disable tx/rx and clear interrupts */
hw->mac.ops.stop_adapter(hw);
/* reset the api version */
hw->api_version = ixgbe_mbox_api_10;
hw->mbx.ops.init_params(hw);
memcpy(&hw->mbx.ops, &ixgbevf_mbx_ops_legacy, sizeof(struct ixgbe_mbx_operations));
/* set our "perm_addr" based on info provided by PF *alsosetupthemc_filter_typewhichispiggybacked *onthemacaddressinword3
*/
ret_val = ixgbevf_poll_mbx(hw, msgbuf, IXGBE_VF_PERMADDR_MSG_LEN); if (ret_val) return ret_val;
/* New versions of the PF may NACK the reset return message *toindicatethatnoMACaddresshasyetbeenassignedfor *theVF.
*/ if (msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_SUCCESS) &&
msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_FAILURE)) return IXGBE_ERR_INVALID_MAC_ADDR;
if (msgbuf[0] == (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_SUCCESS))
ether_addr_copy(hw->mac.perm_addr, addr);
for (i = 0; i < 6; i++)
pci_read_config_byte(adapter->pdev,
(i + IXGBE_HV_RESET_OFFSET),
&hw->mac.perm_addr[i]); return0; #else
pr_err("PCI_MMCONFIG needs to be enabled for Hyper-V\n"); return -EOPNOTSUPP; #endif
}
/* Set the adapter_stopped flag so other driver functions stop touching *thehardware
*/
hw->adapter_stopped = true;
/* Disable the receive unit by stopped each queue */
number_of_queues = hw->mac.max_rx_queues; for (i = 0; i < number_of_queues; i++) {
reg_val = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); if (reg_val & IXGBE_RXDCTL_ENABLE) {
reg_val &= ~IXGBE_RXDCTL_ENABLE;
IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), reg_val);
}
}
IXGBE_WRITE_FLUSH(hw);
/* Clear interrupt mask to stop from interrupts being generated */
IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, IXGBE_VF_IRQ_CLEAR_MASK);
/* Clear any pending interrupts */
IXGBE_READ_REG(hw, IXGBE_VTEICR);
/* Disable the transmit unit. Each queue must be disabled. */
number_of_queues = hw->mac.max_tx_queues; for (i = 0; i < number_of_queues; i++) {
reg_val = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); if (reg_val & IXGBE_TXDCTL_ENABLE) {
reg_val &= ~IXGBE_TXDCTL_ENABLE;
IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), reg_val);
}
}
memset(msgbuf, 0, sizeof(msgbuf)); /* If index is one then this is the start of a new list and needs *indicationtothePFsoitcandoitsownlistmanagement. *IfitiszerothenthattellsthePFtojustclearallof *thisVF'smacvlansandthereisnonewlist.
*/
msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
msgbuf_chk = msgbuf[0];
/** *ixgbevf_get_reta_locked-gettheRSSredirectiontable(RETA)contents. *@hw:pointertohardwarestructure *@reta:buffertofillwithRETAcontents. *@num_rx_queues:NumberofRxqueuesconfiguredforthisport * *The"reta"buffershouldbebigenoughtocontain32registers. * *Returns:0onsuccess. *ifAPIdoesn'tsupportthisoperation-(-EOPNOTSUPP).
*/ int ixgbevf_get_reta_locked(struct ixgbe_hw *hw, u32 *reta, int num_rx_queues)
{ int err, i, j;
u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
u32 *hw_reta = &msgbuf[1];
u32 mask = 0;
/* We have to use a mailbox for 82599 and x540 devices only. *ForthesedevicesRETAhas128entries. *AlsotheseVFssupportupto4RSSqueues.ThereforePFwillcompress *16RETAentriesineachDWORDgiving2bitstoeachentry.
*/ int dwords = IXGBEVF_82599_RETA_SIZE / 16;
/* We support the RSS querying for 82599 and x540 devices only. *ThusreturnanerrorifAPIdoesn'tsupportRETAqueryingorquerying *isnotsupportedforthisdevicetype.
*/ switch (hw->api_version) { case ixgbe_mbox_api_17: case ixgbe_mbox_api_16: case ixgbe_mbox_api_15: case ixgbe_mbox_api_14: case ixgbe_mbox_api_13: case ixgbe_mbox_api_12: if (hw->mac.type < ixgbe_mac_X550_vf) break;
fallthrough; default: return -EOPNOTSUPP;
}
msgbuf[0] = IXGBE_VF_GET_RETA;
err = ixgbevf_write_mbx(hw, msgbuf, 1);
if (err) return err;
err = ixgbevf_poll_mbx(hw, msgbuf, dwords + 1);
if (err) return err;
msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
/* If the operation has been refused by a PF return -EPERM */ if (msgbuf[0] == (IXGBE_VF_GET_RETA | IXGBE_VT_MSGTYPE_FAILURE)) return -EPERM;
/* If we didn't get an ACK there must have been *somesortofmailboxerrorsoweshouldtreatit *assuch.
*/ if (msgbuf[0] != (IXGBE_VF_GET_RETA | IXGBE_VT_MSGTYPE_SUCCESS)) return IXGBE_ERR_MBX;
/* ixgbevf doesn't support more than 2 queues at the moment */ if (num_rx_queues > 1)
mask = 0x1;
for (i = 0; i < dwords; i++) for (j = 0; j < 16; j++)
reta[i * 16 + j] = (hw_reta[i] >> (2 * j)) & mask;
/* We currently support the RSS Random Key retrieval for 82599 and x540 *devicesonly. * *ThusreturnanerrorifAPIdoesn'tsupportRSSRandomKeyretrieval *oriftheoperationisnotsupportedforthisdevicetype.
*/ switch (hw->api_version) { case ixgbe_mbox_api_17: case ixgbe_mbox_api_16: case ixgbe_mbox_api_15: case ixgbe_mbox_api_14: case ixgbe_mbox_api_13: case ixgbe_mbox_api_12: if (hw->mac.type < ixgbe_mac_X550_vf) break;
fallthrough; default: return -EOPNOTSUPP;
}
/* If the operation has been refused by a PF return -EPERM */ if (msgbuf[0] == (IXGBE_VF_GET_RSS_KEY | IXGBE_VT_MSGTYPE_FAILURE)) return -EPERM;
/* If we didn't get an ACK there must have been *somesortofmailboxerrorsoweshouldtreatit *assuch.
*/ if (msgbuf[0] != (IXGBE_VF_GET_RSS_KEY | IXGBE_VT_MSGTYPE_SUCCESS)) return IXGBE_ERR_MBX;
/* if nacked the address was rejected, use "perm_addr" */ if (!ret_val &&
(msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_FAILURE))) {
ixgbevf_get_mac_addr_vf(hw, hw->mac.addr); return IXGBE_ERR_MBX;
}
/* Each entry in the list uses 1 16 bit word. We have 30 *16bitwordsavailableinourHWmsgbuffer(minus1forthe *msgtype).That's30hashvaluesifwepack'emright.If *therearemorethan30MCaddressestoaddthenpuntthe *extrasfornowandthenaddcodetohandlemorethan30later. *Itwouldbeunusualforaservertorequestthatmanymulti-cast *addressesexceptforinlargeenterprisenetworkenvironments.
*/
switch (hw->api_version) { case ixgbe_mbox_api_12: /* promisc introduced in 1.3 version */ if (xcast_mode == IXGBEVF_XCAST_MODE_PROMISC) return -EOPNOTSUPP;
fallthrough; case ixgbe_mbox_api_13: case ixgbe_mbox_api_14: case ixgbe_mbox_api_15: case ixgbe_mbox_api_16: case ixgbe_mbox_api_17: break; default: return -EOPNOTSUPP;
}
switch (hw->api_version) { case ixgbe_mbox_api_16: case ixgbe_mbox_api_17: break; default: return -EOPNOTSUPP;
}
msgbuf[0] = IXGBE_VF_GET_PF_LINK_STATE;
err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf,
ARRAY_SIZE(msgbuf)); if (err || (msgbuf[0] & IXGBE_VT_MSGTYPE_FAILURE)) {
err = IXGBE_ERR_MBX;
*speed = IXGBE_LINK_SPEED_UNKNOWN; /* No need to set @link_up to false as it will be done by *ixgbe_check_mac_link_vf().
*/
} else {
*speed = msgbuf[1];
*link_up = msgbuf[2];
}
msgbuf[0] = IXGBE_VF_SET_VLAN;
msgbuf[1] = vlan; /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT;
err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf,
ARRAY_SIZE(msgbuf)); if (err) goto mbx_err;
/* remove extra bits from the message */
msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
msgbuf[0] &= ~(0xFF << IXGBE_VT_MSGINFO_SHIFT);
if (msgbuf[0] != (IXGBE_VF_SET_VLAN | IXGBE_VT_MSGTYPE_SUCCESS))
err = IXGBE_ERR_INVALID_ARGUMENT;
/* if link status is down no point in checking to see if PF is up */ if (!(vflinks & IXGBE_LINKS_UP)) {
*link_up = false; return;
}
/* for SFP+ modules and DA cables on 82599 it can take up to 500usecs *beforethelinkstatusiscorrect
*/ if (hw->mac.type == ixgbe_mac_82599_vf) { for (int i = 0; i < 5; i++) {
udelay(100);
vflinks = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
/* If we were hit with a reset drop the link */ if (!mbx->ops.check_for_rst(hw) || !mbx->timeout)
mac->get_link_status = true;
if (!mac->get_link_status) goto out;
if (hw->mac.type == ixgbe_mac_e610_vf) {
ret_val = ixgbevf_get_pf_link_state(hw, speed, link_up); if (ret_val) goto out;
} else {
ixgbe_read_vflinks(hw, speed, link_up); if (*link_up == false) goto out;
}
/* if the read failed it could just be a mailbox collision, best wait *untilwearecalledagainanddon'treportanerror
*/ if (mbx->ops.read(hw, &in_msg, 1)) { if (adapter->pf_features & IXGBEVF_PF_SUP_ESX_MBX)
mac->get_link_status = false; goto out;
}
if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) { /* msg is not CTS and is NACK we must have lost CTS status */ if (in_msg & IXGBE_VT_MSGTYPE_FAILURE)
ret_val = -1; goto out;
}
/* the pf is talking, if we timed out in the past we reinit */ if (!mbx->timeout) {
ret_val = -1; goto out;
}
/* if we passed all the tests above then the link is up and we no *longerneedtocheckforlink
*/
mac->get_link_status = false;
/* If we were hit with a reset drop the link */ if (!mbx->ops.check_for_rst(hw) || !mbx->timeout)
mac->get_link_status = true;
if (!mac->get_link_status) goto out;
/* if link status is down no point in checking to see if pf is up */
links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS); if (!(links_reg & IXGBE_LINKS_UP)) goto out;
/* for SFP+ modules and DA cables on 82599 it can take up to 500usecs *beforethelinkstatusiscorrect
*/ if (mac->type == ixgbe_mac_82599_vf) { int i;
for (i = 0; i < 5; i++) {
udelay(100);
links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
if (!(links_reg & IXGBE_LINKS_UP)) goto out;
}
}
switch (links_reg & IXGBE_LINKS_SPEED_82599) { case IXGBE_LINKS_SPEED_10G_82599:
*speed = IXGBE_LINK_SPEED_10GB_FULL; break; case IXGBE_LINKS_SPEED_1G_82599:
*speed = IXGBE_LINK_SPEED_1GB_FULL; break; case IXGBE_LINKS_SPEED_100_82599:
*speed = IXGBE_LINK_SPEED_100_FULL; break;
}
/* if we passed all the tests above then the link is up and we no *longerneedtocheckforlink
*/
mac->get_link_status = false;
/* Store value and return 0 on success */ if (msg[0] == (IXGBE_VF_API_NEGOTIATE |
IXGBE_VT_MSGTYPE_SUCCESS)) {
hw->api_version = api; return0;
}
err = IXGBE_ERR_INVALID_ARGUMENT;
}
return err;
}
/** *ixgbevf_hv_negotiate_api_version_vf-NegotiatesupportedAPIversion *@hw:pointertotheHWstructure *@api:integercontainingrequestedAPIversion *Hyper-Vversion-onlyixgbe_mbox_api_10supported.
**/ staticint ixgbevf_hv_negotiate_api_version_vf(struct ixgbe_hw *hw, int api)
{ /* Hyper-V only supports api version ixgbe_mbox_api_10 */ if (api != ixgbe_mbox_api_10) return IXGBE_ERR_INVALID_ARGUMENT;
return0;
}
int ixgbevf_get_queues(struct ixgbe_hw *hw, unsignedint *num_tcs, unsignedint *default_tc)
{ int err;
u32 msg[5];
/* do nothing if API doesn't support ixgbevf_get_queues */ switch (hw->api_version) { case ixgbe_mbox_api_11: case ixgbe_mbox_api_12: case ixgbe_mbox_api_13: case ixgbe_mbox_api_14: case ixgbe_mbox_api_15: case ixgbe_mbox_api_16: case ixgbe_mbox_api_17: break; default: return0;
}
/* Fetch queue configuration from the PF */
msg[0] = IXGBE_VF_GET_QUEUE;
msg[1] = msg[2] = msg[3] = msg[4] = 0;
/* if we didn't get an ACK there must have been *somesortofmailboxerrorsoweshouldtreatit *assuch
*/ if (msg[0] != (IXGBE_VF_GET_QUEUE | IXGBE_VT_MSGTYPE_SUCCESS)) return IXGBE_ERR_MBX;
/* record and validate values from message */
hw->mac.max_tx_queues = msg[IXGBE_VF_TX_QUEUES]; if (hw->mac.max_tx_queues == 0 ||
hw->mac.max_tx_queues > IXGBE_VF_MAX_TX_QUEUES)
hw->mac.max_tx_queues = IXGBE_VF_MAX_TX_QUEUES;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.