Commit 2b7c86eb authored by Ioana Radulescu's avatar Ioana Radulescu Committed by Greg Kroah-Hartman

staging: fsl-dpaa2/eth: Don't enable FAS on Tx

For Tx confirmed frames that have an error indication in the frame
descriptor, we look at the Frame Annotation Status field (in the
buffer headroom) for details on the root cause and then print
a debug message with that information.

While useful in initial development stages, it doesn't bring
enough added value to justify reserving 64B of headroom for all
Tx frames (FAS is only 8B long, but we must reserve chunks of 64B
from the hardware annotation area).

If we remove the need for FAS field from egress frames, we can
renounce hardware annotation completely, since FAS is the only
HWA field we currently use.
Signed-off-by: default avatarIoana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6662b5e4
......@@ -348,7 +348,6 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv,
int num_sg;
int num_dma_bufs;
struct dpaa2_eth_swa *swa;
struct dpaa2_fas *fas;
/* Create and map scatterlist.
* We don't advertise NETIF_F_FRAGLIST, so skb_to_sgvec() will not have
......@@ -379,15 +378,6 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv,
goto sgt_buf_alloc_failed;
}
sgt_buf = PTR_ALIGN(sgt_buf, DPAA2_ETH_TX_BUF_ALIGN);
/* PTA from egress side is passed as is to the confirmation side so
* we need to clear some fields here in order to find consistent values
* on TX confirmation. We are clearing FAS (Frame Annotation Status)
* field from the hardware annotation area
*/
fas = dpaa2_get_fas(sgt_buf, true);
memset(fas, 0, DPAA2_FAS_SIZE);
sgt = (struct dpaa2_sg_entry *)(sgt_buf + priv->tx_data_offset);
/* Fill in the HW SGT structure.
......@@ -424,8 +414,7 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv,
dpaa2_fd_set_format(fd, dpaa2_fd_sg);
dpaa2_fd_set_addr(fd, addr);
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_ASAL | DPAA2_FD_CTRL_PTA |
DPAA2_FD_CTRL_PTV1);
dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_PTA | DPAA2_FD_CTRL_PTV1);
return 0;
......@@ -445,21 +434,12 @@ static int build_single_fd(struct dpaa2_eth_priv *priv,
{
struct device *dev = priv->net_dev->dev.parent;
u8 *buffer_start;
struct dpaa2_fas *fas;
struct sk_buff **skbh;
dma_addr_t addr;
buffer_start = PTR_ALIGN(skb->data - dpaa2_eth_needed_headroom(priv),
DPAA2_ETH_TX_BUF_ALIGN);
/* PTA from egress side is passed as is to the confirmation side so
* we need to clear some fields here in order to find consistent values
* on TX confirmation. We are clearing FAS (Frame Annotation Status)
* field from the hardware annotation area
*/
fas = dpaa2_get_fas(buffer_start, true);
memset(fas, 0, DPAA2_FAS_SIZE);
/* Store a backpointer to the skb at the beginning of the buffer
* (in the private data area) such that we can release it
* on Tx confirm
......@@ -477,8 +457,7 @@ static int build_single_fd(struct dpaa2_eth_priv *priv,
dpaa2_fd_set_offset(fd, (u16)(skb->data - buffer_start));
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_format(fd, dpaa2_fd_single);
dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_ASAL | DPAA2_FD_CTRL_PTA |
DPAA2_FD_CTRL_PTV1);
dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_PTA | DPAA2_FD_CTRL_PTV1);
return 0;
}
......@@ -493,8 +472,7 @@ static int build_single_fd(struct dpaa2_eth_priv *priv,
* to be checked if we're on the confirmation path.
*/
static void free_tx_fd(const struct dpaa2_eth_priv *priv,
const struct dpaa2_fd *fd,
u32 *status)
const struct dpaa2_fd *fd)
{
struct device *dev = priv->net_dev->dev.parent;
dma_addr_t fd_addr;
......@@ -505,11 +483,9 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv,
int num_sg, num_dma_bufs;
struct dpaa2_eth_swa *swa;
u8 fd_format = dpaa2_fd_get_format(fd);
struct dpaa2_fas *fas;
fd_addr = dpaa2_fd_get_addr(fd);
skbh = dpaa2_iova_to_virt(priv->iommu_domain, fd_addr);
fas = dpaa2_get_fas(skbh, true);
if (fd_format == dpaa2_fd_single) {
skb = *skbh;
......@@ -536,19 +512,10 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv,
sizeof(struct dpaa2_sg_entry) * (1 + num_dma_bufs);
dma_unmap_single(dev, fd_addr, unmap_size, DMA_BIDIRECTIONAL);
} else {
/* Unsupported format, mark it as errored and give up */
if (status)
*status = ~0;
netdev_dbg(priv->net_dev, "Invalid FD format\n");
return;
}
/* Read the status from the Frame Annotation after we unmap the first
* buffer but before we free it. The caller function is responsible
* for checking the status value.
*/
if (status)
*status = le32_to_cpu(fas->status);
/* Free SGT buffer kmalloc'ed on tx */
if (fd_format != dpaa2_fd_single)
kfree(skbh);
......@@ -627,7 +594,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
if (unlikely(err < 0)) {
percpu_stats->tx_errors++;
/* Clean up everything, including freeing the skb */
free_tx_fd(priv, &fd, NULL);
free_tx_fd(priv, &fd);
} else {
percpu_stats->tx_packets++;
percpu_stats->tx_bytes += dpaa2_fd_get_len(&fd);
......@@ -650,9 +617,7 @@ static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv,
{
struct rtnl_link_stats64 *percpu_stats;
struct dpaa2_eth_drv_stats *percpu_extras;
u32 status = 0;
u32 fd_errors;
bool has_fas_errors = false;
/* Tracing point */
trace_dpaa2_tx_conf_fd(priv->net_dev, fd);
......@@ -663,29 +628,18 @@ static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv,
/* Check frame errors in the FD field */
fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_TX_ERR_MASK;
if (unlikely(fd_errors)) {
/* We only check error bits in the FAS field if corresponding
* FAERR bit is set in FD and the FAS field is marked as valid
*/
has_fas_errors = (fd_errors & DPAA2_FD_CTRL_FAERR) &&
!!(dpaa2_fd_get_frc(fd) & DPAA2_FD_FRC_FASV);
if (net_ratelimit())
netdev_dbg(priv->net_dev, "TX frame FD error: 0x%08x\n",
fd_errors);
}
free_tx_fd(priv, fd, has_fas_errors ? &status : NULL);
free_tx_fd(priv, fd);
if (likely(!fd_errors))
return;
if (net_ratelimit())
netdev_dbg(priv->net_dev, "TX frame FD error: 0x%08x\n",
fd_errors);
percpu_stats = this_cpu_ptr(priv->percpu_stats);
/* Tx-conf logically pertains to the egress path. */
percpu_stats->tx_errors++;
if (has_fas_errors && net_ratelimit())
netdev_dbg(priv->net_dev, "TX frame FAS error: 0x%08x\n",
status & DPAA2_FAS_TX_ERR_MASK);
}
static int set_rx_csum(struct dpaa2_eth_priv *priv, bool enable)
......@@ -1791,10 +1745,8 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv)
priv->rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN;
/* tx buffer */
buf_layout.pass_frame_status = true;
buf_layout.private_data_size = DPAA2_ETH_SWA_SIZE;
buf_layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
buf_layout.options = DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
err = dpni_set_buffer_layout(priv->mc_io, 0, priv->mc_token,
DPNI_QUEUE_TX, &buf_layout);
if (err) {
......@@ -1803,7 +1755,7 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv)
}
/* tx-confirm buffer */
buf_layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS;
buf_layout.options = 0;
err = dpni_set_buffer_layout(priv->mc_io, 0, priv->mc_token,
DPNI_QUEUE_TX_CONFIRM, &buf_layout);
if (err) {
......@@ -1826,6 +1778,7 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv)
priv->tx_data_offset);
/* rx buffer */
buf_layout.pass_frame_status = true;
buf_layout.pass_parser_result = true;
buf_layout.data_align = priv->rx_buf_align;
buf_layout.data_head_room = dpaa2_eth_rx_head_room(priv);
......
......@@ -134,7 +134,6 @@ struct dpaa2_eth_swa {
DPAA2_FD_CTRL_FAERR)
/* Annotation bits in FD CTRL */
#define DPAA2_FD_CTRL_ASAL 0x00010000 /* ASAL = 64 */
#define DPAA2_FD_CTRL_PTA 0x00800000
#define DPAA2_FD_CTRL_PTV1 0x00400000
......@@ -208,11 +207,6 @@ static inline struct dpaa2_fas *dpaa2_get_fas(void *buf_addr, bool swa)
DPAA2_FAS_BLE | \
DPAA2_FAS_L3CE | \
DPAA2_FAS_L4CE)
/* Tx errors */
#define DPAA2_FAS_TX_ERR_MASK (DPAA2_FAS_KSE | \
DPAA2_FAS_EOFHE | \
DPAA2_FAS_MNLE | \
DPAA2_FAS_TIDE)
/* Time in milliseconds between link state updates */
#define DPAA2_ETH_LINK_STATE_REFRESH 1000
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment