Loading drivers/net/ethernet/msm/emac/emac_hw.c +4 −2 Original line number Diff line number Diff line Loading @@ -646,7 +646,9 @@ void emac_hw_disable_intr(struct emac_hw *hw) emac_reg_w32(hw, EMAC, irq_info->mask_reg, 0); } emac_reg_w32(hw, EMAC_1588, EMAC_P1588_PTP_EXPANDED_INT_MASK, 0); if (adpt->tstamp_en) emac_reg_w32(hw, EMAC_1588, EMAC_P1588_PTP_EXPANDED_INT_MASK, 0); if (adpt->phy_mode == PHY_INTERFACE_MODE_SGMII) { irq_info = &adpt->irq_info[EMAC_SGMII_PHY_IRQ]; Loading Loading @@ -1195,7 +1197,7 @@ void emac_hw_start_mac(struct emac_hw *hw) (INT_RD_CLR_EN | LPW_MODE | IRQ_MODERATOR_EN | IRQ_MODERATOR2_EN)); if (CHK_HW_FLAG(PTP_EN)) { if (CHK_HW_FLAG(PTP_CAP)) { if (hw->link_speed == EMAC_LINK_SPEED_1GB_FULL) emac_ptp_set_linkspeed(hw, emac_mac_speed_1000); else Loading drivers/net/ethernet/msm/emac/emac_main.c +12 −4 Original line number Diff line number Diff line Loading @@ -1624,12 +1624,16 @@ static int emac_mii_ioctl(struct net_device *netdev, /* IOCTL support for the interface */ static int emac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { struct emac_adapter *adpt = netdev_priv(netdev); struct emac_hw *hw = &adpt->hw; switch (cmd) { case SIOCGMIIPHY: case SIOCGMIIREG: case SIOCSMIIREG: return emac_mii_ioctl(netdev, ifr, cmd); case SIOCSHWTSTAMP: if (CHK_HW_FLAG(PTP_CAP)) return emac_tstamp_ioctl(netdev, ifr, cmd); default: return -EOPNOTSUPP; Loading Loading @@ -2063,9 +2067,6 @@ static void emac_init_adapter(struct emac_adapter *adpt) /* phy */ emac_hw_init_phy(hw); if (CHK_HW_FLAG(PTP_CAP)) emac_ptp_init(hw); } #ifdef CONFIG_PM_RUNTIME Loading Loading @@ -2440,6 +2441,9 @@ static int emac_probe(struct platform_device *pdev) goto err_register_netdev; } if (CHK_HW_FLAG(PTP_CAP)) emac_ptp_init(adpt->netdev); pr_info("%s - version %s\n", emac_drv_description, emac_drv_version); emac_dbg(adpt, probe, "EMAC HW ID %d.%d\n", hw->devid, hw->revid); emac_dbg(adpt, probe, "EMAC HW version %d.%d.%d\n", Loading @@ -2461,10 +2465,14 @@ static int emac_remove(struct platform_device *pdev) { struct net_device *netdev = dev_get_drvdata(&pdev->dev); struct emac_adapter *adpt = netdev_priv(netdev); struct emac_hw *hw = &adpt->hw; pr_info("exiting %s\n", emac_drv_name); unregister_netdev(netdev); if (CHK_HW_FLAG(PTP_CAP)) emac_ptp_remove(netdev); emac_release_resources(adpt); free_netdev(netdev); dev_set_drvdata(&pdev->dev, NULL); Loading drivers/net/ethernet/msm/emac/emac_ptp.c +94 −26 Original line number Diff line number Diff line Loading @@ -162,21 +162,6 @@ static void rtc_adjtime(struct emac_hw *hw, s64 delta) wmb(); } int emac_ptp_init(struct emac_hw *hw) { int ret = 0; if (!CHK_HW_FLAG(PTP_CAP)) { emac_err(hw->adpt, "not ieee-1588 capable\n"); return -ENOTSUPP; } spin_lock_init(&hw->ptp_lock); ret = emac_hw_1588_core_disable(hw); return ret; } int emac_ptp_config(struct emac_hw *hw) { struct timespec ts; Loading Loading @@ -233,37 +218,49 @@ int emac_ptp_set_linkspeed(struct emac_hw *hw, enum emac_mac_speed link_speed) return 0; } int emac_ptp_settime(struct emac_hw *hw, const struct timespec *ts) static int emac_ptp_settime(struct emac_hw *hw, const struct timespec *ts) { int ret = 0; unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) ret = -EPERM; else rtc_settime(hw, ts); spin_unlock_irqrestore(&hw->ptp_lock, flag); return 0; return ret; } int emac_ptp_gettime(struct emac_hw *hw, struct timespec *ts) static int emac_ptp_gettime(struct emac_hw *hw, struct timespec *ts) { int ret = 0; unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) ret = -EPERM; else rtc_gettime(hw, ts); spin_unlock_irqrestore(&hw->ptp_lock, flag); return 0; return ret; } int emac_ptp_adjtime(struct emac_hw *hw, s64 delta) { int ret = 0; unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) ret = -EPERM; else rtc_adjtime(hw, delta); spin_unlock_irqrestore(&hw->ptp_lock, flag); return 0; return ret; } int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) Loading @@ -272,9 +269,6 @@ int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) struct emac_hw *hw = &adpt->hw; struct hwtstamp_config cfg; if (!CHK_HW_FLAG(PTP_CAP)) return -ENOTSUPP; if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) return -EFAULT; Loading Loading @@ -312,3 +306,77 @@ int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; } static int emac_ptp_sysfs_cmd(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct emac_adapter *adpt = netdev_priv(to_net_dev(dev)); struct timespec ts; int ret = -EINVAL; if (!strncmp(buf, "setTs", 5)) { getnstimeofday(&ts); ret = emac_ptp_settime(&adpt->hw, &ts); if (!ret) ret = count; } return ret; } static int emac_ptp_sysfs_tstamp_show(struct device *dev, struct device_attribute *attr, char *buf) { struct emac_adapter *adpt = netdev_priv(to_net_dev(dev)); struct timespec ts, ts_now; int count = PAGE_SIZE; int retval; retval = emac_ptp_gettime(&adpt->hw, &ts); if (retval) return retval; getnstimeofday(&ts_now); retval = snprintf(buf, count, "%12u.%09u tstamp %12u.%08u time-of-day\n", (int)ts.tv_sec, (int)ts.tv_nsec, (int)ts_now.tv_sec, (int)ts_now.tv_nsec); return retval; } static DEVICE_ATTR(cmd, 0222, NULL, emac_ptp_sysfs_cmd); static DEVICE_ATTR(tstamp, 0444, emac_ptp_sysfs_tstamp_show, NULL); static void emac_ptp_sysfs_create(struct net_device *netdev) { struct emac_adapter *adpt = netdev_priv(netdev); if (device_create_file(&netdev->dev, &dev_attr_cmd) || device_create_file(&netdev->dev, &dev_attr_tstamp)) emac_err(adpt, "emac_ptp: failed to create sysfs files\n"); } static void emac_ptp_sysfs_remove(struct net_device *netdev) { device_remove_file(&netdev->dev, &dev_attr_cmd); device_remove_file(&netdev->dev, &dev_attr_tstamp); } int emac_ptp_init(struct net_device *netdev) { struct emac_adapter *adpt = netdev_priv(netdev); struct emac_hw *hw = &adpt->hw; int ret = 0; spin_lock_init(&hw->ptp_lock); emac_ptp_sysfs_create(netdev); ret = emac_hw_1588_core_disable(hw); return ret; } void emac_ptp_remove(struct net_device *netdev) { emac_ptp_sysfs_remove(netdev); } drivers/net/ethernet/msm/emac/emac_ptp.h +2 −4 Original line number Diff line number Diff line Loading @@ -15,13 +15,11 @@ #define DEFAULT_RTC_REF_CLKRATE 125000000 int emac_ptp_init(struct emac_hw *hw); int emac_ptp_init(struct net_device *netdev); void emac_ptp_remove(struct net_device *netdev); int emac_ptp_config(struct emac_hw *hw); int emac_ptp_stop(struct emac_hw *hw); int emac_ptp_set_linkspeed(struct emac_hw *hw, enum emac_mac_speed speed); int emac_ptp_settime(struct emac_hw *hw, const struct timespec *ts); int emac_ptp_gettime(struct emac_hw *hw, struct timespec *ts); int emac_ptp_adjtime(struct emac_hw *hw, s64 delta); int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); #endif /* _EMAC_PTP_H_ */ Loading
drivers/net/ethernet/msm/emac/emac_hw.c +4 −2 Original line number Diff line number Diff line Loading @@ -646,7 +646,9 @@ void emac_hw_disable_intr(struct emac_hw *hw) emac_reg_w32(hw, EMAC, irq_info->mask_reg, 0); } emac_reg_w32(hw, EMAC_1588, EMAC_P1588_PTP_EXPANDED_INT_MASK, 0); if (adpt->tstamp_en) emac_reg_w32(hw, EMAC_1588, EMAC_P1588_PTP_EXPANDED_INT_MASK, 0); if (adpt->phy_mode == PHY_INTERFACE_MODE_SGMII) { irq_info = &adpt->irq_info[EMAC_SGMII_PHY_IRQ]; Loading Loading @@ -1195,7 +1197,7 @@ void emac_hw_start_mac(struct emac_hw *hw) (INT_RD_CLR_EN | LPW_MODE | IRQ_MODERATOR_EN | IRQ_MODERATOR2_EN)); if (CHK_HW_FLAG(PTP_EN)) { if (CHK_HW_FLAG(PTP_CAP)) { if (hw->link_speed == EMAC_LINK_SPEED_1GB_FULL) emac_ptp_set_linkspeed(hw, emac_mac_speed_1000); else Loading
drivers/net/ethernet/msm/emac/emac_main.c +12 −4 Original line number Diff line number Diff line Loading @@ -1624,12 +1624,16 @@ static int emac_mii_ioctl(struct net_device *netdev, /* IOCTL support for the interface */ static int emac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { struct emac_adapter *adpt = netdev_priv(netdev); struct emac_hw *hw = &adpt->hw; switch (cmd) { case SIOCGMIIPHY: case SIOCGMIIREG: case SIOCSMIIREG: return emac_mii_ioctl(netdev, ifr, cmd); case SIOCSHWTSTAMP: if (CHK_HW_FLAG(PTP_CAP)) return emac_tstamp_ioctl(netdev, ifr, cmd); default: return -EOPNOTSUPP; Loading Loading @@ -2063,9 +2067,6 @@ static void emac_init_adapter(struct emac_adapter *adpt) /* phy */ emac_hw_init_phy(hw); if (CHK_HW_FLAG(PTP_CAP)) emac_ptp_init(hw); } #ifdef CONFIG_PM_RUNTIME Loading Loading @@ -2440,6 +2441,9 @@ static int emac_probe(struct platform_device *pdev) goto err_register_netdev; } if (CHK_HW_FLAG(PTP_CAP)) emac_ptp_init(adpt->netdev); pr_info("%s - version %s\n", emac_drv_description, emac_drv_version); emac_dbg(adpt, probe, "EMAC HW ID %d.%d\n", hw->devid, hw->revid); emac_dbg(adpt, probe, "EMAC HW version %d.%d.%d\n", Loading @@ -2461,10 +2465,14 @@ static int emac_remove(struct platform_device *pdev) { struct net_device *netdev = dev_get_drvdata(&pdev->dev); struct emac_adapter *adpt = netdev_priv(netdev); struct emac_hw *hw = &adpt->hw; pr_info("exiting %s\n", emac_drv_name); unregister_netdev(netdev); if (CHK_HW_FLAG(PTP_CAP)) emac_ptp_remove(netdev); emac_release_resources(adpt); free_netdev(netdev); dev_set_drvdata(&pdev->dev, NULL); Loading
drivers/net/ethernet/msm/emac/emac_ptp.c +94 −26 Original line number Diff line number Diff line Loading @@ -162,21 +162,6 @@ static void rtc_adjtime(struct emac_hw *hw, s64 delta) wmb(); } int emac_ptp_init(struct emac_hw *hw) { int ret = 0; if (!CHK_HW_FLAG(PTP_CAP)) { emac_err(hw->adpt, "not ieee-1588 capable\n"); return -ENOTSUPP; } spin_lock_init(&hw->ptp_lock); ret = emac_hw_1588_core_disable(hw); return ret; } int emac_ptp_config(struct emac_hw *hw) { struct timespec ts; Loading Loading @@ -233,37 +218,49 @@ int emac_ptp_set_linkspeed(struct emac_hw *hw, enum emac_mac_speed link_speed) return 0; } int emac_ptp_settime(struct emac_hw *hw, const struct timespec *ts) static int emac_ptp_settime(struct emac_hw *hw, const struct timespec *ts) { int ret = 0; unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) ret = -EPERM; else rtc_settime(hw, ts); spin_unlock_irqrestore(&hw->ptp_lock, flag); return 0; return ret; } int emac_ptp_gettime(struct emac_hw *hw, struct timespec *ts) static int emac_ptp_gettime(struct emac_hw *hw, struct timespec *ts) { int ret = 0; unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) ret = -EPERM; else rtc_gettime(hw, ts); spin_unlock_irqrestore(&hw->ptp_lock, flag); return 0; return ret; } int emac_ptp_adjtime(struct emac_hw *hw, s64 delta) { int ret = 0; unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) ret = -EPERM; else rtc_adjtime(hw, delta); spin_unlock_irqrestore(&hw->ptp_lock, flag); return 0; return ret; } int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) Loading @@ -272,9 +269,6 @@ int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) struct emac_hw *hw = &adpt->hw; struct hwtstamp_config cfg; if (!CHK_HW_FLAG(PTP_CAP)) return -ENOTSUPP; if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) return -EFAULT; Loading Loading @@ -312,3 +306,77 @@ int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; } static int emac_ptp_sysfs_cmd(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct emac_adapter *adpt = netdev_priv(to_net_dev(dev)); struct timespec ts; int ret = -EINVAL; if (!strncmp(buf, "setTs", 5)) { getnstimeofday(&ts); ret = emac_ptp_settime(&adpt->hw, &ts); if (!ret) ret = count; } return ret; } static int emac_ptp_sysfs_tstamp_show(struct device *dev, struct device_attribute *attr, char *buf) { struct emac_adapter *adpt = netdev_priv(to_net_dev(dev)); struct timespec ts, ts_now; int count = PAGE_SIZE; int retval; retval = emac_ptp_gettime(&adpt->hw, &ts); if (retval) return retval; getnstimeofday(&ts_now); retval = snprintf(buf, count, "%12u.%09u tstamp %12u.%08u time-of-day\n", (int)ts.tv_sec, (int)ts.tv_nsec, (int)ts_now.tv_sec, (int)ts_now.tv_nsec); return retval; } static DEVICE_ATTR(cmd, 0222, NULL, emac_ptp_sysfs_cmd); static DEVICE_ATTR(tstamp, 0444, emac_ptp_sysfs_tstamp_show, NULL); static void emac_ptp_sysfs_create(struct net_device *netdev) { struct emac_adapter *adpt = netdev_priv(netdev); if (device_create_file(&netdev->dev, &dev_attr_cmd) || device_create_file(&netdev->dev, &dev_attr_tstamp)) emac_err(adpt, "emac_ptp: failed to create sysfs files\n"); } static void emac_ptp_sysfs_remove(struct net_device *netdev) { device_remove_file(&netdev->dev, &dev_attr_cmd); device_remove_file(&netdev->dev, &dev_attr_tstamp); } int emac_ptp_init(struct net_device *netdev) { struct emac_adapter *adpt = netdev_priv(netdev); struct emac_hw *hw = &adpt->hw; int ret = 0; spin_lock_init(&hw->ptp_lock); emac_ptp_sysfs_create(netdev); ret = emac_hw_1588_core_disable(hw); return ret; } void emac_ptp_remove(struct net_device *netdev) { emac_ptp_sysfs_remove(netdev); }
drivers/net/ethernet/msm/emac/emac_ptp.h +2 −4 Original line number Diff line number Diff line Loading @@ -15,13 +15,11 @@ #define DEFAULT_RTC_REF_CLKRATE 125000000 int emac_ptp_init(struct emac_hw *hw); int emac_ptp_init(struct net_device *netdev); void emac_ptp_remove(struct net_device *netdev); int emac_ptp_config(struct emac_hw *hw); int emac_ptp_stop(struct emac_hw *hw); int emac_ptp_set_linkspeed(struct emac_hw *hw, enum emac_mac_speed speed); int emac_ptp_settime(struct emac_hw *hw, const struct timespec *ts); int emac_ptp_gettime(struct emac_hw *hw, struct timespec *ts); int emac_ptp_adjtime(struct emac_hw *hw, s64 delta); int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); #endif /* _EMAC_PTP_H_ */