Merge branch 'enetc-ptp'
Yangbo Lu says: ==================== enetc: support PTP Sync packet one-step timestamping This patch-set is to add support for PTP Sync packet one-step timestamping. Since ENETC single-step register has to be configured dynamically per packet for correctionField offeset and UDP checksum update, current one-step timestamping packet has to be sent only when the last one completes transmitting on hardware. So, on the TX, this patch handles one-step timestamping packet as below: - Trasmit packet immediately if no other one in transfer, or queue to skb queue if there is already one in transfer. The test_and_set_bit_lock() is used here to lock and check state. - Start a work when complete transfer on hardware, to release the bit lock and to send one skb in skb queue if has. Changes for v2: - Rebased. - Fixed issues from patchwork checks. - netif_tx_lock for one-step timestamping packet sending. Changes for v3: - Used system workqueue. - Set bit lock when transmitted one-step packet, and scheduled work when completed. The worker cleared the bit lock, and transmitted one skb in skb queue if has, instead of a loop. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
d27139c544
|
@ -6,6 +6,7 @@
|
||||||
#include <linux/tcp.h>
|
#include <linux/tcp.h>
|
||||||
#include <linux/udp.h>
|
#include <linux/udp.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/ptp_classify.h>
|
||||||
#include <net/pkt_sched.h>
|
#include <net/pkt_sched.h>
|
||||||
|
|
||||||
static struct sk_buff *enetc_tx_swbd_get_skb(struct enetc_tx_swbd *tx_swbd)
|
static struct sk_buff *enetc_tx_swbd_get_skb(struct enetc_tx_swbd *tx_swbd)
|
||||||
|
@ -67,16 +68,52 @@ static void enetc_update_tx_ring_tail(struct enetc_bdr *tx_ring)
|
||||||
enetc_wr_reg_hot(tx_ring->tpir, tx_ring->next_to_use);
|
enetc_wr_reg_hot(tx_ring->tpir, tx_ring->next_to_use);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb,
|
static int enetc_ptp_parse(struct sk_buff *skb, u8 *udp,
|
||||||
int active_offloads)
|
u8 *msgtype, u8 *twostep,
|
||||||
|
u16 *correction_offset, u16 *body_offset)
|
||||||
{
|
{
|
||||||
|
unsigned int ptp_class;
|
||||||
|
struct ptp_header *hdr;
|
||||||
|
unsigned int type;
|
||||||
|
u8 *base;
|
||||||
|
|
||||||
|
ptp_class = ptp_classify_raw(skb);
|
||||||
|
if (ptp_class == PTP_CLASS_NONE)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
hdr = ptp_parse_header(skb, ptp_class);
|
||||||
|
if (!hdr)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
type = ptp_class & PTP_CLASS_PMASK;
|
||||||
|
if (type == PTP_CLASS_IPV4 || type == PTP_CLASS_IPV6)
|
||||||
|
*udp = 1;
|
||||||
|
else
|
||||||
|
*udp = 0;
|
||||||
|
|
||||||
|
*msgtype = ptp_get_msgtype(hdr, ptp_class);
|
||||||
|
*twostep = hdr->flag_field[0] & 0x2;
|
||||||
|
|
||||||
|
base = skb_mac_header(skb);
|
||||||
|
*correction_offset = (u8 *)&hdr->correction - base;
|
||||||
|
*body_offset = (u8 *)hdr + sizeof(struct ptp_header) - base;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
bool do_vlan, do_onestep_tstamp = false, do_twostep_tstamp = false;
|
||||||
|
struct enetc_ndev_priv *priv = netdev_priv(tx_ring->ndev);
|
||||||
|
struct enetc_hw *hw = &priv->si->hw;
|
||||||
struct enetc_tx_swbd *tx_swbd;
|
struct enetc_tx_swbd *tx_swbd;
|
||||||
skb_frag_t *frag;
|
|
||||||
int len = skb_headlen(skb);
|
int len = skb_headlen(skb);
|
||||||
union enetc_tx_bd temp_bd;
|
union enetc_tx_bd temp_bd;
|
||||||
|
u8 msgtype, twostep, udp;
|
||||||
union enetc_tx_bd *txbd;
|
union enetc_tx_bd *txbd;
|
||||||
bool do_vlan, do_tstamp;
|
u16 offset1, offset2;
|
||||||
int i, count = 0;
|
int i, count = 0;
|
||||||
|
skb_frag_t *frag;
|
||||||
unsigned int f;
|
unsigned int f;
|
||||||
dma_addr_t dma;
|
dma_addr_t dma;
|
||||||
u8 flags = 0;
|
u8 flags = 0;
|
||||||
|
@ -101,12 +138,21 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb,
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
do_vlan = skb_vlan_tag_present(skb);
|
do_vlan = skb_vlan_tag_present(skb);
|
||||||
do_tstamp = (active_offloads & ENETC_F_TX_TSTAMP) &&
|
if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
|
||||||
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP);
|
if (enetc_ptp_parse(skb, &udp, &msgtype, &twostep, &offset1,
|
||||||
tx_swbd->do_tstamp = do_tstamp;
|
&offset2) ||
|
||||||
tx_swbd->check_wb = tx_swbd->do_tstamp;
|
msgtype != PTP_MSGTYPE_SYNC || twostep)
|
||||||
|
WARN_ONCE(1, "Bad packet for one-step timestamping\n");
|
||||||
|
else
|
||||||
|
do_onestep_tstamp = true;
|
||||||
|
} else if (skb->cb[0] & ENETC_F_TX_TSTAMP) {
|
||||||
|
do_twostep_tstamp = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (do_vlan || do_tstamp)
|
tx_swbd->do_twostep_tstamp = do_twostep_tstamp;
|
||||||
|
tx_swbd->check_wb = tx_swbd->do_twostep_tstamp;
|
||||||
|
|
||||||
|
if (do_vlan || do_onestep_tstamp || do_twostep_tstamp)
|
||||||
flags |= ENETC_TXBD_FLAGS_EX;
|
flags |= ENETC_TXBD_FLAGS_EX;
|
||||||
|
|
||||||
if (tx_ring->tsd_enable)
|
if (tx_ring->tsd_enable)
|
||||||
|
@ -143,7 +189,40 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb,
|
||||||
e_flags |= ENETC_TXBD_E_FLAGS_VLAN_INS;
|
e_flags |= ENETC_TXBD_E_FLAGS_VLAN_INS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_tstamp) {
|
if (do_onestep_tstamp) {
|
||||||
|
u32 lo, hi, val;
|
||||||
|
u64 sec, nsec;
|
||||||
|
u8 *data;
|
||||||
|
|
||||||
|
lo = enetc_rd_hot(hw, ENETC_SICTR0);
|
||||||
|
hi = enetc_rd_hot(hw, ENETC_SICTR1);
|
||||||
|
sec = (u64)hi << 32 | lo;
|
||||||
|
nsec = do_div(sec, 1000000000);
|
||||||
|
|
||||||
|
/* Configure extension BD */
|
||||||
|
temp_bd.ext.tstamp = cpu_to_le32(lo & 0x3fffffff);
|
||||||
|
e_flags |= ENETC_TXBD_E_FLAGS_ONE_STEP_PTP;
|
||||||
|
|
||||||
|
/* Update originTimestamp field of Sync packet
|
||||||
|
* - 48 bits seconds field
|
||||||
|
* - 32 bits nanseconds field
|
||||||
|
*/
|
||||||
|
data = skb_mac_header(skb);
|
||||||
|
*(__be16 *)(data + offset2) =
|
||||||
|
htons((sec >> 32) & 0xffff);
|
||||||
|
*(__be32 *)(data + offset2 + 2) =
|
||||||
|
htonl(sec & 0xffffffff);
|
||||||
|
*(__be32 *)(data + offset2 + 6) = htonl(nsec);
|
||||||
|
|
||||||
|
/* Configure single-step register */
|
||||||
|
val = ENETC_PM0_SINGLE_STEP_EN;
|
||||||
|
val |= ENETC_SET_SINGLE_STEP_OFFSET(offset1);
|
||||||
|
if (udp)
|
||||||
|
val |= ENETC_PM0_SINGLE_STEP_CH;
|
||||||
|
|
||||||
|
enetc_port_wr(hw, ENETC_PM0_SINGLE_STEP, val);
|
||||||
|
enetc_port_wr(hw, ENETC_PM1_SINGLE_STEP, val);
|
||||||
|
} else if (do_twostep_tstamp) {
|
||||||
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
|
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
|
||||||
e_flags |= ENETC_TXBD_E_FLAGS_TWO_STEP_PTP;
|
e_flags |= ENETC_TXBD_E_FLAGS_TWO_STEP_PTP;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +294,8 @@ dma_err:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev)
|
static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
|
||||||
|
struct net_device *ndev)
|
||||||
{
|
{
|
||||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||||
struct enetc_bdr *tx_ring;
|
struct enetc_bdr *tx_ring;
|
||||||
|
@ -234,7 +314,7 @@ netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||||
}
|
}
|
||||||
|
|
||||||
enetc_lock_mdio();
|
enetc_lock_mdio();
|
||||||
count = enetc_map_tx_buffs(tx_ring, skb, priv->active_offloads);
|
count = enetc_map_tx_buffs(tx_ring, skb);
|
||||||
enetc_unlock_mdio();
|
enetc_unlock_mdio();
|
||||||
|
|
||||||
if (unlikely(!count))
|
if (unlikely(!count))
|
||||||
|
@ -250,6 +330,40 @@ drop_packet_err:
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||||
|
{
|
||||||
|
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||||
|
u8 udp, msgtype, twostep;
|
||||||
|
u16 offset1, offset2;
|
||||||
|
|
||||||
|
/* Mark tx timestamp type on skb->cb[0] if requires */
|
||||||
|
if ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
|
||||||
|
(priv->active_offloads & ENETC_F_TX_TSTAMP_MASK)) {
|
||||||
|
skb->cb[0] = priv->active_offloads & ENETC_F_TX_TSTAMP_MASK;
|
||||||
|
} else {
|
||||||
|
skb->cb[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fall back to two-step timestamp if not one-step Sync packet */
|
||||||
|
if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
|
||||||
|
if (enetc_ptp_parse(skb, &udp, &msgtype, &twostep,
|
||||||
|
&offset1, &offset2) ||
|
||||||
|
msgtype != PTP_MSGTYPE_SYNC || twostep != 0)
|
||||||
|
skb->cb[0] = ENETC_F_TX_TSTAMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Queue one-step Sync packet if already locked */
|
||||||
|
if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
|
||||||
|
if (test_and_set_bit_lock(ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS,
|
||||||
|
&priv->flags)) {
|
||||||
|
skb_queue_tail(&priv->tx_skbs, skb);
|
||||||
|
return NETDEV_TX_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return enetc_start_xmit(skb, ndev);
|
||||||
|
}
|
||||||
|
|
||||||
static irqreturn_t enetc_msix(int irq, void *data)
|
static irqreturn_t enetc_msix(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct enetc_int_vector *v = data;
|
struct enetc_int_vector *v = data;
|
||||||
|
@ -390,10 +504,11 @@ static void enetc_recycle_xdp_tx_buff(struct enetc_bdr *tx_ring,
|
||||||
static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
|
static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
|
||||||
{
|
{
|
||||||
struct net_device *ndev = tx_ring->ndev;
|
struct net_device *ndev = tx_ring->ndev;
|
||||||
|
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||||
int tx_frm_cnt = 0, tx_byte_cnt = 0;
|
int tx_frm_cnt = 0, tx_byte_cnt = 0;
|
||||||
struct enetc_tx_swbd *tx_swbd;
|
struct enetc_tx_swbd *tx_swbd;
|
||||||
int i, bds_to_clean;
|
int i, bds_to_clean;
|
||||||
bool do_tstamp;
|
bool do_twostep_tstamp;
|
||||||
u64 tstamp = 0;
|
u64 tstamp = 0;
|
||||||
|
|
||||||
i = tx_ring->next_to_clean;
|
i = tx_ring->next_to_clean;
|
||||||
|
@ -401,7 +516,7 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
|
||||||
|
|
||||||
bds_to_clean = enetc_bd_ready_count(tx_ring, i);
|
bds_to_clean = enetc_bd_ready_count(tx_ring, i);
|
||||||
|
|
||||||
do_tstamp = false;
|
do_twostep_tstamp = false;
|
||||||
|
|
||||||
while (bds_to_clean && tx_frm_cnt < ENETC_DEFAULT_TX_WORK) {
|
while (bds_to_clean && tx_frm_cnt < ENETC_DEFAULT_TX_WORK) {
|
||||||
struct xdp_frame *xdp_frame = enetc_tx_swbd_get_xdp_frame(tx_swbd);
|
struct xdp_frame *xdp_frame = enetc_tx_swbd_get_xdp_frame(tx_swbd);
|
||||||
|
@ -415,10 +530,10 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
|
||||||
txbd = ENETC_TXBD(*tx_ring, i);
|
txbd = ENETC_TXBD(*tx_ring, i);
|
||||||
|
|
||||||
if (txbd->flags & ENETC_TXBD_FLAGS_W &&
|
if (txbd->flags & ENETC_TXBD_FLAGS_W &&
|
||||||
tx_swbd->do_tstamp) {
|
tx_swbd->do_twostep_tstamp) {
|
||||||
enetc_get_tx_tstamp(&priv->si->hw, txbd,
|
enetc_get_tx_tstamp(&priv->si->hw, txbd,
|
||||||
&tstamp);
|
&tstamp);
|
||||||
do_tstamp = true;
|
do_twostep_tstamp = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,9 +546,16 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
|
||||||
xdp_return_frame(xdp_frame);
|
xdp_return_frame(xdp_frame);
|
||||||
tx_swbd->xdp_frame = NULL;
|
tx_swbd->xdp_frame = NULL;
|
||||||
} else if (skb) {
|
} else if (skb) {
|
||||||
if (unlikely(do_tstamp)) {
|
if (unlikely(tx_swbd->skb->cb[0] &
|
||||||
|
ENETC_F_TX_ONESTEP_SYNC_TSTAMP)) {
|
||||||
|
/* Start work to release lock for next one-step
|
||||||
|
* timestamping packet. And send one skb in
|
||||||
|
* tx_skbs queue if has.
|
||||||
|
*/
|
||||||
|
queue_work(system_wq, &priv->tx_onestep_tstamp);
|
||||||
|
} else if (unlikely(do_twostep_tstamp)) {
|
||||||
enetc_tstamp_tx(skb, tstamp);
|
enetc_tstamp_tx(skb, tstamp);
|
||||||
do_tstamp = false;
|
do_twostep_tstamp = false;
|
||||||
}
|
}
|
||||||
napi_consume_skb(skb, napi_budget);
|
napi_consume_skb(skb, napi_budget);
|
||||||
tx_swbd->skb = NULL;
|
tx_swbd->skb = NULL;
|
||||||
|
@ -1862,6 +1984,29 @@ static int enetc_phylink_connect(struct net_device *ndev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void enetc_tx_onestep_tstamp(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct enetc_ndev_priv *priv;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
|
priv = container_of(work, struct enetc_ndev_priv, tx_onestep_tstamp);
|
||||||
|
|
||||||
|
netif_tx_lock(priv->ndev);
|
||||||
|
|
||||||
|
clear_bit_unlock(ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS, &priv->flags);
|
||||||
|
skb = skb_dequeue(&priv->tx_skbs);
|
||||||
|
if (skb)
|
||||||
|
enetc_start_xmit(skb, priv->ndev);
|
||||||
|
|
||||||
|
netif_tx_unlock(priv->ndev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void enetc_tx_onestep_tstamp_init(struct enetc_ndev_priv *priv)
|
||||||
|
{
|
||||||
|
INIT_WORK(&priv->tx_onestep_tstamp, enetc_tx_onestep_tstamp);
|
||||||
|
skb_queue_head_init(&priv->tx_skbs);
|
||||||
|
}
|
||||||
|
|
||||||
void enetc_start(struct net_device *ndev)
|
void enetc_start(struct net_device *ndev)
|
||||||
{
|
{
|
||||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||||
|
@ -1914,6 +2059,7 @@ int enetc_open(struct net_device *ndev)
|
||||||
if (err)
|
if (err)
|
||||||
goto err_set_queues;
|
goto err_set_queues;
|
||||||
|
|
||||||
|
enetc_tx_onestep_tstamp_init(priv);
|
||||||
enetc_setup_bdrs(priv);
|
enetc_setup_bdrs(priv);
|
||||||
enetc_start(ndev);
|
enetc_start(ndev);
|
||||||
|
|
||||||
|
@ -2212,11 +2358,16 @@ static int enetc_hwtstamp_set(struct net_device *ndev, struct ifreq *ifr)
|
||||||
|
|
||||||
switch (config.tx_type) {
|
switch (config.tx_type) {
|
||||||
case HWTSTAMP_TX_OFF:
|
case HWTSTAMP_TX_OFF:
|
||||||
priv->active_offloads &= ~ENETC_F_TX_TSTAMP;
|
priv->active_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
|
||||||
break;
|
break;
|
||||||
case HWTSTAMP_TX_ON:
|
case HWTSTAMP_TX_ON:
|
||||||
|
priv->active_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
|
||||||
priv->active_offloads |= ENETC_F_TX_TSTAMP;
|
priv->active_offloads |= ENETC_F_TX_TSTAMP;
|
||||||
break;
|
break;
|
||||||
|
case HWTSTAMP_TX_ONESTEP_SYNC:
|
||||||
|
priv->active_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
|
||||||
|
priv->active_offloads |= ENETC_F_TX_ONESTEP_SYNC_TSTAMP;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
@ -2247,7 +2398,9 @@ static int enetc_hwtstamp_get(struct net_device *ndev, struct ifreq *ifr)
|
||||||
|
|
||||||
config.flags = 0;
|
config.flags = 0;
|
||||||
|
|
||||||
if (priv->active_offloads & ENETC_F_TX_TSTAMP)
|
if (priv->active_offloads & ENETC_F_TX_ONESTEP_SYNC_TSTAMP)
|
||||||
|
config.tx_type = HWTSTAMP_TX_ONESTEP_SYNC;
|
||||||
|
else if (priv->active_offloads & ENETC_F_TX_TSTAMP)
|
||||||
config.tx_type = HWTSTAMP_TX_ON;
|
config.tx_type = HWTSTAMP_TX_ON;
|
||||||
else
|
else
|
||||||
config.tx_type = HWTSTAMP_TX_OFF;
|
config.tx_type = HWTSTAMP_TX_OFF;
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct enetc_tx_swbd {
|
||||||
enum dma_data_direction dir;
|
enum dma_data_direction dir;
|
||||||
u8 is_dma_page:1;
|
u8 is_dma_page:1;
|
||||||
u8 check_wb:1;
|
u8 check_wb:1;
|
||||||
u8 do_tstamp:1;
|
u8 do_twostep_tstamp:1;
|
||||||
u8 is_eof:1;
|
u8 is_eof:1;
|
||||||
u8 is_xdp_tx:1;
|
u8 is_xdp_tx:1;
|
||||||
u8 is_xdp_redirect:1;
|
u8 is_xdp_redirect:1;
|
||||||
|
@ -271,12 +271,20 @@ struct psfp_cap {
|
||||||
u32 max_psfp_meter;
|
u32 max_psfp_meter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ENETC_F_TX_TSTAMP_MASK 0xff
|
||||||
/* TODO: more hardware offloads */
|
/* TODO: more hardware offloads */
|
||||||
enum enetc_active_offloads {
|
enum enetc_active_offloads {
|
||||||
ENETC_F_RX_TSTAMP = BIT(0),
|
/* 8 bits reserved for TX timestamp types (hwtstamp_tx_types) */
|
||||||
ENETC_F_TX_TSTAMP = BIT(1),
|
ENETC_F_TX_TSTAMP = BIT(0),
|
||||||
ENETC_F_QBV = BIT(2),
|
ENETC_F_TX_ONESTEP_SYNC_TSTAMP = BIT(1),
|
||||||
ENETC_F_QCI = BIT(3),
|
|
||||||
|
ENETC_F_RX_TSTAMP = BIT(8),
|
||||||
|
ENETC_F_QBV = BIT(9),
|
||||||
|
ENETC_F_QCI = BIT(10),
|
||||||
|
};
|
||||||
|
|
||||||
|
enum enetc_flags_bit {
|
||||||
|
ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* interrupt coalescing modes */
|
/* interrupt coalescing modes */
|
||||||
|
@ -321,6 +329,11 @@ struct enetc_ndev_priv {
|
||||||
u32 tx_ictt;
|
u32 tx_ictt;
|
||||||
|
|
||||||
struct bpf_prog *xdp_prog;
|
struct bpf_prog *xdp_prog;
|
||||||
|
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
struct work_struct tx_onestep_tstamp;
|
||||||
|
struct sk_buff_head tx_skbs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Messaging */
|
/* Messaging */
|
||||||
|
|
|
@ -671,7 +671,8 @@ static int enetc_get_ts_info(struct net_device *ndev,
|
||||||
SOF_TIMESTAMPING_RAW_HARDWARE;
|
SOF_TIMESTAMPING_RAW_HARDWARE;
|
||||||
|
|
||||||
info->tx_types = (1 << HWTSTAMP_TX_OFF) |
|
info->tx_types = (1 << HWTSTAMP_TX_OFF) |
|
||||||
(1 << HWTSTAMP_TX_ON);
|
(1 << HWTSTAMP_TX_ON) |
|
||||||
|
(1 << HWTSTAMP_TX_ONESTEP_SYNC);
|
||||||
info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
|
info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
|
||||||
(1 << HWTSTAMP_FILTER_ALL);
|
(1 << HWTSTAMP_FILTER_ALL);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -239,6 +239,12 @@ enum enetc_bdr_type {TX, RX};
|
||||||
|
|
||||||
#define ENETC_PM_IMDIO_BASE 0x8030
|
#define ENETC_PM_IMDIO_BASE 0x8030
|
||||||
|
|
||||||
|
#define ENETC_PM0_SINGLE_STEP 0x80c0
|
||||||
|
#define ENETC_PM1_SINGLE_STEP 0x90c0
|
||||||
|
#define ENETC_PM0_SINGLE_STEP_CH BIT(7)
|
||||||
|
#define ENETC_PM0_SINGLE_STEP_EN BIT(31)
|
||||||
|
#define ENETC_SET_SINGLE_STEP_OFFSET(v) (((v) & 0xff) << 8)
|
||||||
|
|
||||||
#define ENETC_PM0_IF_MODE 0x8300
|
#define ENETC_PM0_IF_MODE 0x8300
|
||||||
#define ENETC_PM0_IFM_RG BIT(2)
|
#define ENETC_PM0_IFM_RG BIT(2)
|
||||||
#define ENETC_PM0_IFM_RLP (BIT(5) | BIT(11))
|
#define ENETC_PM0_IFM_RLP (BIT(5) | BIT(11))
|
||||||
|
@ -548,6 +554,7 @@ static inline void enetc_clear_tx_bd(union enetc_tx_bd *txbd)
|
||||||
|
|
||||||
/* Extension flags */
|
/* Extension flags */
|
||||||
#define ENETC_TXBD_E_FLAGS_VLAN_INS BIT(0)
|
#define ENETC_TXBD_E_FLAGS_VLAN_INS BIT(0)
|
||||||
|
#define ENETC_TXBD_E_FLAGS_ONE_STEP_PTP BIT(1)
|
||||||
#define ENETC_TXBD_E_FLAGS_TWO_STEP_PTP BIT(2)
|
#define ENETC_TXBD_E_FLAGS_TWO_STEP_PTP BIT(2)
|
||||||
|
|
||||||
union enetc_rx_bd {
|
union enetc_rx_bd {
|
||||||
|
|
Loading…
Reference in New Issue