if (!mac_ctrl_drv->get_link_status) return link_status;
for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) {
msleep(HNS_MAC_LINK_WAIT_TIME);
mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status); if (!link_status) break;
}
if (mac_ctrl_drv->get_link_status)
mac_ctrl_drv->get_link_status(mac_ctrl_drv, link_status); else
*link_status = 0;
if (mac_cb->media_type == HNAE_MEDIA_TYPE_FIBER) {
ret = mac_cb->dsaf_dev->misc_op->get_sfp_prsnt(mac_cb,
&sfp_prsnt); if (!ret)
*link_status = *link_status && sfp_prsnt;
/* for FIBER port, it may have a fake link up. * when the link status changes from down to up, we need to do * anti-shake. the anti-shake time is base on tests. * only FIBER port need to do this.
*/ if (*link_status && !mac_cb->link)
*link_status = hns_mac_link_anti_shake(mac_ctrl_drv);
}
if (mac_ctrl_drv->adjust_link) {
ret = mac_ctrl_drv->adjust_link(mac_ctrl_drv,
(enum mac_speed)speed, duplex); if (ret) {
dev_err(mac_cb->dev, "adjust_link failed, %s mac%d ret = %#x!\n",
mac_cb->dsaf_dev->ae_dev.name,
mac_cb->mac_id, ret); return;
}
}
}
/** *hns_mac_get_inner_port_num - get mac table inner port number *@mac_cb: mac device *@vmid: vm id *@port_num:port number *
*/ int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb, u8 vmid, u8 *port_num)
{ int q_num_per_vf, vf_num_per_port; int vm_queue_id;
u8 tmp_port;
switch (mac_cb->dsaf_dev->dsaf_mode) { case DSAF_MODE_ENABLE_FIX:
tmp_port = 0; break; case DSAF_MODE_DISABLE_FIX:
tmp_port = 0; break; case DSAF_MODE_ENABLE_0VM: case DSAF_MODE_ENABLE_8VM: case DSAF_MODE_ENABLE_16VM: case DSAF_MODE_ENABLE_32VM: case DSAF_MODE_ENABLE_128VM: case DSAF_MODE_DISABLE_2PORT_8VM: case DSAF_MODE_DISABLE_2PORT_16VM: case DSAF_MODE_DISABLE_2PORT_64VM: case DSAF_MODE_DISABLE_6PORT_0VM: case DSAF_MODE_DISABLE_6PORT_2VM: case DSAF_MODE_DISABLE_6PORT_4VM: case DSAF_MODE_DISABLE_6PORT_16VM:
tmp_port = vm_queue_id; break; default:
dev_err(mac_cb->dev, "dsaf mode invalid, %s mac%d!\n",
mac_cb->dsaf_dev->ae_dev.name, mac_cb->mac_id); return -EINVAL;
}
tmp_port += DSAF_BASE_INNER_PORT_NUM;
if (!enable)
ret = hns_dsaf_del_mac_mc_port(dsaf_dev, &mac_entry); else
ret = hns_dsaf_add_mac_mc_port(dsaf_dev, &mac_entry); if (ret) {
dev_err(dsaf_dev->dev, "set mac mc port failed, %s mac%d ret = %#x!\n",
mac_cb->dsaf_dev->ae_dev.name,
mac_cb->mac_id, ret); return ret;
}
}
return 0;
}
int hns_mac_clr_multicast(struct hns_mac_cb *mac_cb, int vfn)
{ struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
u8 port_num; int ret = hns_mac_get_inner_port_num(mac_cb, vfn, &port_num);
if (drv->config_max_frame_length)
drv->config_max_frame_length(drv, mac_cb->max_frm);
if (drv->set_tx_auto_pause_frames)
drv->set_tx_auto_pause_frames(drv, mac_cb->tx_pause_frm_time);
if (drv->set_an_mode)
drv->set_an_mode(drv, 1);
if (drv->mac_pausefrm_cfg) { if (mac_cb->mac_type == HNAE_PORT_DEBUG)
drv->mac_pausefrm_cfg(drv, !is_ver1, !is_ver1); else/* mac rx must disable, dsaf pfc close instead of it*/
drv->mac_pausefrm_cfg(drv, 0, 1);
}
}
if (new_frm > HNS_RCB_RING_MAX_BD_PER_PKT * buf_size) return -EINVAL;
if (!drv->config_max_frame_length) return -ECHILD;
/* adjust max frame to be at least the size of a standard frame */ if (new_frm < (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN))
new_frm = (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN);
phy = get_phy_device(mdio, addr, is_c45); if (IS_ERR_OR_NULL(phy)) return -EIO;
phy->irq = mdio->irq[addr];
/* All data is now stored in the phy struct; * register it
*/
rc = phy_device_register(phy); if (rc) {
phy_device_free(phy);
dev_err(&mdio->dev, "registered phy fail at address %i\n",
addr); return -ENODEV;
}
mac_cb->phy_dev = phy;
dev_dbg(&mdio->dev, "registered phy at address %i\n", addr);
return 0;
}
staticint hns_mac_register_phy(struct hns_mac_cb *mac_cb)
{ struct fwnode_reference_args args; struct platform_device *pdev; struct mii_bus *mii_bus; int rc; int addr;
/* Loop over the child nodes and register a phy_device for each one */ if (!to_acpi_device_node(mac_cb->fw_port)) return -ENODEV;
rc = acpi_node_get_property_reference(
mac_cb->fw_port, "mdio-node", 0, &args); if (rc) return rc; if (!is_acpi_device_node(args.fwnode)) return -EINVAL;
addr = hns_mac_phy_parse_addr(mac_cb->dev, mac_cb->fw_port); if (addr < 0) return addr;
/* dev address in adev */
pdev = hns_dsaf_find_platform_device(args.fwnode); if (!pdev) {
dev_err(mac_cb->dev, "mac%d mdio pdev is NULL\n",
mac_cb->mac_id); return -EINVAL;
}
mii_bus = platform_get_drvdata(pdev); if (!mii_bus) {
dev_err(mac_cb->dev, "mac%d mdio is NULL, dsaf will probe again later\n",
mac_cb->mac_id); return -EPROBE_DEFER;
}
/* if the dsaf node doesn't contain a port subnode, get phy-handle * from dsaf node
*/ if (!mac_cb->fw_port) {
np = of_parse_phandle(mac_cb->dev->of_node, "phy-handle",
mac_cb->mac_id);
mac_cb->phy_dev = of_phy_find_device(np); if (mac_cb->phy_dev) { /* refcount is held by of_phy_find_device() * if the phy_dev is found
*/
put_device(&mac_cb->phy_dev->mdio.dev);
if (is_of_node(mac_cb->fw_port)) { /* parse property from port subnode in dsaf */
np = of_parse_phandle(to_of_node(mac_cb->fw_port), "phy-handle", 0);
mac_cb->phy_dev = of_phy_find_device(np); if (mac_cb->phy_dev) { /* refcount is held by of_phy_find_device() * if the phy_dev is found
*/
put_device(&mac_cb->phy_dev->mdio.dev);
dev_dbg(mac_cb->dev, "mac%d phy_node: %pOFn\n",
mac_cb->mac_id, np);
}
of_node_put(np);
ret = fwnode_property_read_u32(mac_cb->fw_port, "port-rst-offset",
&mac_cb->port_rst_off); if (ret) {
dev_dbg(mac_cb->dev, "mac%d port-rst-offset not found, use default value.\n",
mac_cb->mac_id);
}
ret = fwnode_property_read_u32(mac_cb->fw_port, "port-mode-offset",
&mac_cb->port_mode_off); if (ret) {
dev_dbg(mac_cb->dev, "mac%d port-mode-offset not found, use default value.\n",
mac_cb->mac_id);
}
ret = of_parse_phandle_with_fixed_args(
to_of_node(mac_cb->fw_port), "cpld-syscon", 1, 0,
&cpld_args); if (ret) {
dev_dbg(mac_cb->dev, "mac%d no cpld-syscon found.\n",
mac_cb->mac_id);
mac_cb->cpld_ctrl = NULL;
} else {
syscon = syscon_node_to_regmap(cpld_args.np);
of_node_put(cpld_args.np); if (IS_ERR_OR_NULL(syscon)) {
dev_dbg(mac_cb->dev, "no cpld-syscon found!\n");
mac_cb->cpld_ctrl = NULL;
} else {
mac_cb->cpld_ctrl = syscon;
mac_cb->cpld_ctrl_reg = cpld_args.args[0];
}
}
} elseif (is_acpi_node(mac_cb->fw_port)) {
ret = hns_mac_register_phy(mac_cb); /* Mac can work well if there is phy or not.If the port don't * connect with phy, the return value will be ignored. Only * when there is phy but can't find mdio bus, the return value * will be handled.
*/ if (ret == -EPROBE_DEFER) return ret;
} else {
dev_err(mac_cb->dev, "mac%d cannot find phy node\n",
mac_cb->mac_id);
}
if (!fwnode_property_read_string(mac_cb->fw_port, "media-type",
&media_type)) { for (i = 0; i < ARRAY_SIZE(media_type_defs); i++) { if (!strncmp(media_type_defs[i].name, media_type,
MAC_MEDIA_TYPE_MAX_LEN)) {
mac_cb->media_type = media_type_defs[i].value; break;
}
}
}
if (fwnode_property_read_u8_array(mac_cb->fw_port, "mc-mac-mask",
mac_cb->mc_mask, ETH_ALEN)) {
dev_warn(mac_cb->dev, "no mc-mac-mask property, set to default value.\n");
eth_broadcast_addr(mac_cb->mc_mask);
}
/* if don't get any port subnode from dsaf node * will init all port then, this is compatible with the old dts
*/ if (!found) { for (port_id = 0; port_id < max_port_num; port_id++) {
mac_cb = devm_kzalloc(dsaf_dev->dev, sizeof(*mac_cb),
GFP_KERNEL); if (!mac_cb) return -ENOMEM;
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.