net: bcmgenet: code movement
authorDoug Berger <opendmb@gmail.com>
Wed, 29 Apr 2020 20:02:04 +0000 (13:02 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 29 Apr 2020 23:55:22 +0000 (16:55 -0700)
The Hardware Filter Block code will be used by ethtool functions
when defining flow types so this commit moves the functions in the
file to prevent the need for prototype declarations.

This is broken out to facilitate review.

Signed-off-by: Doug Berger <opendmb@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/genet/bcmgenet.c

index b37ef05c5083a268c00997b974029e12f99869a5..ad41944d2cc03bb243a7ed4598b2d2c295592fcf 100644 (file)
@@ -459,6 +459,160 @@ static inline void bcmgenet_rdma_ring_writel(struct bcmgenet_priv *priv,
                        genet_dma_ring_regs[r]);
 }
 
+static bool bcmgenet_hfb_is_filter_enabled(struct bcmgenet_priv *priv,
+                                          u32 f_index)
+{
+       u32 offset;
+       u32 reg;
+
+       offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32);
+       reg = bcmgenet_hfb_reg_readl(priv, offset);
+       return !!(reg & (1 << (f_index % 32)));
+}
+
+static void bcmgenet_hfb_enable_filter(struct bcmgenet_priv *priv, u32 f_index)
+{
+       u32 offset;
+       u32 reg;
+
+       offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32);
+       reg = bcmgenet_hfb_reg_readl(priv, offset);
+       reg |= (1 << (f_index % 32));
+       bcmgenet_hfb_reg_writel(priv, reg, offset);
+}
+
+static void bcmgenet_hfb_set_filter_rx_queue_mapping(struct bcmgenet_priv *priv,
+                                                    u32 f_index, u32 rx_queue)
+{
+       u32 offset;
+       u32 reg;
+
+       offset = f_index / 8;
+       reg = bcmgenet_rdma_readl(priv, DMA_INDEX2RING_0 + offset);
+       reg &= ~(0xF << (4 * (f_index % 8)));
+       reg |= ((rx_queue & 0xF) << (4 * (f_index % 8)));
+       bcmgenet_rdma_writel(priv, reg, DMA_INDEX2RING_0 + offset);
+}
+
+static void bcmgenet_hfb_set_filter_length(struct bcmgenet_priv *priv,
+                                          u32 f_index, u32 f_length)
+{
+       u32 offset;
+       u32 reg;
+
+       offset = HFB_FLT_LEN_V3PLUS +
+                ((priv->hw_params->hfb_filter_cnt - 1 - f_index) / 4) *
+                sizeof(u32);
+       reg = bcmgenet_hfb_reg_readl(priv, offset);
+       reg &= ~(0xFF << (8 * (f_index % 4)));
+       reg |= ((f_length & 0xFF) << (8 * (f_index % 4)));
+       bcmgenet_hfb_reg_writel(priv, reg, offset);
+}
+
+static int bcmgenet_hfb_find_unused_filter(struct bcmgenet_priv *priv)
+{
+       u32 f_index;
+
+       for (f_index = 0; f_index < priv->hw_params->hfb_filter_cnt; f_index++)
+               if (!bcmgenet_hfb_is_filter_enabled(priv, f_index))
+                       return f_index;
+
+       return -ENOMEM;
+}
+
+/* bcmgenet_hfb_add_filter
+ *
+ * Add new filter to Hardware Filter Block to match and direct Rx traffic to
+ * desired Rx queue.
+ *
+ * f_data is an array of unsigned 32-bit integers where each 32-bit integer
+ * provides filter data for 2 bytes (4 nibbles) of Rx frame:
+ *
+ * bits 31:20 - unused
+ * bit  19    - nibble 0 match enable
+ * bit  18    - nibble 1 match enable
+ * bit  17    - nibble 2 match enable
+ * bit  16    - nibble 3 match enable
+ * bits 15:12 - nibble 0 data
+ * bits 11:8  - nibble 1 data
+ * bits 7:4   - nibble 2 data
+ * bits 3:0   - nibble 3 data
+ *
+ * Example:
+ * In order to match:
+ * - Ethernet frame type = 0x0800 (IP)
+ * - IP version field = 4
+ * - IP protocol field = 0x11 (UDP)
+ *
+ * The following filter is needed:
+ * u32 hfb_filter_ipv4_udp[] = {
+ *   Rx frame offset 0x00: 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ *   Rx frame offset 0x08: 0x00000000, 0x00000000, 0x000F0800, 0x00084000,
+ *   Rx frame offset 0x10: 0x00000000, 0x00000000, 0x00000000, 0x00030011,
+ * };
+ *
+ * To add the filter to HFB and direct the traffic to Rx queue 0, call:
+ * bcmgenet_hfb_add_filter(priv, hfb_filter_ipv4_udp,
+ *                         ARRAY_SIZE(hfb_filter_ipv4_udp), 0);
+ */
+int bcmgenet_hfb_add_filter(struct bcmgenet_priv *priv, u32 *f_data,
+                           u32 f_length, u32 rx_queue)
+{
+       int f_index;
+       u32 i;
+
+       f_index = bcmgenet_hfb_find_unused_filter(priv);
+       if (f_index < 0)
+               return -ENOMEM;
+
+       if (f_length > priv->hw_params->hfb_filter_size)
+               return -EINVAL;
+
+       for (i = 0; i < f_length; i++)
+               bcmgenet_hfb_writel(priv, f_data[i],
+                       (f_index * priv->hw_params->hfb_filter_size + i) *
+                       sizeof(u32));
+
+       bcmgenet_hfb_set_filter_length(priv, f_index, 2 * f_length);
+       bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f_index, rx_queue);
+       bcmgenet_hfb_enable_filter(priv, f_index);
+       bcmgenet_hfb_reg_writel(priv, 0x1, HFB_CTRL);
+
+       return 0;
+}
+
+/* bcmgenet_hfb_clear
+ *
+ * Clear Hardware Filter Block and disable all filtering.
+ */
+static void bcmgenet_hfb_clear(struct bcmgenet_priv *priv)
+{
+       u32 i;
+
+       bcmgenet_hfb_reg_writel(priv, 0x0, HFB_CTRL);
+       bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS);
+       bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS + 4);
+
+       for (i = DMA_INDEX2RING_0; i <= DMA_INDEX2RING_7; i++)
+               bcmgenet_rdma_writel(priv, 0x0, i);
+
+       for (i = 0; i < (priv->hw_params->hfb_filter_cnt / 4); i++)
+               bcmgenet_hfb_reg_writel(priv, 0x0,
+                                       HFB_FLT_LEN_V3PLUS + i * sizeof(u32));
+
+       for (i = 0; i < priv->hw_params->hfb_filter_cnt *
+                       priv->hw_params->hfb_filter_size; i++)
+               bcmgenet_hfb_writel(priv, 0x0, i * sizeof(u32));
+}
+
+static void bcmgenet_hfb_init(struct bcmgenet_priv *priv)
+{
+       if (GENET_IS_V1(priv) || GENET_IS_V2(priv))
+               return;
+
+       bcmgenet_hfb_clear(priv);
+}
+
 static int bcmgenet_begin(struct net_device *dev)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -2759,160 +2913,6 @@ static void bcmgenet_enable_dma(struct bcmgenet_priv *priv, u32 dma_ctrl)
        bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
 }
 
-static bool bcmgenet_hfb_is_filter_enabled(struct bcmgenet_priv *priv,
-                                          u32 f_index)
-{
-       u32 offset;
-       u32 reg;
-
-       offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32);
-       reg = bcmgenet_hfb_reg_readl(priv, offset);
-       return !!(reg & (1 << (f_index % 32)));
-}
-
-static void bcmgenet_hfb_enable_filter(struct bcmgenet_priv *priv, u32 f_index)
-{
-       u32 offset;
-       u32 reg;
-
-       offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32);
-       reg = bcmgenet_hfb_reg_readl(priv, offset);
-       reg |= (1 << (f_index % 32));
-       bcmgenet_hfb_reg_writel(priv, reg, offset);
-}
-
-static void bcmgenet_hfb_set_filter_rx_queue_mapping(struct bcmgenet_priv *priv,
-                                                    u32 f_index, u32 rx_queue)
-{
-       u32 offset;
-       u32 reg;
-
-       offset = f_index / 8;
-       reg = bcmgenet_rdma_readl(priv, DMA_INDEX2RING_0 + offset);
-       reg &= ~(0xF << (4 * (f_index % 8)));
-       reg |= ((rx_queue & 0xF) << (4 * (f_index % 8)));
-       bcmgenet_rdma_writel(priv, reg, DMA_INDEX2RING_0 + offset);
-}
-
-static void bcmgenet_hfb_set_filter_length(struct bcmgenet_priv *priv,
-                                          u32 f_index, u32 f_length)
-{
-       u32 offset;
-       u32 reg;
-
-       offset = HFB_FLT_LEN_V3PLUS +
-                ((priv->hw_params->hfb_filter_cnt - 1 - f_index) / 4) *
-                sizeof(u32);
-       reg = bcmgenet_hfb_reg_readl(priv, offset);
-       reg &= ~(0xFF << (8 * (f_index % 4)));
-       reg |= ((f_length & 0xFF) << (8 * (f_index % 4)));
-       bcmgenet_hfb_reg_writel(priv, reg, offset);
-}
-
-static int bcmgenet_hfb_find_unused_filter(struct bcmgenet_priv *priv)
-{
-       u32 f_index;
-
-       for (f_index = 0; f_index < priv->hw_params->hfb_filter_cnt; f_index++)
-               if (!bcmgenet_hfb_is_filter_enabled(priv, f_index))
-                       return f_index;
-
-       return -ENOMEM;
-}
-
-/* bcmgenet_hfb_add_filter
- *
- * Add new filter to Hardware Filter Block to match and direct Rx traffic to
- * desired Rx queue.
- *
- * f_data is an array of unsigned 32-bit integers where each 32-bit integer
- * provides filter data for 2 bytes (4 nibbles) of Rx frame:
- *
- * bits 31:20 - unused
- * bit  19    - nibble 0 match enable
- * bit  18    - nibble 1 match enable
- * bit  17    - nibble 2 match enable
- * bit  16    - nibble 3 match enable
- * bits 15:12 - nibble 0 data
- * bits 11:8  - nibble 1 data
- * bits 7:4   - nibble 2 data
- * bits 3:0   - nibble 3 data
- *
- * Example:
- * In order to match:
- * - Ethernet frame type = 0x0800 (IP)
- * - IP version field = 4
- * - IP protocol field = 0x11 (UDP)
- *
- * The following filter is needed:
- * u32 hfb_filter_ipv4_udp[] = {
- *   Rx frame offset 0x00: 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- *   Rx frame offset 0x08: 0x00000000, 0x00000000, 0x000F0800, 0x00084000,
- *   Rx frame offset 0x10: 0x00000000, 0x00000000, 0x00000000, 0x00030011,
- * };
- *
- * To add the filter to HFB and direct the traffic to Rx queue 0, call:
- * bcmgenet_hfb_add_filter(priv, hfb_filter_ipv4_udp,
- *                         ARRAY_SIZE(hfb_filter_ipv4_udp), 0);
- */
-int bcmgenet_hfb_add_filter(struct bcmgenet_priv *priv, u32 *f_data,
-                           u32 f_length, u32 rx_queue)
-{
-       int f_index;
-       u32 i;
-
-       f_index = bcmgenet_hfb_find_unused_filter(priv);
-       if (f_index < 0)
-               return -ENOMEM;
-
-       if (f_length > priv->hw_params->hfb_filter_size)
-               return -EINVAL;
-
-       for (i = 0; i < f_length; i++)
-               bcmgenet_hfb_writel(priv, f_data[i],
-                       (f_index * priv->hw_params->hfb_filter_size + i) *
-                       sizeof(u32));
-
-       bcmgenet_hfb_set_filter_length(priv, f_index, 2 * f_length);
-       bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f_index, rx_queue);
-       bcmgenet_hfb_enable_filter(priv, f_index);
-       bcmgenet_hfb_reg_writel(priv, 0x1, HFB_CTRL);
-
-       return 0;
-}
-
-/* bcmgenet_hfb_clear
- *
- * Clear Hardware Filter Block and disable all filtering.
- */
-static void bcmgenet_hfb_clear(struct bcmgenet_priv *priv)
-{
-       u32 i;
-
-       bcmgenet_hfb_reg_writel(priv, 0x0, HFB_CTRL);
-       bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS);
-       bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS + 4);
-
-       for (i = DMA_INDEX2RING_0; i <= DMA_INDEX2RING_7; i++)
-               bcmgenet_rdma_writel(priv, 0x0, i);
-
-       for (i = 0; i < (priv->hw_params->hfb_filter_cnt / 4); i++)
-               bcmgenet_hfb_reg_writel(priv, 0x0,
-                                       HFB_FLT_LEN_V3PLUS + i * sizeof(u32));
-
-       for (i = 0; i < priv->hw_params->hfb_filter_cnt *
-                       priv->hw_params->hfb_filter_size; i++)
-               bcmgenet_hfb_writel(priv, 0x0, i * sizeof(u32));
-}
-
-static void bcmgenet_hfb_init(struct bcmgenet_priv *priv)
-{
-       if (GENET_IS_V1(priv) || GENET_IS_V2(priv))
-               return;
-
-       bcmgenet_hfb_clear(priv);
-}
-
 static void bcmgenet_netif_start(struct net_device *dev)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);