[PATCH net-next V3 08/16] net: fec: set cbd_sc without relying on previous value
Fugang Duan
fugang.duan at nxp.com
Wed Apr 6 02:51:48 PDT 2016
From: Troy Kisky <troy.kisky at boundarydevices.com> Sent: Wednesday, April 06, 2016 10:26 AM
> To: netdev at vger.kernel.org; davem at davemloft.net; Fugang Duan
> <fugang.duan at nxp.com>; lznuaa at gmail.com
> Cc: Fabio Estevam <fabio.estevam at nxp.com>; l.stach at pengutronix.de;
> andrew at lunn.ch; tremyfr at gmail.com; gerg at uclinux.org; linux-arm-
> kernel at lists.infradead.org; johannes at sipsolutions.net;
> stillcompiling at gmail.com; sergei.shtylyov at cogentembedded.com;
> arnd at arndb.de; Troy Kisky <troy.kisky at boundarydevices.com>
> Subject: [PATCH net-next V3 08/16] net: fec: set cbd_sc without relying on
> previous value
>
> Relying on the wrap bit of cdb_sc to stay valid once initialized when the
> controller also writes to this byte seems undesirable since we can easily know
> what the value should be.
>
> Signed-off-by: Troy Kisky <troy.kisky at boundarydevices.com>
>
> ---
> v3: change commit message
> ---
> drivers/net/ethernet/freescale/fec_main.c | 38 +++++++++----------------------
> 1 file changed, 11 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/fec_main.c
> b/drivers/net/ethernet/freescale/fec_main.c
> index 3cd0cdf..21d2cd0 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -340,9 +340,8 @@ fec_enet_txq_submit_frag_skb(struct
> fec_enet_priv_tx_q *txq,
> bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
> ebdp = (struct bufdesc_ex *)bdp;
>
> - status = fec16_to_cpu(bdp->cbd_sc);
> - status &= ~BD_ENET_TX_STATS;
> - status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
> + status = BD_ENET_TX_TC | BD_ENET_TX_READY |
> + ((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
> frag_len = skb_shinfo(skb)->frags[frag].size;
>
> /* Handle the last BD specially */
> @@ -436,8 +435,6 @@ static int fec_enet_txq_submit_skb(struct
> fec_enet_priv_tx_q *txq,
> /* Fill in a Tx ring entry */
> bdp = txq->bd.cur;
> last_bdp = bdp;
> - status = fec16_to_cpu(bdp->cbd_sc);
> - status &= ~BD_ENET_TX_STATS;
>
> /* Set buffer length and buffer pointer */
> bufaddr = skb->data;
> @@ -462,6 +459,8 @@ static int fec_enet_txq_submit_skb(struct
> fec_enet_priv_tx_q *txq,
> return NETDEV_TX_OK;
> }
>
> + status = BD_ENET_TX_TC | BD_ENET_TX_READY |
> + ((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
> if (nr_frags) {
> last_bdp = fec_enet_txq_submit_frag_skb(txq, skb, ndev);
> if (IS_ERR(last_bdp)) {
> @@ -512,7 +511,6 @@ static int fec_enet_txq_submit_skb(struct
> fec_enet_priv_tx_q *txq,
> /* Send it on its way. Tell FEC it's ready, interrupt when done,
> * it's the last BD of the frame, and to put the CRC on the end.
> */
> - status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
> bdp->cbd_sc = cpu_to_fec16(status);
>
> /* If this was the last BD in the ring, start at the beginning again. */ @@ -
> 544,11 +542,6 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq,
> struct sk_buff *skb,
> unsigned int estatus = 0;
> dma_addr_t addr;
>
> - status = fec16_to_cpu(bdp->cbd_sc);
> - status &= ~BD_ENET_TX_STATS;
> -
> - status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
> -
> if (((unsigned long) data) & fep->tx_align ||
> fep->quirks & FEC_QUIRK_SWAP_FRAME) {
> memcpy(txq->tx_bounce[index], data, size); @@ -578,15
> +571,16 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq,
> struct sk_buff *skb,
> ebdp->cbd_esc = cpu_to_fec32(estatus);
> }
>
> + status = BD_ENET_TX_TC | BD_ENET_TX_READY |
> + ((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
> /* Handle the last BD specially */
> if (last_tcp)
> - status |= (BD_ENET_TX_LAST | BD_ENET_TX_TC);
> + status |= BD_ENET_TX_LAST;
> if (is_last) {
> status |= BD_ENET_TX_INTR;
> if (fep->bufdesc_ex)
> ebdp->cbd_esc |= cpu_to_fec32(BD_ENET_TX_INT);
> }
> -
> bdp->cbd_sc = cpu_to_fec16(status);
>
> return 0;
> @@ -602,13 +596,8 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q
> *txq,
> struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
> void *bufaddr;
> unsigned long dmabuf;
> - unsigned short status;
> unsigned int estatus = 0;
>
> - status = fec16_to_cpu(bdp->cbd_sc);
> - status &= ~BD_ENET_TX_STATS;
> - status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
> -
> bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
> dmabuf = txq->tso_hdrs_dma + index * TSO_HEADER_SIZE;
> if (((unsigned long)bufaddr) & fep->tx_align || @@ -641,8 +630,8 @@
> fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
> ebdp->cbd_esc = cpu_to_fec32(estatus);
> }
>
> - bdp->cbd_sc = cpu_to_fec16(status);
> -
> + bdp->cbd_sc = cpu_to_fec16(BD_ENET_TX_TC | BD_ENET_TX_READY |
> + ((bdp == txq->bd.last) ? BD_SC_WRAP : 0));
> return 0;
> }
>
> @@ -1454,12 +1443,6 @@ static int fec_rxq(struct net_device *ndev, struct
> fec_enet_priv_rx_q *rxq,
> }
>
> rx_processing_done:
> - /* Clear the status flags for this buffer */
> - status &= ~BD_ENET_RX_STATS;
> -
> - /* Mark the buffer empty */
> - status |= BD_ENET_RX_EMPTY;
> -
> if (fep->bufdesc_ex) {
> struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
>
> @@ -1471,7 +1454,8 @@ rx_processing_done:
> * performed before transferring ownership.
> */
> wmb();
> - bdp->cbd_sc = cpu_to_fec16(status);
> + bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY |
> + ((bdp == rxq->bd.last) ? BD_SC_WRAP : 0));
>
> /* Update BD pointer to next entry */
> bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
> --
> 2.5.0
Patch 08 ~ 16: Acked-by: Fugang Duan <fugang.duan at nxp.com>
More information about the linux-arm-kernel
mailing list