提交 6fa9a115 编写于 作者: D David S. Miller

Merge branch 'stmmac-fixes'

Jose Abreu says:

====================
net: stmmac: Fixes for -net

Fixes for stmmac.

1) Fixes the filtering selftests (again) for cases when the number of multicast
filters are not enough.

2) Fixes SPH feature for MTU > default.

3) Fixes the behavior of accepting invalid MTU values.

4) Fixes FCS stripping for multi-descriptor packets.

5) Fixes the change of RX buffer size in XGMAC.

6) Fixes RX buffer size alignment.

7) Fixes the 16KB buffer alignment.

8) Fixes the enabling of 16KB buffer size feature.

9) Always arm the TX coalesce timer so that missed interrupts do not cause
a TX queue timeout.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -365,9 +365,8 @@ struct dma_features { ...@@ -365,9 +365,8 @@ struct dma_features {
unsigned int arpoffsel; unsigned int arpoffsel;
}; };
/* GMAC TX FIFO is 8K, Rx FIFO is 16K */ /* RX Buffer size must be multiple of 4/8/16 bytes */
#define BUF_SIZE_16KiB 16384 #define BUF_SIZE_16KiB 16368
/* RX Buffer size must be < 8191 and multiple of 4/8/16 bytes */
#define BUF_SIZE_8KiB 8188 #define BUF_SIZE_8KiB 8188
#define BUF_SIZE_4KiB 4096 #define BUF_SIZE_4KiB 4096
#define BUF_SIZE_2KiB 2048 #define BUF_SIZE_2KiB 2048
......
...@@ -343,6 +343,8 @@ ...@@ -343,6 +343,8 @@
#define XGMAC_DMA_CH_RX_CONTROL(x) (0x00003108 + (0x80 * (x))) #define XGMAC_DMA_CH_RX_CONTROL(x) (0x00003108 + (0x80 * (x)))
#define XGMAC_RxPBL GENMASK(21, 16) #define XGMAC_RxPBL GENMASK(21, 16)
#define XGMAC_RxPBL_SHIFT 16 #define XGMAC_RxPBL_SHIFT 16
#define XGMAC_RBSZ GENMASK(14, 1)
#define XGMAC_RBSZ_SHIFT 1
#define XGMAC_RXST BIT(0) #define XGMAC_RXST BIT(0)
#define XGMAC_DMA_CH_TxDESC_HADDR(x) (0x00003110 + (0x80 * (x))) #define XGMAC_DMA_CH_TxDESC_HADDR(x) (0x00003110 + (0x80 * (x)))
#define XGMAC_DMA_CH_TxDESC_LADDR(x) (0x00003114 + (0x80 * (x))) #define XGMAC_DMA_CH_TxDESC_LADDR(x) (0x00003114 + (0x80 * (x)))
......
...@@ -482,7 +482,8 @@ static void dwxgmac2_set_bfsize(void __iomem *ioaddr, int bfsize, u32 chan) ...@@ -482,7 +482,8 @@ static void dwxgmac2_set_bfsize(void __iomem *ioaddr, int bfsize, u32 chan)
u32 value; u32 value;
value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
value |= bfsize << 1; value &= ~XGMAC_RBSZ;
value |= bfsize << XGMAC_RBSZ_SHIFT;
writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
} }
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#include "dwxgmac2.h" #include "dwxgmac2.h"
#include "hwif.h" #include "hwif.h"
#define STMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES) #define STMMAC_ALIGN(x) ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16)
#define TSO_MAX_BUFF_SIZE (SZ_16K - 1) #define TSO_MAX_BUFF_SIZE (SZ_16K - 1)
/* Module parameters */ /* Module parameters */
...@@ -1109,7 +1109,9 @@ static int stmmac_set_bfsize(int mtu, int bufsize) ...@@ -1109,7 +1109,9 @@ static int stmmac_set_bfsize(int mtu, int bufsize)
{ {
int ret = bufsize; int ret = bufsize;
if (mtu >= BUF_SIZE_4KiB) if (mtu >= BUF_SIZE_8KiB)
ret = BUF_SIZE_16KiB;
else if (mtu >= BUF_SIZE_4KiB)
ret = BUF_SIZE_8KiB; ret = BUF_SIZE_8KiB;
else if (mtu >= BUF_SIZE_2KiB) else if (mtu >= BUF_SIZE_2KiB)
ret = BUF_SIZE_4KiB; ret = BUF_SIZE_4KiB;
...@@ -1293,19 +1295,9 @@ static int init_dma_rx_desc_rings(struct net_device *dev, gfp_t flags) ...@@ -1293,19 +1295,9 @@ static int init_dma_rx_desc_rings(struct net_device *dev, gfp_t flags)
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
u32 rx_count = priv->plat->rx_queues_to_use; u32 rx_count = priv->plat->rx_queues_to_use;
int ret = -ENOMEM; int ret = -ENOMEM;
int bfsize = 0;
int queue; int queue;
int i; int i;
bfsize = stmmac_set_16kib_bfsize(priv, dev->mtu);
if (bfsize < 0)
bfsize = 0;
if (bfsize < BUF_SIZE_16KiB)
bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
priv->dma_buf_sz = bfsize;
/* RX INITIALIZATION */ /* RX INITIALIZATION */
netif_dbg(priv, probe, priv->dev, netif_dbg(priv, probe, priv->dev,
"SKB addresses:\nskb\t\tskb data\tdma data\n"); "SKB addresses:\nskb\t\tskb data\tdma data\n");
...@@ -1347,8 +1339,6 @@ static int init_dma_rx_desc_rings(struct net_device *dev, gfp_t flags) ...@@ -1347,8 +1339,6 @@ static int init_dma_rx_desc_rings(struct net_device *dev, gfp_t flags)
} }
} }
buf_sz = bfsize;
return 0; return 0;
err_init_rx_buffers: err_init_rx_buffers:
...@@ -2658,6 +2648,7 @@ static void stmmac_hw_teardown(struct net_device *dev) ...@@ -2658,6 +2648,7 @@ static void stmmac_hw_teardown(struct net_device *dev)
static int stmmac_open(struct net_device *dev) static int stmmac_open(struct net_device *dev)
{ {
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
int bfsize = 0;
u32 chan; u32 chan;
int ret; int ret;
...@@ -2677,7 +2668,16 @@ static int stmmac_open(struct net_device *dev) ...@@ -2677,7 +2668,16 @@ static int stmmac_open(struct net_device *dev)
memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
priv->xstats.threshold = tc; priv->xstats.threshold = tc;
priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); bfsize = stmmac_set_16kib_bfsize(priv, dev->mtu);
if (bfsize < 0)
bfsize = 0;
if (bfsize < BUF_SIZE_16KiB)
bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
priv->dma_buf_sz = bfsize;
buf_sz = bfsize;
priv->rx_copybreak = STMMAC_RX_COPYBREAK; priv->rx_copybreak = STMMAC_RX_COPYBREAK;
ret = alloc_dma_desc_resources(priv); ret = alloc_dma_desc_resources(priv);
...@@ -3053,8 +3053,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3053,8 +3053,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
tx_q->tx_count_frames = 0; tx_q->tx_count_frames = 0;
stmmac_set_tx_ic(priv, desc); stmmac_set_tx_ic(priv, desc);
priv->xstats.tx_set_ic_bit++; priv->xstats.tx_set_ic_bit++;
} else {
stmmac_tx_timer_arm(priv, queue);
} }
/* We've used all descriptors we need for this skb, however, /* We've used all descriptors we need for this skb, however,
...@@ -3125,6 +3123,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3125,6 +3123,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc)); tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue); stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
stmmac_tx_timer_arm(priv, queue);
return NETDEV_TX_OK; return NETDEV_TX_OK;
...@@ -3276,8 +3275,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3276,8 +3275,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
tx_q->tx_count_frames = 0; tx_q->tx_count_frames = 0;
stmmac_set_tx_ic(priv, desc); stmmac_set_tx_ic(priv, desc);
priv->xstats.tx_set_ic_bit++; priv->xstats.tx_set_ic_bit++;
} else {
stmmac_tx_timer_arm(priv, queue);
} }
/* We've used all descriptors we need for this skb, however, /* We've used all descriptors we need for this skb, however,
...@@ -3366,6 +3363,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3366,6 +3363,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc)); tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue); stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
stmmac_tx_timer_arm(priv, queue);
return NETDEV_TX_OK; return NETDEV_TX_OK;
...@@ -3646,8 +3644,9 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) ...@@ -3646,8 +3644,9 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
* feature is always disabled and packets need to be * feature is always disabled and packets need to be
* stripped manually. * stripped manually.
*/ */
if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00) || if (likely(!(status & rx_not_ls)) &&
unlikely(status != llc_snap)) { (likely(priv->synopsys_id >= DWMAC_CORE_4_00) ||
unlikely(status != llc_snap))) {
if (buf2_len) if (buf2_len)
buf2_len -= ETH_FCS_LEN; buf2_len -= ETH_FCS_LEN;
else else
...@@ -3829,12 +3828,24 @@ static void stmmac_set_rx_mode(struct net_device *dev) ...@@ -3829,12 +3828,24 @@ static void stmmac_set_rx_mode(struct net_device *dev)
static int stmmac_change_mtu(struct net_device *dev, int new_mtu) static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
{ {
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
int txfifosz = priv->plat->tx_fifo_size;
if (txfifosz == 0)
txfifosz = priv->dma_cap.tx_fifo_size;
txfifosz /= priv->plat->tx_queues_to_use;
if (netif_running(dev)) { if (netif_running(dev)) {
netdev_err(priv->dev, "must be stopped to change its MTU\n"); netdev_err(priv->dev, "must be stopped to change its MTU\n");
return -EBUSY; return -EBUSY;
} }
new_mtu = STMMAC_ALIGN(new_mtu);
/* If condition true, FIFO is too small or MTU too large */
if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB))
return -EINVAL;
dev->mtu = new_mtu; dev->mtu = new_mtu;
netdev_update_features(dev); netdev_update_features(dev);
......
...@@ -624,6 +624,8 @@ static int stmmac_test_mcfilt(struct stmmac_priv *priv) ...@@ -624,6 +624,8 @@ static int stmmac_test_mcfilt(struct stmmac_priv *priv)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (netdev_uc_count(priv->dev) >= priv->hw->unicast_filter_entries) if (netdev_uc_count(priv->dev) >= priv->hw->unicast_filter_entries)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (netdev_mc_count(priv->dev) >= priv->hw->multicast_filter_bins)
return -EOPNOTSUPP;
while (--tries) { while (--tries) {
/* We only need to check the mc_addr for collisions */ /* We only need to check the mc_addr for collisions */
...@@ -666,6 +668,8 @@ static int stmmac_test_ucfilt(struct stmmac_priv *priv) ...@@ -666,6 +668,8 @@ static int stmmac_test_ucfilt(struct stmmac_priv *priv)
if (stmmac_filter_check(priv)) if (stmmac_filter_check(priv))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (netdev_uc_count(priv->dev) >= priv->hw->unicast_filter_entries)
return -EOPNOTSUPP;
if (netdev_mc_count(priv->dev) >= priv->hw->multicast_filter_bins) if (netdev_mc_count(priv->dev) >= priv->hw->multicast_filter_bins)
return -EOPNOTSUPP; return -EOPNOTSUPP;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册