* [PATCH] net: ethernet: stmmac: add ARP management
@ 2017-01-17 16:56 Christophe Roullier
2017-01-17 17:02 ` David Miller
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Christophe Roullier @ 2017-01-17 16:56 UTC (permalink / raw)
To: Alexandre Torgue, Giuseppe Cavallaro, netdev, linux-kernel,
Christophe Roullier
DWC_ether_qos supports the Address Recognition
Protocol (ARP) Offload for IPv4 packets. This feature
allows the processing of the IPv4 ARP request packet
in the receive path and generating corresponding ARP
response packet in the transmit path. DWC_ether_qos
generates the ARP reply packets for appropriate ARP
request packets.
Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 4 ++++
drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 3 +++
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 15 ++++++++++++++
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 23 ++++++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 ++++++++++++
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
include/linux/stmmac.h | 1 +
8 files changed, 61 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 75e2666..1d1c815 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -306,6 +306,7 @@ struct dma_features {
unsigned int pmt_remote_wake_up;
unsigned int pmt_magic_frame;
unsigned int rmon;
+ unsigned int arpoffsel;
/* IEEE 1588-2002 */
unsigned int time_stamp;
/* IEEE 1588-2008 */
@@ -447,6 +448,7 @@ struct stmmac_dma_ops {
void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
+ void (*set_arp_addr)(void __iomem *ioaddr, bool en, u32 addr);
};
struct mac_device_info;
@@ -459,6 +461,8 @@ struct stmmac_ops {
int (*rx_ipc)(struct mac_device_info *hw);
/* Enable RX Queues */
void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
+ /* Enable and verify that the ARP feature is supported */
+ int (*arp_en)(struct mac_device_info *hw);
/* Dump MAC registers */
void (*dump_regs)(struct mac_device_info *hw);
/* Handle extra events on specific interrupts hw dependent */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
index db45134..d1e2e37 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
@@ -35,6 +35,7 @@
#define GMAC_HW_FEATURE2 0x00000124
#define GMAC_MDIO_ADDR 0x00000200
#define GMAC_MDIO_DATA 0x00000204
+#define GMAC_ARP_ADDR 0x00000210
#define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8)
#define GMAC_ADDR_LOW(reg) (0x304 + reg * 8)
@@ -116,6 +117,7 @@ enum power_event {
#define GMAC_DEBUG_RPESTS BIT(0)
/* MAC config */
+#define GMAC_CONFIG_ARPEN BIT(31)
#define GMAC_CONFIG_IPC BIT(27)
#define GMAC_CONFIG_2K BIT(22)
#define GMAC_CONFIG_ACS BIT(20)
@@ -135,6 +137,7 @@ enum power_event {
#define GMAC_HW_FEAT_TXCOSEL BIT(14)
#define GMAC_HW_FEAT_EEESEL BIT(13)
#define GMAC_HW_FEAT_TSSEL BIT(12)
+#define GMAC_HW_FEAT_ARPOFFSEL BIT(9)
#define GMAC_HW_FEAT_MMCSEL BIT(8)
#define GMAC_HW_FEAT_MGKSEL BIT(7)
#define GMAC_HW_FEAT_RWKSEL BIT(6)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 834f40f..33d0fb3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -102,6 +102,20 @@ static int dwmac4_rx_ipc_enable(struct mac_device_info *hw)
return !!(value & GMAC_CONFIG_IPC);
}
+static int dwmac4_arp_enable(struct mac_device_info *hw)
+{
+ void __iomem *ioaddr = hw->pcsr;
+ u32 value = readl(ioaddr + GMAC_CONFIG);
+
+ value |= GMAC_CONFIG_ARPEN;
+
+ writel(value, ioaddr + GMAC_CONFIG);
+
+ value = readl(ioaddr + GMAC_CONFIG);
+
+ return !!(value & GMAC_CONFIG_ARPEN);
+}
+
static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode)
{
void __iomem *ioaddr = hw->pcsr;
@@ -463,6 +477,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
.core_init = dwmac4_core_init,
.rx_ipc = dwmac4_rx_ipc_enable,
.rx_queue_enable = dwmac4_rx_queue_enable,
+ .arp_en = dwmac4_arp_enable,
.dump_regs = dwmac4_dump_regs,
.host_irq_status = dwmac4_irq_status,
.flow_ctrl = dwmac4_flow_ctrl,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 377d1b4..fbbd303 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -284,6 +284,8 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
dma_cap->pmt_magic_frame = (hw_cap & GMAC_HW_FEAT_MGKSEL) >> 7;
/* MMC */
dma_cap->rmon = (hw_cap & GMAC_HW_FEAT_MMCSEL) >> 8;
+ /* ARP */
+ dma_cap->arpoffsel = (hw_cap & GMAC_HW_FEAT_ARPOFFSEL) >> 9;
/* IEEE 1588-2008 */
dma_cap->atime_stamp = (hw_cap & GMAC_HW_FEAT_TSSEL) >> 12;
/* 802.3az - Energy-Efficient Ethernet (EEE) */
@@ -331,6 +333,25 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
}
}
+/* Set ARP Address */
+static void dwmac4_set_arp_addr(void __iomem *ioaddr, bool set, u32 addr)
+{
+ u32 value;
+
+ value = readl(ioaddr + GMAC_ARP_ADDR);
+
+ if (set) {
+ /* set arp address */
+ value = addr;
+ } else {
+ /* unset arp address */
+ value = 0;
+ }
+
+ writel(value, ioaddr + GMAC_ARP_ADDR);
+ value = readl(ioaddr + GMAC_ARP_ADDR);
+}
+
const struct stmmac_dma_ops dwmac4_dma_ops = {
.reset = dwmac4_dma_reset,
.init = dwmac4_dma_init,
@@ -351,6 +372,7 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
.set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
.set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
.enable_tso = dwmac4_enable_tso,
+ .set_arp_addr = dwmac4_set_arp_addr,
};
const struct stmmac_dma_ops dwmac410_dma_ops = {
@@ -373,4 +395,5 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
.set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
.set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
.enable_tso = dwmac4_enable_tso,
+ .set_arp_addr = dwmac4_set_arp_addr,
};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index bf8a83e..51666fa 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -67,6 +67,7 @@ struct stmmac_priv {
bool tx_path_in_lpi_mode;
struct timer_list txtimer;
bool tso;
+ int arp;
struct dma_desc *dma_rx ____cacheline_aligned_in_smp;
struct dma_extended_desc *dma_erx;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d481c5f..2217dc3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3284,6 +3284,19 @@ int stmmac_dvr_probe(struct device *device,
priv->tso = true;
dev_info(priv->device, "TSO feature enabled\n");
}
+
+ if ((priv->plat->arp_en) && (priv->dma_cap.arpoffsel)) {
+ ret = priv->hw->mac->arp_en(priv->hw);
+ if (!ret) {
+ pr_warn(" ARP feature disabled\n");
+ } else {
+ pr_info(" ARP feature enabled\n");
+ /* Copy MAC addr into MAC_ARP_ADDRESS register*/
+ priv->hw->dma->set_arp_addr(priv->ioaddr, 1,
+ priv->dev->dev_addr);
+ }
+ }
+
ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
#ifdef STMMAC_VLAN_TAG_USED
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 4daa8a3..92a0db9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -306,6 +306,7 @@ struct plat_stmmacenet_data *
plat->has_gmac = 0;
plat->pmt = 1;
plat->tso_en = of_property_read_bool(np, "snps,tso");
+ plat->arp_en = of_property_read_bool(np, "snps,arp");
}
if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index d76033d6..2491285 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -148,5 +148,6 @@ struct plat_stmmacenet_data {
bool tso_en;
int mac_port_sel_speed;
bool en_tx_lpi_clockgating;
+ bool arp_en;
};
#endif
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH] net: ethernet: stmmac: add ARP management
2017-01-17 16:56 [PATCH] net: ethernet: stmmac: add ARP management Christophe Roullier
@ 2017-01-17 17:02 ` David Miller
2017-01-17 17:17 ` Florian Fainelli
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2017-01-17 17:02 UTC (permalink / raw)
To: christophe.roullier
Cc: alexandre.torgue, peppe.cavallaro, netdev, linux-kernel
From: Christophe Roullier <christophe.roullier@st.com>
Date: Tue, 17 Jan 2017 17:56:40 +0100
> DWC_ether_qos supports the Address Recognition
> Protocol (ARP) Offload for IPv4 packets. This feature
It's Address "Resolution" Protocol, not Recognition.
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] net: ethernet: stmmac: add ARP management
2017-01-17 16:56 [PATCH] net: ethernet: stmmac: add ARP management Christophe Roullier
2017-01-17 17:02 ` David Miller
@ 2017-01-17 17:17 ` Florian Fainelli
2017-01-17 17:25 ` Andrew Lunn
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Florian Fainelli @ 2017-01-17 17:17 UTC (permalink / raw)
To: Christophe Roullier, Alexandre Torgue, Giuseppe Cavallaro, netdev,
linux-kernel
On 01/17/2017 08:56 AM, Christophe Roullier wrote:
> DWC_ether_qos supports the Address Recognition
> Protocol (ARP) Offload for IPv4 packets. This feature
> allows the processing of the IPv4 ARP request packet
> in the receive path and generating corresponding ARP
> response packet in the transmit path. DWC_ether_qos
> generates the ARP reply packets for appropriate ARP
> request packets.
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> index 4daa8a3..92a0db9 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> @@ -306,6 +306,7 @@ struct plat_stmmacenet_data *
> plat->has_gmac = 0;
> plat->pmt = 1;
> plat->tso_en = of_property_read_bool(np, "snps,tso");
> + plat->arp_en = of_property_read_bool(np, "snps,arp");
You introduce a new property that needs to be documented in the Device
Tree binding document for stmmac.
--
Florian
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] net: ethernet: stmmac: add ARP management
2017-01-17 16:56 [PATCH] net: ethernet: stmmac: add ARP management Christophe Roullier
2017-01-17 17:02 ` David Miller
2017-01-17 17:17 ` Florian Fainelli
@ 2017-01-17 17:25 ` Andrew Lunn
2017-01-17 17:41 ` Florian Fainelli
2017-01-17 23:14 ` Andy Shevchenko
` (2 subsequent siblings)
5 siblings, 1 reply; 8+ messages in thread
From: Andrew Lunn @ 2017-01-17 17:25 UTC (permalink / raw)
To: Christophe Roullier
Cc: Alexandre Torgue, Giuseppe Cavallaro, netdev, linux-kernel
On Tue, Jan 17, 2017 at 05:56:40PM +0100, Christophe Roullier wrote:
> DWC_ether_qos supports the Address Recognition
Resolution not Recognition?
> Protocol (ARP) Offload for IPv4 packets. This feature
> allows the processing of the IPv4 ARP request packet
> in the receive path and generating corresponding ARP
> response packet in the transmit path. DWC_ether_qos
> generates the ARP reply packets for appropriate ARP
> request packets.
What about when .ndo_set_mac_address is called?
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] net: ethernet: stmmac: add ARP management
2017-01-17 17:25 ` Andrew Lunn
@ 2017-01-17 17:41 ` Florian Fainelli
0 siblings, 0 replies; 8+ messages in thread
From: Florian Fainelli @ 2017-01-17 17:41 UTC (permalink / raw)
To: Andrew Lunn, Christophe Roullier
Cc: Alexandre Torgue, Giuseppe Cavallaro, netdev, linux-kernel
On 01/17/2017 09:25 AM, Andrew Lunn wrote:
> On Tue, Jan 17, 2017 at 05:56:40PM +0100, Christophe Roullier wrote:
>> DWC_ether_qos supports the Address Recognition
>
> Resolution not Recognition?
>
>> Protocol (ARP) Offload for IPv4 packets. This feature
>> allows the processing of the IPv4 ARP request packet
>> in the receive path and generating corresponding ARP
>> response packet in the transmit path. DWC_ether_qos
>> generates the ARP reply packets for appropriate ARP
>> request packets.
>
> What about when .ndo_set_mac_address is called?
Was wondering about the same thing, but presumably, if there is correct
programming of the MAC address into the appropriate MAC address
registers, one could expect the hardware to latch that value while
generating the ARP replies?
While it sounds like this feature may be useful under heavy ARP spoofing
workloads, in practice, ARP packets are both small and infrequent, so
this sounds like micro optimization.
--
Florian
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] net: ethernet: stmmac: add ARP management
2017-01-17 16:56 [PATCH] net: ethernet: stmmac: add ARP management Christophe Roullier
` (2 preceding siblings ...)
2017-01-17 17:25 ` Andrew Lunn
@ 2017-01-17 23:14 ` Andy Shevchenko
2017-01-18 2:51 ` kbuild test robot
2017-01-18 10:19 ` Rayagond Kokatanur
5 siblings, 0 replies; 8+ messages in thread
From: Andy Shevchenko @ 2017-01-17 23:14 UTC (permalink / raw)
To: Christophe Roullier
Cc: Alexandre Torgue, Giuseppe Cavallaro, netdev,
linux-kernel@vger.kernel.org
On Tue, Jan 17, 2017 at 6:56 PM, Christophe Roullier
<christophe.roullier@st.com> wrote:
> +static int dwmac4_arp_enable(struct mac_device_info *hw)
> +{
> + void __iomem *ioaddr = hw->pcsr;
__iomem *config = hw->pcsr + GMAC_CONFIG;
> + u32 value = readl(ioaddr + GMAC_CONFIG);
> +
> + value |= GMAC_CONFIG_ARPEN;
> +
> + writel(value, ioaddr + GMAC_CONFIG);
u32 value;
value = readl();
writel(value | ...);
?
> +
> + value = readl(ioaddr + GMAC_CONFIG);
> +
> + return !!(value & GMAC_CONFIG_ARPEN);
> +}
> +/* Set ARP Address */
> +static void dwmac4_set_arp_addr(void __iomem *ioaddr, bool set, u32 addr)
> +{
__iomem *arp_addr = ioaddr + GMAC_ARP_ADDR;
> + u32 value;
> +
> + value = readl(ioaddr + GMAC_ARP_ADDR);
Care to explain why do you need dummy readl() here?
> +
> + if (set) {
> + /* set arp address */
> + value = addr;
> + } else {
> + /* unset arp address */
> + value = 0;
> + }
value = set ? addr : 0;
> +
> + writel(value, ioaddr + GMAC_ARP_ADDR);
> + value = readl(ioaddr + GMAC_ARP_ADDR);
> +}
> + if ((priv->plat->arp_en) && (priv->dma_cap.arpoffsel)) {
> + ret = priv->hw->mac->arp_en(priv->hw);
> + if (!ret) {
Hmm... Most would expect
if (ret) {
doing something
} else {
doing something else
}
> + pr_warn(" ARP feature disabled\n");
> + } else {
> + pr_info(" ARP feature enabled\n");
Wouldn't be too noisy?
pr_* -> dev_*
> + /* Copy MAC addr into MAC_ARP_ADDRESS register*/
> + priv->hw->dma->set_arp_addr(priv->ioaddr, 1,
> + priv->dev->dev_addr);
> + }
> + }
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] net: ethernet: stmmac: add ARP management
2017-01-17 16:56 [PATCH] net: ethernet: stmmac: add ARP management Christophe Roullier
` (3 preceding siblings ...)
2017-01-17 23:14 ` Andy Shevchenko
@ 2017-01-18 2:51 ` kbuild test robot
2017-01-18 10:19 ` Rayagond Kokatanur
5 siblings, 0 replies; 8+ messages in thread
From: kbuild test robot @ 2017-01-18 2:51 UTC (permalink / raw)
To: Christophe Roullier
Cc: kbuild-all, Alexandre Torgue, Giuseppe Cavallaro, netdev,
linux-kernel, Christophe Roullier
[-- Attachment #1: Type: text/plain, Size: 2222 bytes --]
Hi Christophe,
[auto build test WARNING on net-next/master]
[also build test WARNING on next-20170117]
[cannot apply to v4.10-rc4]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Christophe-Roullier/net-ethernet-stmmac-add-ARP-management/20170118-084026
config: x86_64-kexec (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function 'stmmac_dvr_probe':
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3296:11: warning: passing argument 3 of 'priv->hw->dma->set_arp_addr' makes integer from pointer without a cast [-Wint-conversion]
priv->dev->dev_addr);
^~~~
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3296:11: note: expected 'u32 {aka unsigned int}' but argument is of type 'unsigned char *'
vim +3296 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
3280 NETIF_F_RXCSUM;
3281
3282 if ((priv->plat->tso_en) && (priv->dma_cap.tsoen)) {
3283 ndev->hw_features |= NETIF_F_TSO;
3284 priv->tso = true;
3285 dev_info(priv->device, "TSO feature enabled\n");
3286 }
3287
3288 if ((priv->plat->arp_en) && (priv->dma_cap.arpoffsel)) {
3289 ret = priv->hw->mac->arp_en(priv->hw);
3290 if (!ret) {
3291 pr_warn(" ARP feature disabled\n");
3292 } else {
3293 pr_info(" ARP feature enabled\n");
3294 /* Copy MAC addr into MAC_ARP_ADDRESS register*/
3295 priv->hw->dma->set_arp_addr(priv->ioaddr, 1,
> 3296 priv->dev->dev_addr);
3297 }
3298 }
3299
3300 ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
3301 ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
3302 #ifdef STMMAC_VLAN_TAG_USED
3303 /* Both mac100 and gmac support receive VLAN tag detection */
3304 ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 24430 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] net: ethernet: stmmac: add ARP management
2017-01-17 16:56 [PATCH] net: ethernet: stmmac: add ARP management Christophe Roullier
` (4 preceding siblings ...)
2017-01-18 2:51 ` kbuild test robot
@ 2017-01-18 10:19 ` Rayagond Kokatanur
5 siblings, 0 replies; 8+ messages in thread
From: Rayagond Kokatanur @ 2017-01-18 10:19 UTC (permalink / raw)
To: Christophe Roullier
Cc: Alexandre Torgue, Giuseppe Cavallaro, netdev, linux-kernel
On Tue, Jan 17, 2017 at 10:26 PM, Christophe Roullier
<christophe.roullier@st.com> wrote:
>
> DWC_ether_qos supports the Address Recognition
> Protocol (ARP) Offload for IPv4 packets. This feature
> allows the processing of the IPv4 ARP request packet
> in the receive path and generating corresponding ARP
> response packet in the transmit path. DWC_ether_qos
> generates the ARP reply packets for appropriate ARP
> request packets.
>
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/common.h | 4 ++++
> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 3 +++
> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 15 ++++++++++++++
> drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 23 ++++++++++++++++++++++
> drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 ++++++++++++
> .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
> include/linux/stmmac.h | 1 +
> 8 files changed, 61 insertions(+)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 75e2666..1d1c815 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -306,6 +306,7 @@ struct dma_features {
> unsigned int pmt_remote_wake_up;
> unsigned int pmt_magic_frame;
> unsigned int rmon;
> + unsigned int arpoffsel;
> /* IEEE 1588-2002 */
> unsigned int time_stamp;
> /* IEEE 1588-2008 */
> @@ -447,6 +448,7 @@ struct stmmac_dma_ops {
> void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
> void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
> void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
> + void (*set_arp_addr)(void __iomem *ioaddr, bool en, u32 addr);
> };
>
> struct mac_device_info;
> @@ -459,6 +461,8 @@ struct stmmac_ops {
> int (*rx_ipc)(struct mac_device_info *hw);
> /* Enable RX Queues */
> void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
> + /* Enable and verify that the ARP feature is supported */
> + int (*arp_en)(struct mac_device_info *hw);
> /* Dump MAC registers */
> void (*dump_regs)(struct mac_device_info *hw);
> /* Handle extra events on specific interrupts hw dependent */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> index db45134..d1e2e37 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> @@ -35,6 +35,7 @@
> #define GMAC_HW_FEATURE2 0x00000124
> #define GMAC_MDIO_ADDR 0x00000200
> #define GMAC_MDIO_DATA 0x00000204
> +#define GMAC_ARP_ADDR 0x00000210
> #define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8)
> #define GMAC_ADDR_LOW(reg) (0x304 + reg * 8)
>
> @@ -116,6 +117,7 @@ enum power_event {
> #define GMAC_DEBUG_RPESTS BIT(0)
>
> /* MAC config */
> +#define GMAC_CONFIG_ARPEN BIT(31)
> #define GMAC_CONFIG_IPC BIT(27)
> #define GMAC_CONFIG_2K BIT(22)
> #define GMAC_CONFIG_ACS BIT(20)
> @@ -135,6 +137,7 @@ enum power_event {
> #define GMAC_HW_FEAT_TXCOSEL BIT(14)
> #define GMAC_HW_FEAT_EEESEL BIT(13)
> #define GMAC_HW_FEAT_TSSEL BIT(12)
> +#define GMAC_HW_FEAT_ARPOFFSEL BIT(9)
> #define GMAC_HW_FEAT_MMCSEL BIT(8)
> #define GMAC_HW_FEAT_MGKSEL BIT(7)
> #define GMAC_HW_FEAT_RWKSEL BIT(6)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> index 834f40f..33d0fb3 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> @@ -102,6 +102,20 @@ static int dwmac4_rx_ipc_enable(struct mac_device_info *hw)
> return !!(value & GMAC_CONFIG_IPC);
> }
>
> +static int dwmac4_arp_enable(struct mac_device_info *hw)
> +{
> + void __iomem *ioaddr = hw->pcsr;
> + u32 value = readl(ioaddr + GMAC_CONFIG);
> +
> + value |= GMAC_CONFIG_ARPEN;
> +
> + writel(value, ioaddr + GMAC_CONFIG);
> +
> + value = readl(ioaddr + GMAC_CONFIG);
> +
> + return !!(value & GMAC_CONFIG_ARPEN);
> +}
> +
> static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode)
> {
> void __iomem *ioaddr = hw->pcsr;
> @@ -463,6 +477,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
> .core_init = dwmac4_core_init,
> .rx_ipc = dwmac4_rx_ipc_enable,
> .rx_queue_enable = dwmac4_rx_queue_enable,
> + .arp_en = dwmac4_arp_enable,
> .dump_regs = dwmac4_dump_regs,
> .host_irq_status = dwmac4_irq_status,
> .flow_ctrl = dwmac4_flow_ctrl,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> index 377d1b4..fbbd303 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> @@ -284,6 +284,8 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
> dma_cap->pmt_magic_frame = (hw_cap & GMAC_HW_FEAT_MGKSEL) >> 7;
> /* MMC */
> dma_cap->rmon = (hw_cap & GMAC_HW_FEAT_MMCSEL) >> 8;
> + /* ARP */
> + dma_cap->arpoffsel = (hw_cap & GMAC_HW_FEAT_ARPOFFSEL) >> 9;
> /* IEEE 1588-2008 */
> dma_cap->atime_stamp = (hw_cap & GMAC_HW_FEAT_TSSEL) >> 12;
> /* 802.3az - Energy-Efficient Ethernet (EEE) */
> @@ -331,6 +333,25 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
> }
> }
>
> +/* Set ARP Address */
> +static void dwmac4_set_arp_addr(void __iomem *ioaddr, bool set, u32 addr)
> +{
> + u32 value;
> +
> + value = readl(ioaddr + GMAC_ARP_ADDR);
> +
> + if (set) {
> + /* set arp address */
> + value = addr;
> + } else {
> + /* unset arp address */
> + value = 0;
> + }
> +
> + writel(value, ioaddr + GMAC_ARP_ADDR);
> + value = readl(ioaddr + GMAC_ARP_ADDR);
> +}
> +
> const struct stmmac_dma_ops dwmac4_dma_ops = {
> .reset = dwmac4_dma_reset,
> .init = dwmac4_dma_init,
> @@ -351,6 +372,7 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
> .set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
> .set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
> .enable_tso = dwmac4_enable_tso,
> + .set_arp_addr = dwmac4_set_arp_addr,
> };
>
> const struct stmmac_dma_ops dwmac410_dma_ops = {
> @@ -373,4 +395,5 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
> .set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
> .set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
> .enable_tso = dwmac4_enable_tso,
> + .set_arp_addr = dwmac4_set_arp_addr,
> };
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> index bf8a83e..51666fa 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> @@ -67,6 +67,7 @@ struct stmmac_priv {
> bool tx_path_in_lpi_mode;
> struct timer_list txtimer;
> bool tso;
> + int arp;
>
> struct dma_desc *dma_rx ____cacheline_aligned_in_smp;
> struct dma_extended_desc *dma_erx;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index d481c5f..2217dc3 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -3284,6 +3284,19 @@ int stmmac_dvr_probe(struct device *device,
> priv->tso = true;
> dev_info(priv->device, "TSO feature enabled\n");
> }
> +
> + if ((priv->plat->arp_en) && (priv->dma_cap.arpoffsel)) {
> + ret = priv->hw->mac->arp_en(priv->hw);
> + if (!ret) {
> + pr_warn(" ARP feature disabled\n");
> + } else {
> + pr_info(" ARP feature enabled\n");
> + /* Copy MAC addr into MAC_ARP_ADDRESS register*/
> + priv->hw->dma->set_arp_addr(priv->ioaddr, 1,
> + priv->dev->dev_addr);
GMAC_ARP_ADDR register suppose to contains IPv4 address not MAC address.
Also priv->dev->dev_addr will be 6 bytes long but GMAC_ARP_ADDR is 4 bytes long.
What about arp request packet received by device, driver rx poll
should check the arp reply generate by device or not and decide
whehther received arp request packet should be passed to stack or not.
Else stack also ends up trasmiting ARP reply always.
>
> + }
> + }
> +
> ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
> ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
> #ifdef STMMAC_VLAN_TAG_USED
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> index 4daa8a3..92a0db9 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> @@ -306,6 +306,7 @@ struct plat_stmmacenet_data *
> plat->has_gmac = 0;
> plat->pmt = 1;
> plat->tso_en = of_property_read_bool(np, "snps,tso");
> + plat->arp_en = of_property_read_bool(np, "snps,arp");
> }
>
> if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
> diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
> index d76033d6..2491285 100644
> --- a/include/linux/stmmac.h
> +++ b/include/linux/stmmac.h
> @@ -148,5 +148,6 @@ struct plat_stmmacenet_data {
> bool tso_en;
> int mac_port_sel_speed;
> bool en_tx_lpi_clockgating;
> + bool arp_en;
> };
> #endif
> --
> 1.9.1
>
--
wwr
Rayagond
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2017-01-18 10:19 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-01-17 16:56 [PATCH] net: ethernet: stmmac: add ARP management Christophe Roullier
2017-01-17 17:02 ` David Miller
2017-01-17 17:17 ` Florian Fainelli
2017-01-17 17:25 ` Andrew Lunn
2017-01-17 17:41 ` Florian Fainelli
2017-01-17 23:14 ` Andy Shevchenko
2017-01-18 2:51 ` kbuild test robot
2017-01-18 10:19 ` Rayagond Kokatanur
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).