Skip to content

Commit ca47130

Browse files
Karicheri, Muralidharandavem330
authored andcommitted
net: netcp: ale: update to support unknown vlan controls for NU switch
In NU Ethernet switch used on some of the Keystone SoCs, there is separate UNKNOWNVLAN register for membership, unreg mcast flood, reg mcast flood and force untag egress bits in ALE. So control for these fields require different address offset, shift and size of field. As this ALE has the same version number as ALE in CPSW found on other SoCs, customization based on version number is not possible. So use a configuration parameter, nu_switch_ale, to identify the ALE ALE found in NU Switch. Different treatment is needed for NU Switch ALE due to difference in the ale table bits, separate unknown vlan registers etc. The register information available in ale_controls, needs to be updated to support the netcp NU switch h/w. So it is not constant array any more since it needs to be updated based on ALE type. The header of the file is also updated to indicate it supports N port switch ALE, not just 3 port. The version mask is 3 bits in NU Switch ALE vs 8 bits on other ALE types. While at it, change the debug print to info print so that ALE version gets displayed in boot log. Signed-off-by: Murali Karicheri <[email protected]> Signed-off-by: Sekhar Nori <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4cd85a6 commit ca47130

File tree

3 files changed

+61
-7
lines changed

3 files changed

+61
-7
lines changed

drivers/net/ethernet/ti/cpsw_ale.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Texas Instruments 3-Port Ethernet Switch Address Lookup Engine
2+
* Texas Instruments N-Port Ethernet Switch Address Lookup Engine
33
*
44
* Copyright (C) 2012 Texas Instruments
55
*
@@ -27,8 +27,9 @@
2727

2828
#define BITMASK(bits) (BIT(bits) - 1)
2929

30-
#define ALE_VERSION_MAJOR(rev) ((rev >> 8) & 0xff)
30+
#define ALE_VERSION_MAJOR(rev, mask) (((rev) >> 8) & (mask))
3131
#define ALE_VERSION_MINOR(rev) (rev & 0xff)
32+
#define ALE_VERSION_1R4 0x0104
3233

3334
/* ALE Registers */
3435
#define ALE_IDVER 0x00
@@ -39,6 +40,12 @@
3940
#define ALE_TABLE 0x34
4041
#define ALE_PORTCTL 0x40
4142

43+
/* ALE NetCP NU switch specific Registers */
44+
#define ALE_UNKNOWNVLAN_MEMBER 0x90
45+
#define ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD 0x94
46+
#define ALE_UNKNOWNVLAN_REG_MCAST_FLOOD 0x98
47+
#define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS 0x9C
48+
4249
#define ALE_TABLE_WRITE BIT(31)
4350

4451
#define ALE_TYPE_FREE 0
@@ -464,7 +471,7 @@ struct ale_control_info {
464471
int bits;
465472
};
466473

467-
static const struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = {
474+
static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = {
468475
[ALE_ENABLE] = {
469476
.name = "enable",
470477
.offset = ALE_CONTROL,
@@ -724,8 +731,41 @@ void cpsw_ale_start(struct cpsw_ale *ale)
724731
u32 rev;
725732

726733
rev = __raw_readl(ale->params.ale_regs + ALE_IDVER);
727-
dev_dbg(ale->params.dev, "initialized cpsw ale revision %d.%d\n",
728-
ALE_VERSION_MAJOR(rev), ALE_VERSION_MINOR(rev));
734+
if (!ale->params.major_ver_mask)
735+
ale->params.major_ver_mask = 0xff;
736+
ale->version =
737+
(ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) |
738+
ALE_VERSION_MINOR(rev);
739+
dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n",
740+
ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask),
741+
ALE_VERSION_MINOR(rev));
742+
743+
if (ale->params.nu_switch_ale) {
744+
/* Separate registers for unknown vlan configuration.
745+
* Also there are N bits, where N is number of ale
746+
* ports and shift value should be 0
747+
*/
748+
ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].bits =
749+
ale->params.ale_ports;
750+
ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].offset =
751+
ALE_UNKNOWNVLAN_MEMBER;
752+
ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].bits =
753+
ale->params.ale_ports;
754+
ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].shift = 0;
755+
ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].offset =
756+
ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD;
757+
ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].bits =
758+
ale->params.ale_ports;
759+
ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].shift = 0;
760+
ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].offset =
761+
ALE_UNKNOWNVLAN_REG_MCAST_FLOOD;
762+
ale_controls[ALE_PORT_UNTAGGED_EGRESS].bits =
763+
ale->params.ale_ports;
764+
ale_controls[ALE_PORT_UNTAGGED_EGRESS].shift = 0;
765+
ale_controls[ALE_PORT_UNTAGGED_EGRESS].offset =
766+
ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS;
767+
}
768+
729769
cpsw_ale_control_set(ale, 0, ALE_ENABLE, 1);
730770
cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
731771

drivers/net/ethernet/ti/cpsw_ale.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Texas Instruments 3-Port Ethernet Switch Address Lookup Engine APIs
2+
* Texas Instruments N-Port Ethernet Switch Address Lookup Engine APIs
33
*
44
* Copyright (C) 2012 Texas Instruments
55
*
@@ -21,13 +21,24 @@ struct cpsw_ale_params {
2121
unsigned long ale_ageout; /* in secs */
2222
unsigned long ale_entries;
2323
unsigned long ale_ports;
24+
/* NU Switch has specific handling as number of bits in ALE entries
25+
* are different than other versions of ALE. Also there are specific
26+
* registers for unknown vlan specific fields. So use nu_switch_ale
27+
* to identify this hardware.
28+
*/
29+
bool nu_switch_ale;
30+
/* mask bit used in NU Switch ALE is 3 bits instead of 8 bits. So
31+
* pass it from caller.
32+
*/
33+
u32 major_ver_mask;
2434
};
2535

2636
struct cpsw_ale {
2737
struct cpsw_ale_params params;
2838
struct timer_list timer;
2939
unsigned long ageout;
3040
int allmulti;
41+
u32 version;
3142
};
3243

3344
enum cpsw_ale_control {

drivers/net/ethernet/ti/netcp_ethss.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3609,7 +3609,10 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
36093609
ale_params.ale_ageout = GBE_DEFAULT_ALE_AGEOUT;
36103610
ale_params.ale_entries = gbe_dev->ale_entries;
36113611
ale_params.ale_ports = gbe_dev->ale_ports;
3612-
3612+
if (IS_SS_ID_MU(gbe_dev)) {
3613+
ale_params.major_ver_mask = 0x7;
3614+
ale_params.nu_switch_ale = true;
3615+
}
36133616
gbe_dev->ale = cpsw_ale_create(&ale_params);
36143617
if (!gbe_dev->ale) {
36153618
dev_err(gbe_dev->dev, "error initializing ale engine\n");

0 commit comments

Comments
 (0)