static u32 hns_get_rss_indir_size(struct net_device *netdev) { struct hns_nic_priv *priv = netdev_priv(netdev); struct hnae_ae_ops *ops; if (AE_IS_VER1(priv->enet_ver)) { netdev_err(netdev, "RSS feature is not supported on this hardware\n"); return 0; } ops = priv->ae_handle->dev->ops; return ops->get_rss_indir_size(priv->ae_handle); }
static int hns_get_rss(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc) { struct hns_nic_priv *priv = netdev_priv(netdev); struct hnae_ae_ops *ops; if (AE_IS_VER1(priv->enet_ver)) { netdev_err(netdev, "RSS feature is not supported on this hardware\n"); return -EOPNOTSUPP; } ops = priv->ae_handle->dev->ops; if (!indir) return 0; return ops->get_rss(priv->ae_handle, indir, key, hfunc); }
/** * ppe_init_hw - init ppe * @ppe_cb: ppe device */ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb) { struct ppe_common_cb *ppe_common_cb = ppe_cb->ppe_common_cb; u32 port = ppe_cb->index; struct dsaf_device *dsaf_dev = ppe_common_cb->dsaf_dev; int i; /* get default RSS key */ netdev_rss_key_fill(ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE); dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 0); mdelay(10); dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 1); /* clr and msk except irq*/ hns_ppe_exc_irq_en(ppe_cb, 0); if (ppe_common_cb->ppe_mode == PPE_COMMON_MODE_DEBUG) { hns_ppe_set_port_mode(ppe_cb, PPE_MODE_GE); dsaf_write_dev(ppe_cb, PPE_CFG_PAUSE_IDLE_CNT_REG, 0); } else { hns_ppe_set_port_mode(ppe_cb, PPE_MODE_XGE); } hns_ppe_checksum_hw(ppe_cb, 0xffffffff); hns_ppe_cnt_clr_ce(ppe_cb); if (!AE_IS_VER1(dsaf_dev->dsaf_ver)) { hns_ppe_set_vlan_strip(ppe_cb, 0); dsaf_write_dev(ppe_cb, PPE_CFG_MAX_FRAME_LEN_REG, HNS_PPEV2_MAX_FRAME_LEN); /* set default RSS key in h/w */ hns_ppe_set_rss_key(ppe_cb, ppe_cb->rss_key); /* Set default indrection table in h/w */ for (i = 0; i < HNS_PPEV2_RSS_IND_TBL_SIZE; i++) ppe_cb->rss_indir_table[i] = i; hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table); } }
static int hns_set_rss(struct net_device *netdev, const u32 *indir, const u8 *key, const u8 hfunc) { struct hns_nic_priv *priv = netdev_priv(netdev); struct hnae_ae_ops *ops; if (AE_IS_VER1(priv->enet_ver)) { netdev_err(netdev, "RSS feature is not supported on this hardware\n"); return -EOPNOTSUPP; } ops = priv->ae_handle->dev->ops; if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) { netdev_err(netdev, "Invalid hfunc!\n"); return -EOPNOTSUPP; } return ops->set_rss(priv->ae_handle, indir, key, hfunc); }
static int hns_set_rss(struct net_device *netdev, const u32 *indir, const u8 *key, const u8 hfunc) { struct hns_nic_priv *priv = netdev_priv(netdev); struct hnae_ae_ops *ops; if (AE_IS_VER1(priv->enet_ver)) { netdev_err(netdev, "RSS feature is not supported on this hardware\n"); return -EOPNOTSUPP; } ops = priv->ae_handle->dev->ops; /* currently hfunc can only be Toeplitz hash */ if (key || (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)) return -EOPNOTSUPP; if (!indir) return 0; return ops->set_rss(priv->ae_handle, indir, key, hfunc); }
static void __lb_other_process(struct hns_nic_ring_data *ring_data, struct sk_buff *skb) { struct net_device *ndev; struct hns_nic_priv *priv; struct hnae_ring *ring; struct netdev_queue *dev_queue; struct sk_buff *new_skb; unsigned int frame_size; int check_ok; u32 i; char buff[33]; /* 32B data and the last character '\0' */ if (!ring_data) { /* Just for doing create frame*/ ndev = skb->dev; priv = netdev_priv(ndev); frame_size = skb->len; memset(skb->data, 0xFF, frame_size); if ((!AE_IS_VER1(priv->enet_ver)) && (priv->ae_handle->port_type == HNAE_PORT_SERVICE)) { memcpy(skb->data, ndev->dev_addr, 6); skb->data[5] += 0x1f; } frame_size &= ~1ul; memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1); memset(&skb->data[frame_size / 2 + 10], 0xBE, frame_size / 2 - 11); memset(&skb->data[frame_size / 2 + 12], 0xAF, frame_size / 2 - 13); return; } ring = ring_data->ring; ndev = ring_data->napi.dev; if (is_tx_ring(ring)) { /* for tx queue reset*/ dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index); netdev_tx_reset_queue(dev_queue); return; } frame_size = skb->len; frame_size &= ~1ul; /* for mutl buffer*/ new_skb = skb_copy(skb, GFP_ATOMIC); dev_kfree_skb_any(skb); skb = new_skb; check_ok = 0; if (*(skb->data + 10) == 0xFF) { /* for rx check frame*/ if ((*(skb->data + frame_size / 2 + 10) == 0xBE) && (*(skb->data + frame_size / 2 + 12) == 0xAF)) check_ok = 1; } if (check_ok) { ndev->stats.rx_packets++; ndev->stats.rx_bytes += skb->len; } else { ndev->stats.rx_frame_errors++; for (i = 0; i < skb->len; i++) { snprintf(buff + i % 16 * 2, 3, /* tailing \0*/ "%02x", *(skb->data + i)); if ((i % 16 == 15) || (i == skb->len - 1)) pr_info("%s\n", buff); } } dev_kfree_skb_any(skb); }
/** *hns_nic_get_link_ksettings - implement ethtool get link ksettings *@net_dev: net_device *@cmd: ethtool_link_ksettings *retuen 0 - success , negative --fail */ static int hns_nic_get_link_ksettings(struct net_device *net_dev, struct ethtool_link_ksettings *cmd) { struct hns_nic_priv *priv = netdev_priv(net_dev); struct hnae_handle *h; u32 link_stat; int ret; u8 duplex; u16 speed; u32 supported, advertising; if (!priv || !priv->ae_handle) return -ESRCH; h = priv->ae_handle; if (!h->dev || !h->dev->ops || !h->dev->ops->get_info) return -ESRCH; ret = h->dev->ops->get_info(h, NULL, &speed, &duplex); if (ret < 0) { netdev_err(net_dev, "%s get_info error!\n", __func__); return -EINVAL; } ethtool_convert_link_mode_to_legacy_u32(&supported, cmd->link_modes.supported); ethtool_convert_link_mode_to_legacy_u32(&advertising, cmd->link_modes.advertising); /* When there is no phy, autoneg is off. */ cmd->base.autoneg = false; cmd->base.cmd = speed; cmd->base.duplex = duplex; if (net_dev->phydev) (void)phy_ethtool_ksettings_get(net_dev->phydev, cmd); link_stat = hns_nic_get_link(net_dev); if (!link_stat) { cmd->base.speed = (u32)SPEED_UNKNOWN; cmd->base.duplex = DUPLEX_UNKNOWN; } if (cmd->base.autoneg) advertising |= ADVERTISED_Autoneg; supported |= h->if_support; if (h->phy_if == PHY_INTERFACE_MODE_SGMII) { supported |= SUPPORTED_TP; advertising |= ADVERTISED_1000baseT_Full; } else if (h->phy_if == PHY_INTERFACE_MODE_XGMII) { supported |= SUPPORTED_FIBRE; advertising |= ADVERTISED_10000baseKR_Full; } switch (h->media_type) { case HNAE_MEDIA_TYPE_FIBER: cmd->base.port = PORT_FIBRE; break; case HNAE_MEDIA_TYPE_COPPER: cmd->base.port = PORT_TP; break; case HNAE_MEDIA_TYPE_UNKNOWN: default: break; } if (!(AE_IS_VER1(priv->enet_ver) && h->port_type == HNAE_PORT_DEBUG)) supported |= SUPPORTED_Pause; ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, supported); ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, advertising); cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C45 | ETH_MDIO_SUPPORTS_C22; hns_get_mdix_mode(net_dev, cmd); return 0; }