Loading drivers/net/ethernet/msm/emac/emac.h +28 −38 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -177,6 +177,33 @@ struct emac_hw_stats { u64 tx_col; /* collisions */ }; enum emac_hw_flags { EMAC_FLAG_HW_PROMISC_EN, EMAC_FLAG_HW_VLANSTRIP_EN, EMAC_FLAG_HW_MULTIALL_EN, EMAC_FLAG_HW_LOOPBACK_EN, EMAC_FLAG_HW_PTP_CAP, EMAC_FLAG_HW_PTP_EN, EMAC_FLAG_HW_TS_RX_EN, EMAC_FLAG_HW_TS_TX_EN, }; enum emac_adapter_flags { EMAC_FLAG_ADPT_STATE_RESETTING, EMAC_FLAG_ADPT_STATE_DOWN, EMAC_FLAG_ADPT_STATE_WATCH_DOG, EMAC_FLAG_ADPT_TASK_REINIT_REQ, EMAC_FLAG_ADPT_TASK_LSC_REQ, EMAC_FLAG_ADPT_TASK_CHK_SGMII_REQ, }; /* emac shorthand bitops macros */ #define TEST_FLAG(OBJ, FLAG) test_bit(EMAC_FLAG_ ## FLAG, &((OBJ)->flags)) #define SET_FLAG(OBJ, FLAG) set_bit(EMAC_FLAG_ ## FLAG, &((OBJ)->flags)) #define CLR_FLAG(OBJ, FLAG) clear_bit(EMAC_FLAG_ ## FLAG, &((OBJ)->flags)) #define TEST_N_SET_FLAG(OBJ, FLAG) \ test_and_set_bit(EMAC_FLAG_ ## FLAG, &((OBJ)->flags)) struct emac_hw { void __iomem *reg_addr[NUM_EMAC_REG_BASES]; Loading Loading @@ -237,20 +264,6 @@ struct emac_hw { unsigned long flags; }; #define EMAC_HW_FLAG_PROMISC_EN 0 #define EMAC_HW_FLAG_VLANSTRIP_EN 1 #define EMAC_HW_FLAG_MULTIALL_EN 2 #define EMAC_HW_FLAG_LOOPBACK_EN 3 #define EMAC_HW_FLAG_PTP_CAP 4 #define EMAC_HW_FLAG_PTP_EN 5 #define EMAC_HW_FLAG_TS_RX_EN 6 #define EMAC_HW_FLAG_TS_TX_EN 7 #define CHK_HW_FLAG(_flag) CHK_FLAG(hw, HW, _flag) #define SET_HW_FLAG(_flag) SET_FLAG(hw, HW, _flag) #define CLI_HW_FLAG(_flag) CLI_FLAG(hw, HW, _flag) /* RSS hstype Definitions */ #define EMAC_RSS_HSTYP_IPV4_EN 0x00000001 #define EMAC_RSS_HSTYP_TCP4_EN 0x00000002 Loading Loading @@ -694,29 +707,6 @@ struct emac_adapter { unsigned long flags; }; #define EMAC_ADPT_FLAG_STATE_RESETTING 16 #define EMAC_ADPT_FLAG_STATE_DOWN 17 #define EMAC_ADPT_FLAG_STATE_WATCH_DOG 18 #define EMAC_ADPT_FLAG_TASK_REINIT_REQ 19 #define EMAC_ADPT_FLAG_TASK_LSC_REQ 20 #define EMAC_ADPT_FLAG_TASK_CHK_SGMII_REQ 21 #define CHK_ADPT_FLAG(_flag) CHK_FLAG(adpt, ADPT, _flag) #define SET_ADPT_FLAG(_flag) SET_FLAG(adpt, ADPT, _flag) #define CLI_ADPT_FLAG(_flag) CLI_FLAG(adpt, ADPT, _flag) #define CHK_AND_SET_ADPT_FLAG(_flag) CHK_AND_SET_FLAG(adpt, ADPT, _flag) /* definitions for flags */ #define CHK_FLAG(_st, _type, _flag) \ test_bit((EMAC_##_type##_FLAG_##_flag), &((_st)->flags)) #define SET_FLAG(_st, _type, _flag) \ set_bit((EMAC_##_type##_FLAG_##_flag), &((_st)->flags)) #define CLI_FLAG(_st, _type, _flag) \ clear_bit((EMAC_##_type##_FLAG_##_flag), &((_st)->flags)) #define CHK_AND_SET_FLAG(_st, _type, _flag) \ test_and_set_bit((EMAC_##_type##_FLAG_##_flag), &((_st)->flags)) /* default to trying for four seconds */ #define EMAC_TRY_LINK_TIMEOUT (4 * HZ) Loading drivers/net/ethernet/msm/emac/emac_ethtool.c +7 −7 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -148,7 +148,7 @@ static int emac_set_settings(struct net_device *netdev, emac_info(adpt, link, "ethtool cmd autoneg %d, speed %d, duplex %d\n", ecmd->autoneg, ecmd->speed, ecmd->duplex); while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ old = hw->autoneg_advertised; Loading @@ -163,7 +163,7 @@ static int emac_set_settings(struct net_device *netdev, if (ecmd->duplex != DUPLEX_FULL) { emac_warn(adpt, hw, "1000M half is invalid\n"); CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return -EINVAL; } advertised = EMAC_LINK_SPEED_1GB_FULL; Loading Loading @@ -202,7 +202,7 @@ static int emac_set_settings(struct net_device *netdev, } done: CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return retval; } Loading Loading @@ -236,7 +236,7 @@ static int emac_set_pauseparam(struct net_device *netdev, bool disable_fc_autoneg; int retval = 0; while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ req_fc_mode = hw->req_fc_mode; Loading @@ -256,7 +256,7 @@ static int emac_set_pauseparam(struct net_device *netdev, else if (!pause->rx_pause && !pause->tx_pause) req_fc_mode = emac_fc_none; else { CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return -EINVAL; } Loading @@ -273,7 +273,7 @@ static int emac_set_pauseparam(struct net_device *netdev, emac_hw_config_fc(hw); } CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return retval; } Loading drivers/net/ethernet/msm/emac/emac_hw.c +7 −7 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -1024,22 +1024,22 @@ void emac_hw_config_mac_ctrl(struct emac_hw *hw) mac = emac_reg_r32(hw, EMAC, EMAC_MAC_CTRL); if (CHK_HW_FLAG(VLANSTRIP_EN)) if (TEST_FLAG(hw, HW_VLANSTRIP_EN)) mac |= VLAN_STRIP; else mac &= ~VLAN_STRIP; if (CHK_HW_FLAG(PROMISC_EN)) if (TEST_FLAG(hw, HW_PROMISC_EN)) mac |= PROM_MODE; else mac &= ~PROM_MODE; if (CHK_HW_FLAG(MULTIALL_EN)) if (TEST_FLAG(hw, HW_MULTIALL_EN)) mac |= MULTI_ALL; else mac &= ~MULTI_ALL; if (CHK_HW_FLAG(LOOPBACK_EN)) if (TEST_FLAG(hw, HW_LOOPBACK_EN)) mac |= MAC_LP_EN; else mac &= ~MAC_LP_EN; Loading Loading @@ -1376,7 +1376,7 @@ void emac_hw_config_mac(struct emac_hw *hw) emac_hw_config_rx_ctrl(hw); emac_hw_config_dma_ctrl(hw); if (CHK_HW_FLAG(PTP_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_config(hw); val = emac_reg_r32(hw, EMAC, EMAC_AXI_MAST_CTRL); Loading Loading @@ -1486,7 +1486,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_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_set_linkspeed(hw, hw->link_speed); emac_hw_config_mac_ctrl(hw); Loading drivers/net/ethernet/msm/emac/emac_main.c +63 −62 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -153,11 +153,11 @@ void emac_reinit_locked(struct emac_adapter *adpt) { WARN_ON(in_interrupt()); while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ if (CHK_ADPT_FLAG(STATE_DOWN)) { CLI_ADPT_FLAG(STATE_RESETTING); if (TEST_FLAG(adpt, ADPT_STATE_DOWN)) { CLR_FLAG(adpt, ADPT_STATE_RESETTING); return; } Loading @@ -169,24 +169,24 @@ void emac_reinit_locked(struct emac_adapter *adpt) } emac_up(adpt); CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); } static void emac_task_schedule(struct emac_adapter *adpt) { if (!CHK_ADPT_FLAG(STATE_DOWN) && !CHK_ADPT_FLAG(STATE_WATCH_DOG)) { SET_ADPT_FLAG(STATE_WATCH_DOG); if (!TEST_FLAG(adpt, ADPT_STATE_DOWN) && !TEST_FLAG(adpt, ADPT_STATE_WATCH_DOG)) { SET_FLAG(adpt, ADPT_STATE_WATCH_DOG); schedule_work(&adpt->emac_task); } } static void emac_check_lsc(struct emac_adapter *adpt) { SET_ADPT_FLAG(TASK_LSC_REQ); SET_FLAG(adpt, ADPT_TASK_LSC_REQ); adpt->link_jiffies = jiffies + EMAC_TRY_LINK_TIMEOUT; if (!CHK_ADPT_FLAG(STATE_DOWN)) if (!TEST_FLAG(adpt, ADPT_STATE_DOWN)) emac_task_schedule(adpt); } Loading @@ -195,8 +195,8 @@ static void emac_tx_timeout(struct net_device *netdev) { struct emac_adapter *adpt = netdev_priv(netdev); if (!CHK_ADPT_FLAG(STATE_DOWN)) { SET_ADPT_FLAG(TASK_REINIT_REQ); if (!TEST_FLAG(adpt, ADPT_STATE_DOWN)) { SET_FLAG(adpt, ADPT_TASK_REINIT_REQ); emac_task_schedule(adpt); } } Loading @@ -210,13 +210,13 @@ static void emac_set_rx_mode(struct net_device *netdev) /* Check for Promiscuous and All Multicast modes */ if (netdev->flags & IFF_PROMISC) { SET_HW_FLAG(PROMISC_EN); SET_FLAG(hw, HW_PROMISC_EN); } else if (netdev->flags & IFF_ALLMULTI) { SET_HW_FLAG(MULTIALL_EN); CLI_HW_FLAG(PROMISC_EN); SET_FLAG(hw, HW_MULTIALL_EN); CLR_FLAG(hw, HW_PROMISC_EN); } else { CLI_HW_FLAG(MULTIALL_EN); CLI_HW_FLAG(PROMISC_EN); CLR_FLAG(hw, HW_MULTIALL_EN); CLR_FLAG(hw, HW_PROMISC_EN); } emac_hw_config_mac_ctrl(hw); Loading Loading @@ -533,7 +533,7 @@ static void emac_poll_hwtxtstamp(struct emac_adapter *adpt) static void emac_schedule_hwtxtstamp_task(struct emac_adapter *adpt) { if (CHK_ADPT_FLAG(STATE_DOWN)) if (TEST_FLAG(adpt, ADPT_STATE_DOWN)) return; if (schedule_work(&adpt->hwtxtstamp_task)) Loading Loading @@ -651,7 +651,7 @@ static void emac_handle_rx(struct emac_adapter *adpt, else skb_checksum_none_assert(skb); if (CHK_HW_FLAG(TS_RX_EN)) { if (TEST_FLAG(hw, HW_TS_RX_EN)) { struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); hwts->hwtstamp = ktime_set(srrd.genr.ts_high, Loading Loading @@ -929,7 +929,7 @@ static void emac_tx_map(struct emac_adapter *adpt, /* The last tpd */ emac_set_tpdesc_lastfrag(txque); if (CHK_HW_FLAG(TS_TX_EN) && if (TEST_FLAG(hw, HW_TS_TX_EN) && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { struct sk_buff *skb_ts = skb_clone(skb, GFP_ATOMIC); Loading Loading @@ -971,7 +971,7 @@ static int emac_start_xmit_frame(struct emac_adapter *adpt, union emac_sw_tpdesc stpd; u32 prod_idx; if (CHK_ADPT_FLAG(STATE_DOWN)) { if (TEST_FLAG(adpt, ADPT_STATE_DOWN)) { dev_kfree_skb_any(skb); return NETDEV_TX_OK; } Loading Loading @@ -1065,7 +1065,7 @@ static irqreturn_t emac_interrupt(int irq, void *data) emac_warn(adpt, intr, "isr error status 0x%x\n", status & ISR_ERROR); /* reset MAC */ SET_ADPT_FLAG(TASK_REINIT_REQ); SET_FLAG(adpt, ADPT_TASK_REINIT_REQ); emac_task_schedule(adpt); } Loading Loading @@ -1127,8 +1127,8 @@ static irqreturn_t emac_sgmii_interrupt(int irq, void *data) break; if (status & SGMII_PHY_INTERRUPT_ERR) { SET_ADPT_FLAG(TASK_CHK_SGMII_REQ); if (!CHK_ADPT_FLAG(STATE_DOWN)) SET_FLAG(adpt, ADPT_TASK_CHK_SGMII_REQ); if (!TEST_FLAG(adpt, ADPT_STATE_DOWN)) emac_task_schedule(adpt); } Loading @@ -1140,7 +1140,7 @@ static irqreturn_t emac_sgmii_interrupt(int irq, void *data) "failed to clear sgmii intr, status=0x%x\n", status); /* reset */ SET_ADPT_FLAG(TASK_REINIT_REQ); SET_FLAG(adpt, ADPT_TASK_REINIT_REQ); emac_task_schedule(adpt); break; } Loading Loading @@ -1184,9 +1184,9 @@ static int emac_set_features(struct net_device *netdev, netdev->features = features; if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) SET_HW_FLAG(VLANSTRIP_EN); SET_FLAG(hw, HW_VLANSTRIP_EN); else CLI_HW_FLAG(VLANSTRIP_EN); CLR_FLAG(hw, HW_VLANSTRIP_EN); if (netif_running(netdev)) emac_reinit_locked(adpt); Loading Loading @@ -1673,10 +1673,10 @@ int emac_up(struct emac_adapter *adpt) emac_enable_intr(adpt); netif_start_queue(netdev); CLI_ADPT_FLAG(STATE_DOWN); CLR_FLAG(adpt, ADPT_STATE_DOWN); /* check link status */ SET_ADPT_FLAG(TASK_LSC_REQ); SET_FLAG(adpt, ADPT_TASK_LSC_REQ); adpt->link_jiffies = jiffies + EMAC_TRY_LINK_TIMEOUT; mod_timer(&adpt->emac_timer, jiffies); Loading @@ -1697,7 +1697,7 @@ void emac_down(struct emac_adapter *adpt, u32 ctrl) unsigned long flags; int i; SET_ADPT_FLAG(STATE_DOWN); SET_FLAG(adpt, ADPT_STATE_DOWN); netif_stop_queue(netdev); netif_carrier_off(netdev); Loading @@ -1712,9 +1712,9 @@ void emac_down(struct emac_adapter *adpt, u32 ctrl) for (i = 0; (!adpt->no_mdio_gpio) && i < EMAC_NUM_GPIO; i++) gpio_free(adpt->gpio_info[i].gpio); CLI_ADPT_FLAG(TASK_LSC_REQ); CLI_ADPT_FLAG(TASK_REINIT_REQ); CLI_ADPT_FLAG(TASK_CHK_SGMII_REQ); CLR_FLAG(adpt, ADPT_TASK_LSC_REQ); CLR_FLAG(adpt, ADPT_TASK_REINIT_REQ); CLR_FLAG(adpt, ADPT_TASK_CHK_SGMII_REQ); del_timer_sync(&adpt->emac_timer); cancel_work_sync(&adpt->hwtxtstamp_task); Loading Loading @@ -1769,21 +1769,21 @@ static int emac_close(struct net_device *netdev) struct emac_hw *hw = &adpt->hw; /* ensure no task is running and no reset is in progress */ while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ pm_runtime_disable(netdev->dev.parent); if (!CHK_ADPT_FLAG(STATE_DOWN)) if (!TEST_FLAG(adpt, ADPT_STATE_DOWN)) emac_down(adpt, EMAC_HW_CTRL_RESET_MAC); else emac_hw_reset_mac(hw); if (CHK_HW_FLAG(PTP_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_stop(hw); emac_free_all_rtx_descriptor(adpt); CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return 0; } Loading Loading @@ -1877,7 +1877,7 @@ static int emac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) case SIOCSMIIREG: return emac_mii_ioctl(netdev, ifr, cmd); case SIOCSHWTSTAMP: if (CHK_HW_FLAG(PTP_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) return emac_tstamp_ioctl(netdev, ifr, cmd); default: return -EOPNOTSUPP; Loading Loading @@ -1977,11 +1977,12 @@ static const struct net_device_ops emac_netdev_ops = { /* Reinitialize the interface/HW if required */ static void emac_reinit_task_routine(struct emac_adapter *adpt) { if (!CHK_ADPT_FLAG(TASK_REINIT_REQ)) if (!TEST_FLAG(adpt, ADPT_TASK_REINIT_REQ)) return; CLI_ADPT_FLAG(TASK_REINIT_REQ); CLR_FLAG(adpt, ADPT_TASK_REINIT_REQ); if (CHK_ADPT_FLAG(STATE_DOWN) || CHK_ADPT_FLAG(STATE_RESETTING)) if (TEST_FLAG(adpt, ADPT_STATE_DOWN) || TEST_FLAG(adpt, ADPT_STATE_RESETTING)) return; emac_reinit_locked(adpt); Loading Loading @@ -2011,15 +2012,15 @@ static void emac_link_task_routine(struct emac_adapter *adpt) struct emac_hw *hw = &adpt->hw; char *link_desc; if (!CHK_ADPT_FLAG(TASK_LSC_REQ)) if (!TEST_FLAG(adpt, ADPT_TASK_LSC_REQ)) return; CLI_ADPT_FLAG(TASK_LSC_REQ); CLR_FLAG(adpt, ADPT_TASK_LSC_REQ); /* ensure that no reset is in progess while link task is running */ while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ if (CHK_ADPT_FLAG(STATE_DOWN)) if (TEST_FLAG(adpt, ADPT_STATE_DOWN)) goto link_task_done; emac_check_phy_link(hw, &hw->link_speed, &hw->link_up); Loading Loading @@ -2057,7 +2058,7 @@ static void emac_link_task_routine(struct emac_adapter *adpt) netif_wake_queue(netdev); } else { if (time_after(adpt->link_jiffies, jiffies)) SET_ADPT_FLAG(TASK_LSC_REQ); SET_FLAG(adpt, ADPT_TASK_LSC_REQ); /* only continue if link was up previously */ if (!netif_carrier_ok(netdev)) Loading @@ -2076,7 +2077,7 @@ static void emac_link_task_routine(struct emac_adapter *adpt) mod_timer(&adpt->emac_timer, jiffies); link_task_done: CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); } /* Check SGMII for error */ Loading @@ -2084,15 +2085,15 @@ static void emac_sgmii_task_routine(struct emac_adapter *adpt) { struct emac_hw *hw = &adpt->hw; if (!CHK_ADPT_FLAG(TASK_CHK_SGMII_REQ)) if (!TEST_FLAG(adpt, ADPT_TASK_CHK_SGMII_REQ)) return; CLI_ADPT_FLAG(TASK_CHK_SGMII_REQ); CLR_FLAG(adpt, ADPT_TASK_CHK_SGMII_REQ); /* ensure that no reset is in progess while link task is running */ while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ if (CHK_ADPT_FLAG(STATE_DOWN)) if (TEST_FLAG(adpt, ADPT_STATE_DOWN)) goto sgmii_task_done; if (emac_reg_r32(hw, EMAC_SGMII_PHY, EMAC_SGMII_PHY_RX_CHK_STATUS) Loading @@ -2102,7 +2103,7 @@ static void emac_sgmii_task_routine(struct emac_adapter *adpt) emac_err(adpt, "SGMII CDR not locked\n"); sgmii_task_done: CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); } /* Watchdog task routine */ Loading @@ -2111,7 +2112,7 @@ static void emac_task_routine(struct work_struct *work) struct emac_adapter *adpt = container_of(work, struct emac_adapter, emac_task); if (!CHK_ADPT_FLAG(STATE_WATCH_DOG)) if (!TEST_FLAG(adpt, ADPT_STATE_WATCH_DOG)) emac_warn(adpt, timer, "flag STATE_WATCH_DOG doesn't set\n"); emac_reinit_task_routine(adpt); Loading @@ -2120,7 +2121,7 @@ static void emac_task_routine(struct work_struct *work) emac_sgmii_task_routine(adpt); CLI_ADPT_FLAG(STATE_WATCH_DOG); CLR_FLAG(adpt, ADPT_STATE_WATCH_DOG); } /* Timer routine */ Loading @@ -2133,7 +2134,7 @@ static void emac_timer_routine(unsigned long data) return; /* poll faster when waiting for link */ if (CHK_ADPT_FLAG(TASK_LSC_REQ)) if (TEST_FLAG(adpt, ADPT_TASK_LSC_REQ)) delay = HZ / 10; else delay = 2 * HZ; Loading Loading @@ -2379,12 +2380,12 @@ static int emac_suspend(struct device *device) netif_device_detach(netdev); if (netif_running(netdev)) { /* ensure no task is running and no reset is in progress */ while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ emac_down(adpt, 0); CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); } emac_check_phy_link(hw, &speed, &link_up); Loading Loading @@ -2774,7 +2775,7 @@ static int emac_probe(struct platform_device *pdev) adpt->rfdesc_size = EMAC_RFDESC_SIZE; if (adpt->tstamp_en) SET_HW_FLAG(PTP_CAP); SET_FLAG(hw, HW_PTP_CAP); /* init netdev */ netdev->netdev_ops = &emac_netdev_ops; Loading Loading @@ -2838,8 +2839,8 @@ static int emac_probe(struct platform_device *pdev) skb_queue_head_init(&adpt->hwtxtstamp_ready_queue); INIT_WORK(&adpt->hwtxtstamp_task, emac_hwtxtstamp_task_routine); SET_HW_FLAG(VLANSTRIP_EN); SET_ADPT_FLAG(STATE_DOWN); SET_FLAG(hw, HW_VLANSTRIP_EN); SET_FLAG(adpt, ADPT_STATE_DOWN); strlcpy(netdev->name, "eth%d", sizeof(netdev->name)); retval = register_netdev(netdev); Loading @@ -2848,7 +2849,7 @@ static int emac_probe(struct platform_device *pdev) goto err_register_netdev; } if (CHK_HW_FLAG(PTP_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_init(adpt->netdev); pr_info("%s - version %s\n", emac_drv_description, emac_drv_version); Loading Loading @@ -2882,7 +2883,7 @@ static int emac_remove(struct platform_device *pdev) pr_info("exiting %s\n", emac_drv_name); unregister_netdev(netdev); if (CHK_HW_FLAG(PTP_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_remove(netdev); emac_disable_clks(adpt); Loading drivers/net/ethernet/msm/emac/emac_ptp.c +22 −22 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -189,12 +189,12 @@ static int emac_hw_config_tx_tstamp(struct emac_hw *hw, bool enable) emac_reg_update32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_CSR1, TX_TS_ENABLE, TX_TS_ENABLE); wmb(); SET_HW_FLAG(TS_TX_EN); SET_FLAG(hw, HW_TS_TX_EN); } else { emac_reg_update32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_CSR1, TX_TS_ENABLE, 0); wmb(); CLI_HW_FLAG(TS_TX_EN); CLR_FLAG(hw, HW_TS_TX_EN); } return 0; Loading @@ -211,9 +211,9 @@ static int emac_hw_config_rx_tstamp(struct emac_hw *hw, bool enable) TS_RX_FIFO_SYNC_RST, 0); wmb(); SET_HW_FLAG(TS_RX_EN); SET_FLAG(hw, HW_TS_RX_EN); } else { CLI_HW_FLAG(TS_RX_EN); CLR_FLAG(hw, HW_TS_RX_EN); } return 0; Loading @@ -221,9 +221,9 @@ static int emac_hw_config_rx_tstamp(struct emac_hw *hw, bool enable) static int emac_hw_1588_core_disable(struct emac_hw *hw) { if (CHK_HW_FLAG(TS_RX_EN)) if (TEST_FLAG(hw, HW_TS_RX_EN)) emac_hw_config_rx_tstamp(hw, false); if (CHK_HW_FLAG(TS_TX_EN)) if (TEST_FLAG(hw, HW_TS_TX_EN)) emac_hw_config_tx_tstamp(hw, false); emac_reg_update32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_CSR1, Loading @@ -235,7 +235,7 @@ static int emac_hw_1588_core_disable(struct emac_hw *hw) emac_reg_w32(hw, EMAC_1588, EMAC_P1588_PTP_EXPANDED_INT_MASK, 0); wmb(); CLI_HW_FLAG(PTP_EN); CLR_FLAG(hw, HW_PTP_EN); return 0; } Loading Loading @@ -297,7 +297,7 @@ static int emac_hw_1588_core_enable(struct emac_hw *hw, GRANDMASTER_MODE | GM_PPS_SYNC, 0); wmb(); SET_HW_FLAG(PTP_EN); SET_FLAG(hw, HW_PTP_EN); return 0; } Loading Loading @@ -401,7 +401,7 @@ int emac_ptp_config(struct emac_hw *hw) spin_lock_irqsave(&hw->ptp_lock, flag); if (CHK_HW_FLAG(PTP_EN)) if (TEST_FLAG(hw, HW_PTP_EN)) goto unlock_out; hw->frac_ns_adj = get_frac_ns_adj_from_tbl(hw); Loading Loading @@ -432,7 +432,7 @@ int emac_ptp_stop(struct emac_hw *hw) spin_lock_irqsave(&hw->ptp_lock, flag); if (CHK_HW_FLAG(PTP_EN)) if (TEST_FLAG(hw, HW_PTP_EN)) ret = emac_hw_1588_core_disable(hw); hw->ptp_intr_mask = 0; Loading Loading @@ -477,7 +477,7 @@ static int emac_ptp_settime(struct emac_hw *hw, const struct timespec *ts) unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) ret = -EPERM; else rtc_settime(hw, ts); Loading @@ -492,7 +492,7 @@ static int emac_ptp_gettime(struct emac_hw *hw, struct timespec *ts) unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) ret = -EPERM; else rtc_gettime(hw, ts); Loading @@ -507,7 +507,7 @@ int emac_ptp_adjtime(struct emac_hw *hw, s64 delta) unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) ret = -EPERM; else rtc_adjtime(hw, delta); Loading @@ -522,7 +522,7 @@ 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_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) return -EPERM; if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) Loading @@ -533,7 +533,7 @@ int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) emac_hw_config_tx_tstamp(hw, false); break; case HWTSTAMP_TX_ON: if (CHK_HW_FLAG(TS_TX_EN)) if (TEST_FLAG(hw, HW_TS_TX_EN)) break; emac_hw_config_tx_tstamp(hw, true); Loading @@ -548,7 +548,7 @@ int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) break; default: cfg.rx_filter = HWTSTAMP_FILTER_ALL; if (CHK_HW_FLAG(TS_RX_EN)) if (TEST_FLAG(hw, HW_TS_RX_EN)) break; emac_hw_config_rx_tstamp(hw, true); Loading Loading @@ -758,9 +758,9 @@ static int emac_ptp_sysfs_mode_set( if (mode == hw->ptp_mode) goto out; if (CHK_HW_FLAG(PTP_EN)) { bool rx_tstamp_enable = CHK_HW_FLAG(TS_RX_EN); bool tx_tstamp_enable = CHK_HW_FLAG(TS_TX_EN); if (TEST_FLAG(hw, HW_PTP_EN)) { bool rx_tstamp_enable = TEST_FLAG(hw, HW_TS_RX_EN); bool tx_tstamp_enable = TEST_FLAG(hw, HW_TS_TX_EN); emac_hw_1588_core_disable(hw); emac_hw_1588_core_enable(hw, mode, hw->ptp_clk_mode, Loading Loading @@ -791,7 +791,7 @@ static int emac_ptp_sysfs_frac_ns_adj_show( int count = PAGE_SIZE; int retval; if (!CHK_HW_FLAG(PTP_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) return -EPERM; retval = scnprintf(buf, count, "%d\n", adpt->hw.frac_ns_adj); Loading @@ -809,7 +809,7 @@ static int emac_ptp_sysfs_frac_ns_adj_set( struct emac_hw *hw = &adpt->hw; s32 adj; if (!CHK_HW_FLAG(PTP_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) return -EPERM; if (kstrtos32(buf, 0, &adj)) Loading Loading
drivers/net/ethernet/msm/emac/emac.h +28 −38 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -177,6 +177,33 @@ struct emac_hw_stats { u64 tx_col; /* collisions */ }; enum emac_hw_flags { EMAC_FLAG_HW_PROMISC_EN, EMAC_FLAG_HW_VLANSTRIP_EN, EMAC_FLAG_HW_MULTIALL_EN, EMAC_FLAG_HW_LOOPBACK_EN, EMAC_FLAG_HW_PTP_CAP, EMAC_FLAG_HW_PTP_EN, EMAC_FLAG_HW_TS_RX_EN, EMAC_FLAG_HW_TS_TX_EN, }; enum emac_adapter_flags { EMAC_FLAG_ADPT_STATE_RESETTING, EMAC_FLAG_ADPT_STATE_DOWN, EMAC_FLAG_ADPT_STATE_WATCH_DOG, EMAC_FLAG_ADPT_TASK_REINIT_REQ, EMAC_FLAG_ADPT_TASK_LSC_REQ, EMAC_FLAG_ADPT_TASK_CHK_SGMII_REQ, }; /* emac shorthand bitops macros */ #define TEST_FLAG(OBJ, FLAG) test_bit(EMAC_FLAG_ ## FLAG, &((OBJ)->flags)) #define SET_FLAG(OBJ, FLAG) set_bit(EMAC_FLAG_ ## FLAG, &((OBJ)->flags)) #define CLR_FLAG(OBJ, FLAG) clear_bit(EMAC_FLAG_ ## FLAG, &((OBJ)->flags)) #define TEST_N_SET_FLAG(OBJ, FLAG) \ test_and_set_bit(EMAC_FLAG_ ## FLAG, &((OBJ)->flags)) struct emac_hw { void __iomem *reg_addr[NUM_EMAC_REG_BASES]; Loading Loading @@ -237,20 +264,6 @@ struct emac_hw { unsigned long flags; }; #define EMAC_HW_FLAG_PROMISC_EN 0 #define EMAC_HW_FLAG_VLANSTRIP_EN 1 #define EMAC_HW_FLAG_MULTIALL_EN 2 #define EMAC_HW_FLAG_LOOPBACK_EN 3 #define EMAC_HW_FLAG_PTP_CAP 4 #define EMAC_HW_FLAG_PTP_EN 5 #define EMAC_HW_FLAG_TS_RX_EN 6 #define EMAC_HW_FLAG_TS_TX_EN 7 #define CHK_HW_FLAG(_flag) CHK_FLAG(hw, HW, _flag) #define SET_HW_FLAG(_flag) SET_FLAG(hw, HW, _flag) #define CLI_HW_FLAG(_flag) CLI_FLAG(hw, HW, _flag) /* RSS hstype Definitions */ #define EMAC_RSS_HSTYP_IPV4_EN 0x00000001 #define EMAC_RSS_HSTYP_TCP4_EN 0x00000002 Loading Loading @@ -694,29 +707,6 @@ struct emac_adapter { unsigned long flags; }; #define EMAC_ADPT_FLAG_STATE_RESETTING 16 #define EMAC_ADPT_FLAG_STATE_DOWN 17 #define EMAC_ADPT_FLAG_STATE_WATCH_DOG 18 #define EMAC_ADPT_FLAG_TASK_REINIT_REQ 19 #define EMAC_ADPT_FLAG_TASK_LSC_REQ 20 #define EMAC_ADPT_FLAG_TASK_CHK_SGMII_REQ 21 #define CHK_ADPT_FLAG(_flag) CHK_FLAG(adpt, ADPT, _flag) #define SET_ADPT_FLAG(_flag) SET_FLAG(adpt, ADPT, _flag) #define CLI_ADPT_FLAG(_flag) CLI_FLAG(adpt, ADPT, _flag) #define CHK_AND_SET_ADPT_FLAG(_flag) CHK_AND_SET_FLAG(adpt, ADPT, _flag) /* definitions for flags */ #define CHK_FLAG(_st, _type, _flag) \ test_bit((EMAC_##_type##_FLAG_##_flag), &((_st)->flags)) #define SET_FLAG(_st, _type, _flag) \ set_bit((EMAC_##_type##_FLAG_##_flag), &((_st)->flags)) #define CLI_FLAG(_st, _type, _flag) \ clear_bit((EMAC_##_type##_FLAG_##_flag), &((_st)->flags)) #define CHK_AND_SET_FLAG(_st, _type, _flag) \ test_and_set_bit((EMAC_##_type##_FLAG_##_flag), &((_st)->flags)) /* default to trying for four seconds */ #define EMAC_TRY_LINK_TIMEOUT (4 * HZ) Loading
drivers/net/ethernet/msm/emac/emac_ethtool.c +7 −7 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -148,7 +148,7 @@ static int emac_set_settings(struct net_device *netdev, emac_info(adpt, link, "ethtool cmd autoneg %d, speed %d, duplex %d\n", ecmd->autoneg, ecmd->speed, ecmd->duplex); while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ old = hw->autoneg_advertised; Loading @@ -163,7 +163,7 @@ static int emac_set_settings(struct net_device *netdev, if (ecmd->duplex != DUPLEX_FULL) { emac_warn(adpt, hw, "1000M half is invalid\n"); CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return -EINVAL; } advertised = EMAC_LINK_SPEED_1GB_FULL; Loading Loading @@ -202,7 +202,7 @@ static int emac_set_settings(struct net_device *netdev, } done: CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return retval; } Loading Loading @@ -236,7 +236,7 @@ static int emac_set_pauseparam(struct net_device *netdev, bool disable_fc_autoneg; int retval = 0; while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ req_fc_mode = hw->req_fc_mode; Loading @@ -256,7 +256,7 @@ static int emac_set_pauseparam(struct net_device *netdev, else if (!pause->rx_pause && !pause->tx_pause) req_fc_mode = emac_fc_none; else { CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return -EINVAL; } Loading @@ -273,7 +273,7 @@ static int emac_set_pauseparam(struct net_device *netdev, emac_hw_config_fc(hw); } CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return retval; } Loading
drivers/net/ethernet/msm/emac/emac_hw.c +7 −7 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -1024,22 +1024,22 @@ void emac_hw_config_mac_ctrl(struct emac_hw *hw) mac = emac_reg_r32(hw, EMAC, EMAC_MAC_CTRL); if (CHK_HW_FLAG(VLANSTRIP_EN)) if (TEST_FLAG(hw, HW_VLANSTRIP_EN)) mac |= VLAN_STRIP; else mac &= ~VLAN_STRIP; if (CHK_HW_FLAG(PROMISC_EN)) if (TEST_FLAG(hw, HW_PROMISC_EN)) mac |= PROM_MODE; else mac &= ~PROM_MODE; if (CHK_HW_FLAG(MULTIALL_EN)) if (TEST_FLAG(hw, HW_MULTIALL_EN)) mac |= MULTI_ALL; else mac &= ~MULTI_ALL; if (CHK_HW_FLAG(LOOPBACK_EN)) if (TEST_FLAG(hw, HW_LOOPBACK_EN)) mac |= MAC_LP_EN; else mac &= ~MAC_LP_EN; Loading Loading @@ -1376,7 +1376,7 @@ void emac_hw_config_mac(struct emac_hw *hw) emac_hw_config_rx_ctrl(hw); emac_hw_config_dma_ctrl(hw); if (CHK_HW_FLAG(PTP_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_config(hw); val = emac_reg_r32(hw, EMAC, EMAC_AXI_MAST_CTRL); Loading Loading @@ -1486,7 +1486,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_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_set_linkspeed(hw, hw->link_speed); emac_hw_config_mac_ctrl(hw); Loading
drivers/net/ethernet/msm/emac/emac_main.c +63 −62 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -153,11 +153,11 @@ void emac_reinit_locked(struct emac_adapter *adpt) { WARN_ON(in_interrupt()); while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ if (CHK_ADPT_FLAG(STATE_DOWN)) { CLI_ADPT_FLAG(STATE_RESETTING); if (TEST_FLAG(adpt, ADPT_STATE_DOWN)) { CLR_FLAG(adpt, ADPT_STATE_RESETTING); return; } Loading @@ -169,24 +169,24 @@ void emac_reinit_locked(struct emac_adapter *adpt) } emac_up(adpt); CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); } static void emac_task_schedule(struct emac_adapter *adpt) { if (!CHK_ADPT_FLAG(STATE_DOWN) && !CHK_ADPT_FLAG(STATE_WATCH_DOG)) { SET_ADPT_FLAG(STATE_WATCH_DOG); if (!TEST_FLAG(adpt, ADPT_STATE_DOWN) && !TEST_FLAG(adpt, ADPT_STATE_WATCH_DOG)) { SET_FLAG(adpt, ADPT_STATE_WATCH_DOG); schedule_work(&adpt->emac_task); } } static void emac_check_lsc(struct emac_adapter *adpt) { SET_ADPT_FLAG(TASK_LSC_REQ); SET_FLAG(adpt, ADPT_TASK_LSC_REQ); adpt->link_jiffies = jiffies + EMAC_TRY_LINK_TIMEOUT; if (!CHK_ADPT_FLAG(STATE_DOWN)) if (!TEST_FLAG(adpt, ADPT_STATE_DOWN)) emac_task_schedule(adpt); } Loading @@ -195,8 +195,8 @@ static void emac_tx_timeout(struct net_device *netdev) { struct emac_adapter *adpt = netdev_priv(netdev); if (!CHK_ADPT_FLAG(STATE_DOWN)) { SET_ADPT_FLAG(TASK_REINIT_REQ); if (!TEST_FLAG(adpt, ADPT_STATE_DOWN)) { SET_FLAG(adpt, ADPT_TASK_REINIT_REQ); emac_task_schedule(adpt); } } Loading @@ -210,13 +210,13 @@ static void emac_set_rx_mode(struct net_device *netdev) /* Check for Promiscuous and All Multicast modes */ if (netdev->flags & IFF_PROMISC) { SET_HW_FLAG(PROMISC_EN); SET_FLAG(hw, HW_PROMISC_EN); } else if (netdev->flags & IFF_ALLMULTI) { SET_HW_FLAG(MULTIALL_EN); CLI_HW_FLAG(PROMISC_EN); SET_FLAG(hw, HW_MULTIALL_EN); CLR_FLAG(hw, HW_PROMISC_EN); } else { CLI_HW_FLAG(MULTIALL_EN); CLI_HW_FLAG(PROMISC_EN); CLR_FLAG(hw, HW_MULTIALL_EN); CLR_FLAG(hw, HW_PROMISC_EN); } emac_hw_config_mac_ctrl(hw); Loading Loading @@ -533,7 +533,7 @@ static void emac_poll_hwtxtstamp(struct emac_adapter *adpt) static void emac_schedule_hwtxtstamp_task(struct emac_adapter *adpt) { if (CHK_ADPT_FLAG(STATE_DOWN)) if (TEST_FLAG(adpt, ADPT_STATE_DOWN)) return; if (schedule_work(&adpt->hwtxtstamp_task)) Loading Loading @@ -651,7 +651,7 @@ static void emac_handle_rx(struct emac_adapter *adpt, else skb_checksum_none_assert(skb); if (CHK_HW_FLAG(TS_RX_EN)) { if (TEST_FLAG(hw, HW_TS_RX_EN)) { struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); hwts->hwtstamp = ktime_set(srrd.genr.ts_high, Loading Loading @@ -929,7 +929,7 @@ static void emac_tx_map(struct emac_adapter *adpt, /* The last tpd */ emac_set_tpdesc_lastfrag(txque); if (CHK_HW_FLAG(TS_TX_EN) && if (TEST_FLAG(hw, HW_TS_TX_EN) && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { struct sk_buff *skb_ts = skb_clone(skb, GFP_ATOMIC); Loading Loading @@ -971,7 +971,7 @@ static int emac_start_xmit_frame(struct emac_adapter *adpt, union emac_sw_tpdesc stpd; u32 prod_idx; if (CHK_ADPT_FLAG(STATE_DOWN)) { if (TEST_FLAG(adpt, ADPT_STATE_DOWN)) { dev_kfree_skb_any(skb); return NETDEV_TX_OK; } Loading Loading @@ -1065,7 +1065,7 @@ static irqreturn_t emac_interrupt(int irq, void *data) emac_warn(adpt, intr, "isr error status 0x%x\n", status & ISR_ERROR); /* reset MAC */ SET_ADPT_FLAG(TASK_REINIT_REQ); SET_FLAG(adpt, ADPT_TASK_REINIT_REQ); emac_task_schedule(adpt); } Loading Loading @@ -1127,8 +1127,8 @@ static irqreturn_t emac_sgmii_interrupt(int irq, void *data) break; if (status & SGMII_PHY_INTERRUPT_ERR) { SET_ADPT_FLAG(TASK_CHK_SGMII_REQ); if (!CHK_ADPT_FLAG(STATE_DOWN)) SET_FLAG(adpt, ADPT_TASK_CHK_SGMII_REQ); if (!TEST_FLAG(adpt, ADPT_STATE_DOWN)) emac_task_schedule(adpt); } Loading @@ -1140,7 +1140,7 @@ static irqreturn_t emac_sgmii_interrupt(int irq, void *data) "failed to clear sgmii intr, status=0x%x\n", status); /* reset */ SET_ADPT_FLAG(TASK_REINIT_REQ); SET_FLAG(adpt, ADPT_TASK_REINIT_REQ); emac_task_schedule(adpt); break; } Loading Loading @@ -1184,9 +1184,9 @@ static int emac_set_features(struct net_device *netdev, netdev->features = features; if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) SET_HW_FLAG(VLANSTRIP_EN); SET_FLAG(hw, HW_VLANSTRIP_EN); else CLI_HW_FLAG(VLANSTRIP_EN); CLR_FLAG(hw, HW_VLANSTRIP_EN); if (netif_running(netdev)) emac_reinit_locked(adpt); Loading Loading @@ -1673,10 +1673,10 @@ int emac_up(struct emac_adapter *adpt) emac_enable_intr(adpt); netif_start_queue(netdev); CLI_ADPT_FLAG(STATE_DOWN); CLR_FLAG(adpt, ADPT_STATE_DOWN); /* check link status */ SET_ADPT_FLAG(TASK_LSC_REQ); SET_FLAG(adpt, ADPT_TASK_LSC_REQ); adpt->link_jiffies = jiffies + EMAC_TRY_LINK_TIMEOUT; mod_timer(&adpt->emac_timer, jiffies); Loading @@ -1697,7 +1697,7 @@ void emac_down(struct emac_adapter *adpt, u32 ctrl) unsigned long flags; int i; SET_ADPT_FLAG(STATE_DOWN); SET_FLAG(adpt, ADPT_STATE_DOWN); netif_stop_queue(netdev); netif_carrier_off(netdev); Loading @@ -1712,9 +1712,9 @@ void emac_down(struct emac_adapter *adpt, u32 ctrl) for (i = 0; (!adpt->no_mdio_gpio) && i < EMAC_NUM_GPIO; i++) gpio_free(adpt->gpio_info[i].gpio); CLI_ADPT_FLAG(TASK_LSC_REQ); CLI_ADPT_FLAG(TASK_REINIT_REQ); CLI_ADPT_FLAG(TASK_CHK_SGMII_REQ); CLR_FLAG(adpt, ADPT_TASK_LSC_REQ); CLR_FLAG(adpt, ADPT_TASK_REINIT_REQ); CLR_FLAG(adpt, ADPT_TASK_CHK_SGMII_REQ); del_timer_sync(&adpt->emac_timer); cancel_work_sync(&adpt->hwtxtstamp_task); Loading Loading @@ -1769,21 +1769,21 @@ static int emac_close(struct net_device *netdev) struct emac_hw *hw = &adpt->hw; /* ensure no task is running and no reset is in progress */ while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ pm_runtime_disable(netdev->dev.parent); if (!CHK_ADPT_FLAG(STATE_DOWN)) if (!TEST_FLAG(adpt, ADPT_STATE_DOWN)) emac_down(adpt, EMAC_HW_CTRL_RESET_MAC); else emac_hw_reset_mac(hw); if (CHK_HW_FLAG(PTP_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_stop(hw); emac_free_all_rtx_descriptor(adpt); CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return 0; } Loading Loading @@ -1877,7 +1877,7 @@ static int emac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) case SIOCSMIIREG: return emac_mii_ioctl(netdev, ifr, cmd); case SIOCSHWTSTAMP: if (CHK_HW_FLAG(PTP_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) return emac_tstamp_ioctl(netdev, ifr, cmd); default: return -EOPNOTSUPP; Loading Loading @@ -1977,11 +1977,12 @@ static const struct net_device_ops emac_netdev_ops = { /* Reinitialize the interface/HW if required */ static void emac_reinit_task_routine(struct emac_adapter *adpt) { if (!CHK_ADPT_FLAG(TASK_REINIT_REQ)) if (!TEST_FLAG(adpt, ADPT_TASK_REINIT_REQ)) return; CLI_ADPT_FLAG(TASK_REINIT_REQ); CLR_FLAG(adpt, ADPT_TASK_REINIT_REQ); if (CHK_ADPT_FLAG(STATE_DOWN) || CHK_ADPT_FLAG(STATE_RESETTING)) if (TEST_FLAG(adpt, ADPT_STATE_DOWN) || TEST_FLAG(adpt, ADPT_STATE_RESETTING)) return; emac_reinit_locked(adpt); Loading Loading @@ -2011,15 +2012,15 @@ static void emac_link_task_routine(struct emac_adapter *adpt) struct emac_hw *hw = &adpt->hw; char *link_desc; if (!CHK_ADPT_FLAG(TASK_LSC_REQ)) if (!TEST_FLAG(adpt, ADPT_TASK_LSC_REQ)) return; CLI_ADPT_FLAG(TASK_LSC_REQ); CLR_FLAG(adpt, ADPT_TASK_LSC_REQ); /* ensure that no reset is in progess while link task is running */ while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ if (CHK_ADPT_FLAG(STATE_DOWN)) if (TEST_FLAG(adpt, ADPT_STATE_DOWN)) goto link_task_done; emac_check_phy_link(hw, &hw->link_speed, &hw->link_up); Loading Loading @@ -2057,7 +2058,7 @@ static void emac_link_task_routine(struct emac_adapter *adpt) netif_wake_queue(netdev); } else { if (time_after(adpt->link_jiffies, jiffies)) SET_ADPT_FLAG(TASK_LSC_REQ); SET_FLAG(adpt, ADPT_TASK_LSC_REQ); /* only continue if link was up previously */ if (!netif_carrier_ok(netdev)) Loading @@ -2076,7 +2077,7 @@ static void emac_link_task_routine(struct emac_adapter *adpt) mod_timer(&adpt->emac_timer, jiffies); link_task_done: CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); } /* Check SGMII for error */ Loading @@ -2084,15 +2085,15 @@ static void emac_sgmii_task_routine(struct emac_adapter *adpt) { struct emac_hw *hw = &adpt->hw; if (!CHK_ADPT_FLAG(TASK_CHK_SGMII_REQ)) if (!TEST_FLAG(adpt, ADPT_TASK_CHK_SGMII_REQ)) return; CLI_ADPT_FLAG(TASK_CHK_SGMII_REQ); CLR_FLAG(adpt, ADPT_TASK_CHK_SGMII_REQ); /* ensure that no reset is in progess while link task is running */ while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ if (CHK_ADPT_FLAG(STATE_DOWN)) if (TEST_FLAG(adpt, ADPT_STATE_DOWN)) goto sgmii_task_done; if (emac_reg_r32(hw, EMAC_SGMII_PHY, EMAC_SGMII_PHY_RX_CHK_STATUS) Loading @@ -2102,7 +2103,7 @@ static void emac_sgmii_task_routine(struct emac_adapter *adpt) emac_err(adpt, "SGMII CDR not locked\n"); sgmii_task_done: CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); } /* Watchdog task routine */ Loading @@ -2111,7 +2112,7 @@ static void emac_task_routine(struct work_struct *work) struct emac_adapter *adpt = container_of(work, struct emac_adapter, emac_task); if (!CHK_ADPT_FLAG(STATE_WATCH_DOG)) if (!TEST_FLAG(adpt, ADPT_STATE_WATCH_DOG)) emac_warn(adpt, timer, "flag STATE_WATCH_DOG doesn't set\n"); emac_reinit_task_routine(adpt); Loading @@ -2120,7 +2121,7 @@ static void emac_task_routine(struct work_struct *work) emac_sgmii_task_routine(adpt); CLI_ADPT_FLAG(STATE_WATCH_DOG); CLR_FLAG(adpt, ADPT_STATE_WATCH_DOG); } /* Timer routine */ Loading @@ -2133,7 +2134,7 @@ static void emac_timer_routine(unsigned long data) return; /* poll faster when waiting for link */ if (CHK_ADPT_FLAG(TASK_LSC_REQ)) if (TEST_FLAG(adpt, ADPT_TASK_LSC_REQ)) delay = HZ / 10; else delay = 2 * HZ; Loading Loading @@ -2379,12 +2380,12 @@ static int emac_suspend(struct device *device) netif_device_detach(netdev); if (netif_running(netdev)) { /* ensure no task is running and no reset is in progress */ while (CHK_AND_SET_ADPT_FLAG(STATE_RESETTING)) while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ emac_down(adpt, 0); CLI_ADPT_FLAG(STATE_RESETTING); CLR_FLAG(adpt, ADPT_STATE_RESETTING); } emac_check_phy_link(hw, &speed, &link_up); Loading Loading @@ -2774,7 +2775,7 @@ static int emac_probe(struct platform_device *pdev) adpt->rfdesc_size = EMAC_RFDESC_SIZE; if (adpt->tstamp_en) SET_HW_FLAG(PTP_CAP); SET_FLAG(hw, HW_PTP_CAP); /* init netdev */ netdev->netdev_ops = &emac_netdev_ops; Loading Loading @@ -2838,8 +2839,8 @@ static int emac_probe(struct platform_device *pdev) skb_queue_head_init(&adpt->hwtxtstamp_ready_queue); INIT_WORK(&adpt->hwtxtstamp_task, emac_hwtxtstamp_task_routine); SET_HW_FLAG(VLANSTRIP_EN); SET_ADPT_FLAG(STATE_DOWN); SET_FLAG(hw, HW_VLANSTRIP_EN); SET_FLAG(adpt, ADPT_STATE_DOWN); strlcpy(netdev->name, "eth%d", sizeof(netdev->name)); retval = register_netdev(netdev); Loading @@ -2848,7 +2849,7 @@ static int emac_probe(struct platform_device *pdev) goto err_register_netdev; } if (CHK_HW_FLAG(PTP_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_init(adpt->netdev); pr_info("%s - version %s\n", emac_drv_description, emac_drv_version); Loading Loading @@ -2882,7 +2883,7 @@ static int emac_remove(struct platform_device *pdev) pr_info("exiting %s\n", emac_drv_name); unregister_netdev(netdev); if (CHK_HW_FLAG(PTP_CAP)) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_remove(netdev); emac_disable_clks(adpt); Loading
drivers/net/ethernet/msm/emac/emac_ptp.c +22 −22 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -189,12 +189,12 @@ static int emac_hw_config_tx_tstamp(struct emac_hw *hw, bool enable) emac_reg_update32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_CSR1, TX_TS_ENABLE, TX_TS_ENABLE); wmb(); SET_HW_FLAG(TS_TX_EN); SET_FLAG(hw, HW_TS_TX_EN); } else { emac_reg_update32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_CSR1, TX_TS_ENABLE, 0); wmb(); CLI_HW_FLAG(TS_TX_EN); CLR_FLAG(hw, HW_TS_TX_EN); } return 0; Loading @@ -211,9 +211,9 @@ static int emac_hw_config_rx_tstamp(struct emac_hw *hw, bool enable) TS_RX_FIFO_SYNC_RST, 0); wmb(); SET_HW_FLAG(TS_RX_EN); SET_FLAG(hw, HW_TS_RX_EN); } else { CLI_HW_FLAG(TS_RX_EN); CLR_FLAG(hw, HW_TS_RX_EN); } return 0; Loading @@ -221,9 +221,9 @@ static int emac_hw_config_rx_tstamp(struct emac_hw *hw, bool enable) static int emac_hw_1588_core_disable(struct emac_hw *hw) { if (CHK_HW_FLAG(TS_RX_EN)) if (TEST_FLAG(hw, HW_TS_RX_EN)) emac_hw_config_rx_tstamp(hw, false); if (CHK_HW_FLAG(TS_TX_EN)) if (TEST_FLAG(hw, HW_TS_TX_EN)) emac_hw_config_tx_tstamp(hw, false); emac_reg_update32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_CSR1, Loading @@ -235,7 +235,7 @@ static int emac_hw_1588_core_disable(struct emac_hw *hw) emac_reg_w32(hw, EMAC_1588, EMAC_P1588_PTP_EXPANDED_INT_MASK, 0); wmb(); CLI_HW_FLAG(PTP_EN); CLR_FLAG(hw, HW_PTP_EN); return 0; } Loading Loading @@ -297,7 +297,7 @@ static int emac_hw_1588_core_enable(struct emac_hw *hw, GRANDMASTER_MODE | GM_PPS_SYNC, 0); wmb(); SET_HW_FLAG(PTP_EN); SET_FLAG(hw, HW_PTP_EN); return 0; } Loading Loading @@ -401,7 +401,7 @@ int emac_ptp_config(struct emac_hw *hw) spin_lock_irqsave(&hw->ptp_lock, flag); if (CHK_HW_FLAG(PTP_EN)) if (TEST_FLAG(hw, HW_PTP_EN)) goto unlock_out; hw->frac_ns_adj = get_frac_ns_adj_from_tbl(hw); Loading Loading @@ -432,7 +432,7 @@ int emac_ptp_stop(struct emac_hw *hw) spin_lock_irqsave(&hw->ptp_lock, flag); if (CHK_HW_FLAG(PTP_EN)) if (TEST_FLAG(hw, HW_PTP_EN)) ret = emac_hw_1588_core_disable(hw); hw->ptp_intr_mask = 0; Loading Loading @@ -477,7 +477,7 @@ static int emac_ptp_settime(struct emac_hw *hw, const struct timespec *ts) unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) ret = -EPERM; else rtc_settime(hw, ts); Loading @@ -492,7 +492,7 @@ static int emac_ptp_gettime(struct emac_hw *hw, struct timespec *ts) unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) ret = -EPERM; else rtc_gettime(hw, ts); Loading @@ -507,7 +507,7 @@ int emac_ptp_adjtime(struct emac_hw *hw, s64 delta) unsigned long flag; spin_lock_irqsave(&hw->ptp_lock, flag); if (!CHK_HW_FLAG(PTP_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) ret = -EPERM; else rtc_adjtime(hw, delta); Loading @@ -522,7 +522,7 @@ 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_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) return -EPERM; if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) Loading @@ -533,7 +533,7 @@ int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) emac_hw_config_tx_tstamp(hw, false); break; case HWTSTAMP_TX_ON: if (CHK_HW_FLAG(TS_TX_EN)) if (TEST_FLAG(hw, HW_TS_TX_EN)) break; emac_hw_config_tx_tstamp(hw, true); Loading @@ -548,7 +548,7 @@ int emac_tstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) break; default: cfg.rx_filter = HWTSTAMP_FILTER_ALL; if (CHK_HW_FLAG(TS_RX_EN)) if (TEST_FLAG(hw, HW_TS_RX_EN)) break; emac_hw_config_rx_tstamp(hw, true); Loading Loading @@ -758,9 +758,9 @@ static int emac_ptp_sysfs_mode_set( if (mode == hw->ptp_mode) goto out; if (CHK_HW_FLAG(PTP_EN)) { bool rx_tstamp_enable = CHK_HW_FLAG(TS_RX_EN); bool tx_tstamp_enable = CHK_HW_FLAG(TS_TX_EN); if (TEST_FLAG(hw, HW_PTP_EN)) { bool rx_tstamp_enable = TEST_FLAG(hw, HW_TS_RX_EN); bool tx_tstamp_enable = TEST_FLAG(hw, HW_TS_TX_EN); emac_hw_1588_core_disable(hw); emac_hw_1588_core_enable(hw, mode, hw->ptp_clk_mode, Loading Loading @@ -791,7 +791,7 @@ static int emac_ptp_sysfs_frac_ns_adj_show( int count = PAGE_SIZE; int retval; if (!CHK_HW_FLAG(PTP_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) return -EPERM; retval = scnprintf(buf, count, "%d\n", adpt->hw.frac_ns_adj); Loading @@ -809,7 +809,7 @@ static int emac_ptp_sysfs_frac_ns_adj_set( struct emac_hw *hw = &adpt->hw; s32 adj; if (!CHK_HW_FLAG(PTP_EN)) if (!TEST_FLAG(hw, HW_PTP_EN)) return -EPERM; if (kstrtos32(buf, 0, &adj)) Loading