From bc5f3cca5a798fa8569b1d6b791ae46eab2b8b41 Mon Sep 17 00:00:00 2001 From: Vandhiadevan Karunamoorthy Date: Wed, 19 Oct 2022 07:21:53 +0530 Subject: [PATCH] board: arm: ipq5332: update ethernet configuration Change-Id: If66707a68ddf5681016acd95332d4056b31fb3fc Signed-off-by: Vandhiadevan Karunamoorthy --- board/qca/arm/ipq5332/ipq5332.c | 64 ++- drivers/net/ipq5332/ipq5332_edma.c | 700 ++++++++++++++------------- drivers/net/ipq5332/ipq5332_ppe.c | 258 +++++----- drivers/net/ipq5332/ipq5332_ppe.h | 9 +- drivers/net/ipq5332/ipq5332_uniphy.c | 95 ++-- drivers/net/ipq5332/ipq5332_uniphy.h | 2 + 6 files changed, 609 insertions(+), 519 deletions(-) diff --git a/board/qca/arm/ipq5332/ipq5332.c b/board/qca/arm/ipq5332/ipq5332.c index 41a4b98002..0ea82c59fb 100644 --- a/board/qca/arm/ipq5332/ipq5332.c +++ b/board/qca/arm/ipq5332/ipq5332.c @@ -905,14 +905,76 @@ void qca808x_phy_reset_init_done(void) } } +int get_sfp_gpio(int sfp_gpio[2]) +{ + int sfp_gpio_cnt = -1, node; + int res = -1; + + node = fdt_path_offset(gd->fdt_blob, "/ess-switch"); + if (node >= 0) { + sfp_gpio_cnt = fdtdec_get_uint(gd->fdt_blob, node, + "sfp_gpio_cnt", -1); + if (sfp_gpio_cnt >= 1) { + res = fdtdec_get_int_array(gd->fdt_blob, node, + "sfp_gpio", + (u32 *)sfp_gpio, + sfp_gpio_cnt); + if (res >= 0) + return sfp_gpio_cnt; + } + } + return res; +} + +void sfp_reset_init(void) +{ + int sfp_gpio[2] = {-1, -1}, sfp_gpio_cnt, i; + unsigned int *sfp_gpio_base; + uint32_t cfg; + + sfp_gpio_cnt = get_sfp_gpio(sfp_gpio); + if (sfp_gpio_cnt >= 1) { + for (i = 0; i < sfp_gpio_cnt; i++) { + if (sfp_gpio[i] >= 0) { + sfp_gpio_base = + (unsigned int *)GPIO_CONFIG_ADDR( + sfp_gpio[i]); + cfg = GPIO_OE | GPIO_DRV_8_MA | GPIO_PULL_UP; + writel(cfg, sfp_gpio_base); + } + } + } +} + +void qca8081_napa_reset(void) +{ + unsigned int *napa_gpio_base; + int node, gpio; + uint32_t cfg; + + node = fdt_path_offset(gd->fdt_blob, "/ess-switch"); + if (node >= 0) { + gpio = fdtdec_get_uint(gd->fdt_blob, node , "napa_gpio", -1); + if (gpio != -1) { + napa_gpio_base = + (unsigned int *)GPIO_CONFIG_ADDR(gpio); + cfg = GPIO_OE | GPIO_DRV_8_MA | GPIO_PULL_UP; + writel(cfg, napa_gpio_base); + mdelay(100); + gpio_set_value(gpio, 0x1); + } + } +} + void bring_phy_out_of_reset(void) { + qca8081_napa_reset(); aquantia_phy_reset_init(); qca808x_phy_reset_init(); + sfp_reset_init(); mdelay(500); aquantia_phy_reset_init_done(); qca808x_phy_reset_init_done(); - mdelay(500); } void ipq5332_eth_initialize(void) diff --git a/drivers/net/ipq5332/ipq5332_edma.c b/drivers/net/ipq5332/ipq5332_edma.c index aa168cdbff..e1c217bc42 100644 --- a/drivers/net/ipq5332/ipq5332_edma.c +++ b/drivers/net/ipq5332/ipq5332_edma.c @@ -45,10 +45,16 @@ DECLARE_GLOBAL_DATA_PTR; #endif static struct ipq5332_eth_dev *ipq5332_edma_dev[IPQ5332_EDMA_DEV]; +typedef struct { + phy_info_t *phy_info; + int port_id; + int uniphy_id; + int mode; +} ipq5332_edma_port_info_t; uchar ipq5332_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xBA, 0xDB, 0xAD}; -phy_info_t *phy_info[IPQ5332_PHY_MAX] = {0}; phy_info_t *swt_info[QCA8084_MAX_PORTS] = {0}; +ipq5332_edma_port_info_t *port_info[IPQ5332_PHY_MAX] = {0}; int sgmii_mode[2] = {0}; #ifndef CONFIG_IPQ5332_RUMI @@ -58,7 +64,8 @@ extern int ipq_sw_mdio_init(const char *); extern int ipq_mdio_read(int mii_id, int regnum, ushort *data); extern void ipq5332_qca8075_phy_map_ops(struct phy_ops **ops); extern int ipq5332_qca8075_phy_init(struct phy_ops **ops, u32 phy_id); -extern void ipq5332_qca8075_phy_interface_set_mode(uint32_t phy_id, uint32_t mode); +extern void ipq5332_qca8075_phy_interface_set_mode(uint32_t phy_id, + uint32_t mode); extern int ipq_qca8033_phy_init(struct phy_ops **ops, u32 phy_id); extern int ipq_qca8081_phy_init(struct phy_ops **ops, u32 phy_id); extern int ipq_qca_aquantia_phy_init(struct phy_ops **ops, u32 phy_id); @@ -126,7 +133,8 @@ int ipq5332_edma_alloc_rx_buffer(struct ipq5332_edma_hw *ehw, reg_data = ipq5332_edma_reg_read(IPQ5332_EDMA_REG_RXFILL_PROD_IDX( rxfill_ring->id)); - next = reg_data & IPQ5332_EDMA_RXFILL_PROD_IDX_MASK & (rxfill_ring->count - 1); + next = reg_data & IPQ5332_EDMA_RXFILL_PROD_IDX_MASK & + (rxfill_ring->count - 1); /* * Read RXFILL ring consumer index @@ -291,13 +299,15 @@ uint32_t ipq5332_edma_clean_rx(struct ipq5332_edma_common_info *c_info, /* * Check src_info from Rx Descriptor */ - src_port_num = IPQ5332_EDMA_RXDESC_SRC_INFO_GET(rxdesc_desc->rdes4); + src_port_num = + IPQ5332_EDMA_RXDESC_SRC_INFO_GET(rxdesc_desc->rdes4); if ((src_port_num & IPQ5332_EDMA_RXDESC_SRCINFO_TYPE_MASK) == IPQ5332_EDMA_RXDESC_SRCINFO_TYPE_PORTID) { src_port_num &= IPQ5332_EDMA_RXDESC_PORTNUM_BITS; } else { pr_warn("WARN: src_info_type:0x%x. Drop skb:%p\n", - (src_port_num & IPQ5332_EDMA_RXDESC_SRCINFO_TYPE_MASK), + (src_port_num & + IPQ5332_EDMA_RXDESC_SRCINFO_TYPE_MASK), skb); goto next_rx_desc; } @@ -498,8 +508,9 @@ static int ipq5332_eth_snd(struct eth_device *dev, void *packet, int length) * * Currently mac port no. is fixed as 3 for the purpose of testing */ - txdesc->tdes4 |= (IPQ5332_EDMA_DST_PORT_TYPE_SET(IPQ5332_EDMA_DST_PORT_TYPE) | - IPQ5332_EDMA_DST_PORT_ID_SET(IPQ5332_EDMA_MAC_PORT_NO)); + txdesc->tdes4 |= + (IPQ5332_EDMA_DST_PORT_TYPE_SET(IPQ5332_EDMA_DST_PORT_TYPE) | + IPQ5332_EDMA_DST_PORT_ID_SET(IPQ5332_EDMA_MAC_PORT_NO)); #endif /* @@ -546,7 +557,8 @@ static int ipq5332_eth_recv(struct eth_device *dev) struct ipq5332_edma_rxfill_ring *rxfill_ring; struct ipq5332_edma_hw *ehw = &c_info->hw; volatile u32 reg_data; - u32 rxdesc_intr_status = 0, txcmpl_intr_status = 0, rxfill_intr_status = 0; + u32 rxdesc_intr_status = 0; + u32 txcmpl_intr_status = 0, rxfill_intr_status = 0; int i; /* @@ -647,15 +659,18 @@ static int ipq5332_edma_setup_ring_resources(struct ipq5332_edma_hw *ehw) rxfill_ring->count = IPQ5332_EDMA_RX_RING_SIZE; rxfill_ring->id = ehw->rxfill_ring_start + i; rxfill_ring->desc = (void *)noncached_alloc( - IPQ5332_EDMA_RXFILL_DESC_SIZE * rxfill_ring->count, + IPQ5332_EDMA_RXFILL_DESC_SIZE * + rxfill_ring->count, CONFIG_SYS_CACHELINE_SIZE); if (rxfill_ring->desc == NULL) { - pr_info("%s: rxfill_ring->desc alloc error\n", __func__); + pr_info("%s: rxfill_ring->desc alloc error\n", + __func__); return -ENOMEM; } rxfill_ring->dma = virt_to_phys(rxfill_ring->desc); - pr_debug("rxfill ring id = %d, rxfill ring ptr = %p, rxfill ring dma = %u\n", + pr_debug("rxfill ring id = %d, rxfill ring ptr = %p," + "rxfill ring dma = %u\n", rxfill_ring->id, rxfill_ring->desc, (unsigned int) rxfill_ring->dma); @@ -701,10 +716,12 @@ static int ipq5332_edma_setup_ring_resources(struct ipq5332_edma_hw *ehw) rxdesc_ring->rxfill = ehw->rxfill_ring; rxdesc_ring->desc = (void *)noncached_alloc( - IPQ5332_EDMA_RXDESC_DESC_SIZE * rxdesc_ring->count, + IPQ5332_EDMA_RXDESC_DESC_SIZE * + rxdesc_ring->count, CONFIG_SYS_CACHELINE_SIZE); if (rxdesc_ring->desc == NULL) { - pr_info("%s: rxdesc_ring->desc alloc error\n", __func__); + pr_info("%s: rxdesc_ring->desc alloc error\n", + __func__); return -ENOMEM; } rxdesc_ring->dma = virt_to_phys(rxdesc_ring->desc); @@ -713,10 +730,12 @@ static int ipq5332_edma_setup_ring_resources(struct ipq5332_edma_hw *ehw) * Allocate secondary Rx ring descriptors */ rxdesc_ring->sdesc = (void *)noncached_alloc( - IPQ5332_EDMA_RX_SEC_DESC_SIZE * rxdesc_ring->count, + IPQ5332_EDMA_RX_SEC_DESC_SIZE * + rxdesc_ring->count, CONFIG_SYS_CACHELINE_SIZE); if (rxdesc_ring->sdesc == NULL) { - pr_info("%s: rxdesc_ring->sdesc alloc error\n", __func__); + pr_info("%s: rxdesc_ring->sdesc alloc error\n", + __func__); return -ENOMEM; } rxdesc_ring->sdma = virt_to_phys(rxdesc_ring->sdesc); @@ -730,10 +749,12 @@ static int ipq5332_edma_setup_ring_resources(struct ipq5332_edma_hw *ehw) txdesc_ring->count = IPQ5332_EDMA_TX_RING_SIZE; txdesc_ring->id = ehw->txdesc_ring_start + i; txdesc_ring->desc = (void *)noncached_alloc( - IPQ5332_EDMA_TXDESC_DESC_SIZE * txdesc_ring->count, + IPQ5332_EDMA_TXDESC_DESC_SIZE * + txdesc_ring->count, CONFIG_SYS_CACHELINE_SIZE); if (txdesc_ring->desc == NULL) { - pr_info("%s: txdesc_ring->desc alloc error\n", __func__); + pr_info("%s: txdesc_ring->desc alloc error\n", + __func__); return -ENOMEM; } txdesc_ring->dma = virt_to_phys(txdesc_ring->desc); @@ -767,10 +788,12 @@ static int ipq5332_edma_setup_ring_resources(struct ipq5332_edma_hw *ehw) * Allocate secondary Tx ring descriptors */ txdesc_ring->sdesc = (void *)noncached_alloc( - IPQ5332_EDMA_TX_SEC_DESC_SIZE * txdesc_ring->count, + IPQ5332_EDMA_TX_SEC_DESC_SIZE * + txdesc_ring->count, CONFIG_SYS_CACHELINE_SIZE); if (txdesc_ring->sdesc == NULL) { - pr_info("%s: txdesc_ring->sdesc alloc error\n", __func__); + pr_info("%s: txdesc_ring->sdesc alloc error\n", + __func__); return -ENOMEM; } txdesc_ring->sdma = virt_to_phys(txdesc_ring->sdesc); @@ -784,11 +807,13 @@ static int ipq5332_edma_setup_ring_resources(struct ipq5332_edma_hw *ehw) txcmpl_ring->count = IPQ5332_EDMA_TX_RING_SIZE; txcmpl_ring->id = ehw->txcmpl_ring_start + i; txcmpl_ring->desc = (void *)noncached_alloc( - IPQ5332_EDMA_TXCMPL_DESC_SIZE * txcmpl_ring->count, + IPQ5332_EDMA_TXCMPL_DESC_SIZE * + txcmpl_ring->count, CONFIG_SYS_CACHELINE_SIZE); if (txcmpl_ring->desc == NULL) { - pr_info("%s: txcmpl_ring->desc alloc error\n", __func__); + pr_info("%s: txcmpl_ring->desc alloc error\n", + __func__); return -ENOMEM; } txcmpl_ring->dma = virt_to_phys(txcmpl_ring->desc); @@ -833,7 +858,7 @@ static void ipq5332_edma_disable_rings(struct ipq5332_edma_hw *edma_hw) IPQ5332_EDMA_REG_TXDESC_CTRL(desc_index)); data &= ~IPQ5332_EDMA_TXDESC_TX_EN; ipq5332_edma_reg_write( - IPQ5332_EDMA_REG_TXDESC_CTRL(desc_index), data); + IPQ5332_EDMA_REG_TXDESC_CTRL(desc_index), data); } } @@ -861,23 +886,13 @@ static void ipq5332_edma_disable_intr(struct ipq5332_edma_hw *ehw) } #ifndef CONFIG_IPQ5332_RUMI -static void set_sgmii_mode(int port_id, int sg_mode) +void print_eth_info(int mac_unit, int phy_id, char *status, int speed, + char *duplex) { - if (port_id == 4) - sgmii_mode[0] = sg_mode; - else if (port_id == 5) - sgmii_mode[1] = sg_mode; + printf("eth%d PHY%d %s Speed :%d %s duplex\n",mac_unit, phy_id, + status, speed, duplex); } -static int get_sgmii_mode(int port_id) -{ - if (port_id == 4) - return sgmii_mode[0]; - else if (port_id == 5) - return sgmii_mode[1]; - else - return -1; -} #endif static int ipq5332_eth_init(struct eth_device *eth_dev, bd_t *this) @@ -888,32 +903,17 @@ static int ipq5332_eth_init(struct eth_device *eth_dev, bd_t *this) #ifndef CONFIG_IPQ5332_RUMI struct ipq5332_eth_dev *priv = eth_dev->priv; struct phy_ops *phy_get_ops; - static fal_port_speed_t old_speed[IPQ5332_PHY_MAX] = {[0 ... IPQ5332_PHY_MAX-1] = FAL_SPEED_BUTT}; + static fal_port_speed_t old_speed[IPQ5332_PHY_MAX] = + {[0 ... IPQ5332_PHY_MAX-1] = FAL_SPEED_BUTT}; static fal_port_speed_t curr_speed[IPQ5332_PHY_MAX]; fal_port_duplex_t duplex; char *lstatus[] = {"up", "Down"}; char *dp[] = {"Half", "Full"}; int linkup = 0; int clk[4] = {0}; - int phy_addr = -1, node = -1; - int aquantia_port[2] = {-1, -1}, aquantia_port_cnt = -1; - int sgmii_mode = -1; - int phy_node = -1, res = -1; - - node = fdt_path_offset(gd->fdt_blob, "/ess-switch"); - - if (node >= 0) { - aquantia_port_cnt = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_port_cnt", -1); - - if (aquantia_port_cnt >= 1) { - res = fdtdec_get_int_array(gd->fdt_blob, node, "aquantia_port", - (u32 *)aquantia_port, aquantia_port_cnt); - if (res < 0) - printf("Error: Aquantia port details not provided in DT\n"); - } - } - - phy_node = fdt_path_offset(gd->fdt_blob, "/ess-switch/port_phyinfo"); + int phy_addr = -1, ret = -1; + phy_info_t *phy_info; + int sgmii_mode = EPORT_WRAPPER_SGMII0_RGMII4, sfp_mode = -1; #endif /* * Check PHY link, speed, Duplex on all phys. @@ -922,18 +922,19 @@ static int ipq5332_eth_init(struct eth_device *eth_dev, bd_t *this) */ for (i = 0; i < IPQ5332_PHY_MAX; i++) { #ifndef CONFIG_IPQ5332_RUMI - if (phy_info[i]->phy_type == UNUSED_PHY_TYPE) + phy_info = port_info[i]->phy_info; + if (phy_info->phy_type == UNUSED_PHY_TYPE) continue; #ifdef CONFIG_QCA8084_SWT_MODE else if ((qca8084_swt_enb && qca8084_chip_detect) && - (phy_info[i]->phy_type == QCA8084_PHY_TYPE)) { + (phy_info->phy_type == QCA8084_PHY_TYPE)) { if (!ipq_qca8084_link_update(swt_info)) linkup++; continue; } #endif #ifdef CONFIG_ATHRS17C_SWITCH - else if (phy_info[i]->phy_type == ATHRS17C_SWITCH_TYPE) { + else if (phy_info->phy_type == ATHRS17C_SWITCH_TYPE) { if (s17c_swt_cfg.chip_detect) { if (!ipq_qca8337_link_update(&s17c_swt_cfg)) linkup++; @@ -941,48 +942,59 @@ static int ipq5332_eth_init(struct eth_device *eth_dev, bd_t *this) } } #endif - else { + else if (phy_info->phy_type == SFP_PHY_TYPE) { + status = phy_status_get_from_ppe(i); + duplex = FAL_FULL_DUPLEX; + sfp_mode = port_info[i]->mode; + + if (sfp_mode == EPORT_WRAPPER_SGMII_FIBER) { + curr_speed[i] = FAL_SPEED_1000; + } else if (sfp_mode == EPORT_WRAPPER_10GBASE_R) { + curr_speed[i] = FAL_SPEED_10000; + } else if (sfp_mode == EPORT_WRAPPER_SGMII_PLUS) { + curr_speed[i] = FAL_SPEED_2500; + } else { + printf("Error: Unsupported SPF mode \n"); + return ret; + } + } else { if (!priv->ops[i]) { printf("Phy ops not mapped\n"); continue; } phy_get_ops = priv->ops[i]; + phy_addr = phy_info->phy_address; if (!phy_get_ops->phy_get_link_status || !phy_get_ops->phy_get_speed || !phy_get_ops->phy_get_duplex) { - printf("Error:Link status/Get speed/Get duplex not mapped\n"); - return -1; + printf("Error:Link status/Get speed/" + "Get duplex not mapped\n"); + return ret; } - if (phy_node >= 0) { - /* - * For each ethernet port, one node should be added - * inside port_phyinfo with appropriate phy address - */ - phy_addr = phy_info[i]->phy_address; - } else { - printf("Error:Phy addresses not configured in DT\n"); - return -1; - } - - status = phy_get_ops->phy_get_link_status(priv->mac_unit, phy_addr); - phy_get_ops->phy_get_speed(priv->mac_unit, phy_addr, &curr_speed[i]); - phy_get_ops->phy_get_duplex(priv->mac_unit, phy_addr, &duplex); + status = phy_get_ops->phy_get_link_status( + priv->mac_unit, phy_addr); + phy_get_ops->phy_get_speed(priv->mac_unit, + phy_addr, &curr_speed[i]); + phy_get_ops->phy_get_duplex(priv->mac_unit, + phy_addr, &duplex); if (status == 0) { linkup++; if (old_speed[i] == curr_speed[i]) { - printf("eth%d PHY%d %s Speed :%d %s duplex\n", - priv->mac_unit, i, lstatus[status], curr_speed[i], + print_eth_info(priv->mac_unit, i, + lstatus[status], + curr_speed[i], dp[duplex]); continue; } else { old_speed[i] = curr_speed[i]; } } else { - printf("eth%d PHY%d %s Speed :%d %s duplex\n", - priv->mac_unit, i, lstatus[status], curr_speed[i], + print_eth_info(priv->mac_unit, i, + lstatus[status], + curr_speed[i], dp[duplex]); continue; } @@ -997,129 +1009,112 @@ static int ipq5332_eth_init(struct eth_device *eth_dev, bd_t *this) * * These conditions are checked above and if any of it * fails, then no config is done for that eth port. + * clk[0-3] = { RX_RCGR, RX_DIV, TX_RCGR, TX_DIV} */ switch (curr_speed[i]) { - case FAL_SPEED_10: - mac_speed = 0x0; + case FAL_SPEED_10: + mac_speed = 0x0; + clk[0] = 0x318; + clk[1] = 9; + clk[2] = 0x318; + clk[3] = 9; + if (phy_info->phy_type == QCA8081_PHY_TYPE) { + clk[1] = 3; + clk[3] = 3; + } + break; + case FAL_SPEED_100: + mac_speed = 0x1; + clk[0] = 0x318; + clk[1] = 1; + clk[2] = 0x318; + clk[3] = 1; + if (phy_info->phy_type == QCA8081_PHY_TYPE) { clk[0] = 0x309; - clk[1] = 0x9; - clk[2] = 0x409; - clk[3] = 0x9; - if (i == aquantia_port[0] || i == aquantia_port[1]) { - clk[1] = 0x18; - clk[3] = 0x18; - clk[0] = 0x313; - clk[2] = 0x413; - } - if (phy_node >= 0) { - if (phy_info[i]->phy_type == QCA8081_PHY_TYPE) { - set_sgmii_mode(i, 1); - clk[0] = 0x309; - clk[2] = 0x409; - } - } - printf("eth%d PHY%d %s Speed :%d %s duplex\n", - priv->mac_unit, i, lstatus[status], curr_speed[i], - dp[duplex]); - break; - case FAL_SPEED_100: - mac_speed = 0x1; - clk[0] = 0x309; - clk[1] = 0x0; - clk[2] = 0x409; - clk[3] = 0x0; - if (i == aquantia_port[0] || i == aquantia_port[1]) { - clk[1] = 0x4; - clk[3] = 0x4; - clk[0] = 0x309; - clk[2] = 0x409; - } - if (phy_node >= 0) { - if (phy_info[i]->phy_type == QCA8081_PHY_TYPE) { - set_sgmii_mode(i, 1); - clk[0] = 0x309; - clk[2] = 0x409; - } - } - printf("eth%d PHY%d %s Speed :%d %s duplex\n", - priv->mac_unit, i, lstatus[status], curr_speed[i], - dp[duplex]); - break; - case FAL_SPEED_1000: + clk[1] = 0; + clk[2] = 0x309; + clk[3] = 0; + } + break; + case FAL_SPEED_1000: + mac_speed = 0x2; + clk[0] = 0x304; + clk[1] = 0x0; + clk[2] = 0x304; + clk[3] = 0x0; + if (phy_info->phy_type == QCA8081_PHY_TYPE) { + clk[0] = 0x301; + clk[2] = 0x301; + } + break; + case FAL_SPEED_2500: + mac_speed = 0x4; + clk[0] = 0x307; + clk[1] = 0x0; + clk[2] = 0x307; + clk[3] = 0x0; + if (phy_info->phy_type == SFP_PHY_TYPE || + phy_info->phy_type == QCA8081_PHY_TYPE) { + clk[0] = 0x301; + clk[2] = 0x301; mac_speed = 0x2; - clk[0] = 0x301; - clk[1] = 0x0; - clk[2] = 0x401; - clk[3] = 0x0; - if (i == aquantia_port[0] || i == aquantia_port[1]) { - clk[0] = 0x304; - clk[2] = 0x404; - } - if (phy_node >= 0) { - if (phy_info[i]->phy_type == QCA8081_PHY_TYPE) { - set_sgmii_mode(i, 1); - clk[0] = 0x301; - clk[2] = 0x401; - } - } - printf("eth%d PHY%d %s Speed :%d %s duplex\n", - priv->mac_unit, i, lstatus[status], curr_speed[i], - dp[duplex]); - break; - case FAL_SPEED_2500: - clk[1] = 0x0; - clk[3] = 0x0; - if (i == aquantia_port[0] || i == aquantia_port[1]) { - mac_speed = 0x4; - clk[0] = 0x307; - clk[2] = 0x407; - } - if (phy_node >= 0) { - if (phy_info[i]->phy_type == QCA8081_PHY_TYPE) { - mac_speed = 0x2; - set_sgmii_mode(i, 0); - clk[0] = 0x301; - clk[2] = 0x401; - } - } - printf("eth%d PHY%d %s Speed :%d %s duplex\n", - priv->mac_unit, i, lstatus[status], curr_speed[i], - dp[duplex]); - break; - case FAL_SPEED_5000: - mac_speed = 0x5; - clk[1] = 0x0; - clk[3] = 0x0; - clk[0] = 0x303; - clk[2] = 0x403; - printf("eth%d PHY%d %s Speed :%d %s duplex\n", - priv->mac_unit, i, lstatus[status], curr_speed[i], - dp[duplex]); - break; - case FAL_SPEED_10000: - mac_speed = 0x3; - clk[1] = 0x0; - clk[3] = 0x0; - clk[0] = 0x301; - clk[2] = 0x401; - printf("eth%d PHY%d %s Speed :%d %s duplex\n", - priv->mac_unit, i, lstatus[status], curr_speed[i], - dp[duplex]); - break; - default: - printf("Unknown speed\n"); - break; + } + + if (phy_info->phy_type == QCA8081_PHY_TYPE) { + sgmii_mode = EPORT_WRAPPER_SGMII_PLUS; + } + break; + case FAL_SPEED_5000: + mac_speed = 0x5; + clk[0] = 0x303; + clk[1] = 0x0; + clk[2] = 0x303; + clk[3] = 0x0; + break; + case FAL_SPEED_10000: + mac_speed = 0x3; + clk[1] = 0x0; + clk[3] = 0x0; + clk[0] = 0x301; + clk[2] = 0x401; + break; + default: + ret = FAL_SPEED_BUTT; + break; } - if (phy_node >= 0) { - if (phy_info[i]->phy_type == QCA8081_PHY_TYPE) { - sgmii_mode = get_sgmii_mode(i); - ppe_port_bridge_txmac_set(i + 1, 1); - if (sgmii_mode == 1) { /* SGMII Mode */ - ppe_uniphy_mode_set(0x0, EPORT_WRAPPER_SGMII0_RGMII4); - } else if (sgmii_mode == 0) { /* SGMII Plus Mode */ - ppe_uniphy_mode_set(0x0, EPORT_WRAPPER_SGMII_PLUS); - } + if (ret == FAL_SPEED_BUTT) { + printf("Unknown speed\n"); + ret = -1; + } else { + print_eth_info(priv->mac_unit, i, lstatus[status], + curr_speed[i], dp[duplex]); + } + + if (phy_info->phy_type == QCA8081_PHY_TYPE) { + ppe_port_bridge_txmac_set(i, 1); + ppe_uniphy_mode_set(port_info[i]->uniphy_id, + sgmii_mode); + } + + if (phy_info->phy_type == SFP_PHY_TYPE) { + if (sfp_mode == EPORT_WRAPPER_SGMII_FIBER) { + /* SGMII Fiber mode */ + ppe_port_bridge_txmac_set(i, 1); + ppe_uniphy_mode_set(port_info[i]->uniphy_id, + EPORT_WRAPPER_SGMII_FIBER); + ppe_port_mux_mac_type_set(i + 1, + EPORT_WRAPPER_SGMII_FIBER); + } else if (sfp_mode == EPORT_WRAPPER_10GBASE_R) { + /* 10GBASE_R mode */ + ppe_uniphy_mode_set(port_info[i]->uniphy_id, + EPORT_WRAPPER_10GBASE_R); + ppe_port_mux_mac_type_set(i + 1, + EPORT_WRAPPER_10GBASE_R); + } else { /* SGMII Plus Mode */ + ppe_port_bridge_txmac_set(i, 1); + ppe_uniphy_mode_set(port_info[i]->uniphy_id, + EPORT_WRAPPER_SGMII_PLUS); } } @@ -1127,15 +1122,20 @@ static int ipq5332_eth_init(struct eth_device *eth_dev, bd_t *this) ipq5332_port_mac_clock_reset(i); - if (i == aquantia_port[0] || i == aquantia_port[1]) + if (phy_info->phy_type == AQ_PHY_TYPE){ ipq5332_uxsgmii_speed_set(i, mac_speed, duplex, status); - else + } else if ((phy_info->phy_type == SFP_PHY_TYPE) && + (sfp_mode != EPORT_WRAPPER_SGMII_FIBER)) { + ipq5332_10g_r_speed_set(i, status); + } else { ipq5332_pqsgmii_speed_set(i, mac_speed, status); + } #else - ppe_port_bridge_txmac_set(i + 1, 1); + ppe_port_bridge_txmac_set(i, 1); //FAL_SPEED_5000 mac_speed = 0x5; - ipq5332_uxsgmii_speed_set(i, mac_speed, FAL_DUPLEX_BUTT, status); + ipq5332_uxsgmii_speed_set(i, mac_speed, + FAL_DUPLEX_BUTT, status); #endif } @@ -1292,7 +1292,7 @@ static int ipq5332_edma_init_rings(struct ipq5332_edma_hw *ehw) * Configure one TxDesc ring */ static void ipq5332_edma_configure_txdesc_ring(struct ipq5332_edma_hw *ehw, - struct ipq5332_edma_txdesc_ring *txdesc_ring) + struct ipq5332_edma_txdesc_ring *txdesc_ring) { /* * Configure TXDESC ring @@ -1319,7 +1319,7 @@ static void ipq5332_edma_configure_txdesc_ring(struct ipq5332_edma_hw *ehw, * Configure one TxCmpl ring */ static void ipq5332_edma_configure_txcmpl_ring(struct ipq5332_edma_hw *ehw, - struct ipq5332_edma_txcmpl_ring *txcmpl_ring) + struct ipq5332_edma_txcmpl_ring *txcmpl_ring) { /* * Configure TxCmpl ring base address @@ -1350,15 +1350,15 @@ static void ipq5332_edma_configure_txcmpl_ring(struct ipq5332_edma_hw *ehw, * Configure one RxDesc ring */ static void ipq5332_edma_configure_rxdesc_ring(struct ipq5332_edma_hw *ehw, - struct ipq5332_edma_rxdesc_ring *rxdesc_ring) + struct ipq5332_edma_rxdesc_ring *rxdesc_ring) { uint32_t data; ipq5332_edma_reg_write(IPQ5332_EDMA_REG_RXDESC_BA(rxdesc_ring->id), - (uint32_t)(rxdesc_ring->dma & IPQ5332_EDMA_RING_DMA_MASK)); + (uint32_t)(rxdesc_ring->dma & IPQ5332_EDMA_RING_DMA_MASK)); ipq5332_edma_reg_write(IPQ5332_EDMA_REG_RXDESC_BA2(rxdesc_ring->id), - (uint32_t)(rxdesc_ring->sdma & IPQ5332_EDMA_RING_DMA_MASK)); + (uint32_t)(rxdesc_ring->sdma & IPQ5332_EDMA_RING_DMA_MASK)); data = rxdesc_ring->count & IPQ5332_EDMA_RXDESC_RING_SIZE_MASK; data |= (ehw->rx_payload_offset & IPQ5332_EDMA_RXDESC_PL_OFFSET_MASK) << @@ -1379,16 +1379,18 @@ static void ipq5332_edma_configure_rxdesc_ring(struct ipq5332_edma_hw *ehw, * Configure one RxFill ring */ static void ipq5332_edma_configure_rxfill_ring(struct ipq5332_edma_hw *ehw, - struct ipq5332_edma_rxfill_ring *rxfill_ring) + struct ipq5332_edma_rxfill_ring *rxfill_ring) { uint32_t data; ipq5332_edma_reg_write(IPQ5332_EDMA_REG_RXFILL_BA(rxfill_ring->id), - (uint32_t)(rxfill_ring->dma & IPQ5332_EDMA_RING_DMA_MASK)); + (uint32_t)(rxfill_ring->dma & + IPQ5332_EDMA_RING_DMA_MASK)); data = rxfill_ring->count & IPQ5332_EDMA_RXFILL_RING_SIZE_MASK; - ipq5332_edma_reg_write(IPQ5332_EDMA_REG_RXFILL_RING_SIZE(rxfill_ring->id), data); + ipq5332_edma_reg_write( + IPQ5332_EDMA_REG_RXFILL_RING_SIZE(rxfill_ring->id), data); } @@ -1426,21 +1428,6 @@ static void ipq5332_edma_configure_rings(struct ipq5332_edma_hw *ehw) pr_info("%s: successfull\n", __func__); } - -/* - * ipq5332_edma_hw_reset() - * EDMA hw reset - */ -void ipq5332_edma_hw_reset(void) -{ -#if 0 - writel(NSS_CC_EDMA_HW_RESET_ASSERT, NSS_CC_PPE_RESET_ADDR); - mdelay(500); - writel(NSS_CC_EDMA_HW_RESET_DEASSERT, NSS_CC_PPE_RESET_ADDR); - mdelay(100); -#endif -} - /* * ipq5332_edma_hw_init() * EDMA hw init @@ -1467,13 +1454,6 @@ int ipq5332_edma_hw_init(struct ipq5332_edma_hw *ehw) ehw->misc_intr_mask = 0xff; ehw->rx_payload_offset = 0x0; -#ifndef CONFIG_IPQ5332_RUMI - /* - * Reset EDMA - */ - ipq5332_edma_hw_reset(); -#endif - /* * Disable interrupts */ @@ -1672,30 +1652,47 @@ int ipq5332_edma_hw_init(struct ipq5332_edma_hw *ehw) return 0; } -void get_phy_address(int offset, phy_info_t * phy_info[], int max_phy_ports) +void ipq5332_prepare_phy_info(int offset, phy_info_t * phy_info) +{ + phy_info->phy_address = fdtdec_get_uint(gd->fdt_blob, + offset, "phy_address", 0); + phy_info->phy_type = fdtdec_get_uint(gd->fdt_blob, + offset, "phy_type", 0); + phy_info->forced_speed = fdtdec_get_uint(gd->fdt_blob, + offset, "forced-speed", 0); + phy_info->forced_duplex = fdtdec_get_uint(gd->fdt_blob, + offset, "forced-duplex", 0); +} + +void ipq5332_prepare_port_info(int offset, int max_phy_ports) { - int phy_type; - int phy_address; - int forced_speed, forced_duplex; int i; - for (i = 0; i < max_phy_ports; i++) + for (i = 0, offset = fdt_first_subnode(gd->fdt_blob, offset); + offset > 0 && i < max_phy_ports; ++i, + offset = fdt_next_subnode(gd->fdt_blob, offset)) { + port_info[i] = ipq5332_alloc_mem( + sizeof(ipq5332_edma_port_info_t)); + port_info[i]->phy_info = ipq5332_alloc_mem(sizeof(phy_info_t)); + ipq5332_prepare_phy_info(offset, port_info[i]->phy_info); + port_info[i]->port_id = i; + port_info[i]->uniphy_id = fdtdec_get_uint(gd->fdt_blob, + offset, "uniphy_id", 0); + port_info[i]->mode = fdtdec_get_uint(gd->fdt_blob, + offset, "uniphy_mode", 0); + } +} + +void ipq5332_prepare_switch_info(int offset, phy_info_t * phy_info[], + int max_phy_ports) +{ + int i; + + for (i = 0, offset = fdt_first_subnode(gd->fdt_blob, offset); + offset > 0 && i < max_phy_ports; ++i, + offset = fdt_next_subnode(gd->fdt_blob, offset)) { phy_info[i] = ipq5332_alloc_mem(sizeof(phy_info_t)); - i = 0; - for (offset = fdt_first_subnode(gd->fdt_blob, offset); offset > 0; - offset = fdt_next_subnode(gd->fdt_blob, offset)) { - phy_address = fdtdec_get_uint(gd->fdt_blob, - offset, "phy_address", 0); - phy_type = fdtdec_get_uint(gd->fdt_blob, - offset, "phy_type", 0); - forced_speed = fdtdec_get_uint(gd->fdt_blob, - offset, "forced-speed", 0); - forced_duplex = fdtdec_get_uint(gd->fdt_blob, - offset, "forced-duplex", 0); - phy_info[i]->phy_address = phy_address; - phy_info[i]->forced_speed = forced_speed; - phy_info[i]->forced_duplex = forced_duplex; - phy_info[i++]->phy_type = phy_type; + ipq5332_prepare_phy_info(offset, phy_info[i]); } } @@ -1708,7 +1705,8 @@ int ipq5332_edma_init(void *edma_board_cfg) int i; int ret = -1; ipq5332_edma_board_cfg_t ledma_cfg, *edma_cfg; -#ifndef CONFIG_IPQ5332_RUMI +#ifndef CONFIG_IPQ5332_RUMI + phy_info_t *phy_info; int phy_id; uint32_t phy_chip_id, phy_chip_id1, phy_chip_id2; #ifdef CONFIG_IPQ5332_QCA8075_PHY @@ -1721,8 +1719,7 @@ int ipq5332_edma_init(void *edma_board_cfg) #ifdef CONFIG_ATHRS17C_SWITCH int s17c_swt_enb = 0, s17c_rst_gpio = 0; #endif - int node, phy_addr, mode, phy_node = -1, res = -1; - int aquantia_port[2] = {-1, -1}, aquantia_port_cnt = -1; + int node, phy_addr, mode, phy_node = -1; #endif /* * Init non cache buffer @@ -1731,29 +1728,21 @@ int ipq5332_edma_init(void *edma_board_cfg) #ifndef CONFIG_IPQ5332_RUMI node = fdt_path_offset(gd->fdt_blob, "/ess-switch"); - - if (node >= 0) { - aquantia_port_cnt = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_port_cnt", -1); - - if (aquantia_port_cnt >= 1) { - res = fdtdec_get_int_array(gd->fdt_blob, node, "aquantia_port", - (u32 *)aquantia_port, aquantia_port_cnt); - if (res < 0) - printf("Error: Aquantia port details not provided in DT"); - } - } - #ifdef CONFIG_QCA8084_SWT_MODE - qca8084_swt_enb = fdtdec_get_uint(gd->fdt_blob, node, "qca8084_switch_enable", 0); + qca8084_swt_enb = fdtdec_get_uint(gd->fdt_blob, node, + "qca8084_switch_enable", 0); if (qca8084_swt_enb) { - qca8084_gpio = fdtdec_get_uint(gd->fdt_blob, node, "qca808x_gpio", 0); + qca8084_gpio = fdtdec_get_uint(gd->fdt_blob, node, + "qca808x_gpio", 0); if (qca8084_gpio) ipq_qca8084_switch_hw_reset(qca8084_gpio); } - phy_node = fdt_path_offset(gd->fdt_blob, "/ess-switch/qca8084_swt_info"); + phy_node = fdt_path_offset(gd->fdt_blob, + "/ess-switch/qca8084_swt_info"); if (phy_node >= 0) - get_phy_address(phy_node, swt_info, QCA8084_MAX_PORTS); + ipq5332_prepare_switch_info(phy_node, swt_info, + QCA8084_MAX_PORTS); #endif #ifdef CONFIG_ATHRS17C_SWITCH @@ -1763,9 +1752,7 @@ int ipq5332_edma_init(void *edma_board_cfg) s17c_swt_cfg.chip_detect = 0; s17c_rst_gpio = fdtdec_get_uint(gd->fdt_blob, node, "s17c_rst_gpio", 0); - ipq_s17c_switch_reset(s17c_rst_gpio); - /* * Set ref clock 25MHZ and enable Force mode */ @@ -1783,10 +1770,9 @@ int ipq5332_edma_init(void *edma_board_cfg) s17c_swt_cfg.port_count); } #endif - phy_node = fdt_path_offset(gd->fdt_blob, "/ess-switch/port_phyinfo"); if (phy_node >= 0) - get_phy_address(phy_node, phy_info, IPQ5332_PHY_MAX); + ipq5332_prepare_port_info(phy_node, IPQ5332_PHY_MAX); mode = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode0", -1); if (mode < 0) { @@ -1876,92 +1862,115 @@ int ipq5332_edma_init(void *edma_board_cfg) goto init_failed; for (phy_id = 0; phy_id < IPQ5332_PHY_MAX; phy_id++) { - if (phy_node >= 0) { - phy_addr = phy_info[phy_id]->phy_address; - } else { - printf("Error:Phy addresses not configured in DT\n"); - goto init_failed; - } + phy_info = port_info[phy_id]->phy_info; + phy_addr = phy_info->phy_address; #ifdef CONFIG_QCA8084_SWT_MODE - if (phy_info[phy_id]->phy_type == QCA8084_PHY_TYPE && !qca8084_init_done) { + if (phy_info->phy_type == QCA8084_PHY_TYPE && + !qca8084_init_done) { ipq_phy_addr_fixup(); ipq_clock_init(); qca8084_init_done = 1; } #endif - - phy_chip_id1 = ipq_mdio_read(phy_addr, QCA_PHY_ID1, NULL); - phy_chip_id2 = ipq_mdio_read(phy_addr, QCA_PHY_ID2, NULL); - phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2; - if (phy_id == aquantia_port[0] || phy_id == aquantia_port[1]) { - phy_chip_id1 = ipq_mdio_read(phy_addr, (1<<30) |(1<<16) | QCA_PHY_ID1, NULL); - phy_chip_id2 = ipq_mdio_read(phy_addr, (1<<30) |(1<<16) | QCA_PHY_ID2, NULL); - phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2; + if (phy_info->phy_type == AQ_PHY_TYPE) { + phy_chip_id1 = ipq_mdio_read(phy_addr, + (1<<30) |(1<<16) | + QCA_PHY_ID1, NULL); + phy_chip_id2 = ipq_mdio_read(phy_addr, + (1<<30) |(1<<16) | + QCA_PHY_ID2, NULL); + phy_chip_id = (phy_chip_id1 << 16) | + phy_chip_id2; + } else { + phy_chip_id1 = ipq_mdio_read(phy_addr, + QCA_PHY_ID1, NULL); + phy_chip_id2 = ipq_mdio_read(phy_addr, + QCA_PHY_ID2, NULL); + phy_chip_id = (phy_chip_id1 << 16) | + phy_chip_id2; } - pr_debug("phy_id is: 0x%x, phy_addr = 0x%x, phy_chip_id1 = 0x%x, phy_chip_id2 = 0x%x, phy_chip_id = 0x%x\n", - phy_id, phy_addr, phy_chip_id1, phy_chip_id2, phy_chip_id); + pr_debug("phy_id is: 0x%x, phy_addr = 0x%x," + "phy_chip_id1 = 0x%x," + "phy_chip_id2 = 0x%x," + "phy_chip_id = 0x%x\n", + phy_id, phy_addr, phy_chip_id1, + phy_chip_id2, phy_chip_id); + switch(phy_chip_id) { #ifdef CONFIG_IPQ5332_QCA8075_PHY - case QCA8075_PHY_V1_0_5P: - case QCA8075_PHY_V1_1_5P: - case QCA8075_PHY_V1_1_2P: - if (!sw_init_done) { - if (ipq5332_qca8075_phy_init(&ipq5332_edma_dev[i]->ops[phy_id], phy_addr) == 0) { - sw_init_done = 1; - } - } else { - ipq5332_qca8075_phy_map_ops(&ipq5332_edma_dev[i]->ops[phy_id]); + case QCA8075_PHY_V1_0_5P: + case QCA8075_PHY_V1_1_5P: + case QCA8075_PHY_V1_1_2P: + if (!sw_init_done) { + if (ipq5332_qca8075_phy_init( + &ipq5332_edma_dev[i]->ops[phy_id], + phy_addr) == 0) { + sw_init_done = 1; } - - if (mode == EPORT_WRAPPER_PSGMII) - ipq5332_qca8075_phy_interface_set_mode(phy_addr, 0x0); - else if (mode == EPORT_WRAPPER_QSGMII) - ipq5332_qca8075_phy_interface_set_mode(phy_addr, 0x4); - break; + } else { + ipq5332_qca8075_phy_map_ops( + &ipq5332_edma_dev[i]->ops[phy_id]); + } + if (mode == EPORT_WRAPPER_PSGMII) + ipq5332_qca8075_phy_interface_set_mode( + phy_addr, 0x0); + else if (mode == EPORT_WRAPPER_QSGMII) + ipq5332_qca8075_phy_interface_set_mode( + phy_addr, 0x4); + break; #endif #ifdef CONFIG_QCA8033_PHY - case QCA8033_PHY: - ipq_qca8033_phy_init(&ipq5332_edma_dev[i]->ops[phy_id], phy_addr); - break; + case QCA8033_PHY: + ipq_qca8033_phy_init( + &ipq5332_edma_dev[i]->ops[phy_id], + phy_addr); + break; #endif #ifdef CONFIG_QCA8081_PHY - case QCA8081_PHY: - case QCA8081_1_1_PHY: - ipq_qca8081_phy_init(&ipq5332_edma_dev[i]->ops[phy_id], phy_addr); - break; + case QCA8081_PHY: + case QCA8081_1_1_PHY: + ipq_qca8081_phy_init( + &ipq5332_edma_dev[i]->ops[phy_id], + phy_addr); + break; #endif #ifdef CONFIG_QCA8084_SWT_MODE - case QCA8084_PHY: - qca8084_chip_detect = 1; - break; + case QCA8084_PHY: + qca8084_chip_detect = 1; + break; #endif #ifdef CONFIG_ATHRS17C_SWITCH - case QCA8337_PHY: - if (s17c_swt_enb) - s17c_swt_cfg.chip_detect = 1; - break; + case QCA8337_PHY: + if (s17c_swt_enb) + s17c_swt_cfg.chip_detect = 1; + break; #endif #ifdef CONFIG_IPQ_QCA_AQUANTIA_PHY - case AQUANTIA_PHY_107: - case AQUANTIA_PHY_109: - case AQUANTIA_PHY_111: - case AQUANTIA_PHY_111B0: - case AQUANTIA_PHY_112: - case AQUANTIA_PHY_112C: - case AQUANTIA_PHY_113C_A0: - case AQUANTIA_PHY_113C_A1: - case AQUANTIA_PHY_113C_B0: - case AQUANTIA_PHY_113C_B1: - ipq_board_fw_download(phy_addr); - mdelay(100); - ipq_qca_aquantia_phy_init(&ipq5332_edma_dev[i]->ops[phy_id], phy_addr); - break; + case AQUANTIA_PHY_107: + case AQUANTIA_PHY_109: + case AQUANTIA_PHY_111: + case AQUANTIA_PHY_111B0: + case AQUANTIA_PHY_112: + case AQUANTIA_PHY_112C: + case AQUANTIA_PHY_113C_A0: + case AQUANTIA_PHY_113C_A1: + case AQUANTIA_PHY_113C_B0: + case AQUANTIA_PHY_113C_B1: + ipq_board_fw_download(phy_addr); + mdelay(100); + ipq_qca_aquantia_phy_init( + &ipq5332_edma_dev[i]->ops[phy_id], + phy_addr); + break; #endif - default: - if (phy_info[phy_id]->phy_type != SFP_PHY_TYPE) - printf("\nphy chip id: 0x%x id not matching for phy id: 0x%x with phy_type: 0x%x and phy address: 0x%x", - phy_chip_id, phy_id, phy_info[phy_id]->phy_type, phy_info[phy_id]->phy_address); - break; + default: + if (phy_info->phy_type != SFP_PHY_TYPE) + printf("Port%d Invalid Phy Id 0x%x" + "Type 0x%x add 0x%x\n", + phy_id, phy_chip_id, + phy_info->phy_type, + phy_info->phy_address); + break; } } #endif @@ -1975,13 +1984,17 @@ int ipq5332_edma_init(void *edma_board_cfg) #ifdef CONFIG_QCA8084_SWT_MODE /** QCA8084 switch specific configurations */ if (qca8084_swt_enb && qca8084_chip_detect) { - /** Force speed ipq5332 2nd port for QCA8084 switch mode */ + /* + * Force speed ipq5332 2nd port + * for QCA8084 switch mode + */ clk[0] = 0x301; clk[1] = 0x0; - clk[2] = 0x401; + clk[2] = 0x301; clk[3] = 0x0; - pr_debug("Force speed ipq5332 2nd PORT for QCA8084 switch mode \n"); + pr_debug("Force speed ipq5332 2nd PORT " + "for QCA8084 switch mode \n"); ipq5332_speed_clock_set(PORT1, clk); /** Force Link-speed: 1000M @@ -1990,7 +2003,8 @@ int ipq5332_edma_init(void *edma_board_cfg) ret = ipq_qca8084_hw_init(swt_info); if (ret < 0) { - printf("Error: ipq_qca8084_hw_init failed \n"); + printf("Error: qca8084 switch mode" + "hw_init failed \n"); goto init_failed; } } diff --git a/drivers/net/ipq5332/ipq5332_ppe.c b/drivers/net/ipq5332/ipq5332_ppe.c index d04e42502b..f9fce53f3c 100644 --- a/drivers/net/ipq5332/ipq5332_ppe.c +++ b/drivers/net/ipq5332/ipq5332_ppe.c @@ -82,7 +82,8 @@ void ppe_ipo_action_set(union ipo_action_u *hw_act, int rule_id) } } -void ipq5332_ppe_acl_set(int rule_id, int rule_type, int field0, int field1, int mask, int permit, int deny) +void ipq5332_ppe_acl_set(int rule_id, int rule_type, int field0, int field1, + int mask, int permit, int deny) { union ipo_rule_reg_u hw_reg = {0}; union ipo_mask_reg_u hw_mask = {0}; @@ -198,14 +199,16 @@ void ppe_port_bridge_txmac_set(int port_id, int status) uint32_t reg_value = 0; ipq5332_ppe_reg_read(IPE_L2_BASE_ADDR + PORT_BRIDGE_CTRL_ADDRESS + - (port_id * PORT_BRIDGE_CTRL_INC), ®_value); + ((port_id * PORT_BRIDGE_CTRL_INC) + PORT_BRIDGE_CTRL_INC), + ®_value); if (status == 0) reg_value |= TX_MAC_EN; else reg_value &= ~TX_MAC_EN; ipq5332_ppe_reg_write(IPE_L2_BASE_ADDR + PORT_BRIDGE_CTRL_ADDRESS + - (port_id * PORT_BRIDGE_CTRL_INC), reg_value); + ((port_id * PORT_BRIDGE_CTRL_INC) + PORT_BRIDGE_CTRL_INC), + reg_value); } @@ -221,8 +224,10 @@ void ppe_port_txmac_status_set(uint32_t port) ipq5332_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), reg_value); - pr_debug("NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION Address = 0x%x -> Value = %u\n", - PPE_SWITCH_NSS_SWITCH_XGMAC0 + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), + pr_debug("NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION Address" + " = 0x%x -> Value = %u\n", + PPE_SWITCH_NSS_SWITCH_XGMAC0 + + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), reg_value); } @@ -233,7 +238,8 @@ void ppe_port_rxmac_status_set(uint32_t port) pr_debug("DEBUGGING rxmac_status_set......... PORTID = %d\n", port); ipq5332_ppe_reg_read(PPE_SWITCH_NSS_SWITCH_XGMAC0 + MAC_RX_CONFIGURATION_ADDRESS + - (port * NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION), ®_value); + (port * NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION), + ®_value); reg_value |= 0x300000c0; reg_value |=RE; @@ -241,9 +247,11 @@ void ppe_port_rxmac_status_set(uint32_t port) reg_value |=CST; ipq5332_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 + MAC_RX_CONFIGURATION_ADDRESS + - (port * NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION), reg_value); + (port * NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION), + reg_value); - pr_debug("NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION Address = 0x%x -> Value = %u\n", + pr_debug("NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION Address" + " = 0x%x -> Value = %u\n", PPE_SWITCH_NSS_SWITCH_XGMAC0 + MAC_RX_CONFIGURATION_ADDRESS + (port * NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION), reg_value); @@ -251,11 +259,12 @@ void ppe_port_rxmac_status_set(uint32_t port) void ppe_mac_packet_filter_set(uint32_t port) { - pr_debug("DEBUGGING mac_packet_filter_set......... PORTID = %d\n", port); + pr_debug("DEBUGGING mac_packet_filter_set...... PORTID = %d\n", port); ipq5332_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 + MAC_PACKET_FILTER_ADDRESS + (port * MAC_PACKET_FILTER_INC), 0x80000081); - pr_debug("NSS_SWITCH_XGMAC_MAC_PACKET_FILTER Address = 0x%x -> Value = %u\n", + pr_debug("NSS_SWITCH_XGMAC_MAC_PACKET_FILTER Address" + " = 0x%x -> Value = %u\n", PPE_SWITCH_NSS_SWITCH_XGMAC0 + MAC_PACKET_FILTER_ADDRESS + (port * MAC_PACKET_FILTER_ADDRESS), 0x80000081); @@ -267,43 +276,28 @@ void ppe_mac_packet_filter_set(uint32_t port) */ void ipq5332_port_mac_clock_reset(int port) { - int reg_val, reg_val1; + int reg_val; - reg_val = readl(NSS_CC_PPE_RESET_ADDR); - reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET); - switch(port) { - case 0: - /* Assert */ - reg_val |= GCC_PPE_PORT1_MAC_ARES; - reg_val1 |= GCC_PORT1_ARES; - writel(reg_val, NSS_CC_PPE_RESET_ADDR); - writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET); - mdelay(150); - /* De-Assert */ - reg_val = readl(NSS_CC_PPE_RESET_ADDR); - reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET); - reg_val &= ~GCC_PPE_PORT1_MAC_ARES; - reg_val1 &= ~GCC_PORT1_ARES; - break; - case 1: - /* Assert */ - reg_val |= GCC_PPE_PORT2_MAC_ARES; - reg_val1 |= GCC_PORT2_ARES; - writel(reg_val, NSS_CC_PPE_RESET_ADDR); - writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET); - mdelay(150); - /* De-Assert */ - reg_val = readl(NSS_CC_PPE_RESET_ADDR); - reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET); - reg_val &= ~GCC_PPE_PORT2_MAC_ARES; - reg_val1 &= ~GCC_PORT2_ARES; - break; - default: - break; - } - writel(reg_val, NSS_CC_PPE_RESET_ADDR); - writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET); - mdelay(150); + /* PPE Reset */ + writel(0x1, NSS_CC_PPE_BCR); + udelay(10); + writel(0x0, NSS_CC_PPE_BCR); + + reg_val = readl(NSS_CC_UNIPHY_PORT1_RX_CBCR + (port * 0x8)); + reg_val |= GCC_PORT1_ARES; + writel(reg_val, NSS_CC_UNIPHY_PORT1_RX_CBCR + (port * 0x8)); + mdelay(10); + reg_val = readl(NSS_CC_UNIPHY_PORT1_RX_CBCR + (port * 0x8)); + reg_val &= ~GCC_PORT1_ARES; + writel(reg_val, NSS_CC_UNIPHY_PORT1_RX_CBCR + (port * 0x8)); + + reg_val = readl(NSS_CC_UNIPHY_PORT1_RX_CBCR + 0x4 + (port * 0x8)); + reg_val |= GCC_PORT1_ARES; + writel(reg_val, NSS_CC_UNIPHY_PORT1_RX_CBCR + 0x4 + (port * 0x8)); + mdelay(10); + reg_val = readl(NSS_CC_UNIPHY_PORT1_RX_CBCR + 0x4 + (port * 0x8)); + reg_val &= ~GCC_PORT1_ARES; + writel(reg_val, NSS_CC_UNIPHY_PORT1_RX_CBCR + 0x4 + (port * 0x8)); } void ipq5332_speed_clock_set(int port_id, int clk[4]) @@ -313,14 +307,15 @@ void ipq5332_speed_clock_set(int port_id, int clk[4]) for (i = 0; i < 6; i++) { - reg_val[i] = readl(NSS_CC_PORT1_RX_CMD_RCGR + (i * 0x4) + (port_id * 0x18)); + reg_val[i] = readl(NSS_CC_PORT1_RX_CMD_RCGR + (i * 0x4) + + (port_id * 0x18)); } reg_val[0] &= ~0x1; reg_val[1] &= ~0x71f; - reg_val[2] &= ~0x1ff; + reg_val[2] &= ~0xf; reg_val[3] &= ~0x1; reg_val[4] &= ~0x71f; - reg_val[5] &= ~0x1ff; + reg_val[5] &= ~0xf; reg_val[1] |= clk[0]; reg_val[2] |= clk[1]; @@ -334,7 +329,8 @@ void ipq5332_speed_clock_set(int port_id, int clk[4]) /* Port Tx direction speed clock cfg */ writel(reg_val[4], NSS_CC_PORT1_RX_CMD_RCGR + 0x10 + (port_id * 0x18)); writel(reg_val[5], NSS_CC_PORT1_RX_CMD_RCGR + 0x14 + (port_id * 0x18)); - writel(reg_val[3] | 0x1, NSS_CC_PORT1_RX_CMD_RCGR + 0xc + (port_id * 0x18)); + writel(reg_val[3] | 0x1, NSS_CC_PORT1_RX_CMD_RCGR + 0xc + + (port_id * 0x18)); } int phy_status_get_from_ppe(int port_id) @@ -342,10 +338,9 @@ int phy_status_get_from_ppe(int port_id) uint32_t reg_field = 0; ipq5332_ppe_reg_read(PORT_PHY_STATUS_ADDRESS, ®_field); - if (port_id == (PORT5 - PPE_UNIPHY_INSTANCE1)) - reg_field >>= PORT_PHY_STATUS_PORT5_1_OFFSET; - else - reg_field >>= PORT_PHY_STATUS_PORT6_OFFSET; + + if (port_id == 1) + reg_field >>= PORT_PHY_STATUS_PORT2_OFFSET; return ((reg_field >> 7) & 0x1) ? 0 : 1; } @@ -362,15 +357,17 @@ void ppe_xgmac_10g_r_speed_set(uint32_t port) ipq5332_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), reg_value); - pr_debug("NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION Address = 0x%x -> Value = %u\n", - PPE_SWITCH_NSS_SWITCH_XGMAC0 + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), - reg_value); + pr_debug("NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION Address = 0x%x" + "-> Value = %u\n", + PPE_SWITCH_NSS_SWITCH_XGMAC0 + + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), + reg_value); } void ipq5332_10g_r_speed_set(int port, int status) { ppe_xgmac_10g_r_speed_set(port); - ppe_port_bridge_txmac_set(port + 1, status); + ppe_port_bridge_txmac_set(port, status); ppe_port_txmac_status_set(port); ppe_port_rxmac_status_set(port); ppe_mac_packet_filter_set(port); @@ -408,12 +405,15 @@ void ppe_xgmac_speed_set(uint32_t port, int speed) reg_value |=JD; ipq5332_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), reg_value); - pr_debug("NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION Address = 0x%x -> Value = %u\n", - PPE_SWITCH_NSS_SWITCH_XGMAC0 + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), - reg_value); - + pr_debug("NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION Address = 0x%x" + " -> Value = %u\n", + PPE_SWITCH_NSS_SWITCH_XGMAC0 + + (port * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), + reg_value); } + + void ipq5332_uxsgmii_speed_set(int port, int speed, int duplex, int status) { @@ -433,7 +433,7 @@ void ipq5332_uxsgmii_speed_set(int port, int speed, int duplex, ppe_uniphy_usxgmii_duplex_set(uniphy_index, duplex); ppe_uniphy_usxgmii_port_reset(uniphy_index); #endif - ppe_port_bridge_txmac_set(port + 1, status); + ppe_port_bridge_txmac_set(port, status); ppe_port_txmac_status_set(port); ppe_port_rxmac_status_set(port); ppe_mac_packet_filter_set(port); @@ -441,7 +441,7 @@ void ipq5332_uxsgmii_speed_set(int port, int speed, int duplex, void ipq5332_pqsgmii_speed_set(int port, int speed, int status) { - ppe_port_bridge_txmac_set(port + 1, status); + ppe_port_bridge_txmac_set(port, status); ipq5332_ppe_reg_write(IPQ5332_PPE_MAC_SPEED + (0x200 * port), speed); ipq5332_ppe_reg_write(IPQ5332_PPE_MAC_ENABLE + (0x200 * port), 0x73); ipq5332_ppe_reg_write(IPQ5332_PPE_MAC_MIB_CTL + (0x200 * port), 0x1); @@ -464,12 +464,12 @@ static void ipq5332_ppe_flow_port_map_tbl_port_num_set(int queue, int port) static void ipq5332_ppe_flow_map_tbl_set(int queue, int port) { uint32_t val = port | 0x401000; /* c_drr_wt = 1, e_drr_wt = 1 */ - ipq5332_ppe_reg_write(IPQ5332_PPE_L0_FLOW_MAP_TBL + queue * IPQ5332_PPE_L0_FLOW_MAP_TBL_INC, - val); + ipq5332_ppe_reg_write(IPQ5332_PPE_L0_FLOW_MAP_TBL + queue * + IPQ5332_PPE_L0_FLOW_MAP_TBL_INC, val); val = port | 0x100400; /* c_drr_wt = 1, e_drr_wt = 1 */ - ipq5332_ppe_reg_write(IPQ5332_PPE_L1_FLOW_MAP_TBL + port * IPQ5332_PPE_L1_FLOW_MAP_TBL_INC, - val); + ipq5332_ppe_reg_write(IPQ5332_PPE_L1_FLOW_MAP_TBL + port * + IPQ5332_PPE_L1_FLOW_MAP_TBL_INC, val); } /* @@ -477,6 +477,38 @@ static void ipq5332_ppe_flow_map_tbl_set(int queue, int port) */ static void ipq5332_ppe_tdm_configuration(void) { +#ifndef CONFIG_IPQ5332_RUMI + ipq5332_ppe_reg_write(0xc000, 0x22); + ipq5332_ppe_reg_write(0xc010, 0x30); + ipq5332_ppe_reg_write(0xc020, 0x21); + ipq5332_ppe_reg_write(0xc030, 0x31); + ipq5332_ppe_reg_write(0xc040, 0x22); + ipq5332_ppe_reg_write(0xc050, 0x32); + ipq5332_ppe_reg_write(0xc060, 0x20); + ipq5332_ppe_reg_write(0xc070, 0x30); + ipq5332_ppe_reg_write(0xc080, 0x22); + ipq5332_ppe_reg_write(0xc090, 0x31); + ipq5332_ppe_reg_write(0xc0a0, 0x21); + ipq5332_ppe_reg_write(0xc0b0, 0x32); + ipq5332_ppe_reg_write(0xc0c0, 0x20); + ipq5332_ppe_reg_write(0xc0d0, 0x30); + ipq5332_ppe_reg_write(0xc0e0, 0x21); + ipq5332_ppe_reg_write(0xc0f0, 0x31); + ipq5332_ppe_reg_write(0xc100, 0x22); + ipq5332_ppe_reg_write(0xc110, 0x32); + ipq5332_ppe_reg_write(0xc120, 0x20); + ipq5332_ppe_reg_write(0xc130, 0x30); + ipq5332_ppe_reg_write(0xc140, 0x22); + ipq5332_ppe_reg_write(0xc150, 0x31); + ipq5332_ppe_reg_write(0xc160, 0x21); + ipq5332_ppe_reg_write(0xc170, 0x32); + ipq5332_ppe_reg_write(0xc180, 0x22); + ipq5332_ppe_reg_write(0xc190, 0x30); + ipq5332_ppe_reg_write(0xc1a0, 0x20); + ipq5332_ppe_reg_write(0xc1b0, 0x31); + ipq5332_ppe_reg_write(0xc1c0, 0x22); + ipq5332_ppe_reg_write(0xc1d0, 0x32); +#else ipq5332_ppe_reg_write(0xc000, 0x20); ipq5332_ppe_reg_write(0xc010, 0x32); ipq5332_ppe_reg_write(0xc020, 0x21); @@ -484,11 +516,11 @@ static void ipq5332_ppe_tdm_configuration(void) ipq5332_ppe_reg_write(0xc040, 0x22); ipq5332_ppe_reg_write(0xc050, 0x31); ipq5332_ppe_reg_write(0xb000, 0x80000006); - ipq5332_ppe_reg_write(0x47a000, 0xfa10); ipq5332_ppe_reg_write(0x47a010, 0xfc21); ipq5332_ppe_reg_write(0x47a020, 0xf902); ipq5332_ppe_reg_write(0x400000, 0x3); +#endif } /* @@ -585,8 +617,10 @@ static void ipq5332_ppe_enable_port_counter(void) */ static void ipq5332_ppe_c_sp_cfg_tbl_drr_id_set(int id) { - ipq5332_ppe_reg_write(IPQ5332_PPE_L0_C_SP_CFG_TBL + (id * 0x80), id * 2); - ipq5332_ppe_reg_write(IPQ5332_PPE_L1_C_SP_CFG_TBL + (id * 0x80), id * 2); + ipq5332_ppe_reg_write(IPQ5332_PPE_L0_C_SP_CFG_TBL + + (id * 0x80), id * 2); + ipq5332_ppe_reg_write(IPQ5332_PPE_L1_C_SP_CFG_TBL + + (id * 0x80), id * 2); } /* @@ -594,8 +628,10 @@ static void ipq5332_ppe_c_sp_cfg_tbl_drr_id_set(int id) */ static void ipq5332_ppe_e_sp_cfg_tbl_drr_id_set(int id) { - ipq5332_ppe_reg_write(IPQ5332_PPE_L0_E_SP_CFG_TBL + (id * 0x80), id * 2 + 1); - ipq5332_ppe_reg_write(IPQ5332_PPE_L1_E_SP_CFG_TBL + (id * 0x80), id * 2 + 1); + ipq5332_ppe_reg_write(IPQ5332_PPE_L0_E_SP_CFG_TBL + + (id * 0x80), id * 2 + 1); + ipq5332_ppe_reg_write(IPQ5332_PPE_L1_E_SP_CFG_TBL + + (id * 0x80), id * 2 + 1); } static void ppe_port_mux_set(int port_id, int port_type, int mode) @@ -611,13 +647,14 @@ static void ppe_port_mux_set(int port_id, int port_type, int mode) else if (port_type == PORT_XGMAC_TYPE) mux_mac_type = IPQ5332_PORT_MUX_XMAC_TYPE; else - printf("\nAttention!!!..Port type configured wrongly..port_id = %d, mode = %d, port_type = %d", - port_id, mode, port_type); + printf("\nAttention!!!..Port type configured wrongly.." + "port_id = %d, mode = %d, port_type = %d", + port_id, mode, port_type); port_mux_ctrl.val = 0; ipq5332_ppe_reg_read(IPQ5332_PORT_MUX_CTRL, &(port_mux_ctrl.val)); - pr_debug("\nBEFORE UPDATE: Port MUX CTRL value is %u", port_mux_ctrl.val); - + pr_debug("\nBEFORE UPDATE: Port MUX CTRL value is %u", + port_mux_ctrl.val); switch (port_id) { case PORT1: @@ -633,7 +670,8 @@ static void ppe_port_mux_set(int port_id, int port_type, int mode) } ipq5332_ppe_reg_write(IPQ5332_PORT_MUX_CTRL, port_mux_ctrl.val); - pr_debug("\nAFTER UPDATE: Port MUX CTRL value is %u", port_mux_ctrl.val); + pr_debug("\nAFTER UPDATE: Port MUX CTRL value is %u", + port_mux_ctrl.val); } void ppe_port_mux_mac_type_set(int port_id, int mode) @@ -653,8 +691,9 @@ void ppe_port_mux_mac_type_set(int port_id, int mode) port_type = PORT_XGMAC_TYPE; break; default: - printf("\nError during port_type set: mode is %d, port_id is: %d", - mode, port_id); + printf("\nError during port_type set: mode is %d, " + "port_id is: %d", + mode, port_id); return; } ppe_port_mux_set(port_id, port_type, mode); @@ -701,6 +740,7 @@ void ipq5332_ppe_provision_init(void) { int i; uint32_t queue; + uint32_t bridge_ctrl; /* tdm/sched configuration */ ipq5332_ppe_tdm_configuration(); @@ -709,28 +749,20 @@ void ipq5332_ppe_provision_init(void) /* Add CPU port 0 to VSI 2 */ ipq5332_ppe_vp_port_tbl_set(0, 2); - /* Add port 1 - 4 to VSI 2 */ + /* Add port 1 - 2 to VSI 2 */ ipq5332_ppe_vp_port_tbl_set(1, 2); ipq5332_ppe_vp_port_tbl_set(2, 2); - ipq5332_ppe_vp_port_tbl_set(3, 2); - ipq5332_ppe_vp_port_tbl_set(4, 2); - ipq5332_ppe_vp_port_tbl_set(5, 2); - ipq5332_ppe_vp_port_tbl_set(6, 2); #else ipq5332_ppe_vp_port_tbl_set(1, 2); ipq5332_ppe_vp_port_tbl_set(2, 3); - ipq5332_ppe_vp_port_tbl_set(3, 4); - ipq5332_ppe_vp_port_tbl_set(4, 5); - ipq5332_ppe_vp_port_tbl_set(5, 6); - ipq5332_ppe_vp_port_tbl_set(6, 7); #endif /* Unicast priority map */ ipq5332_ppe_reg_write(IPQ5332_PPE_QM_UPM_TBL, 0); - /* Port0 - 7 unicast queue settings */ - for (i = 0; i < 8; i++) { + /* Port0 - 3 unicast queue settings */ + for (i = 0; i < 3; i++) { if (i == 0) queue = 0; else @@ -748,7 +780,7 @@ void ipq5332_ppe_provision_init(void) ipq5332_ppe_reg_write(0x403000, 0x00401000); /* Port1 - 7 multicast queue */ - for (i = 1; i < 8; i++) { + for (i = 1; i < 3; i++) { ipq5332_ppe_reg_write(0x409100 + ((i - 1) * 0x40), i); ipq5332_ppe_reg_write(0x403100 + ((i - 1) * 0x40), 0x401000 | i); } @@ -771,57 +803,51 @@ void ipq5332_ppe_provision_init(void) /* * Port0 - TX_EN is set by default, Port1 - LRN_EN is set * Port0 -> CPU Port - * Port1-6 -> Ethernet Ports - * Port7 -> EIP197 + * Port1-2 -> Ethernet Ports */ - for (i = 0; i < 8; i++) { - if (i == 0) - ipq5332_ppe_reg_write(IPQ5332_PPE_PORT_BRIDGE_CTRL_OFFSET + (i * 4), + for (i = 0; i < 3; i++) { + bridge_ctrl = IPQ5332_PPE_PORT_BRIDGE_CTRL_OFFSET; + if (i == 0) { + ipq5332_ppe_reg_write(bridge_ctrl + (i * 4), IPQ5332_PPE_PORT_BRIDGE_CTRL_PROMISC_EN | IPQ5332_PPE_PORT_BRIDGE_CTRL_TXMAC_EN | IPQ5332_PPE_PORT_BRIDGE_CTRL_PORT_ISOLATION_BMP | IPQ5332_PPE_PORT_BRIDGE_CTRL_STATION_LRN_EN | IPQ5332_PPE_PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN); - else if (i == 7) - ipq5332_ppe_reg_write(IPQ5332_PPE_PORT_BRIDGE_CTRL_OFFSET + (i * 4), - IPQ5332_PPE_PORT_BRIDGE_CTRL_PROMISC_EN | - IPQ5332_PPE_PORT_BRIDGE_CTRL_PORT_ISOLATION_BMP | - IPQ5332_PPE_PORT_BRIDGE_CTRL_STATION_LRN_EN | - IPQ5332_PPE_PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN); - else - ipq5332_ppe_reg_write(IPQ5332_PPE_PORT_BRIDGE_CTRL_OFFSET + (i * 4), + } else { + ipq5332_ppe_reg_write(bridge_ctrl + (i * 4), IPQ5332_PPE_PORT_BRIDGE_CTRL_PROMISC_EN | IPQ5332_PPE_PORT_BRIDGE_CTRL_PORT_ISOLATION_BMP); + } } /* Global learning */ ipq5332_ppe_reg_write(0x060038, 0xc0); #ifdef CONFIG_IPQ5332_BRIDGED_MODE - ipq5332_vsi_setup(2, 0x7f); + ipq5332_vsi_setup(2, 0x7); #else ipq5332_vsi_setup(2, 0x03); ipq5332_vsi_setup(3, 0x05); - ipq5332_vsi_setup(4, 0x09); - ipq5332_vsi_setup(5, 0x11); - ipq5332_vsi_setup(6, 0x21); - ipq5332_vsi_setup(7, 0x41); #endif - /* Port 0-7 STP */ - for (i = 0; i < 8; i++) + /* Port 0-3 STP */ + for (i = 0; i < 3; i++) ipq5332_ppe_reg_write(IPQ5332_PPE_STP_BASE + (0x4 * i), 0x3); ipq5332_ppe_interface_mode_init(); /* Port 1-2 disable */ for (i = 0; i < 2; i++) { ipq5332_gmac_port_disable(i); - ppe_port_bridge_txmac_set(i + 1, 1); + ppe_port_bridge_txmac_set(i, 1); } /* Allowing DHCP packets */ - ipq5332_ppe_acl_set(0, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 67, 0xffff, 0, 0); - ipq5332_ppe_acl_set(1, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 68, 0xffff, 0, 0); + ipq5332_ppe_acl_set(0, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 67, + 0xffff, 0, 0); + ipq5332_ppe_acl_set(1, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 68, + 0xffff, 0, 0); /* Dropping all the UDP packets */ - ipq5332_ppe_acl_set(2, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 0, 0, 0, 1); + ipq5332_ppe_acl_set(2, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 0, 0, 0, + 1); } diff --git a/drivers/net/ipq5332/ipq5332_ppe.h b/drivers/net/ipq5332/ipq5332_ppe.h index cf54a94f6d..3ec5f344bf 100644 --- a/drivers/net/ipq5332/ipq5332_ppe.h +++ b/drivers/net/ipq5332/ipq5332_ppe.h @@ -115,9 +115,8 @@ union ipo_action_u { #define IPQ5332_PORT_MUX_CTRL_INC 0x4 #define IPQ5332_PORT_MUX_CTRL_DEFAULT 0x0 -#define PORT_PHY_STATUS_ADDRESS 0x44 -#define PORT_PHY_STATUS_PORT5_1_OFFSET 8 -#define PORT_PHY_STATUS_PORT6_OFFSET 16 +#define PORT_PHY_STATUS_ADDRESS 0x40 +#define PORT_PHY_STATUS_PORT2_OFFSET 8 #define IPQ5332_PPE_IPE_L3_BASE_ADDR 0x200000 #define IPQ5332_PPE_L3_VP_PORT_TBL_ADDR (IPQ5332_PPE_IPE_L3_BASE_ADDR + 0x4000) @@ -260,3 +259,7 @@ union ipo_action_u { #define IPO_ACTION_ADDRESS 0x8000 #define IPO_ACTION_INC 0x20 + +#define NSS_CC_PORT1_RX_CMD_RCGR 0x39B00450 +#define GCC_PORT1_ARES 1 << 2 +#define NSS_CC_PPE_BCR 0x39B003E4 diff --git a/drivers/net/ipq5332/ipq5332_uniphy.c b/drivers/net/ipq5332/ipq5332_uniphy.c index 8e1a5c4f68..50a882016c 100644 --- a/drivers/net/ipq5332/ipq5332_uniphy.c +++ b/drivers/net/ipq5332/ipq5332_uniphy.c @@ -72,8 +72,9 @@ static int ppe_uniphy_calibration(uint32_t uniphy_index) printf("uniphy callibration time out!\n"); return -1; } - reg_value = readl(PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) - + PPE_UNIPHY_OFFSET_CALIB_4); + reg_value = readl(PPE_UNIPHY_BASE + + (uniphy_index * PPE_UNIPHY_REG_INC) + + PPE_UNIPHY_OFFSET_CALIB_4); calibration_done = (reg_value >> 0x7) & 0x1; } @@ -82,70 +83,41 @@ static int ppe_uniphy_calibration(uint32_t uniphy_index) static void ppe_uniphy_reset(enum uniphy_reset_type rst_type, bool enable) { - uint32_t mode, node; - uint32_t reg_val, reg_val1; + uint32_t reg_val; switch(rst_type) { case UNIPHY0_SOFT_RESET: - node = fdt_path_offset(gd->fdt_blob, "/ess-switch"); - if (node < 0) { - printf("\nError: ess-switch not specified in dts"); - return; - } - mode = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode1", -1); - if (mode < 0) { - printf("\nError: switch_mac_mode1 not specified in dts"); - return; - } - reg_val = readl(GCC_UNIPHY0_MISC); - reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET); - if (mode == EPORT_WRAPPER_MAX) { - if (enable) { - reg_val |= 0x1; - reg_val1 |= 0xffc000; - } else { - reg_val &= ~0x1; - reg_val1 &= ~0xffc000; - } + reg_val = readl(GCC_UNIPHY0_SYS_CBCR); + if (enable) { + reg_val |= 0x4; } else { - if (enable) { - reg_val |= 0x1; - reg_val1 |= 0xff0000; - } else { - reg_val &= ~0x1; - reg_val1 &= ~0xff0000; - } + reg_val &= ~0x4; } - writel(reg_val, GCC_UNIPHY0_MISC); - writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET); + writel(reg_val, GCC_UNIPHY0_SYS_CBCR); break; case UNIPHY0_XPCS_RESET: reg_val = readl(GCC_UNIPHY0_MISC); if (enable) - reg_val |= 0x4; + reg_val |= 0x1; else - reg_val &= ~0x4; + reg_val &= ~0x1; writel(reg_val, GCC_UNIPHY0_MISC); break; case UNIPHY1_SOFT_RESET: - reg_val = readl(GCC_UNIPHY0_MISC + GCC_UNIPHY_REG_INC); - reg_val1 = readl(NSS_CC_UNIPHY_MISC_RESET); + reg_val = readl(GCC_UNIPHY1_SYS_CBCR); if (enable) { - reg_val |= 0x1; - reg_val1 |= 0xC000; + reg_val |= 0x4; } else { - reg_val &= ~0x1; - reg_val1 &= ~0xC000; + reg_val &= ~0x4; } - writel(reg_val, GCC_UNIPHY0_MISC + GCC_UNIPHY_REG_INC); - writel(reg_val1, NSS_CC_UNIPHY_MISC_RESET); + writel(reg_val, GCC_UNIPHY1_SYS_CBCR); break; case UNIPHY1_XPCS_RESET: reg_val = readl(GCC_UNIPHY0_MISC + GCC_UNIPHY_REG_INC); if (enable) - reg_val |= 0x4; + reg_val |= 0x1; else - reg_val &= ~0x4; + reg_val &= ~0x1; writel(reg_val, GCC_UNIPHY0_MISC + GCC_UNIPHY_REG_INC); break; default: @@ -218,22 +190,27 @@ static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t mode) { if ((uniphy_index == 1) && (mode == EPORT_WRAPPER_SGMII_PLUS)) { writel(UNIPHY_MISC_SRC_PHY_MODE, PPE_UNIPHY_BASE + - (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC_SOURCE_SELECTION_REG_OFFSET); + (uniphy_index * PPE_UNIPHY_REG_INC) + + UNIPHY_MISC_SOURCE_SELECTION_REG_OFFSET); ppe_uniphy_set_forceMode(uniphy_index); writel(UNIPHY_MISC2_REG_SGMII_PLUS_MODE, PPE_UNIPHY_BASE + - (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET); + (uniphy_index * PPE_UNIPHY_REG_INC) + + UNIPHY_MISC2_REG_OFFSET); } else { writel(UNIPHY_MISC2_REG_SGMII_MODE, PPE_UNIPHY_BASE + - (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET); + (uniphy_index * PPE_UNIPHY_REG_INC) + + UNIPHY_MISC2_REG_OFFSET); } writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE + - (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET); + (uniphy_index * PPE_UNIPHY_REG_INC) + + UNIPHY_PLL_RESET_REG_OFFSET); mdelay(500); writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE + - (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET); + (uniphy_index * PPE_UNIPHY_REG_INC) + + UNIPHY_PLL_RESET_REG_OFFSET); mdelay(500); if (uniphy_index == 0) ppe_uniphy_reset(UNIPHY0_XPCS_RESET, true); @@ -248,23 +225,27 @@ static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t mode) switch (mode) { case EPORT_WRAPPER_SGMII_FIBER: - writel(0x400, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) + writel(0x400, PPE_UNIPHY_BASE + + (uniphy_index * PPE_UNIPHY_REG_INC) + PPE_UNIPHY_MODE_CONTROL); break; case EPORT_WRAPPER_SGMII0_RGMII4: case EPORT_WRAPPER_SGMII1_RGMII4: case EPORT_WRAPPER_SGMII4_RGMII4: - writel(0x420, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) + writel(0x420, PPE_UNIPHY_BASE + + (uniphy_index * PPE_UNIPHY_REG_INC) + PPE_UNIPHY_MODE_CONTROL); break; case EPORT_WRAPPER_SGMII_PLUS: if (uniphy_index == 1) - writel(0x20, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) + writel(0x20, PPE_UNIPHY_BASE + + (uniphy_index * PPE_UNIPHY_REG_INC) + PPE_UNIPHY_MODE_CONTROL); else - writel(0x820, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) + writel(0x820, PPE_UNIPHY_BASE + + (uniphy_index * PPE_UNIPHY_REG_INC) + PPE_UNIPHY_MODE_CONTROL); break; @@ -347,10 +328,12 @@ static void ppe_uniphy_usxgmii_mode_set(uint32_t uniphy_index) writel(UNIPHY_MISC2_REG_VALUE, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET); writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE + - (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET); + (uniphy_index * PPE_UNIPHY_REG_INC) + + UNIPHY_PLL_RESET_REG_OFFSET); mdelay(500); writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE + - (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET); + (uniphy_index * PPE_UNIPHY_REG_INC) + + UNIPHY_PLL_RESET_REG_OFFSET); mdelay(500); if (uniphy_index == 0) diff --git a/drivers/net/ipq5332/ipq5332_uniphy.h b/drivers/net/ipq5332/ipq5332_uniphy.h index 8ab195c008..7f564f90d6 100644 --- a/drivers/net/ipq5332/ipq5332_uniphy.h +++ b/drivers/net/ipq5332/ipq5332_uniphy.h @@ -72,6 +72,8 @@ #define VR_MII_AN_INTR_STS 0x1f8002 #define CL37_ANCMPLT_INTR (1 << 0) +#define GCC_UNIPHY0_MISC 0x1816050 + enum uniphy_reset_type { UNIPHY0_SOFT_RESET = 0, UNIPHY0_XPCS_RESET,