blob: 209e6aca54e187ce0629bd4f5122dbd6596bfcbc [file] [log] [blame]
/*
* Copyright (c) 2012, 2014-2015, 2017-2020, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*qca808x_start*/
#ifndef __SSDK_PLAT_H
#define __SSDK_PLAT_H
#include "sw.h"
/*qca808x_end*/
#include <linux/kconfig.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#if defined(IN_SWCONFIG)
#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
#include <linux/switch.h>
#else
#include <net/switch.h>
#endif
#endif
/*qca808x_start*/
#include <linux/phy.h>
#ifndef BIT
#define BIT(_n) (1UL << (_n))
#endif
#ifndef BITS
#define BITS(_s, _n) (((1UL << (_n)) - 1) << _s)
#endif
/* Atheros specific MII registers */
#define QCA_MII_MMD_ADDR 0x0d
#define QCA_MII_MMD_DATA 0x0e
#define QCA_MII_DBG_ADDR 0x1d
#define QCA_MII_DBG_DATA 0x1e
/*qca808x_end*/
#define AR8327_REG_CTRL 0x0000
#define AR8327_CTRL_REVISION BITS(0, 8)
#define AR8327_CTRL_REVISION_S 0
#define AR8327_CTRL_VERSION BITS(8, 8)
#define AR8327_CTRL_VERSION_S 8
#define AR8327_CTRL_RESET BIT(31)
#define AR8327_REG_LED_CTRL_0 0x50
#define AR8327_REG_LED_CTRL_1 0x54
#define AR8327_REG_LED_CTRL_2 0x58
#define AR8327_REG_LED_CTRL_3 0x5c
#define AR8327_REG_PORT_STATUS(_i) (0x07c + (_i) * 4)
#define AR8327_PORT_STATUS_SPEED BITS(0,2)
#define AR8327_PORT_STATUS_SPEED_S 0
#define AR8327_PORT_STATUS_TXMAC BIT(2)
#define AR8327_PORT_STATUS_RXMAC BIT(3)
#define AR8327_PORT_STATUS_TXFLOW BIT(4)
#define AR8327_PORT_STATUS_RXFLOW BIT(5)
#define AR8327_PORT_STATUS_DUPLEX BIT(6)
#define AR8327_PORT_STATUS_LINK_UP BIT(8)
#define AR8327_PORT_STATUS_LINK_AUTO BIT(9)
#define AR8327_PORT_STATUS_LINK_PAUSE BIT(10)
#define AR8327_REG_PAD0_CTRL 0x4
#define AR8327_REG_PAD5_CTRL 0x8
#define AR8327_REG_PAD6_CTRL 0xc
#define AR8327_PAD_CTRL_MAC_MII_RXCLK_SEL BIT(0)
#define AR8327_PAD_CTRL_MAC_MII_TXCLK_SEL BIT(1)
#define AR8327_PAD_CTRL_MAC_MII_EN BIT(2)
#define AR8327_PAD_CTRL_MAC_GMII_RXCLK_SEL BIT(4)
#define AR8327_PAD_CTRL_MAC_GMII_TXCLK_SEL BIT(5)
#define AR8327_PAD_CTRL_MAC_GMII_EN BIT(6)
#define AR8327_PAD_CTRL_SGMII_EN BIT(7)
#define AR8327_PAD_CTRL_PHY_MII_RXCLK_SEL BIT(8)
#define AR8327_PAD_CTRL_PHY_MII_TXCLK_SEL BIT(9)
#define AR8327_PAD_CTRL_PHY_MII_EN BIT(10)
#define AR8327_PAD_CTRL_PHY_GMII_PIPE_RXCLK_SEL BIT(11)
#define AR8327_PAD_CTRL_PHY_GMII_RXCLK_SEL BIT(12)
#define AR8327_PAD_CTRL_PHY_GMII_TXCLK_SEL BIT(13)
#define AR8327_PAD_CTRL_PHY_GMII_EN BIT(14)
#define AR8327_PAD_CTRL_PHYX_GMII_EN BIT(16)
#define AR8327_PAD_CTRL_PHYX_RGMII_EN BIT(17)
#define AR8327_PAD_CTRL_PHYX_MII_EN BIT(18)
#define AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_SEL BITS(20, 2)
#define AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_SEL_S 20
#define AR8327_PAD_CTRL_RGMII_TXCLK_DELAY_SEL BITS(22, 2)
#define AR8327_PAD_CTRL_RGMII_TXCLK_DELAY_SEL_S 22
#define AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_EN BIT(24)
#define AR8327_PAD_CTRL_RGMII_TXCLK_DELAY_EN BIT(25)
#define AR8327_PAD_CTRL_RGMII_EN BIT(26)
#define AR8327_PORT5_PHY_ADDR 4
/*AR8327 inner phy debug register for RGMII mode*/
#define AR8327_PHY_REG_MODE_SEL 0x12
#define AR8327_PHY_RGMII_MODE BIT(3)
#define AR8327_PHY_REG_TEST_CTRL 0x0
#define AR8327_PHY_RGMII_RX_DELAY BIT(15)
#define AR8327_PHY_REG_SYS_CTRL 0x5
#define AR8327_PHY_RGMII_TX_DELAY BIT(8)
#define AR8327_REG_POS 0x10
#define AR8327_REG_POS_HW_INIT 0x261320
#define AR8327_POS_POWER_ON_SEL BIT(31)
#define AR8327_POS_LED_OPEN_EN BIT(24)
#define AR8327_POS_SERDES_AEN BIT(7)
#define AR8327_REG_MODULE_EN 0x30
#define AR8327_REG_MODULE_EN_QM_ERR BIT(8)
#define AR8327_REG_MODULE_EN_LOOKUP_ERR BIT(9)
#define AR8327_REG_MAC_SFT_RST 0x68
#define AR8327_REG_PAD_SGMII_CTRL 0xe0
#define AR8327_REG_PAD_SGMII_CTRL_HW_INIT 0xc70164c0
#define AR8327_PAD_SGMII_CTRL_MODE_CTRL BITS(22, 2)
#define AR8327_PAD_SGMII_CTRL_MODE_CTRL_S 22
#define AR8327_PAD_SGMII_CTRL_EN_SD BIT(4)
#define AR8327_PAD_SGMII_CTRL_EN_TX BIT(3)
#define AR8327_PAD_SGMII_CTRL_EN_RX BIT(2)
#define AR8327_PAD_SGMII_CTRL_EN_PLL BIT(1)
#define AR8327_PAD_SGMII_CTRL_EN_LCKDT BIT(0)
#define AR8327_REG_PAD_MAC_PWR_SEL 0x0e4
#define AR8327_PAD_MAC_PWR_RGMII0_1_8V BIT(18)
#define AR8327_PAD_MAC_PWR_RGMII1_1_8V BIT(19)
#define AR8327_REG_PORT_LOOKUP(_i) (0x660 + (_i) * 0xc)
#define AR8327_REG_PORT_VLAN0(_i) (0x420 + (_i) * 0x8)
#define DESS_PSGMII_MODE_CONTROL 0x1b4
#define DESS_PSGMII_ATHR_CSCO_MODE_25M BIT(0)
#define DESS_PSGMIIPHY_TX_CONTROL 0x288
#define DESS_PSGMII_PLL_VCO_RELATED_CONTROL_1 0x78c
#define DESS_PSGMII_MII_REG_UPHY_PLL_LCKDT_EN BIT(0)
#define DESS_PSGMII_VCO_CALIBRATION_CONTROL_1 0x9c
#define SSDK_PSGMII_ID 5
/*qca808x_start*/
#define SSDK_PHY_BCAST_ID 0x1f
#define SSDK_PHY_MIN_ID 0x0
#define SSDK_PORT_CPU 0
/*qca808x_end*/
#define SSDK_PORT0_FC_THRESH_ON_DFLT 0x60
#define SSDK_PORT0_FC_THRESH_OFF_DFLT 0x90
#define AR8327_NUM_PHYS 5
#define AR8327_PORT_CPU 0
#define AR8327_NUM_PORTS 7
#define AR8327_MAX_VLANS 128
#define MII_PHYADDR_C45 (1<<30)
#define SSDK_GPIO_RESET 0
#define SSDK_GPIO_RELEASE 1
#define SSDK_INVALID_GPIO 0
enum {
AR8327_PORT_SPEED_10M = 0,
AR8327_PORT_SPEED_100M = 1,
AR8327_PORT_SPEED_1000M = 2,
AR8327_PORT_SPEED_NONE = 3,
};
/*qca808x_start*/
enum {
QCA_VER_AR8216 = 0x01,
QCA_VER_AR8227 = 0x02,
QCA_VER_AR8236 = 0x03,
QCA_VER_AR8316 = 0x10,
QCA_VER_AR8327 = 0x12,
QCA_VER_AR8337 = 0x13,
QCA_VER_DESS = 0x14,
QCA_VER_HPPE = 0x15,
QCA_VER_SCOMPHY = 0xEE
};
/*qca808x_end*/
/*poll mib per 120secs*/
#define QCA_PHY_MIB_WORK_DELAY 120000
#define QCA_MIB_ITEM_NUMBER \
(sizeof(fal_mib_counter_t)/sizeof(a_uint64_t))
#define SSDK_MAX_UNIPHY_INSTANCE 3
#define SSDK_UNIPHY_INSTANCE0 0
#define SSDK_UNIPHY_INSTANCE1 1
#define SSDK_UNIPHY_INSTANCE2 2
#define SSDK_UNIPHY_CHANNEL0 0
#define SSDK_UNIPHY_CHANNEL1 1
#define SSDK_UNIPHY_CHANNEL2 2
#define SSDK_UNIPHY_CHANNEL3 3
#define SSDK_UNIPHY_CHANNEL4 4
/*qca808x_start*/
#define SSDK_PHYSICAL_PORT0 0
#define SSDK_PHYSICAL_PORT1 1
#define SSDK_PHYSICAL_PORT2 2
#define SSDK_PHYSICAL_PORT3 3
#define SSDK_PHYSICAL_PORT4 4
#define SSDK_PHYSICAL_PORT5 5
#define SSDK_PHYSICAL_PORT6 6
#define SSDK_PHYSICAL_PORT7 7
/*qca808x_end*/
#define SSDK_GLOBAL_INT0_ACL_INI_INT (1<<29)
#define SSDK_GLOBAL_INT0_LOOKUP_INI_INT (1<<28)
#define SSDK_GLOBAL_INT0_QM_INI_INT (1<<27)
#define SSDK_GLOBAL_INT0_MIB_INI_INT (1<<26)
#define SSDK_GLOBAL_INT0_OFFLOAD_INI_INT (1<<25)
#define SSDK_GLOBAL_INT0_HARDWARE_INI_DONE (1<<24)
#define SSDK_GLOBAL_INITIALIZED_STATUS \
( \
SSDK_GLOBAL_INT0_ACL_INI_INT | \
SSDK_GLOBAL_INT0_LOOKUP_INI_INT | \
SSDK_GLOBAL_INT0_QM_INI_INT | \
SSDK_GLOBAL_INT0_MIB_INI_INT | \
SSDK_GLOBAL_INT0_OFFLOAD_INI_INT | \
SSDK_GLOBAL_INT0_HARDWARE_INI_DONE \
)
/*qca808x_start*/
#define SSDK_LOG_LEVEL_ERROR 0
#define SSDK_LOG_LEVEL_WARN 1
#define SSDK_LOG_LEVEL_INFO 2
#define SSDK_LOG_LEVEL_DEBUG 3
#define SSDK_LOG_LEVEL_DEFAULT SSDK_LOG_LEVEL_INFO
extern a_uint32_t ssdk_log_level;
#define __SSDK_LOG_FUN(lev, fmt, ...) \
do { \
if (SSDK_LOG_LEVEL_##lev <= ssdk_log_level) { \
printk("%s[%u]:"#lev":"fmt, \
__FUNCTION__, __LINE__, ##__VA_ARGS__); \
} \
} while(0)
#define SSDK_DUMP_BUF(lev, buf, len) \
do {\
if (SSDK_LOG_LEVEL_##lev <= ssdk_log_level) {\
a_uint32_t i_buf = 0;\
for(i_buf=0; i_buf<(len); i_buf++) {\
printk(KERN_CONT "%08lx ", *((buf)+i_buf));\
}\
printk(KERN_CONT "\n");\
}\
} while(0)
#define SSDK_ERROR(fmt, ...) __SSDK_LOG_FUN(ERROR, fmt, ##__VA_ARGS__)
#define SSDK_WARN(fmt, ...) __SSDK_LOG_FUN(WARN, fmt, ##__VA_ARGS__)
#define SSDK_INFO(fmt, ...) __SSDK_LOG_FUN(INFO, fmt, ##__VA_ARGS__)
#define SSDK_DEBUG(fmt, ...) __SSDK_LOG_FUN(DEBUG, fmt, ##__VA_ARGS__)
struct qca_phy_priv {
struct phy_device *phy;
#if defined(IN_SWCONFIG)
struct switch_dev sw_dev;
#endif
a_uint8_t version;
a_uint8_t revision;
a_uint32_t (*mii_read)(a_uint32_t dev_id, a_uint32_t reg);
void (*mii_write)(a_uint32_t dev_id, a_uint32_t reg, a_uint32_t val);
void (*phy_dbg_write)(a_uint32_t dev_id, a_uint32_t phy_addr,
a_uint16_t dbg_addr, a_uint16_t dbg_data);
void (*phy_dbg_read)(a_uint32_t dev_id, a_uint32_t phy_addr,
a_uint16_t dbg_addr, a_uint16_t *dbg_data);
void (*phy_mmd_write)(a_uint32_t dev_id, a_uint32_t phy_addr,
a_uint16_t addr, a_uint16_t data);
sw_error_t (*phy_write)(a_uint32_t dev_id, a_uint32_t phy_addr,
a_uint32_t reg, a_uint16_t data);
sw_error_t (*phy_read)(a_uint32_t dev_id, a_uint32_t phy_addr,
a_uint32_t reg, a_uint16_t* data);
bool init;
/*qca808x_end*/
a_bool_t qca_ssdk_sw_dev_registered;
a_bool_t ess_switch_flag;
struct mutex reg_mutex;
struct mutex mib_lock;
struct delayed_work mib_dwork;
/*qm_err_check*/
struct mutex qm_lock;
a_uint32_t port_link_down[SW_MAX_NR_PORT];
a_uint32_t port_link_up[SW_MAX_NR_PORT];
a_uint32_t port_old_link[SW_MAX_NR_PORT];
a_uint32_t port_old_speed[SW_MAX_NR_PORT];
a_uint32_t port_old_duplex[SW_MAX_NR_PORT];
a_uint32_t port_old_phy_status[SW_MAX_NR_PORT];
a_uint32_t port_qm_buf[SW_MAX_NR_PORT];
a_bool_t port_old_tx_flowctrl[SW_MAX_NR_PORT];
a_bool_t port_old_rx_flowctrl[SW_MAX_NR_PORT];
a_bool_t port_tx_flowctrl_forcemode[SW_MAX_NR_PORT];
a_bool_t port_rx_flowctrl_forcemode[SW_MAX_NR_PORT];
struct delayed_work qm_dwork_polling;
struct work_struct intr_workqueue;
/*qm_err_check end*/
/*qca808x_start*/
a_uint8_t device_id;
struct device_node *of_node;
/*qca808x_end*/
/*dess_rgmii_mac*/
struct mutex rgmii_lock;
struct delayed_work rgmii_dwork;
/*dess_rgmii_mac end*/
/*hppe_mac_sw_sync*/
struct mutex mac_sw_sync_lock;
struct delayed_work mac_sw_sync_dwork;
/*hppe_mac_sw_sync end*/
/*qca808x_start*/
struct mii_bus *miibus;
/*qca808x_end*/
u64 *mib_counters;
/* dump buf */
a_uint8_t buf[2048];
a_uint32_t link_polling_required;
/* it is valid only when link_polling_required is false*/
a_uint32_t link_interrupt_no;
a_uint32_t interrupt_flag;
char link_intr_name[IFNAMSIZ];
/* VLAN database */
bool vlan; /* True: 1q vlan mode, False: port vlan mode */
a_uint16_t vlan_id[AR8327_MAX_VLANS];
a_uint8_t vlan_table[AR8327_MAX_VLANS];
a_uint8_t vlan_tagged[AR8327_MAX_VLANS];
a_uint16_t pvid[SSDK_MAX_PORT_NUM];
a_uint32_t ports;
u8 __iomem *hw_addr;
u8 __iomem *psgmii_hw_addr;
u8 __iomem *uniphy_hw_addr;
/*qca808x_start*/
};
struct ipq40xx_mdio_data {
struct mii_bus *mii_bus;
void __iomem *membase;
int phy_irq[PHY_MAX_ADDR];
};
#if defined(IN_SWCONFIG)
#define qca_phy_priv_get(_dev) \
container_of(_dev, struct qca_phy_priv, sw_dev)
#endif
/*qca808x_end*/
a_uint32_t
qca_ar8216_mii_read(a_uint32_t dev_id, a_uint32_t reg);
void
qca_ar8216_mii_write(a_uint32_t dev_id, a_uint32_t reg, a_uint32_t val);
/*qca808x_start*/
sw_error_t
qca_ar8327_phy_read(a_uint32_t dev_id, a_uint32_t phy_addr,
a_uint32_t reg, a_uint16_t* data);
sw_error_t
qca_ar8327_phy_write(a_uint32_t dev_id, a_uint32_t phy_addr,
a_uint32_t reg, a_uint16_t data);
void
qca_ar8327_mmd_write(a_uint32_t dev_id, a_uint32_t phy_addr,
a_uint16_t addr, a_uint16_t data);
void
qca_ar8327_phy_dbg_write(a_uint32_t dev_id, a_uint32_t phy_addr,
a_uint16_t dbg_addr, a_uint16_t dbg_data);
void
qca_ar8327_phy_dbg_read(a_uint32_t dev_id, a_uint32_t phy_addr,
a_uint16_t dbg_addr, a_uint16_t *dbg_data);
void
qca_phy_mmd_write(u32 dev_id, u32 phy_id,
u16 mmd_num, u16 reg_id, u16 reg_val);
u16
qca_phy_mmd_read(u32 dev_id, u32 phy_id,
u16 mmd_num, u16 reg_id);
/*qca808x_end*/
sw_error_t
qca_switch_reg_read(a_uint32_t dev_id, a_uint32_t reg_addr,
a_uint8_t * reg_data, a_uint32_t len);
sw_error_t
qca_switch_reg_write(a_uint32_t dev_id, a_uint32_t reg_addr,
a_uint8_t * reg_data, a_uint32_t len);
sw_error_t
qca_psgmii_reg_read(a_uint32_t dev_id, a_uint32_t reg_addr,
a_uint8_t * reg_data, a_uint32_t len);
sw_error_t
qca_psgmii_reg_write(a_uint32_t dev_id, a_uint32_t reg_addr,
a_uint8_t * reg_data, a_uint32_t len);
sw_error_t
qca_uniphy_reg_write(a_uint32_t dev_id, a_uint32_t uniphy_index,
a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len);
sw_error_t
qca_uniphy_reg_read(a_uint32_t dev_id, a_uint32_t uniphy_index,
a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len);
struct mii_bus *ssdk_miibus_get_by_device(a_uint32_t dev_id);
int ssdk_sysfs_init (void);
void ssdk_sysfs_exit (void);
/*qca808x_start*/
int ssdk_plat_init(ssdk_init_cfg *cfg, a_uint32_t dev_id);
void ssdk_plat_exit(a_uint32_t dev_id);
#endif
/*qca808x_end*/