/* clear all rxd ctl */ for (i = 0; i < WX_VF_MAX_RING_NUMS; i++)
wr32m(wx, WX_VXRXDCTL(i),
WX_VXRXDCTL_HDRSZ_MASK | WX_VXRXDCTL_BUFSZ_MASK,
vfsrrctl);
rd32(wx, WX_VXSTATUS);
}
/** * wx_init_hw_vf - virtual function hardware initialization * @wx: pointer to hardware structure * * Initialize the mac address
**/ void wx_init_hw_vf(struct wx *wx)
{
wx_get_mac_addr_vf(wx, wx->mac.addr);
}
EXPORT_SYMBOL(wx_init_hw_vf);
/* Disable the transmit unit. Each queue must be disabled. */ for (i = 0; i < wx->mac.max_tx_queues; i++)
wr32(wx, WX_VXTXDCTL(i), WX_VXTXDCTL_FLUSH);
/* Disable the receive unit by stopping each queue */ for (i = 0; i < wx->mac.max_rx_queues; i++) {
reg_val = rd32(wx, WX_VXRXDCTL(i));
reg_val &= ~WX_VXRXDCTL_ENABLE;
wr32(wx, WX_VXRXDCTL(i), reg_val);
} /* Clear packet split and pool config */
wr32(wx, WX_VXMRQC, 0);
/* flush all queues disables */
rd32(wx, WX_VXSTATUS);
}
EXPORT_SYMBOL(wx_stop_adapter_vf);
/** * wx_set_rar_vf - set device MAC address * @wx: pointer to hardware structure * @index: Receive address register to write * @addr: Address to put into receive address register * @enable_addr: set flag that address is active * * Return: returns 0 on success, negative error code on failure
**/ int wx_set_rar_vf(struct wx *wx, u32 index, u8 *addr, u32 enable_addr)
{
u32 msgbuf[3] = {WX_VF_SET_MAC_ADDR};
u8 *msg_addr = (u8 *)(&msgbuf[1]); int ret;
memcpy(msg_addr, addr, ETH_ALEN);
ret = wx_mbx_write_and_read_reply(wx, msgbuf, msgbuf,
ARRAY_SIZE(msgbuf)); if (ret) return ret;
msgbuf[0] &= ~WX_VT_MSGTYPE_CTS;
/* if nacked the address was rejected, use "perm_addr" */ if (msgbuf[0] == (WX_VF_SET_MAC_ADDR | WX_VT_MSGTYPE_NACK)) {
wx_get_mac_addr_vf(wx, wx->mac.addr); return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL(wx_set_rar_vf);
/** * wx_update_mc_addr_list_vf - Update Multicast addresses * @wx: pointer to the HW structure * @netdev: pointer to the net device structure * * Updates the Multicast Table Array. * * Return: returns 0 on success, negative error code on failure
**/ int wx_update_mc_addr_list_vf(struct wx *wx, struct net_device *netdev)
{
u32 msgbuf[WX_VXMAILBOX_SIZE] = {WX_VF_SET_MULTICAST};
u16 *vector_l = (u16 *)&msgbuf[1]; struct netdev_hw_addr *ha;
u32 cnt, i;
/** * wx_get_link_state_vf - Get VF link state from PF * @wx: pointer to the HW structure * @link_state: link state storage * * Return: return state of the operation error or success.
**/ int wx_get_link_state_vf(struct wx *wx, u16 *link_state)
{
u32 msgbuf[2] = {WX_VF_GET_LINK_STATE}; int ret;
ret = wx_mbx_write_and_read_reply(wx, msgbuf, msgbuf,
ARRAY_SIZE(msgbuf)); if (ret) return ret;
if (msgbuf[0] & WX_VT_MSGTYPE_NACK) return -EINVAL;
*link_state = msgbuf[1];
return 0;
}
EXPORT_SYMBOL(wx_get_link_state_vf);
/** * wx_set_vfta_vf - Set/Unset vlan filter table address * @wx: pointer to the HW structure * @vlan: 12 bit VLAN ID * @vind: unused by VF drivers * @vlan_on: if true then set bit, else clear bit * @vlvf_bypass: boolean flag indicating updating default pool is okay * * Turn on/off specified VLAN in the VLAN filter table. * * Return: returns 0 on success, negative error code on failure
**/ int wx_set_vfta_vf(struct wx *wx, u32 vlan, u32 vind, bool vlan_on, bool vlvf_bypass)
{
u32 msgbuf[2] = {WX_VF_SET_VLAN, vlan}; bool vlan_offload = false; int ret;
/* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
msgbuf[0] |= vlan_on << WX_VT_MSGINFO_SHIFT; /* if vf vlan offload is disabled, allow to create vlan under pf port vlan */
msgbuf[0] |= BIT(vlan_offload);
ret = wx_mbx_write_and_read_reply(wx, msgbuf, msgbuf,
ARRAY_SIZE(msgbuf)); if (ret) return ret;
int wx_get_fw_version_vf(struct wx *wx)
{
u32 msgbuf[2] = {WX_VF_GET_FW_VERSION}; int ret;
ret = wx_mbx_write_and_read_reply(wx, msgbuf, msgbuf,
ARRAY_SIZE(msgbuf)); if (ret) return ret;
if (msgbuf[0] & WX_VT_MSGTYPE_NACK) return -EINVAL;
snprintf(wx->eeprom_id, 32, "0x%08x", msgbuf[1]);
return 0;
}
EXPORT_SYMBOL(wx_get_fw_version_vf);
int wx_set_uc_addr_vf(struct wx *wx, u32 index, u8 *addr)
{
u32 msgbuf[3] = {WX_VF_SET_MACVLAN};
u8 *msg_addr = (u8 *)(&msgbuf[1]); int ret;
/* If index is one then this is the start of a new list and needs * indication to the PF so it can do it's own list management. * If it is zero then that tells the PF to just clear all of * this VF's macvlans and there is no new list.
*/
msgbuf[0] |= index << WX_VT_MSGINFO_SHIFT; if (addr)
memcpy(msg_addr, addr, 6);
ret = wx_mbx_write_and_read_reply(wx, msgbuf, msgbuf,
ARRAY_SIZE(msgbuf)); if (ret) return ret;
msgbuf[0] &= ~WX_VT_MSGTYPE_CTS;
if (msgbuf[0] == (WX_VF_SET_MACVLAN | WX_VT_MSGTYPE_NACK)) return -EINVAL;
return 0;
}
EXPORT_SYMBOL(wx_set_uc_addr_vf);
/** * wx_rlpml_set_vf - Set the maximum receive packet length * @wx: pointer to the HW structure * @max_size: value to assign to max frame size * * Return: returns 0 on success, negative error code on failure
**/ int wx_rlpml_set_vf(struct wx *wx, u16 max_size)
{
u32 msgbuf[2] = {WX_VF_SET_LPE, max_size}; int ret;
ret = wx_mbx_write_and_read_reply(wx, msgbuf, msgbuf,
ARRAY_SIZE(msgbuf)); if (ret) return ret; if ((msgbuf[0] & WX_VF_SET_LPE) &&
(msgbuf[0] & WX_VT_MSGTYPE_NACK)) return -EINVAL;
return 0;
}
EXPORT_SYMBOL(wx_rlpml_set_vf);
/** * wx_negotiate_api_version - Negotiate supported API version * @wx: pointer to the HW structure * @api: integer containing requested API version * * Return: returns 0 on success, negative error code on failure
**/ int wx_negotiate_api_version(struct wx *wx, int api)
{
u32 msgbuf[2] = {WX_VF_API_NEGOTIATE, api}; int ret;
ret = wx_mbx_write_and_read_reply(wx, msgbuf, msgbuf,
ARRAY_SIZE(msgbuf)); if (ret) return ret;
msgbuf[0] &= ~WX_VT_MSGTYPE_CTS;
/* Store value and return 0 on success */ if (msgbuf[0] == (WX_VF_API_NEGOTIATE | WX_VT_MSGTYPE_NACK)) return -EINVAL;
wx->vfinfo->vf_api = api;
int wx_get_queues_vf(struct wx *wx, u32 *num_tcs, u32 *default_tc)
{
u32 msgbuf[5] = {WX_VF_GET_QUEUES}; int ret;
/* do nothing if API doesn't support wx_get_queues */ if (wx->vfinfo->vf_api < wx_mbox_api_13) return -EINVAL;
/* Fetch queue configuration from the PF */
ret = wx_mbx_write_and_read_reply(wx, msgbuf, msgbuf,
ARRAY_SIZE(msgbuf)); if (ret) return ret;
msgbuf[0] &= ~WX_VT_MSGTYPE_CTS;
/* if we didn't get an ACK there must have been * some sort of mailbox error so we should treat it * as such
*/ if (msgbuf[0] != (WX_VF_GET_QUEUES | WX_VT_MSGTYPE_ACK)) return -EINVAL; /* record and validate values from message */
wx->mac.max_tx_queues = msgbuf[WX_VF_TX_QUEUES]; if (wx->mac.max_tx_queues == 0 ||
wx->mac.max_tx_queues > WX_VF_MAX_TX_QUEUES)
wx->mac.max_tx_queues = WX_VF_MAX_TX_QUEUES;
*num_tcs = msgbuf[WX_VF_TRANS_VLAN]; /* in case of unknown state assume we cannot tag frames */ if (*num_tcs > wx->mac.max_rx_queues)
*num_tcs = 1;
*default_tc = msgbuf[WX_VF_DEF_QUEUE]; /* default to queue 0 on out-of-bounds queue number */ if (*default_tc >= wx->mac.max_tx_queues)
*default_tc = 0;
staticvoid wx_check_physical_link(struct wx *wx)
{
u32 val, link_val; int ret;
/* get link status from hw status reg * for SFP+ modules and DA cables, it can take up to 500usecs * before the link status is correct
*/ if (wx->mac.type == wx_mac_em)
ret = read_poll_timeout_atomic(rd32, val, val & GENMASK(4, 1),
100, 500, false, wx, WX_VXSTATUS); else
ret = read_poll_timeout_atomic(rd32, val, val & BIT(0), 100,
500, false, wx, WX_VXSTATUS); if (ret) {
wx->speed = SPEED_UNKNOWN;
wx->link = false; return;
}
int wx_check_mac_link_vf(struct wx *wx)
{ struct wx_mbx_info *mbx = &wx->mbx;
u32 msgbuf[2] = {0}; int ret = 0;
if (!mbx->timeout) goto out;
wx_check_for_rst_vf(wx); if (!wx_check_for_msg_vf(wx))
ret = wx_read_mbx_vf(wx, msgbuf, 2); if (ret) goto out;
switch (msgbuf[0] & GENMASK(8, 0)) { case WX_PF_NOFITY_VF_LINK_STATUS | WX_PF_CONTROL_MSG:
ret = wx_get_link_status_from_pf(wx, msgbuf); goto out; case WX_PF_CONTROL_MSG:
ret = wx_pf_ping_vf(wx, msgbuf); goto out; case 0: if (msgbuf[0] & WX_VT_MSGTYPE_NACK) { /* msg is NACK, we must have lost CTS status */
ret = -EBUSY; goto out;
} /* no message, check link status */
wx_check_physical_link(wx); goto out; default: break;
}
if (!(msgbuf[0] & WX_VT_MSGTYPE_CTS)) { /* msg is not CTS and is NACK we must have lost CTS status */ if (msgbuf[0] & WX_VT_MSGTYPE_NACK)
ret = -EBUSY; goto out;
}
/* the pf is talking, if we timed out in the past we reinit */ if (!mbx->timeout) {
ret = -EBUSY; goto out;
}
out: return ret;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet)
¤
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.