Lines Matching +full:smi +full:- +full:based
1 // SPDX-License-Identifier: GPL-2.0+
5 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
10 * based on - Driver for MV64360X ethernet ports
42 #define MVGBE_SMI_REG (((struct mvgbe_registers *)MVGBE0_BASE)->smi)
52 printf("Error: SMI busy timeout\n"); in smi_wait_ready()
62 struct mvgbe_registers *regs = dmvgbe->regs; in __mvgbe_mdio_read()
71 data = (u16) (MVGBE_REG_RD(regs->phyadr) & PHYADR_MASK); in __mvgbe_mdio_read()
78 return -EFAULT; in __mvgbe_mdio_read()
83 return -EFAULT; in __mvgbe_mdio_read()
86 /* wait till the SMI is not busy */ in __mvgbe_mdio_read()
88 return -EFAULT; in __mvgbe_mdio_read()
95 /* write the smi register */ in __mvgbe_mdio_read()
102 /* read smi register */ in __mvgbe_mdio_read()
104 if (timeout-- == 0) { in __mvgbe_mdio_read()
105 printf("Err..(%s) SMI read ready timeout\n", in __mvgbe_mdio_read()
107 return -EFAULT; in __mvgbe_mdio_read()
111 /* Wait for the data to update in the SMI register */ in __mvgbe_mdio_read()
124 * smi_reg_read - miiphy_read callback function.
126 * Returns 16bit phy register value, or -EFAULT on error
132 struct mvgbe_device *dmvgbe = bus->priv; in smi_reg_read()
134 struct eth_device *dev = eth_get_dev_by_name(bus->name); in smi_reg_read()
144 struct mvgbe_registers *regs = dmvgbe->regs; in __mvgbe_mdio_write()
150 MVGBE_REG_WR(regs->phyadr, data); in __mvgbe_mdio_write()
157 return -EINVAL; in __mvgbe_mdio_write()
161 return -EFAULT; in __mvgbe_mdio_write()
164 /* wait till the SMI is not busy */ in __mvgbe_mdio_write()
166 return -EFAULT; in __mvgbe_mdio_write()
174 /* write the smi register */ in __mvgbe_mdio_write()
181 * smi_reg_write - miiphy_write callback function.
183 * Returns 0 if write succeed, -EFAULT on error
189 struct mvgbe_device *dmvgbe = bus->priv; in smi_reg_write()
191 struct eth_device *dev = eth_get_dev_by_name(bus->name); in smi_reg_write()
223 * set_access_control - Config address decode parameters for Ethernet unit
237 access_prot_reg = MVGBE_REG_RD(regs->epap); in set_access_control()
239 access_prot_reg &= (~(3 << (param->win * 2))); in set_access_control()
240 access_prot_reg |= (param->access_ctrl << (param->win * 2)); in set_access_control()
241 MVGBE_REG_WR(regs->epap, access_prot_reg); in set_access_control()
244 MVGBE_REG_WR(regs->barsz[param->win].size, in set_access_control()
245 (((param->size / 0x10000) - 1) << 16)); in set_access_control()
248 MVGBE_REG_WR(regs->barsz[param->win].bar, in set_access_control()
249 (param->target | param->attrib | param->base_addr)); in set_access_control()
251 if (param->win < 4) in set_access_control()
252 MVGBE_REG_WR(regs->ha_remap[param->win], param->high_addr); in set_access_control()
255 if (param->enable == 1) in set_access_control()
256 MVGBE_REG_BITS_RESET(regs->bare, (1 << param->win)); in set_access_control()
258 MVGBE_REG_BITS_SET(regs->bare, (1 << param->win)); in set_access_control()
269 /* Window target - DDR */ in set_dram_access()
275 win_param.base_addr = gd->bd->bi_dram[i].start; in set_dram_access()
276 win_param.size = gd->bd->bi_dram[i].size; in set_dram_access()
308 * port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
319 MVGBE_REG_WR(regs->dfut[table_index], 0); in port_init_mac_tables()
323 MVGBE_REG_WR(regs->dfsmt[table_index], 0); in port_init_mac_tables()
325 MVGBE_REG_WR(regs->dfomt[table_index], 0); in port_init_mac_tables()
330 * port_uc_addr - This function Set the port unicast address table
363 unicast_reg = MVGBE_REG_RD(regs->dfut[tbl_offset]); in port_uc_addr()
365 MVGBE_REG_WR(regs->dfut[tbl_offset], unicast_reg); in port_uc_addr()
369 unicast_reg = MVGBE_REG_RD(regs->dfut[tbl_offset]); in port_uc_addr()
372 MVGBE_REG_WR(regs->dfut[tbl_offset], unicast_reg); in port_uc_addr()
381 * port_uc_addr_set - This function Set the port Unicast address.
385 struct mvgbe_registers *regs = dmvgbe->regs; in port_uc_addr_set()
393 MVGBE_REG_WR(regs->macal, mac_l); in port_uc_addr_set()
394 MVGBE_REG_WR(regs->macah, mac_h); in port_uc_addr_set()
401 * mvgbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
409 p_rx_desc = dmvgbe->p_rxdesc; in mvgbe_init_rx_desc_ring()
411 p_rx_desc->cmd_sts = in mvgbe_init_rx_desc_ring()
413 p_rx_desc->buf_size = PKTSIZE_ALIGN; in mvgbe_init_rx_desc_ring()
414 p_rx_desc->byte_cnt = 0; in mvgbe_init_rx_desc_ring()
415 p_rx_desc->buf_ptr = dmvgbe->p_rxbuf + i * PKTSIZE_ALIGN; in mvgbe_init_rx_desc_ring()
416 if (i == (RINGSZ - 1)) in mvgbe_init_rx_desc_ring()
417 p_rx_desc->nxtdesc_p = dmvgbe->p_rxdesc; in mvgbe_init_rx_desc_ring()
419 p_rx_desc->nxtdesc_p = (struct mvgbe_rxdesc *) in mvgbe_init_rx_desc_ring()
421 p_rx_desc = p_rx_desc->nxtdesc_p; in mvgbe_init_rx_desc_ring()
424 dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc; in mvgbe_init_rx_desc_ring()
430 struct mvgbe_registers *regs = dmvgbe->regs; in __mvgbe_init()
441 MVGBE_REG_WR(regs->ic, 0); in __mvgbe_init()
442 MVGBE_REG_WR(regs->ice, 0); in __mvgbe_init()
444 MVGBE_REG_WR(regs->pim, INT_CAUSE_UNMASK_ALL); in __mvgbe_init()
446 MVGBE_REG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT); in __mvgbe_init()
453 MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL); in __mvgbe_init()
454 MVGBE_REG_WR(regs->pxcx, PORT_CFG_EXTEND_VALUE); in __mvgbe_init()
455 MVGBE_REG_WR(regs->psc0, PORT_SERIAL_CONTROL_VALUE); in __mvgbe_init()
458 MVGBE_REG_WR(regs->sdc, PORT_SDMA_CFG_VALUE); in __mvgbe_init()
459 MVGBE_REG_WR(regs->tqx[0].qxttbc, QTKNBKT_DEF_VAL); in __mvgbe_init()
460 MVGBE_REG_WR(regs->tqx[0].tqxtbc, in __mvgbe_init()
463 MVGBE_REG_WR(regs->pmtu, 0); in __mvgbe_init()
466 MVGBE_REG_WR(regs->psc0, MVGBE_MAX_RX_PACKET_9700BYTE in __mvgbe_init()
467 | (MVGBE_REG_RD(regs->psc0) & MRU_MASK)); in __mvgbe_init()
470 MVGBE_REG_BITS_SET(regs->psc0, MVGBE_SERIAL_PORT_EN); in __mvgbe_init()
473 * Set ethernet MTU for leaky bucket mechanism to 0 - this will in __mvgbe_init()
476 MVGBE_REG_WR(regs->pmtu, 0); in __mvgbe_init()
479 MVGBE_REG_WR(regs->rxcdp[RXUQ], (u32) dmvgbe->p_rxdesc_curr); in __mvgbe_init()
483 MVGBE_REG_WR(regs->rqc, (1 << RXUQ)); in __mvgbe_init()
502 return -1; in __mvgbe_init()
512 return __mvgbe_init(dmvgbe, dmvgbe->dev.enetaddr, dmvgbe->dev.name); in mvgbe_init()
518 struct mvgbe_registers *regs = dmvgbe->regs; in __mvgbe_halt()
521 MVGBE_REG_WR(regs->bare, 0x3f); in __mvgbe_halt()
523 stop_queue(®s->tqc); in __mvgbe_halt()
524 stop_queue(®s->rqc); in __mvgbe_halt()
527 MVGBE_REG_BITS_RESET(regs->psc0, MVGBE_SERIAL_PORT_EN); in __mvgbe_halt()
529 MVGBE_REG_BITS_RESET(regs->psc1, 1 << 4); in __mvgbe_halt()
532 MVGBE_REG_BITS_RESET(regs->psc1, 1 << 3); in __mvgbe_halt()
535 MVGBE_REG_WR(regs->ic, 0); in __mvgbe_halt()
536 MVGBE_REG_WR(regs->ice, 0); in __mvgbe_halt()
537 MVGBE_REG_WR(regs->pim, 0); in __mvgbe_halt()
538 MVGBE_REG_WR(regs->peim, 0); in __mvgbe_halt()
557 port_uc_addr_set(dev_get_priv(dev), pdata->enetaddr); in mvgbe_write_hwaddr()
567 port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr); in mvgbe_write_hwaddr()
575 struct mvgbe_registers *regs = dmvgbe->regs; in __mvgbe_send()
576 struct mvgbe_txdesc *p_txdesc = dmvgbe->p_txdesc; in __mvgbe_send()
584 printf("Non-aligned data too large (%d)\n", in __mvgbe_send()
586 return -1; in __mvgbe_send()
589 memcpy(dmvgbe->p_aligned_txbuf, p, datasize); in __mvgbe_send()
590 p = dmvgbe->p_aligned_txbuf; in __mvgbe_send()
593 p_txdesc->cmd_sts = MVGBE_ZERO_PADDING | MVGBE_GEN_CRC; in __mvgbe_send()
594 p_txdesc->cmd_sts |= MVGBE_TX_FIRST_DESC | MVGBE_TX_LAST_DESC; in __mvgbe_send()
595 p_txdesc->cmd_sts |= MVGBE_BUFFER_OWNED_BY_DMA; in __mvgbe_send()
596 p_txdesc->cmd_sts |= MVGBE_TX_EN_INTERRUPT; in __mvgbe_send()
597 p_txdesc->buf_ptr = (u8 *) p; in __mvgbe_send()
598 p_txdesc->byte_cnt = datasize; in __mvgbe_send()
601 txuq0_reg_addr = (u32)®s->tcqdp[TXUQ]; in __mvgbe_send()
608 MVGBE_REG_WR(regs->tqc, (1 << TXUQ)); in __mvgbe_send()
613 cmd_sts = readl(&p_txdesc->cmd_sts); in __mvgbe_send()
620 return -1; in __mvgbe_send()
622 cmd_sts = readl(&p_txdesc->cmd_sts); in __mvgbe_send()
638 struct mvgbe_rxdesc *p_rxdesc_curr = dmvgbe->p_rxdesc_curr; in __mvgbe_recv()
653 return -1; in __mvgbe_recv()
655 } while (readl(&p_rxdesc_curr->cmd_sts) & MVGBE_BUFFER_OWNED_BY_DMA); in __mvgbe_recv()
657 if (p_rxdesc_curr->byte_cnt != 0) { in __mvgbe_recv()
659 __func__, (u32) p_rxdesc_curr->byte_cnt, in __mvgbe_recv()
660 (u32) p_rxdesc_curr->buf_ptr, in __mvgbe_recv()
661 (u32) p_rxdesc_curr->cmd_sts); in __mvgbe_recv()
669 cmd_sts = readl(&p_rxdesc_curr->cmd_sts); in __mvgbe_recv()
689 data = (p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET); in __mvgbe_recv()
690 rx_bytes = (int)(p_rxdesc_curr->byte_cnt - in __mvgbe_recv()
698 p_rxdesc_curr->cmd_sts = in __mvgbe_recv()
700 p_rxdesc_curr->buf_size = PKTSIZE_ALIGN; in __mvgbe_recv()
701 p_rxdesc_curr->byte_cnt = 0; in __mvgbe_recv()
703 rxdesc_curr_addr = (u32)&dmvgbe->p_rxdesc_curr; in __mvgbe_recv()
704 writel((unsigned)p_rxdesc_curr->nxtdesc_p, rxdesc_curr_addr); in __mvgbe_recv()
742 miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST, in __mvgbe_phy_init()
768 return -ENOMEM; in mvgbe_phylib_init()
770 bus->read = smi_reg_read; in mvgbe_phylib_init()
771 bus->write = smi_reg_write; in mvgbe_phylib_init()
772 strcpy(bus->name, dev->name); in mvgbe_phylib_init()
778 return -ENOMEM; in mvgbe_phylib_init()
783 return -ENODEV; in mvgbe_phylib_init()
791 dmvgbe->p_rxdesc = memalign(PKTALIGN, in mvgbe_alloc_buffers()
793 if (!dmvgbe->p_rxdesc) in mvgbe_alloc_buffers()
796 dmvgbe->p_rxbuf = memalign(PKTALIGN, in mvgbe_alloc_buffers()
798 if (!dmvgbe->p_rxbuf) in mvgbe_alloc_buffers()
801 dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN); in mvgbe_alloc_buffers()
802 if (!dmvgbe->p_aligned_txbuf) in mvgbe_alloc_buffers()
805 dmvgbe->p_txdesc = memalign(PKTALIGN, sizeof(struct mvgbe_txdesc) + 1); in mvgbe_alloc_buffers()
806 if (!dmvgbe->p_txdesc) in mvgbe_alloc_buffers()
812 free(dmvgbe->p_aligned_txbuf); in mvgbe_alloc_buffers()
814 free(dmvgbe->p_rxbuf); in mvgbe_alloc_buffers()
816 free(dmvgbe->p_rxdesc); in mvgbe_alloc_buffers()
818 return -ENOMEM; in mvgbe_alloc_buffers()
837 return -ENOMEM; in mvgbe_initialize()
848 dev = &dmvgbe->dev; in mvgbe_initialize()
850 /* must be less than sizeof(dev->name) */ in mvgbe_initialize()
851 sprintf(dev->name, "egiga%d", devnum); in mvgbe_initialize()
855 dmvgbe->regs = (void *)MVGBE0_BASE; in mvgbe_initialize()
859 dmvgbe->regs = (void *)MVGBE1_BASE; in mvgbe_initialize()
865 return -1; in mvgbe_initialize()
868 dev->init = (void *)mvgbe_init; in mvgbe_initialize()
869 dev->halt = (void *)mvgbe_halt; in mvgbe_initialize()
870 dev->send = (void *)mvgbe_send; in mvgbe_initialize()
871 dev->recv = (void *)mvgbe_recv; in mvgbe_initialize()
872 dev->write_hwaddr = (void *)mvgbe_write_hwaddr; in mvgbe_initialize()
882 return -ENOMEM; in mvgbe_initialize()
883 strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); in mvgbe_initialize()
884 mdiodev->read = smi_reg_read; in mvgbe_initialize()
885 mdiodev->write = smi_reg_write; in mvgbe_initialize()
891 miiphy_write(dev->name, MV_PHY_ADR_REQUEST, in mvgbe_initialize()
902 return dmvgbe->phyaddr > PHY_MAX_ADDR; in mvgbe_port_is_fixed_link()
911 ret = __mvgbe_init(dmvgbe, pdata->enetaddr, dev->name); in mvgbe_start()
916 dmvgbe->phydev = __mvgbe_phy_init(dev, dmvgbe->bus, in mvgbe_start()
917 dmvgbe->phy_interface, in mvgbe_start()
918 dmvgbe->phyaddr); in mvgbe_start()
919 if (!dmvgbe->phydev) in mvgbe_start()
920 return -ENODEV; in mvgbe_start()
958 dmvgbe->regs = (void __iomem *)pdata->iobase; in mvgbe_probe()
963 return -ENOMEM; in mvgbe_probe()
966 bus->read = smi_reg_read; in mvgbe_probe()
967 bus->write = smi_reg_write; in mvgbe_probe()
968 snprintf(bus->name, sizeof(bus->name), dev->name); in mvgbe_probe()
969 bus->priv = dmvgbe; in mvgbe_probe()
970 dmvgbe->bus = bus; in mvgbe_probe()
991 void *blob = (void *)gd->fdt_blob; in mvgbe_ofdata_to_platdata()
998 pdata->iobase = devfdt_get_addr(dev); in mvgbe_ofdata_to_platdata()
999 pdata->phy_interface = -1; in mvgbe_ofdata_to_platdata()
1002 "marvell,kirkwood-eth-port"); in mvgbe_ofdata_to_platdata()
1004 /* Get phy-mode / phy_interface from DT */ in mvgbe_ofdata_to_platdata()
1005 phy_mode = fdt_getprop(gd->fdt_blob, pnode, "phy-mode", NULL); in mvgbe_ofdata_to_platdata()
1007 pdata->phy_interface = phy_get_interface_by_name(phy_mode); in mvgbe_ofdata_to_platdata()
1009 pdata->phy_interface = PHY_INTERFACE_MODE_GMII; in mvgbe_ofdata_to_platdata()
1011 dmvgbe->phy_interface = pdata->phy_interface; in mvgbe_ofdata_to_platdata()
1013 /* fetch 'fixed-link' property */ in mvgbe_ofdata_to_platdata()
1014 fl_node = fdt_subnode_offset(blob, pnode, "fixed-link"); in mvgbe_ofdata_to_platdata()
1015 if (fl_node != -FDT_ERR_NOTFOUND) { in mvgbe_ofdata_to_platdata()
1017 dmvgbe->phyaddr = PHY_MAX_ADDR + 1; in mvgbe_ofdata_to_platdata()
1018 dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex"); in mvgbe_ofdata_to_platdata()
1019 dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0); in mvgbe_ofdata_to_platdata()
1022 addr = fdtdec_lookup_phandle(blob, pnode, "phy-handle"); in mvgbe_ofdata_to_platdata()
1024 dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0); in mvgbe_ofdata_to_platdata()
1031 { .compatible = "marvell,kirkwood-eth" },