[PATCH net-next 1/1] net: stmmac: fix memory leak during driver probe

2021-04-19 Thread Wong Vee Khee
On driver probe, kmemleak reported the following memory leak which was
due to allocated bitmap that was not being freed in stmmac_dvr_probe().

unreferenced object 0x9276014b13c0 (size 8):
  comm "systemd-udevd", pid 2143, jiffies 4294681112 (age 116.720s)
  hex dump (first 8 bytes):
00 00 00 00 00 00 00 00  
  backtrace:
[<c51e34b2>] stmmac_dvr_probe+0x1c0/0x440 [stmmac]
[<b530eb41>] intel_eth_pci_probe.cold+0x2b/0x14e [dwmac_intel]
[<b10f8929>] pci_device_probe+0xd2/0x150
[<fb254c74>] really_probe+0xf8/0x410
[<34128a59>] driver_probe_device+0x5d/0x150
[<016104d5>] device_driver_attach+0x53/0x60
[<cb18cd07>] __driver_attach+0x96/0x140
[<da9ffd5c>] bus_for_each_dev+0x7a/0xc0
[<af061a88>] bus_add_driver+0x184/0x1f0
[<8be5c1c5>] driver_register+0x6c/0xc0
[<52b18a9e>] do_one_initcall+0x4d/0x210
[<154d4f07>] do_init_module+0x5c/0x230
[<9b648d09>] load_module+0x2a5a/0x2d40
[<0d86b76d>] __do_sys_finit_module+0xb5/0x120
[<2b0cef95>] do_syscall_64+0x33/0x40
[<67b45bbb>] entry_SYSCALL_64_after_hwframe+0x44/0xa9

Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy")
Cc: Ong Boon Leong 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9f396648d76f..d1ca07c846e6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7035,6 +7035,7 @@ int stmmac_dvr_probe(struct device *device,
 error_hw_init:
destroy_workqueue(priv->wq);
stmmac_bus_clks_config(priv, false);
+   bitmap_free(priv->af_xdp_zc_qps);
 
return ret;
 }
@@ -7077,6 +7078,7 @@ int stmmac_dvr_remove(struct device *dev)
stmmac_mdio_unregister(ndev);
destroy_workqueue(priv->wq);
mutex_destroy(>lock);
+   bitmap_free(priv->af_xdp_zc_qps);
 
return 0;
 }
-- 
2.25.1



[PATCH net-next v4 1/1] net: stmmac: Add support for external trigger timestamping

2021-04-13 Thread Wong Vee Khee
From: Tan Tee Min 

The Synopsis MAC controller supports auxiliary snapshot feature that
allows user to store a snapshot of the system time based on an external
event.

This patch add supports to the above mentioned feature. Users will be
able to triggered capturing the time snapshot from user-space using
application such as testptp or any other applications that uses the
PTP_EXTTS_REQUEST ioctl request.

Cc: Richard Cochran 
Signed-off-by: Tan Tee Min 
Co-developed-by: Wong Vee Khee 
Signed-off-by: Wong Vee Khee 
---
v3 -> v4:
  - Group variable of same datatype together in oneline.
  - Removed unnecessary mutex_unlock()
  - Added mutex_destroy() on ptp_unregister().
v2 -> v3:
  - Flip ext_snapshot_en condition check for early return.
v1 -> v2:
  - Changed from pr_info() to netdev_dbg().
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 10 +
 drivers/net/ethernet/stmicro/stmmac/hwif.h|  5 +++
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  3 ++
 .../ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 39 ++
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.c  | 40 ++-
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.h  |  1 +
 include/linux/stmmac.h|  2 +
 8 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 60566598d644..ec140fc4a0f5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -296,6 +296,13 @@ static int intel_crosststamp(ktime_t *device,
 
intel_priv = priv->plat->bsp_priv;
 
+   /* Both internal crosstimestamping and external triggered event
+* timestamping cannot be run concurrently.
+*/
+   if (priv->plat->ext_snapshot_en)
+   return -EBUSY;
+
+   mutex_lock(>aux_ts_lock);
/* Enable Internal snapshot trigger */
acr_value = readl(ptpaddr + PTP_ACR);
acr_value &= ~PTP_ACR_MASK;
@@ -321,6 +328,8 @@ static int intel_crosststamp(ktime_t *device,
acr_value = readl(ptpaddr + PTP_ACR);
acr_value |= PTP_ACR_ATSFC;
writel(acr_value, ptpaddr + PTP_ACR);
+   /* Release the mutex */
+   mutex_unlock(>aux_ts_lock);
 
/* Trigger Internal snapshot signal
 * Create a rising edge by just toggle the GPO1 to low
@@ -520,6 +529,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
plat->mdio_bus_data->phy_mask |= 1 << INTEL_MGBE_XPCS_ADDR;
 
plat->int_snapshot_num = AUX_SNAPSHOT1;
+   plat->ext_snapshot_num = AUX_SNAPSHOT0;
 
plat->has_crossts = true;
plat->crosststamp = intel_crosststamp;
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h 
b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 2b5022ef1e52..2cc91759b91f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -504,6 +504,8 @@ struct stmmac_ops {
 #define stmmac_fpe_irq_status(__priv, __args...) \
stmmac_do_callback(__priv, mac, fpe_irq_status, __args)
 
+struct stmmac_priv;
+
 /* PTP and HW Timer helpers */
 struct stmmac_hwtimestamp {
void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
@@ -515,6 +517,7 @@ struct stmmac_hwtimestamp {
   int add_sub, int gmac4);
void (*get_systime) (void __iomem *ioaddr, u64 *systime);
void (*get_ptptime)(void __iomem *ioaddr, u64 *ptp_time);
+   void (*timestamp_interrupt)(struct stmmac_priv *priv);
 };
 
 #define stmmac_config_hw_tstamping(__priv, __args...) \
@@ -531,6 +534,8 @@ struct stmmac_hwtimestamp {
stmmac_do_void_callback(__priv, ptp, get_systime, __args)
 #define stmmac_get_ptptime(__priv, __args...) \
stmmac_do_void_callback(__priv, ptp, get_ptptime, __args)
+#define stmmac_timestamp_interrupt(__priv, __args...) \
+   stmmac_do_void_callback(__priv, ptp, timestamp_interrupt, __args)
 
 /* Helpers to manage the descriptors for chain and ring modes */
 struct stmmac_mode_ops {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index b8a42260066d..b6cd43eda7ac 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -250,6 +250,9 @@ struct stmmac_priv {
int use_riwt;
int irq_wake;
spinlock_t ptp_lock;
+   /* Protects auxiliary snapshot registers from concurrent access. */
+   struct mutex aux_ts_lock;
+
void __iomem *mmcaddr;
void __iomem *ptpaddr;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
index 113c51bcc0b5..074e2cdfb0fa 100644
--- a/drivers/net/ethernet/stmi

Re: [PATCH net-next v3 1/1] net: stmmac: Add support for external trigger timestamping

2021-04-12 Thread Wong Vee Khee
On Sun, Apr 11, 2021 at 08:10:55AM -0700, Richard Cochran wrote:
> On Sun, Apr 11, 2021 at 10:40:28AM +0800, Wong Vee Khee wrote:
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
> > b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> > index 60566598d644..60e17fd24aba 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> > @@ -296,6 +296,13 @@ static int intel_crosststamp(ktime_t *device,
> >  
> > intel_priv = priv->plat->bsp_priv;
> >  
> > +   /* Both internal crosstimestamping and external triggered event
> > +* timestamping cannot be run concurrently.
> > +*/
> > +   if (priv->plat->ext_snapshot_en)
> > +   return -EBUSY;
> > +
> > +   mutex_lock(>aux_ts_lock);
> 
> Lock, then ...
> 
> > /* Enable Internal snapshot trigger */
> > acr_value = readl(ptpaddr + PTP_ACR);
> > acr_value &= ~PTP_ACR_MASK;
> > @@ -321,6 +328,7 @@ static int intel_crosststamp(ktime_t *device,
> > acr_value = readl(ptpaddr + PTP_ACR);
> > acr_value |= PTP_ACR_ATSFC;
> > writel(acr_value, ptpaddr + PTP_ACR);
> > +   mutex_unlock(>aux_ts_lock);
> 
> unlock, then ...
>   
> > /* Trigger Internal snapshot signal
> >  * Create a rising edge by just toggle the GPO1 to low
> > @@ -355,6 +363,8 @@ static int intel_crosststamp(ktime_t *device,
> > *system = convert_art_to_tsc(art_time);
> > }
> >  
> > +   /* Release the mutex */
> > +   mutex_unlock(>aux_ts_lock);
> 
> unlock again?  Huh?
>

Nice catch. Fix in v4.
 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
> > b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> > index c49debb62b05..abadcd8cdc41 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> > @@ -239,6 +239,9 @@ struct stmmac_priv {
> > int use_riwt;
> > int irq_wake;
> > spinlock_t ptp_lock;
> > +   /* Mutex lock for Auxiliary Snapshots */
> > +   struct mutex aux_ts_lock;
> 
> In the comment, please be specific about which data are protected.
> For example:
> 
>   /* Protects auxiliary snapshot registers from concurrent access. */
> 
> > @@ -163,6 +166,43 @@ static void get_ptptime(void __iomem *ptpaddr, u64 
> > *ptp_time)
> > *ptp_time = ns;
> >  }
> >  
> > +static void timestamp_interrupt(struct stmmac_priv *priv)
> > +{
> > +   struct ptp_clock_event event;
> > +   unsigned long flags;
> > +   u32 num_snapshot;
> > +   u32 ts_status;
> > +   u32 tsync_int;
> 
> Please group same types together (u32) in a one-line list.
> 
> > +   u64 ptp_time;
> > +   int i;
> > +
> > +   tsync_int = readl(priv->ioaddr + GMAC_INT_STATUS) & GMAC_INT_TSIE;
> > +
> > +   if (!tsync_int)
> > +   return;
> > +
> > +   /* Read timestamp status to clear interrupt from either external
> > +* timestamp or start/end of PPS.
> > +*/
> > +   ts_status = readl(priv->ioaddr + GMAC_TIMESTAMP_STATUS);
> 
> Reading this register has a side effect of clearing status?  If so,
> doesn't it need protection against concurrent access?
> 
> The function, intel_crosststamp() also reads this bit.
>

The following check is introduced in intel_crosststamp() to avoid this:

/* Both internal crosstimestamping and external triggered event
 * timestamping cannot be run concurrently.
 */
 if (priv->plat->ext_snapshot_en)
return -EBUSY;

 
> > +   if (!priv->plat->ext_snapshot_en)
> > +   return;
> 
> Doesn't this test come too late?  Setting ts_status just cleared the
> bit used by the other code path.
>

As per Synopsys's design, all bits except Bits[27:25] gets cleared when
this register is read.

> > +   num_snapshot = (ts_status & GMAC_TIMESTAMP_ATSNS_MASK) >>
> > +  GMAC_TIMESTAMP_ATSNS_SHIFT;
> > +
> > +   for (i = 0; i < num_snapshot; i++) {
> > +   spin_lock_irqsave(>ptp_lock, flags);
> > +   get_ptptime(priv->ptpaddr, _time);
> > +   spin_unlock_irqrestore(>ptp_lock, flags);
> > +   event.type = PTP_CLOCK_EXTTS;
> > +   event.index = 0;
> > +   event.timestamp = ptp_time;
> > +   ptp_clock_event(priv->ptp_clock, );
> > +   }
> > +}
> > +
> 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 
> > b/drivers/net/e

[PATCH net-next v3 1/1] net: stmmac: Add support for external trigger timestamping

2021-04-10 Thread Wong Vee Khee
From: Tan Tee Min 

The Synopsis MAC controller supports auxiliary snapshot feature that
allows user to store a snapshot of the system time based on an external
event.

This patch add supports to the above mentioned feature. Users will be
able to triggered capturing the time snapshot from user-space using
application such as testptp or any other applications that uses the
PTP_EXTTS_REQUEST ioctl request.

Cc: Richard Cochran 
Signed-off-by: Tan Tee Min 
Co-developed-by: Wong Vee Khee 
Signed-off-by: Wong Vee Khee 
---
v2 -> v3:
  - Flip ext_snapshot_en condition check for early return.
v1 -> v2:
  - Changed from pr_info() to netdev_dbg().

 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 11 +
 drivers/net/ethernet/stmicro/stmmac/hwif.h|  5 +++
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  3 ++
 .../ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 41 +++
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.c  | 39 +-
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.h  |  1 +
 include/linux/stmmac.h|  2 +
 8 files changed, 103 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 60566598d644..60e17fd24aba 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -296,6 +296,13 @@ static int intel_crosststamp(ktime_t *device,
 
intel_priv = priv->plat->bsp_priv;
 
+   /* Both internal crosstimestamping and external triggered event
+* timestamping cannot be run concurrently.
+*/
+   if (priv->plat->ext_snapshot_en)
+   return -EBUSY;
+
+   mutex_lock(>aux_ts_lock);
/* Enable Internal snapshot trigger */
acr_value = readl(ptpaddr + PTP_ACR);
acr_value &= ~PTP_ACR_MASK;
@@ -321,6 +328,7 @@ static int intel_crosststamp(ktime_t *device,
acr_value = readl(ptpaddr + PTP_ACR);
acr_value |= PTP_ACR_ATSFC;
writel(acr_value, ptpaddr + PTP_ACR);
+   mutex_unlock(>aux_ts_lock);
 
/* Trigger Internal snapshot signal
 * Create a rising edge by just toggle the GPO1 to low
@@ -355,6 +363,8 @@ static int intel_crosststamp(ktime_t *device,
*system = convert_art_to_tsc(art_time);
}
 
+   /* Release the mutex */
+   mutex_unlock(>aux_ts_lock);
system->cycles *= intel_priv->crossts_adj;
 
return 0;
@@ -520,6 +530,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
plat->mdio_bus_data->phy_mask |= 1 << INTEL_MGBE_XPCS_ADDR;
 
plat->int_snapshot_num = AUX_SNAPSHOT1;
+   plat->ext_snapshot_num = AUX_SNAPSHOT0;
 
plat->has_crossts = true;
plat->crosststamp = intel_crosststamp;
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h 
b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 2b5022ef1e52..2cc91759b91f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -504,6 +504,8 @@ struct stmmac_ops {
 #define stmmac_fpe_irq_status(__priv, __args...) \
stmmac_do_callback(__priv, mac, fpe_irq_status, __args)
 
+struct stmmac_priv;
+
 /* PTP and HW Timer helpers */
 struct stmmac_hwtimestamp {
void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
@@ -515,6 +517,7 @@ struct stmmac_hwtimestamp {
   int add_sub, int gmac4);
void (*get_systime) (void __iomem *ioaddr, u64 *systime);
void (*get_ptptime)(void __iomem *ioaddr, u64 *ptp_time);
+   void (*timestamp_interrupt)(struct stmmac_priv *priv);
 };
 
 #define stmmac_config_hw_tstamping(__priv, __args...) \
@@ -531,6 +534,8 @@ struct stmmac_hwtimestamp {
stmmac_do_void_callback(__priv, ptp, get_systime, __args)
 #define stmmac_get_ptptime(__priv, __args...) \
stmmac_do_void_callback(__priv, ptp, get_ptptime, __args)
+#define stmmac_timestamp_interrupt(__priv, __args...) \
+   stmmac_do_void_callback(__priv, ptp, timestamp_interrupt, __args)
 
 /* Helpers to manage the descriptors for chain and ring modes */
 struct stmmac_mode_ops {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index c49debb62b05..abadcd8cdc41 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -239,6 +239,9 @@ struct stmmac_priv {
int use_riwt;
int irq_wake;
spinlock_t ptp_lock;
+   /* Mutex lock for Auxiliary Snapshots */
+   struct mutex aux_ts_lock;
+
void __iomem *mmcaddr;
void __iomem *ptpaddr;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
index

Re: [PATCH net-next v2 1/1] net: stmmac: Add support for external trigger timestamping

2021-04-10 Thread Wong Vee Khee
On Fri, Apr 09, 2021 at 05:50:04PM -0700, Jakub Kicinski wrote:
> Other than the minor nit below LGTM. Let's give Richard one more day.
> 
> On Thu,  8 Apr 2021 01:04:42 +0800 Wong Vee Khee wrote:
> > +static void timestamp_interrupt(struct stmmac_priv *priv)
> > +{
> > +   struct ptp_clock_event event;
> > +   unsigned long flags;
> > +   u32 num_snapshot;
> > +   u32 ts_status;
> > +   u32 tsync_int;
> > +   u64 ptp_time;
> > +   int i;
> > +
> > +   tsync_int = readl(priv->ioaddr + GMAC_INT_STATUS) & GMAC_INT_TSIE;
> > +
> > +   if (!tsync_int)
> > +   return;
> > +
> > +   /* Read timestamp status to clear interrupt from either external
> > +* timestamp or start/end of PPS.
> > +*/
> > +   ts_status = readl(priv->ioaddr + GMAC_TIMESTAMP_STATUS);
> > +
> > +   if (priv->plat->ext_snapshot_en) {
> 
> Are you intending to add more code after this if? Otherwise you could
> flip the condition and return early instead of having the extra level
> of indentation.
>

Thanks fo the suggestion.
There's no plan to add more code after this as per STMMAC features that
required this interrupt. I will flip the condition.

> > +   num_snapshot = (ts_status & GMAC_TIMESTAMP_ATSNS_MASK) >>
> > +  GMAC_TIMESTAMP_ATSNS_SHIFT;
> > +
> > +   for (i = 0; i < num_snapshot; i++) {
> > +   spin_lock_irqsave(>ptp_lock, flags);
> > +   get_ptptime(priv->ptpaddr, _time);
> > +   spin_unlock_irqrestore(>ptp_lock, flags);
> > +   event.type = PTP_CLOCK_EXTTS;
> > +   event.index = 0;
> > +   event.timestamp = ptp_time;
> > +   ptp_clock_event(priv->ptp_clock, );
> > +   }
> > +   }
> > +}
> 
> Not really related to this patch but how does stmmac set IRQF_SHARED
> and yet not track if it indeed generated the interrupt? Isn't that
> against the rules?
>

Good point! Thanks for pointing that out. I looked at how STMMAC
interrupt handlers are coded, and indeed there are no tracking. Will
work on that and send as a seperate patch in near future.




[PATCH net-next v2 1/1] net: stmmac: Add support for external trigger timestamping

2021-04-07 Thread Wong Vee Khee
From: Tan Tee Min 

The Synopsis MAC controller supports auxiliary snapshot feature that
allows user to store a snapshot of the system time based on an external
event.

This patch add supports to the above mentioned feature. Users will be
able to triggered capturing the time snapshot from user-space using
application such as testptp or any other applications that uses the
PTP_EXTTS_REQUEST ioctl request.

Cc: Richard Cochran 
Signed-off-by: Tan Tee Min 
Co-developed-by: Wong Vee Khee 
Signed-off-by: Wong Vee Khee 
---
v1 -> v2:
Changed from pr_info() to netdev_dbg().

 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 11 +
 drivers/net/ethernet/stmicro/stmmac/hwif.h|  5 +++
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  3 ++
 .../ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 40 +++
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.c  | 39 +-
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.h  |  1 +
 include/linux/stmmac.h|  2 +
 8 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 8ba87c0be976..aee3e0b5fb46 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -286,6 +286,13 @@ static int intel_crosststamp(ktime_t *device,
 
intel_priv = priv->plat->bsp_priv;
 
+   /* Both internal crosstimestamping and external triggered event
+* timestamping cannot be run concurrently.
+*/
+   if (priv->plat->ext_snapshot_en)
+   return -EBUSY;
+
+   mutex_lock(>aux_ts_lock);
/* Enable Internal snapshot trigger */
acr_value = readl(ptpaddr + PTP_ACR);
acr_value &= ~PTP_ACR_MASK;
@@ -311,6 +318,7 @@ static int intel_crosststamp(ktime_t *device,
acr_value = readl(ptpaddr + PTP_ACR);
acr_value |= PTP_ACR_ATSFC;
writel(acr_value, ptpaddr + PTP_ACR);
+   mutex_unlock(>aux_ts_lock);
 
/* Trigger Internal snapshot signal
 * Create a rising edge by just toggle the GPO1 to low
@@ -345,6 +353,8 @@ static int intel_crosststamp(ktime_t *device,
*system = convert_art_to_tsc(art_time);
}
 
+   /* Release the mutex */
+   mutex_unlock(>aux_ts_lock);
system->cycles *= intel_priv->crossts_adj;
 
return 0;
@@ -510,6 +520,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
plat->mdio_bus_data->phy_mask |= 1 << INTEL_MGBE_XPCS_ADDR;
 
plat->int_snapshot_num = AUX_SNAPSHOT1;
+   plat->ext_snapshot_num = AUX_SNAPSHOT0;
 
plat->has_crossts = true;
plat->crosststamp = intel_crosststamp;
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h 
b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 2b5022ef1e52..2cc91759b91f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -504,6 +504,8 @@ struct stmmac_ops {
 #define stmmac_fpe_irq_status(__priv, __args...) \
stmmac_do_callback(__priv, mac, fpe_irq_status, __args)
 
+struct stmmac_priv;
+
 /* PTP and HW Timer helpers */
 struct stmmac_hwtimestamp {
void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
@@ -515,6 +517,7 @@ struct stmmac_hwtimestamp {
   int add_sub, int gmac4);
void (*get_systime) (void __iomem *ioaddr, u64 *systime);
void (*get_ptptime)(void __iomem *ioaddr, u64 *ptp_time);
+   void (*timestamp_interrupt)(struct stmmac_priv *priv);
 };
 
 #define stmmac_config_hw_tstamping(__priv, __args...) \
@@ -531,6 +534,8 @@ struct stmmac_hwtimestamp {
stmmac_do_void_callback(__priv, ptp, get_systime, __args)
 #define stmmac_get_ptptime(__priv, __args...) \
stmmac_do_void_callback(__priv, ptp, get_ptptime, __args)
+#define stmmac_timestamp_interrupt(__priv, __args...) \
+   stmmac_do_void_callback(__priv, ptp, timestamp_interrupt, __args)
 
 /* Helpers to manage the descriptors for chain and ring modes */
 struct stmmac_mode_ops {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index c49debb62b05..abadcd8cdc41 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -239,6 +239,9 @@ struct stmmac_priv {
int use_riwt;
int irq_wake;
spinlock_t ptp_lock;
+   /* Mutex lock for Auxiliary Snapshots */
+   struct mutex aux_ts_lock;
+
void __iomem *mmcaddr;
void __iomem *ptpaddr;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
index 113c51bcc0b5..ec7ec926f27c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/s

Re: [PATCH net-next 1/1] net: stmmac: Add support for external trigger timestamping

2021-04-07 Thread Wong Vee Khee
On Wed, Apr 07, 2021 at 04:21:09PM +0200, Andrew Lunn wrote:
> On Wed, Apr 07, 2021 at 10:15:37PM +0800, Wong Vee Khee wrote:
> > From: Tan Tee Min 
> > 
> > The Synopsis MAC controller supports auxiliary snapshot feature that
> > allows user to store a snapshot of the system time based on an external
> > event.
> > 
> > This patch add supports to the above mentioned feature. Users will be
> > able to triggered capturing the time snapshot from user-space using
> > application such as testptp or any other applications that uses the
> > PTP_EXTTS_REQUEST ioctl request.
> 
> You forgot to Cc: the PTP maintainer.
>

Will Cc Richard Cochran on v2.
 
> > @@ -159,6 +163,37 @@ static int stmmac_enable(struct ptp_clock_info *ptp,
> >  priv->systime_flags);
> > spin_unlock_irqrestore(>ptp_lock, flags);
> > break;
> > +   case PTP_CLK_REQ_EXTTS:
> > +   priv->plat->ext_snapshot_en = on;
> > +   mutex_lock(>aux_ts_lock);
> > +   acr_value = readl(ptpaddr + PTP_ACR);
> > +   acr_value &= ~PTP_ACR_MASK;
> > +   if (on) {
> > +   /* Enable External snapshot trigger */
> > +   acr_value |= priv->plat->ext_snapshot_num;
> > +   acr_value |= PTP_ACR_ATSFC;
> > +   pr_info("Auxiliary Snapshot %d enabled.\n",
> > +   priv->plat->ext_snapshot_num >>
> > +   PTP_ACR_ATSEN_SHIFT);
> 
> dev_dbg()?
> 
> > +   /* Enable Timestamp Interrupt */
> > +   intr_value = readl(ioaddr + GMAC_INT_EN);
> > +   intr_value |= GMAC_INT_TSIE;
> > +   writel(intr_value, ioaddr + GMAC_INT_EN);
> > +
> > +   } else {
> > +   pr_info("Auxiliary Snapshot %d disabled.\n",
> > +   priv->plat->ext_snapshot_num >>
> > +   PTP_ACR_ATSEN_SHIFT);
> 
> dev_dbg()?
> 
> Do you really want to spam the kernel log with this?
>

Thanks for the review.
I will switch this to netdev_dbg().
 


[PATCH net-next 1/1] net: stmmac: Add support for external trigger timestamping

2021-04-07 Thread Wong Vee Khee
From: Tan Tee Min 

The Synopsis MAC controller supports auxiliary snapshot feature that
allows user to store a snapshot of the system time based on an external
event.

This patch add supports to the above mentioned feature. Users will be
able to triggered capturing the time snapshot from user-space using
application such as testptp or any other applications that uses the
PTP_EXTTS_REQUEST ioctl request.

Signed-off-by: Tan Tee Min 
Co-developed-by: Wong Vee Khee 
Signed-off-by: Wong Vee Khee 
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 11 +
 drivers/net/ethernet/stmicro/stmmac/hwif.h|  5 +++
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  3 ++
 .../ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 40 +++
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.c  | 39 +-
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.h  |  1 +
 include/linux/stmmac.h|  2 +
 8 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 8ba87c0be976..aee3e0b5fb46 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -286,6 +286,13 @@ static int intel_crosststamp(ktime_t *device,
 
intel_priv = priv->plat->bsp_priv;
 
+   /* Both internal crosstimestamping and external triggered event
+* timestamping cannot be run concurrently.
+*/
+   if (priv->plat->ext_snapshot_en)
+   return -EBUSY;
+
+   mutex_lock(>aux_ts_lock);
/* Enable Internal snapshot trigger */
acr_value = readl(ptpaddr + PTP_ACR);
acr_value &= ~PTP_ACR_MASK;
@@ -311,6 +318,7 @@ static int intel_crosststamp(ktime_t *device,
acr_value = readl(ptpaddr + PTP_ACR);
acr_value |= PTP_ACR_ATSFC;
writel(acr_value, ptpaddr + PTP_ACR);
+   mutex_unlock(>aux_ts_lock);
 
/* Trigger Internal snapshot signal
 * Create a rising edge by just toggle the GPO1 to low
@@ -345,6 +353,8 @@ static int intel_crosststamp(ktime_t *device,
*system = convert_art_to_tsc(art_time);
}
 
+   /* Release the mutex */
+   mutex_unlock(>aux_ts_lock);
system->cycles *= intel_priv->crossts_adj;
 
return 0;
@@ -510,6 +520,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
plat->mdio_bus_data->phy_mask |= 1 << INTEL_MGBE_XPCS_ADDR;
 
plat->int_snapshot_num = AUX_SNAPSHOT1;
+   plat->ext_snapshot_num = AUX_SNAPSHOT0;
 
plat->has_crossts = true;
plat->crosststamp = intel_crosststamp;
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h 
b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 2b5022ef1e52..2cc91759b91f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -504,6 +504,8 @@ struct stmmac_ops {
 #define stmmac_fpe_irq_status(__priv, __args...) \
stmmac_do_callback(__priv, mac, fpe_irq_status, __args)
 
+struct stmmac_priv;
+
 /* PTP and HW Timer helpers */
 struct stmmac_hwtimestamp {
void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
@@ -515,6 +517,7 @@ struct stmmac_hwtimestamp {
   int add_sub, int gmac4);
void (*get_systime) (void __iomem *ioaddr, u64 *systime);
void (*get_ptptime)(void __iomem *ioaddr, u64 *ptp_time);
+   void (*timestamp_interrupt)(struct stmmac_priv *priv);
 };
 
 #define stmmac_config_hw_tstamping(__priv, __args...) \
@@ -531,6 +534,8 @@ struct stmmac_hwtimestamp {
stmmac_do_void_callback(__priv, ptp, get_systime, __args)
 #define stmmac_get_ptptime(__priv, __args...) \
stmmac_do_void_callback(__priv, ptp, get_ptptime, __args)
+#define stmmac_timestamp_interrupt(__priv, __args...) \
+   stmmac_do_void_callback(__priv, ptp, timestamp_interrupt, __args)
 
 /* Helpers to manage the descriptors for chain and ring modes */
 struct stmmac_mode_ops {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index c49debb62b05..abadcd8cdc41 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -239,6 +239,9 @@ struct stmmac_priv {
int use_riwt;
int irq_wake;
spinlock_t ptp_lock;
+   /* Mutex lock for Auxiliary Snapshots */
+   struct mutex aux_ts_lock;
+
void __iomem *mmcaddr;
void __iomem *ptpaddr;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
index 113c51bcc0b5..ec7ec926f27c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtsta

[PATCH net v1 1/1] ethtool: fix incorrect datatype in set_eee ops

2021-04-06 Thread Wong Vee Khee
The member 'tx_lpi_timer' is defined with __u32 datatype in the ethtool
header file. Hence, we should use ethnl_update_u32() in set_eee ops.

Fixes: fd77be7bd43c ("ethtool: set EEE settings with EEE_SET request")
Cc:  # 5.10.x
Cc: Michal Kubecek 
Signed-off-by: Wong Vee Khee 
---
 net/ethtool/eee.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ethtool/eee.c b/net/ethtool/eee.c
index 901b7de941ab..e10bfcc07853 100644
--- a/net/ethtool/eee.c
+++ b/net/ethtool/eee.c
@@ -169,8 +169,8 @@ int ethnl_set_eee(struct sk_buff *skb, struct genl_info 
*info)
ethnl_update_bool32(_enabled, tb[ETHTOOL_A_EEE_ENABLED], );
ethnl_update_bool32(_lpi_enabled,
tb[ETHTOOL_A_EEE_TX_LPI_ENABLED], );
-   ethnl_update_bool32(_lpi_timer, tb[ETHTOOL_A_EEE_TX_LPI_TIMER],
-   );
+   ethnl_update_u32(_lpi_timer, tb[ETHTOOL_A_EEE_TX_LPI_TIMER],
+);
ret = 0;
if (!mod)
goto out_ops;
-- 
2.25.1



Re: [PATCH net-next v1 1/1] stmmac: intel: Drop duplicate ID in the list of PCI device IDs

2021-04-06 Thread Wong Vee Khee
On Tue, Apr 06, 2021 at 01:13:06PM +0300, Andy Shevchenko wrote:
> The PCI device IDs are defined with a prefix PCI_DEVICE_ID.
> There is no need to repeat the ID part at the end of each definition.
> 
> Signed-off-by: Andy Shevchenko 

Reviewed-by: Wong Vee Khee 

> ---
>  .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 60 +--
>  1 file changed, 30 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
> b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> index 3d9a57043af2..7f0ce373a63d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> @@ -1053,41 +1053,41 @@ static int __maybe_unused intel_eth_pci_resume(struct 
> device *dev)
>  static SIMPLE_DEV_PM_OPS(intel_eth_pm_ops, intel_eth_pci_suspend,
>intel_eth_pci_resume);
>  
> -#define PCI_DEVICE_ID_INTEL_QUARK_ID 0x0937
> -#define PCI_DEVICE_ID_INTEL_EHL_RGMII1G_ID   0x4b30
> -#define PCI_DEVICE_ID_INTEL_EHL_SGMII1G_ID   0x4b31
> -#define PCI_DEVICE_ID_INTEL_EHL_SGMII2G5_ID  0x4b32
> +#define PCI_DEVICE_ID_INTEL_QUARK0x0937
> +#define PCI_DEVICE_ID_INTEL_EHL_RGMII1G  0x4b30
> +#define PCI_DEVICE_ID_INTEL_EHL_SGMII1G  0x4b31
> +#define PCI_DEVICE_ID_INTEL_EHL_SGMII2G5 0x4b32
>  /* Intel(R) Programmable Services Engine (Intel(R) PSE) consist of 2 MAC
>   * which are named PSE0 and PSE1
>   */
> -#define PCI_DEVICE_ID_INTEL_EHL_PSE0_RGMII1G_ID  0x4ba0
> -#define PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII1G_ID  0x4ba1
> -#define PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII2G5_ID 0x4ba2
> -#define PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G_ID  0x4bb0
> -#define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G_ID  0x4bb1
> -#define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G5_ID 0x4bb2
> -#define PCI_DEVICE_ID_INTEL_TGLH_SGMII1G_0_ID0x43ac
> -#define PCI_DEVICE_ID_INTEL_TGLH_SGMII1G_1_ID0x43a2
> -#define PCI_DEVICE_ID_INTEL_TGL_SGMII1G_ID   0xa0ac
> -#define PCI_DEVICE_ID_INTEL_ADLS_SGMII1G_0_ID0x7aac
> -#define PCI_DEVICE_ID_INTEL_ADLS_SGMII1G_1_ID0x7aad
> +#define PCI_DEVICE_ID_INTEL_EHL_PSE0_RGMII1G 0x4ba0
> +#define PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII1G 0x4ba1
> +#define PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII2G50x4ba2
> +#define PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G 0x4bb0
> +#define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G 0x4bb1
> +#define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G50x4bb2
> +#define PCI_DEVICE_ID_INTEL_TGLH_SGMII1G_0   0x43ac
> +#define PCI_DEVICE_ID_INTEL_TGLH_SGMII1G_1   0x43a2
> +#define PCI_DEVICE_ID_INTEL_TGL_SGMII1G  0xa0ac
> +#define PCI_DEVICE_ID_INTEL_ADLS_SGMII1G_0   0x7aac
> +#define PCI_DEVICE_ID_INTEL_ADLS_SGMII1G_1   0x7aad
>  
>  static const struct pci_device_id intel_eth_pci_id_table[] = {
> - { PCI_DEVICE_DATA(INTEL, QUARK_ID, _info) },
> - { PCI_DEVICE_DATA(INTEL, EHL_RGMII1G_ID, _rgmii1g_info) },
> - { PCI_DEVICE_DATA(INTEL, EHL_SGMII1G_ID, _sgmii1g_info) },
> - { PCI_DEVICE_DATA(INTEL, EHL_SGMII2G5_ID, _sgmii1g_info) },
> - { PCI_DEVICE_DATA(INTEL, EHL_PSE0_RGMII1G_ID, _pse0_rgmii1g_info) },
> - { PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII1G_ID, _pse0_sgmii1g_info) },
> - { PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII2G5_ID, _pse0_sgmii1g_info) 
> },
> - { PCI_DEVICE_DATA(INTEL, EHL_PSE1_RGMII1G_ID, _pse1_rgmii1g_info) },
> - { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII1G_ID, _pse1_sgmii1g_info) },
> - { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII2G5_ID, _pse1_sgmii1g_info) 
> },
> - { PCI_DEVICE_DATA(INTEL, TGL_SGMII1G_ID, _sgmii1g_phy0_info) },
> - { PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_0_ID, _sgmii1g_phy0_info) },
> - { PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_1_ID, _sgmii1g_phy1_info) },
> - { PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_0_ID, _sgmii1g_phy0_info) },
> - { PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_1_ID, _sgmii1g_phy1_info) },
> + { PCI_DEVICE_DATA(INTEL, QUARK, _info) },
> + { PCI_DEVICE_DATA(INTEL, EHL_RGMII1G, _rgmii1g_info) },
> + { PCI_DEVICE_DATA(INTEL, EHL_SGMII1G, _sgmii1g_info) },
> + { PCI_DEVICE_DATA(INTEL, EHL_SGMII2G5, _sgmii1g_info) },
> + { PCI_DEVICE_DATA(INTEL, EHL_PSE0_RGMII1G, _pse0_rgmii1g_info) },
> + { PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII1G, _pse0_sgmii1g_info) },
> + { PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII2G5, _pse0_sgmii1g_info) },
> + { PCI_DEVICE_DATA(INTEL, EHL_PSE1_RGMII1G, _pse1_rgmii1g_info) },
> + { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII1G, _pse1_sgmii1g_info) },
> + { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII2G5, _pse1_sgmii1g_info) },
>

RE: [PATCH net-next] net: intel: Enable SERDES PHY rx clk for PSE

2021-04-05 Thread Wong, Vee Khee
On Tue, Apr 06, 2021 at 12:33:57AM +0800, Voon Weifeng wrote: 
>
> EHL PSE SGMII mode requires to ungate the SERDES PHY rx clk for power up
> sequence and vice versa.
> 
> Signed-off-by: Voon Weifeng 
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 10 ++
>  drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h |  1 +
>  2 files changed, 11 insertions(+)
> 

Why not use "stmmac: intel" for the commit message header?


> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> index add95e20548d..a4fec5fe0779 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> @@ -153,6 +153,11 @@ static int intel_serdes_powerup(struct net_device
> *ndev, void *priv_data)
>   return data;
>   }
> 
> + /* PSE only - ungate SGMII PHY Rx Clock */
> + if (intel_priv->is_pse)
> + mdiobus_modify(priv->mii, serdes_phy_addr, SERDES_GCR0,
> +0, SERDES_PHY_RX_CLK);
> +
>   return 0;
>  }
> 
> @@ -168,6 +173,11 @@ static void intel_serdes_powerdown(struct
> net_device *ndev, void *intel_data)
> 
>   serdes_phy_addr = intel_priv->mdio_adhoc_addr;
> 
> + /* PSE only - gate SGMII PHY Rx Clock */
> + if (intel_priv->is_pse)
> + mdiobus_modify(priv->mii, serdes_phy_addr, SERDES_GCR0,
> +SERDES_PHY_RX_CLK, 0);
> +
>   /*  move power state to P3 */
>   data = mdiobus_read(priv->mii, serdes_phy_addr, SERDES_GCR0);
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
> b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
> index e723096c0b15..542acb8ce467 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
> @@ -14,6 +14,7 @@
> 
>  /* SERDES defines */
>  #define SERDES_PLL_CLK   BIT(0)  /* PLL clk valid signal
> */
> +#define SERDES_PHY_RX_CLKBIT(1)  /* PSE SGMII PHY rx clk */
>  #define SERDES_RST   BIT(2)  /* Serdes Reset */
>  #define SERDES_PWR_ST_MASK   GENMASK(6, 4)   /* Serdes Power
> state*/
>  #define SERDES_PWR_ST_SHIFT  4
> --
> 2.17.1



[PATCH net-next 1/1] net: stmmac: remove unnecessary pci_enable_msi() call

2021-04-01 Thread Wong Vee Khee
The commit d2a029bde37b ("stmmac: pci: add MSI support for Intel Quark
X1000") introduced a pci_enable_msi() call in stmmac_pci.c.

With the commit 58da0cfa6cf1 ("net: stmmac: create dwmac-intel.c to
contain all Intel platform"), Intel Quark platform related codes
have been moved to the newly created driver.

Removing this unnecessary pci_enable_msi() call as there are no other
devices that uses stmmac-pci and need MSI to be enabled.

Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index 272cb47af9f2..95e0e4d6f74d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -198,8 +198,6 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
if (ret)
return ret;
 
-   pci_enable_msi(pdev);
-
memset(, 0, sizeof(res));
res.addr = pcim_iomap_table(pdev)[i];
res.wol_irq = pdev->irq;
-- 
2.25.1



[PATCH net-next 1/1] stmmac: intel: use managed PCI function on probe and resume

2021-03-31 Thread Wong Vee Khee
Update dwmac-intel to use managed function, i.e. pcim_enable_device().

This will allow devres framework to call resource free function for us.

Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 3d9a57043af2..add95e20548d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -924,7 +924,7 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
return -ENOMEM;
 
/* Enable pci device */
-   ret = pci_enable_device(pdev);
+   ret = pcim_enable_device(pdev);
if (ret) {
dev_err(>dev, "%s: ERROR: failed to enable device\n",
__func__);
@@ -1006,13 +1006,9 @@ static void intel_eth_pci_remove(struct pci_dev *pdev)
 
stmmac_dvr_remove(>dev);
 
-   pci_free_irq_vectors(pdev);
-
clk_unregister_fixed_rate(priv->plat->stmmac_clk);
 
pcim_iounmap_regions(pdev, BIT(0));
-
-   pci_disable_device(pdev);
 }
 
 static int __maybe_unused intel_eth_pci_suspend(struct device *dev)
@@ -1028,7 +1024,6 @@ static int __maybe_unused intel_eth_pci_suspend(struct 
device *dev)
if (ret)
return ret;
 
-   pci_disable_device(pdev);
pci_wake_from_d3(pdev, true);
return 0;
 }
@@ -1041,7 +1036,7 @@ static int __maybe_unused intel_eth_pci_resume(struct 
device *dev)
pci_restore_state(pdev);
pci_set_power_state(pdev, PCI_D0);
 
-   ret = pci_enable_device(pdev);
+   ret = pcim_enable_device(pdev);
if (ret)
return ret;
 
-- 
2.25.1



[PATCH 1/1] watchdog: Fix a typo in Kconfig

2021-03-31 Thread Wong Vee Khee
s/thershold/threshold

Cc: Vijayakannan Ayyathurai 
Signed-off-by: Wong Vee Khee 
---
 drivers/watchdog/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 0470dc15c085..aa382e5edfef 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -2111,7 +2111,7 @@ config KEEMBAY_WATCHDOG
 This option enable support for an In-secure watchdog timer driver for
 Intel Keem Bay SoC. This WDT has a 32 bit timer and decrements in every
 count unit. An interrupt will be triggered, when the count crosses
-the thershold configured in the register.
+the threshold configured in the register.
 
 To compile this driver as a module, choose M here: the
 module will be called keembay_wdt.
-- 
2.25.1



[PATCH net-next 1/1] net: stmmac: enable MTL ECC Error Address Status Over-ride by default

2021-03-31 Thread Wong Vee Khee
From: Voon Weifeng 

Turn on the MEEAO field of MTL_ECC_Control_Register by default.

As the MTL ECC Error Address Status Over-ride(MEEAO) is set by default,
the following error address fields will hold the last valid address
where the error is detected.

Signed-off-by: Voon Weifeng 
Signed-off-by: Tan Tee Min 
Co-developed-by: Wong Vee Khee 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac5.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
index 5b010ebfede9..d8c6ff725237 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
@@ -192,6 +192,7 @@ int dwmac5_safety_feat_config(void __iomem *ioaddr, 
unsigned int asp)
 
/* 1. Enable Safety Features */
value = readl(ioaddr + MTL_ECC_CONTROL);
+   value |= MEEAO; /* MTL ECC Error Addr Status Override */
value |= TSOEE; /* TSO ECC */
value |= MRXPEE; /* MTL RX Parser ECC */
value |= MESTEE; /* MTL EST ECC */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h 
b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
index ff555d8b0cdf..6b2fd37b29ad 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
@@ -98,6 +98,7 @@
 #define ADDR   GENMASK(15, 0)
 #define MTL_RXP_IACC_DATA  0x0cb4
 #define MTL_ECC_CONTROL0x0cc0
+#define MEEAO  BIT(8)
 #define TSOEE  BIT(4)
 #define MRXPEE BIT(3)
 #define MESTEE BIT(2)
-- 
2.25.1



[PATCH net-next 1/1] stmmac: intel: add cross time-stamping freq difference adjustment

2021-03-29 Thread Wong Vee Khee
Cross time-stamping mechanism used in certain instance of Intel mGbE
may run at different clock frequency in comparison to the clock
frequency used by processor, so we introduce cross T/S frequency
adjustment to ensure TSC calculation is correct when processor got the
cross time-stamps.

Signed-off-by: Wong Vee Khee 
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 08b4852eed4c..3d9a57043af2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -22,8 +22,13 @@
 #define PCH_PTP_CLK_FREQ_19_2MHZ   (GMAC_GPO0)
 #define PCH_PTP_CLK_FREQ_200MHZ(0)
 
+/* Cross-timestamping defines */
+#define ART_CPUID_LEAF 0x15
+#define EHL_PSE_ART_MHZ1920
+
 struct intel_priv_data {
int mdio_adhoc_addr;/* mdio address for serdes & etc */
+   unsigned long crossts_adj;
bool is_pse;
 };
 
@@ -340,9 +345,26 @@ static int intel_crosststamp(ktime_t *device,
*system = convert_art_to_tsc(art_time);
}
 
+   system->cycles *= intel_priv->crossts_adj;
+
return 0;
 }
 
+static void intel_mgbe_pse_crossts_adj(struct intel_priv_data *intel_priv,
+  int base)
+{
+   if (boot_cpu_has(X86_FEATURE_ART)) {
+   unsigned int art_freq;
+
+   /* On systems that support ART, ART frequency can be obtained
+* from ECX register of CPUID leaf (0x15).
+*/
+   art_freq = cpuid_ecx(ART_CPUID_LEAF);
+   do_div(art_freq, base);
+   intel_priv->crossts_adj = art_freq;
+   }
+}
+
 static void common_default_data(struct plat_stmmacenet_data *plat)
 {
plat->clk_csr = 2;  /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
@@ -551,6 +573,8 @@ static int ehl_pse0_common_data(struct pci_dev *pdev,
plat->bus_id = 2;
plat->addr64 = 32;
 
+   intel_mgbe_pse_crossts_adj(intel_priv, EHL_PSE_ART_MHZ);
+
return ehl_common_data(pdev, plat);
 }
 
@@ -587,6 +611,8 @@ static int ehl_pse1_common_data(struct pci_dev *pdev,
plat->bus_id = 3;
plat->addr64 = 32;
 
+   intel_mgbe_pse_crossts_adj(intel_priv, EHL_PSE_ART_MHZ);
+
return ehl_common_data(pdev, plat);
 }
 
@@ -913,6 +939,7 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
 
plat->bsp_priv = intel_priv;
intel_priv->mdio_adhoc_addr = INTEL_MGBE_ADHOC_ADDR;
+   intel_priv->crossts_adj = 1;
 
/* Initialize all MSI vectors to invalid so that it can be set
 * according to platform data settings below.
-- 
2.25.1



RE: [PATCH net-next] net: stmmac: support FPE link partner hand-shaking procedure

2021-03-25 Thread Wong, Vee Khee
On Thu, 25 March 2021, 11:13PM +800, Marek Szyprowski wrote: 
> This patch landed in today's linux-next as commit 5a5586112b92 ("net:
> stmmac: support FPE link partner hand-shaking procedure"). It causes the
> following NULL pointer dereference issue on various Amlogic SoC based
> boards:
> 
>   meson8b-dwmac ff3f.ethernet eth0: PHY [0.0:00] driver [RTL8211F
> Gigabit Ethernet] (irq=35)
>   meson8b-dwmac ff3f.ethernet eth0: No Safety Features support
> found
>   meson8b-dwmac ff3f.ethernet eth0: PTP not supported by HW
>   meson8b-dwmac ff3f.ethernet eth0: configuring for phy/rgmii link
> mode
>   Unable to handle kernel NULL pointer dereference at virtual address
> 0001
>   Mem abort info:
> ...
>   user pgtable: 4k pages, 48-bit VAs, pgdp=044eb000
>   [0001] pgd=, p4d=
>   Internal error: Oops: 9604 [#1] PREEMPT SMP
>   Modules linked in: dw_hdmi_i2s_audio dw_hdmi_cec meson_gxl realtek
> meson_gxbb_wdt snd_soc_meson_axg_sound_card dwmac_generic
> axg_audio
> meson_dw_hdmi crct10dif_ce snd_soc_meson_card_utils
> snd_soc_meson_axg_tdmout panfrost rc_odroid gpu_sched
> reset_meson_audio_arb meson_ir snd_soc_meson_g12a_tohdmitx
> snd_soc_meson_axg_frddr sclk_div clk_phase snd_soc_meson_codec_glue
> dwmac_meson8b snd_soc_meson_axg_fifo stmmac_platform meson_rng
> meson_drm
> stmmac rtc_meson_vrtc rng_core meson_canvas pwm_meson dw_hdmi
> mdio_mux_meson_g12a pcs_xpcs snd_soc_meson_axg_tdm_interface
> snd_soc_meson_axg_tdm_formatter nvmem_meson_efuse
> display_connector
>   CPU: 1 PID: 7 Comm: kworker/u8:0 Not tainted 5.12.0-rc4-next-20210325+
> #2747
>   Hardware name: Hardkernel ODROID-C4 (DT)
>   Workqueue: events_power_efficient phylink_resolve
>   pstate: 2049 (nzCv daif +PAN -UAO -TCO BTYPE=--)
>   pc : stmmac_mac_link_up+0x14c/0x348 [stmmac]
>   lr : stmmac_mac_link_up+0x284/0x348 [stmmac]
> ...
>   Call trace:
>    stmmac_mac_link_up+0x14c/0x348 [stmmac]
>    phylink_resolve+0x104/0x420
>    process_one_work+0x2a8/0x718
>    worker_thread+0x48/0x460
>    kthread+0x134/0x160
>    ret_from_fork+0x10/0x18
>   Code: b971ba60 350007c0 f958c260 f9402000 (39400401)
>   ---[ end trace 0c9deb6c510228aa ]---
> 
> 
> Best regards
> --
> Marek Szyprowski, PhD
> Samsung R Institute Poland

Sorry for that, we will submit a fix for this.

VK



[PATCH net-next 2/2] net: phy: marvell10g: Add PHY loopback support

2021-03-23 Thread Wong Vee Khee
Add support for PHY loopback for Marvell 88x2110 and Marvell 88x3310.

This allow user to perform PHY loopback test using ethtool selftest.

Signed-off-by: Wong Vee Khee 
---
 drivers/net/phy/marvell10g.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index b1bb9b8e1e4e..74b64e52ffa2 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -781,6 +781,7 @@ static struct phy_driver mv3310_drivers[] = {
.get_tunable= mv3310_get_tunable,
.set_tunable= mv3310_set_tunable,
.remove = mv3310_remove,
+   .set_loopback   = genphy_c45_loopback,
},
{
.phy_id = MARVELL_PHY_ID_88E2110,
@@ -796,6 +797,7 @@ static struct phy_driver mv3310_drivers[] = {
.get_tunable= mv3310_get_tunable,
.set_tunable= mv3310_set_tunable,
.remove = mv3310_remove,
+   .set_loopback   = genphy_c45_loopback,
},
 };
 
-- 
2.25.1



[PATCH net-next 0/2] Add support for Clause-45 PHY Loopback

2021-03-23 Thread Wong Vee Khee
This patch series add support for Clause-45 PHY loopback.

It involves adding a generic API in the PHY framework, which can be
accessed by all C45 PHY drivers using the .set_loopback callback.

Also, enable PHY loopback for the Marvell 88x3310/88x2110 driver.

Wong Vee Khee (2):
  net: phy: add genphy_c45_loopback
  net: phy: marvell10g: Add PHY loopback support

 drivers/net/phy/marvell10g.c | 2 ++
 drivers/net/phy/phy-c45.c| 8 
 include/linux/phy.h  | 1 +
 3 files changed, 11 insertions(+)

-- 
2.25.1



[PATCH net-next 1/2] net: phy: add genphy_c45_loopback

2021-03-23 Thread Wong Vee Khee
Add generic code to enable C45 PHY loopback into the common phy-c45.c
file. This will allow C45 PHY drivers aceess this by setting
.set_loopback.

Suggested-by: Heiner Kallweit 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/phy/phy-c45.c | 8 
 include/linux/phy.h   | 1 +
 2 files changed, 9 insertions(+)

diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index 077f2929c45e..91e3acb9e397 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -560,6 +560,14 @@ int gen10g_config_aneg(struct phy_device *phydev)
 }
 EXPORT_SYMBOL_GPL(gen10g_config_aneg);
 
+int genphy_c45_loopback(struct phy_device *phydev, bool enable)
+{
+   return phy_modify_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
+ MDIO_PCS_CTRL1_LOOPBACK,
+ enable ? MDIO_PCS_CTRL1_LOOPBACK : 0);
+}
+EXPORT_SYMBOL_GPL(genphy_c45_loopback);
+
 struct phy_driver genphy_c45_driver = {
.phy_id = 0x,
.phy_id_mask= 0x,
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 1a12e4436b5b..8e2cf84b2318 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1532,6 +1532,7 @@ int genphy_c45_read_mdix(struct phy_device *phydev);
 int genphy_c45_pma_read_abilities(struct phy_device *phydev);
 int genphy_c45_read_status(struct phy_device *phydev);
 int genphy_c45_config_aneg(struct phy_device *phydev);
+int genphy_c45_loopback(struct phy_device *phydev, bool enable);
 
 /* Generic C45 PHY driver */
 extern struct phy_driver genphy_c45_driver;
-- 
2.25.1



[PATCH net-next 1/1] net: stmmac: Add hardware supported cross-timestamp

2021-03-23 Thread Wong Vee Khee
From: Tan Tee Min 

Cross timestamping is supported on Integrated Ethernet Controller in
Intel SoC such as EHL and TGL with Always Running Timer.

The hardware cross-timestamp result is made available to
applications through the PTP_SYS_OFFSET_PRECISE ioctl which calls
stmmac_getcrosststamp().

Device time is stored in the MAC Auxiliary register. The 64-bit System
time (ART timestamp) is stored in registers that are only addressable
by using MDIO space.

Signed-off-by: Tan Tee Min 
Co-developed-by: Wong Vee Khee 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/common.h  |   2 +
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 108 ++
 drivers/net/ethernet/stmicro/stmmac/dwmac4.h  |   8 ++
 .../net/ethernet/stmicro/stmmac/dwmac4_dma.c  |   2 +
 drivers/net/ethernet/stmicro/stmmac/hwif.h|   3 +
 .../ethernet/stmicro/stmmac/stmmac_hwtstamp.c |  11 ++
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.c  |  32 ++
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.h  |  23 
 include/linux/stmmac.h|   4 +
 9 files changed, 193 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1c0c60bdf854..95469059dca1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -388,6 +388,8 @@ struct dma_features {
unsigned int estsel;
unsigned int fpesel;
unsigned int tbssel;
+   /* Numbers of Auxiliary Snapshot Inputs */
+   unsigned int aux_snapshot_n;
 };
 
 /* RX Buffer size must be multiple of 4/8/16 bytes */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 763b549e3c2d..992294d25706 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -8,6 +8,7 @@
 #include "dwmac-intel.h"
 #include "dwmac4.h"
 #include "stmmac.h"
+#include "stmmac_ptp.h"
 
 #define INTEL_MGBE_ADHOC_ADDR  0x15
 #define INTEL_MGBE_XPCS_ADDR   0x16
@@ -240,6 +241,108 @@ static void intel_mgbe_ptp_clk_freq_config(void *npriv)
writel(gpio_value, priv->ioaddr + GMAC_GPIO_STATUS);
 }
 
+static void get_arttime(struct mii_bus *mii, int intel_adhoc_addr,
+   u64 *art_time)
+{
+   u64 ns;
+
+   ns = mdiobus_read(mii, intel_adhoc_addr, PMC_ART_VALUE3);
+   ns <<= GMAC4_ART_TIME_SHIFT;
+   ns |= mdiobus_read(mii, intel_adhoc_addr, PMC_ART_VALUE2);
+   ns <<= GMAC4_ART_TIME_SHIFT;
+   ns |= mdiobus_read(mii, intel_adhoc_addr, PMC_ART_VALUE1);
+   ns <<= GMAC4_ART_TIME_SHIFT;
+   ns |= mdiobus_read(mii, intel_adhoc_addr, PMC_ART_VALUE0);
+
+   *art_time = ns;
+}
+
+static int intel_crosststamp(ktime_t *device,
+struct system_counterval_t *system,
+void *ctx)
+{
+   struct intel_priv_data *intel_priv;
+
+   struct stmmac_priv *priv = (struct stmmac_priv *)ctx;
+   void __iomem *ptpaddr = priv->ptpaddr;
+   void __iomem *ioaddr = priv->hw->pcsr;
+   unsigned long flags;
+   u64 art_time = 0;
+   u64 ptp_time = 0;
+   u32 num_snapshot;
+   u32 gpio_value;
+   u32 acr_value;
+   int ret;
+   u32 v;
+   int i;
+
+   if (!boot_cpu_has(X86_FEATURE_ART))
+   return -EOPNOTSUPP;
+
+   intel_priv = priv->plat->bsp_priv;
+
+   /* Enable Internal snapshot trigger */
+   acr_value = readl(ptpaddr + PTP_ACR);
+   acr_value &= ~PTP_ACR_MASK;
+   switch (priv->plat->int_snapshot_num) {
+   case AUX_SNAPSHOT0:
+   acr_value |= PTP_ACR_ATSEN0;
+   break;
+   case AUX_SNAPSHOT1:
+   acr_value |= PTP_ACR_ATSEN1;
+   break;
+   case AUX_SNAPSHOT2:
+   acr_value |= PTP_ACR_ATSEN2;
+   break;
+   case AUX_SNAPSHOT3:
+   acr_value |= PTP_ACR_ATSEN3;
+   break;
+   default:
+   return -EINVAL;
+   }
+   writel(acr_value, ptpaddr + PTP_ACR);
+
+   /* Clear FIFO */
+   acr_value = readl(ptpaddr + PTP_ACR);
+   acr_value |= PTP_ACR_ATSFC;
+   writel(acr_value, ptpaddr + PTP_ACR);
+
+   /* Trigger Internal snapshot signal
+* Create a rising edge by just toggle the GPO1 to low
+* and back to high.
+*/
+   gpio_value = readl(ioaddr + GMAC_GPIO_STATUS);
+   gpio_value &= ~GMAC_GPO1;
+   writel(gpio_value, ioaddr + GMAC_GPIO_STATUS);
+   gpio_value |= GMAC_GPO1;
+   writel(gpio_value, ioaddr + GMAC_GPIO_STATUS);
+
+   /* Poll for time sync operation done */
+   ret = readl_poll_timeout(priv->ioaddr + GMAC_INT_STATUS, v,
+(v & GMAC_INT_TSIE), 100, 1);
+
+   if (ret == -ETIMEDOUT) {
+

[PATCH net-next 1/1] net: phy: marvell10g: Add PHY loopback support for 88E2110 PHY

2021-03-23 Thread Wong Vee Khee
From: Tan Tee Min 

Add support for PHY loopback for the Marvell 88E2110 PHY.

This allow user to perform selftest using ethtool.

Signed-off-by: Tan Tee Min 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/phy/marvell10g.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index b1bb9b8e1e4e..c45a8f11bdcf 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -89,6 +89,8 @@ enum {
MV_V2_TEMP_CTRL_DISABLE = 0xc000,
MV_V2_TEMP  = 0xf08c,
MV_V2_TEMP_UNKNOWN  = 0x9600, /* unknown function */
+
+   MV_LOOPBACK = BIT(14), /* Loopback (88E2110 only) */
 };
 
 struct mv3310_priv {
@@ -765,6 +767,15 @@ static int mv3310_set_tunable(struct phy_device *phydev,
}
 }
 
+static int mv3310_loopback(struct phy_device *phydev, bool enable)
+{
+   if (phydev->drv->phy_id != MARVELL_PHY_ID_88E2110)
+   return -EOPNOTSUPP;
+
+   return phy_modify_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_T,
+ MV_LOOPBACK, enable ? MV_LOOPBACK : 0);
+}
+
 static struct phy_driver mv3310_drivers[] = {
{
.phy_id = MARVELL_PHY_ID_88X3310,
@@ -796,6 +807,7 @@ static struct phy_driver mv3310_drivers[] = {
.get_tunable= mv3310_get_tunable,
.set_tunable= mv3310_set_tunable,
.remove = mv3310_remove,
+   .set_loopback   = mv3310_loopback,
},
 };
 
-- 
2.25.1



RE: [PATCH net V2 1/1] net: phy: fix invalid phy id when probe using C22

2021-03-22 Thread Wong, Vee Khee
On Fri, Mar 19, 2021 at 04:56PM +0800, Russell King - ARM Linux admin wrote:
> On Fri, Mar 19, 2021 at 08:40:45AM +0100, Heiner Kallweit wrote:
>> Is there a specific reason why c22 is probed first? Reversing the order
>> would solve the issue we speak about here.
>> c45-probing of c22-only PHY's shouldn't return false positives
>> (at least at a first glance).
> 
> That would likely cause problems for the I2f MDIO driver, since a
> C45 read is indistinguishable from a C22 write on the I2C bus.
> 

Hi Russell,

STMMAC is capable of supporting external PHYs that accessible using 
C22 or C45. 

Accordng to patch [1] send earlier, it should solve the problem.

As for any other drivers, if it is not using MDIOBUS_C45_C22, 
It should still work as it is by using MDIOBUS_C22.

[1] https://lkml.org/lkml/2020/11/9/443

> --
> RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
> FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


[PATCH net V2 1/1] net: phy: fix invalid phy id when probe using C22

2021-03-18 Thread Wong Vee Khee
When using Clause-22 to probe for PHY devices such as the Marvell
88E2110, PHY ID with value 0 is read from the MII PHYID registers
which caused the PHY framework failed to attach the Marvell PHY
driver.

Fixed this by adding a check of PHY ID equals to all zeroes.

Fixes: ee951005e95e ("net: phy: clean up get_phy_c22_id() invalid ID handling")
Cc: sta...@vger.kernel.org
Reviewed-by: Voon Weifeng 
Signed-off-by: Wong Vee Khee 
---
v2 changelog:
 - added fixes tag
 - marked for net instead of net-next
---
 drivers/net/phy/phy_device.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index cc38e326405a..c12c30254c11 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -809,8 +809,8 @@ static int get_phy_c22_id(struct mii_bus *bus, int addr, 
u32 *phy_id)
 
*phy_id |= phy_reg;
 
-   /* If the phy_id is mostly Fs, there is no device there */
-   if ((*phy_id & 0x1fff) == 0x1fff)
+   /* If the phy_id is mostly Fs or all zeroes, there is no device there */
+   if (((*phy_id & 0x1fff) == 0x1fff) || (*phy_id == 0))
return -ENODEV;
 
return 0;
-- 
2.25.1



RE: [PATCH net-next 1/1] net: phy: fix invalid phy id when probe using C22

2021-03-18 Thread Wong, Vee Khee
> -Original Message-
> From: Heiner Kallweit 
> Sent: Wednesday, March 17, 2021 4:15 PM
> To: Wong, Vee Khee ; Andrew Lunn
> ; Russell King ; David S . Miller
> ; Jakub Kicinski 
> Cc: net...@vger.kernel.org; linux-kernel@vger.kernel.org;
> sta...@vger.kernel.org; Voon Weifeng ; Ong,
> Boon Leong 
> Subject: Re: [PATCH net-next 1/1] net: phy: fix invalid phy id when probe
> using C22
> 
> On 16.03.2021 09:57, Wong Vee Khee wrote:
> > When using Clause-22 to probe for PHY devices such as the Marvell
> > 88E2110, PHY ID with value 0 is read from the MII PHYID registers
> > which caused the PHY framework failed to attach the Marvell PHY
> > driver.
> >
> 
> The issue occurs with a MAC driver that sets MDIO bus capability
> flag MDIOBUS_C22_C45, like stmmac? Or what is the affected MAC
> driver?
> 

Yes, you are right. This issue is seen when MarvellE2110 is used with
the STMMAC.

> And if you state it's a fix, a Fixes tag would be needed.
> 

Noted. Will send a v2 and marked for net.

> > Fixed this by adding a check of PHY ID equals to all zeroes.
> >
> > Cc: sta...@vger.kernel.org
> > Reviewed-by: Voon Weifeng 
> > Signed-off-by: Wong Vee Khee 
> > ---
> >  drivers/net/phy/phy_device.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> > index a009d1769b08..f1afc00fcba2 100644
> > --- a/drivers/net/phy/phy_device.c
> > +++ b/drivers/net/phy/phy_device.c
> > @@ -820,8 +820,8 @@ static int get_phy_c22_id(struct mii_bus *bus, int
> addr, u32 *phy_id)
> >
> > *phy_id |= phy_reg;
> >
> > -   /* If the phy_id is mostly Fs, there is no device there */
> > -   if ((*phy_id & 0x1fff) == 0x1fff)
> > +   /* If the phy_id is mostly Fs or all zeroes, there is no device there */
> > +   if (((*phy_id & 0x1fff) == 0x1fff) || (*phy_id == 0))
> > return -ENODEV;
> >
> > return 0;
> >



[PATCH net-next 1/1] net: stmmac: add timestamp correction to rid CDC sync error

2021-03-16 Thread Wong Vee Khee
From: Voon Weifeng 

According to Synopsis DesignWare EQoS Databook, the Clock Domain Cross
synchronization error is introduced tue to the clock(GMII Tx/Rx clock)
being different at the capture as compared to the PTP
clock(clk_ptp_ref_i) that is used to generate the time.

The CDC synchronization error is almost equal to 2 times the clock
period of the PTP clock(clk_ptp_ref_i).

On a Intel Tigerlake platform (with Marvell 88E2110 external PHY):

Before applying this patch (with CDC synchronization error):
ptp4l[64.044]: rms8 max   13 freq +30877 +/-  11 delay   216 +/-   0
ptp4l[65.047]: rms   13 max   20 freq +30869 +/-  17 delay   213 +/-   0
ptp4l[66.050]: rms   12 max   20 freq +30857 +/-  11 delay   213 +/-   0
ptp4l[67.052]: rms   11 max   22 freq +30849 +/-  10 delay   215 +/-   0
ptp4l[68.055]: rms   10 max   16 freq +30853 +/-  13 delay   215 +/-   0
ptp4l[69.057]: rms7 max   13 freq +30848 +/-   9 delay   216 +/-   0
ptp4l[70.060]: rms8 max   13 freq +30846 +/-  10 delay   216 +/-   0
ptp4l[71.063]: rms9 max   15 freq +30836 +/-   8 delay   218 +/-   0

After applying this patch (CDC syncrhonization error is taken care of):
ptp4l[61.516]: rms  773 max  824 freq +31526 +/- 158 delay   200 +/-   0
ptp4l[62.519]: rms  427 max  596 freq +31668 +/-  39 delay   198 +/-   0
ptp4l[63.522]: rms  113 max  206 freq +31482 +/-  57 delay   198 +/-   0
ptp4l[64.525]: rms   40 max   56 freq +31316 +/-  29 delay   200 +/-   0
ptp4l[65.528]: rms   47 max   56 freq +31255 +/-  17 delay   200 +/-   0
ptp4l[66.531]: rms   26 max   36 freq +31246 +/-   9 delay   200 +/-   0
ptp4l[67.534]: rms   12 max   18 freq +31254 +/-  12 delay   202 +/-   0
ptp4l[68.537]: rms7 max   12 freq +31263 +/-  10 delay   202 +/-   0

Signed-off-by: Voon Weifeng 
Signed-off-by: Wong Vee Khee 
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c| 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index a10704d8e3c6..ddf54b8ad75d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -466,6 +466,7 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
 {
struct skb_shared_hwtstamps shhwtstamp;
bool found = false;
+   s64 adjust = 0;
u64 ns = 0;
 
if (!priv->hwts_tx_en)
@@ -484,6 +485,13 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv 
*priv,
}
 
if (found) {
+   /* Correct the clk domain crossing(CDC) error */
+   if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) {
+   adjust += -(2 * (NSEC_PER_SEC /
+priv->plat->clk_ptp_rate));
+   ns += adjust;
+   }
+
memset(, 0, sizeof(struct skb_shared_hwtstamps));
shhwtstamp.hwtstamp = ns_to_ktime(ns);
 
@@ -507,6 +515,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv 
*priv, struct dma_desc *p,
 {
struct skb_shared_hwtstamps *shhwtstamp = NULL;
struct dma_desc *desc = p;
+   u64 adjust = 0;
u64 ns = 0;
 
if (!priv->hwts_rx_en)
@@ -518,6 +527,13 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv 
*priv, struct dma_desc *p,
/* Check if timestamp is available */
if (stmmac_get_rx_timestamp_status(priv, p, np, priv->adv_ts)) {
stmmac_get_timestamp(priv, desc, priv->adv_ts, );
+
+   /* Correct the clk domain crossing(CDC) error */
+   if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) {
+   adjust += 2 * (NSEC_PER_SEC / priv->plat->clk_ptp_rate);
+   ns -= adjust;
+   }
+
netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns);
shhwtstamp = skb_hwtstamps(skb);
memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
-- 
2.25.1



[PATCH net-next 1/1] net: phy: fix invalid phy id when probe using C22

2021-03-16 Thread Wong Vee Khee
When using Clause-22 to probe for PHY devices such as the Marvell
88E2110, PHY ID with value 0 is read from the MII PHYID registers
which caused the PHY framework failed to attach the Marvell PHY
driver.

Fixed this by adding a check of PHY ID equals to all zeroes.

Cc: sta...@vger.kernel.org
Reviewed-by: Voon Weifeng 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/phy/phy_device.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index a009d1769b08..f1afc00fcba2 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -820,8 +820,8 @@ static int get_phy_c22_id(struct mii_bus *bus, int addr, 
u32 *phy_id)
 
*phy_id |= phy_reg;
 
-   /* If the phy_id is mostly Fs, there is no device there */
-   if ((*phy_id & 0x1fff) == 0x1fff)
+   /* If the phy_id is mostly Fs or all zeroes, there is no device there */
+   if (((*phy_id & 0x1fff) == 0x1fff) || (*phy_id == 0))
return -ENODEV;
 
return 0;
-- 
2.25.1



[PATCH net 1/1] stmmac: intel: Fix mdio bus registration issue for TGL-H/ADL-S

2021-03-02 Thread Wong Vee Khee
On Intel platforms which consist of two Ethernet Controllers such as
TGL-H and ADL-S, a unique MDIO bus id is required for MDIO bus to be
successful registered:

[   13.076133] sysfs: cannot create duplicate filename 
'/class/mdio_bus/stmmac-1'
[   13.083404] CPU: 8 PID: 1898 Comm: systemd-udevd Tainted: G U
5.11.0-net-next #106
[   13.092410] Hardware name: Intel Corporation Alder Lake Client 
Platform/AlderLake-S ADP-S DRR4 CRB, BIOS ADLIFSI1.R00.1494.B00.2012031421 
12/03/2020
[   13.105709] Call Trace:
[   13.108176]  dump_stack+0x64/0x7c
[   13.111553]  sysfs_warn_dup+0x56/0x70
[   13.115273]  sysfs_do_create_link_sd.isra.2+0xbd/0xd0
[   13.120371]  device_add+0x4df/0x840
[   13.123917]  ? complete_all+0x2a/0x40
[   13.127636]  __mdiobus_register+0x98/0x310 [libphy]
[   13.132572]  stmmac_mdio_register+0x1c5/0x3f0 [stmmac]
[   13.137771]  ? stmmac_napi_add+0xa5/0xf0 [stmmac]
[   13.142493]  stmmac_dvr_probe+0x806/0xee0 [stmmac]
[   13.147341]  intel_eth_pci_probe+0x1cb/0x250 [dwmac_intel]
[   13.152884]  pci_device_probe+0xd2/0x150
[   13.156897]  really_probe+0xf7/0x4d0
[   13.160527]  driver_probe_device+0x5d/0x140
[   13.164761]  device_driver_attach+0x4f/0x60
[   13.168996]  __driver_attach+0xa2/0x140
[   13.172891]  ? device_driver_attach+0x60/0x60
[   13.177300]  bus_for_each_dev+0x76/0xc0
[   13.181188]  bus_add_driver+0x189/0x230
[   13.185083]  ? 0xc0795000
[   13.188446]  driver_register+0x5b/0xf0
[   13.192249]  ? 0xc0795000
[   13.195577]  do_one_initcall+0x4d/0x210
[   13.199467]  ? kmem_cache_alloc_trace+0x2ff/0x490
[   13.204228]  do_init_module+0x5b/0x21c
[   13.208031]  load_module+0x2a0c/0x2de0
[   13.211838]  ? __do_sys_finit_module+0xb1/0x110
[   13.216420]  __do_sys_finit_module+0xb1/0x110
[   13.220825]  do_syscall_64+0x33/0x40
[   13.224451]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[   13.229515] RIP: 0033:0x7fc2b1919ccd
[   13.233113] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 
f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 
f0 ff ff 73 01 c3 48 8b 0d 93 31 0c 00 f7 d8 64 89 01 48
[   13.251912] RSP: 002b:7ffcea2e5b98 EFLAGS: 0246 ORIG_RAX: 
0139
[   13.259527] RAX: ffda RBX: 560558920f10 RCX: 7fc2b1919ccd
[   13.266706] RDX:  RSI: 7fc2b1a881e3 RDI: 0012
[   13.273887] RBP: 0002 R08:  R09: 
[   13.281036] R10: 0012 R11: 0246 R12: 7fc2b1a881e3
[   13.288183] R13:  R14:  R15: 7ffcea2e5d58
[   13.295389] libphy: mii_bus stmmac-1 failed to register

Fixes: 88af9bd4efbd ("stmmac: intel: Add ADL-S 1Gbps PCI IDs")
Fixes: 8450e23f142f ("stmmac: intel: Add PCI IDs for TGL-H platform")
Signed-off-by: Wong Vee Khee 
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 54 ++-
 1 file changed, 41 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 74b14d647619..e6eaf378e8e7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -462,8 +462,8 @@ static int tgl_common_data(struct pci_dev *pdev,
return intel_mgbe_common_data(pdev, plat);
 }
 
-static int tgl_sgmii_data(struct pci_dev *pdev,
- struct plat_stmmacenet_data *plat)
+static int tgl_sgmii_phy0_data(struct pci_dev *pdev,
+  struct plat_stmmacenet_data *plat)
 {
plat->bus_id = 1;
plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
@@ -472,12 +472,26 @@ static int tgl_sgmii_data(struct pci_dev *pdev,
return tgl_common_data(pdev, plat);
 }
 
-static struct stmmac_pci_info tgl_sgmii1g_info = {
-   .setup = tgl_sgmii_data,
+static struct stmmac_pci_info tgl_sgmii1g_phy0_info = {
+   .setup = tgl_sgmii_phy0_data,
 };
 
-static int adls_sgmii_data(struct pci_dev *pdev,
-  struct plat_stmmacenet_data *plat)
+static int tgl_sgmii_phy1_data(struct pci_dev *pdev,
+  struct plat_stmmacenet_data *plat)
+{
+   plat->bus_id = 2;
+   plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+   plat->serdes_powerup = intel_serdes_powerup;
+   plat->serdes_powerdown = intel_serdes_powerdown;
+   return tgl_common_data(pdev, plat);
+}
+
+static struct stmmac_pci_info tgl_sgmii1g_phy1_info = {
+   .setup = tgl_sgmii_phy1_data,
+};
+
+static int adls_sgmii_phy0_data(struct pci_dev *pdev,
+   struct plat_stmmacenet_data *plat)
 {
plat->bus_id = 1;
plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
@@ -487,10 +501,24 @@ static int adls_sgmii_data(struct pci_dev *pdev,
return tgl_common_data(pdev, plat);
 }
 
-static struct stmmac_pci_info adls_sgmii1g_info = 

[PATCH net-next 1/1] net: stmmac: Add PCI bus info to ethtool driver query output

2021-02-17 Thread Wong Vee Khee
This patch populates the PCI bus info in the ethtool driver query data.

Users will be able to view PCI bus info using 'ethtool -i '.

Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c| 1 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 4 
 include/linux/stmmac.h   | 1 +
 3 files changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 1c9c67b641a2..751dfdeec41c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -236,6 +236,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
int ret;
int i;
 
+   plat->pdev = pdev;
plat->phy_addr = -1;
plat->clk_csr = 5;
plat->has_gmac = 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 9e54f953634b..c5642985ef95 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -268,6 +268,10 @@ static void stmmac_ethtool_getdrvinfo(struct net_device 
*dev,
strlcpy(info->driver, MAC100_ETHTOOL_NAME,
sizeof(info->driver));
 
+   if (priv->plat->pdev) {
+   strlcpy(info->bus_info, pci_name(priv->plat->pdev),
+   sizeof(info->bus_info));
+   }
strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
 }
 
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 15ca6b4167cc..a302982de2d7 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -202,5 +202,6 @@ struct plat_stmmacenet_data {
bool vlan_fail_q_en;
u8 vlan_fail_q;
unsigned int eee_usecs_rate;
+   struct pci_dev *pdev;
 };
 #endif
-- 
2.17.0



[PATCH net-next 1/1] stmmac: intel: Add ADL-S 1Gbps PCI IDs

2021-01-26 Thread Wong Vee Khee
From: "Wong, Vee Khee" 

Added PCI IDs for both Ethernet TSN Controllers on the ADL-S.

Also, skip SerDes programming sequences as these are being carried out
at the BIOS level for ADL-S.

Signed-off-by: Wong, Vee Khee 
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 9a6a519426a0..9c272a241136 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -457,6 +457,21 @@ static struct stmmac_pci_info tgl_sgmii1g_info = {
.setup = tgl_sgmii_data,
 };
 
+static int adls_sgmii_data(struct pci_dev *pdev,
+  struct plat_stmmacenet_data *plat)
+{
+   plat->bus_id = 1;
+   plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+
+   /* SerDes power up and power down are done in BIOS for ADL */
+
+   return tgl_common_data(pdev, plat);
+}
+
+static struct stmmac_pci_info adls_sgmii1g_info = {
+   .setup = adls_sgmii_data,
+};
+
 static const struct stmmac_pci_func_data galileo_stmmac_func_data[] = {
{
.func = 6,
@@ -724,6 +739,8 @@ static SIMPLE_DEV_PM_OPS(intel_eth_pm_ops, 
intel_eth_pci_suspend,
 #define PCI_DEVICE_ID_INTEL_TGLH_SGMII1G_0_ID  0x43ac
 #define PCI_DEVICE_ID_INTEL_TGLH_SGMII1G_1_ID  0x43a2
 #define PCI_DEVICE_ID_INTEL_TGL_SGMII1G_ID 0xa0ac
+#define PCI_DEVICE_ID_INTEL_ADLS_SGMII1G_0_ID  0x7aac
+#define PCI_DEVICE_ID_INTEL_ADLS_SGMII1G_1_ID  0x7aad
 
 static const struct pci_device_id intel_eth_pci_id_table[] = {
{ PCI_DEVICE_DATA(INTEL, QUARK_ID, _info) },
@@ -739,6 +756,8 @@ static const struct pci_device_id intel_eth_pci_id_table[] 
= {
{ PCI_DEVICE_DATA(INTEL, TGL_SGMII1G_ID, _sgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_0_ID, _sgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_1_ID, _sgmii1g_info) },
+   { PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_0_ID, _sgmii1g_info) },
+   { PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_1_ID, _sgmii1g_info) },
{}
 };
 MODULE_DEVICE_TABLE(pci, intel_eth_pci_id_table);
-- 
2.17.0



[PATCH v2 net-next 1/1] net: stmmac: allow stmmac to probe for C45 PHY devices

2020-12-09 Thread Wong Vee Khee
Assign stmmac's mdio_bus probe capabilities to MDIOBUS_C22_C45.
This extended the probing of C45 PHY devices on the MDIO bus.

Signed-off-by: Wong Vee Khee 
---
v2 changelog:
- Added conditional check for gmac4.
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index b2a707e2ef43..d64116e0543e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -365,6 +365,9 @@ int stmmac_mdio_register(struct net_device *ndev)
 
new_bus->name = "stmmac";
 
+   if (priv->plat->has_gmac4)
+   new_bus->probe_capabilities = MDIOBUS_C22_C45;
+
if (priv->plat->has_xgmac) {
new_bus->read = _xgmac2_mdio_read;
new_bus->write = _xgmac2_mdio_write;
-- 
2.17.0



RE: [PATCH net-next 1/1] net: stmmac: allow stmmac to probe for C45 PHY devices

2020-12-09 Thread Wong, Vee Khee



> -Original Message-
> From: Andrew Lunn 
> Sent: Thursday, December 10, 2020 12:09 AM
> To: Wong, Vee Khee 
> Cc: Giuseppe Cavallaro ; Alexandre Torgue
> ; Jose Abreu ; David
> S . Miller ; Jakub Kicinski ;
> Maxime Coquelin ; Voon, Weifeng
> ; net...@vger.kernel.org; linux-
> ker...@vger.kernel.org; Ong, Boon Leong ;
> linux-st...@st-md-mailman.stormreply.com; linux-arm-
> ker...@lists.infradead.org
> Subject: Re: [PATCH net-next 1/1] net: stmmac: allow stmmac to probe for
> C45 PHY devices
> 
> On Wed, Dec 09, 2020 at 07:19:33PM +0800, Wong Vee Khee wrote:
> > Assign stmmac's mdio_bus probe capabilities to MDIOBUS_C22_C45.
> > This extends the probing of C45 PHY devices on the MDIO bus.
> >
> > Signed-off-by: Wong Vee Khee 
> > ---
> >  drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> > index b2a707e2ef43..9f96bb7d27db 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> > @@ -364,6 +364,7 @@ int stmmac_mdio_register(struct net_device *ndev)
> > memcpy(new_bus->irq, mdio_bus_data->irqs,
> sizeof(new_bus->irq));
> >
> > new_bus->name = "stmmac";
> > +   new_bus->probe_capabilities = MDIOBUS_C22_C45;
> 
> It looks like this needs to be conditional on the version. xgmax2
> supports C45. And gmac4. But other versions don't.
> 
>Andrew

I will send a v2 with conditional checking for gmac4.
I do not have a xgmac2 hardware setup to test this.


[PATCH net-next 1/1] net: stmmac: allow stmmac to probe for C45 PHY devices

2020-12-09 Thread Wong Vee Khee
Assign stmmac's mdio_bus probe capabilities to MDIOBUS_C22_C45.
This extends the probing of C45 PHY devices on the MDIO bus.

Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index b2a707e2ef43..9f96bb7d27db 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -364,6 +364,7 @@ int stmmac_mdio_register(struct net_device *ndev)
memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
 
new_bus->name = "stmmac";
+   new_bus->probe_capabilities = MDIOBUS_C22_C45;
 
if (priv->plat->has_xgmac) {
new_bus->read = _xgmac2_mdio_read;
-- 
2.17.0



[PATCH v2 net 1/1] net: stmmac: Use rtnl_lock/unlock on netif_set_real_num_rx_queues() call

2020-11-14 Thread Wong Vee Khee
Fix an issue where dump stack is printed on suspend resume flow due to
netif_set_real_num_rx_queues() is not called with rtnl_lock held().

Fixes: 686cff3d7022 ("net: stmmac: Fix incorrect location to set 
real_num_rx|tx_queues")
Reported-by: Christophe ROULLIER 
Tested-by: Christophe ROULLIER 
Cc: Alexandre TORGUE 
Reviewed-by: Ong Boon Leong 
Signed-off-by: Wong Vee Khee 
---
v2 changelog:
- Move rtnl_lock() before priv->lock and release it after to avoid a
  possible ABBA deadlock scenario.
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ba855465a2db..c8770e9668a1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5272,6 +5272,7 @@ int stmmac_resume(struct device *dev)
return ret;
}
 
+   rtnl_lock();
mutex_lock(>lock);
 
stmmac_reset_queues_param(priv);
@@ -5287,6 +5288,7 @@ int stmmac_resume(struct device *dev)
stmmac_enable_all_queues(priv);
 
mutex_unlock(>lock);
+   rtnl_unlock();
 
if (!device_may_wakeup(priv->device) || !priv->plat->pmt) {
rtnl_lock();
-- 
2.17.0



[PATCH net-next 1/1] net: phy: Add additional logics on probing C45 PHY devices

2020-11-12 Thread Wong Vee Khee
For clause 45 PHY, introduce additional logics in get_phy_c45_ids() to
check if there is at least one valid device ID, return 0 on true, and
-ENODEV otherwise.

Signed-off-by: Wong Vee Khee 
---
 drivers/net/phy/phy_device.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index e13a46c25437..c9ddcd7a63d4 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -730,6 +730,7 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr,
const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
u32 devs_in_pkg = 0;
int i, ret, phy_reg;
+   u32 valid_did = 0;
 
/* Find first non-zero Devices In package. Device zero is reserved
 * for 802.3 c45 complied PHYs, so don't probe it at first.
@@ -796,12 +797,21 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr,
if (phy_reg < 0)
return -EIO;
c45_ids->device_ids[i] |= phy_reg;
+
+   /* Check if there is at least one valid device ID */
+   if (c45_ids->device_ids[i] &&
+   (c45_ids->device_ids[i] & 0x1fff) != 0x1fff)
+   valid_did |= (1 << i);
}
 
c45_ids->devices_in_package = devs_in_pkg;
/* Bit 0 doesn't represent a device, it indicates c22 regs presence */
c45_ids->mmds_present = devs_in_pkg & ~BIT(0);
 
+   /* There is no valid device ID */
+   if (!valid_did)
+   return -ENODEV;
+
return 0;
 }
 
-- 
2.17.0



[PATCH net 1/1] net: stmmac: Use rtnl_lock/unlock on netif_set_real_num_rx_queues() call

2020-11-12 Thread Wong Vee Khee
Fix an issue where dump stack is printed on suspend resume flow due to
netif_set_real_num_rx_queues() is not called with rtnl_lock held().

Fixes: 686cff3d7022 ("net: stmmac: Fix incorrect location to set 
real_num_rx|tx_queues")
Reported-by: Christophe ROULLIER 
Tested-by: Christophe ROULLIER 
Cc: Alexandre TORGUE 
Reviewed-by: Ong Boon Leong 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ba855465a2db..33e28004 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5278,7 +5278,10 @@ int stmmac_resume(struct device *dev)
 
stmmac_clear_descriptors(priv);
 
+   rtnl_lock();
stmmac_hw_setup(ndev, false);
+   rtnl_unlock();
+
stmmac_init_coalesce(priv);
stmmac_set_rx_mode(ndev);
 
-- 
2.17.0



[PATCH net-next 1/1] net: phy: Allow mdio buses to probe C45 before falling back to C22

2020-11-09 Thread Wong Vee Khee
This patch makes mdiobus_scan() to try on C45 first as C45 can access
all devices. This allows the function available for the PHY that
supports for both C45 and C22.

Reviewed-by: Voon Weifeng 
Reviewed-by: Ong Boon Leong 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/phy/mdio_bus.c | 5 +
 include/linux/phy.h| 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 56094dd6bf26..372d0d088f7e 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -691,6 +691,11 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int 
addr)
if (IS_ERR(phydev))
phydev = get_phy_device(bus, addr, true);
break;
+   case MDIOBUS_C45_C22:
+   phydev = get_phy_device(bus, addr, true);
+   if (IS_ERR(phydev))
+   phydev = get_phy_device(bus, addr, false);
+   break;
}
 
if (IS_ERR(phydev))
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 189bc9881ea6..73d9be2c00f4 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -360,6 +360,7 @@ struct mii_bus {
MDIOBUS_C22,
MDIOBUS_C45,
MDIOBUS_C22_C45,
+   MDIOBUS_C45_C22,
} probe_capabilities;
 
/** @shared_lock: protect access to the shared element */
-- 
2.17.0



[PATCH net-next 1/1] stmmac: intel: change all EHL/TGL to auto detect phy addr

2020-11-06 Thread Wong Vee Khee
From: Voon Weifeng 

Set all EHL/TGL phy_addr to -1 so that the driver will automatically
detect it at run-time by probing all the possible 32 addresses.

Signed-off-by: Voon Weifeng 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index b6e5e3e36b63..7c1353f37247 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -236,6 +236,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
int ret;
int i;
 
+   plat->phy_addr = -1;
plat->clk_csr = 5;
plat->has_gmac = 0;
plat->has_gmac4 = 1;
@@ -345,7 +346,6 @@ static int ehl_sgmii_data(struct pci_dev *pdev,
  struct plat_stmmacenet_data *plat)
 {
plat->bus_id = 1;
-   plat->phy_addr = 0;
plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
 
plat->serdes_powerup = intel_serdes_powerup;
@@ -362,7 +362,6 @@ static int ehl_rgmii_data(struct pci_dev *pdev,
  struct plat_stmmacenet_data *plat)
 {
plat->bus_id = 1;
-   plat->phy_addr = 0;
plat->phy_interface = PHY_INTERFACE_MODE_RGMII;
 
return ehl_common_data(pdev, plat);
@@ -376,7 +375,6 @@ static int ehl_pse0_common_data(struct pci_dev *pdev,
struct plat_stmmacenet_data *plat)
 {
plat->bus_id = 2;
-   plat->phy_addr = 1;
return ehl_common_data(pdev, plat);
 }
 
@@ -408,7 +406,6 @@ static int ehl_pse1_common_data(struct pci_dev *pdev,
struct plat_stmmacenet_data *plat)
 {
plat->bus_id = 3;
-   plat->phy_addr = 1;
return ehl_common_data(pdev, plat);
 }
 
@@ -450,7 +447,6 @@ static int tgl_sgmii_data(struct pci_dev *pdev,
  struct plat_stmmacenet_data *plat)
 {
plat->bus_id = 1;
-   plat->phy_addr = 0;
plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
plat->serdes_powerup = intel_serdes_powerup;
plat->serdes_powerdown = intel_serdes_powerdown;
-- 
2.17.0



[PATCH net 1/1] stmmac: intel: Fix kernel panic on pci probe

2020-10-29 Thread Wong Vee Khee
The commit "stmmac: intel: Adding ref clock 1us tic for LPI cntr"
introduced a regression which leads to the kernel panic duing loading
of the dwmac_intel module.

Move the code block after pci resources is obtained.

Fixes: b4c5f83ae3f3 ("stmmac: intel: Adding ref clock 1us tic for LPI cntr")
Cc: Voon Weifeng 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index b6e5e3e36b63..81ee0a071b4e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -625,13 +625,6 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
if (ret)
return ret;
 
-   if (plat->eee_usecs_rate > 0) {
-   u32 tx_lpi_usec;
-
-   tx_lpi_usec = (plat->eee_usecs_rate / 100) - 1;
-   writel(tx_lpi_usec, res.addr + GMAC_1US_TIC_COUNTER);
-   }
-
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
return ret;
@@ -641,6 +634,13 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
res.wol_irq = pci_irq_vector(pdev, 0);
res.irq = pci_irq_vector(pdev, 0);
 
+   if (plat->eee_usecs_rate > 0) {
+   u32 tx_lpi_usec;
+
+   tx_lpi_usec = (plat->eee_usecs_rate / 100) - 1;
+   writel(tx_lpi_usec, res.addr + GMAC_1US_TIC_COUNTER);
+   }
+
ret = stmmac_dvr_probe(>dev, plat, );
if (ret) {
pci_free_irq_vectors(pdev);
-- 
2.17.0



[PATCH net 1/1] net: stmmac: Fix clock handling on remove path

2020-09-25 Thread Wong Vee Khee
While unloading the dwmac-intel driver, clk_disable_unprepare() is
being called twice in stmmac_dvr_remove() and
intel_eth_pci_remove(). This causes kernel panic on the second call.

Removing the second call of clk_disable_unprepare() in
intel_eth_pci_remove().

Fixes: 09f012e64e4b ("stmmac: intel: Fix clock handling on error and remove 
paths")
Cc: Andy Shevchenko 
Reviewed-by: Voon Weifeng 
Signed-off-by: Wong Vee Khee 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 2ac9dfb3462c..9e6d60e75f85 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -653,7 +653,6 @@ static void intel_eth_pci_remove(struct pci_dev *pdev)
 
pci_free_irq_vectors(pdev);
 
-   clk_disable_unprepare(priv->plat->stmmac_clk);
clk_unregister_fixed_rate(priv->plat->stmmac_clk);
 
pcim_iounmap_regions(pdev, BIT(0));
-- 
2.17.0



[PATCH net-next 1/1] net: stmmac: Add option for VLAN filter fail queue enable

2020-09-25 Thread Wong Vee Khee
From: "Chuah, Kim Tatt" 

Add option in plat_stmmacenet_data struct to enable VLAN Filter Fail
Queuing. This option allows packets that fail VLAN filter to be routed
to a specific Rx queue when Receive All is also set.

When this option is enabled:
- Enable VFFQ only when entering promiscuous mode, because Receive All
  will pass up all rx packets that failed address filtering (similar to
  promiscuous mode).
- VLAN-promiscuous mode is never entered to allow rx packet to fail VLAN
  filters and get routed to selected VFFQ Rx queue.

Reviewed-by: Voon Weifeng 
Reviewed-by: Ong Boon Leong 
Signed-off-by: Chuah, Kim Tatt 
Signed-off-by: Ong Boon Leong 
---
 drivers/net/ethernet/stmicro/stmmac/common.h  |  2 ++
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c |  5 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4.h  |  1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 15 +--
 drivers/net/ethernet/stmicro/stmmac/dwmac5.h  |  6 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  3 +++
 include/linux/stmmac.h|  2 ++
 7 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index cafa8e3c3573..df7de50497a0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -481,6 +481,8 @@ struct mac_device_info {
unsigned int num_vlan;
u32 vlan_filter[32];
unsigned int promisc;
+   bool vlan_fail_q_en;
+   u8 vlan_fail_q;
 };
 
 struct stmmac_rx_routing {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 2ac9dfb3462c..ab0a81e0fea1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -321,6 +321,11 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
/* Set the maxmtu to a default of JUMBO_LEN */
plat->maxmtu = JUMBO_LEN;
 
+   plat->vlan_fail_q_en = true;
+
+   /* Use the last Rx queue */
+   plat->vlan_fail_q = plat->rx_queues_to_use - 1;
+
return 0;
 }
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
index 61f3249bd724..592b043f9676 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
@@ -76,6 +76,7 @@
 #define GMAC_PACKET_FILTER_HPF BIT(10)
 #define GMAC_PACKET_FILTER_VTFEBIT(16)
 #define GMAC_PACKET_FILTER_IPFEBIT(20)
+#define GMAC_PACKET_FILTER_RA  BIT(31)
 
 #define GMAC_MAX_PERFECT_ADDRESSES 128
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index ecd834e0e121..002791b77356 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -618,7 +618,18 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
value &= ~GMAC_PACKET_FILTER_PM;
value &= ~GMAC_PACKET_FILTER_PR;
if (dev->flags & IFF_PROMISC) {
-   value = GMAC_PACKET_FILTER_PR | GMAC_PACKET_FILTER_PCF;
+   /* VLAN Tag Filter Fail Packets Queuing */
+   if (hw->vlan_fail_q_en) {
+   value = readl(ioaddr + GMAC_RXQ_CTRL4);
+   value &= ~GMAC_RXQCTRL_VFFQ_MASK;
+   value |= GMAC_RXQCTRL_VFFQE |
+(hw->vlan_fail_q << GMAC_RXQCTRL_VFFQ_SHIFT);
+   writel(value, ioaddr + GMAC_RXQ_CTRL4);
+   value = GMAC_PACKET_FILTER_PR | GMAC_PACKET_FILTER_RA;
+   } else {
+   value = GMAC_PACKET_FILTER_PR | GMAC_PACKET_FILTER_PCF;
+   }
+
} else if ((dev->flags & IFF_ALLMULTI) ||
   (netdev_mc_count(dev) > hw->multicast_filter_bins)) {
/* Pass all multi */
@@ -680,7 +691,7 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
 
writel(value, ioaddr + GMAC_PACKET_FILTER);
 
-   if (dev->flags & IFF_PROMISC) {
+   if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) {
if (!hw->promisc) {
hw->promisc = 1;
dwmac4_vlan_promisc_enable(dev, hw);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h 
b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
index 3e8faa96b4d4..56b0762c1276 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
@@ -92,6 +92,12 @@
 #define TCEIE  BIT(0)
 #define DMA_ECC_INT_STATUS 0x1088
 
+/* EQoS version 5.xx VLAN Tag Filter Fail Packets Queuing */
+#define GMAC_RXQ_CTRL4 0x0094
+#define GMAC_RXQCTRL_VFFQ_MASK GENMASK(19, 17)
+#define 

[PATCH net-next 0/1] net: stmmac: Enable VLAN filter fail queue for Intel platform data

2020-09-25 Thread Wong Vee Khee
This is a follow-up on a earlier patch submission at:-
https://patchwork.ozlabs.org/patch/1275604/

Changes since the previous patch submission:
- Enable VLAN fail queue for Intel platform data (dwmac-intel).
- Steer the VLAN failed packet to the last Rx queue.


Chuah, Kim Tatt (1):
  net: stmmac: Add option for VLAN filter fail queue enable

 drivers/net/ethernet/stmicro/stmmac/common.h  |  2 ++
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c |  5 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4.h  |  1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 15 +--
 drivers/net/ethernet/stmicro/stmmac/dwmac5.h  |  6 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  3 +++
 include/linux/stmmac.h|  2 ++
 7 files changed, 32 insertions(+), 2 deletions(-)

-- 
2.17.0



[PATCH net-next] net: stmmac: introduce rtnl_lock|unlock() on configuring real_num_rx|tx_queues

2020-09-16 Thread Wong Vee Khee
From: "Tan, Tee Min" 

For driver open(), rtnl_lock is acquired by network stack but not in the
resume(). Therefore, we introduce lock_acquired boolean to control when
to use rtnl_lock|unlock() within stmmac_hw_setup().

Fixes: 686cff3d7022 ("net: stmmac: Fix incorrect location to set 
real_num_rx|tx_queues")

Signed-off-by: Tan, Tee Min 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index df2c74bbfcff..22e6a3defa78 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2607,7 +2607,8 @@ static void stmmac_safety_feat_configuration(struct 
stmmac_priv *priv)
  *  0 on success and an appropriate (-)ve integer as defined in errno.h
  *  file on failure.
  */
-static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
+static int stmmac_hw_setup(struct net_device *dev, bool init_ptp,
+  bool lock_acquired)
 {
struct stmmac_priv *priv = netdev_priv(dev);
u32 rx_cnt = priv->plat->rx_queues_to_use;
@@ -2715,9 +2716,15 @@ static int stmmac_hw_setup(struct net_device *dev, bool 
init_ptp)
}
 
/* Configure real RX and TX queues */
+   if (!lock_acquired)
+   rtnl_lock();
+
netif_set_real_num_rx_queues(dev, priv->plat->rx_queues_to_use);
netif_set_real_num_tx_queues(dev, priv->plat->tx_queues_to_use);
 
+   if (!lock_acquired)
+   rtnl_unlock();
+
/* Start the ball rolling... */
stmmac_start_all_dma(priv);
 
@@ -2804,7 +2811,7 @@ static int stmmac_open(struct net_device *dev)
goto init_error;
}
 
-   ret = stmmac_hw_setup(dev, true);
+   ret = stmmac_hw_setup(dev, true, true);
if (ret < 0) {
netdev_err(priv->dev, "%s: Hw setup failed\n", __func__);
goto init_error;
@@ -5238,7 +5245,7 @@ int stmmac_resume(struct device *dev)
 
stmmac_clear_descriptors(priv);
 
-   stmmac_hw_setup(ndev, false);
+   stmmac_hw_setup(ndev, false, false);
stmmac_init_coalesce(priv);
stmmac_set_rx_mode(ndev);
 
-- 
2.17.0



[PATCH net-next] net: stmmac: Add support to Ethtool get/set ring parameters

2020-09-16 Thread Wong Vee Khee
From: "Song, Yoong Siang" 

This patch add support to --show-ring & --set-ring Ethtool functions:
- Adding min, max, power of two check to new ring parameter's value.
- Bring down the network interface before changing the value of ring
  parameters.
- Bring up the network interface after changing the value of ring
  parameters.

Signed-off-by: Song, Yoong Siang 
Signed-off-by: Voon Weifeng 
Signed-off-by: Ong Boon Leong 
---
 .../net/ethernet/stmicro/stmmac/chain_mode.c  |   7 +-
 drivers/net/ethernet/stmicro/stmmac/common.h  |  13 +-
 .../net/ethernet/stmicro/stmmac/ring_mode.c   |   2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   3 +
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  |  29 
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 135 +++---
 .../stmicro/stmmac/stmmac_selftests.c |   2 +-
 7 files changed, 132 insertions(+), 59 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c 
b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
index 52971f5293aa..d2cdc02d9f94 100644
--- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
@@ -46,7 +46,7 @@ static int jumbo_frm(void *p, struct sk_buff *skb, int csum)
 
while (len != 0) {
tx_q->tx_skbuff[entry] = NULL;
-   entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
+   entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size);
desc = tx_q->dma_tx + entry;
 
if (len > bmax) {
@@ -137,7 +137,7 @@ static void refill_desc3(void *priv_ptr, struct dma_desc *p)
 */
p->des3 = cpu_to_le32((unsigned int)(rx_q->dma_rx_phy +
  (((rx_q->dirty_rx) + 1) %
-  DMA_RX_SIZE) *
+  priv->dma_rx_size) *
  sizeof(struct dma_desc)));
 }
 
@@ -154,7 +154,8 @@ static void clean_desc3(void *priv_ptr, struct dma_desc *p)
 * to keep explicit chaining in the descriptor.
 */
p->des3 = cpu_to_le32((unsigned int)((tx_q->dma_tx_phy +
- ((tx_q->dirty_tx + 1) % DMA_TX_SIZE))
+ ((tx_q->dirty_tx + 1) %
+  priv->dma_tx_size))
  * sizeof(struct dma_desc)));
 }
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index acc5e3fc1c2f..cafa8e3c3573 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -42,9 +42,16 @@
 
 #define STMMAC_CHAN0   0   /* Always supported and default for all chips */
 
-/* These need to be power of two, and >= 4 */
-#define DMA_TX_SIZE 512
-#define DMA_RX_SIZE 512
+/* TX and RX Descriptor Length, these need to be power of two.
+ * TX descriptor length less than 64 may cause transmit queue timed out error.
+ * RX descriptor length less than 64 may cause inconsistent Rx chain error.
+ */
+#define DMA_MIN_TX_SIZE64
+#define DMA_MAX_TX_SIZE1024
+#define DMA_DEFAULT_TX_SIZE512
+#define DMA_MIN_RX_SIZE64
+#define DMA_MAX_RX_SIZE1024
+#define DMA_DEFAULT_RX_SIZE512
 #define STMMAC_GET_ENTRY(x, size)  ((x + 1) & (size - 1))
 
 #undef FRAME_FILTER_DEBUG
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c 
b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
index 14bd5e7b9875..8ad900949dc8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
@@ -51,7 +51,7 @@ static int jumbo_frm(void *p, struct sk_buff *skb, int csum)
stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum,
STMMAC_RING_MODE, 0, false, skb->len);
tx_q->tx_skbuff[entry] = NULL;
-   entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
+   entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size);
 
if (priv->extend_desc)
desc = (struct dma_desc *)(tx_q->dma_etx + entry);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 509ce067538e..014a816c9d0b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -171,9 +171,11 @@ struct stmmac_priv {
 
/* RX Queue */
struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES];
+   unsigned int dma_rx_size;
 
/* TX Queue */
struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES];
+   unsigned int dma_tx_size;
 
/* Generic channel for NAPI */
struct stmmac_channel channel[STMMAC_CH_MAX];
@@ -265,6 +267,7 @@ int stmmac_dvr_probe(struct device *device,
 void stmmac_disable_eee_mode(struct stmmac_priv *priv);
 bool 

RE: [PATCH net-next 0/3] net: stmmac: Add ethtool support for get|set channels

2020-09-15 Thread Wong, Vee Khee
My bad...

Hi David Miller,

Can you help with the commit message fix or do you want to to send a new patch 
with the fix since the patches are applied on net-next?

Regards,
Vee Khee

> -Original Message-
> From: Florian Fainelli 
> Sent: Wednesday, September 16, 2020 6:54 AM
> To: David Miller ; Wong, Vee Khee
> 
> Cc: peppe.cavall...@st.com; alexandre.tor...@st.com;
> joab...@synopsys.com; mcoquelin.st...@gmail.com; k...@kernel.org;
> joao.pi...@synopsys.com; a...@arndb.de; li...@armlinux.org.uk;
> net...@vger.kernel.org; linux-st...@st-md-mailman.stormreply.com;
> linux-arm-ker...@lists.infradead.org; linux-kernel@vger.kernel.org; Ong,
> Boon Leong ; Voon, Weifeng
> ; Vijaya Balan, Sadhishkhanna
> ; Seow, Chen Yong
> 
> Subject: Re: [PATCH net-next 0/3] net: stmmac: Add ethtool support for
> get|set channels
> 
> 
> 
> On 9/15/2020 3:43 PM, David Miller wrote:
> > From: Wong Vee Khee 
> > Date: Tue, 15 Sep 2020 09:28:37 +0800
> >
> >> This patch set is to add support for user to get or set Tx/Rx channel
> >> via ethtool. There are two patches that fixes bug introduced on
> >> upstream in order to have the feature work.
> >>
> >> Tested on Intel Tigerlake Platform.
> >
> > Series applied, thank you.
> 
> patch #2 does not have a proper Fixes: tag format, it should be:
> 
> Fixes: cafebabed00d ("some super subject")
> --
> Florian


[PATCH net-next 0/3] net: stmmac: Add ethtool support for get|set channels

2020-09-14 Thread Wong Vee Khee
This patch set is to add support for user to get or set Tx/Rx channel
via ethtool. There are two patches that fixes bug introduced on upstream
in order to have the feature work.

Tested on Intel Tigerlake Platform.

Aashish Verma (1):
  net: stmmac: Fix incorrect location to set real_num_rx|tx_queues

Ong Boon Leong (2):
  net: stmmac: add ethtool support for get/set channels
  net: stmmac: use netif_tx_start|stop_all_queues() function

 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   1 +
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  |  26 
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 135 +-
 3 files changed, 98 insertions(+), 64 deletions(-)

-- 
2.17.0



[PATCH net-next 2/3] net: stmmac: Fix incorrect location to set real_num_rx|tx_queues

2020-09-14 Thread Wong Vee Khee
From: Aashish Verma 

netif_set_real_num_tx_queues() & netif_set_real_num_rx_queues() should be
used to inform network stack about the real Tx & Rx queue (active) number
in both stmmac_open() and stmmac_resume(), therefore, we move the code
from stmmac_dvr_probe() to stmmac_hw_setup().

Fixes: c02b7a914551 net: stmmac: use netif_set_real_num_{rx,tx}_queues

Signed-off-by: Aashish Verma 
Signed-off-by: Ong Boon Leong 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9302d8012a10..fea3b77892ab 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2733,6 +2733,10 @@ static int stmmac_hw_setup(struct net_device *dev, bool 
init_ptp)
stmmac_enable_tbs(priv, priv->ioaddr, enable, chan);
}
 
+   /* Configure real RX and TX queues */
+   netif_set_real_num_rx_queues(dev, priv->plat->rx_queues_to_use);
+   netif_set_real_num_tx_queues(dev, priv->plat->tx_queues_to_use);
+
/* Start the ball rolling... */
stmmac_start_all_dma(priv);
 
@@ -4883,10 +4887,6 @@ int stmmac_dvr_probe(struct device *device,
 
stmmac_check_ether_addr(priv);
 
-   /* Configure real RX and TX queues */
-   netif_set_real_num_rx_queues(ndev, priv->plat->rx_queues_to_use);
-   netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use);
-
ndev->netdev_ops = _netdev_ops;
 
ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-- 
2.17.0



[PATCH net-next 2/3] net: stmmac: Fix incorrect location to set real_num_rx|tx_queues

2020-09-10 Thread Wong Vee Khee
From: Aashish Verma 

netif_set_real_num_tx_queues() & netif_set_real_num_rx_queues() should be
used to inform network stack about the real Tx & Rx queue (active) number
in both stmmac_open() and stmmac_resume(), therefore, we move the code
from stmmac_dvr_probe() to stmmac_hw_setup().

Fixes: c02b7a914551 net: stmmac: use netif_set_real_num_{rx,tx}_queues

Signed-off-by: Aashish Verma 
Signed-off-by: Ong Boon Leong 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9302d8012a10..fea3b77892ab 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2733,6 +2733,10 @@ static int stmmac_hw_setup(struct net_device *dev, bool 
init_ptp)
stmmac_enable_tbs(priv, priv->ioaddr, enable, chan);
}
 
+   /* Configure real RX and TX queues */
+   netif_set_real_num_rx_queues(dev, priv->plat->rx_queues_to_use);
+   netif_set_real_num_tx_queues(dev, priv->plat->tx_queues_to_use);
+
/* Start the ball rolling... */
stmmac_start_all_dma(priv);
 
@@ -4883,10 +4887,6 @@ int stmmac_dvr_probe(struct device *device,
 
stmmac_check_ether_addr(priv);
 
-   /* Configure real RX and TX queues */
-   netif_set_real_num_rx_queues(ndev, priv->plat->rx_queues_to_use);
-   netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use);
-
ndev->netdev_ops = _netdev_ops;
 
ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-- 
2.17.0



[PATCH net-next 3/3] net: stmmac: use netif_tx_start|stop_all_queues() function

2020-09-10 Thread Wong Vee Khee
From: Ong Boon Leong 

The current implementation of stmmac_stop_all_queues() and
stmmac_start_all_queues() will not work correctly when the value of
tx_queues_to_use is changed through ethtool -L DEVNAME rx N tx M command.

Also, netif_tx_start|stop_all_queues() are only needed in driver open()
and close() only.

Fixes: c22a3f48 net: stmmac: adding multiple napi mechanism

Signed-off-by: Ong Boon Leong 
Signed-off-by: Voon Weifeng 
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 33 +--
 1 file changed, 1 insertion(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index fea3b77892ab..90c1c37b64e0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -176,32 +176,6 @@ static void stmmac_enable_all_queues(struct stmmac_priv 
*priv)
}
 }
 
-/**
- * stmmac_stop_all_queues - Stop all queues
- * @priv: driver private structure
- */
-static void stmmac_stop_all_queues(struct stmmac_priv *priv)
-{
-   u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
-   u32 queue;
-
-   for (queue = 0; queue < tx_queues_cnt; queue++)
-   netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue));
-}
-
-/**
- * stmmac_start_all_queues - Start all queues
- * @priv: driver private structure
- */
-static void stmmac_start_all_queues(struct stmmac_priv *priv)
-{
-   u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
-   u32 queue;
-
-   for (queue = 0; queue < tx_queues_cnt; queue++)
-   netif_tx_start_queue(netdev_get_tx_queue(priv->dev, queue));
-}
-
 static void stmmac_service_event_schedule(struct stmmac_priv *priv)
 {
if (!test_bit(STMMAC_DOWN, >state) &&
@@ -2865,7 +2839,7 @@ static int stmmac_open(struct net_device *dev)
}
 
stmmac_enable_all_queues(priv);
-   stmmac_start_all_queues(priv);
+   netif_tx_start_all_queues(priv->dev);
 
return 0;
 
@@ -2908,8 +2882,6 @@ static int stmmac_release(struct net_device *dev)
phylink_stop(priv->phylink);
phylink_disconnect_phy(priv->phylink);
 
-   stmmac_stop_all_queues(priv);
-
stmmac_disable_all_queues(priv);
 
for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
@@ -5117,7 +5089,6 @@ int stmmac_suspend(struct device *dev)
mutex_lock(>lock);
 
netif_device_detach(ndev);
-   stmmac_stop_all_queues(priv);
 
stmmac_disable_all_queues(priv);
 
@@ -5244,8 +5215,6 @@ int stmmac_resume(struct device *dev)
 
stmmac_enable_all_queues(priv);
 
-   stmmac_start_all_queues(priv);
-
mutex_unlock(>lock);
 
if (!device_may_wakeup(priv->device) || !priv->plat->pmt) {
-- 
2.17.0



RE: [PATCH net-next 1/1] net: stmmac: Add option for VLAN filter fail queue enable

2020-05-05 Thread Wong, Vee Khee


> -Original Message-
> From: netdev-ow...@vger.kernel.org  On
> Behalf Of David Miller
> Sent: Friday, April 24, 2020 6:53 AM
> To: Wong, Vee Khee 
> Cc: peppe.cavall...@st.com; alexandre.tor...@st.com;
> joab...@synopsys.com; mcoquelin.st...@gmail.com;
> net...@vger.kernel.org; linux-st...@st-md-mailman.stormreply.com;
> linux-arm-ker...@lists.infradead.org; linux-kernel@vger.kernel.org; Ong,
> Boon Leong ; Voon, Weifeng
> 
> Subject: Re: [PATCH net-next 1/1] net: stmmac: Add option for VLAN filter fail
> queue enable
> 
> From: Wong Vee Khee 
> Date: Thu, 23 Apr 2020 15:00:26 +0800
> 
> > From: "Chuah, Kim Tatt" 
> >
> > Add option in plat_stmmacenet_data struct to enable VLAN Filter Fail
> > Queuing. This option allows packets that fail VLAN filter to be routed
> > to a specific Rx queue when Receive All is also set.
> >
> > When this option is enabled:
> > - Enable VFFQ only when entering promiscuous mode, because Receive All
> >   will pass up all rx packets that failed address filtering (similar to
> >   promiscuous mode).
> > - VLAN-promiscuous mode is never entered to allow rx packet to fail VLAN
> >   filters and get routed to selected VFFQ Rx queue.
> >
> > Reviewed-by: Voon Weifeng 
> > Reviewed-by: Ong Boon Leong 
> > Signed-off-by: Chuah, Kim Tatt 
> > Signed-off-by: Ong Boon Leong 
> 
> Why would you be setting this with a platform attribute?  Even if the
> capability exists, wouldn't you want the user to be able to choose to opt out?

Hi Jose/David Miller,

1/ In current implementation, TSN uses VLAN filter that can either 
accept/reject VLAN-tagged network packets. In some situation, we do not want to 
drop failed packets, but instead steer the packet to a VLAN Failed Queue 
Channel.

2/ VLAN Fail Queue Channel will be set to use the RxQ with higheset index as 
per HW IP configuration because that is the least priority channel.

3/ The way user will enable this feature is through promiscuous mode settings 
using ifconfig. (e.g. ifconfig enp0s30f4 promisc)

4/ VLAN Filter Fail Packets Queue feature is IP version specific (only 
applicable to DWMAC5). I would propose we add this under platform data (e.g. 
dwmac-intel), so that it can be built in according to hardware on a separate 
patch.

Any thoughts?



[RESEND PATCH v3] pci-sysfs: Make PCI bridge attribute visible in sysfs

2017-06-01 Thread Wong Vee Khee
From: vwong <vee.khee.w...@ni.com>

 In this commit, we are exposing PCIe bridges attributes
 such as secondary bus number, subordinate bus number,
 max link speed and link width, current link speed and
 link width to sysfs located in /sys/bus/pci/devices/...

 Part of the reasons we are doing this rather than getting
 these information through parsing lspci is due to the fact
 that accessing PCIe link information via lspci require root
 privilege.

 This changes also allow clients to get PCIe bridges information
 easily because lspci list out all PCIe devices.

Signed-off-by: Wong Vee Khee <vee.khee.w...@ni.com>
Signed-off-by: Hui Chun Ong <hui.chun@ni.com>
---
v3: Update commit message to be more explicit
v2: Remove error checking on LNKCAP
Add define of PCI_LNKCAP_SLS_8_0GB
---
 drivers/pci/pci-sysfs.c   | 197 +-
 include/uapi/linux/pci_regs.h |   1 +
 2 files changed, 194 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 31e9961..a2ada91 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -154,6 +154,127 @@ static ssize_t resource_show(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR_RO(resource);
 
+static ssize_t max_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   if (!err) {
+   switch (linkcap & PCI_EXP_LNKCAP_SLS) {
+   case PCI_EXP_LNKCAP_SLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(max_link_speed);
+
+static ssize_t max_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4);
+}
+static DEVICE_ATTR_RO(max_link_width);
+
+static ssize_t current_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   if (!err) {
+   switch (linkstat & PCI_EXP_LNKSTA_CLS) {
+   case PCI_EXP_LNKSTA_CLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(current_link_speed);
+
+static ssize_t current_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n",
+   (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
+}
+static DEVICE_ATTR_RO(current_link_width);
+
+static ssize_t secondary_bus_number_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sec_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sec_bus);
+}
+static DEVICE_ATTR_RO(secondary_bus_number);
+
+static ssize_t subordinate_bus_number_show(struct device *dev,
+  struct device_attribute *attr,
+

[RESEND PATCH v3] pci-sysfs: Make PCI bridge attribute visible in sysfs

2017-06-01 Thread Wong Vee Khee
From: vwong 

 In this commit, we are exposing PCIe bridges attributes
 such as secondary bus number, subordinate bus number,
 max link speed and link width, current link speed and
 link width to sysfs located in /sys/bus/pci/devices/...

 Part of the reasons we are doing this rather than getting
 these information through parsing lspci is due to the fact
 that accessing PCIe link information via lspci require root
 privilege.

 This changes also allow clients to get PCIe bridges information
 easily because lspci list out all PCIe devices.

Signed-off-by: Wong Vee Khee 
Signed-off-by: Hui Chun Ong 
---
v3: Update commit message to be more explicit
v2: Remove error checking on LNKCAP
Add define of PCI_LNKCAP_SLS_8_0GB
---
 drivers/pci/pci-sysfs.c   | 197 +-
 include/uapi/linux/pci_regs.h |   1 +
 2 files changed, 194 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 31e9961..a2ada91 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -154,6 +154,127 @@ static ssize_t resource_show(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR_RO(resource);
 
+static ssize_t max_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   if (!err) {
+   switch (linkcap & PCI_EXP_LNKCAP_SLS) {
+   case PCI_EXP_LNKCAP_SLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(max_link_speed);
+
+static ssize_t max_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4);
+}
+static DEVICE_ATTR_RO(max_link_width);
+
+static ssize_t current_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   if (!err) {
+   switch (linkstat & PCI_EXP_LNKSTA_CLS) {
+   case PCI_EXP_LNKSTA_CLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(current_link_speed);
+
+static ssize_t current_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n",
+   (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
+}
+static DEVICE_ATTR_RO(current_link_width);
+
+static ssize_t secondary_bus_number_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sec_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sec_bus);
+}
+static DEVICE_ATTR_RO(secondary_bus_number);
+
+static ssize_t subordinate_bus_number_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf)
+{
+   struct pci_dev *pci_dev = 

[PATCH v3] pci-sysfs: Make PCI bridge attribute visible in sysfs

2017-05-19 Thread Wong Vee Khee
From: vwong <vee.khee.w...@ni.com>

 In this commit, we are exposing PCIe bridges attributes
 such as secondary bus number, subordinate bus number,
 max link speed and link width, current link speed and
 link width to sysfs located in /sys/bus/pci/devices/...

 Part of the reasons we are doing this rather than getting
 these information through parsing lspci is due to the fact
 that accessing PCIe link information via lspci require root
 privilege.

 This changes also allow clients to get PCIe bridges information
 easily because lspci list out all PCIe devices.

Signed-off-by: Wong Vee Khee <vee.khee.w...@ni.com>
Signed-off-by: Hui Chun Ong <hui.chun@ni.com>
---
 drivers/pci/pci-sysfs.c   | 197 +-
 include/uapi/linux/pci_regs.h |   1 +
 2 files changed, 194 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 31e9961..a2ada91 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -154,6 +154,127 @@ static ssize_t resource_show(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR_RO(resource);
 
+static ssize_t max_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   if (!err) {
+   switch (linkcap & PCI_EXP_LNKCAP_SLS) {
+   case PCI_EXP_LNKCAP_SLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(max_link_speed);
+
+static ssize_t max_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4);
+}
+static DEVICE_ATTR_RO(max_link_width);
+
+static ssize_t current_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   if (!err) {
+   switch (linkstat & PCI_EXP_LNKSTA_CLS) {
+   case PCI_EXP_LNKSTA_CLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(current_link_speed);
+
+static ssize_t current_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n",
+   (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
+}
+static DEVICE_ATTR_RO(current_link_width);
+
+static ssize_t secondary_bus_number_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sec_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sec_bus);
+}
+static DEVICE_ATTR_RO(secondary_bus_number);
+
+static ssize_t subordinate_bus_number_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sub_bus;
+   

[PATCH v3] pci-sysfs: Make PCI bridge attribute visible in sysfs

2017-05-19 Thread Wong Vee Khee
From: vwong 

 In this commit, we are exposing PCIe bridges attributes
 such as secondary bus number, subordinate bus number,
 max link speed and link width, current link speed and
 link width to sysfs located in /sys/bus/pci/devices/...

 Part of the reasons we are doing this rather than getting
 these information through parsing lspci is due to the fact
 that accessing PCIe link information via lspci require root
 privilege.

 This changes also allow clients to get PCIe bridges information
 easily because lspci list out all PCIe devices.

Signed-off-by: Wong Vee Khee 
Signed-off-by: Hui Chun Ong 
---
 drivers/pci/pci-sysfs.c   | 197 +-
 include/uapi/linux/pci_regs.h |   1 +
 2 files changed, 194 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 31e9961..a2ada91 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -154,6 +154,127 @@ static ssize_t resource_show(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR_RO(resource);
 
+static ssize_t max_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   if (!err) {
+   switch (linkcap & PCI_EXP_LNKCAP_SLS) {
+   case PCI_EXP_LNKCAP_SLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(max_link_speed);
+
+static ssize_t max_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4);
+}
+static DEVICE_ATTR_RO(max_link_width);
+
+static ssize_t current_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   if (!err) {
+   switch (linkstat & PCI_EXP_LNKSTA_CLS) {
+   case PCI_EXP_LNKSTA_CLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(current_link_speed);
+
+static ssize_t current_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n",
+   (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
+}
+static DEVICE_ATTR_RO(current_link_width);
+
+static ssize_t secondary_bus_number_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sec_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sec_bus);
+}
+static DEVICE_ATTR_RO(secondary_bus_number);
+
+static ssize_t subordinate_bus_number_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sub_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SUBORDINATE_BUS, _b

[PATCH v2] pci-sysfs: Make PCI bridge attribute visible in sysfs

2017-05-11 Thread Wong Vee Khee
From: vwong <vee.khee.w...@ni.com>

Export the PCIe link attributes of PCI bridges to sysfs.

Signed-off-by: Wong Vee Khee <vee.khee.w...@ni.com>
Signed-off-by: Hui Chun Ong <hui.chun@ni.com>
---
 drivers/pci/pci-sysfs.c   | 197 +-
 include/uapi/linux/pci_regs.h |   1 +
 2 files changed, 194 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 31e9961..a2ada91 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -154,6 +154,127 @@ static ssize_t resource_show(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR_RO(resource);
 
+static ssize_t max_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   if (!err) {
+   switch (linkcap & PCI_EXP_LNKCAP_SLS) {
+   case PCI_EXP_LNKCAP_SLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(max_link_speed);
+
+static ssize_t max_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4);
+}
+static DEVICE_ATTR_RO(max_link_width);
+
+static ssize_t current_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   if (!err) {
+   switch (linkstat & PCI_EXP_LNKSTA_CLS) {
+   case PCI_EXP_LNKSTA_CLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(current_link_speed);
+
+static ssize_t current_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n",
+   (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
+}
+static DEVICE_ATTR_RO(current_link_width);
+
+static ssize_t secondary_bus_number_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sec_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sec_bus);
+}
+static DEVICE_ATTR_RO(secondary_bus_number);
+
+static ssize_t subordinate_bus_number_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sub_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SUBORDINATE_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sub_bus);
+}
+static DEVICE_ATTR_RO(subordinate_bus_number);
+
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 char *buf)
 {
@@ -629,12 +750,17 @@ static struct attribute *pci_dev_attrs[] = {
NULL,
 };
 
-static const struct attribute_group pci_dev_g

[PATCH v2] pci-sysfs: Make PCI bridge attribute visible in sysfs

2017-05-11 Thread Wong Vee Khee
From: vwong 

Export the PCIe link attributes of PCI bridges to sysfs.

Signed-off-by: Wong Vee Khee 
Signed-off-by: Hui Chun Ong 
---
 drivers/pci/pci-sysfs.c   | 197 +-
 include/uapi/linux/pci_regs.h |   1 +
 2 files changed, 194 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 31e9961..a2ada91 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -154,6 +154,127 @@ static ssize_t resource_show(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR_RO(resource);
 
+static ssize_t max_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   if (!err) {
+   switch (linkcap & PCI_EXP_LNKCAP_SLS) {
+   case PCI_EXP_LNKCAP_SLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_SLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(max_link_speed);
+
+static ssize_t max_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4);
+}
+static DEVICE_ATTR_RO(max_link_width);
+
+static ssize_t current_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   if (!err) {
+   switch (linkstat & PCI_EXP_LNKSTA_CLS) {
+   case PCI_EXP_LNKSTA_CLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(current_link_speed);
+
+static ssize_t current_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n",
+   (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
+}
+static DEVICE_ATTR_RO(current_link_width);
+
+static ssize_t secondary_bus_number_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sec_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sec_bus);
+}
+static DEVICE_ATTR_RO(secondary_bus_number);
+
+static ssize_t subordinate_bus_number_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sub_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SUBORDINATE_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sub_bus);
+}
+static DEVICE_ATTR_RO(subordinate_bus_number);
+
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 char *buf)
 {
@@ -629,12 +750,17 @@ static struct attribute *pci_dev_attrs[] = {
NULL,
 };
 
-static const struct attribute_group pci_dev_group = {
-   .attrs = pci_dev_attrs,
+static struct attribute *pci_

[PATCH] pci-sysfs: Make PCI bridge attribute visible in sysfs

2017-04-16 Thread Wong Vee Khee
From: vwong <vee.khee.w...@ni.com>

Export the PCIe link attributes of PCI bridges to sysfs.

Signed-off-by: Wong Vee Khee <vee.khee.w...@ni.com>
Signed-off-by: Hui Chun Ong <hui.chun@ni.com>
---
 drivers/pci/pci-sysfs.c   | 197 +-
 include/uapi/linux/pci_regs.h |   4 +
 2 files changed, 197 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 25d010d..a218c43 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -154,6 +154,127 @@ static ssize_t resource_show(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR_RO(resource);
 
+static ssize_t max_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   if (!err && linkcap) {
+   switch (linkcap & PCI_EXP_LNKCAP_MLS) {
+   case PCI_EXP_LNKCAP_MLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_MLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_MLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(max_link_speed);
+
+static ssize_t max_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4);
+}
+static DEVICE_ATTR_RO(max_link_width);
+
+static ssize_t current_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   if (!err && linkstat) {
+   switch (linkstat & PCI_EXP_LNKSTA_CLS) {
+   case PCI_EXP_LNKSTA_CLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(current_link_speed);
+
+static ssize_t current_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n",
+   (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
+}
+static DEVICE_ATTR_RO(current_link_width);
+
+static ssize_t secondary_bus_number_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sec_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sec_bus);
+}
+static DEVICE_ATTR_RO(secondary_bus_number);
+
+static ssize_t subordinate_bus_number_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sub_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SUBORDINATE_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sub_bus);
+}
+static DEVICE_ATTR_RO(subordinate_bus_number);
+
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 char *buf)
 {
@@ -602,12 +723,17 @@ static struct attribute *pci_dev_attrs[]

[PATCH] pci-sysfs: Make PCI bridge attribute visible in sysfs

2017-04-16 Thread Wong Vee Khee
From: vwong 

Export the PCIe link attributes of PCI bridges to sysfs.

Signed-off-by: Wong Vee Khee 
Signed-off-by: Hui Chun Ong 
---
 drivers/pci/pci-sysfs.c   | 197 +-
 include/uapi/linux/pci_regs.h |   4 +
 2 files changed, 197 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 25d010d..a218c43 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -154,6 +154,127 @@ static ssize_t resource_show(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR_RO(resource);
 
+static ssize_t max_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   if (!err && linkcap) {
+   switch (linkcap & PCI_EXP_LNKCAP_MLS) {
+   case PCI_EXP_LNKCAP_MLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_MLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKCAP_MLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(max_link_speed);
+
+static ssize_t max_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u32 linkcap;
+   int err;
+
+   err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4);
+}
+static DEVICE_ATTR_RO(max_link_width);
+
+static ssize_t current_link_speed_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+   const char *speed;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   if (!err && linkstat) {
+   switch (linkstat & PCI_EXP_LNKSTA_CLS) {
+   case PCI_EXP_LNKSTA_CLS_8_0GB:
+   speed = "8 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_5_0GB:
+   speed = "5 GT/s";
+   break;
+   case PCI_EXP_LNKSTA_CLS_2_5GB:
+   speed = "2.5 GT/s";
+   break;
+   default:
+   speed = "Unknown speed";
+   }
+
+   return sprintf(buf, "%s\n", speed);
+   }
+
+   return -EINVAL;
+}
+static DEVICE_ATTR_RO(current_link_speed);
+
+static ssize_t current_link_width_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u16 linkstat;
+   int err;
+
+   err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, );
+
+   return err ? -EINVAL : sprintf(
+   buf, "%u\n",
+   (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
+}
+static DEVICE_ATTR_RO(current_link_width);
+
+static ssize_t secondary_bus_number_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sec_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sec_bus);
+}
+static DEVICE_ATTR_RO(secondary_bus_number);
+
+static ssize_t subordinate_bus_number_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf)
+{
+   struct pci_dev *pci_dev = to_pci_dev(dev);
+   u8 sub_bus;
+   int err;
+
+   err = pci_read_config_byte(pci_dev, PCI_SUBORDINATE_BUS, _bus);
+
+   return err ? -EINVAL : sprintf(buf, "%u\n", sub_bus);
+}
+static DEVICE_ATTR_RO(subordinate_bus_number);
+
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 char *buf)
 {
@@ -602,12 +723,17 @@ static struct attribute *pci_dev_attrs[] = {
NULL,
 };
 
-static const struct attribute_group pci_dev_group = {
-   .attrs = pci_dev_attrs