mirror of https://github.com/hak5/openwrt.git
generic: ar8216: add support for ar8229
ar8229 is the builtin switch in ar934x and later chips. There is also a standalone version available and their registers/functions are the same. This commit added support for the builtin ar8229. The only thing missing for standalone ar8229 should be phy modes. Since I don't have a router using that, this commit doesn't add support for other phy modes. Only add its support for mdio-device probing method because the current PHY probing can't return 1G speed when it's a FE switch. Signed-off-by: Chuanhong Guo <gch981213@gmail.com>openwrt-19.07
parent
7d504f68a6
commit
cb7d96499c
|
@ -25,6 +25,7 @@
|
|||
#include <linux/netlink.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <net/genetlink.h>
|
||||
#include <linux/switch.h>
|
||||
|
@ -715,7 +716,8 @@ ar8216_init_globals(struct ar8xxx_priv *priv)
|
|||
}
|
||||
|
||||
static void
|
||||
ar8216_init_port(struct ar8xxx_priv *priv, int port)
|
||||
__ar8216_init_port(struct ar8xxx_priv *priv, int port,
|
||||
bool cpu_ge, bool flow_en)
|
||||
{
|
||||
/* Enable port learning and tx */
|
||||
ar8xxx_write(priv, AR8216_REG_PORT_CTRL(port),
|
||||
|
@ -727,12 +729,11 @@ ar8216_init_port(struct ar8xxx_priv *priv, int port)
|
|||
if (port == AR8216_PORT_CPU) {
|
||||
ar8xxx_write(priv, AR8216_REG_PORT_STATUS(port),
|
||||
AR8216_PORT_STATUS_LINK_UP |
|
||||
(ar8xxx_has_gige(priv) ?
|
||||
AR8216_PORT_SPEED_1000M : AR8216_PORT_SPEED_100M) |
|
||||
(cpu_ge ? AR8216_PORT_SPEED_1000M : AR8216_PORT_SPEED_100M) |
|
||||
AR8216_PORT_STATUS_TXMAC |
|
||||
AR8216_PORT_STATUS_RXMAC |
|
||||
(chip_is_ar8316(priv) ? AR8216_PORT_STATUS_RXFLOW : 0) |
|
||||
(chip_is_ar8316(priv) ? AR8216_PORT_STATUS_TXFLOW : 0) |
|
||||
(flow_en ? AR8216_PORT_STATUS_RXFLOW : 0) |
|
||||
(flow_en ? AR8216_PORT_STATUS_TXFLOW : 0) |
|
||||
AR8216_PORT_STATUS_DUPLEX);
|
||||
} else {
|
||||
ar8xxx_write(priv, AR8216_REG_PORT_STATUS(port),
|
||||
|
@ -740,6 +741,13 @@ ar8216_init_port(struct ar8xxx_priv *priv, int port)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ar8216_init_port(struct ar8xxx_priv *priv, int port)
|
||||
{
|
||||
__ar8216_init_port(priv, port, ar8xxx_has_gige(priv),
|
||||
chip_is_ar8316(priv));
|
||||
}
|
||||
|
||||
static void
|
||||
ar8216_wait_atu_ready(struct ar8xxx_priv *priv, u16 r2, u16 r1)
|
||||
{
|
||||
|
@ -807,6 +815,85 @@ static void ar8216_get_arl_entry(struct ar8xxx_priv *priv,
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ar8229_hw_init(struct ar8xxx_priv *priv)
|
||||
{
|
||||
int phy_if_mode;
|
||||
|
||||
if (priv->initialized)
|
||||
return 0;
|
||||
|
||||
ar8xxx_write(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET);
|
||||
ar8xxx_reg_wait(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET, 0, 1000);
|
||||
|
||||
phy_if_mode = of_get_phy_mode(priv->pdev->of_node);
|
||||
|
||||
if (phy_if_mode == PHY_INTERFACE_MODE_GMII) {
|
||||
ar8xxx_write(priv, AR8229_REG_OPER_MODE0,
|
||||
AR8229_OPER_MODE0_MAC_GMII_EN);
|
||||
} else if (phy_if_mode == PHY_INTERFACE_MODE_MII) {
|
||||
ar8xxx_write(priv, AR8229_REG_OPER_MODE0,
|
||||
AR8229_OPER_MODE0_PHY_MII_EN);
|
||||
} else {
|
||||
pr_err("ar8229: unsupported mii mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (priv->port4_phy)
|
||||
ar8xxx_write(priv, AR8229_REG_OPER_MODE1,
|
||||
AR8229_REG_OPER_MODE1_PHY4_MII_EN);
|
||||
|
||||
ar8xxx_phy_init(priv);
|
||||
|
||||
priv->initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ar8229_init_globals(struct ar8xxx_priv *priv)
|
||||
{
|
||||
|
||||
/* Enable CPU port, and disable mirror port */
|
||||
ar8xxx_write(priv, AR8216_REG_GLOBAL_CPUPORT,
|
||||
AR8216_GLOBAL_CPUPORT_EN |
|
||||
(15 << AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S));
|
||||
|
||||
/* Setup TAG priority mapping */
|
||||
ar8xxx_write(priv, AR8216_REG_TAG_PRIORITY, 0xfa50);
|
||||
|
||||
/* Enable aging, MAC replacing */
|
||||
ar8xxx_write(priv, AR8216_REG_ATU_CTRL,
|
||||
0x2b /* 5 min age time */ |
|
||||
AR8216_ATU_CTRL_AGE_EN |
|
||||
AR8216_ATU_CTRL_LEARN_CHANGE);
|
||||
|
||||
/* Enable ARP frame acknowledge */
|
||||
ar8xxx_reg_set(priv, AR8229_REG_QM_CTRL,
|
||||
AR8229_QM_CTRL_ARP_EN);
|
||||
|
||||
/* Enable Broadcast/Multicast frames transmitted to the CPU */
|
||||
ar8xxx_reg_set(priv, AR8216_REG_FLOOD_MASK,
|
||||
AR8229_FLOOD_MASK_BC_DP(0) |
|
||||
AR8229_FLOOD_MASK_MC_DP(0));
|
||||
|
||||
/* setup MTU */
|
||||
ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CTRL,
|
||||
AR8236_GCTRL_MTU, AR8236_GCTRL_MTU);
|
||||
|
||||
/* Enable MIB counters */
|
||||
ar8xxx_reg_set(priv, AR8216_REG_MIB_FUNC,
|
||||
AR8236_MIB_EN);
|
||||
|
||||
/* setup Service TAG */
|
||||
ar8xxx_rmw(priv, AR8216_REG_SERVICE_TAG, AR8216_SERVICE_TAG_M, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ar8229_init_port(struct ar8xxx_priv *priv, int port)
|
||||
{
|
||||
__ar8216_init_port(priv, port, true, true);
|
||||
}
|
||||
|
||||
static void
|
||||
ar8236_setup_port(struct ar8xxx_priv *priv, int port, u32 members)
|
||||
{
|
||||
|
@ -1753,6 +1840,36 @@ static const struct ar8xxx_chip ar8216_chip = {
|
|||
.mib_func = AR8216_REG_MIB_FUNC
|
||||
};
|
||||
|
||||
static const struct ar8xxx_chip ar8229_chip = {
|
||||
.caps = AR8XXX_CAP_MIB_COUNTERS,
|
||||
|
||||
.reg_port_stats_start = 0x20000,
|
||||
.reg_port_stats_length = 0x100,
|
||||
.reg_arl_ctrl = AR8216_REG_ATU_CTRL,
|
||||
|
||||
.name = "Atheros AR8229",
|
||||
.ports = AR8216_NUM_PORTS,
|
||||
.vlans = AR8216_NUM_VLANS,
|
||||
.swops = &ar8xxx_sw_ops,
|
||||
|
||||
.hw_init = ar8229_hw_init,
|
||||
.init_globals = ar8229_init_globals,
|
||||
.init_port = ar8229_init_port,
|
||||
.setup_port = ar8236_setup_port,
|
||||
.read_port_status = ar8216_read_port_status,
|
||||
.atu_flush = ar8216_atu_flush,
|
||||
.atu_flush_port = ar8216_atu_flush_port,
|
||||
.vtu_flush = ar8216_vtu_flush,
|
||||
.vtu_load_vlan = ar8216_vtu_load_vlan,
|
||||
.set_mirror_regs = ar8216_set_mirror_regs,
|
||||
.get_arl_entry = ar8216_get_arl_entry,
|
||||
.sw_hw_apply = ar8xxx_sw_hw_apply,
|
||||
|
||||
.num_mibs = ARRAY_SIZE(ar8236_mibs),
|
||||
.mib_decs = ar8236_mibs,
|
||||
.mib_func = AR8216_REG_MIB_FUNC
|
||||
};
|
||||
|
||||
static const struct ar8xxx_chip ar8236_chip = {
|
||||
.caps = AR8XXX_CAP_MIB_COUNTERS,
|
||||
|
||||
|
@ -2336,6 +2453,9 @@ static struct phy_driver ar8xxx_phy_driver[] = {
|
|||
|
||||
static const struct of_device_id ar8xxx_mdiodev_of_match[] = {
|
||||
{
|
||||
.compatible = "qca,ar8229",
|
||||
.data = &ar8229_chip,
|
||||
}, {
|
||||
.compatible = "qca,ar8236",
|
||||
.data = &ar8236_chip,
|
||||
}, {
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
#define AR8216_REG_FLOOD_MASK 0x002C
|
||||
#define AR8216_FM_UNI_DEST_PORTS BITS(0, 6)
|
||||
#define AR8216_FM_MULTI_DEST_PORTS BITS(16, 6)
|
||||
#define AR8229_FLOOD_MASK_MC_DP(_p) BIT(16 + (_p))
|
||||
#define AR8229_FLOOD_MASK_BC_DP(_p) BIT(25 + (_p))
|
||||
#define AR8236_FM_CPU_BROADCAST_EN BIT(26)
|
||||
#define AR8236_FM_CPU_BCAST_FWD_EN BIT(25)
|
||||
|
||||
|
@ -127,6 +129,12 @@
|
|||
#define AR8216_ATU_CTRL_AGE_TIME BITS(0, 16)
|
||||
#define AR8216_ATU_CTRL_AGE_TIME_S 0
|
||||
#define AR8236_ATU_CTRL_RES BIT(20)
|
||||
#define AR8216_ATU_CTRL_LEARN_CHANGE BIT(18)
|
||||
|
||||
#define AR8216_REG_TAG_PRIORITY 0x0070
|
||||
|
||||
#define AR8216_REG_SERVICE_TAG 0x0074
|
||||
#define AR8216_SERVICE_TAG_M BITS(0, 16)
|
||||
|
||||
#define AR8216_REG_MIB_FUNC 0x0080
|
||||
#define AR8216_MIB_TIMER BITS(0, 16)
|
||||
|
@ -142,6 +150,7 @@
|
|||
#define AR8216_REG_GLOBAL_CPUPORT 0x0078
|
||||
#define AR8216_GLOBAL_CPUPORT_MIRROR_PORT BITS(4, 4)
|
||||
#define AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S 4
|
||||
#define AR8216_GLOBAL_CPUPORT_EN BIT(8)
|
||||
|
||||
#define AR8216_PORT_OFFSET(_i) (0x0100 * (_i + 1))
|
||||
#define AR8216_REG_PORT_STATUS(_i) (AR8216_PORT_OFFSET(_i) + 0x0000)
|
||||
|
@ -237,6 +246,16 @@
|
|||
#define AR8216_STATS_TXDEFER 0x98
|
||||
#define AR8216_STATS_TXLATECOL 0x9c
|
||||
|
||||
#define AR8229_REG_OPER_MODE0 0x04
|
||||
#define AR8229_OPER_MODE0_MAC_GMII_EN BIT(6)
|
||||
#define AR8229_OPER_MODE0_PHY_MII_EN BIT(10)
|
||||
|
||||
#define AR8229_REG_OPER_MODE1 0x08
|
||||
#define AR8229_REG_OPER_MODE1_PHY4_MII_EN BIT(28)
|
||||
|
||||
#define AR8229_REG_QM_CTRL 0x3c
|
||||
#define AR8229_QM_CTRL_ARP_EN BIT(15)
|
||||
|
||||
#define AR8236_REG_PORT_VLAN(_i) (AR8216_PORT_OFFSET((_i)) + 0x0008)
|
||||
#define AR8236_PORT_VLAN_DEFAULT_ID BITS(16, 12)
|
||||
#define AR8236_PORT_VLAN_DEFAULT_ID_S 16
|
||||
|
|
Loading…
Reference in New Issue