2019-04-27 01:12:23 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2012-03-19 04:17:53 +08:00
|
|
|
/*
|
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 <m-karicheri2@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-01-07 04:37:44 +08:00
|
|
|
* Texas Instruments N-Port Ethernet Switch Address Lookup Engine APIs
|
2012-03-19 04:17:53 +08:00
|
|
|
*
|
|
|
|
* Copyright (C) 2012 Texas Instruments
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#ifndef __TI_CPSW_ALE_H__
|
|
|
|
#define __TI_CPSW_ALE_H__
|
|
|
|
|
|
|
|
struct cpsw_ale_params {
|
|
|
|
struct device *dev;
|
|
|
|
void __iomem *ale_regs;
|
|
|
|
unsigned long ale_ageout; /* in secs */
|
|
|
|
unsigned long ale_entries;
|
|
|
|
unsigned long ale_ports;
|
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 <m-karicheri2@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-01-07 04:37:44 +08:00
|
|
|
/* NU Switch has specific handling as number of bits in ALE entries
|
|
|
|
* are different than other versions of ALE. Also there are specific
|
|
|
|
* registers for unknown vlan specific fields. So use nu_switch_ale
|
|
|
|
* to identify this hardware.
|
|
|
|
*/
|
|
|
|
bool nu_switch_ale;
|
|
|
|
/* mask bit used in NU Switch ALE is 3 bits instead of 8 bits. So
|
|
|
|
* pass it from caller.
|
|
|
|
*/
|
|
|
|
u32 major_ver_mask;
|
2020-09-11 04:28:00 +08:00
|
|
|
const char *dev_id;
|
2020-09-11 04:28:05 +08:00
|
|
|
unsigned long bus_freq;
|
2012-03-19 04:17:53 +08:00
|
|
|
};
|
|
|
|
|
2020-09-11 04:28:06 +08:00
|
|
|
struct ale_entry_fld;
|
|
|
|
|
2012-03-19 04:17:53 +08:00
|
|
|
struct cpsw_ale {
|
|
|
|
struct cpsw_ale_params params;
|
|
|
|
struct timer_list timer;
|
|
|
|
unsigned long ageout;
|
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 <m-karicheri2@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-01-07 04:37:44 +08:00
|
|
|
u32 version;
|
2020-09-11 04:28:04 +08:00
|
|
|
u32 features;
|
2017-01-07 04:37:46 +08:00
|
|
|
/* These bits are different on NetCP NU Switch ALE */
|
|
|
|
u32 port_mask_bits;
|
|
|
|
u32 port_num_bits;
|
|
|
|
u32 vlan_field_bits;
|
2019-11-20 06:19:14 +08:00
|
|
|
unsigned long *p0_untag_vid_mask;
|
2020-09-11 04:28:06 +08:00
|
|
|
const struct ale_entry_fld *vlan_entry_tbl;
|
2012-03-19 04:17:53 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
enum cpsw_ale_control {
|
|
|
|
/* global */
|
|
|
|
ALE_ENABLE,
|
|
|
|
ALE_CLEAR,
|
|
|
|
ALE_AGEOUT,
|
2014-01-23 02:33:12 +08:00
|
|
|
ALE_P0_UNI_FLOOD,
|
2012-03-19 04:17:53 +08:00
|
|
|
ALE_VLAN_NOLEARN,
|
|
|
|
ALE_NO_PORT_VLAN,
|
|
|
|
ALE_OUI_DENY,
|
|
|
|
ALE_BYPASS,
|
|
|
|
ALE_RATE_LIMIT_TX,
|
|
|
|
ALE_VLAN_AWARE,
|
|
|
|
ALE_AUTH_ENABLE,
|
|
|
|
ALE_RATE_LIMIT,
|
|
|
|
/* port controls */
|
|
|
|
ALE_PORT_STATE,
|
|
|
|
ALE_PORT_DROP_UNTAGGED,
|
|
|
|
ALE_PORT_DROP_UNKNOWN_VLAN,
|
|
|
|
ALE_PORT_NOLEARN,
|
2014-01-23 02:33:12 +08:00
|
|
|
ALE_PORT_NO_SA_UPDATE,
|
2012-03-19 04:17:53 +08:00
|
|
|
ALE_PORT_UNKNOWN_VLAN_MEMBER,
|
|
|
|
ALE_PORT_UNKNOWN_MCAST_FLOOD,
|
|
|
|
ALE_PORT_UNKNOWN_REG_MCAST_FLOOD,
|
|
|
|
ALE_PORT_UNTAGGED_EGRESS,
|
2020-03-24 06:52:46 +08:00
|
|
|
ALE_PORT_MACONLY,
|
|
|
|
ALE_PORT_MACONLY_CAF,
|
2012-03-19 04:17:53 +08:00
|
|
|
ALE_PORT_BCAST_LIMIT,
|
|
|
|
ALE_PORT_MCAST_LIMIT,
|
2020-03-24 06:52:47 +08:00
|
|
|
ALE_DEFAULT_THREAD_ID,
|
|
|
|
ALE_DEFAULT_THREAD_ENABLE,
|
2012-03-19 04:17:53 +08:00
|
|
|
ALE_NUM_CONTROLS,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum cpsw_ale_port_state {
|
|
|
|
ALE_PORT_STATE_DISABLE = 0x00,
|
|
|
|
ALE_PORT_STATE_BLOCK = 0x01,
|
|
|
|
ALE_PORT_STATE_LEARN = 0x02,
|
|
|
|
ALE_PORT_STATE_FORWARD = 0x03,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* ALE unicast entry flags - passed into cpsw_ale_add_ucast() */
|
2013-02-05 16:26:47 +08:00
|
|
|
#define ALE_SECURE BIT(0)
|
|
|
|
#define ALE_BLOCKED BIT(1)
|
|
|
|
#define ALE_SUPER BIT(2)
|
|
|
|
#define ALE_VLAN BIT(3)
|
2012-03-19 04:17:53 +08:00
|
|
|
|
2013-02-05 16:26:48 +08:00
|
|
|
#define ALE_PORT_HOST BIT(0)
|
|
|
|
#define ALE_PORT_1 BIT(1)
|
|
|
|
#define ALE_PORT_2 BIT(2)
|
|
|
|
|
2012-03-19 04:17:53 +08:00
|
|
|
#define ALE_MCAST_FWD 0
|
|
|
|
#define ALE_MCAST_BLOCK_LEARN_FWD 1
|
|
|
|
#define ALE_MCAST_FWD_LEARN 2
|
|
|
|
#define ALE_MCAST_FWD_2 3
|
|
|
|
|
2014-07-23 01:55:07 +08:00
|
|
|
#define ALE_ENTRY_BITS 68
|
|
|
|
#define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32)
|
|
|
|
|
2012-03-19 04:17:53 +08:00
|
|
|
struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params);
|
|
|
|
|
|
|
|
void cpsw_ale_start(struct cpsw_ale *ale);
|
|
|
|
void cpsw_ale_stop(struct cpsw_ale *ale);
|
|
|
|
|
2015-01-13 20:05:49 +08:00
|
|
|
int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid);
|
2018-10-12 23:28:14 +08:00
|
|
|
int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
|
2013-02-05 16:26:47 +08:00
|
|
|
int flags, u16 vid);
|
2018-10-12 23:28:14 +08:00
|
|
|
int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
|
2013-02-05 16:26:47 +08:00
|
|
|
int flags, u16 vid);
|
2018-10-12 23:28:14 +08:00
|
|
|
int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
|
2013-02-05 16:26:47 +08:00
|
|
|
int flags, u16 vid, int mcast_state);
|
2018-10-12 23:28:14 +08:00
|
|
|
int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
|
2013-02-05 16:26:47 +08:00
|
|
|
int flags, u16 vid);
|
|
|
|
int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
|
|
|
|
int reg_mcast, int unreg_mcast);
|
|
|
|
int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port);
|
2019-04-27 01:12:33 +08:00
|
|
|
void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port);
|
2012-03-19 04:17:53 +08:00
|
|
|
|
|
|
|
int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control);
|
|
|
|
int cpsw_ale_control_set(struct cpsw_ale *ale, int port,
|
|
|
|
int control, int value);
|
2014-07-23 01:55:07 +08:00
|
|
|
void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data);
|
2020-09-11 04:27:59 +08:00
|
|
|
u32 cpsw_ale_get_num_entries(struct cpsw_ale *ale);
|
2012-03-19 04:17:53 +08:00
|
|
|
|
2019-11-20 06:19:14 +08:00
|
|
|
static inline int cpsw_ale_get_vlan_p0_untag(struct cpsw_ale *ale, u16 vid)
|
|
|
|
{
|
|
|
|
return test_bit(vid, ale->p0_untag_vid_mask);
|
|
|
|
}
|
2019-11-20 06:19:15 +08:00
|
|
|
|
|
|
|
int cpsw_ale_vlan_add_modify(struct cpsw_ale *ale, u16 vid, int port_mask,
|
|
|
|
int untag_mask, int reg_mcast, int unreg_mcast);
|
|
|
|
void cpsw_ale_set_unreg_mcast(struct cpsw_ale *ale, int unreg_mcast_mask,
|
|
|
|
bool add);
|
|
|
|
|
2012-03-19 04:17:53 +08:00
|
|
|
#endif
|