Loading drivers/net/ethernet/msm/emac/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -4,4 +4,4 @@ obj-$(CONFIG_MSM_EMAC) += msm_emac.o msm_emac-objs := emac_main.o emac_hw.o emac_ethtool.o msm_emac-objs := emac_main.o emac_hw.o emac_ethtool.o emac_ptp.o drivers/net/ethernet/msm/emac/emac.h +17 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,17 @@ enum emac_fc_mode { emac_fc_default }; /* IEEE1588 */ enum emac_ptp_clk_mode { emac_ptp_clk_mode_oc_two_step, emac_ptp_clk_mode_oc_one_step }; enum emac_ptp_mode { emac_ptp_mode_slave, emac_ptp_mode_master }; struct emac_hw_stats { /* rx */ u64 rx_ok; /* good packets */ Loading Loading @@ -200,6 +211,11 @@ struct emac_hw { #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) Loading Loading @@ -431,6 +447,7 @@ union emac_sw_tpdesc { ((_que)->tpd.tpdesc + (_size * (_i))) #define EMAC_TPD_LAST_FRAGMENT 0x80000000 #define EMAC_TPD_TSTAMP_SAVE 0x80000000 /* emac_ring_header represents a single, contiguous block of DMA space * mapped for the three descriptor rings (tpd, rfd, rrd) Loading drivers/net/ethernet/msm/emac/emac_defines.h +72 −0 Original line number Diff line number Diff line Loading @@ -267,10 +267,82 @@ #define H1TPD_PROD_IDX_SHFT 0 /* EMAC_EMAC_WRAPPER_CSR1 */ #define TX_TS_ENABLE 0x10000 #define DIS_1588_CLKS 0x800 #define FREQ_MODE 0x200 #define ENABLE_RRD_TIMESTAMP 0x8 /* EMAC_EMAC_WRAPPER_CSR2 */ #define WOL_EN 0x80 /* EMAC_EMAC_WRAPPER_CSR10 */ #define RD_CLR_1588 0x2 #define DIS_1588 0x1 /* EMAC_EMAC_WRAPPER_TX_TS_INX */ #define EMAC_WRAPPER_TX_TS_EMPTY 0x80000000 #define EMAC_WRAPPER_TX_TS_INX_BMSK 0xffff /* EMAC_P1588_CTRL_REG */ #define ATTACH_EN 0x10 #define BYPASS_O 0x8 #define CLOCK_MODE_BMSK 0x6 #define CLOCK_MODE_SHFT 1 #define ETH_MODE_SW 0x1 /* EMAC_P1588_INC_VALUE_2 */ #define INC_VALUE_2_BMSK 0xffff /* EMAC_P1588_INC_VALUE_1 */ #define INC_VALUE_1_BMSK 0xffff /* EMAC_P1588_NANO_OFFSET_2 */ #define NANO_OFFSET_2_BMSK 0xffff /* EMAC_P1588_NANO_OFFSET_1 */ #define NANO_OFFSET_1_BMSK 0xffff /* EMAC_P1588_SEC_OFFSET_2 */ #define SEC_OFFSET_2_BMSK 0xffff /* EMAC_P1588_SEC_OFFSET_1 */ #define SEC_OFFSET_1_BMSK 0xffff /* EMAC_P1588_REAL_TIME_5 */ #define REAL_TIME_5_BMSK 0xffff #define REAL_TIME_5_SHFT 0 /* EMAC_P1588_REAL_TIME_4 */ #define REAL_TIME_4_BMSK 0xffff #define REAL_TIME_4_SHFT 0 /* EMAC_P1588_REAL_TIME_3 */ #define REAL_TIME_3_BMSK 0xffff #define REAL_TIME_3_SHFT 0 /* EMAC_P1588_REAL_TIME_2 */ #define REAL_TIME_2_BMSK 0xffff #define REAL_TIME_2_SHFT 0 /* EMAC_P1588_REAL_TIME_1 */ #define REAL_TIME_1_BMSK 0xffff #define REAL_TIME_1_SHFT 0 /* EMAC_P1588_RTC_EXPANDED_CONFIG */ #define RTC_READ_MODE 0x20 #define RTC_SNAPSHOT 0x10 #define LOAD_RTC 0x1 /* EMAC_P1588_RTC_PRELOADED_4 */ #define RTC_PRELOADED_4_BMSK 0xffff /* EMAC_P1588_RTC_PRELOADED_3 */ #define RTC_PRELOADED_3_BMSK 0xffff /* EMAC_P1588_RTC_PRELOADED_2 */ #define RTC_PRELOADED_2_BMSK 0xffff /* EMAC_P1588_RTC_PRELOADED_1 */ #define RTC_PRELOADED_1_BMSK 0xffff #endif /* __EMAC_DEFINES_H__ */ drivers/net/ethernet/msm/emac/emac_hw.c +12 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/if_vlan.h> #include "emac_hw.h" #include "emac_ptp.h" #define RFD_PREF_LOW_TH 0x10 #define RFD_PREF_UP_TH 0x10 Loading Loading @@ -339,6 +340,7 @@ void emac_hw_disable_intr(struct emac_hw *hw) { emac_reg_w32(hw, EMAC, EMAC_INT_STATUS, DIS_INT); emac_reg_w32(hw, EMAC, EMAC_INT_MASK, 0); emac_reg_w32(hw, EMAC_1588, EMAC_P1588_PTP_EXPANDED_INT_MASK, 0); wmb(); } Loading Loading @@ -777,6 +779,9 @@ 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)) emac_ptp_config(hw); val = emac_reg_r32(hw, EMAC, EMAC_AXI_MAST_CTRL); val &= ~(DATA_BYTE_SWAP | MAX_BOUND); val |= MAX_BTYPE; Loading Loading @@ -864,6 +869,13 @@ void emac_hw_start_mac(struct emac_hw *hw) /* clear all interrupts, set interrupt read clear */ emac_reg_w32(hw, EMAC, EMAC_DMA_MAS_CTRL, INT_RD_CLR_EN); if (CHK_HW_FLAG(PTP_EN)) { if (hw->link_speed == EMAC_LINK_SPEED_1GB_FULL) emac_ptp_set_linkspeed(hw, emac_mac_speed_1000); else emac_ptp_set_linkspeed(hw, emac_mac_speed_10_100); } emac_hw_config_mac_ctrl(hw); emac_reg_update32(hw, EMAC, EMAC_ATHR_HEADER_CTRL, Loading drivers/net/ethernet/msm/emac/emac_main.c +81 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "emac.h" #include "emac_hw.h" #include "emac_ptp.h" #define DRV_VERSION "1.0.0.0" Loading Loading @@ -265,6 +266,19 @@ static void emac_set_tpdesc_lastfrag(struct emac_tx_queue *txque) writel_relaxed(tmp_tpd, htpd + 1); } void emac_set_tpdesc_tstamp_sav(struct emac_tx_queue *txque) { struct emac_adapter *adpt = netdev_priv(txque->netdev); u32 tmp_tpd; u32 *htpd = EMAC_TPD(txque, adpt->tpdesc_size, txque->tpd.last_produce_idx); tmp_tpd = readl_relaxed(htpd + 3); tmp_tpd |= EMAC_TPD_TSTAMP_SAVE; writel_relaxed(tmp_tpd, htpd + 3); wmb(); } /* Fill up receive queue's RFD with preallocated receive buffers */ static int emac_refresh_rx_buffer(struct emac_rx_queue *rxque) { Loading Loading @@ -345,6 +359,42 @@ static void emac_clean_rfdesc(struct emac_rx_queue *rxque, rxque->rfd.process_idx = consume_idx; } static void emac_read_tx_tstamp_fifo(struct emac_hw *hw, struct emac_tx_queue *txque) { struct emac_buffer *tpbuf; u32 ts_idx = 0; u32 sec, ns; while (1) { ts_idx = emac_reg_r32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_TX_TS_INX); if (ts_idx & EMAC_WRAPPER_TX_TS_EMPTY) break; ns = emac_reg_r32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_TX_TS_LO); sec = emac_reg_r32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_TX_TS_HI); ts_idx &= EMAC_WRAPPER_TX_TS_INX_BMSK; if ((ts_idx < txque->tpd.consume_idx) || (ts_idx > txque->tpd.last_produce_idx)) { emac_warn(hw->adpt, tx_done, "zombie timestamp desc idx %d\n", ts_idx); continue; } tpbuf = GET_TPD_BUFFER(txque, ts_idx); if (tpbuf->skb && (skb_shinfo(tpbuf->skb)->tx_flags & SKBTX_HW_TSTAMP)) { struct skb_shared_hwtstamps ts; ts.hwtstamp = ktime_set(sec, ns); skb_tstamp_tx(tpbuf->skb, &ts); } } } /* Process receive event */ static void emac_handle_rx(struct emac_adapter *adpt, struct emac_rx_queue *rxque, Loading Loading @@ -401,6 +451,14 @@ static void emac_handle_rx(struct emac_adapter *adpt, skb->ip_summed = CHECKSUM_NONE; skb->dev = netdev; skb->protocol = eth_type_trans(skb, skb->dev); if (CHK_HW_FLAG(TS_RX_EN)) { struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); hwts->hwtstamp = ktime_set(srrd.genr.ts_high, srrd.genr.ts_low); } emac_receive_skb(rxque, skb, (u16)srrd.genr.cvlan_tag, (bool)srrd.genr.cvlan_flag); Loading Loading @@ -439,6 +497,7 @@ static void emac_handle_tx(struct emac_adapter *adpt, txque->que_idx, hw_consume_idx); while (txque->tpd.consume_idx != hw_consume_idx) { emac_read_tx_tstamp_fifo(hw, txque); tpbuf = GET_TPD_BUFFER(txque, txque->tpd.consume_idx); if (tpbuf->dma) { dma_unmap_single(txque->dev, tpbuf->dma, tpbuf->length, Loading Loading @@ -608,6 +667,7 @@ static void emac_tx_map(struct emac_adapter *adpt, struct sk_buff *skb, union emac_sw_tpdesc *stpd) { struct emac_hw *hw = &adpt->hw; struct emac_buffer *tpbuf = NULL; u16 nr_frags = skb_shinfo(skb)->nr_frags; u32 len = skb_headlen(skb); Loading @@ -628,7 +688,6 @@ static void emac_tx_map(struct emac_adapter *adpt, stpd->genr.addr_lo = EMAC_DMA_ADDR_LO(tpbuf->dma); stpd->genr.addr_hi = EMAC_DMA_ADDR_HI(tpbuf->dma); stpd->genr.buffer_len = tpbuf->length; emac_set_tpdesc(txque, stpd); } Loading Loading @@ -663,6 +722,12 @@ static void emac_tx_map(struct emac_adapter *adpt, /* The last tpd */ emac_set_tpdesc_lastfrag(txque); if (CHK_HW_FLAG(TS_TX_EN) && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { emac_set_tpdesc_tstamp_sav(txque); skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; } /* The last buffer info contain the skb address, * so it will be freed after unmap */ Loading Loading @@ -1385,6 +1450,7 @@ err_alloc_rtx: static int emac_close(struct net_device *netdev) { struct emac_adapter *adpt = netdev_priv(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)) Loading @@ -1395,6 +1461,9 @@ static int emac_close(struct net_device *netdev) else emac_hw_reset_mac(hw); if (CHK_HW_FLAG(PTP_CAP)) emac_ptp_stop(hw); emac_free_all_rtx_descriptor(adpt); CLI_ADPT_FLAG(STATE_RESETTING); Loading Loading @@ -1459,6 +1528,8 @@ static int emac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) case SIOCGMIIREG: case SIOCSMIIREG: return emac_mii_ioctl(netdev, ifr, cmd); case SIOCSHWTSTAMP: return emac_tstamp_ioctl(netdev, ifr, cmd); default: return -EOPNOTSUPP; } Loading Loading @@ -1849,6 +1920,9 @@ 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 Loading Loading @@ -2057,7 +2131,7 @@ static int emac_probe(struct platform_device *pdev) dma_set_max_seg_size(&pdev->dev, 65536); dma_set_seg_boundary(&pdev->dev, 0xffffffff); adpt->tstamp_en = false; adpt->tstamp_en = true; retval = emac_get_resources(pdev, adpt); if (retval) goto err_res; Loading @@ -2075,6 +2149,11 @@ static int emac_probe(struct platform_device *pdev) adpt->tpdesc_size = EMAC_TPDESC_SIZE; adpt->rfdesc_size = EMAC_RFDESC_SIZE; if (adpt->tstamp_en) { hw->rtc_ref_clkrate = DEFAULT_RTC_REF_CLKRATE; SET_HW_FLAG(PTP_CAP); } /* init netdev */ netdev->netdev_ops = &emac_netdev_ops; Loading Loading
drivers/net/ethernet/msm/emac/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -4,4 +4,4 @@ obj-$(CONFIG_MSM_EMAC) += msm_emac.o msm_emac-objs := emac_main.o emac_hw.o emac_ethtool.o msm_emac-objs := emac_main.o emac_hw.o emac_ethtool.o emac_ptp.o
drivers/net/ethernet/msm/emac/emac.h +17 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,17 @@ enum emac_fc_mode { emac_fc_default }; /* IEEE1588 */ enum emac_ptp_clk_mode { emac_ptp_clk_mode_oc_two_step, emac_ptp_clk_mode_oc_one_step }; enum emac_ptp_mode { emac_ptp_mode_slave, emac_ptp_mode_master }; struct emac_hw_stats { /* rx */ u64 rx_ok; /* good packets */ Loading Loading @@ -200,6 +211,11 @@ struct emac_hw { #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) Loading Loading @@ -431,6 +447,7 @@ union emac_sw_tpdesc { ((_que)->tpd.tpdesc + (_size * (_i))) #define EMAC_TPD_LAST_FRAGMENT 0x80000000 #define EMAC_TPD_TSTAMP_SAVE 0x80000000 /* emac_ring_header represents a single, contiguous block of DMA space * mapped for the three descriptor rings (tpd, rfd, rrd) Loading
drivers/net/ethernet/msm/emac/emac_defines.h +72 −0 Original line number Diff line number Diff line Loading @@ -267,10 +267,82 @@ #define H1TPD_PROD_IDX_SHFT 0 /* EMAC_EMAC_WRAPPER_CSR1 */ #define TX_TS_ENABLE 0x10000 #define DIS_1588_CLKS 0x800 #define FREQ_MODE 0x200 #define ENABLE_RRD_TIMESTAMP 0x8 /* EMAC_EMAC_WRAPPER_CSR2 */ #define WOL_EN 0x80 /* EMAC_EMAC_WRAPPER_CSR10 */ #define RD_CLR_1588 0x2 #define DIS_1588 0x1 /* EMAC_EMAC_WRAPPER_TX_TS_INX */ #define EMAC_WRAPPER_TX_TS_EMPTY 0x80000000 #define EMAC_WRAPPER_TX_TS_INX_BMSK 0xffff /* EMAC_P1588_CTRL_REG */ #define ATTACH_EN 0x10 #define BYPASS_O 0x8 #define CLOCK_MODE_BMSK 0x6 #define CLOCK_MODE_SHFT 1 #define ETH_MODE_SW 0x1 /* EMAC_P1588_INC_VALUE_2 */ #define INC_VALUE_2_BMSK 0xffff /* EMAC_P1588_INC_VALUE_1 */ #define INC_VALUE_1_BMSK 0xffff /* EMAC_P1588_NANO_OFFSET_2 */ #define NANO_OFFSET_2_BMSK 0xffff /* EMAC_P1588_NANO_OFFSET_1 */ #define NANO_OFFSET_1_BMSK 0xffff /* EMAC_P1588_SEC_OFFSET_2 */ #define SEC_OFFSET_2_BMSK 0xffff /* EMAC_P1588_SEC_OFFSET_1 */ #define SEC_OFFSET_1_BMSK 0xffff /* EMAC_P1588_REAL_TIME_5 */ #define REAL_TIME_5_BMSK 0xffff #define REAL_TIME_5_SHFT 0 /* EMAC_P1588_REAL_TIME_4 */ #define REAL_TIME_4_BMSK 0xffff #define REAL_TIME_4_SHFT 0 /* EMAC_P1588_REAL_TIME_3 */ #define REAL_TIME_3_BMSK 0xffff #define REAL_TIME_3_SHFT 0 /* EMAC_P1588_REAL_TIME_2 */ #define REAL_TIME_2_BMSK 0xffff #define REAL_TIME_2_SHFT 0 /* EMAC_P1588_REAL_TIME_1 */ #define REAL_TIME_1_BMSK 0xffff #define REAL_TIME_1_SHFT 0 /* EMAC_P1588_RTC_EXPANDED_CONFIG */ #define RTC_READ_MODE 0x20 #define RTC_SNAPSHOT 0x10 #define LOAD_RTC 0x1 /* EMAC_P1588_RTC_PRELOADED_4 */ #define RTC_PRELOADED_4_BMSK 0xffff /* EMAC_P1588_RTC_PRELOADED_3 */ #define RTC_PRELOADED_3_BMSK 0xffff /* EMAC_P1588_RTC_PRELOADED_2 */ #define RTC_PRELOADED_2_BMSK 0xffff /* EMAC_P1588_RTC_PRELOADED_1 */ #define RTC_PRELOADED_1_BMSK 0xffff #endif /* __EMAC_DEFINES_H__ */
drivers/net/ethernet/msm/emac/emac_hw.c +12 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/if_vlan.h> #include "emac_hw.h" #include "emac_ptp.h" #define RFD_PREF_LOW_TH 0x10 #define RFD_PREF_UP_TH 0x10 Loading Loading @@ -339,6 +340,7 @@ void emac_hw_disable_intr(struct emac_hw *hw) { emac_reg_w32(hw, EMAC, EMAC_INT_STATUS, DIS_INT); emac_reg_w32(hw, EMAC, EMAC_INT_MASK, 0); emac_reg_w32(hw, EMAC_1588, EMAC_P1588_PTP_EXPANDED_INT_MASK, 0); wmb(); } Loading Loading @@ -777,6 +779,9 @@ 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)) emac_ptp_config(hw); val = emac_reg_r32(hw, EMAC, EMAC_AXI_MAST_CTRL); val &= ~(DATA_BYTE_SWAP | MAX_BOUND); val |= MAX_BTYPE; Loading Loading @@ -864,6 +869,13 @@ void emac_hw_start_mac(struct emac_hw *hw) /* clear all interrupts, set interrupt read clear */ emac_reg_w32(hw, EMAC, EMAC_DMA_MAS_CTRL, INT_RD_CLR_EN); if (CHK_HW_FLAG(PTP_EN)) { if (hw->link_speed == EMAC_LINK_SPEED_1GB_FULL) emac_ptp_set_linkspeed(hw, emac_mac_speed_1000); else emac_ptp_set_linkspeed(hw, emac_mac_speed_10_100); } emac_hw_config_mac_ctrl(hw); emac_reg_update32(hw, EMAC, EMAC_ATHR_HEADER_CTRL, Loading
drivers/net/ethernet/msm/emac/emac_main.c +81 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "emac.h" #include "emac_hw.h" #include "emac_ptp.h" #define DRV_VERSION "1.0.0.0" Loading Loading @@ -265,6 +266,19 @@ static void emac_set_tpdesc_lastfrag(struct emac_tx_queue *txque) writel_relaxed(tmp_tpd, htpd + 1); } void emac_set_tpdesc_tstamp_sav(struct emac_tx_queue *txque) { struct emac_adapter *adpt = netdev_priv(txque->netdev); u32 tmp_tpd; u32 *htpd = EMAC_TPD(txque, adpt->tpdesc_size, txque->tpd.last_produce_idx); tmp_tpd = readl_relaxed(htpd + 3); tmp_tpd |= EMAC_TPD_TSTAMP_SAVE; writel_relaxed(tmp_tpd, htpd + 3); wmb(); } /* Fill up receive queue's RFD with preallocated receive buffers */ static int emac_refresh_rx_buffer(struct emac_rx_queue *rxque) { Loading Loading @@ -345,6 +359,42 @@ static void emac_clean_rfdesc(struct emac_rx_queue *rxque, rxque->rfd.process_idx = consume_idx; } static void emac_read_tx_tstamp_fifo(struct emac_hw *hw, struct emac_tx_queue *txque) { struct emac_buffer *tpbuf; u32 ts_idx = 0; u32 sec, ns; while (1) { ts_idx = emac_reg_r32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_TX_TS_INX); if (ts_idx & EMAC_WRAPPER_TX_TS_EMPTY) break; ns = emac_reg_r32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_TX_TS_LO); sec = emac_reg_r32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_TX_TS_HI); ts_idx &= EMAC_WRAPPER_TX_TS_INX_BMSK; if ((ts_idx < txque->tpd.consume_idx) || (ts_idx > txque->tpd.last_produce_idx)) { emac_warn(hw->adpt, tx_done, "zombie timestamp desc idx %d\n", ts_idx); continue; } tpbuf = GET_TPD_BUFFER(txque, ts_idx); if (tpbuf->skb && (skb_shinfo(tpbuf->skb)->tx_flags & SKBTX_HW_TSTAMP)) { struct skb_shared_hwtstamps ts; ts.hwtstamp = ktime_set(sec, ns); skb_tstamp_tx(tpbuf->skb, &ts); } } } /* Process receive event */ static void emac_handle_rx(struct emac_adapter *adpt, struct emac_rx_queue *rxque, Loading Loading @@ -401,6 +451,14 @@ static void emac_handle_rx(struct emac_adapter *adpt, skb->ip_summed = CHECKSUM_NONE; skb->dev = netdev; skb->protocol = eth_type_trans(skb, skb->dev); if (CHK_HW_FLAG(TS_RX_EN)) { struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); hwts->hwtstamp = ktime_set(srrd.genr.ts_high, srrd.genr.ts_low); } emac_receive_skb(rxque, skb, (u16)srrd.genr.cvlan_tag, (bool)srrd.genr.cvlan_flag); Loading Loading @@ -439,6 +497,7 @@ static void emac_handle_tx(struct emac_adapter *adpt, txque->que_idx, hw_consume_idx); while (txque->tpd.consume_idx != hw_consume_idx) { emac_read_tx_tstamp_fifo(hw, txque); tpbuf = GET_TPD_BUFFER(txque, txque->tpd.consume_idx); if (tpbuf->dma) { dma_unmap_single(txque->dev, tpbuf->dma, tpbuf->length, Loading Loading @@ -608,6 +667,7 @@ static void emac_tx_map(struct emac_adapter *adpt, struct sk_buff *skb, union emac_sw_tpdesc *stpd) { struct emac_hw *hw = &adpt->hw; struct emac_buffer *tpbuf = NULL; u16 nr_frags = skb_shinfo(skb)->nr_frags; u32 len = skb_headlen(skb); Loading @@ -628,7 +688,6 @@ static void emac_tx_map(struct emac_adapter *adpt, stpd->genr.addr_lo = EMAC_DMA_ADDR_LO(tpbuf->dma); stpd->genr.addr_hi = EMAC_DMA_ADDR_HI(tpbuf->dma); stpd->genr.buffer_len = tpbuf->length; emac_set_tpdesc(txque, stpd); } Loading Loading @@ -663,6 +722,12 @@ static void emac_tx_map(struct emac_adapter *adpt, /* The last tpd */ emac_set_tpdesc_lastfrag(txque); if (CHK_HW_FLAG(TS_TX_EN) && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { emac_set_tpdesc_tstamp_sav(txque); skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; } /* The last buffer info contain the skb address, * so it will be freed after unmap */ Loading Loading @@ -1385,6 +1450,7 @@ err_alloc_rtx: static int emac_close(struct net_device *netdev) { struct emac_adapter *adpt = netdev_priv(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)) Loading @@ -1395,6 +1461,9 @@ static int emac_close(struct net_device *netdev) else emac_hw_reset_mac(hw); if (CHK_HW_FLAG(PTP_CAP)) emac_ptp_stop(hw); emac_free_all_rtx_descriptor(adpt); CLI_ADPT_FLAG(STATE_RESETTING); Loading Loading @@ -1459,6 +1528,8 @@ static int emac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) case SIOCGMIIREG: case SIOCSMIIREG: return emac_mii_ioctl(netdev, ifr, cmd); case SIOCSHWTSTAMP: return emac_tstamp_ioctl(netdev, ifr, cmd); default: return -EOPNOTSUPP; } Loading Loading @@ -1849,6 +1920,9 @@ 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 Loading Loading @@ -2057,7 +2131,7 @@ static int emac_probe(struct platform_device *pdev) dma_set_max_seg_size(&pdev->dev, 65536); dma_set_seg_boundary(&pdev->dev, 0xffffffff); adpt->tstamp_en = false; adpt->tstamp_en = true; retval = emac_get_resources(pdev, adpt); if (retval) goto err_res; Loading @@ -2075,6 +2149,11 @@ static int emac_probe(struct platform_device *pdev) adpt->tpdesc_size = EMAC_TPDESC_SIZE; adpt->rfdesc_size = EMAC_RFDESC_SIZE; if (adpt->tstamp_en) { hw->rtc_ref_clkrate = DEFAULT_RTC_REF_CLKRATE; SET_HW_FLAG(PTP_CAP); } /* init netdev */ netdev->netdev_ops = &emac_netdev_ops; Loading