void e40::internal_loopback(uint32_t instance) { gen_ctrl_ = 0; mon_ctrl_ = 0; auto mac0 = read_mac_address(0); auto mac_ctrl = instance == 0 ? mac_reg::mac0_ctrl : mac_reg::mac1_ctrl; if (packet_count_ > 0) { eth_->write(eth_ctrl_reg::gen_pkt_number, instance, packet_count_); eth_->write(eth_ctrl_reg::mon_pkt_number, instance, packet_count_); } else { mon_ctrl_ |= static_cast<uint32_t>(gen_ctrl::continuous); gen_ctrl_ |= static_cast<uint32_t>(gen_ctrl::continuous); } mac_write(mac_ctrl, mac_reg::mac_srl_lpbk_ctrl, 0x3FF); mac_write(mac_ctrl, mac_reg::mac_cntr_tx_ctrl, 1); mac_write(mac_ctrl, mac_reg::mac_cntr_rx_ctrl, 1); eth_->write(eth_ctrl_reg::gen_src_addr_l, instance, mac0.lo); eth_->write(eth_ctrl_reg::gen_src_addr_h, instance, mac0.hi); eth_->write(eth_ctrl_reg::mon_src_addr_l, instance, mac0.lo); eth_->write(eth_ctrl_reg::mon_src_addr_h, instance, mac0.hi); eth_->write(eth_ctrl_reg::gen_dst_addr_l, instance, mac0.lo); eth_->write(eth_ctrl_reg::gen_dst_addr_h, instance, mac0.hi); eth_->write(eth_ctrl_reg::mon_dst_addr_l, instance, mac0.lo); eth_->write(eth_ctrl_reg::mon_dst_addr_h, instance, mac0.hi); eth_->write(eth_ctrl_reg::mon_pkt_ctrl, instance, mon_ctrl_ | static_cast<uint32_t>(mon_ctrl::start)); eth_->write(eth_ctrl_reg::gen_pkt_ctrl, instance, gen_ctrl_ | static_cast<uint32_t>(gen_ctrl::start)); }
std::vector<mac_address_t> e40::get_mac_addresses() { int begin = 0, end = 4; std::vector<mac_address_t> addresses; for (int i = begin; i < end; ++i) { mac_address_t mac = read_mac_address(i); addresses.push_back(mac); } return addresses; }
static int sh_eth_drv_probe(struct platform_device *pdev) { int ret, i, devno = 0; struct resource *res; struct net_device *ndev = NULL; struct sh_eth_private *mdp; struct sh_eth_plat_data *pd; /* get base addr */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(res == NULL)) { dev_err(&pdev->dev, "invalid resource\n"); ret = -EINVAL; goto out; } ndev = alloc_etherdev(sizeof(struct sh_eth_private)); if (!ndev) { printk(KERN_ERR "%s: could not allocate device.\n", CARDNAME); ret = -ENOMEM; goto out; } /* The sh Ether-specific entries in the device structure. */ ndev->base_addr = res->start; devno = pdev->id; if (devno < 0) devno = 0; ndev->dma = -1; ret = platform_get_irq(pdev, 0); if (ret < 0) { ret = -ENODEV; goto out_release; } ndev->irq = ret; SET_NETDEV_DEV(ndev, &pdev->dev); /* Fill in the fields of the device structure with ethernet values. */ ether_setup(ndev); mdp = netdev_priv(ndev); spin_lock_init(&mdp->lock); pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data); /* get PHY ID */ mdp->phy_id = pd->phy; /* EDMAC endian */ mdp->edmac_endian = pd->edmac_endian; /* set function */ ndev->netdev_ops = &sh_eth_netdev_ops; ndev->watchdog_timeo = TX_TIMEOUT; mdp->post_rx = POST_RX >> (devno << 1); mdp->post_fw = POST_FW >> (devno << 1); /* read and set MAC address */ read_mac_address(ndev); /* First device only init */ if (!devno) { #if defined(ARSTR) /* reset device */ ctrl_outl(ARSTR_ARSTR, ARSTR); mdelay(1); #endif #if defined(SH_TSU_ADDR) /* TSU init (Init only)*/ sh_eth_tsu_init(SH_TSU_ADDR); #endif } /* network device register */ ret = register_netdev(ndev); if (ret) goto out_release; /* mdio bus init */ ret = sh_mdio_init(ndev, pdev->id); if (ret) goto out_unregister; /* pritnt device infomation */ printk(KERN_INFO "%s: %s at 0x%x, ", ndev->name, CARDNAME, (u32) ndev->base_addr); for (i = 0; i < 5; i++) printk("%02X:", ndev->dev_addr[i]); printk("%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq); platform_set_drvdata(pdev, ndev); return ret; out_unregister: unregister_netdev(ndev); out_release: /* net_dev free */ if (ndev) free_netdev(ndev); out: return ret; }
void e40::external_loopback(uint32_t source_port, uint32_t destination_port) { auto mac0 = read_mac_address(source_port); auto mac1 = read_mac_address(destination_port); gen_ctrl_ = 0; mon_ctrl_ = 0; if (random_length_) { gen_ctrl_ |= static_cast<uint32_t>(gen_ctrl::random_packet_length); } if (continuous_) { gen_ctrl_ |= static_cast<uint32_t>(gen_ctrl::continuous); mon_ctrl_ |= static_cast<uint32_t>(mon_ctrl::continuous); } else { if (packet_count_ > 0) { eth_->write(eth_ctrl_reg::gen_pkt_number, source_port, packet_count_); eth_->write(eth_ctrl_reg::mon_pkt_number, destination_port, packet_count_); } } if (packet_length_ > 0) eth_->write(eth_ctrl_reg::gen_pkt_length, source_port, packet_length_); if (packet_delay_ > 0) eth_->write(eth_ctrl_reg::gen_pkt_delay, source_port, packet_delay_); // turn off serial loopback mac_write(mac_reg::mac0_ctrl, mac_reg::mac_srl_lpbk_ctrl, 0x0); mac_write(mac_reg::mac1_ctrl, mac_reg::mac_srl_lpbk_ctrl, 0x0); // PORT 0 GEN SRC -> MAC0 eth_->write(eth_ctrl_reg::gen_src_addr_l, source_port, mac0.lo); eth_->write(eth_ctrl_reg::gen_src_addr_h, source_port, mac0.hi); // PORT 0 GEN DST -> MAC1 eth_->write(eth_ctrl_reg::gen_dst_addr_l, source_port, mac1.lo); eth_->write(eth_ctrl_reg::gen_dst_addr_h, source_port, mac1.hi); // PORT 0 MON SRC -> MAC1 eth_->write(eth_ctrl_reg::mon_src_addr_l, source_port, mac1.lo); eth_->write(eth_ctrl_reg::mon_src_addr_h, source_port, mac1.hi); // PORT 0 MON DST -> MAC0 eth_->write(eth_ctrl_reg::mon_dst_addr_l, source_port, mac0.lo); eth_->write(eth_ctrl_reg::mon_dst_addr_h, source_port, mac0.hi); // PORT 1 GEN SRC -> MAC1 eth_->write(eth_ctrl_reg::gen_src_addr_l, destination_port, mac1.lo); eth_->write(eth_ctrl_reg::gen_src_addr_h, destination_port, mac1.hi); // PORT 1 GEN SRC -> MAC0 eth_->write(eth_ctrl_reg::gen_dst_addr_l, destination_port, mac0.lo); eth_->write(eth_ctrl_reg::gen_dst_addr_h, destination_port, mac0.hi); // PORT 1 MON SRC -> MAC0 eth_->write(eth_ctrl_reg::mon_src_addr_l, destination_port, mac0.lo); eth_->write(eth_ctrl_reg::mon_src_addr_h, destination_port, mac0.hi); // PORT 1 MON DST -> MAC1 eth_->write(eth_ctrl_reg::mon_dst_addr_l, destination_port, mac1.lo); eth_->write(eth_ctrl_reg::mon_dst_addr_h, destination_port, mac1.hi); eth_->write(eth_ctrl_reg::mon_pkt_ctrl, destination_port, mon_ctrl_ | static_cast<uint32_t>(mon_ctrl::start)); eth_->write(eth_ctrl_reg::gen_pkt_ctrl, source_port, gen_ctrl_ | static_cast<uint32_t>(gen_ctrl::start)); }
static int sh_eth_drv_probe(struct platform_device *pdev) { int ret, devno = 0; struct resource *res; struct net_device *ndev = NULL; struct sh_eth_private *mdp; struct sh_eth_plat_data *pd; /* get base addr */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(res == NULL)) { dev_err(&pdev->dev, "invalid resource\n"); ret = -EINVAL; goto out; } ndev = alloc_etherdev(sizeof(struct sh_eth_private)); if (!ndev) { dev_err(&pdev->dev, "Could not allocate device.\n"); ret = -ENOMEM; goto out; } /* The sh Ether-specific entries in the device structure. */ ndev->base_addr = res->start; devno = pdev->id; if (devno < 0) devno = 0; ndev->dma = -1; ret = platform_get_irq(pdev, 0); if (ret < 0) { ret = -ENODEV; goto out_release; } ndev->irq = ret; SET_NETDEV_DEV(ndev, &pdev->dev); /* Fill in the fields of the device structure with ethernet values. */ ether_setup(ndev); mdp = netdev_priv(ndev); spin_lock_init(&mdp->lock); mdp->pdev = pdev; pm_runtime_enable(&pdev->dev); pm_runtime_resume(&pdev->dev); pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data); /* get PHY ID */ mdp->phy_id = pd->phy; mdp->phy_interface = pd->phy_interface; /* EDMAC endian */ mdp->edmac_endian = pd->edmac_endian; mdp->no_ether_link = pd->no_ether_link; mdp->ether_link_active_low = pd->ether_link_active_low; mdp->reg_offset = sh_eth_get_register_offset(pd->register_type); /* set cpu data */ #if defined(SH_ETH_HAS_BOTH_MODULES) mdp->cd = sh_eth_get_cpu_data(mdp); #else mdp->cd = &sh_eth_my_cpu_data; #endif sh_eth_set_default_cpu_data(mdp->cd); /* set function */ ndev->netdev_ops = &sh_eth_netdev_ops; SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops); ndev->watchdog_timeo = TX_TIMEOUT; /* debug message level */ mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE; mdp->post_rx = POST_RX >> (devno << 1); mdp->post_fw = POST_FW >> (devno << 1); /* read and set MAC address */ read_mac_address(ndev, pd->mac_addr); /* First device only init */ if (!devno) { if (mdp->cd->tsu) { struct resource *rtsu; rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!rtsu) { dev_err(&pdev->dev, "Not found TSU resource\n"); goto out_release; } mdp->tsu_addr = ioremap(rtsu->start, resource_size(rtsu)); } if (mdp->cd->chip_reset) mdp->cd->chip_reset(ndev); if (mdp->cd->tsu) { /* TSU init (Init only)*/ sh_eth_tsu_init(mdp); } } /* network device register */ ret = register_netdev(ndev); if (ret) goto out_release; /* mdio bus init */ ret = sh_mdio_init(ndev, pdev->id, pd); if (ret) goto out_unregister; /* print device information */ pr_info("Base address at 0x%x, %pM, IRQ %d.\n", (u32)ndev->base_addr, ndev->dev_addr, ndev->irq); platform_set_drvdata(pdev, ndev); return ret; out_unregister: unregister_netdev(ndev); out_release: /* net_dev free */ if (mdp->tsu_addr) iounmap(mdp->tsu_addr); if (ndev) free_netdev(ndev); out: return ret; }