Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2244d07b authored by Oliver Hartkopp's avatar Oliver Hartkopp Committed by David S. Miller
Browse files

net: simplify flags for tx timestamping

This patch removes the abstraction introduced by the union skb_shared_tx in
the shared skb data.

The access of the different union elements at several places led to some
confusion about accessing the shared tx_flags e.g. in skb_orphan_try().

    http://marc.info/?l=linux-netdev&m=128084897415886&w=2



Signed-off-by: default avatarOliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4d5870ec
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -172,15 +172,19 @@ struct skb_shared_hwtstamps {
};

Time stamps for outgoing packets are to be generated as follows:
- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero.
  If yes, then the driver is expected to do hardware time stamping.
- In hard_start_xmit(), check if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
  is set no-zero. If yes, then the driver is expected to do hardware time
  stamping.
- If this is possible for the skb and requested, then declare
  that the driver is doing the time stamping by setting the field
  skb_tx(skb)->in_progress non-zero. You might want to keep a pointer
  to the associated skb for the next step and not free the skb. A driver
  not supporting hardware time stamping doesn't do that. A driver must
  never touch sk_buff::tstamp! It is used to store software generated
  time stamps by the network subsystem.
  that the driver is doing the time stamping by setting the flag
  SKBTX_IN_PROGRESS in skb_shinfo(skb)->tx_flags , e.g. with

      skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;

  You might want to keep a pointer to the associated skb for the next step
  and not free the skb. A driver not supporting hardware time stamping doesn't
  do that. A driver must never touch sk_buff::tstamp! It is used to store
  software generated time stamps by the network subsystem.
- As soon as the driver has sent the packet and/or obtained a
  hardware time stamp for it, it passes the time stamp back by
  calling skb_hwtstamp_tx() with the original skb, the raw
@@ -191,6 +195,6 @@ Time stamps for outgoing packets are to be generated as follows:
  this would occur at a later time in the processing pipeline than other
  software time stamping and therefore could lead to unexpected deltas
  between time stamps.
- If the driver did not call set skb_tx(skb)->in_progress, then
- If the driver did not set the SKBTX_IN_PROGRESS flag (see above), then
  dev_hard_start_xmit() checks whether software time stamping
  is wanted as fallback and potentially generates the time stamp.
+4 −6
Original line number Diff line number Diff line
@@ -803,15 +803,14 @@ static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompa
static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
{
	struct bfin_mac_local *lp = netdev_priv(netdev);
	union skb_shared_tx *shtx = skb_tx(skb);

	if (shtx->hardware) {
	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
		int timeout_cnt = MAX_TIMEOUT_CNT;

		/* When doing time stamping, keep the connection to the socket
		 * a while longer
		 */
		shtx->in_progress = 1;
		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;

		/*
		 * The timestamping is done at the EMAC module's MII/RMII interface
@@ -991,7 +990,6 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
	struct bfin_mac_local *lp = netdev_priv(dev);
	u16 *data;
	u32 data_align = (unsigned long)(skb->data) & 0x3;
	union skb_shared_tx *shtx = skb_tx(skb);

	current_tx_ptr->skb = skb;

@@ -1005,7 +1003,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
		 * of this field are the length of the packet payload in bytes and the higher
		 * 4 bits are the timestamping enable field.
		 */
		if (shtx->hardware)
		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
			*data |= 0x1000;

		current_tx_ptr->desc_a.start_addr = (u32)data;
@@ -1015,7 +1013,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
	} else {
		*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
		/* enable timestamping for the sent packet */
		if (shtx->hardware)
		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
			*((u16 *)(current_tx_ptr->packet)) |= 0x1000;
		memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
			skb->len);
+6 −9
Original line number Diff line number Diff line
@@ -2048,7 +2048,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
	u32 bufaddr;
	unsigned long flags;
	unsigned int nr_frags, nr_txbds, length;
	union skb_shared_tx *shtx;

	/*
	 * TOE=1 frames larger than 2500 bytes may see excess delays
@@ -2069,10 +2068,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
	txq = netdev_get_tx_queue(dev, rq);
	base = tx_queue->tx_bd_base;
	regs = tx_queue->grp->regs;
	shtx = skb_tx(skb);

	/* check if time stamp should be generated */
	if (unlikely(shtx->hardware && priv->hwts_tx_en))
	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
		     priv->hwts_tx_en))
		do_tstamp = 1;

	/* make space for additional header when fcb is needed */
@@ -2174,7 +2173,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)

	/* Setup tx hardware time stamping if requested */
	if (unlikely(do_tstamp)) {
		shtx->in_progress = 1;
		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
		if (fcb == NULL)
			fcb = gfar_add_fcb(skb);
		fcb->ptp = 1;
@@ -2446,7 +2445,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
	int howmany = 0;
	u32 lstatus;
	size_t buflen;
	union skb_shared_tx *shtx;

	rx_queue = priv->rx_queue[tx_queue->qindex];
	bdp = tx_queue->dirty_tx;
@@ -2461,8 +2459,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
		 * When time stamping, one additional TxBD must be freed.
		 * Also, we need to dma_unmap_single() the TxPAL.
		 */
		shtx = skb_tx(skb);
		if (unlikely(shtx->in_progress))
		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
			nr_txbds = frags + 2;
		else
			nr_txbds = frags + 1;
@@ -2476,7 +2473,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
				(lstatus & BD_LENGTH_MASK))
			break;

		if (unlikely(shtx->in_progress)) {
		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
			next = next_txbd(bdp, base, tx_ring_size);
			buflen = next->length + GMAC_FCB_LEN;
		} else
@@ -2485,7 +2482,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
		dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
				buflen, DMA_TO_DEVICE);

		if (unlikely(shtx->in_progress)) {
		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
			struct skb_shared_hwtstamps shhwtstamps;
			u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7);
			memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+1 −1
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ struct igb_buffer {
			u16 next_to_watch;
			unsigned int bytecount;
			u16 gso_segs;
			union skb_shared_tx shtx;
			u8 tx_flags;
			u8 mapped_as_page;
		};
		/* RX */
+5 −6
Original line number Diff line number Diff line
@@ -3954,7 +3954,7 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb,
	}

	tx_ring->buffer_info[i].skb = skb;
	tx_ring->buffer_info[i].shtx = skb_shinfo(skb)->tx_flags;
	tx_ring->buffer_info[i].tx_flags = skb_shinfo(skb)->tx_flags;
	/* multiply data chunks by size of headers */
	tx_ring->buffer_info[i].bytecount = ((gso_segs - 1) * hlen) + skb->len;
	tx_ring->buffer_info[i].gso_segs = gso_segs;
@@ -4088,7 +4088,6 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
	u32 tx_flags = 0;
	u16 first;
	u8 hdr_len = 0;
	union skb_shared_tx *shtx = skb_tx(skb);

	/* need: 1 descriptor per page,
	 *       + 2 desc gap to keep tail from touching head,
@@ -4100,8 +4099,8 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
		return NETDEV_TX_BUSY;
	}

	if (unlikely(shtx->hardware)) {
		shtx->in_progress = 1;
	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
		tx_flags |= IGB_TX_FLAGS_TSTAMP;
	}

@@ -5319,7 +5318,7 @@ static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct igb_buffer *bu
	u64 regval;

	/* if skb does not support hw timestamp or TX stamp not valid exit */
	if (likely(!buffer_info->shtx.hardware) ||
	if (likely(!(buffer_info->tx_flags & SKBTX_HW_TSTAMP)) ||
	    !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID))
		return;

@@ -5500,7 +5499,7 @@ static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr,
	 * values must belong to this one here and therefore we don't need to
	 * compare any of the additional attributes stored for it.
	 *
	 * If nothing went wrong, then it should have a skb_shared_tx that we
	 * If nothing went wrong, then it should have a shared tx_flags that we
	 * can turn into a skb_shared_hwtstamps.
	 */
	if (staterr & E1000_RXDADV_STAT_TSIP) {
Loading