val = enetc_port_mac_rd(si, ENETC4_PM_CMD_CFG(0));
val = u32_replace_bits(val, en ? 1 : 0, PM_CMD_CFG_LOOP_EN); /* Default to select MAC level loopback mode if loopback is enabled. */
val = u32_replace_bits(val, en ? LPBCK_MODE_MAC_LEVEL : 0,
PM_CMD_CFG_LPBK_MODE);
staticint enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf)
{ int max_num_mfe = pf->caps.mac_filter_num; struct enetc_mac_filter mac_filter = {}; struct net_device *ndev = pf->si->ndev; struct enetc_hw *hw = &pf->si->hw; struct enetc_mac_addr *mac_tbl; struct netdev_hw_addr *ha; int i = 0, err; int mac_cnt;
netif_addr_lock_bh(ndev);
mac_cnt = netdev_uc_count(ndev); if (!mac_cnt) {
netif_addr_unlock_bh(ndev); /* clear both MAC hash and exact filters */
enetc4_pf_set_si_uc_hash_filter(hw, 0, 0);
enetc4_pf_clear_maft_entries(pf);
/* Set temporary unicast hash filters in case of Rx loss when * updating MAC address filter table
*/
enetc4_pf_set_si_uc_hash_filter(hw, 0, *mac_filter.mac_hash_table);
enetc4_pf_clear_maft_entries(pf);
if (!enetc4_pf_add_maft_entries(pf, mac_tbl, i))
enetc4_pf_set_si_uc_hash_filter(hw, 0, 0);
staticvoid enetc4_pf_set_mac_filter(struct enetc_pf *pf, int type)
{ /* Currently, the MAC address filter table (MAFT) only has 4 entries, * and multiple multicast addresses for filtering will be configured * in the default network configuration, so MAFT is only suitable for * unicast filtering. If the number of unicast addresses exceeds the * table capacity, the MAC hash filter will be used.
*/ if (type & ENETC_MAC_FILTER_TYPE_UC && enetc4_pf_set_uc_exact_filter(pf)) { /* Fall back to the MAC hash filter */
enetc4_pf_set_mac_hash_filter(pf, ENETC_MAC_FILTER_TYPE_UC); /* Clear the old MAC exact filter */
enetc4_pf_clear_maft_entries(pf);
}
if (type & ENETC_MAC_FILTER_TYPE_MC)
enetc4_pf_set_mac_hash_filter(pf, ENETC_MAC_FILTER_TYPE_MC);
}
val = ENETC_PSICFGR0_SET_TXBDR(num_tx_bdr);
val |= ENETC_PSICFGR0_SET_RXBDR(num_rx_bdr);
val |= ENETC_PSICFGR0_SIVC(ENETC_VLAN_TYPE_C | ENETC_VLAN_TYPE_S);
if (is_vf)
val |= ENETC_PSICFGR0_VTE | ENETC_PSICFGR0_SIVIE;
staticvoid enetc4_pf_set_si_vlan_promisc(struct enetc_hw *hw, int si, bool en)
{
u32 val = enetc_port_rd(hw, ENETC4_PSIPVMR);
if (en)
val |= BIT(si); else
val &= ~BIT(si);
enetc_port_wr(hw, ENETC4_PSIPVMR, val);
}
staticvoid enetc4_set_default_si_vlan_promisc(struct enetc_pf *pf)
{ struct enetc_hw *hw = &pf->si->hw; int num_si = pf->caps.num_vsi + 1; int i;
/* enforce VLAN promiscuous mode for all SIs */ for (i = 0; i < num_si; i++)
enetc4_pf_set_si_vlan_promisc(hw, i, true);
}
/* Allocate the number of MSI-X vectors for per SI. */ staticvoid enetc4_set_si_msix_num(struct enetc_pf *pf)
{ struct enetc_hw *hw = &pf->si->hw; int i, num_msix, total_si;
u32 val;
/* Initialize the MAC address for PF and VFs */
err = enetc_setup_mac_addresses(dev->of_node, pf); if (err) {
dev_err(dev, "Failed to set MAC addresses\n"); return err;
}
err = enetc4_init_ntmp_user(pf->si); if (err) {
dev_err(dev, "Failed to init CBDR\n"); return err;
}
val = enetc_port_mac_rd(si, ENETC4_PM_IF_MODE(0));
val &= ~(PM_IF_MODE_IFMODE | PM_IF_MODE_ENA);
switch (phy_mode) { case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_TXID:
val |= IFMODE_RGMII; /* We need to enable auto-negotiation for the MAC * if its RGMII interface support In-Band status.
*/ if (phylink_autoneg_inband(mode))
val |= PM_IF_MODE_ENA; break; case PHY_INTERFACE_MODE_RMII:
val |= IFMODE_RMII; break; case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_2500BASEX:
val |= IFMODE_SGMII; break; case PHY_INTERFACE_MODE_10GBASER: case PHY_INTERFACE_MODE_XGMII: case PHY_INTERFACE_MODE_USXGMII:
val |= IFMODE_XGMII; break; default:
dev_err(priv->dev, "Unsupported PHY mode:%d\n", phy_mode); return;
}
val = enetc_port_rd(&priv->si->hw, ENETC4_PCR);
val &= ~PCR_PSPEED;
switch (speed) { case SPEED_100: case SPEED_1000: case SPEED_2500: case SPEED_10000:
val |= (PCR_PSPEED & PCR_PSPEED_VAL(speed)); break; case SPEED_10: default:
val |= (PCR_PSPEED & PCR_PSPEED_VAL(SPEED_10));
}
switch (speed) { case SPEED_1000:
val = u32_replace_bits(val, SSP_1G, PM_IF_MODE_SSP); break; case SPEED_100:
val = u32_replace_bits(val, SSP_100M, PM_IF_MODE_SSP); break; case SPEED_10:
val = u32_replace_bits(val, SSP_10M, PM_IF_MODE_SSP);
}
for (i = 0; i < num_rxbdr; i++) {
old_rbmr = enetc_rxbdr_rd(hw, i, ENETC_RBMR);
rbmr = u32_replace_bits(old_rbmr, tx_pause ? 1 : 0, ENETC_RBMR_CM); if (rbmr == old_rbmr) continue;
enetc_rxbdr_wr(hw, i, ENETC_RBMR, rbmr);
}
if (tx_pause) { /* When the port first enters congestion, send a PAUSE request * with the maximum number of quanta. When the port exits * congestion, it will automatically send a PAUSE frame with * zero quanta.
*/
init_quanta = 0xffff;
/* Also, set up the refresh timer to send follow-up PAUSE * frames at half the quanta value, in case the congestion * condition persists.
*/
refresh_quanta = 0xffff / 2;
/* Start emitting PAUSE frames when 3 large frames (or more * smaller frames) have accumulated in the FIFO waiting to be * DMAed to the RX ring.
*/
pause_on_thresh = 3 * ENETC_MAC_MAXFRM_SIZE;
pause_off_thresh = 1 * ENETC_MAC_MAXFRM_SIZE;
}
val = enetc_port_mac_rd(si, ENETC4_PM_CMD_CFG(0));
val &= ~(PM_CMD_CFG_TX_EN | PM_CMD_CFG_RX_EN);
val |= en ? (PM_CMD_CFG_TX_EN | PM_CMD_CFG_RX_EN) : 0;
if (!phylink_autoneg_inband(mode) &&
phy_interface_mode_is_rgmii(interface))
enetc4_set_rgmii_mac(pf, speed, duplex);
if (interface == PHY_INTERFACE_MODE_RMII)
enetc4_set_rmii_mac(pf, speed, duplex);
if (duplex == DUPLEX_FULL) { /* When preemption is enabled, generation of PAUSE frames * must be disabled, as stated in the IEEE 802.3 standard.
*/ if (priv->active_offloads & ENETC_F_QBU)
tx_pause = false;
} else { /* DUPLEX_HALF */ if (tx_pause || rx_pause)
hd_fc = true;
/* As per 802.3 annex 31B, PAUSE frames are only supported * when the link is configured for full duplex operation.
*/
tx_pause = false;
rx_pause = false;
}
/* si is the private data. */
si = pci_get_drvdata(pdev); if (!si->hw.port || !si->hw.global) return dev_err_probe(dev, -ENODEV, "Couldn't map PF only space\n");
si->revision = enetc_get_ip_revision(&si->hw);
si->ops = &enetc4_psi_ops;
err = enetc_get_driver_data(si); if (err) return dev_err_probe(dev, err, "Could not get PF driver data\n");
err = enetc4_pf_struct_init(si); if (err) return err;
pf = enetc_si_priv(si);
err = enetc4_pf_init(pf); if (err) return err;
enetc_get_si_caps(si);
err = enetc4_pf_netdev_create(si); if (err) goto err_netdev_create;
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.