net/dpaa2: add support for MAC address filtering
authorHemant Agrawal <hemant.agrawal@nxp.com>
Fri, 26 May 2017 06:51:16 +0000 (12:21 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 12 Jun 2017 09:41:26 +0000 (10:41 +0100)
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
doc/guides/nics/features/dpaa2.ini
drivers/net/dpaa2/dpaa2_ethdev.c
drivers/net/dpaa2/mc/dpni.c
drivers/net/dpaa2/mc/fsl_dpni.h
drivers/net/dpaa2/mc/fsl_dpni_cmd.h

index d43f404..470853c 100644 (file)
@@ -8,6 +8,7 @@ Link status          = Y
 Queue start/stop     = Y
 MTU update           = Y
 Promiscuous mode     = Y
+Unicast MAC filter   = Y
 RSS hash             = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
index 0526e26..5180871 100644 (file)
@@ -672,6 +672,78 @@ dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
        return 0;
 }
 
+static int
+dpaa2_dev_add_mac_addr(struct rte_eth_dev *dev,
+                      struct ether_addr *addr,
+                      __rte_unused uint32_t index,
+                      __rte_unused uint32_t pool)
+{
+       int ret;
+       struct dpaa2_dev_priv *priv = dev->data->dev_private;
+       struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+
+       PMD_INIT_FUNC_TRACE();
+
+       if (dpni == NULL) {
+               RTE_LOG(ERR, PMD, "dpni is NULL");
+               return -1;
+       }
+
+       ret = dpni_add_mac_addr(dpni, CMD_PRI_LOW,
+                               priv->token, addr->addr_bytes);
+       if (ret)
+               RTE_LOG(ERR, PMD, "error: Adding the MAC ADDR failed:"
+                       " err = %d", ret);
+       return 0;
+}
+
+static void
+dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev,
+                         uint32_t index)
+{
+       int ret;
+       struct dpaa2_dev_priv *priv = dev->data->dev_private;
+       struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+       struct rte_eth_dev_data *data = dev->data;
+       struct ether_addr *macaddr;
+
+       PMD_INIT_FUNC_TRACE();
+
+       macaddr = &data->mac_addrs[index];
+
+       if (dpni == NULL) {
+               RTE_LOG(ERR, PMD, "dpni is NULL");
+               return;
+       }
+
+       ret = dpni_remove_mac_addr(dpni, CMD_PRI_LOW,
+                                  priv->token, macaddr->addr_bytes);
+       if (ret)
+               RTE_LOG(ERR, PMD, "error: Removing the MAC ADDR failed:"
+                       " err = %d", ret);
+}
+
+static void
+dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
+                      struct ether_addr *addr)
+{
+       int ret;
+       struct dpaa2_dev_priv *priv = dev->data->dev_private;
+       struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+
+       PMD_INIT_FUNC_TRACE();
+
+       if (dpni == NULL) {
+               RTE_LOG(ERR, PMD, "dpni is NULL");
+               return;
+       }
+
+       ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW,
+                                       priv->token, addr->addr_bytes);
+
+       if (ret)
+               RTE_LOG(ERR, PMD, "error: Setting the MAC ADDR failed %d", ret);
+}
 static
 void dpaa2_dev_stats_get(struct rte_eth_dev *dev,
                         struct rte_eth_stats *stats)
@@ -720,7 +792,11 @@ void dpaa2_dev_stats_get(struct rte_eth_dev *dev,
        if (retcode)
                goto err;
 
-       stats->ierrors = value.page_2.ingress_discarded_frames;
+       /* Ingress drop frame count due to configured rules */
+       stats->ierrors = value.page_2.ingress_filtered_frames;
+       /* Ingress drop frame count due to error */
+       stats->ierrors += value.page_2.ingress_discarded_frames;
+
        stats->oerrors = value.page_2.egress_discarded_frames;
        stats->imissed = value.page_2.ingress_nobuffer_discards;
 
@@ -822,6 +898,9 @@ static struct eth_dev_ops dpaa2_ethdev_ops = {
        .rx_queue_release  = dpaa2_dev_rx_queue_release,
        .tx_queue_setup    = dpaa2_dev_tx_queue_setup,
        .tx_queue_release  = dpaa2_dev_tx_queue_release,
+       .mac_addr_add         = dpaa2_dev_add_mac_addr,
+       .mac_addr_remove      = dpaa2_dev_remove_mac_addr,
+       .mac_addr_set         = dpaa2_dev_set_mac_addr,
 };
 
 static int
index 21aedef..4cea5f2 100644 (file)
@@ -591,6 +591,82 @@ int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
        return 0;
 }
 
+int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
+                     uint32_t cmd_flags,
+                     uint16_t token,
+                     const uint8_t mac_addr[6])
+{
+       struct mc_command cmd = { 0 };
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR,
+                                         cmd_flags,
+                                         token);
+       DPNI_CMD_ADD_MAC_ADDR(cmd, mac_addr);
+
+       /* send command to mc*/
+       return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
+                        uint32_t cmd_flags,
+                        uint16_t token,
+                        const uint8_t mac_addr[6])
+{
+       struct mc_command cmd = { 0 };
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR,
+                                         cmd_flags,
+                                         token);
+       DPNI_CMD_REMOVE_MAC_ADDR(cmd, mac_addr);
+
+       /* send command to mc*/
+       return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_clear_mac_filters(struct fsl_mc_io *mc_io,
+                          uint32_t cmd_flags,
+                          uint16_t token,
+                          int unicast,
+                          int multicast)
+{
+       struct mc_command cmd = { 0 };
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_MAC_FILTERS,
+                                         cmd_flags,
+                                         token);
+       DPNI_CMD_CLEAR_MAC_FILTERS(cmd, unicast, multicast);
+
+       /* send command to mc*/
+       return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
+                          uint32_t cmd_flags,
+                          uint16_t token,
+                          uint8_t mac_addr[6])
+{
+       struct mc_command cmd = { 0 };
+       int err;
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PORT_MAC_ADDR,
+                                         cmd_flags,
+                                         token);
+
+       /* send command to mc*/
+       err = mc_send_command(mc_io, &cmd);
+       if (err)
+               return err;
+
+       /* retrieve response parameters */
+       DPNI_RSP_GET_PORT_MAC_ADDR(cmd, mac_addr);
+
+       return 0;
+}
+
 int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
                        uint32_t cmd_flags,
                        uint16_t token,
index 8783af6..dbb3b20 100644 (file)
@@ -854,6 +854,51 @@ int dpni_get_primary_mac_addr(struct fsl_mc_io     *mc_io,
                              uint16_t          token,
                              uint8_t           mac_addr[6]);
 
+/**
+ * dpni_add_mac_addr() - Add MAC address filter
+ * @mc_io:     Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:     Token of DPNI object
+ * @mac_addr:  MAC address to add
+ *
+ * Return:     '0' on Success; Error code otherwise.
+ */
+int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
+                     uint32_t          cmd_flags,
+                     uint16_t          token,
+                     const uint8_t     mac_addr[6]);
+
+/**
+ * dpni_remove_mac_addr() - Remove MAC address filter
+ * @mc_io:     Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:     Token of DPNI object
+ * @mac_addr:  MAC address to remove
+ *
+ * Return:     '0' on Success; Error code otherwise.
+ */
+int dpni_remove_mac_addr(struct fsl_mc_io      *mc_io,
+                        uint32_t               cmd_flags,
+                        uint16_t               token,
+                        const uint8_t          mac_addr[6]);
+
+/**
+ * dpni_clear_mac_filters() - Clear all unicast and/or multicast MAC filters
+ * @mc_io:     Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:     Token of DPNI object
+ * @unicast:   Set to '1' to clear unicast addresses
+ * @multicast: Set to '1' to clear multicast addresses
+ *
+ * The primary MAC address is not cleared by this operation.
+ *
+ * Return:     '0' on Success; Error code otherwise.
+ */
+int dpni_clear_mac_filters(struct fsl_mc_io    *mc_io,
+                          uint32_t             cmd_flags,
+                          uint16_t             token,
+                          int                  unicast,
+                          int                  multicast);
 
 /**
  * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
index 41a4d54..1ae734a 100644 (file)
@@ -69,6 +69,9 @@
 #define DPNI_CMDID_GET_UNICAST_PROMISC                 ((0x223 << 4) | (0x1))
 #define DPNI_CMDID_SET_PRIM_MAC                        ((0x224 << 4) | (0x1))
 #define DPNI_CMDID_GET_PRIM_MAC                        ((0x225 << 4) | (0x1))
+#define DPNI_CMDID_ADD_MAC_ADDR                        ((0x226 << 4) | (0x1))
+#define DPNI_CMDID_REMOVE_MAC_ADDR                     ((0x227 << 4) | (0x1))
+#define DPNI_CMDID_CLR_MAC_FILTERS                     ((0x228 << 4) | (0x1))
 
 #define DPNI_CMDID_SET_RX_TC_DIST                      ((0x235 << 4) | (0x1))
 
@@ -273,6 +276,45 @@ do { \
        MC_RSP_OP(cmd, 0, 56, 8,  uint8_t,  mac_addr[0]); \
 } while (0)
 
+#define DPNI_RSP_GET_PORT_MAC_ADDR(cmd, mac_addr) \
+do { \
+       MC_RSP_OP(cmd, 0, 16, 8,  uint8_t,  mac_addr[5]); \
+       MC_RSP_OP(cmd, 0, 24, 8,  uint8_t,  mac_addr[4]); \
+       MC_RSP_OP(cmd, 0, 32, 8,  uint8_t,  mac_addr[3]); \
+       MC_RSP_OP(cmd, 0, 40, 8,  uint8_t,  mac_addr[2]); \
+       MC_RSP_OP(cmd, 0, 48, 8,  uint8_t,  mac_addr[1]); \
+       MC_RSP_OP(cmd, 0, 56, 8,  uint8_t,  mac_addr[0]); \
+} while (0)
+
+/*                cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_ADD_MAC_ADDR(cmd, mac_addr) \
+do { \
+       MC_CMD_OP(cmd, 0, 16, 8,  uint8_t,  mac_addr[5]); \
+       MC_CMD_OP(cmd, 0, 24, 8,  uint8_t,  mac_addr[4]); \
+       MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  mac_addr[3]); \
+       MC_CMD_OP(cmd, 0, 40, 8,  uint8_t,  mac_addr[2]); \
+       MC_CMD_OP(cmd, 0, 48, 8,  uint8_t,  mac_addr[1]); \
+       MC_CMD_OP(cmd, 0, 56, 8,  uint8_t,  mac_addr[0]); \
+} while (0)
+
+/*                cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_REMOVE_MAC_ADDR(cmd, mac_addr) \
+do { \
+       MC_CMD_OP(cmd, 0, 16, 8,  uint8_t,  mac_addr[5]); \
+       MC_CMD_OP(cmd, 0, 24, 8,  uint8_t,  mac_addr[4]); \
+       MC_CMD_OP(cmd, 0, 32, 8,  uint8_t,  mac_addr[3]); \
+       MC_CMD_OP(cmd, 0, 40, 8,  uint8_t,  mac_addr[2]); \
+       MC_CMD_OP(cmd, 0, 48, 8,  uint8_t,  mac_addr[1]); \
+       MC_CMD_OP(cmd, 0, 56, 8,  uint8_t,  mac_addr[0]); \
+} while (0)
+
+/*                cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_CLEAR_MAC_FILTERS(cmd, unicast, multicast) \
+do { \
+       MC_CMD_OP(cmd, 0, 0,  1,  int,      unicast); \
+       MC_CMD_OP(cmd, 0, 1,  1,  int,      multicast); \
+} while (0)
+
 
 /*                cmd, param, offset, width, type, arg_name */
 #define DPNI_CMD_SET_RX_TC_DIST(cmd, tc_id, cfg) \