static struct pp2_bpool *mrvl_port_to_bpool_lookup[RTE_MAX_ETHPORTS];
static int mrvl_port_bpool_size[PP2_NUM_PKT_PROC][PP2_BPOOL_NUM_POOLS][RTE_MAX_LCORE];
static uint64_t cookie_addr_high = MRVL_COOKIE_ADDR_INVALID;
+static int dummy_pool_id[PP2_NUM_PKT_PROC];
+struct pp2_bpool *dummy_pool[PP2_NUM_PKT_PROC] = {0};
struct mrvl_ifnames {
const char *names[PP2_NUM_ETH_PPIO * PP2_NUM_PKT_PROC];
mrvl_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);
static int mrvl_promiscuous_enable(struct rte_eth_dev *dev);
static int mrvl_allmulticast_enable(struct rte_eth_dev *dev);
+static int
+mrvl_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf);
#define MRVL_XSTATS_TBL_ENTRY(name) { \
#name, offsetof(struct pp2_ppio_statistics, name), \
MRVL_XSTATS_TBL_ENTRY(tx_errors)
};
+static inline int
+mrvl_reserve_bit(int *bitmap, int max)
+{
+ int n = sizeof(*bitmap) * 8 - __builtin_clz(*bitmap);
+
+ if (n >= max)
+ return -1;
+
+ *bitmap |= 1 << n;
+
+ return n;
+}
+
+static int
+mrvl_pp2_fixup_init(void)
+{
+ struct pp2_bpool_params bpool_params;
+ char name[15];
+ int err, i;
+
+ memset(dummy_pool, 0, sizeof(dummy_pool));
+ for (i = 0; i < pp2_get_num_inst(); i++) {
+ dummy_pool_id[i] = mrvl_reserve_bit(&used_bpools[i],
+ PP2_BPOOL_NUM_POOLS);
+ if (dummy_pool_id[i] < 0) {
+ MRVL_LOG(ERR, "Can't find free pool\n");
+ return -1;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, sizeof(name), "pool-%d:%d", i, dummy_pool_id[i]);
+ memset(&bpool_params, 0, sizeof(bpool_params));
+ bpool_params.match = name;
+ bpool_params.buff_len = MRVL_PKT_OFFS;
+ bpool_params.dummy_short_pool = 1;
+ err = pp2_bpool_init(&bpool_params, &dummy_pool[i]);
+ if (err != 0 || !dummy_pool[i]) {
+ MRVL_LOG(ERR, "BPool init failed!\n");
+ used_bpools[i] &= ~(1 << dummy_pool_id[i]);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Initialize packet processor.
+ *
+ * @return
+ * 0 on success, negative error value otherwise.
+ */
+static int
+mrvl_init_pp2(void)
+{
+ struct pp2_init_params init_params;
+ int err;
+
+ memset(&init_params, 0, sizeof(init_params));
+ init_params.hif_reserved_map = MRVL_MUSDK_HIFS_RESERVED;
+ init_params.bm_pool_reserved_map = MRVL_MUSDK_BPOOLS_RESERVED;
+ init_params.rss_tbl_reserved_map = MRVL_MUSDK_RSS_RESERVED;
+ if (mrvl_cfg && mrvl_cfg->pp2_cfg.prs_udfs.num_udfs)
+ memcpy(&init_params.prs_udfs, &mrvl_cfg->pp2_cfg.prs_udfs,
+ sizeof(struct pp2_parse_udfs));
+ err = pp2_init(&init_params);
+ if (err != 0) {
+ MRVL_LOG(ERR, "PP2 init failed");
+ return -1;
+ }
+
+ err = mrvl_pp2_fixup_init();
+ if (err != 0) {
+ MRVL_LOG(ERR, "PP2 fixup init failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+mrvl_pp2_fixup_deinit(void)
+{
+ int i;
+
+ for (i = 0; i < PP2_NUM_PKT_PROC; i++) {
+ if (!dummy_pool[i])
+ continue;
+ pp2_bpool_deinit(dummy_pool[i]);
+ used_bpools[i] &= ~(1 << dummy_pool_id[i]);
+ }
+}
+
+/**
+ * Deinitialize packet processor.
+ *
+ * @return
+ * 0 on success, negative error value otherwise.
+ */
+static void
+mrvl_deinit_pp2(void)
+{
+ mrvl_pp2_fixup_deinit();
+ pp2_deinit();
+}
+
static inline void
mrvl_fill_shadowq(struct mrvl_shadow_txq *sq, struct rte_mbuf *buf)
{
sq->size++;
}
+/**
+ * Deinitialize per-lcore MUSDK hardware interfaces (hifs).
+ */
+static void
+mrvl_deinit_hifs(void)
+{
+ int i;
+
+ for (i = mrvl_lcore_first; i <= mrvl_lcore_last; i++) {
+ if (hifs[i])
+ pp2_hif_deinit(hifs[i]);
+ }
+ used_hifs = MRVL_MUSDK_HIFS_RESERVED;
+ memset(hifs, 0, sizeof(hifs));
+}
+
static inline void
mrvl_fill_desc(struct pp2_ppio_desc *desc, struct rte_mbuf *buf)
{
return size;
}
-static inline int
-mrvl_reserve_bit(int *bitmap, int max)
-{
- int n = sizeof(*bitmap) * 8 - __builtin_clz(*bitmap);
-
- if (n >= max)
- return -1;
-
- *bitmap |= 1 << n;
-
- return n;
-}
-
static int
mrvl_init_hif(int core_id)
{
return -EINVAL;
}
- if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)
+ if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -
MRVL_PP2_ETH_HDRS_LEN;
+ if (dev->data->mtu > priv->max_mtu) {
+ MRVL_LOG(ERR, "inherit MTU %u from max_rx_pkt_len %u is larger than max_mtu %u\n",
+ dev->data->mtu,
+ dev->data->dev_conf.rxmode.max_rx_pkt_len,
+ priv->max_mtu);
+ return -EINVAL;
+ }
+ }
if (dev->data->dev_conf.txmode.offloads & DEV_TX_OFFLOAD_MULTI_SEGS)
priv->multiseg = 1;
if (dev->data->promiscuous == 1)
mrvl_promiscuous_enable(dev);
+ if (priv->flow_ctrl) {
+ ret = mrvl_flow_ctrl_set(dev, &priv->fc_conf);
+ if (ret) {
+ MRVL_LOG(ERR, "Failed to configure flow control");
+ goto out;
+ }
+ priv->flow_ctrl = 0;
+ }
+
if (dev->data->dev_link.link_status == ETH_LINK_UP) {
ret = mrvl_dev_set_link_up(dev);
if (ret) {
case SPEED_1000:
dev->data->dev_link.link_speed = ETH_SPEED_NUM_1G;
break;
+ case SPEED_2500:
+ dev->data->dev_link.link_speed = ETH_SPEED_NUM_2_5G;
+ break;
case SPEED_10000:
dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
break;
* Info structure output buffer.
*/
static int
-mrvl_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
+mrvl_dev_infos_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *info)
{
+ struct mrvl_priv *priv = dev->data->dev_private;
+
info->speed_capa = ETH_LINK_SPEED_10M |
ETH_LINK_SPEED_100M |
ETH_LINK_SPEED_1G |
+ ETH_LINK_SPEED_2_5G |
ETH_LINK_SPEED_10G;
info->max_rx_queues = MRVL_PP2_RXQ_MAX;
info->default_rxconf.rx_drop_en = 1;
info->max_rx_pktlen = MRVL_PKT_SIZE_MAX;
+ info->max_mtu = priv->max_mtu;
return 0;
}
struct mrvl_priv *priv = dev->data->dev_private;
int ret, en;
- if (!priv)
- return -EPERM;
+ if (!priv->ppio) {
+ memcpy(fc_conf, &priv->fc_conf, sizeof(struct rte_eth_fc_conf));
+ return 0;
+ }
+ fc_conf->autoneg = 1;
ret = pp2_ppio_get_rx_pause(priv->ppio, &en);
if (ret) {
MRVL_LOG(ERR, "Failed to read rx pause state");
int ret;
int rx_en, tx_en;
- if (!priv)
- return -EPERM;
-
if (fc_conf->high_water ||
fc_conf->low_water ||
fc_conf->pause_time ||
- fc_conf->mac_ctrl_frame_fwd ||
- fc_conf->autoneg) {
+ fc_conf->mac_ctrl_frame_fwd) {
MRVL_LOG(ERR, "Flowctrl parameter is not supported");
return -EINVAL;
}
+ if (fc_conf->autoneg == 0) {
+ MRVL_LOG(ERR, "Flowctrl Autoneg disable is not supported");
+ return -EINVAL;
+ }
+
+ if (!priv->ppio) {
+ memcpy(&priv->fc_conf, fc_conf, sizeof(struct rte_eth_fc_conf));
+ priv->flow_ctrl = 1;
+ return 0;
+ }
+
switch (fc_conf->mode) {
case RTE_FC_FULL:
rx_en = 1;
return nb_pkts;
}
-/**
- * Initialize packet processor.
- *
- * @return
- * 0 on success, negative error value otherwise.
- */
-static int
-mrvl_init_pp2(void)
-{
- struct pp2_init_params init_params;
-
- memset(&init_params, 0, sizeof(init_params));
- init_params.hif_reserved_map = MRVL_MUSDK_HIFS_RESERVED;
- init_params.bm_pool_reserved_map = MRVL_MUSDK_BPOOLS_RESERVED;
- init_params.rss_tbl_reserved_map = MRVL_MUSDK_RSS_RESERVED;
-
- return pp2_init(&init_params);
-}
-
-/**
- * Deinitialize packet processor.
- *
- * @return
- * 0 on success, negative error value otherwise.
- */
-static void
-mrvl_deinit_pp2(void)
-{
- pp2_deinit();
-}
-
/**
* Create private device structure.
*
struct pp2_bpool_params bpool_params;
char match[MRVL_MATCH_LEN];
struct mrvl_priv *priv;
+ uint16_t max_frame_size;
int ret, bpool_bit;
priv = rte_zmalloc_socket(dev_name, sizeof(*priv), 0, rte_socket_id());
if (ret)
goto out_free_priv;
+ ret = pp2_ppio_get_l4_cksum_max_frame_size(priv->pp_id, priv->ppio_id,
+ &max_frame_size);
+ if (ret)
+ goto out_free_priv;
+
+ priv->max_mtu = max_frame_size + RTE_ETHER_CRC_LEN -
+ MRVL_PP2_ETH_HDRS_LEN;
+
bpool_bit = mrvl_reserve_bit(&used_bpools[priv->pp_id],
PP2_BPOOL_NUM_POOLS);
if (bpool_bit < 0)
return 0;
}
-/**
- * Deinitialize per-lcore MUSDK hardware interfaces (hifs).
- */
-static void
-mrvl_deinit_hifs(void)
-{
- int i;
-
- for (i = mrvl_lcore_first; i <= mrvl_lcore_last; i++) {
- if (hifs[i])
- pp2_hif_deinit(hifs[i]);
- }
- used_hifs = MRVL_MUSDK_HIFS_RESERVED;
- memset(hifs, 0, sizeof(hifs));
-}
-
/**
* DPDK callback to register the virtual device.
*