コード例 #1
0
ファイル: hns_ethtool.c プロジェクト: acton393/linux
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);
}
コード例 #2
0
ファイル: hns_ethtool.c プロジェクト: acton393/linux
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);
}
コード例 #3
0
ファイル: hns_dsaf_ppe.c プロジェクト: guribe94/linux
/**
 * 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);
	}
}
コード例 #4
0
ファイル: hns_ethtool.c プロジェクト: austriancoder/linux
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);
}
コード例 #5
0
ファイル: hns_ethtool.c プロジェクト: acton393/linux
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);
}
コード例 #6
0
ファイル: hns_ethtool.c プロジェクト: acton393/linux
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);
}
コード例 #7
0
ファイル: hns_ethtool.c プロジェクト: acton393/linux
/**
 *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;
}