Lines Matching full:fec

42  * 64-byte alignment in the DMA RX FEC buffer.
99 * programming the FEC's MII data register. in fec_mdio_read()
138 * HOLDTIME + 1 is the number of clk cycles the fec is holding the in fec_mii_setspeed()
201 struct fec_priv *fec = (struct fec_priv *)dev->priv; in miiphy_restart_aneg() local
202 struct ethernet_regs *eth = fec->bus->priv; in miiphy_restart_aneg()
209 fec_mdio_write(eth, fec->phy_id, MII_DCOUNTER, 0x00FF); in miiphy_restart_aneg()
211 fec_mdio_write(eth, fec->phy_id, MII_BMCR, BMCR_RESET); in miiphy_restart_aneg()
215 fec_mdio_write(eth, fec->phy_id, MII_ADVERTISE, in miiphy_restart_aneg()
218 fec_mdio_write(eth, fec->phy_id, MII_BMCR, in miiphy_restart_aneg()
221 if (fec->mii_postcall) in miiphy_restart_aneg()
222 ret = fec->mii_postcall(fec->phy_id); in miiphy_restart_aneg()
233 struct fec_priv *fec = (struct fec_priv *)dev->priv; in miiphy_wait_aneg() local
234 struct ethernet_regs *eth = fec->bus->priv; in miiphy_wait_aneg()
244 status = fec_mdio_read(eth, fec->phy_id, MII_BMSR); in miiphy_wait_aneg()
257 static int fec_rx_task_enable(struct fec_priv *fec) in fec_rx_task_enable() argument
259 writel(FEC_R_DES_ACTIVE_RDAR, &fec->eth->r_des_active); in fec_rx_task_enable()
263 static int fec_rx_task_disable(struct fec_priv *fec) in fec_rx_task_disable() argument
268 static int fec_tx_task_enable(struct fec_priv *fec) in fec_tx_task_enable() argument
270 writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active); in fec_tx_task_enable()
274 static int fec_tx_task_disable(struct fec_priv *fec) in fec_tx_task_disable() argument
281 * @param[in] fec all we know about the device yet
288 static void fec_rbd_init(struct fec_priv *fec, int count, int dsize) in fec_rbd_init() argument
300 data = (uint8_t *)fec->rbd_base[i].data_pointer; in fec_rbd_init()
304 fec->rbd_base[i].status = FEC_RBD_EMPTY; in fec_rbd_init()
305 fec->rbd_base[i].data_length = 0; in fec_rbd_init()
309 fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY; in fec_rbd_init()
310 fec->rbd_index = 0; in fec_rbd_init()
312 flush_dcache_range((unsigned)fec->rbd_base, in fec_rbd_init()
313 (unsigned)fec->rbd_base + size); in fec_rbd_init()
318 * @param[in] fec all we know about the device yet
328 static void fec_tbd_init(struct fec_priv *fec) in fec_tbd_init() argument
330 unsigned addr = (unsigned)fec->tbd_base; in fec_tbd_init()
334 memset(fec->tbd_base, 0, size); in fec_tbd_init()
335 fec->tbd_base[0].status = 0; in fec_tbd_init()
336 fec->tbd_base[1].status = FEC_TBD_WRAP; in fec_tbd_init()
337 fec->tbd_index = 0; in fec_tbd_init()
368 struct fec_priv *fec = dev_get_priv(dev); in fecmxc_set_hwaddr() local
373 struct fec_priv *fec = (struct fec_priv *)dev->priv; in fecmxc_set_hwaddr()
376 writel(0, &fec->eth->iaddr1); in fecmxc_set_hwaddr()
377 writel(0, &fec->eth->iaddr2); in fecmxc_set_hwaddr()
378 writel(0, &fec->eth->gaddr1); in fecmxc_set_hwaddr()
379 writel(0, &fec->eth->gaddr2); in fecmxc_set_hwaddr()
383 &fec->eth->paddr1); in fecmxc_set_hwaddr()
384 writel((mac[4] << 24) + (mac[5] << 16) + 0x8808, &fec->eth->paddr2); in fecmxc_set_hwaddr()
389 /* Do initial configuration of the FEC registers */
390 static void fec_reg_setup(struct fec_priv *fec) in fec_reg_setup() argument
395 writel(0x00000000, &fec->eth->imask); in fec_reg_setup()
397 /* Clear FEC-Lite interrupt event register(IEVENT) */ in fec_reg_setup()
398 writel(0xffffffff, &fec->eth->ievent); in fec_reg_setup()
400 /* Set FEC-Lite receive control register(R_CNTRL): */ in fec_reg_setup()
404 if (fec->xcv_type != SEVENWIRE) /* xMII modes */ in fec_reg_setup()
406 if (fec->xcv_type == RGMII) in fec_reg_setup()
408 else if (fec->xcv_type == RMII) in fec_reg_setup()
411 writel(rcntrl, &fec->eth->r_cntrl); in fec_reg_setup()
415 * Start the FEC engine
425 struct fec_priv *fec = dev_get_priv(dev); in fec_open() local
427 struct fec_priv *fec = (struct fec_priv *)edev->priv; in fec_open()
435 writel(1 << 2, &fec->eth->x_cntrl); in fec_open()
436 fec->rbd_index = 0; in fec_open()
440 fec_rbd_clean(0, &fec->rbd_base[i]); in fec_open()
441 fec_rbd_clean(1, &fec->rbd_base[i]); in fec_open()
446 addr = (uint32_t)fec->rbd_base; in fec_open()
451 writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP, in fec_open()
452 &fec->eth->ecntrl); in fec_open()
454 writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD, in fec_open()
455 &fec->eth->x_wmrk); in fec_open()
457 /* Enable FEC-Lite controller */ in fec_open()
458 writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN, in fec_open()
459 &fec->eth->ecntrl); in fec_open()
466 writew(0, &fec->eth->miigsk_enr); in fec_open()
469 while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) in fec_open()
473 writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr); in fec_open()
476 writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr); in fec_open()
480 while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) { in fec_open()
491 int ret = phy_startup(fec->phydev); in fec_open()
495 fec->phydev->dev->name); in fec_open()
498 speed = fec->phydev->speed; in fec_open()
504 speed = miiphy_speed(edev->name, fec->phy_id); in fec_open()
505 miiphy_duplex(edev->name, fec->phy_id); in fec_open()
510 u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED; in fec_open()
511 u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T; in fec_open()
516 writel(ecr, &fec->eth->ecntrl); in fec_open()
517 writel(rcr, &fec->eth->r_cntrl); in fec_open()
523 fec_rx_task_enable(fec); in fec_open()
536 struct fec_priv *fec = dev_get_priv(dev); in fecmxc_init() local
538 struct fec_priv *fec = (struct fec_priv *)dev->priv; in fecmxc_init()
540 uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop; in fecmxc_init()
551 fec_tbd_init(fec); in fecmxc_init()
554 fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE); in fecmxc_init()
556 fec_reg_setup(fec); in fecmxc_init()
558 if (fec->xcv_type != SEVENWIRE) in fecmxc_init()
559 fec_mii_setspeed(fec->bus->priv); in fecmxc_init()
562 writel(0x00010020, &fec->eth->op_pause); /* FIXME 0xffff0020; */ in fecmxc_init()
563 writel(0x2, &fec->eth->x_wmrk); in fecmxc_init()
566 writel(0x00000000, &fec->eth->gaddr1); in fecmxc_init()
567 writel(0x00000000, &fec->eth->gaddr2); in fecmxc_init()
576 writel(0x520, &fec->eth->r_fstart); in fecmxc_init()
580 writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr); in fecmxc_init()
581 writel((uint32_t)fec->tbd_base, &fec->eth->etdsr); in fecmxc_init()
582 writel((uint32_t)fec->rbd_base, &fec->eth->erdsr); in fecmxc_init()
585 if (fec->xcv_type != SEVENWIRE) in fecmxc_init()
593 * Halt the FEC engine
603 struct fec_priv *fec = dev_get_priv(dev); in fecmxc_halt() local
605 struct fec_priv *fec = (struct fec_priv *)dev->priv; in fecmxc_halt()
609 /* issue graceful stop command to the FEC transmitter if necessary */ in fecmxc_halt()
610 writel(FEC_TCNTRL_GTS | readl(&fec->eth->x_cntrl), in fecmxc_halt()
611 &fec->eth->x_cntrl); in fecmxc_halt()
615 while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA))) in fecmxc_halt()
619 fec_tx_task_disable(fec); in fecmxc_halt()
620 fec_rx_task_disable(fec); in fecmxc_halt()
626 writel(readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_ETHER_EN, in fecmxc_halt()
627 &fec->eth->ecntrl); in fecmxc_halt()
628 fec->rbd_index = 0; in fecmxc_halt()
629 fec->tbd_index = 0; in fecmxc_halt()
657 struct fec_priv *fec = dev_get_priv(dev); in fecmxc_send() local
659 struct fec_priv *fec = (struct fec_priv *)dev->priv; in fecmxc_send() local
684 writew(length, &fec->tbd_base[fec->tbd_index].data_length); in fecmxc_send()
685 writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer); in fecmxc_send()
695 status = readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_WRAP; in fecmxc_send()
697 writew(status, &fec->tbd_base[fec->tbd_index].status); in fecmxc_send()
705 addr = (uint32_t)fec->tbd_base; in fecmxc_send()
720 * 2) ARM core writes the FEC registers via AHB_ARB2 in fecmxc_send()
721 * 3) FEC DMA starts reading/writing from/to DRAM via AHB_ARB3 in fecmxc_send()
731 fec_tx_task_enable(fec); in fecmxc_send()
739 if (!(readl(&fec->eth->x_des_active) & FEC_X_DES_ACTIVE_TDAR)) in fecmxc_send()
755 * In mx6solox, we use a later version of FEC IP. It looks like that in fecmxc_send()
756 * this intrinsic behaviour of TDAR bit has changed in this newer FEC in fecmxc_send()
765 if (!(readw(&fec->tbd_base[fec->tbd_index].status) & in fecmxc_send()
775 readw(&fec->tbd_base[fec->tbd_index].status), in fecmxc_send()
776 fec->tbd_index, ret); in fecmxc_send()
778 if (fec->tbd_index) in fecmxc_send()
779 fec->tbd_index = 0; in fecmxc_send()
781 fec->tbd_index = 1; in fecmxc_send()
798 struct fec_priv *fec = dev_get_priv(dev); in fecmxc_recv() local
800 struct fec_priv *fec = (struct fec_priv *)dev->priv; in fecmxc_recv()
802 struct fec_bd *rbd = &fec->rbd_base[fec->rbd_index]; in fecmxc_recv()
811 ievent = readl(&fec->eth->ievent); in fecmxc_recv()
812 writel(ievent, &fec->eth->ievent); in fecmxc_recv()
820 fec_init(dev, fec->bd); in fecmxc_recv()
827 writel(0x00000001 | readl(&fec->eth->x_cntrl), in fecmxc_recv()
828 &fec->eth->x_cntrl); in fecmxc_recv()
832 if (readl(&fec->eth->x_cntrl) & 0x00000001) { in fecmxc_recv()
838 writel(~0x00000001 & readl(&fec->eth->x_cntrl), in fecmxc_recv()
839 &fec->eth->x_cntrl); in fecmxc_recv()
843 fec_init(dev, fec->bd); in fecmxc_recv()
900 if ((fec->rbd_index & size) == size) { in fecmxc_recv()
901 i = fec->rbd_index - size; in fecmxc_recv()
902 addr = (uint32_t)&fec->rbd_base[i]; in fecmxc_recv()
903 for (; i <= fec->rbd_index ; i++) { in fecmxc_recv()
905 &fec->rbd_base[i]); in fecmxc_recv()
911 fec_rx_task_enable(fec); in fecmxc_recv()
912 fec->rbd_index = (fec->rbd_index + 1) % FEC_RBD_NUM; in fecmxc_recv()
921 sprintf(dest, (dev_id == -1) ? "FEC" : "FEC%i", dev_id); in fec_set_dev_name()
924 static int fec_alloc_descs(struct fec_priv *fec) in fec_alloc_descs() argument
932 fec->tbd_base = memalign(ARCH_DMA_MINALIGN, size); in fec_alloc_descs()
933 if (!fec->tbd_base) in fec_alloc_descs()
938 fec->rbd_base = memalign(ARCH_DMA_MINALIGN, size); in fec_alloc_descs()
939 if (!fec->rbd_base) in fec_alloc_descs()
942 memset(fec->rbd_base, 0, size); in fec_alloc_descs()
957 fec->rbd_base[i].data_pointer = (uint32_t)data; in fec_alloc_descs()
958 fec->rbd_base[i].status = FEC_RBD_EMPTY; in fec_alloc_descs()
959 fec->rbd_base[i].data_length = 0; in fec_alloc_descs()
965 fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY; in fec_alloc_descs()
967 fec->rbd_index = 0; in fec_alloc_descs()
968 fec->tbd_index = 0; in fec_alloc_descs()
974 free((void *)fec->rbd_base[i].data_pointer); in fec_alloc_descs()
975 free(fec->rbd_base); in fec_alloc_descs()
977 free(fec->tbd_base); in fec_alloc_descs()
982 static void fec_free_descs(struct fec_priv *fec) in fec_free_descs() argument
987 free((void *)fec->rbd_base[i].data_pointer); in fec_free_descs()
988 free(fec->rbd_base); in fec_free_descs()
989 free(fec->tbd_base); in fec_free_descs()
1037 struct fec_priv *fec; in fec_probe() local
1051 fec = (struct fec_priv *)malloc(sizeof(struct fec_priv)); in fec_probe()
1052 if (!fec) { in fec_probe()
1059 memset(fec, 0, sizeof(*fec)); in fec_probe()
1061 ret = fec_alloc_descs(fec); in fec_probe()
1065 edev->priv = fec; in fec_probe()
1072 fec->eth = (struct ethernet_regs *)base_addr; in fec_probe()
1073 fec->bd = bd; in fec_probe()
1075 fec->xcv_type = CONFIG_FEC_XCV_TYPE; in fec_probe()
1078 writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl); in fec_probe()
1080 while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) { in fec_probe()
1082 printf("FEC MXC: Timeout resetting chip\n"); in fec_probe()
1088 fec_reg_setup(fec); in fec_probe()
1090 fec->dev_id = (dev_id == -1) ? 0 : dev_id; in fec_probe()
1091 fec->bus = bus; in fec_probe()
1094 fec->phydev = phydev; in fec_probe()
1099 fec->phy_id = phy_id; in fec_probe()
1103 edev->index = fec->dev_id; in fec_probe()
1105 if (fec_get_hwaddr(fec->dev_id, ethaddr) == 0) { in fec_probe()
1106 debug("got MAC%d address from fuse: %pM\n", fec->dev_id, ethaddr); in fec_probe()
1108 if (fec->dev_id) in fec_probe()
1109 sprintf(mac, "eth%daddr", fec->dev_id); in fec_probe()
1117 fec_free_descs(fec); in fec_probe()
1119 free(fec); in fec_probe()
1180 struct fec_priv *fec = (struct fec_priv *)dev->priv; in fecmxc_register_mii_postcall() local
1181 fec->mii_postcall = cb; in fecmxc_register_mii_postcall()
1245 printf("FEC MXC: Timeout reseting chip\n"); in fecmxc_probe()
1334 { .compatible = "fsl,imx6q-fec" },