return 0;
}
+/*
+ * Sets up an egress interface for L3 actions Actions for ip4/6_icmp_redirect, ip4/6_pbr_icmp_redirect are:
+ * 0: FORWARD, 1: DROP, 2: TRAP2CPU, 3: COPY2CPU, 4: TRAP2MASTERCPU, 5: COPY2MASTERCPU, 6: HARDDROP
+ * idx is the index in the HW interface table: idx < 0x80
+ */
+__maybe_unused
+static void otto_l3_930x_set_egress_intf(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_intf *intf)
+{
+ struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 4);
+ u32 u, v;
+
+ /* The table has 2 registers */
+ u = (intf->vid & 0xfff) << 9;
+ u |= (intf->smac_idx & 0x3f) << 3;
+ u |= (intf->ip4_mtu_id & 0x7);
+
+ v = (intf->ip6_mtu_id & 0x7) << 28;
+ v |= (intf->ttl_scope & 0xff) << 20;
+ v |= (intf->hl_scope & 0xff) << 12;
+ v |= (intf->ip4_icmp_redirect & 0x7) << 9;
+ v |= (intf->ip6_icmp_redirect & 0x7) << 6;
+ v |= (intf->ip4_pbr_icmp_redirect & 0x7) << 3;
+ v |= (intf->ip6_pbr_icmp_redirect & 0x7);
+
+ sw_w32(u, rtl_table_data(r, 0));
+ sw_w32(v, rtl_table_data(r, 1));
+
+ dev_dbg(ctrl->dev, "writing to index %d: %08x %08x\n", idx, u, v);
+ rtl_table_write(r, idx & 0x7f);
+ rtl_table_release(r);
+}
+
static int otto_l3_alloc_egress_intf(struct otto_l3_ctrl *ctrl, u64 mac, int vlan)
{
struct rtl838x_switch_priv *priv = ctrl->priv;
- struct rtl838x_l3_intf intf;
+ struct otto_l3_intf intf;
int free_mac = -1;
u64 m;
intf.hl_scope = 1; /* Hop Limit */
intf.ip4_icmp_redirect = intf.ip6_icmp_redirect = 2; /* FORWARD */
intf.ip4_pbr_icmp_redirect = intf.ip6_pbr_icmp_redirect = 2; /* FORWARD; */
- priv->r->set_l3_egress_intf(free_mac, &intf);
+ ctrl->cfg->set_egress_intf(ctrl, free_mac, &intf);
priv->r->set_l3_egress_mac(L3_EGRESS_DMACS + free_mac, mac);
const struct otto_l3_config otto_l3_930x_cfg = {
#ifdef CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD
.get_egress_mac = otto_l3_930x_get_egress_mac,
+ .set_egress_intf = otto_l3_930x_set_egress_intf,
.host_route_write = otto_l3_930x_host_route_write,
.get_router_mac = otto_l3_930x_get_router_mac,
.set_router_mac = otto_l3_930x_set_router_mac,
#include "rtl-otto.h"
#define MAX_HOST_ROUTES 1536
+#define MAX_INTERFACES 100
/* An entry in the RTL93XX SoC's ROUTER_MAC tables setting up a termination point
* for the L3 routing system. Packets arriving and matching an entry in this table
u64 mac_mask;
};
+struct otto_l3_intf {
+ u16 vid;
+ u8 smac_idx;
+ u8 ip4_mtu_id;
+ u8 ip6_mtu_id;
+ u16 ip4_mtu;
+ u16 ip6_mtu;
+ u8 ttl_scope;
+ u8 hl_scope;
+ u8 ip4_icmp_redirect;
+ u8 ip6_icmp_redirect;
+ u8 ip4_pbr_icmp_redirect;
+ u8 ip6_pbr_icmp_redirect;
+};
struct otto_l3_config {
+ void (*set_egress_intf)(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_intf *intf);
u64 (*get_egress_mac)(struct otto_l3_ctrl *ctrl, u32 idx);
void (*host_route_write)(struct otto_l3_ctrl *ctrl, int idx, struct otto_l3_route *rt);
void (*get_router_mac)(struct otto_l3_ctrl *ctrl, u32 idx, struct otto_l3_router_mac *m);
struct notifier_block ne_nb;
struct rhltable routes;
unsigned long host_route_use_bm[MAX_HOST_ROUTES / 32];
+ struct otto_l3_intf *interfaces[MAX_INTERFACES];
};
struct otto_l3_route_attr {
#define MAX_ROUTES 512
#define MAX_INTF_MTUS 8
#define DEFAULT_MTU 1536
-#define MAX_INTERFACES 100
#define MAX_ROUTER_MACS 64
#define L3_EGRESS_DMACS 2048
#define MAX_SMACS 64
bool bypass_ibc_sc; /* Bypass Ingress Bandwidth Control and Storm Control */
};
-struct rtl838x_l3_intf {
- u16 vid;
- u8 smac_idx;
- u8 ip4_mtu_id;
- u8 ip6_mtu_id;
- u16 ip4_mtu;
- u16 ip6_mtu;
- u8 ttl_scope;
- u8 hl_scope;
- u8 ip4_icmp_redirect;
- u8 ip6_icmp_redirect;
- u8 ip4_pbr_icmp_redirect;
- u8 ip6_pbr_icmp_redirect;
-};
-
struct rtl838x_switch_priv;
struct rtl83xx_flow {
int (*l3_setup)(struct rtl838x_switch_priv *priv);
void (*set_l3_egress_mac)(u32 idx, u64 mac);
int (*find_l3_slot)(struct otto_l3_route *rt, bool must_exist);
- void (*set_l3_egress_intf)(int idx, struct rtl838x_l3_intf *intf);
void (*set_receive_management_action)(int port, rma_ctrl_t type, action_type_t action);
void (*led_init)(struct rtl838x_switch_priv *priv);
void (*qos_init)(struct rtl838x_switch_priv *priv);
unsigned long octet_cntr_use_bm[MAX_COUNTERS >> 5];
unsigned long packet_cntr_use_bm[MAX_COUNTERS >> 4];
unsigned long route_use_bm[MAX_ROUTES >> 5];
- struct rtl838x_l3_intf *interfaces[MAX_INTERFACES];
u16 intf_mtus[MAX_INTF_MTUS];
int intf_mtu_count[MAX_INTF_MTUS];
#ifdef CONFIG_NET_DSA_RTL83XX_RTL930X_L3_OFFLOAD
-/* Sets up an egress interface for L3 actions
- * Actions for ip4/6_icmp_redirect, ip4/6_pbr_icmp_redirect are:
- * 0: FORWARD, 1: DROP, 2: TRAP2CPU, 3: COPY2CPU, 4: TRAP2MASTERCPU 5: COPY2MASTERCPU
- * 6: HARDDROP
- * idx is the index in the HW interface table: idx < 0x80
- */
-static void rtl930x_set_l3_egress_intf(int idx, struct rtl838x_l3_intf *intf)
-{
- u32 u, v;
- /* Read L3_EGR_INTF table (4) via register RTL9300_TBL_1 */
- struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 4);
-
- /* The table has 2 registers */
- u = (intf->vid & 0xfff) << 9;
- u |= (intf->smac_idx & 0x3f) << 3;
- u |= (intf->ip4_mtu_id & 0x7);
-
- v = (intf->ip6_mtu_id & 0x7) << 28;
- v |= (intf->ttl_scope & 0xff) << 20;
- v |= (intf->hl_scope & 0xff) << 12;
- v |= (intf->ip4_icmp_redirect & 0x7) << 9;
- v |= (intf->ip6_icmp_redirect & 0x7) << 6;
- v |= (intf->ip4_pbr_icmp_redirect & 0x7) << 3;
- v |= (intf->ip6_pbr_icmp_redirect & 0x7);
-
- sw_w32(u, rtl_table_data(r, 0));
- sw_w32(v, rtl_table_data(r, 1));
-
- pr_debug("%s writing to index %d: %08x %08x\n", __func__, idx, u, v);
- rtl_table_write(r, idx & 0x7f);
- rtl_table_release(r);
-}
-
/* Set the Destination-MAC of a route or the Source MAC of an L3 egress interface
* in the SoC's L3_EGR_INTF_MAC table
* Indexes 0-2047 are DMACs, 2048+ are SMACs
.l3_setup = rtl930x_l3_setup,
.set_l3_egress_mac = rtl930x_set_l3_egress_mac,
.find_l3_slot = rtl930x_find_l3_slot,
- .set_l3_egress_intf = rtl930x_set_l3_egress_intf,
#endif
.led_init = rtl930x_led_init,
.enable_learning = rtldsa_930x_enable_learning,