net/mvpp2: update start header name in config file
[dpdk.git] / drivers / net / mvpp2 / mrvl_ethdev.c
index 0d202b1..fa5e6f7 100644 (file)
@@ -90,6 +90,8 @@ static int used_bpools[PP2_NUM_PKT_PROC] = {
 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];
@@ -162,6 +164,8 @@ static int
 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),      \
@@ -189,6 +193,112 @@ static struct {
        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)
 {
@@ -205,6 +315,22 @@ 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)
 {
@@ -226,19 +352,6 @@ mrvl_get_bpool_size(int pp2_id, int pool_id)
        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)
 {
@@ -385,9 +498,17 @@ mrvl_dev_configure(struct rte_eth_dev *dev)
                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;
@@ -796,6 +917,15 @@ mrvl_dev_start(struct rte_eth_dev *dev)
        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) {
@@ -1077,6 +1207,9 @@ mrvl_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
        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;
@@ -1568,12 +1701,15 @@ mrvl_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
  *   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;
@@ -1602,6 +1738,7 @@ mrvl_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
        info->default_rxconf.rx_drop_en = 1;
 
        info->max_rx_pktlen = MRVL_PKT_SIZE_MAX;
+       info->max_mtu = priv->max_mtu;
 
        return 0;
 }
@@ -2024,9 +2161,12 @@ mrvl_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
        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");
@@ -2070,19 +2210,26 @@ mrvl_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
        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;
@@ -2889,37 +3036,6 @@ mrvl_tx_sg_pkt_burst(void *txq, struct rte_mbuf **tx_pkts,
        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.
  *
@@ -2935,6 +3051,7 @@ mrvl_priv_create(const char *dev_name)
        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());
@@ -2946,6 +3063,14 @@ mrvl_priv_create(const char *dev_name)
        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)
@@ -3059,22 +3184,6 @@ mrvl_get_ifnames(const char *key __rte_unused, const char *value,
        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.
  *