Skip to content

Commit b56bbaf

Browse files
author
Paolo Abeni
committed
Merge branch 'net-airoha-fix-ipv6-hw-acceleration'
Lorenzo Bianconi says: ==================== net: airoha: Fix IPv6 hw acceleration Fix IPv6 hw acceleration in bridge mode resolving ib2 and airoha_foe_mac_info_common overwrite in airoha_ppe_foe_commit_subflow_entry routine. Introduce UPDMEM source-mac table used to set source mac address for L3 IPv6 hw accelerated traffic. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents d3f2a95 + c86fac5 commit b56bbaf

File tree

4 files changed

+55
-12
lines changed

4 files changed

+55
-12
lines changed

drivers/net/ethernet/airoha/airoha_eth.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
8484
val = (addr[3] << 16) | (addr[4] << 8) | addr[5];
8585
airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val);
8686
airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val);
87+
88+
airoha_ppe_init_upd_mem(port);
8789
}
8890

8991
static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,

drivers/net/ethernet/airoha/airoha_eth.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb,
614614
int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data);
615615
int airoha_ppe_init(struct airoha_eth *eth);
616616
void airoha_ppe_deinit(struct airoha_eth *eth);
617+
void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port);
617618
struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe,
618619
u32 hash);
619620
void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash,

drivers/net/ethernet/airoha/airoha_ppe.c

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
223223
int dsa_port = airoha_get_dsa_port(&dev);
224224
struct airoha_foe_mac_info_common *l2;
225225
u32 qdata, ports_pad, val;
226+
u8 smac_id = 0xf;
226227

227228
memset(hwe, 0, sizeof(*hwe));
228229

@@ -257,6 +258,8 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
257258
*/
258259
if (airhoa_is_lan_gdm_port(port))
259260
val |= AIROHA_FOE_IB2_FAST_PATH;
261+
262+
smac_id = port->id;
260263
}
261264

262265
if (is_multicast_ether_addr(data->eth.h_dest))
@@ -291,7 +294,7 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
291294
hwe->ipv4.l2.src_mac_lo =
292295
get_unaligned_be16(data->eth.h_source + 4);
293296
} else {
294-
l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, 0xf);
297+
l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, smac_id);
295298
}
296299

297300
if (data->vlan.num) {
@@ -636,7 +639,6 @@ airoha_ppe_foe_commit_subflow_entry(struct airoha_ppe *ppe,
636639
u32 mask = AIROHA_FOE_IB1_BIND_PACKET_TYPE | AIROHA_FOE_IB1_BIND_UDP;
637640
struct airoha_foe_entry *hwe_p, hwe;
638641
struct airoha_flow_table_entry *f;
639-
struct airoha_foe_mac_info *l2;
640642
int type;
641643

642644
hwe_p = airoha_ppe_foe_get_entry(ppe, hash);
@@ -653,18 +655,25 @@ airoha_ppe_foe_commit_subflow_entry(struct airoha_ppe *ppe,
653655

654656
memcpy(&hwe, hwe_p, sizeof(*hwe_p));
655657
hwe.ib1 = (hwe.ib1 & mask) | (e->data.ib1 & ~mask);
656-
l2 = &hwe.bridge.l2;
657-
memcpy(l2, &e->data.bridge.l2, sizeof(*l2));
658658

659659
type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe.ib1);
660-
if (type == PPE_PKT_TYPE_IPV4_HNAPT)
661-
memcpy(&hwe.ipv4.new_tuple, &hwe.ipv4.orig_tuple,
662-
sizeof(hwe.ipv4.new_tuple));
663-
else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T &&
664-
l2->common.etype == ETH_P_IP)
665-
l2->common.etype = ETH_P_IPV6;
666-
667-
hwe.bridge.ib2 = e->data.bridge.ib2;
660+
if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) {
661+
memcpy(&hwe.ipv6.l2, &e->data.bridge.l2, sizeof(hwe.ipv6.l2));
662+
hwe.ipv6.ib2 = e->data.bridge.ib2;
663+
/* setting smac_id to 0xf instruct the hw to keep original
664+
* source mac address
665+
*/
666+
hwe.ipv6.l2.src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID,
667+
0xf);
668+
} else {
669+
memcpy(&hwe.bridge.l2, &e->data.bridge.l2,
670+
sizeof(hwe.bridge.l2));
671+
hwe.bridge.ib2 = e->data.bridge.ib2;
672+
if (type == PPE_PKT_TYPE_IPV4_HNAPT)
673+
memcpy(&hwe.ipv4.new_tuple, &hwe.ipv4.orig_tuple,
674+
sizeof(hwe.ipv4.new_tuple));
675+
}
676+
668677
hwe.bridge.data = e->data.bridge.data;
669678
airoha_ppe_foe_commit_entry(ppe, &hwe, hash);
670679

@@ -1238,6 +1247,27 @@ void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb,
12381247
airoha_ppe_foe_insert_entry(ppe, skb, hash);
12391248
}
12401249

1250+
void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
1251+
{
1252+
struct airoha_eth *eth = port->qdma->eth;
1253+
struct net_device *dev = port->dev;
1254+
const u8 *addr = dev->dev_addr;
1255+
u32 val;
1256+
1257+
val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
1258+
airoha_fe_wr(eth, REG_UPDMEM_DATA(0), val);
1259+
airoha_fe_wr(eth, REG_UPDMEM_CTRL(0),
1260+
FIELD_PREP(PPE_UPDMEM_ADDR_MASK, port->id) |
1261+
PPE_UPDMEM_WR_MASK | PPE_UPDMEM_REQ_MASK);
1262+
1263+
val = (addr[0] << 8) | addr[1];
1264+
airoha_fe_wr(eth, REG_UPDMEM_DATA(0), val);
1265+
airoha_fe_wr(eth, REG_UPDMEM_CTRL(0),
1266+
FIELD_PREP(PPE_UPDMEM_ADDR_MASK, port->id) |
1267+
FIELD_PREP(PPE_UPDMEM_OFFSET_MASK, 1) |
1268+
PPE_UPDMEM_WR_MASK | PPE_UPDMEM_REQ_MASK);
1269+
}
1270+
12411271
int airoha_ppe_init(struct airoha_eth *eth)
12421272
{
12431273
struct airoha_ppe *ppe;

drivers/net/ethernet/airoha/airoha_regs.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,16 @@
313313
#define REG_PPE_RAM_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x320)
314314
#define REG_PPE_RAM_ENTRY(_m, _n) (REG_PPE_RAM_BASE(_m) + ((_n) << 2))
315315

316+
#define REG_UPDMEM_CTRL(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x370)
317+
#define PPE_UPDMEM_ACK_MASK BIT(31)
318+
#define PPE_UPDMEM_ADDR_MASK GENMASK(11, 8)
319+
#define PPE_UPDMEM_OFFSET_MASK GENMASK(7, 4)
320+
#define PPE_UPDMEM_SEL_MASK GENMASK(3, 2)
321+
#define PPE_UPDMEM_WR_MASK BIT(1)
322+
#define PPE_UPDMEM_REQ_MASK BIT(0)
323+
324+
#define REG_UPDMEM_DATA(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x374)
325+
316326
#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280)
317327
#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284)
318328
#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288)

0 commit comments

Comments
 (0)