* [PATCH 11/12] net-next: mediatek: only wake the queue if it is stopped
From: John Crispin @ 2016-05-05 9:26 UTC (permalink / raw)
To: David S. Miller; +Cc: nbd, netdev, linux-mediatek, linux-kernel, John Crispin
In-Reply-To: <1462440385-51939-1-git-send-email-john@phrozen.org>
The current code unconditionally wakes up the queue at the end of each
tx_poll action. Change the code to only wake up the queues if any of
them have actually been stopped before.
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 81155a1..2d3c464 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -701,6 +701,20 @@ static inline int mtk_cal_txd_req(struct sk_buff *skb)
return nfrags;
}
+static int mtk_queue_stopped(struct mtk_eth *eth)
+{
+ int i;
+
+ for (i = 0; i < MTK_MAC_COUNT; i++) {
+ if (!eth->netdev[i])
+ continue;
+ if (netif_queue_stopped(eth->netdev[i]))
+ return 1;
+ }
+
+ return 0;
+}
+
static void mtk_wake_queue(struct mtk_eth *eth)
{
int i;
@@ -945,7 +959,8 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
if (!total)
return 0;
- if (atomic_read(&ring->free_count) > ring->thresh)
+ if (mtk_queue_stopped(eth) &&
+ (atomic_read(&ring->free_count) > ring->thresh))
mtk_wake_queue(eth);
return total;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 09/12] net-next: mediatek: increase watchdog_timeo
From: John Crispin @ 2016-05-05 9:26 UTC (permalink / raw)
To: David S. Miller; +Cc: nbd, netdev, linux-mediatek, linux-kernel, John Crispin
In-Reply-To: <1462440385-51939-1-git-send-email-john@phrozen.org>
During stress testing, after reducing the threshold value, we have seen
TX timeouts that were caused by the watchdog_timeo value being too low.
Increase the value to 5 * HZ which is a value commonly used by many other
drivers.
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 4439991..12e9f1a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1704,7 +1704,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
SET_NETDEV_DEV(eth->netdev[id], eth->dev);
- eth->netdev[id]->watchdog_timeo = HZ;
+ eth->netdev[id]->watchdog_timeo = 5 * HZ;
eth->netdev[id]->netdev_ops = &mtk_netdev_ops;
eth->netdev[id]->base_addr = (unsigned long)eth->base;
eth->netdev[id]->vlan_features = MTK_HW_FEATURES &
--
1.7.10.4
^ permalink raw reply related
* [PATCH 08/12] net-next: mediatek: fix threshold value
From: John Crispin @ 2016-05-05 9:26 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
In-Reply-To: <1462440385-51939-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
The logic to calculate the threshold value for stopping the TX queue is
bad. Currently it will always use 1/2 of the rings size, which is way too
much. Set the threshold to MAX_SKB_FRAGS. This makes sure that the queue
is stopped when there is not enough room to accept an additional segment.
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 08f3df4..4439991 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1028,8 +1028,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
ring->next_free = &ring->dma[0];
ring->last_free = &ring->dma[MTK_DMA_SIZE - 2];
- ring->thresh = max((unsigned long)MTK_DMA_SIZE >> 2,
- MAX_SKB_FRAGS);
+ ring->thresh = MAX_SKB_FRAGS;
/* make sure that all changes to the dma ring are flushed before we
* continue
--
1.7.10.4
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* [PATCH 07/12] net-next: mediatek: disable all interrupts during probe
From: John Crispin @ 2016-05-05 9:26 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
In-Reply-To: <1462440385-51939-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
The current code only disables those IRQs that we will later use. To
ensure that we have a predefined state, we really want to disable all IRQs.
Change the code to disable all IRQs to achieve this.
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 60095be..08f3df4 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1391,7 +1391,7 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
/* disable delay and normal interrupt */
mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
- mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
+ mtk_irq_disable(eth, ~0);
mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
mtk_w32(eth, 0, MTK_RST_GL);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 06/12] net-next: mediatek: add next data pointer coherency protection
From: John Crispin @ 2016-05-05 9:26 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
In-Reply-To: <1462440385-51939-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
The QDMA engine can fail to update the register pointing to the next TX
descriptor if this bit does not get set in the QDMA configuration register.
Not setting this bit can result in invalid values inside the TX rings
registers which will causes TX stalls.
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 2e79af9..60095be 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1277,7 +1277,7 @@ static int mtk_start_dma(struct mtk_eth *eth)
mtk_w32(eth,
MTK_TX_WB_DDONE | MTK_RX_DMA_EN | MTK_TX_DMA_EN |
MTK_RX_2B_OFFSET | MTK_DMA_SIZE_16DWORDS |
- MTK_RX_BT_32DWORDS,
+ MTK_RX_BT_32DWORDS | MTK_NDP_CO_PRO,
MTK_QDMA_GLO_CFG);
return 0;
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 57f7e8a..a5eb7c6 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -91,6 +91,7 @@
#define MTK_QDMA_GLO_CFG 0x1A04
#define MTK_RX_2B_OFFSET BIT(31)
#define MTK_RX_BT_32DWORDS (3 << 11)
+#define MTK_NDP_CO_PRO BIT(10)
#define MTK_TX_WB_DDONE BIT(6)
#define MTK_DMA_SIZE_16DWORDS (2 << 4)
#define MTK_RX_DMA_BUSY BIT(3)
--
1.7.10.4
^ permalink raw reply related
* [PATCH 05/12] net-next: mediatek: dropped rx packets are not being counted properly
From: John Crispin @ 2016-05-05 9:26 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
In-Reply-To: <1462440385-51939-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
There are 2 places inside mtk_poll_rx where rx_dropped is not being
incremented properly. Fix this by adding the missing code to increment
the counter.
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 7fdd1a3..2e79af9 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -826,6 +826,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
DMA_FROM_DEVICE);
if (unlikely(dma_mapping_error(&netdev->dev, dma_addr))) {
skb_free_frag(new_data);
+ netdev->stats.rx_dropped++;
goto release_desc;
}
@@ -833,6 +834,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
skb = build_skb(data, ring->frag_size);
if (unlikely(!skb)) {
put_page(virt_to_head_page(new_data));
+ netdev->stats.rx_dropped++;
goto release_desc;
}
skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 04/12] net-next: mediatek: invalid buffer lookup in mtk_tx_map()
From: John Crispin @ 2016-05-05 9:26 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
In-Reply-To: <1462440385-51939-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
The lookup of the tx_buffer in the error path inside mtk_tx_map() uses the
wrong descriptor pointer. This looks like a copy & paste error. Change the
code to use the correct pointer.
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index e415986..7fdd1a3 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -671,7 +671,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
err_dma:
do {
- tx_buf = mtk_desc_to_tx_buf(ring, txd);
+ tx_buf = mtk_desc_to_tx_buf(ring, itxd);
/* unmap dma */
mtk_tx_unmap(&dev->dev, tx_buf);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 03/12] net-next: mediatek: fix missing free of scratch memory
From: John Crispin @ 2016-05-05 9:26 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
In-Reply-To: <1462440385-51939-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
Scratch memory gets allocated in mtk_init_fq_dma() but the corresponding
code to free it is missing inside mtk_dma_free() causing a memory leak.
With this patch applied, we can run ifconfig/up/down several thousand
times without any problems.
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 18 +++++++++++++-----
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 0ed49a4..e415986 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -469,14 +469,14 @@ static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd,
/* the qdma core needs scratch memory to be setup */
static int mtk_init_fq_dma(struct mtk_eth *eth)
{
- dma_addr_t phy_ring_head, phy_ring_tail;
+ dma_addr_t phy_ring_tail;
int cnt = MTK_DMA_SIZE;
dma_addr_t dma_addr;
int i;
eth->scratch_ring = dma_alloc_coherent(eth->dev,
cnt * sizeof(struct mtk_tx_dma),
- &phy_ring_head,
+ ð->phy_scratch_ring,
GFP_ATOMIC | __GFP_ZERO);
if (unlikely(!eth->scratch_ring))
return -ENOMEM;
@@ -493,19 +493,19 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
return -ENOMEM;
memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt);
- phy_ring_tail = phy_ring_head +
+ phy_ring_tail = eth->phy_scratch_ring +
(sizeof(struct mtk_tx_dma) * (cnt - 1));
for (i = 0; i < cnt; i++) {
eth->scratch_ring[i].txd1 =
(dma_addr + (i * MTK_QDMA_PAGE_SIZE));
if (i < cnt - 1)
- eth->scratch_ring[i].txd2 = (phy_ring_head +
+ eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring +
((i + 1) * sizeof(struct mtk_tx_dma)));
eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE);
}
- mtk_w32(eth, phy_ring_head, MTK_QDMA_FQ_HEAD);
+ mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD);
mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL);
mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT);
mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN);
@@ -1205,6 +1205,14 @@ static void mtk_dma_free(struct mtk_eth *eth)
for (i = 0; i < MTK_MAC_COUNT; i++)
if (eth->netdev[i])
netdev_reset_queue(eth->netdev[i]);
+ if (eth->scratch_ring) {
+ dma_free_coherent(eth->dev,
+ MTK_DMA_SIZE * sizeof(struct mtk_tx_dma),
+ eth->scratch_ring,
+ eth->phy_scratch_ring);
+ eth->scratch_ring = NULL;
+ eth->phy_scratch_ring = 0;
+ }
mtk_tx_clean(eth);
mtk_rx_clean(eth);
kfree(eth->scratch_head);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index eed626d..57f7e8a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -357,6 +357,7 @@ struct mtk_rx_ring {
* @rx_ring: Pointer to the memore holding info about the RX ring
* @rx_napi: The NAPI struct
* @scratch_ring: Newer SoCs need memory for a second HW managed TX ring
+ * @phy_scratch_ring: physical address of scratch_ring
* @scratch_head: The scratch memory that scratch_ring points to.
* @clk_ethif: The ethif clock
* @clk_esw: The switch clock
@@ -384,6 +385,7 @@ struct mtk_eth {
struct mtk_rx_ring rx_ring;
struct napi_struct rx_napi;
struct mtk_tx_dma *scratch_ring;
+ dma_addr_t phy_scratch_ring;
void *scratch_head;
struct clk *clk_ethif;
struct clk *clk_esw;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 02/12] net-next: mediatek: add missing return code check
From: John Crispin @ 2016-05-05 9:26 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
In-Reply-To: <1462440385-51939-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
The code fails to check if the scratch memory was properly allocated. Add
this check and return with an error if the allocation failed.
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 07674e5..0ed49a4 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -483,6 +483,9 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE,
GFP_KERNEL);
+ if (unlikely(!eth->scratch_head))
+ return -ENOMEM;
+
dma_addr = dma_map_single(eth->dev,
eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE,
DMA_FROM_DEVICE);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 00/12] net-next: mediatek: bug fixes and tx stall fixes
From: John Crispin @ 2016-05-05 9:26 UTC (permalink / raw)
To: David S. Miller; +Cc: nbd, netdev, linux-mediatek, linux-kernel, John Crispin
This series is a collection of fixes for bugs that we stumble across while
doing more performance testing and code level review.
John Crispin (12):
net-next: mediatek: fix DQL support
net-next: mediatek: add missing return code check
net-next: mediatek: fix missing free of scratch memory
net-next: mediatek: invalid buffer lookup in mtk_tx_map()
net-next: mediatek: dropped rx packets are not being counted properly
net-next: mediatek: add next data pointer coherency protection
net-next: mediatek: disable all interrupts during probe
net-next: mediatek: fix threshold value
net-next: mediatek: increase watchdog_timeo
net-next: mediatek: fix off by one in the TX ring allocation
net-next: mediatek: only wake the queue if it is stopped
net-next: mediatek: remove superfluous queue wake up call
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 94 ++++++++++++++++++---------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 +
2 files changed, 65 insertions(+), 32 deletions(-)
--
1.7.10.4
^ permalink raw reply
* [PATCH 3/3] net-next: mediatek: add RX delay support
From: John Crispin @ 2016-05-05 9:17 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
In-Reply-To: <1462439856-51788-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
If an external Gigabit PHY is connected to either of the MACs we need to
tell the to use a RX delay. Not doing so will result in heavy packet loss
and/or data corruption of RX traffic.
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index d397bec..41cdc0d 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -226,6 +226,7 @@ static int mtk_phy_connect(struct mtk_mac *mac)
return -ENODEV;
switch (of_get_phy_mode(np)) {
+ case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII:
ge_mode = 0;
break;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/3] net-next: mediatek: add fixed-phy support
From: John Crispin @ 2016-05-05 9:17 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
In-Reply-To: <1462439856-51788-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
The MT7623 SoC has a builtin gigabit switch. If we want to use it, GMAC1
needs to be configured using a fixed link speed and flow control settings.
The easiest way to do this is to used the fixed-phy driver, allowing us to
reuse the existing mdio polling code to setup the MAC.
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 093073c..d397bec 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -219,6 +219,9 @@ static int mtk_phy_connect(struct mtk_mac *mac)
u32 val, ge_mode;
np = of_parse_phandle(mac->of_node, "phy-handle", 0);
+ if (!np && of_phy_is_fixed_link(mac->of_node))
+ if (!of_phy_register_fixed_link(mac->of_node))
+ np = of_node_get(mac->of_node);
if (!np)
return -ENODEV;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/3] net-next: mediatek: fix gigabit and flow control advertisement
From: John Crispin @ 2016-05-05 9:17 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
In-Reply-To: <1462439856-51788-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
The current code will not setup the PHYs advertisement features correctly.
Fix this and properly advertise Gigabit features and properly handle
asymmetric pause frames.
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index c984462..093073c 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -133,6 +133,8 @@ static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
static void mtk_phy_link_adjust(struct net_device *dev)
{
struct mtk_mac *mac = netdev_priv(dev);
+ u16 lcl_adv, rmt_adv = 0;
+ u8 flowctrl;
u32 mcr = MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG |
MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN |
MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN |
@@ -154,7 +156,16 @@ static void mtk_phy_link_adjust(struct net_device *dev)
mcr |= MAC_MCR_FORCE_DPX;
if (mac->phy_dev->pause)
- mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
+ rmt_adv = LPA_PAUSE_CAP;
+ if (mac->phy_dev->asym_pause)
+ rmt_adv |= LPA_PAUSE_ASYM;
+
+ lcl_adv = mii_advertise_flowctrl(FLOW_CTRL_RX | FLOW_CTRL_TX);
+ flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
+ if (flowctrl & FLOW_CTRL_TX)
+ mcr |= MAC_MCR_FORCE_TX_FC;
+ if (flowctrl & FLOW_CTRL_RX)
+ mcr |= MAC_MCR_FORCE_RX_FC;
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
@@ -236,7 +247,8 @@ static int mtk_phy_connect(struct mtk_mac *mac)
mac->phy_dev->autoneg = AUTONEG_ENABLE;
mac->phy_dev->speed = 0;
mac->phy_dev->duplex = 0;
- mac->phy_dev->supported &= PHY_BASIC_FEATURES;
+ mac->phy_dev->supported &= PHY_GBIT_FEATURES | SUPPORTED_Pause |
+ ~SUPPORTED_Asym_Pause;
mac->phy_dev->advertising = mac->phy_dev->supported |
ADVERTISED_Autoneg;
phy_start_aneg(mac->phy_dev);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 0/3] net-next: mediatek: improve phy support
From: John Crispin @ 2016-05-05 9:17 UTC (permalink / raw)
To: David S. Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, nbd-Vt+b4OUoWG0
This series contains 3 patches. One adds support for fixed-phy, making
boards work where the internal gigabit switch is used. Additionally the
series fixes support for GBit PHYs that so far only worked at 100Mbit.
John Crispin (3):
net-next: mediatek: fix gigabit and flow control advertisement
net-next: mediatek: add fixed-phy support
net-next: mediatek: add RX delay support
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
--
1.7.10.4
^ permalink raw reply
* Re: [PATCH] netdev: enc28j60 kernel panic fix.
From: Francois Romieu @ 2016-05-05 8:51 UTC (permalink / raw)
To: David Russell; +Cc: netdev
In-Reply-To: <CAEGHc+xdoSVa9J_uYm-Az7n4xc+mycy7Jf1p75pss3eVK3jUHA@mail.gmail.com>
David Russell <david@aprsworld.com> :
> When connected directly to another system (not via a switch)
> eventually a condition where a NULL pointer dereference occurs in
> enc28j60_hw_tx() and this patch simply checks for that condition and
> returns gracefully without causing a kernel panic. I believe, but
> have not investigated this is caused by a packet collision and am not
> sure if the kernel tracks collisions or counts them as errors, so that
> should probably be added if this is what's happening. I'm also not
> familiar with the linux kernel, so may have fixed this in a less than
> ideal way.
Is it possible for EIR.EIR_TXERIF and EIR.EIR_TXIF to be set for the
same packet ?
If so the driver is intrinsically racy:
- EIR.EIR_TXIF completes transmission, clears tx_skb and enables queueing
again (see netif_wake_queue in enc28j60_tx_clear)
- insert start_xmit here: tx_skb is set and enc28j60_hw_tx is scheduled
for late execution (user context work)
- EIR.EIR_EIR.EIR_TXERIF issues same enc28j60_tx_clear and clears tx_skb
- enc28j60_hw_tx is run but tx_skb is NULL
> diff --git a/drivers/net/ethernet/microchip/enc28j60.c
> b/drivers/net/ethernet/microchip/enc28j60.c
> index 86ea17e..36ac65f 100644
> --- a/drivers/net/ethernet/microchip/enc28j60.c
> +++ b/drivers/net/ethernet/microchip/enc28j60.c
> @@ -1233,6 +1233,9 @@ static void enc28j60_irq_work_handler(struct
> work_struct *work)
> */
> static void enc28j60_hw_tx(struct enc28j60_net *priv)
> {
> + if (!priv->tx_skb)
> + return;
> +
> if (netif_msg_tx_queued(priv))
> printk(KERN_DEBUG DRV_NAME
> ": Tx Packet Len:%d\n", priv->tx_skb->len);
enc28j60_hw_tx isn't the culprit. It's the victim.
This change silences the bug but it does not fix it at all.
--
Ueimor
^ permalink raw reply
* Re: [PATCH net-next 06/13] net: original ingress device index in PKTINFO
From: Julian Anastasov @ 2016-05-05 8:41 UTC (permalink / raw)
To: David Ahern; +Cc: netdev
In-Reply-To: <1462419210-10463-7-git-send-email-dsa@cumulusnetworks.com>
Hello,
On Wed, 4 May 2016, David Ahern wrote:
> Applications such as OSPF and BFD need the original ingress device not
> the VRF device; the latter can be derived from the former. To that end
> add the skb_iif to inet_skb_parm and set it in ipv4 code after clearing
> the skb control buffer similar to IPv6. From there the pktinfo can just
> pull it from cb with the PKTINFO_SKB_CB cast.
>
> The previous patch moving the skb->dev change to L3 means nothing else
> is needed for IPv6; it just works.
>
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
> ---
> include/net/ip.h | 1 +
> net/ipv4/ip_input.c | 1 +
> net/ipv4/ip_sockglue.c | 9 +++++++--
> 3 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/ip.h b/include/net/ip.h
> index 247ac82e9cf2..37165fba3741 100644
> --- a/include/net/ip.h
> +++ b/include/net/ip.h
> @@ -36,6 +36,7 @@
> struct sock;
>
> struct inet_skb_parm {
> + int iif;
> struct ip_options opt; /* Compiled IP options */
> unsigned char flags;
>
> diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
> index 37375eedeef9..4b351af3e67b 100644
> --- a/net/ipv4/ip_input.c
> +++ b/net/ipv4/ip_input.c
> @@ -478,6 +478,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
>
> /* Remove any debris in the socket control block */
> memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
> + IPCB(skb)->iif = skb->skb_iif;
For loopback traffic (including looped back multicast)
this is now a zero :( Can inet_iif be moved to ip_rcv_finish
instead? Still, we spend cycles in fast path in case nobody
listens for such info.
> /* Must drop socket now because of tproxy. */
> skb_orphan(skb);
> diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
> index bdb222c0c6a2..dbcd027c38e7 100644
> --- a/net/ipv4/ip_sockglue.c
> +++ b/net/ipv4/ip_sockglue.c
> @@ -476,9 +476,9 @@ static bool ipv4_datagram_support_cmsg(const struct sock *sk,
> (!skb->dev))
> return false;
>
> + /* see comment in ipv4_pktinfo_prepare about CB re-use */
> info = PKTINFO_SKB_CB(skb);
> info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr;
> - info->ipi_ifindex = skb->dev->ifindex;
This code is only for SOF_TIMESTAMPING_OPT_CMSG.
I'm not sure skb passes ip_rcv in all cases. So, we can not
easily remove it.
Regards
^ permalink raw reply
* Re: [v10, 7/7] mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0
From: Arnd Bergmann @ 2016-05-05 8:31 UTC (permalink / raw)
To: linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
Cc: Mark Rutland, ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
xiaobo.xie-3arQi8VN3Tc, linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
Bhupesh Sharma, Claudiu Manoil, devicetree-u79uwXL29TY76Z2rM5mHXA,
Kumar Gala, Scott Wood, Rob Herring, Santosh Shilimkar,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-mmc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, leoyang.li-3arQi8VN3Tc,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu
In-Reply-To: <1462417950-46796-8-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
On Thursday 05 May 2016 11:12:30 Yangbo Lu wrote:
>
> + fsl_guts_init();
> + svr = fsl_guts_get_svr();
> + if (svr) {
> + esdhc->soc_ver = SVR_SOC_VER(svr);
> + esdhc->soc_rev = SVR_REV(svr);
> + } else {
> + dev_err(&pdev->dev, "Failed to get SVR value!\n");
> + }
> +
>
Sorry for jumping in again after not participating in the discussion for the
past few versions.
What happened to my suggestion of making this a platform-independent interface
to avoid the link time dependency?
Specifically, why not add an exported function to drivers/base/soc.c that
uses glob_match() for comparing a string in the device driver to the ID
of the SoC that is set by whatever SoC identifying driver the platform
has?
Arnd
^ permalink raw reply
* Re: [REGRESSION] asix: Lots of asix_rx_fixup() errors and slow transmissions
From: Dean Jenkins @ 2016-05-05 8:11 UTC (permalink / raw)
To: John Stultz
Cc: Guodong Xu, lkml, Mark Craske, David S. Miller, YongQin Liu,
linux-usb, netdev, Ivan Vecera, David B. Robins
In-Reply-To: <CALAqxLXbMuK3Sj45vbf_r4GYQR=8bGUrhDz9-7+S2pbO_dJZ4A@mail.gmail.com>
On 05/05/16 00:45, John Stultz wrote:
> On Tue, May 3, 2016 at 3:54 AM, Dean Jenkins <Dean_Jenkins@mentor.com> wrote:
>> On 03/05/16 11:04, Guodong Xu wrote:
>>> did you test on ARM 64-bit system or ARM 32-bit? I ask because HiKey
>>> is an ARM 64-bit system. I suggest we should be careful on that. I saw
>>> similar issues when transferring to a 64-bit system in other net
>>> drivers.
>> We used 32-bit ARM and never tested on 64-bit ARM so I suggest that the
>> commits need to be reviewed with 64-bit OS in mind.
>>>
>>> Do you have any suggestion on this regard?
>> Try testing on a Linux PC x86 32-bit OS which has has a kernel containing my
>> ASIX commits. This will help to confirm whether the failure is related to
>> 32-bit or 64-bit OS. Then try with Linux PC x86 64-bit OS, this should fail
>> otherwise it points to something specific in your ARM 64-bit platform.
> Just as a sample point, I have managed to reproduce exactly this issue
> on an x86_64 system by simply scp'ing a large file.
Please tell us the x86_64 kernel version number that you used and which
Linux Distribution it was ? This allows other people a chance to
reproduce your observations.
>
> [ 417.819276] asix 1-5:1.0 eth1: asix_rx_fixup() Data Header
> synchronisation was lost, remaining 988
It is interesting that the reported "remaining" value is 988. Is 988
always shown ? I mean that do you see any other "remaining" values for
the "Data Header synchronisation was lost" error message ?
> [ 417.823415] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0xef830347, offset 4
The gap in the timestamps shows 417.823415 - 417.819276 = 0.004139 = 4ms
which is a large gap in terms of USB 2.0 high speed communications. This
gap is expected to be in the 100us range for consecutive URBs. So 4ms is
strange.
The expectation is that the "Data Header synchronisation was lost" error
message resets the 32-bit header word synchronisation to the start of
the next URB buffer. The "Bad Header Length, offset 4" is the expected
outcome for the next URB because it is unlikely the 32-bit header word
is at the start of URB buffer due to Ethernet frames spanning across URBs.
> [ 417.827502] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x31e2b348, offset 4
Timestamps show the gap to be 4ms which is strange for USB 2.0 high
speed, are you sure high speed mode is being used ?
> [ 417.843779] asix 1-5:1.0 eth1: asix_rx_fixup() Data Header
> synchronisation was lost, remaining 988
> [ 417.847921] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x8af91035, offset 4
> [ 417.852004] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x8521fa03, offset 4
> [ 418.273394] asix 1-5:1.0 eth1: asix_rx_fixup() Data Header
> synchronisation was lost, remaining 988
> [ 418.277532] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x33cd9c7c, offset 4
> [ 418.281683] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x3d850896, offset 4
> [ 418.286227] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x86443357, offset 4
> [ 418.290319] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0xee6c81d1, offset 4
>
> I don't have any 32bit x86 installs around so I'm not sure I can easly
> test there, but its clear its not arm64 specific.
I agree the issue is not specific to your ARM 64 bit platform.
Please can you supply the output of ifconfig for the USB to Ethernet
adaptor, your example above shows eth1 as the device.
Please show the output of ifconfig eth1 before and after the issue is
seen. This will show us whether the kernel logs any network errors and
how many bytes have been transferred.
After the issue is seen, please can you show us the output of "dmesg |
grep asix" so that we can see status messages from the ASIX driver that
the USB to Ethernet adaptor is using. In particular we need to check
that USB high speed operation (480Mbps) is being used and not full speed
operation (12Mbps).
Thanks,
Regards,
Dean
>
> thanks
> -john
--
Dean Jenkins
Embedded Software Engineer
Linux Transportation Solutions
Mentor Embedded Software Division
Mentor Graphics (UK) Ltd.
^ permalink raw reply
* Re: [PATCH net-next 03/13] net: l3mdev: Allow send on enslaved interface
From: Julian Anastasov @ 2016-05-05 7:40 UTC (permalink / raw)
To: David Ahern; +Cc: netdev
In-Reply-To: <1462419210-10463-4-git-send-email-dsa@cumulusnetworks.com>
Hello,
On Wed, 4 May 2016, David Ahern wrote:
> Allow udp and raw sockets to send by oif that is an enslaved interface
> versus the l3mdev/VRF device. For example, this allows BFD to use ifindex
> from IP_PKTINFO on a receive to send a response without the need to
> convert to the VRF index. It also allows ping and ping6 to work when
> specifying an enslaved interface (e.g., ping -I swp1 <ip>) which is
> a natural use case.
>
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
> ---
> drivers/net/vrf.c | 2 ++
> net/ipv4/route.c | 4 ++++
> net/l3mdev/l3mdev.c | 20 +++++++++++++++-----
> 3 files changed, 21 insertions(+), 5 deletions(-)
>
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index 8c8c655bb2c4..a1f2830d8110 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -2146,6 +2146,7 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
> unsigned int flags = 0;
> struct fib_result res;
> struct rtable *rth;
> + int master_idx;
> int orig_oif;
> int err = -ENETUNREACH;
>
> @@ -2155,6 +2156,9 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
>
> orig_oif = fl4->flowi4_oif;
>
> + master_idx = l3mdev_master_ifindex_by_index(net, fl4->flowi4_oif);
> + if (master_idx)
> + fl4->flowi4_oif = master_idx;
Changing the flowi4_oif at this point can have
bad effects. I remember for recent commit for __mkroute_output
where the route caching is disabled if traffic is redirected
to loopback. I think, such change can affect the route
caching, for example, now we use nexthop on master_idx to
cache routes for orig_oif. Such problems with the caching
in the past always caused lookups to return wrong cached result
for other users. But this is only my fears, I don't know
the actual result of this change. May be you are trying to
change flowi4_oif at one place instead of every caller.
Regards
^ permalink raw reply
* A couple of questions about the SKB fragments
From: Ilya Matveychikov @ 2016-05-05 7:40 UTC (permalink / raw)
To: netdev; +Cc: Aleksey.Baulin
Hello folks,
While working with fragmented SKBs we've got stuck with the following:
- is it possible for an SKB fragment in skb_shinfo(skb)->frag_list to
be fragmented too (i.e. to have SKBs in frag_list)?
- do skb->len and skb->data_len contain the whole SKB length,
including the length of all fragments (not only the paged parts)?
Is there any docs except the kernel sources itself to refer to?
Thanks.
^ permalink raw reply
* [PATCH] cfg80211/nl80211: add wifi tx power mode switching support
From: Wei-Ning Huang @ 2016-05-05 6:44 UTC (permalink / raw)
To: Linux-Wireless
Cc: LKML, Johannes Berg, Sameer Nanda, Todd Broch, Wei-Ning Huang,
davem, netdev
Recent new hardware has the ability to switch between tablet mode and
clamshell mode. To optimize WiFi performance, we want to be able to use
different power table between modes. This patch adds a new netlink
message type and cfg80211_ops function to allow userspace to trigger a
power mode switch for a given wireless interface.
Signed-off-by: Wei-Ning Huang <wnhuang@chromium.org>
---
include/net/cfg80211.h | 11 +++++++++++
include/uapi/linux/nl80211.h | 21 +++++++++++++++++++++
net/wireless/nl80211.c | 16 ++++++++++++++++
net/wireless/rdev-ops.h | 22 ++++++++++++++++++++++
net/wireless/trace.h | 20 ++++++++++++++++++++
5 files changed, 90 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9e1b24c..aa77fa0 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2370,6 +2370,12 @@ struct cfg80211_qos_map {
* @get_tx_power: store the current TX power into the dbm variable;
* return 0 if successful
*
+ * @set_tx_power_mode: set the transmit power mode. Some device have the ability
+ * to transform between different mode such as clamshell and tablet mode.
+ * set_tx_power_mode allows setting of different TX power mode at runtime.
+ * @get_tx_power_mode: store the current TX power mode into the mode variable;
+ * return 0 if successful
+ *
* @set_wds_peer: set the WDS peer for a WDS interface
*
* @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting
@@ -2631,6 +2637,11 @@ struct cfg80211_ops {
int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
int *dbm);
+ int (*set_tx_power_mode)(struct wiphy *wiphy,
+ enum nl80211_tx_power_mode mode);
+ int (*get_tx_power_mode)(struct wiphy *wiphy,
+ enum nl80211_tx_power_mode *mode);
+
int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
const u8 *addr);
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 5a30a75..9b1888a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1796,6 +1796,9 @@ enum nl80211_commands {
* connecting to a PCP, and in %NL80211_CMD_START_AP to start
* a PCP instead of AP. Relevant for DMG networks only.
*
+ * @NL80211_ATTR_WIPHY_TX_POWER_MODE: Transmit power mode. See
+ * &enum nl80211_tx_power_mode for possible values.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2172,6 +2175,8 @@ enum nl80211_attrs {
NL80211_ATTR_PBSS,
+ NL80211_ATTR_WIPHY_TX_POWER_MODE,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -3703,6 +3708,22 @@ enum nl80211_tx_power_setting {
};
/**
+ * enum nl80211_tx_power_mode - TX power mode setting
+ * @NL80211_TX_POWER_LOW: general low TX power mode
+ * @NL80211_TX_POWER_MEDIUM: general medium TX power mode
+ * @NL80211_TX_POWER_HIGH: general high TX power mode
+ * @NL80211_TX_POWER_CLAMSHELL: clamshell mode TX power mode
+ * @NL80211_TX_POWER_TABLET: tablet mode TX power mode
+ */
+enum nl80211_tx_power_mode {
+ NL80211_TX_POWER_LOW,
+ NL80211_TX_POWER_MEDIUM,
+ NL80211_TX_POWER_HIGH,
+ NL80211_TX_POWER_CLAMSHELL,
+ NL80211_TX_POWER_TABLET,
+};
+
+/**
* enum nl80211_packet_pattern_attr - packet pattern attribute
* @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
* @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 056a730..61b474d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -402,6 +402,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
[NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
[NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
+ [NL80211_ATTR_WIPHY_TX_POWER_MODE] = { .type = NLA_U32 },
};
/* policy for the key attributes */
@@ -2218,6 +2219,21 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
return result;
}
+ if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_MODE]) {
+ enum nl80211_tx_power_mode mode;
+ int idx = 0;
+
+ if (!rdev->ops->set_tx_power_mode)
+ return -EOPNOTSUPP;
+
+ idx = NL80211_ATTR_WIPHY_TX_POWER_MODE;
+ mode = nla_get_u32(info->attrs[idx]);
+
+ result = rdev_set_tx_power_mode(rdev, mode);
+ if (result)
+ return result;
+ }
+
if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
u32 tx_ant, rx_ant;
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 8ae0c04..c3a1035 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -552,6 +552,28 @@ static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev,
return ret;
}
+static inline int
+rdev_set_tx_power_mode(struct cfg80211_registered_device *rdev,
+ enum nl80211_tx_power_mode mode)
+{
+ int ret;
+ trace_rdev_set_tx_power_mode(&rdev->wiphy, mode);
+ ret = rdev->ops->set_tx_power_mode(&rdev->wiphy, mode);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+
+static inline int
+rdev_get_tx_power_mode(struct cfg80211_registered_device *rdev,
+ enum nl80211_tx_power_mode *mode)
+{
+ int ret;
+ trace_rdev_get_tx_power_mode(&rdev->wiphy);
+ ret = rdev->ops->get_tx_power_mode(&rdev->wiphy, mode);
+ trace_rdev_return_int_int(&rdev->wiphy, ret, *mode);
+ return ret;
+}
+
static inline int rdev_set_wds_peer(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *addr)
{
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 09b242b..132c8c2 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1420,6 +1420,26 @@ TRACE_EVENT(rdev_set_tx_power,
WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm)
);
+DEFINE_EVENT(wiphy_only_evt, rdev_get_tx_power_mode,
+ TP_PROTO(struct wiphy *wiphy),
+ TP_ARGS(wiphy)
+);
+
+TRACE_EVENT(rdev_set_tx_power_mode,
+ TP_PROTO(struct wiphy *wiphy, enum nl80211_tx_power_mode mode),
+ TP_ARGS(wiphy, mode),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ __field(enum nl80211_tx_power_mode, mode)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ __entry->mode = mode;
+ ),
+ TP_printk(WIPHY_PR_FMT ", mode: %d",
+ WIPHY_PR_ARG, __entry->mode)
+);
+
TRACE_EVENT(rdev_return_int_int,
TP_PROTO(struct wiphy *wiphy, int func_ret, int func_fill),
TP_ARGS(wiphy, func_ret, func_fill),
--
2.1.2
^ permalink raw reply related
* [PATCH net-next] cxgb4: Reset dcb state machine and tx queue prio only if dcb is enabled
From: Hariprasad Shenai @ 2016-05-05 5:35 UTC (permalink / raw)
To: davem; +Cc: netdev, leedom, nirranjan, Hariprasad Shenai
When cxgb4 is enabled with CONFIG_CHELSIO_T4_DCB set, VI enable command
gets called with DCB enabled. But when we have a back to back setup with
DCB enabled on one side and non-DCB on the Peer side. Firmware doesn't
send any DCB_L2_CFG, and DCB priority is never set for Tx queue.
But driver resets the queue priority and state machine whenever there
is a link down, this patch fixes it by adding a check to reset only if
cxgb4_dcb_enabled() returns true.
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 38 +++++++++++++------------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index d7f40436f319..477db477b133 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -304,6 +304,22 @@ static void dcb_tx_queue_prio_enable(struct net_device *dev, int enable)
}
#endif /* CONFIG_CHELSIO_T4_DCB */
+int cxgb4_dcb_enabled(const struct net_device *dev)
+{
+#ifdef CONFIG_CHELSIO_T4_DCB
+ struct port_info *pi = netdev_priv(dev);
+
+ if (!pi->dcb.enabled)
+ return 0;
+
+ return ((pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED) ||
+ (pi->dcb.state == CXGB4_DCB_STATE_HOST));
+#else
+ return 0;
+#endif
+}
+EXPORT_SYMBOL(cxgb4_dcb_enabled);
+
void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat)
{
struct net_device *dev = adapter->port[port_id];
@@ -314,8 +330,10 @@ void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat)
netif_carrier_on(dev);
else {
#ifdef CONFIG_CHELSIO_T4_DCB
- cxgb4_dcb_state_init(dev);
- dcb_tx_queue_prio_enable(dev, false);
+ if (cxgb4_dcb_enabled(dev)) {
+ cxgb4_dcb_state_init(dev);
+ dcb_tx_queue_prio_enable(dev, false);
+ }
#endif /* CONFIG_CHELSIO_T4_DCB */
netif_carrier_off(dev);
}
@@ -494,22 +512,6 @@ static int link_start(struct net_device *dev)
return ret;
}
-int cxgb4_dcb_enabled(const struct net_device *dev)
-{
-#ifdef CONFIG_CHELSIO_T4_DCB
- struct port_info *pi = netdev_priv(dev);
-
- if (!pi->dcb.enabled)
- return 0;
-
- return ((pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED) ||
- (pi->dcb.state == CXGB4_DCB_STATE_HOST));
-#else
- return 0;
-#endif
-}
-EXPORT_SYMBOL(cxgb4_dcb_enabled);
-
#ifdef CONFIG_CHELSIO_T4_DCB
/* Handle a Data Center Bridging update message from the firmware. */
static void dcb_rpl(struct adapter *adap, const struct fw_port_cmd *pcmd)
--
2.3.4
^ permalink raw reply related
* [PATCH net 1/1] qede: prevent chip hang when increasing channels
From: Sudarsana Reddy Kalluru @ 2016-05-05 4:35 UTC (permalink / raw)
To: davem; +Cc: netdev, Yuval.Mintz, sudarsana.kalluru
qede requires qed to provide enough resources to accommodate 16 combined
channels, but that upper-bound isn't actually being enforced by it.
Instead, qed inform back to qede how many channels can be opened based on
available resources - but that calculation doesn't really take into account
the resources requested by qede; Instead it considers other FW/HW available
resources.
As a result, if a user would increase the number of channels to more than
16 [e.g., using ethtool] the chip would hang.
This change increments the resources requested by qede to 64 combined
channels instead of 16; This value is an upper bound on the possible
available channels [due to other FW/HW resources].
Signed-off-by: Sudarsana Reddy Kalluru <sudarsana.kalluru@qlogic.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
---
drivers/net/ethernet/qlogic/qede/qede_main.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 7869465..8d5248c 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -1938,8 +1938,6 @@ static struct qede_dev *qede_alloc_etherdev(struct qed_dev *cdev,
edev->q_num_rx_buffers = NUM_RX_BDS_DEF;
edev->q_num_tx_buffers = NUM_TX_BDS_DEF;
- DP_INFO(edev, "Allocated netdev with 64 tx queues and 64 rx queues\n");
-
SET_NETDEV_DEV(ndev, &pdev->dev);
memset(&edev->stats, 0, sizeof(edev->stats));
@@ -2090,9 +2088,9 @@ static void qede_update_pf_params(struct qed_dev *cdev)
{
struct qed_pf_params pf_params;
- /* 16 rx + 16 tx */
+ /* 64 rx + 64 tx */
memset(&pf_params, 0, sizeof(struct qed_pf_params));
- pf_params.eth_pf_params.num_cons = 32;
+ pf_params.eth_pf_params.num_cons = 128;
qed_ops->common->update_pf_params(cdev, &pf_params);
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next 2/2] net: l3mdev: Allow send on enslaved interface
From: David Ahern @ 2016-05-05 4:54 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
In-Reply-To: <1462424050-16084-1-git-send-email-dsa@cumulusnetworks.com>
Allow udp and raw sockets to send by oif that is an enslaved interface
versus the l3mdev/VRF device. For example, this allows BFD to use ifindex
from IP_PKTINFO on a receive to send a response without the need to
convert to the VRF index. It also allows ping and ping6 to work when
specifying an enslaved interface (e.g., ping -I swp1 <ip>) which is
a natural use case.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
drivers/net/vrf.c | 2 ++
net/ipv4/route.c | 4 ++++
net/l3mdev/l3mdev.c | 20 +++++++++++++++-----
3 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 4b2461ae5d3b..c8db55aa8280 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -648,6 +648,8 @@ static int vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
fl4->flowi4_flags |= FLOWI_FLAG_SKIP_NH_OIF;
fl4->flowi4_iif = LOOPBACK_IFINDEX;
+ /* make sure oif is set to VRF device for lookup */
+ fl4->flowi4_oif = dev->ifindex;
fl4->flowi4_tos = tos & IPTOS_RT_MASK;
fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8c8c655bb2c4..a1f2830d8110 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2146,6 +2146,7 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
unsigned int flags = 0;
struct fib_result res;
struct rtable *rth;
+ int master_idx;
int orig_oif;
int err = -ENETUNREACH;
@@ -2155,6 +2156,9 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
orig_oif = fl4->flowi4_oif;
+ master_idx = l3mdev_master_ifindex_by_index(net, fl4->flowi4_oif);
+ if (master_idx)
+ fl4->flowi4_oif = master_idx;
fl4->flowi4_iif = LOOPBACK_IFINDEX;
fl4->flowi4_tos = tos & IPTOS_RT_MASK;
fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
diff --git a/net/l3mdev/l3mdev.c b/net/l3mdev/l3mdev.c
index 0fe4211e646f..0fd8cc1417cd 100644
--- a/net/l3mdev/l3mdev.c
+++ b/net/l3mdev/l3mdev.c
@@ -112,12 +112,19 @@ struct dst_entry *l3mdev_get_rt6_dst(struct net *net,
struct dst_entry *dst = NULL;
struct net_device *dev;
- dev = dev_get_by_index(net, fl6->flowi6_oif);
- if (dev) {
- if (netif_is_l3_master(dev) &&
- dev->l3mdev_ops->l3mdev_get_rt6_dst)
+ if (fl6->flowi6_oif) {
+ rcu_read_lock();
+
+ dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
+ if (dev && netif_is_l3_slave(dev))
+ dev = netdev_master_upper_dev_get_rcu(dev);
+
+ if (dev && netif_is_l3_master(dev) &&
+ dev->l3mdev_ops->l3mdev_get_rt6_dst) {
dst = dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
- dev_put(dev);
+ }
+
+ rcu_read_unlock();
}
return dst;
@@ -141,6 +148,9 @@ int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4)
rcu_read_lock();
dev = dev_get_by_index_rcu(net, ifindex);
+ if (dev && netif_is_l3_slave(dev))
+ dev = netdev_master_upper_dev_get_rcu(dev);
+
if (dev && netif_is_l3_master(dev) &&
dev->l3mdev_ops->l3mdev_get_saddr) {
rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
--
2.1.4
^ permalink raw reply related
* [PATCH net-next 1/2] net: l3mdev: Move get_saddr and rt6_dst
From: David Ahern @ 2016-05-05 4:54 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
In-Reply-To: <1462424050-16084-1-git-send-email-dsa@cumulusnetworks.com>
Move l3mdev_rt6_dst_by_oif and l3mdev_get_saddr to l3mdev.c. Collapse
l3mdev_get_rt6_dst into l3mdev_rt6_dst_by_oif since it is the only
user and keep the l3mdev_get_rt6_dst name for consistency with other
hooks.
A follow-on patch adds more code to these functions making them long
for inlined functions.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
include/net/l3mdev.h | 56 +++-------------------------------------------------
net/ipv6/route.c | 2 +-
net/l3mdev/l3mdev.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 59 insertions(+), 54 deletions(-)
diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h
index c43a9c73de5e..78872bd1dc2c 100644
--- a/include/net/l3mdev.h
+++ b/include/net/l3mdev.h
@@ -130,52 +130,9 @@ static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
return rc;
}
-static inline int l3mdev_get_saddr(struct net *net, int ifindex,
- struct flowi4 *fl4)
-{
- struct net_device *dev;
- int rc = 0;
-
- if (ifindex) {
-
- rcu_read_lock();
-
- dev = dev_get_by_index_rcu(net, ifindex);
- if (dev && netif_is_l3_master(dev) &&
- dev->l3mdev_ops->l3mdev_get_saddr) {
- rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
- }
-
- rcu_read_unlock();
- }
-
- return rc;
-}
+int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4);
-static inline struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
- const struct flowi6 *fl6)
-{
- if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rt6_dst)
- return dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
-
- return NULL;
-}
-
-static inline
-struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
- const struct flowi6 *fl6)
-{
- struct dst_entry *dst = NULL;
- struct net_device *dev;
-
- dev = dev_get_by_index(net, fl6->flowi6_oif);
- if (dev) {
- dst = l3mdev_get_rt6_dst(dev, fl6);
- dev_put(dev);
- }
-
- return dst;
-}
+struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6);
#else
@@ -233,14 +190,7 @@ static inline int l3mdev_get_saddr(struct net *net, int ifindex,
}
static inline
-struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
- const struct flowi6 *fl6)
-{
- return NULL;
-}
-static inline
-struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
- const struct flowi6 *fl6)
+struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6)
{
return NULL;
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index af46e19205f5..c42fa1deb152 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1190,7 +1190,7 @@ struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
struct dst_entry *dst;
bool any_src;
- dst = l3mdev_rt6_dst_by_oif(net, fl6);
+ dst = l3mdev_get_rt6_dst(net, fl6);
if (dst)
return dst;
diff --git a/net/l3mdev/l3mdev.c b/net/l3mdev/l3mdev.c
index e925037fa0df..0fe4211e646f 100644
--- a/net/l3mdev/l3mdev.c
+++ b/net/l3mdev/l3mdev.c
@@ -97,3 +97,58 @@ u32 l3mdev_fib_table_by_index(struct net *net, int ifindex)
return tb_id;
}
EXPORT_SYMBOL_GPL(l3mdev_fib_table_by_index);
+
+/**
+ * l3mdev_get_rt6_dst - IPv6 route lookup based on flow. Returns
+ * cached route for L3 master device if relevant
+ * to flow
+ * @net: network namespace for device index lookup
+ * @fl6: IPv6 flow struct for lookup
+ */
+
+struct dst_entry *l3mdev_get_rt6_dst(struct net *net,
+ const struct flowi6 *fl6)
+{
+ struct dst_entry *dst = NULL;
+ struct net_device *dev;
+
+ dev = dev_get_by_index(net, fl6->flowi6_oif);
+ if (dev) {
+ if (netif_is_l3_master(dev) &&
+ dev->l3mdev_ops->l3mdev_get_rt6_dst)
+ dst = dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
+ dev_put(dev);
+ }
+
+ return dst;
+}
+EXPORT_SYMBOL_GPL(l3mdev_get_rt6_dst);
+
+/**
+ * l3mdev_get_saddr - get source address for a flow based on an interface
+ * enslaved to an L3 master device
+ * @net: network namespace for device index lookup
+ * @ifindex: Interface index
+ * @fl4: IPv4 flow struct
+ */
+
+int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4)
+{
+ struct net_device *dev;
+ int rc = 0;
+
+ if (ifindex) {
+ rcu_read_lock();
+
+ dev = dev_get_by_index_rcu(net, ifindex);
+ if (dev && netif_is_l3_master(dev) &&
+ dev->l3mdev_ops->l3mdev_get_saddr) {
+ rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
+ }
+
+ rcu_read_unlock();
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(l3mdev_get_saddr);
--
2.1.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox