Re: [bug report] staging: qlge: Initialize devlink health dump framework

2021-02-03 Thread Coiby Xu

On Wed, Feb 03, 2021 at 05:36:01PM +0300, Dan Carpenter wrote:

On Wed, Feb 03, 2021 at 09:45:51PM +0800, Coiby Xu wrote:

Hi Dan,


On Wed, Feb 03, 2021 at 12:42:50PM +0300, Dan Carpenter wrote:
> Hello Coiby Xu,
>
> The patch 953b94009377: "staging: qlge: Initialize devlink health
> dump framework" from Jan 23, 2021, leads to the following static
> checker warning:
>
>drivers/staging/qlge/qlge_devlink.c:163 qlge_health_create_reporters()
>error: uninitialized symbol 'reporter'.
>
> drivers/staging/qlge/qlge_devlink.c
>   151  void qlge_health_create_reporters(struct qlge_adapter *priv)
>   152  {
>   153  struct devlink_health_reporter *reporter;
>   154  struct devlink *devlink;
>   155
>   156  devlink = priv_to_devlink(priv);
>   157  priv->reporter =
>   158  devlink_health_reporter_create(devlink, 
_reporter_ops,
>   159 0, priv);
>   160  if (IS_ERR(priv->reporter))
>   161  netdev_warn(priv->ndev,
>   162  "Failed to create reporter, err = %ld\n",
>   163  PTR_ERR(reporter));
>
> Obviously the static checker is correct because we initialized
> "priv->reporter" instead of "reporter".
>
> It's not clear to me how "reporter" is used.  Presumably this should be:
>
>reporter = devlink_health_reporter_create(devlink, _reporter_ops,
>  0, priv);
>if (IS_ERR(reporter)) {
>netdev_warn(priv->ndev,
>"Failed to create reporter, err = %ld\n",
>PTR_ERR(reporter));
>return;
>}
>priv->reporter = reporter;
>

Thank you for finding this issue! "struct devlink_health_reporter
*reporter" is not needed since priv->reporter is used instead which
I think simplifies the code.

> But I can't actually find where "priv->reporter" is checked against
> NULL.  There should be some NULL checks, right?
>

There is no need to do NULL check since devlink_health_reporter_create
has done the job for us,

// net/core/devlink.c
__devlink_health_reporter_create(struct devlink *devlink,
 const struct devlink_health_reporter_ops *ops,
 u64 graceful_period, void *priv)
{
reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
if (!reporter)
return ERR_PTR(-ENOMEM);

}


No, Sorry I was unclear.  I mean that instead of error handling this
qlge_health_create_reporters() function just prints an error:

netdev_warn(priv->ndev,
"Failed to create reporter, err = %ld\n",
PTR_ERR(priv->reporter));

Then it looks like it gets passed to qlge_reporter_coredump() which
dereferences "reporter" without checking.  That will crash, right?



Now I see what you mean. Thanks for the explanation! I'll send a patch
to address this issue.


regards,
dan carpenter



--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH][next] staging: qlge: fix read of an uninitialized pointer

2021-02-03 Thread Coiby Xu

On Wed, Feb 03, 2021 at 01:38:34PM +, Colin King wrote:

From: Colin Ian King 

Currently the pointer 'reporter' is not being initialized and is
being read in a netdev_warn message.  The pointer is not used
and is redundant, fix this by removing it and replacing the reference
to it with priv->reporter instead.

Addresses-Coverity: ("Uninitialized pointer read")
Fixes: 1053c27804df ("staging: qlge: coredump via devlink health reporter")
Signed-off-by: Colin Ian King 
---
drivers/staging/qlge/qlge_devlink.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
index c6ef5163e241..86834d96cebf 100644
--- a/drivers/staging/qlge/qlge_devlink.c
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -150,7 +150,6 @@ static const struct devlink_health_reporter_ops 
qlge_reporter_ops = {

void qlge_health_create_reporters(struct qlge_adapter *priv)
{
-   struct devlink_health_reporter *reporter;
struct devlink *devlink;

devlink = priv_to_devlink(priv);
@@ -160,5 +159,5 @@ void qlge_health_create_reporters(struct qlge_adapter *priv)
if (IS_ERR(priv->reporter))
netdev_warn(priv->ndev,
"Failed to create reporter, err = %ld\n",
-   PTR_ERR(reporter));
+   PTR_ERR(priv->reporter));
}
--
2.29.2



Thanks for fixing this issue.

Reviewed-by: Coiby Xu 

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [bug report] staging: qlge: Initialize devlink health dump framework

2021-02-03 Thread Coiby Xu

Hi Dan,


On Wed, Feb 03, 2021 at 12:42:50PM +0300, Dan Carpenter wrote:

Hello Coiby Xu,

The patch 953b94009377: "staging: qlge: Initialize devlink health
dump framework" from Jan 23, 2021, leads to the following static
checker warning:

drivers/staging/qlge/qlge_devlink.c:163 qlge_health_create_reporters()
error: uninitialized symbol 'reporter'.

drivers/staging/qlge/qlge_devlink.c
  151  void qlge_health_create_reporters(struct qlge_adapter *priv)
  152  {
  153  struct devlink_health_reporter *reporter;
  154  struct devlink *devlink;
  155
  156  devlink = priv_to_devlink(priv);
  157  priv->reporter =
  158  devlink_health_reporter_create(devlink, 
_reporter_ops,
  159 0, priv);
  160  if (IS_ERR(priv->reporter))
  161  netdev_warn(priv->ndev,
  162  "Failed to create reporter, err = %ld\n",
  163  PTR_ERR(reporter));

Obviously the static checker is correct because we initialized
"priv->reporter" instead of "reporter".

It's not clear to me how "reporter" is used.  Presumably this should be:

reporter = devlink_health_reporter_create(devlink, _reporter_ops,
  0, priv);
if (IS_ERR(reporter)) {
netdev_warn(priv->ndev,
"Failed to create reporter, err = %ld\n",
PTR_ERR(reporter));
return;
}
priv->reporter = reporter;



Thank you for finding this issue! "struct devlink_health_reporter
*reporter" is not needed since priv->reporter is used instead which
I think simplifies the code.


But I can't actually find where "priv->reporter" is checked against
NULL.  There should be some NULL checks, right?



There is no need to do NULL check since devlink_health_reporter_create
has done the job for us,

// net/core/devlink.c
__devlink_health_reporter_create(struct devlink *devlink,
 const struct devlink_health_reporter_ops *ops,
 u64 graceful_period, void *priv)
{
reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
if (!reporter)
return ERR_PTR(-ENOMEM);

}


  164  }

regards,
dan carpenter


--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 6/8] staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer

2021-01-23 Thread Coiby Xu
devlink health could be used to get coredump. No need to send so much
data to the kernel ring buffer.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/TODO   |  2 --
 drivers/staging/qlge/qlge.h |  3 ---
 drivers/staging/qlge/qlge_dbg.c | 11 ---
 drivers/staging/qlge/qlge_ethtool.c |  1 -
 drivers/staging/qlge/qlge_main.c|  2 --
 drivers/staging/qlge/qlge_mpi.c |  6 --
 6 files changed, 25 deletions(-)

diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO
index 5ac55664c3e2..e68c95f47754 100644
--- a/drivers/staging/qlge/TODO
+++ b/drivers/staging/qlge/TODO
@@ -18,8 +18,6 @@
   of questionable value. In particular, qlge_dbg.c has hundreds of lines of
   code bitrotting away in ifdef land (doesn't compile since commit
   18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago).
-* triggering an ethtool regdump will hexdump a 176k struct to dmesg depending
-  on some module parameters.
 * the flow control implementation in firmware is buggy (sends a flood of pause
   frames, resets the link, device and driver buffer queues become
   desynchronized), disable it by default
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 41f69751d34d..aa5721862140 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2153,7 +2153,6 @@ struct qlge_adapter {
u32 port_init;
u32 link_status;
struct qlge_mpi_coredump *mpi_coredump;
-   u32 core_is_dumped;
u32 link_config;
u32 led_config;
u32 max_frame_size;
@@ -2166,7 +2165,6 @@ struct qlge_adapter {
struct delayed_work mpi_work;
struct delayed_work mpi_port_cfg_work;
struct delayed_work mpi_idc_work;
-   struct delayed_work mpi_core_to_log;
struct completion ide_completion;
const struct nic_operations *nic_ops;
u16 device_id;
@@ -2257,7 +2255,6 @@ int qlge_write_cfg(struct qlge_adapter *qdev, void *ptr, 
int size, u32 bit,
 void qlge_queue_fw_error(struct qlge_adapter *qdev);
 void qlge_mpi_work(struct work_struct *work);
 void qlge_mpi_reset_work(struct work_struct *work);
-void qlge_mpi_core_to_log(struct work_struct *work);
 int qlge_wait_reg_rdy(struct qlge_adapter *qdev, u32 reg, u32 bit, u32 ebit);
 void qlge_queue_asic_error(struct qlge_adapter *qdev);
 void qlge_set_ethtool_ops(struct net_device *ndev);
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index b0d4ea071f32..5c64d6de3b30 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1313,17 +1313,6 @@ void qlge_get_dump(struct qlge_adapter *qdev, void *buff)
}
 }
 
-/* Coredump to messages log file using separate worker thread */
-void qlge_mpi_core_to_log(struct work_struct *work)
-{
-   struct qlge_adapter *qdev =
-   container_of(work, struct qlge_adapter, mpi_core_to_log.work);
-
-   print_hex_dump(KERN_DEBUG, "Core is dumping to log file!\n",
-  DUMP_PREFIX_OFFSET, 32, 4, qdev->mpi_coredump,
-  sizeof(*qdev->mpi_coredump), false);
-}
-
 #ifdef QL_REG_DUMP
 static void qlge_dump_intr_states(struct qlge_adapter *qdev)
 {
diff --git a/drivers/staging/qlge/qlge_ethtool.c 
b/drivers/staging/qlge/qlge_ethtool.c
index 24b079523d5c..3e911f147dfc 100644
--- a/drivers/staging/qlge/qlge_ethtool.c
+++ b/drivers/staging/qlge/qlge_ethtool.c
@@ -617,7 +617,6 @@ static void qlge_get_regs(struct net_device *ndev,
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
 
qlge_get_dump(qdev, p);
-   qdev->core_is_dumped = 0;
if (!test_bit(QL_FRC_COREDUMP, >flags))
regs->len = sizeof(struct qlge_mpi_coredump);
else
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 2ec688d3d946..747dbb54dde4 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3800,7 +3800,6 @@ static void qlge_cancel_all_work_sync(struct qlge_adapter 
*qdev)
cancel_delayed_work_sync(>mpi_reset_work);
cancel_delayed_work_sync(>mpi_work);
cancel_delayed_work_sync(>mpi_idc_work);
-   cancel_delayed_work_sync(>mpi_core_to_log);
cancel_delayed_work_sync(>mpi_port_cfg_work);
 }
 
@@ -4493,7 +4492,6 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
INIT_DELAYED_WORK(>mpi_work, qlge_mpi_work);
INIT_DELAYED_WORK(>mpi_port_cfg_work, qlge_mpi_port_cfg_work);
INIT_DELAYED_WORK(>mpi_idc_work, qlge_mpi_idc_work);
-   INIT_DELAYED_WORK(>mpi_core_to_log, qlge_mpi_core_to_log);
init_completion(>ide_completion);
mutex_init(>mpi_mutex);
 
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index 2b77995ec76c..2630ebf50341 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -

[PATCH v4 5/8] staging: qlge: support force_coredump option for devlink health dump

2021-01-23 Thread Coiby Xu
With force_coredump module parameter set, devlink health dump will
reset the MPI RISC first which takes 5 secs to be finished.

Note that only NIC function that owns the firmware can do the
force_dumping. Otherwise devlink will receive an EPERM error.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_devlink.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
index bf7d75ed5eae..c6ef5163e241 100644
--- a/drivers/staging/qlge/qlge_devlink.c
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -56,10 +56,23 @@ static int qlge_reporter_coredump(struct 
devlink_health_reporter *reporter,
 
struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter);
struct qlge_mpi_coredump *dump;
+   wait_queue_head_t wait;
 
if (!netif_running(qdev->ndev))
return 0;
 
+   if (test_bit(QL_FRC_COREDUMP, >flags)) {
+   if (qlge_own_firmware(qdev)) {
+   qlge_queue_fw_error(qdev);
+   init_waitqueue_head();
+   wait_event_timeout(wait, 0, 5 * HZ);
+   } else {
+   netif_err(qdev, ifup, qdev->ndev,
+ "Force Coredump failed because this NIC 
function doesn't own the firmware\n");
+   return -EPERM;
+   }
+   }
+
dump = kvmalloc(sizeof(*dump), GFP_KERNEL);
if (!dump)
return -ENOMEM;
-- 
2.29.2

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 8/8] staging: qlge: add documentation for debugging qlge

2021-01-23 Thread Coiby Xu
Instructions and examples on kernel data structures dumping and
coredump.

Signed-off-by: Coiby Xu 
---
 .../networking/device_drivers/index.rst   |   1 +
 .../device_drivers/qlogic/index.rst   |  18 +++
 .../networking/device_drivers/qlogic/qlge.rst | 118 ++
 MAINTAINERS   |   6 +
 4 files changed, 143 insertions(+)
 create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst
 create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst

diff --git a/Documentation/networking/device_drivers/index.rst 
b/Documentation/networking/device_drivers/index.rst
index a3113ffd7a16..d8279de7bf25 100644
--- a/Documentation/networking/device_drivers/index.rst
+++ b/Documentation/networking/device_drivers/index.rst
@@ -15,6 +15,7 @@ Contents:
ethernet/index
fddi/index
hamradio/index
+   qlogic/index
wan/index
wifi/index
 
diff --git a/Documentation/networking/device_drivers/qlogic/index.rst 
b/Documentation/networking/device_drivers/qlogic/index.rst
new file mode 100644
index ..ad05b04286e4
--- /dev/null
+++ b/Documentation/networking/device_drivers/qlogic/index.rst
@@ -0,0 +1,18 @@
+.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+QLogic QLGE Device Drivers
+===
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   qlge
+
+.. only::  subproject and html
+
+   Indices
+   ===
+
+   * :ref:`genindex`
diff --git a/Documentation/networking/device_drivers/qlogic/qlge.rst 
b/Documentation/networking/device_drivers/qlogic/qlge.rst
new file mode 100644
index ..0b888253d152
--- /dev/null
+++ b/Documentation/networking/device_drivers/qlogic/qlge.rst
@@ -0,0 +1,118 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===
+QLogic QLGE 10Gb Ethernet device driver
+===
+
+This driver use drgn and devlink for debugging.
+
+Dump kernel data structures in drgn
+---
+
+To dump kernel data structures, the following Python script can be used
+in drgn:
+
+.. code-block:: python
+
+   def align(x, a):
+   """the alignment a should be a power of 2
+   """
+   mask = a - 1
+   return (x+ mask) & ~mask
+
+   def struct_size(struct_type):
+   struct_str = "struct {}".format(struct_type)
+   return sizeof(Object(prog, struct_str, address=0x0))
+
+   def netdev_priv(netdevice):
+   NETDEV_ALIGN = 32
+   return netdevice.value_() + align(struct_size("net_device"), 
NETDEV_ALIGN)
+
+   name = 'xxx'
+   qlge_device = None
+   netdevices = prog['init_net'].dev_base_head.address_of_()
+   for netdevice in list_for_each_entry("struct net_device", netdevices, 
"dev_list"):
+   if netdevice.name.string_().decode('ascii') == name:
+   print(netdevice.name)
+
+   ql_adapter = Object(prog, "struct ql_adapter", 
address=netdev_priv(qlge_device))
+
+The struct ql_adapter will be printed in drgn as follows,
+
+>>> ql_adapter
+(struct ql_adapter){
+.ricb = (struct ricb){
+.base_cq = (u8)0,
+.flags = (u8)120,
+.mask = (__le16)26637,
+.hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 },
+.ipv6_hash_key = (__le32 [10]){},
+.ipv4_hash_key = (__le32 [4]){},
+},
+.flags = (unsigned long)0,
+.wol = (u32)0,
+.nic_stats = (struct nic_stats){
+.tx_pkts = (u64)0,
+.tx_bytes = (u64)0,
+.tx_mcast_pkts = (u64)0,
+.tx_bcast_pkts = (u64)0,
+.tx_ucast_pkts = (u64)0,
+.tx_ctl_pkts = (u64)0,
+.tx_pause_pkts = (u64)0,
+...
+},
+.active_vlans = (unsigned long [64]){
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615,
+18446619461681283072, 0, 42949673024, 2147483647,
+},
+.rx_ring = (struct rx_ring [17]){
+{
+.cqicb = (struct cqicb){
+.msix_vect = (u8)0,
+.reserved1 = (u8)0,
+.reserved2 = (u8)0,
+.flags = (u8)0,
+.len = (__le16)0,
+.rid = (__le16)0,
+...
+},
+

[PATCH v4 7/8] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land

2021-01-23 Thread Coiby Xu
The debugging code in the following ifdef land
 - QL_ALL_DUMP
 - QL_REG_DUMP
 - QL_DEV_DUMP
 - QL_CB_DUMP
 - QL_IB_DUMP
 - QL_OB_DUMP

becomes unnecessary because,
 - Device status and general registers can be obtained by ethtool.
 - Coredump can be done via devlink health reporter.
 - Structure related to the hardware (struct ql_adapter) can be obtained
   by crash or drgn.

Link: https://lkml.org/lkml/2020/6/30/19
Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/TODO   |   4 -
 drivers/staging/qlge/qlge.h |  82 
 drivers/staging/qlge/qlge_dbg.c | 688 
 drivers/staging/qlge/qlge_ethtool.c |   2 -
 drivers/staging/qlge/qlge_main.c|   7 +-
 5 files changed, 1 insertion(+), 782 deletions(-)

diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO
index e68c95f47754..c76394b9451b 100644
--- a/drivers/staging/qlge/TODO
+++ b/drivers/staging/qlge/TODO
@@ -14,10 +14,6 @@
   queues" is confusing.
 * struct rx_ring is used for rx and tx completions, with some members relevant
   to one case only
-* there is an inordinate amount of disparate debugging code, most of which is
-  of questionable value. In particular, qlge_dbg.c has hundreds of lines of
-  code bitrotting away in ifdef land (doesn't compile since commit
-  18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago).
 * the flow control implementation in firmware is buggy (sends a flood of pause
   frames, resets the link, device and driver buffer queues become
   desynchronized), disable it by default
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index aa5721862140..55e0ad759250 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2289,86 +2289,4 @@ void qlge_check_lb_frame(struct qlge_adapter *qdev, 
struct sk_buff *skb);
 int qlge_own_firmware(struct qlge_adapter *qdev);
 int qlge_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget);
 
-/* #define QL_ALL_DUMP */
-/* #define QL_REG_DUMP */
-/* #define QL_DEV_DUMP */
-/* #define QL_CB_DUMP */
-/* #define QL_IB_DUMP */
-/* #define QL_OB_DUMP */
-
-#ifdef QL_REG_DUMP
-void qlge_dump_xgmac_control_regs(struct qlge_adapter *qdev);
-void qlge_dump_routing_entries(struct qlge_adapter *qdev);
-void qlge_dump_regs(struct qlge_adapter *qdev);
-#define QL_DUMP_REGS(qdev) qlge_dump_regs(qdev)
-#define QL_DUMP_ROUTE(qdev) qlge_dump_routing_entries(qdev)
-#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) qlge_dump_xgmac_control_regs(qdev)
-#else
-#define QL_DUMP_REGS(qdev)
-#define QL_DUMP_ROUTE(qdev)
-#define QL_DUMP_XGMAC_CONTROL_REGS(qdev)
-#endif
-
-#ifdef QL_STAT_DUMP
-void qlge_dump_stat(struct qlge_adapter *qdev);
-#define QL_DUMP_STAT(qdev) qlge_dump_stat(qdev)
-#else
-#define QL_DUMP_STAT(qdev)
-#endif
-
-#ifdef QL_DEV_DUMP
-void qlge_dump_qdev(struct qlge_adapter *qdev);
-#define QL_DUMP_QDEV(qdev) qlge_dump_qdev(qdev)
-#else
-#define QL_DUMP_QDEV(qdev)
-#endif
-
-#ifdef QL_CB_DUMP
-void qlge_dump_wqicb(struct wqicb *wqicb);
-void qlge_dump_tx_ring(struct tx_ring *tx_ring);
-void qlge_dump_ricb(struct ricb *ricb);
-void qlge_dump_cqicb(struct cqicb *cqicb);
-void qlge_dump_rx_ring(struct rx_ring *rx_ring);
-void qlge_dump_hw_cb(struct qlge_adapter *qdev, int size, u32 bit, u16 q_id);
-#define QL_DUMP_RICB(ricb) qlge_dump_ricb(ricb)
-#define QL_DUMP_WQICB(wqicb) qlge_dump_wqicb(wqicb)
-#define QL_DUMP_TX_RING(tx_ring) qlge_dump_tx_ring(tx_ring)
-#define QL_DUMP_CQICB(cqicb) qlge_dump_cqicb(cqicb)
-#define QL_DUMP_RX_RING(rx_ring) qlge_dump_rx_ring(rx_ring)
-#define QL_DUMP_HW_CB(qdev, size, bit, q_id) \
-   qlge_dump_hw_cb(qdev, size, bit, q_id)
-#else
-#define QL_DUMP_RICB(ricb)
-#define QL_DUMP_WQICB(wqicb)
-#define QL_DUMP_TX_RING(tx_ring)
-#define QL_DUMP_CQICB(cqicb)
-#define QL_DUMP_RX_RING(rx_ring)
-#define QL_DUMP_HW_CB(qdev, size, bit, q_id)
-#endif
-
-#ifdef QL_OB_DUMP
-void qlge_dump_tx_desc(struct qlge_adapter *qdev, struct tx_buf_desc *tbd);
-void qlge_dump_ob_mac_iocb(struct qlge_adapter *qdev, struct 
qlge_ob_mac_iocb_req *ob_mac_iocb);
-void qlge_dump_ob_mac_rsp(struct qlge_adapter *qdev, struct 
qlge_ob_mac_iocb_rsp *ob_mac_rsp);
-#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) qlge_dump_ob_mac_iocb(qdev, 
ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) qlge_dump_ob_mac_rsp(qdev, 
ob_mac_rsp)
-#else
-#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp)
-#endif
-
-#ifdef QL_IB_DUMP
-void qlge_dump_ib_mac_rsp(struct qlge_adapter *qdev, struct 
qlge_ib_mac_iocb_rsp *ib_mac_rsp);
-#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) qlge_dump_ib_mac_rsp(qdev, 
ib_mac_rsp)
-#else
-#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp)
-#endif
-
-#ifdef QL_ALL_DUMP
-void qlge_dump_all(struct qlge_adapter *qdev);
-#define QL_DUMP_ALL(qdev) qlge_dump_all(qdev)
-#else
-#define QL_DUMP_ALL(qdev)
-#endif
-
 #endif /* _QLGE_H_ */
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/q

[PATCH v4 4/8] staging: qlge: coredump via devlink health reporter

2021-01-23 Thread Coiby Xu
$ devlink health dump show DEVICE reporter coredump -p -j
{
"Core Registers": {
"segment": 1,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
"Test Logic Regs": {
"segment": 2,
"values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
},
"RMII Registers": {
"segment": 3,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
...
"Sem Registers": {
    "segment": 50,
"values": [ 0,0,0,0 ]
}
}

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_devlink.c | 132 ++--
 1 file changed, 126 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
index d9c71f45211f..bf7d75ed5eae 100644
--- a/drivers/staging/qlge/qlge_devlink.c
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -2,16 +2,136 @@
 #include "qlge.h"
 #include "qlge_devlink.h"
 
-static int
-qlge_reporter_coredump(struct devlink_health_reporter *reporter,
-  struct devlink_fmsg *fmsg, void *priv_ctx,
-  struct netlink_ext_ack *extack)
+static int qlge_fill_seg_(struct devlink_fmsg *fmsg,
+ struct mpi_coredump_segment_header *seg_header,
+ u32 *reg_data)
 {
-   return 0;
+   int regs_num = (seg_header->seg_size
+   - sizeof(struct mpi_coredump_segment_header)) / 
sizeof(u32);
+   int err;
+   int i;
+
+   err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description);
+   if (err)
+   return err;
+   err = devlink_fmsg_obj_nest_start(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_start(fmsg, "values");
+   if (err)
+   return err;
+   for (i = 0; i < regs_num; i++) {
+   err = devlink_fmsg_u32_put(fmsg, *reg_data);
+   if (err)
+   return err;
+   reg_data++;
+   }
+   err = devlink_fmsg_obj_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_pair_nest_end(fmsg);
+   return err;
+}
+
+#define FILL_SEG(seg_hdr, seg_regs)\
+   do {\
+   err = qlge_fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \
+   if (err) {  \
+   kvfree(dump);   \
+   return err; \
+   }   \
+   } while (0)
+
+static int qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+ struct devlink_fmsg *fmsg, void *priv_ctx,
+ struct netlink_ext_ack *extack)
+{
+   int err = 0;
+
+   struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter);
+   struct qlge_mpi_coredump *dump;
+
+   if (!netif_running(qdev->ndev))
+   return 0;
+
+   dump = kvmalloc(sizeof(*dump), GFP_KERNEL);
+   if (!dump)
+   return -ENOMEM;
+
+   err = qlge_core_dump(qdev, dump);
+   if (err) {
+   kvfree(dump);
+   return err;
+   }
+
+   qlge_soft_reset_mpi_risc(qdev);
+
+   FILL_SEG(core_regs_seg_hdr, mpi_core_regs);
+   FILL_SEG(test_logic_regs_seg_hdr, test_logic_regs);
+   FILL_SEG(rmii_regs_seg_hdr, rmii_regs);
+   FILL_SEG(fcmac1_regs_seg_hdr, fcmac1_regs);
+   FILL_SEG(fcmac2_regs_seg_hdr, fcmac2_regs);
+   FILL_SEG(fc1_mbx_regs_seg_hdr, fc1_mbx_regs);
+   FILL_SEG(ide_regs_seg_hdr, ide_regs);
+   FILL_SEG(nic1_mbx_regs_seg_hdr, nic1_mbx_regs);
+   FILL_SEG(smbus_regs_seg_hdr, smbus_regs);
+   FILL_SEG(fc2_mbx_regs_seg_hdr, fc2_mbx_regs);
+   FILL_SEG(nic2_mbx_regs_seg_hdr, nic2_mbx_regs);
+   FILL_SEG(i2c_regs_seg_hdr, i2c_regs);
+   FILL_SEG(memc_regs_seg_hdr, memc_regs);
+   FILL_SEG(pbus_regs_seg_hdr, pbus_regs)

[PATCH v4 3/8] staging: qlge: re-write qlge_init_device

2021-01-23 Thread Coiby Xu
Stop calling ql_release_all in qlge_init_device and free things one step
at a time.

struct qlge_adapter *qdev is now a private structure of struct devlink
and memset is not necessary.

Link: https://lore.kernel.org/patchwork/patch/1321092/#1516928
Suggested-by: Dan Carpenter 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_main.c | 32 
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index bb9fc590d97b..2ec688d3d946 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -4394,13 +4394,13 @@ static int qlge_init_device(struct pci_dev *pdev, 
struct qlge_adapter *qdev,
err = pcie_set_readrq(pdev, 4096);
if (err) {
dev_err(>dev, "Set readrq failed.\n");
-   goto err_out1;
+   goto err_disable_pci;
}
 
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
dev_err(>dev, "PCI region request failed.\n");
-   return err;
+   goto err_disable_pci;
}
 
pci_set_master(pdev);
@@ -4416,7 +4416,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
 
if (err) {
dev_err(>dev, "No usable DMA configuration.\n");
-   goto err_out2;
+   goto err_release_pci;
}
 
/* Set PCIe reset type for EEH to fundamental. */
@@ -4427,7 +4427,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
if (!qdev->reg_base) {
dev_err(>dev, "Register mapping failed.\n");
err = -ENOMEM;
-   goto err_out2;
+   goto err_release_pci;
}
 
qdev->doorbell_area_size = pci_resource_len(pdev, 3);
@@ -4436,14 +4436,14 @@ static int qlge_init_device(struct pci_dev *pdev, 
struct qlge_adapter *qdev,
if (!qdev->doorbell_area) {
dev_err(>dev, "Doorbell register mapping failed.\n");
err = -ENOMEM;
-   goto err_out2;
+   goto err_iounmap_base;
}
 
err = qlge_get_board_info(qdev);
if (err) {
dev_err(>dev, "Register access failed.\n");
err = -EIO;
-   goto err_out2;
+   goto err_iounmap_doorbell;
}
qdev->msg_enable = netif_msg_init(debug, default_msg);
spin_lock_init(>stats_lock);
@@ -4453,7 +4453,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
vmalloc(sizeof(struct qlge_mpi_coredump));
if (!qdev->mpi_coredump) {
err = -ENOMEM;
-   goto err_out2;
+   goto err_iounmap_doorbell;
}
if (qlge_force_coredump)
set_bit(QL_FRC_COREDUMP, >flags);
@@ -4462,7 +4462,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
err = qdev->nic_ops->get_flash(qdev);
if (err) {
dev_err(>dev, "Invalid FLASH.\n");
-   goto err_out2;
+   goto err_free_mpi_coredump;
}
 
/* Keep local copy of current mac address. */
@@ -4485,7 +4485,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
  ndev->name);
if (!qdev->workqueue) {
err = -ENOMEM;
-   goto err_out2;
+   goto err_free_mpi_coredump;
}
 
INIT_DELAYED_WORK(>asic_reset_work, qlge_asic_reset_work);
@@ -4503,10 +4503,18 @@ static int qlge_init_device(struct pci_dev *pdev, 
struct qlge_adapter *qdev,
 DRV_NAME, DRV_VERSION);
}
return 0;
-err_out2:
-   qlge_release_all(pdev);
-err_out1:
+
+err_free_mpi_coredump:
+   vfree(qdev->mpi_coredump);
+err_iounmap_doorbell:
+   iounmap(qdev->doorbell_area);
+err_iounmap_base:
+   iounmap(qdev->reg_base);
+err_release_pci:
+   pci_release_regions(pdev);
+err_disable_pci:
pci_disable_device(pdev);
+
return err;
 }
 
-- 
2.29.2

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 2/8] staging: qlge: Initialize devlink health dump framework

2021-01-23 Thread Coiby Xu
Initialize devlink health dump framework for the qlge driver so the
coredump could be done via devlink.

struct qlge_adapter is now used as the private data structure of
struct devlink so it could exist independently of struct net_device
and devlink reload could be supported in the future. The private data
of PCIe driver now points to qlge_adapter.

Since devlink_alloc will zero out struct qlge_adapter, memset in
qlge_init_device is not necessary.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/Kconfig|   1 +
 drivers/staging/qlge/Makefile   |   2 +-
 drivers/staging/qlge/qlge.h |  13 +++
 drivers/staging/qlge/qlge_devlink.c |  31 +++
 drivers/staging/qlge/qlge_devlink.h |   9 ++
 drivers/staging/qlge/qlge_ethtool.c |  36 
 drivers/staging/qlge/qlge_main.c| 125 +---
 7 files changed, 151 insertions(+), 66 deletions(-)
 create mode 100644 drivers/staging/qlge/qlge_devlink.c
 create mode 100644 drivers/staging/qlge/qlge_devlink.h

diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig
index a3cb25a3ab80..6d831ed67965 100644
--- a/drivers/staging/qlge/Kconfig
+++ b/drivers/staging/qlge/Kconfig
@@ -3,6 +3,7 @@
 config QLGE
tristate "QLogic QLGE 10Gb Ethernet Driver Support"
depends on ETHERNET && PCI
+   select NET_DEVLINK
help
This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
 
diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile
index 1dc2568e820c..07c1898a512e 100644
--- a/drivers/staging/qlge/Makefile
+++ b/drivers/staging/qlge/Makefile
@@ -5,4 +5,4 @@
 
 obj-$(CONFIG_QLGE) += qlge.o
 
-qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
+qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 1ac85f2f770f..41f69751d34d 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2060,6 +2060,18 @@ struct nic_operations {
int (*port_initialize)(struct qlge_adapter *qdev);
 };
 
+struct qlge_netdev_priv {
+   struct qlge_adapter *qdev;
+   struct net_device *ndev;
+};
+
+static inline
+struct qlge_adapter *netdev_to_qdev(struct net_device *ndev)
+{
+   struct qlge_netdev_priv *ndev_priv = netdev_priv(ndev);
+
+   return ndev_priv->qdev;
+}
 /*
  * The main Adapter structure definition.
  * This structure has all fields relevant to the hardware.
@@ -2077,6 +2089,7 @@ struct qlge_adapter {
struct pci_dev *pdev;
struct net_device *ndev;/* Parent NET device */
 
+   struct devlink_health_reporter *reporter;
/* Hardware information */
u32 chip_rev_id;
u32 fw_rev_id;
diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
new file mode 100644
index ..d9c71f45211f
--- /dev/null
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "qlge.h"
+#include "qlge_devlink.h"
+
+static int
+qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+  struct devlink_fmsg *fmsg, void *priv_ctx,
+  struct netlink_ext_ack *extack)
+{
+   return 0;
+}
+
+static const struct devlink_health_reporter_ops qlge_reporter_ops = {
+   .name = "dummy",
+   .dump = qlge_reporter_coredump,
+};
+
+void qlge_health_create_reporters(struct qlge_adapter *priv)
+{
+   struct devlink_health_reporter *reporter;
+   struct devlink *devlink;
+
+   devlink = priv_to_devlink(priv);
+   priv->reporter =
+   devlink_health_reporter_create(devlink, _reporter_ops,
+  0, priv);
+   if (IS_ERR(priv->reporter))
+   netdev_warn(priv->ndev,
+   "Failed to create reporter, err = %ld\n",
+   PTR_ERR(reporter));
+}
diff --git a/drivers/staging/qlge/qlge_devlink.h 
b/drivers/staging/qlge/qlge_devlink.h
new file mode 100644
index ..19078e1ac694
--- /dev/null
+++ b/drivers/staging/qlge/qlge_devlink.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef QLGE_DEVLINK_H
+#define QLGE_DEVLINK_H
+
+#include 
+
+void qlge_health_create_reporters(struct qlge_adapter *priv);
+
+#endif /* QLGE_DEVLINK_H */
diff --git a/drivers/staging/qlge/qlge_ethtool.c 
b/drivers/staging/qlge/qlge_ethtool.c
index 3e577e1bc27c..24b079523d5c 100644
--- a/drivers/staging/qlge/qlge_ethtool.c
+++ b/drivers/staging/qlge/qlge_ethtool.c
@@ -366,7 +366,7 @@ static void
 qlge_get_ethtool_stats(struct net_device *ndev,
   struct ethtool_stats *stats, u64 *data)
 {
-   struct qlge_adapter *qdev = netdev_priv(ndev);
+   struct qlge_adapter *qdev = netdev_to_qdev(ndev);
int index, length;
 
length = QLGE_STATS_LEN;
@@ -3

[PATCH v4 0/8] staging: qlge: Re-writing the debugging features

2021-01-23 Thread Coiby Xu
This patch set aims to avoid dumping registers, data structures and
coredump to dmesg and also to reduce the code size of the qlge driver.

As pointed out by Benjamin [1],

> At 2000 lines, qlge_dbg.c alone is larger than some entire ethernet
> drivers. Most of what it does is dump kernel data structures or pci
> memory mapped registers to dmesg. There are better facilities for that.
> My thinking is not simply to delete qlge_dbg.c but to replace it, making
> sure that most of the same information is still available. For data
> structures, crash or drgn can be used; possibly with a script for the
> latter which formats the data. For pci registers, they should be
> included in the ethtool register dump and a patch added to ethtool to
> pretty print them. That's what other drivers like e1000e do. For the
> "coredump", devlink health can be used.

So the debugging features are re-written following Benjamin's advice,
   - dump kernel data structures in drgn
   - use devlink to do coredump which also includes device status and
 general registers

For the usage examples of supported devlink commands, please check the
last patch.

The tests have been done successfully following Shung-Hsi's steps[2] on
a machine from Red Hat,
 - build the kernel and this driver with KASAN, UBSAN, DEBUG_ATOMIC_SLEEP,
   PROVE_LOCKING and DEBUG_KMEMLEAK enabled
 - load and unload the driver
 - devlink health dump

[1] https://lkml.org/lkml/2020/6/30/19

[2] https://lore.kernel.org/netdev/20200816025717.GA28176@f3/T/

v3 -> v4
 - remove unnecessary memeset in qlge_init_device [Shung-Hsi Yu]
 - Call qlge_soft_reset_mpi_risc after getting coredump
 - only allow force_coredump for NIC function that owns the firmware

v2 -> v3
- Fix newly introduced resource leak [Dan Carpenter]
- Fix bugs after using struct qlge_adapter as the private data struct of devlink
- Add qlge_ prefix for structures not having a prefix and fix a left-over 
ql_adapter [Benjamin Poirier]

v1 -> v2
 - Call devlink_free when register_netdev fails [Willem de Bruijn]
 - "scripts/checkpatch.pl --strict" for changes [Dan Carpente]
 - Declares variables in "Reverse Christmas Tree" [Dan Carpente]
 - Use the sizeof() directly  [Dan Carpente]
 - Add SPDX-License-Identifier to qlge_devlink.{c,h}
 - Rename ql_* to qlge_* [Benjamin Poirier]
 - Update drivers/staging/qlge/TODO [Benjamin Poirier]
 - struct qlge_adapter is now used as the private data struct of
   devlink instead of net_device [Benjamin Poirier]

RFC -> v1
 - select NET_DEVLINK in Kconfig [Benjamin Poirier]
 - Don't do a coredump when the interface is down [Shung-Hsi Yu]
 - Remove stray newlines [Benjamin Poirier]
 - force_coredump for devlink
 - Remove mpi_core_to_log which will output the coredump to the kernel
   ring buffer
 - Put drgn script under Documentation [Benjamin Poirier]
 - Rename qlge_health.* to qlge_devlink.*

Coiby Xu (8):
  staging: qlge: use qlge_* prefix to avoid namespace clashes with other
qlogic drivers
  staging: qlge: Initialize devlink health dump framework
  staging: qlge: re-write qlge_init_device
  staging: qlge: coredump via devlink health reporter
  staging: qlge: support force_coredump option for devlink health dump
  staging: qlge: remove mpi_core_to_log which sends coredump to the
kernel ring buffer
  staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land
  staging: qlge: add documentation for debugging qlge

 .../networking/device_drivers/index.rst   |1 +
 .../device_drivers/qlogic/index.rst   |   18 +
 .../networking/device_drivers/qlogic/qlge.rst |  118 ++
 MAINTAINERS   |6 +
 drivers/staging/qlge/Kconfig  |1 +
 drivers/staging/qlge/Makefile |2 +-
 drivers/staging/qlge/TODO |   10 -
 drivers/staging/qlge/qlge.h   |  244 +--
 drivers/staging/qlge/qlge_dbg.c   | 1650 +
 drivers/staging/qlge/qlge_devlink.c   |  164 ++
 drivers/staging/qlge/qlge_devlink.h   |9 +
 drivers/staging/qlge/qlge_ethtool.c   |  233 ++-
 drivers/staging/qlge/qlge_main.c  | 1376 +++---
 drivers/staging/qlge/qlge_mpi.c   |  356 ++--
 14 files changed, 1873 insertions(+), 2315 deletions(-)
 create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst
 create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst
 create mode 100644 drivers/staging/qlge/qlge_devlink.c
 create mode 100644 drivers/staging/qlge/qlge_devlink.h

--
2.29.2

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 2/8] staging: qlge: Initialize devlink health dump framework

2020-10-20 Thread Coiby Xu

Hi,

Thank you for testing this patch!

On Tue, Oct 20, 2020 at 06:27:41PM +0800, Shung-Hsi Yu wrote:

On Tue, Oct 20, 2020 at 04:57:11PM +0800, Shung-Hsi Yu wrote:

Hi,

This patch trigger the following KASAN error inside qlge_init_device().

[...] general protection fault, probably for non-canonical address 
0xdc4b:  [#1] SMP DEBUG_PAGEALLOC KASAN PTI
[...] KASAN: null-ptr-deref in range [0x0258-0x025f]
[...] CPU: 0 PID: 438 Comm: systemd-udevd Tainted: G C  E 
5.9.0-kvmsmall+ #7
[...] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-48-
g...ilt.opensuse.org 04/01/2014
[...] RIP: 0010:qlge_get_8000_flash_params+0x377/0x6e0 [qlge]
[...] Code: 03 80 3c 02 00 0f 85 57 03 00 00 49 8b af 68 08 00 00 48 b8 00 00 00 00 
00 fc ff df 48 8d bd 5f 02 00 00 48 89 fa 48 c1 ea 03 <0f> b6 04 02 48 89 fa 83 
e2 07 38 d0 7f 08 84 c0 0f 85 c6 02 00 00
[...] RSP: 0018:c9f97788 EFLAGS: 00010207
[...] RAX: dc00 RBX:  RCX: 
[...] RDX: 004b RSI: c08cb843 RDI: 025f
[...] R10: fbfff5f718a0 R11: 0001 R12: dc00
[...] R13: 888111085d40 R14: 888111085d40 R15: 888111080280
[...] FS:  7f315f5db280() GS:8881f520() 
knlGS:
[...] CS:  0010 DS:  ES:  CR0: 80050033
[...] CR2: 55bb25297170 CR3: 000110674000 CR4: 06f0
[...] DR0:  DR1:  DR2: 
[...] DR3:  DR6: fffe0ff0 DR7: 0400
[...] Call Trace:
[...]  ? qlge_get_8012_flash_params+0x600/0x600 [qlge]
[...]  ? static_obj+0x8a/0xc0
[...]  ? lockdep_init_map_waits+0x26a/0x700
[...]  qlge_init_device+0x425/0x1000 [qlge]
[...]  ? debug_mutex_init+0x31/0x60
[...]  qlge_probe+0xfe/0x6c0 [qlge]


With qlge_get_8000_flash_params+0x377/0x6e0 corresponding to the following:

if (qdev->flash.flash_params_8000.data_type1 == 2)
memcpy(mac_addr,
   qdev->flash.flash_params_8000.mac_addr1,
   qdev->ndev->addr_len); // < Here


This is because qdev->ndev == 0.

The reason is that before qlge_get_8000_flash_params() get called qdev is 
memset-ed inside qlge_init_device().

static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev,
int cards_found)
{
struct net_device *ndev = qdev->ndev;
int err = 0;

memset((void *)qdev, 0, sizeof(*qdev));

// ...

// qlge_get_8000_flash_params() get's called
err = qdev->nic_ops->get_flash(qdev);

// ...
}



Thank you for reporting this issue and providing the fix. I was a bit
confused after reading previous email because I dind't notice memset
and the address of ((struct net_device *) 0)->addr_len is 0x026f
which is outside the range reported by KASAN,


[...] KASAN: null-ptr-deref in range [0x0258-0x025f]



--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/7] staging: qlge: replace ql_* with qlge_* to avoid namespace clashes with other qlogic drivers

2020-10-18 Thread Coiby Xu

On Sun, Oct 18, 2020 at 08:02:53PM +0900, Benjamin Poirier wrote:

On 2020-10-17 07:16 +0800, Coiby Xu wrote:

On Thu, Oct 15, 2020 at 10:01:36AM +0900, Benjamin Poirier wrote:
> On 2020-10-14 18:43 +0800, Coiby Xu wrote:
> > To avoid namespace clashes with other qlogic drivers and also for the
> > sake of naming consistency, use the "qlge_" prefix as suggested in
> > drivers/staging/qlge/TODO.
> >
> > Suggested-by: Benjamin Poirier 
> > Signed-off-by: Coiby Xu 
> > ---
> >  drivers/staging/qlge/TODO   |4 -
> >  drivers/staging/qlge/qlge.h |  190 ++--
> >  drivers/staging/qlge/qlge_dbg.c | 1073 ---
> >  drivers/staging/qlge/qlge_ethtool.c |  231 ++---
> >  drivers/staging/qlge/qlge_main.c| 1257 +--
> >  drivers/staging/qlge/qlge_mpi.c |  352 
> >  6 files changed, 1551 insertions(+), 1556 deletions(-)
> >
> > diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO
> > index f93f7428f5d5..5ac55664c3e2 100644
> > --- a/drivers/staging/qlge/TODO
> > +++ b/drivers/staging/qlge/TODO
> > @@ -28,10 +28,6 @@
> >  * the driver has a habit of using runtime checks where compile time checks 
are
> >possible (ex. ql_free_rx_buffers(), ql_alloc_rx_buffers())
> >  * reorder struct members to avoid holes if it doesn't impact performance
> > -* in terms of namespace, the driver uses either qlge_, ql_ (used by
> > -  other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with
> > -  clashes, ex: struct ob_mac_iocb_req). Rename everything to use the 
"qlge_"
> > -  prefix.
>
> You only renamed ql -> qlge. The prefix needs to be added where there is
> currently none like the second example of that text.

On second thoughts, these structs like ob_mac_iocb_req are defined in
local headers and there is no mixed usage. So even when we want to
build this diver and other qlogic drivers into the kernel instead of
as separate modules, it won't lead to real problems, is it right?


Using cscope or ctags and searching for ob_mac_iocb_req will yield
ambiguous results. It might also make things more difficult if using a
debugger.


Even if I have been using gtags, I didn't realize it. Thank you for
explaining it to me.

Looking at other drivers (ex. ice, mlx5), they use a prefix for their
private types, just like for their static functions, even though it's
not absolutely necessary. I think it's helpful when reading the code
because it quickly shows that it is something that was defined in the
driver, not in some subsystem.


Good point!


I didn't think about it earlier but it would have been better to leave
out this renaming to a subsequent patchset, since this change is
unrelated to the debugging features.


It seems it's more reasonable to do renaming first. So in a sense, the
renaming is a preparatory step for the debugging features.

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver

2020-10-16 Thread Coiby Xu

On Thu, Oct 15, 2020 at 08:06:06PM +0900, Benjamin Poirier wrote:

On 2020-10-15 11:37 +0800, Coiby Xu wrote:

On Tue, Oct 13, 2020 at 09:37:04AM +0900, Benjamin Poirier wrote:
> On 2020-10-12 19:24 +0800, Coiby Xu wrote:
> [...]
> > > I think, but didn't check in depth, that in those drivers, the devlink
> > > device is tied to the pci device and can exist independently of the
> > > netdev, at least in principle.
> > >
> > You are right. Take drivers/net/ethernet/mellanox/mlxsw as an example,
> > devlink reload would first first unregister_netdev and then
> > register_netdev but struct devlink stays put. But I have yet to
> > understand when unregister/register_netdev is needed.
>
> Maybe it can be useful to manually recover if the hardware or driver
> gets in an erroneous state. I've used `modprobe -r qlge && modprobe
> qlge` for the same in the past.

Thank you for providing this user case!
>
> > Do we need to
> > add "devlink reload" for qlge?
>
> Not for this patchset. That would be a new feature.

To implement this feature, it seems I need to understand how qlge work
under the hood. For example, what's the difference between
qlge_soft_reset_mpi_risc and qlge_hard_reset_mpi_risc? Or should we use
a brute-force way like do the tasks in qlge_remove and then re-do the
tasks in qlge_probe?


I don't know. Like I've said before, I'd recommend testing on actual
hardware. I don't have access to it anymore.


Yeah, as I'm changing more code, it's more and more important to test
it on actual hardware. Have you heard anyone installing qle8142 to
Raspberry Pi which has a PCIe bus.



Is a hardware reference manual for qlge device?


I've never gotten access to one.


My experience of wrestling with an AMD GPIO chip [1] shows it would
be a bit annoying to deal with a device without a reference manual.
I have to treat it like a blackbox and try different kinds of input
to see what would happen.

Btw, it seems resetting the device is a kind of panacea. For example,
according to the specs of my touchpad (Synaptics RMI4 Specification),
it even has the feature of spontaneous reset. devlink health [2] also
has the so-called auto-recovery. So resetting is a common phenomenon. I
wonder if there are some common guidelines to do resetting which also
apply to the qlge8*** devices.


The only noteworthy thing from Qlogic that I know of is the firmware
update:
http://driverdownloads.qlogic.com/QLogicDriverDownloads_UI/SearchByProduct.aspx?ProductCategory=322=1104=190

It did fix some weird behavior when I applied it so I'd recommend doing
the same if you get an adapter.


Thank you for sharing the info!


[1] https://www.spinics.net/lists/linux-gpio/msg53901.html
[2] 
https://www.kernel.org/doc/html/latest/networking/devlink/devlink-health.html

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/7] staging: qlge: replace ql_* with qlge_* to avoid namespace clashes with other qlogic drivers

2020-10-16 Thread Coiby Xu

On Thu, Oct 15, 2020 at 10:01:36AM +0900, Benjamin Poirier wrote:

On 2020-10-14 18:43 +0800, Coiby Xu wrote:

To avoid namespace clashes with other qlogic drivers and also for the
sake of naming consistency, use the "qlge_" prefix as suggested in
drivers/staging/qlge/TODO.

Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/TODO   |4 -
 drivers/staging/qlge/qlge.h |  190 ++--
 drivers/staging/qlge/qlge_dbg.c | 1073 ---
 drivers/staging/qlge/qlge_ethtool.c |  231 ++---
 drivers/staging/qlge/qlge_main.c| 1257 +--
 drivers/staging/qlge/qlge_mpi.c |  352 
 6 files changed, 1551 insertions(+), 1556 deletions(-)

diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO
index f93f7428f5d5..5ac55664c3e2 100644
--- a/drivers/staging/qlge/TODO
+++ b/drivers/staging/qlge/TODO
@@ -28,10 +28,6 @@
 * the driver has a habit of using runtime checks where compile time checks are
   possible (ex. ql_free_rx_buffers(), ql_alloc_rx_buffers())
 * reorder struct members to avoid holes if it doesn't impact performance
-* in terms of namespace, the driver uses either qlge_, ql_ (used by
-  other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with
-  clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_"
-  prefix.


You only renamed ql -> qlge. The prefix needs to be added where there is
currently none like the second example of that text.


On second thoughts, these structs like ob_mac_iocb_req are defined in
local headers and there is no mixed usage. So even when we want to
build this diver and other qlogic drivers into the kernel instead of
as separate modules, it won't lead to real problems, is it right?


Besides, the next patch reintroduces the name struct ql_adapter.


--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 8/8] staging: qlge: add documentation for debugging qlge

2020-10-16 Thread Coiby Xu
Instructions and examples on kernel data structures dumping and
coredump.

Signed-off-by: Coiby Xu 
---
 .../networking/device_drivers/index.rst   |   1 +
 .../device_drivers/qlogic/index.rst   |  18 +++
 .../networking/device_drivers/qlogic/qlge.rst | 118 ++
 MAINTAINERS   |   6 +
 4 files changed, 143 insertions(+)
 create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst
 create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst

diff --git a/Documentation/networking/device_drivers/index.rst 
b/Documentation/networking/device_drivers/index.rst
index a3113ffd7a16..d8279de7bf25 100644
--- a/Documentation/networking/device_drivers/index.rst
+++ b/Documentation/networking/device_drivers/index.rst
@@ -15,6 +15,7 @@ Contents:
ethernet/index
fddi/index
hamradio/index
+   qlogic/index
wan/index
wifi/index
 
diff --git a/Documentation/networking/device_drivers/qlogic/index.rst 
b/Documentation/networking/device_drivers/qlogic/index.rst
new file mode 100644
index ..ad05b04286e4
--- /dev/null
+++ b/Documentation/networking/device_drivers/qlogic/index.rst
@@ -0,0 +1,18 @@
+.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+QLogic QLGE Device Drivers
+===
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   qlge
+
+.. only::  subproject and html
+
+   Indices
+   ===
+
+   * :ref:`genindex`
diff --git a/Documentation/networking/device_drivers/qlogic/qlge.rst 
b/Documentation/networking/device_drivers/qlogic/qlge.rst
new file mode 100644
index ..0b888253d152
--- /dev/null
+++ b/Documentation/networking/device_drivers/qlogic/qlge.rst
@@ -0,0 +1,118 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===
+QLogic QLGE 10Gb Ethernet device driver
+===
+
+This driver use drgn and devlink for debugging.
+
+Dump kernel data structures in drgn
+---
+
+To dump kernel data structures, the following Python script can be used
+in drgn:
+
+.. code-block:: python
+
+   def align(x, a):
+   """the alignment a should be a power of 2
+   """
+   mask = a - 1
+   return (x+ mask) & ~mask
+
+   def struct_size(struct_type):
+   struct_str = "struct {}".format(struct_type)
+   return sizeof(Object(prog, struct_str, address=0x0))
+
+   def netdev_priv(netdevice):
+   NETDEV_ALIGN = 32
+   return netdevice.value_() + align(struct_size("net_device"), 
NETDEV_ALIGN)
+
+   name = 'xxx'
+   qlge_device = None
+   netdevices = prog['init_net'].dev_base_head.address_of_()
+   for netdevice in list_for_each_entry("struct net_device", netdevices, 
"dev_list"):
+   if netdevice.name.string_().decode('ascii') == name:
+   print(netdevice.name)
+
+   ql_adapter = Object(prog, "struct ql_adapter", 
address=netdev_priv(qlge_device))
+
+The struct ql_adapter will be printed in drgn as follows,
+
+>>> ql_adapter
+(struct ql_adapter){
+.ricb = (struct ricb){
+.base_cq = (u8)0,
+.flags = (u8)120,
+.mask = (__le16)26637,
+.hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 },
+.ipv6_hash_key = (__le32 [10]){},
+.ipv4_hash_key = (__le32 [4]){},
+},
+.flags = (unsigned long)0,
+.wol = (u32)0,
+.nic_stats = (struct nic_stats){
+.tx_pkts = (u64)0,
+.tx_bytes = (u64)0,
+.tx_mcast_pkts = (u64)0,
+.tx_bcast_pkts = (u64)0,
+.tx_ucast_pkts = (u64)0,
+.tx_ctl_pkts = (u64)0,
+.tx_pause_pkts = (u64)0,
+...
+},
+.active_vlans = (unsigned long [64]){
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615,
+18446619461681283072, 0, 42949673024, 2147483647,
+},
+.rx_ring = (struct rx_ring [17]){
+{
+.cqicb = (struct cqicb){
+.msix_vect = (u8)0,
+.reserved1 = (u8)0,
+.reserved2 = (u8)0,
+.flags = (u8)0,
+.len = (__le16)0,
+.rid = (__le16)0,
+...
+},
+

[PATCH v3 7/8] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land

2020-10-16 Thread Coiby Xu
The debugging code in the following ifdef land
 - QL_ALL_DUMP
 - QL_REG_DUMP
 - QL_DEV_DUMP
 - QL_CB_DUMP
 - QL_IB_DUMP
 - QL_OB_DUMP

becomes unnecessary because,
 - Device status and general registers can be obtained by ethtool.
 - Coredump can be done via devlink health reporter.
 - Structure related to the hardware (struct ql_adapter) can be obtained
   by crash or drgn.

Link: https://lkml.org/lkml/2020/6/30/19
Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/TODO   |   4 -
 drivers/staging/qlge/qlge.h |  82 
 drivers/staging/qlge/qlge_dbg.c | 688 
 drivers/staging/qlge/qlge_ethtool.c |   2 -
 drivers/staging/qlge/qlge_main.c|   7 +-
 5 files changed, 1 insertion(+), 782 deletions(-)

diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO
index e68c95f47754..c76394b9451b 100644
--- a/drivers/staging/qlge/TODO
+++ b/drivers/staging/qlge/TODO
@@ -14,10 +14,6 @@
   queues" is confusing.
 * struct rx_ring is used for rx and tx completions, with some members relevant
   to one case only
-* there is an inordinate amount of disparate debugging code, most of which is
-  of questionable value. In particular, qlge_dbg.c has hundreds of lines of
-  code bitrotting away in ifdef land (doesn't compile since commit
-  18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago).
 * the flow control implementation in firmware is buggy (sends a flood of pause
   frames, resets the link, device and driver buffer queues become
   desynchronized), disable it by default
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 8552ca7433f5..9015e2b0b54a 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2289,86 +2289,4 @@ void qlge_check_lb_frame(struct qlge_adapter *qdev, 
struct sk_buff *skb);
 int qlge_own_firmware(struct qlge_adapter *qdev);
 int qlge_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget);
 
-/* #define QL_ALL_DUMP */
-/* #define QL_REG_DUMP */
-/* #define QL_DEV_DUMP */
-/* #define QL_CB_DUMP */
-/* #define QL_IB_DUMP */
-/* #define QL_OB_DUMP */
-
-#ifdef QL_REG_DUMP
-void qlge_dump_xgmac_control_regs(struct qlge_adapter *qdev);
-void qlge_dump_routing_entries(struct qlge_adapter *qdev);
-void qlge_dump_regs(struct qlge_adapter *qdev);
-#define QL_DUMP_REGS(qdev) qlge_dump_regs(qdev)
-#define QL_DUMP_ROUTE(qdev) qlge_dump_routing_entries(qdev)
-#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) qlge_dump_xgmac_control_regs(qdev)
-#else
-#define QL_DUMP_REGS(qdev)
-#define QL_DUMP_ROUTE(qdev)
-#define QL_DUMP_XGMAC_CONTROL_REGS(qdev)
-#endif
-
-#ifdef QL_STAT_DUMP
-void qlge_dump_stat(struct qlge_adapter *qdev);
-#define QL_DUMP_STAT(qdev) qlge_dump_stat(qdev)
-#else
-#define QL_DUMP_STAT(qdev)
-#endif
-
-#ifdef QL_DEV_DUMP
-void qlge_dump_qdev(struct qlge_adapter *qdev);
-#define QL_DUMP_QDEV(qdev) qlge_dump_qdev(qdev)
-#else
-#define QL_DUMP_QDEV(qdev)
-#endif
-
-#ifdef QL_CB_DUMP
-void qlge_dump_wqicb(struct wqicb *wqicb);
-void qlge_dump_tx_ring(struct tx_ring *tx_ring);
-void qlge_dump_ricb(struct ricb *ricb);
-void qlge_dump_cqicb(struct cqicb *cqicb);
-void qlge_dump_rx_ring(struct rx_ring *rx_ring);
-void qlge_dump_hw_cb(struct qlge_adapter *qdev, int size, u32 bit, u16 q_id);
-#define QL_DUMP_RICB(ricb) qlge_dump_ricb(ricb)
-#define QL_DUMP_WQICB(wqicb) qlge_dump_wqicb(wqicb)
-#define QL_DUMP_TX_RING(tx_ring) qlge_dump_tx_ring(tx_ring)
-#define QL_DUMP_CQICB(cqicb) qlge_dump_cqicb(cqicb)
-#define QL_DUMP_RX_RING(rx_ring) qlge_dump_rx_ring(rx_ring)
-#define QL_DUMP_HW_CB(qdev, size, bit, q_id) \
-   qlge_dump_hw_cb(qdev, size, bit, q_id)
-#else
-#define QL_DUMP_RICB(ricb)
-#define QL_DUMP_WQICB(wqicb)
-#define QL_DUMP_TX_RING(tx_ring)
-#define QL_DUMP_CQICB(cqicb)
-#define QL_DUMP_RX_RING(rx_ring)
-#define QL_DUMP_HW_CB(qdev, size, bit, q_id)
-#endif
-
-#ifdef QL_OB_DUMP
-void qlge_dump_tx_desc(struct qlge_adapter *qdev, struct tx_buf_desc *tbd);
-void qlge_dump_ob_mac_iocb(struct qlge_adapter *qdev, struct 
qlge_ob_mac_iocb_req *ob_mac_iocb);
-void qlge_dump_ob_mac_rsp(struct qlge_adapter *qdev, struct 
qlge_ob_mac_iocb_rsp *ob_mac_rsp);
-#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) qlge_dump_ob_mac_iocb(qdev, 
ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) qlge_dump_ob_mac_rsp(qdev, 
ob_mac_rsp)
-#else
-#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp)
-#endif
-
-#ifdef QL_IB_DUMP
-void qlge_dump_ib_mac_rsp(struct qlge_adapter *qdev, struct 
qlge_ib_mac_iocb_rsp *ib_mac_rsp);
-#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) qlge_dump_ib_mac_rsp(qdev, 
ib_mac_rsp)
-#else
-#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp)
-#endif
-
-#ifdef QL_ALL_DUMP
-void qlge_dump_all(struct qlge_adapter *qdev);
-#define QL_DUMP_ALL(qdev) qlge_dump_all(qdev)
-#else
-#define QL_DUMP_ALL(qdev)
-#endif
-
 #endif /* _QLGE_H_ */
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/q

[PATCH v3 6/8] staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer

2020-10-16 Thread Coiby Xu
devlink health could be used to get coredump. No need to send so much
data to the kernel ring buffer.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/TODO   |  2 --
 drivers/staging/qlge/qlge.h |  3 ---
 drivers/staging/qlge/qlge_dbg.c | 11 ---
 drivers/staging/qlge/qlge_ethtool.c |  1 -
 drivers/staging/qlge/qlge_main.c|  2 --
 drivers/staging/qlge/qlge_mpi.c |  6 --
 6 files changed, 25 deletions(-)

diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO
index 5ac55664c3e2..e68c95f47754 100644
--- a/drivers/staging/qlge/TODO
+++ b/drivers/staging/qlge/TODO
@@ -18,8 +18,6 @@
   of questionable value. In particular, qlge_dbg.c has hundreds of lines of
   code bitrotting away in ifdef land (doesn't compile since commit
   18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago).
-* triggering an ethtool regdump will hexdump a 176k struct to dmesg depending
-  on some module parameters.
 * the flow control implementation in firmware is buggy (sends a flood of pause
   frames, resets the link, device and driver buffer queues become
   desynchronized), disable it by default
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 0a470f02b0c6..8552ca7433f5 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2153,7 +2153,6 @@ struct qlge_adapter {
u32 port_init;
u32 link_status;
struct qlge_mpi_coredump *mpi_coredump;
-   u32 core_is_dumped;
u32 link_config;
u32 led_config;
u32 max_frame_size;
@@ -2166,7 +2165,6 @@ struct qlge_adapter {
struct delayed_work mpi_work;
struct delayed_work mpi_port_cfg_work;
struct delayed_work mpi_idc_work;
-   struct delayed_work mpi_core_to_log;
struct completion ide_completion;
const struct nic_operations *nic_ops;
u16 device_id;
@@ -2257,7 +2255,6 @@ int qlge_write_cfg(struct qlge_adapter *qdev, void *ptr, 
int size, u32 bit,
 void qlge_queue_fw_error(struct qlge_adapter *qdev);
 void qlge_mpi_work(struct work_struct *work);
 void qlge_mpi_reset_work(struct work_struct *work);
-void qlge_mpi_core_to_log(struct work_struct *work);
 int qlge_wait_reg_rdy(struct qlge_adapter *qdev, u32 reg, u32 bit, u32 ebit);
 void qlge_queue_asic_error(struct qlge_adapter *qdev);
 void qlge_set_ethtool_ops(struct net_device *ndev);
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index b0d4ea071f32..5c64d6de3b30 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1313,17 +1313,6 @@ void qlge_get_dump(struct qlge_adapter *qdev, void *buff)
}
 }
 
-/* Coredump to messages log file using separate worker thread */
-void qlge_mpi_core_to_log(struct work_struct *work)
-{
-   struct qlge_adapter *qdev =
-   container_of(work, struct qlge_adapter, mpi_core_to_log.work);
-
-   print_hex_dump(KERN_DEBUG, "Core is dumping to log file!\n",
-  DUMP_PREFIX_OFFSET, 32, 4, qdev->mpi_coredump,
-  sizeof(*qdev->mpi_coredump), false);
-}
-
 #ifdef QL_REG_DUMP
 static void qlge_dump_intr_states(struct qlge_adapter *qdev)
 {
diff --git a/drivers/staging/qlge/qlge_ethtool.c 
b/drivers/staging/qlge/qlge_ethtool.c
index 24b079523d5c..3e911f147dfc 100644
--- a/drivers/staging/qlge/qlge_ethtool.c
+++ b/drivers/staging/qlge/qlge_ethtool.c
@@ -617,7 +617,6 @@ static void qlge_get_regs(struct net_device *ndev,
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
 
qlge_get_dump(qdev, p);
-   qdev->core_is_dumped = 0;
if (!test_bit(QL_FRC_COREDUMP, >flags))
regs->len = sizeof(struct qlge_mpi_coredump);
else
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index c081aa1bb43d..b138109a24a5 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3808,7 +3808,6 @@ static void qlge_cancel_all_work_sync(struct qlge_adapter 
*qdev)
cancel_delayed_work_sync(>mpi_reset_work);
cancel_delayed_work_sync(>mpi_work);
cancel_delayed_work_sync(>mpi_idc_work);
-   cancel_delayed_work_sync(>mpi_core_to_log);
cancel_delayed_work_sync(>mpi_port_cfg_work);
 }
 
@@ -4502,7 +4501,6 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
INIT_DELAYED_WORK(>mpi_work, qlge_mpi_work);
INIT_DELAYED_WORK(>mpi_port_cfg_work, qlge_mpi_port_cfg_work);
INIT_DELAYED_WORK(>mpi_idc_work, qlge_mpi_idc_work);
-   INIT_DELAYED_WORK(>mpi_core_to_log, qlge_mpi_core_to_log);
init_completion(>ide_completion);
mutex_init(>mpi_mutex);
 
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index e67d2f8652a3..7dd9e2de30e5 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -

[PATCH v3 5/8] staging: qlge: support force_coredump option for devlink health dump

2020-10-16 Thread Coiby Xu
With force_coredump module parameter set, devlink health dump will
reset the MPI RISC first which takes 5 secs to be finished.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_devlink.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
index b75ec5bff26a..92db531ad5e0 100644
--- a/drivers/staging/qlge/qlge_devlink.c
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -56,10 +56,17 @@ static int qlge_reporter_coredump(struct 
devlink_health_reporter *reporter,
 
struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter);
struct qlge_mpi_coredump *dump;
+   wait_queue_head_t wait;
 
if (!netif_running(qdev->ndev))
return 0;
 
+   if (test_bit(QL_FRC_COREDUMP, >flags)) {
+   qlge_queue_fw_error(qdev);
+   init_waitqueue_head();
+   wait_event_timeout(wait, 0, 5 * HZ);
+   }
+
dump = kvmalloc(sizeof(*dump), GFP_KERNEL);
if (!dump)
return -ENOMEM;
-- 
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 4/8] staging: qlge: coredump via devlink health reporter

2020-10-16 Thread Coiby Xu
$ devlink health dump show DEVICE reporter coredump -p -j
{
"Core Registers": {
"segment": 1,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
"Test Logic Regs": {
"segment": 2,
"values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
},
"RMII Registers": {
"segment": 3,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
...
"Sem Registers": {
    "segment": 50,
"values": [ 0,0,0,0 ]
}
}

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_devlink.c | 130 ++--
 1 file changed, 124 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
index d9c71f45211f..b75ec5bff26a 100644
--- a/drivers/staging/qlge/qlge_devlink.c
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -2,16 +2,134 @@
 #include "qlge.h"
 #include "qlge_devlink.h"
 
-static int
-qlge_reporter_coredump(struct devlink_health_reporter *reporter,
-  struct devlink_fmsg *fmsg, void *priv_ctx,
-  struct netlink_ext_ack *extack)
+static int qlge_fill_seg_(struct devlink_fmsg *fmsg,
+ struct mpi_coredump_segment_header *seg_header,
+ u32 *reg_data)
 {
-   return 0;
+   int regs_num = (seg_header->seg_size
+   - sizeof(struct mpi_coredump_segment_header)) / 
sizeof(u32);
+   int err;
+   int i;
+
+   err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description);
+   if (err)
+   return err;
+   err = devlink_fmsg_obj_nest_start(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_start(fmsg, "values");
+   if (err)
+   return err;
+   for (i = 0; i < regs_num; i++) {
+   err = devlink_fmsg_u32_put(fmsg, *reg_data);
+   if (err)
+   return err;
+   reg_data++;
+   }
+   err = devlink_fmsg_obj_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_pair_nest_end(fmsg);
+   return err;
+}
+
+#define FILL_SEG(seg_hdr, seg_regs)\
+   do {\
+   err = qlge_fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \
+   if (err) {  \
+   kvfree(dump);   \
+   return err; \
+   }   \
+   } while (0)
+
+static int qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+ struct devlink_fmsg *fmsg, void *priv_ctx,
+ struct netlink_ext_ack *extack)
+{
+   int err = 0;
+
+   struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter);
+   struct qlge_mpi_coredump *dump;
+
+   if (!netif_running(qdev->ndev))
+   return 0;
+
+   dump = kvmalloc(sizeof(*dump), GFP_KERNEL);
+   if (!dump)
+   return -ENOMEM;
+
+   err = qlge_core_dump(qdev, dump);
+   if (err) {
+   kvfree(dump);
+   return err;
+   }
+
+   FILL_SEG(core_regs_seg_hdr, mpi_core_regs);
+   FILL_SEG(test_logic_regs_seg_hdr, test_logic_regs);
+   FILL_SEG(rmii_regs_seg_hdr, rmii_regs);
+   FILL_SEG(fcmac1_regs_seg_hdr, fcmac1_regs);
+   FILL_SEG(fcmac2_regs_seg_hdr, fcmac2_regs);
+   FILL_SEG(fc1_mbx_regs_seg_hdr, fc1_mbx_regs);
+   FILL_SEG(ide_regs_seg_hdr, ide_regs);
+   FILL_SEG(nic1_mbx_regs_seg_hdr, nic1_mbx_regs);
+   FILL_SEG(smbus_regs_seg_hdr, smbus_regs);
+   FILL_SEG(fc2_mbx_regs_seg_hdr, fc2_mbx_regs);
+   FILL_SEG(nic2_mbx_regs_seg_hdr, nic2_mbx_regs);
+   FILL_SEG(i2c_regs_seg_hdr, i2c_regs);
+   FILL_SEG(memc_regs_seg_hdr, memc_regs);
+   FILL_SEG(pbus_regs_seg_hdr, pbus_regs);
+   FILL_SEG(mde_regs_seg_hdr, mde_r

[PATCH v3 3/8] staging: qlge: re-write qlge_init_device

2020-10-16 Thread Coiby Xu
Stop calling ql_release_all in qlge_init_device and free things one step
at a time.

Link: https://lore.kernel.org/patchwork/patch/1321092/#1516928
Suggested-by: Dan Carpenter 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_main.c | 32 
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 888179fbf98c..c081aa1bb43d 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -4403,13 +4403,13 @@ static int qlge_init_device(struct pci_dev *pdev, 
struct qlge_adapter *qdev,
err = pcie_set_readrq(pdev, 4096);
if (err) {
dev_err(>dev, "Set readrq failed.\n");
-   goto err_out1;
+   goto err_disable_pci;
}
 
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
dev_err(>dev, "PCI region request failed.\n");
-   return err;
+   goto err_disable_pci;
}
 
pci_set_master(pdev);
@@ -4425,7 +4425,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
 
if (err) {
dev_err(>dev, "No usable DMA configuration.\n");
-   goto err_out2;
+   goto err_release_pci;
}
 
/* Set PCIe reset type for EEH to fundamental. */
@@ -4436,7 +4436,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
if (!qdev->reg_base) {
dev_err(>dev, "Register mapping failed.\n");
err = -ENOMEM;
-   goto err_out2;
+   goto err_release_pci;
}
 
qdev->doorbell_area_size = pci_resource_len(pdev, 3);
@@ -4445,14 +4445,14 @@ static int qlge_init_device(struct pci_dev *pdev, 
struct qlge_adapter *qdev,
if (!qdev->doorbell_area) {
dev_err(>dev, "Doorbell register mapping failed.\n");
err = -ENOMEM;
-   goto err_out2;
+   goto err_iounmap_base;
}
 
err = qlge_get_board_info(qdev);
if (err) {
dev_err(>dev, "Register access failed.\n");
err = -EIO;
-   goto err_out2;
+   goto err_iounmap_doorbell;
}
qdev->msg_enable = netif_msg_init(debug, default_msg);
spin_lock_init(>stats_lock);
@@ -4462,7 +4462,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
vmalloc(sizeof(struct qlge_mpi_coredump));
if (!qdev->mpi_coredump) {
err = -ENOMEM;
-   goto err_out2;
+   goto err_iounmap_doorbell;
}
if (qlge_force_coredump)
set_bit(QL_FRC_COREDUMP, >flags);
@@ -4471,7 +4471,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
err = qdev->nic_ops->get_flash(qdev);
if (err) {
dev_err(>dev, "Invalid FLASH.\n");
-   goto err_out2;
+   goto err_free_mpi_coredump;
}
 
/* Keep local copy of current mac address. */
@@ -4494,7 +4494,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
  ndev->name);
if (!qdev->workqueue) {
err = -ENOMEM;
-   goto err_out2;
+   goto err_free_mpi_coredump;
}
 
INIT_DELAYED_WORK(>asic_reset_work, qlge_asic_reset_work);
@@ -4512,10 +4512,18 @@ static int qlge_init_device(struct pci_dev *pdev, 
struct qlge_adapter *qdev,
 DRV_NAME, DRV_VERSION);
}
return 0;
-err_out2:
-   qlge_release_all(pdev);
-err_out1:
+
+err_free_mpi_coredump:
+   vfree(qdev->mpi_coredump);
+err_iounmap_doorbell:
+   iounmap(qdev->doorbell_area);
+err_iounmap_base:
+   iounmap(qdev->reg_base);
+err_release_pci:
+   pci_release_regions(pdev);
+err_disable_pci:
pci_disable_device(pdev);
+
return err;
 }
 
-- 
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 2/8] staging: qlge: Initialize devlink health dump framework

2020-10-16 Thread Coiby Xu
Initialize devlink health dump framework for the qlge driver so the
coredump could be done via devlink.

struct qlge_adapter is now used as the private data structure of
struct devlink so it could exist independently of struct net_device
and devlink reload could be supported in the future. The private data
of PCIe driver now points to qlge_adapter.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/Kconfig|   1 +
 drivers/staging/qlge/Makefile   |   2 +-
 drivers/staging/qlge/qlge.h |  13 +++
 drivers/staging/qlge/qlge_devlink.c |  31 +++
 drivers/staging/qlge/qlge_devlink.h |   9 ++
 drivers/staging/qlge/qlge_ethtool.c |  36 
 drivers/staging/qlge/qlge_main.c| 124 +---
 7 files changed, 151 insertions(+), 65 deletions(-)
 create mode 100644 drivers/staging/qlge/qlge_devlink.c
 create mode 100644 drivers/staging/qlge/qlge_devlink.h

diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig
index a3cb25a3ab80..6d831ed67965 100644
--- a/drivers/staging/qlge/Kconfig
+++ b/drivers/staging/qlge/Kconfig
@@ -3,6 +3,7 @@
 config QLGE
tristate "QLogic QLGE 10Gb Ethernet Driver Support"
depends on ETHERNET && PCI
+   select NET_DEVLINK
help
This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
 
diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile
index 1dc2568e820c..07c1898a512e 100644
--- a/drivers/staging/qlge/Makefile
+++ b/drivers/staging/qlge/Makefile
@@ -5,4 +5,4 @@
 
 obj-$(CONFIG_QLGE) += qlge.o
 
-qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
+qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 57947f9336a8..0a470f02b0c6 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2060,6 +2060,18 @@ struct nic_operations {
int (*port_initialize)(struct qlge_adapter *qdev);
 };
 
+struct qlge_netdev_priv {
+   struct qlge_adapter *qdev;
+   struct net_device *ndev;
+};
+
+static inline
+struct qlge_adapter *netdev_to_qdev(struct net_device *ndev)
+{
+   struct qlge_netdev_priv *ndev_priv = netdev_priv(ndev);
+
+   return ndev_priv->qdev;
+}
 /*
  * The main Adapter structure definition.
  * This structure has all fields relevant to the hardware.
@@ -2077,6 +2089,7 @@ struct qlge_adapter {
struct pci_dev *pdev;
struct net_device *ndev;/* Parent NET device */
 
+   struct devlink_health_reporter *reporter;
/* Hardware information */
u32 chip_rev_id;
u32 fw_rev_id;
diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
new file mode 100644
index ..d9c71f45211f
--- /dev/null
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "qlge.h"
+#include "qlge_devlink.h"
+
+static int
+qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+  struct devlink_fmsg *fmsg, void *priv_ctx,
+  struct netlink_ext_ack *extack)
+{
+   return 0;
+}
+
+static const struct devlink_health_reporter_ops qlge_reporter_ops = {
+   .name = "dummy",
+   .dump = qlge_reporter_coredump,
+};
+
+void qlge_health_create_reporters(struct qlge_adapter *priv)
+{
+   struct devlink_health_reporter *reporter;
+   struct devlink *devlink;
+
+   devlink = priv_to_devlink(priv);
+   priv->reporter =
+   devlink_health_reporter_create(devlink, _reporter_ops,
+  0, priv);
+   if (IS_ERR(priv->reporter))
+   netdev_warn(priv->ndev,
+   "Failed to create reporter, err = %ld\n",
+   PTR_ERR(reporter));
+}
diff --git a/drivers/staging/qlge/qlge_devlink.h 
b/drivers/staging/qlge/qlge_devlink.h
new file mode 100644
index ..19078e1ac694
--- /dev/null
+++ b/drivers/staging/qlge/qlge_devlink.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef QLGE_DEVLINK_H
+#define QLGE_DEVLINK_H
+
+#include 
+
+void qlge_health_create_reporters(struct qlge_adapter *priv);
+
+#endif /* QLGE_DEVLINK_H */
diff --git a/drivers/staging/qlge/qlge_ethtool.c 
b/drivers/staging/qlge/qlge_ethtool.c
index 3e577e1bc27c..24b079523d5c 100644
--- a/drivers/staging/qlge/qlge_ethtool.c
+++ b/drivers/staging/qlge/qlge_ethtool.c
@@ -366,7 +366,7 @@ static void
 qlge_get_ethtool_stats(struct net_device *ndev,
   struct ethtool_stats *stats, u64 *data)
 {
-   struct qlge_adapter *qdev = netdev_priv(ndev);
+   struct qlge_adapter *qdev = netdev_to_qdev(ndev);
int index, length;
 
length = QLGE_STATS_LEN;
@@ -383,7 +383,7 @@ qlge_get_ethtool_stats(struct net_device *ndev,
 static int qlge_get_link_ksetti

[PATCH v3 0/8] staging: qlge: Re-writing the debugging features

2020-10-16 Thread Coiby Xu
This patch set aims to avoid dumping registers, data structures and
coredump to dmesg and also to reduce the code size of the qlge driver.

As pointed out by Benjamin [1],

> At 2000 lines, qlge_dbg.c alone is larger than some entire ethernet
> drivers. Most of what it does is dump kernel data structures or pci
> memory mapped registers to dmesg. There are better facilities for that.
> My thinking is not simply to delete qlge_dbg.c but to replace it, making
> sure that most of the same information is still available. For data
> structures, crash or drgn can be used; possibly with a script for the
> latter which formats the data. For pci registers, they should be
> included in the ethtool register dump and a patch added to ethtool to
> pretty print them. That's what other drivers like e1000e do. For the
> "coredump", devlink health can be used.

So the debugging features are re-written following Benjamin's advice,
   - dump kernel data structures in drgn
   - use devlink to do coredump which also includes device status and
 general registers

For the usage examples of supported devlink commands, please check the
last patch.

[1] https://lkml.org/lkml/2020/6/30/19

v2 -> v3
- Fix newly introduced resource leak [Dan Carpenter]
- Fix bugs after using struct qlge_adapter as the private data struct of devlink
- Add qlge_ prefix for structures not having a prefix and fix a left-over 
ql_adapter [Benjamin Poirier]

v1 -> v2
- Call devlink_free when register_netdev fails [Willem de Bruijn]
- "scripts/checkpatch.pl --strict" for changes [Dan Carpente]
- Declares variables in "Reverse Christmas Tree" [Dan Carpente]
- Use the sizeof() directly  [Dan Carpente]
- Add SPDX-License-Identifier to qlge_devlink.{c,h}
- Rename ql_* to qlge_* [Benjamin Poirier]
- Update drivers/staging/qlge/TODO [Benjamin Poirier]
- struct qlge_adapter is now used as the private data struct of
  devlink instead of net_device [Benjamin Poirier]

RFC -> v1
 - select NET_DEVLINK in Kconfig [Benjamin Poirier]
 - Don't do a coredump when the interface is down [Shung-Hsi Yu]
 - Remove stray newlines [Benjamin Poirier]
 - force_coredump for devlink
 - Remove mpi_core_to_log which will output the coredump to the kernel
   ring buffer
 - Put drgn script under Documentation [Benjamin Poirier]
 - Rename qlge_health.* to qlge_devlink.*

Coiby Xu (8):
  staging: qlge: use qlge_* prefix to avoid namespace clashes with other
qlogic drivers
  staging: qlge: Initialize devlink health dump framework
  staging: qlge: re-write qlge_init_device
  staging: qlge: coredump via devlink health reporter
  staging: qlge: support force_coredump option for devlink health dump
  staging: qlge: remove mpi_core_to_log which sends coredump to the
kernel ring buffer
  staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land
  staging: qlge: add documentation for debugging qlge

 .../networking/device_drivers/index.rst   |1 +
 .../device_drivers/qlogic/index.rst   |   18 +
 .../networking/device_drivers/qlogic/qlge.rst |  118 ++
 MAINTAINERS   |6 +
 drivers/staging/qlge/Kconfig  |1 +
 drivers/staging/qlge/Makefile |2 +-
 drivers/staging/qlge/TODO |   10 -
 drivers/staging/qlge/qlge.h   |  244 +--
 drivers/staging/qlge/qlge_dbg.c   | 1650 +
 drivers/staging/qlge/qlge_devlink.c   |  156 ++
 drivers/staging/qlge/qlge_devlink.h   |9 +
 drivers/staging/qlge/qlge_ethtool.c   |  234 ++-
 drivers/staging/qlge/qlge_main.c  | 1375 +++---
 drivers/staging/qlge/qlge_mpi.c   |  356 ++--
 14 files changed, 1866 insertions(+), 2314 deletions(-)
 create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst
 create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst
 create mode 100644 drivers/staging/qlge/qlge_devlink.c
 create mode 100644 drivers/staging/qlge/qlge_devlink.h

--
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/7] staging: qlge: replace ql_* with qlge_* to avoid namespace clashes with other qlogic drivers

2020-10-14 Thread Coiby Xu

On Thu, Oct 15, 2020 at 12:26:28PM +0800, Coiby Xu wrote:

On Thu, Oct 15, 2020 at 10:01:36AM +0900, Benjamin Poirier wrote:

On 2020-10-14 18:43 +0800, Coiby Xu wrote:

To avoid namespace clashes with other qlogic drivers and also for the
sake of naming consistency, use the "qlge_" prefix as suggested in
drivers/staging/qlge/TODO.

Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
drivers/staging/qlge/TODO   |4 -
drivers/staging/qlge/qlge.h |  190 ++--
drivers/staging/qlge/qlge_dbg.c | 1073 ---
drivers/staging/qlge/qlge_ethtool.c |  231 ++---
drivers/staging/qlge/qlge_main.c| 1257 +--
drivers/staging/qlge/qlge_mpi.c |  352 
6 files changed, 1551 insertions(+), 1556 deletions(-)

diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO
index f93f7428f5d5..5ac55664c3e2 100644
--- a/drivers/staging/qlge/TODO
+++ b/drivers/staging/qlge/TODO
@@ -28,10 +28,6 @@
* the driver has a habit of using runtime checks where compile time checks are
  possible (ex. ql_free_rx_buffers(), ql_alloc_rx_buffers())
* reorder struct members to avoid holes if it doesn't impact performance
-* in terms of namespace, the driver uses either qlge_, ql_ (used by
-  other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with
-  clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_"
-  prefix.


You only renamed ql -> qlge. The prefix needs to be added where there is
currently none like the second example of that text.


Thank you for reminding me of the second example!


Besides, the next patch reintroduces the name struct ql_adapter.


Oh, there is still a left-over ql_adapter in qlge.h (I renamed ql->qlge
after initializing the devlink framework earlier but did a git rebase
to make the order of the changes more reasonable). Thank you for the
reminding!


Btw, is there a way to configure kernel building to let the compiler
discover this kind of issue automatically?


--
Best regards,
Coiby


--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/7] staging: qlge: replace ql_* with qlge_* to avoid namespace clashes with other qlogic drivers

2020-10-14 Thread Coiby Xu

On Thu, Oct 15, 2020 at 10:01:36AM +0900, Benjamin Poirier wrote:

On 2020-10-14 18:43 +0800, Coiby Xu wrote:

To avoid namespace clashes with other qlogic drivers and also for the
sake of naming consistency, use the "qlge_" prefix as suggested in
drivers/staging/qlge/TODO.

Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/TODO   |4 -
 drivers/staging/qlge/qlge.h |  190 ++--
 drivers/staging/qlge/qlge_dbg.c | 1073 ---
 drivers/staging/qlge/qlge_ethtool.c |  231 ++---
 drivers/staging/qlge/qlge_main.c| 1257 +--
 drivers/staging/qlge/qlge_mpi.c |  352 
 6 files changed, 1551 insertions(+), 1556 deletions(-)

diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO
index f93f7428f5d5..5ac55664c3e2 100644
--- a/drivers/staging/qlge/TODO
+++ b/drivers/staging/qlge/TODO
@@ -28,10 +28,6 @@
 * the driver has a habit of using runtime checks where compile time checks are
   possible (ex. ql_free_rx_buffers(), ql_alloc_rx_buffers())
 * reorder struct members to avoid holes if it doesn't impact performance
-* in terms of namespace, the driver uses either qlge_, ql_ (used by
-  other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with
-  clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_"
-  prefix.


You only renamed ql -> qlge. The prefix needs to be added where there is
currently none like the second example of that text.


Thank you for reminding me of the second example!


Besides, the next patch reintroduces the name struct ql_adapter.


Oh, there is still a left-over ql_adapter in qlge.h (I renamed ql->qlge
after initializing the devlink framework earlier but did a git rebase
to make the order of the changes more reasonable). Thank you for the
reminding!

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 2/7] staging: qlge: Initialize devlink health dump framework

2020-10-14 Thread Coiby Xu

On Wed, Oct 14, 2020 at 04:08:46PM +0300, Dan Carpenter wrote:

On Wed, Oct 14, 2020 at 06:43:01PM +0800, Coiby Xu wrote:

 static int qlge_probe(struct pci_dev *pdev,
  const struct pci_device_id *pci_entry)
 {
struct net_device *ndev = NULL;
struct qlge_adapter *qdev = NULL;
+   struct devlink *devlink;
static int cards_found;
int err = 0;

-   ndev = alloc_etherdev_mq(sizeof(struct qlge_adapter),
+   devlink = devlink_alloc(_devlink_ops, sizeof(struct qlge_adapter));
+   if (!devlink)
+   return -ENOMEM;
+
+   qdev = devlink_priv(devlink);
+
+   ndev = alloc_etherdev_mq(sizeof(struct qlge_netdev_priv),
 min(MAX_CPUS,
 netif_get_num_default_rss_queues()));
if (!ndev)
-   return -ENOMEM;
+   goto devlink_free;

-   err = qlge_init_device(pdev, ndev, cards_found);
-   if (err < 0) {
-   free_netdev(ndev);
-   return err;


In the old code, if qlge_init_device() fails then it frees "ndev".


-   }
+   qdev->ndev = ndev;
+   err = qlge_init_device(pdev, qdev, cards_found);
+   if (err < 0)
+   goto devlink_free;


But the patch introduces a new resource leak.


Thank you for spotting this issue!





-   qdev = netdev_priv(ndev);
SET_NETDEV_DEV(ndev, >dev);
ndev->hw_features = NETIF_F_SG |
NETIF_F_IP_CSUM |
@@ -4611,8 +4619,14 @@ static int qlge_probe(struct pci_dev *pdev,
qlge_release_all(pdev);
pci_disable_device(pdev);
free_netdev(ndev);
-   return err;
+   goto devlink_free;
}
+
+   err = devlink_register(devlink, >dev);
+   if (err)
+   goto devlink_free;
+
+   qlge_health_create_reporters(qdev);
/* Start up the timer to trigger EEH if
 * the bus goes dead
 */
@@ -4623,6 +4637,10 @@ static int qlge_probe(struct pci_dev *pdev,
atomic_set(>lb_count, 0);
cards_found++;
return 0;
+
+devlink_free:
+   devlink_free(devlink);
+   return err;
 }


The best way to write error handling code is keep tracke of the most
recent allocation which was allocated successfully.

one = alloc();
if (!one)
return -ENOMEM;  //  <-- nothing allocated successfully

two = alloc();
if (!two) {
ret = -ENOMEM;
goto free_one; // <-- one was allocated successfully
  // Notice that the label name says what
   // the goto does.
}

three = alloc();
if (!three) {
ret = -ENOMEM;
goto free_two; // <-- two allocated, two freed.
}

...

return 0;

free_two:
free(two);
free_one:
free(one);

return ret;


Thank you for teaching me this pattern!


In the old code qlge_probe() freed things before returning, and that's
fine if there is only two allocations in the function but when there are
three or more allocations, then use gotos to unwind.

Ideally there would be a ql_deinit_device() function to mirror the
ql_init_device() function.  The ql_init_device() is staging quality
code with leaks and bad label names.  It should be re-written to free
things one step at a time instead of calling ql_release_all().


I'll see how I can improve ql_init_device. Thank you for the suggestion!


Anyway, let's not introduce new leaks at least.

regards,
dan carpenter


--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver

2020-10-14 Thread Coiby Xu

On Tue, Oct 13, 2020 at 09:37:04AM +0900, Benjamin Poirier wrote:

On 2020-10-12 19:24 +0800, Coiby Xu wrote:
[...]

> I think, but didn't check in depth, that in those drivers, the devlink
> device is tied to the pci device and can exist independently of the
> netdev, at least in principle.
>
You are right. Take drivers/net/ethernet/mellanox/mlxsw as an example,
devlink reload would first first unregister_netdev and then
register_netdev but struct devlink stays put. But I have yet to
understand when unregister/register_netdev is needed.


Maybe it can be useful to manually recover if the hardware or driver
gets in an erroneous state. I've used `modprobe -r qlge && modprobe
qlge` for the same in the past.


Thank you for providing this user case!



Do we need to
add "devlink reload" for qlge?


Not for this patchset. That would be a new feature.


To implement this feature, it seems I need to understand how qlge work
under the hood. For example, what's the difference between
qlge_soft_reset_mpi_risc and qlge_hard_reset_mpi_risc? Or should we use
a brute-force way like do the tasks in qlge_remove and then re-do the
tasks in qlge_probe? Is a hardware reference manual for qlge device?

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 4/7] staging: qlge: support force_coredump option for devlink health dump

2020-10-14 Thread Coiby Xu
With force_coredump module parameter set, devlink health dump will
reset the MPI RISC first which takes 5 secs to be finished.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_devlink.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
index b75ec5bff26a..92db531ad5e0 100644
--- a/drivers/staging/qlge/qlge_devlink.c
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -56,10 +56,17 @@ static int qlge_reporter_coredump(struct 
devlink_health_reporter *reporter,
 
struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter);
struct qlge_mpi_coredump *dump;
+   wait_queue_head_t wait;
 
if (!netif_running(qdev->ndev))
return 0;
 
+   if (test_bit(QL_FRC_COREDUMP, >flags)) {
+   qlge_queue_fw_error(qdev);
+   init_waitqueue_head();
+   wait_event_timeout(wait, 0, 5 * HZ);
+   }
+
dump = kvmalloc(sizeof(*dump), GFP_KERNEL);
if (!dump)
return -ENOMEM;
-- 
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 6/7] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land

2020-10-14 Thread Coiby Xu
The debugging code in the following ifdef land
 - QL_ALL_DUMP
 - QL_REG_DUMP
 - QL_DEV_DUMP
 - QL_CB_DUMP
 - QL_IB_DUMP
 - QL_OB_DUMP

becomes unnecessary because,
 - Device status and general registers can be obtained by ethtool.
 - Coredump can be done via devlink health reporter.
 - Structure related to the hardware (struct ql_adapter) can be obtained
   by crash or drgn.

Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/TODO   |   4 -
 drivers/staging/qlge/qlge.h |  82 
 drivers/staging/qlge/qlge_dbg.c | 688 
 drivers/staging/qlge/qlge_ethtool.c |   2 -
 drivers/staging/qlge/qlge_main.c|   7 +-
 5 files changed, 1 insertion(+), 782 deletions(-)

diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO
index e68c95f47754..c76394b9451b 100644
--- a/drivers/staging/qlge/TODO
+++ b/drivers/staging/qlge/TODO
@@ -14,10 +14,6 @@
   queues" is confusing.
 * struct rx_ring is used for rx and tx completions, with some members relevant
   to one case only
-* there is an inordinate amount of disparate debugging code, most of which is
-  of questionable value. In particular, qlge_dbg.c has hundreds of lines of
-  code bitrotting away in ifdef land (doesn't compile since commit
-  18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago).
 * the flow control implementation in firmware is buggy (sends a flood of pause
   frames, resets the link, device and driver buffer queues become
   desynchronized), disable it by default
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 5eb5c9a6fb84..1a26cbc67b79 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2281,86 +2281,4 @@ void qlge_check_lb_frame(struct qlge_adapter *qdev, 
struct sk_buff *skb);
 int qlge_own_firmware(struct qlge_adapter *qdev);
 int qlge_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget);
 
-/* #define QL_ALL_DUMP */
-/* #define QL_REG_DUMP */
-/* #define QL_DEV_DUMP */
-/* #define QL_CB_DUMP */
-/* #define QL_IB_DUMP */
-/* #define QL_OB_DUMP */
-
-#ifdef QL_REG_DUMP
-void qlge_dump_xgmac_control_regs(struct qlge_adapter *qdev);
-void qlge_dump_routing_entries(struct qlge_adapter *qdev);
-void qlge_dump_regs(struct qlge_adapter *qdev);
-#define QL_DUMP_REGS(qdev) qlge_dump_regs(qdev)
-#define QL_DUMP_ROUTE(qdev) qlge_dump_routing_entries(qdev)
-#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) qlge_dump_xgmac_control_regs(qdev)
-#else
-#define QL_DUMP_REGS(qdev)
-#define QL_DUMP_ROUTE(qdev)
-#define QL_DUMP_XGMAC_CONTROL_REGS(qdev)
-#endif
-
-#ifdef QL_STAT_DUMP
-void qlge_dump_stat(struct qlge_adapter *qdev);
-#define QL_DUMP_STAT(qdev) qlge_dump_stat(qdev)
-#else
-#define QL_DUMP_STAT(qdev)
-#endif
-
-#ifdef QL_DEV_DUMP
-void qlge_dump_qdev(struct qlge_adapter *qdev);
-#define QL_DUMP_QDEV(qdev) qlge_dump_qdev(qdev)
-#else
-#define QL_DUMP_QDEV(qdev)
-#endif
-
-#ifdef QL_CB_DUMP
-void qlge_dump_wqicb(struct wqicb *wqicb);
-void qlge_dump_tx_ring(struct tx_ring *tx_ring);
-void qlge_dump_ricb(struct ricb *ricb);
-void qlge_dump_cqicb(struct cqicb *cqicb);
-void qlge_dump_rx_ring(struct rx_ring *rx_ring);
-void qlge_dump_hw_cb(struct qlge_adapter *qdev, int size, u32 bit, u16 q_id);
-#define QL_DUMP_RICB(ricb) qlge_dump_ricb(ricb)
-#define QL_DUMP_WQICB(wqicb) qlge_dump_wqicb(wqicb)
-#define QL_DUMP_TX_RING(tx_ring) qlge_dump_tx_ring(tx_ring)
-#define QL_DUMP_CQICB(cqicb) qlge_dump_cqicb(cqicb)
-#define QL_DUMP_RX_RING(rx_ring) qlge_dump_rx_ring(rx_ring)
-#define QL_DUMP_HW_CB(qdev, size, bit, q_id) \
-   qlge_dump_hw_cb(qdev, size, bit, q_id)
-#else
-#define QL_DUMP_RICB(ricb)
-#define QL_DUMP_WQICB(wqicb)
-#define QL_DUMP_TX_RING(tx_ring)
-#define QL_DUMP_CQICB(cqicb)
-#define QL_DUMP_RX_RING(rx_ring)
-#define QL_DUMP_HW_CB(qdev, size, bit, q_id)
-#endif
-
-#ifdef QL_OB_DUMP
-void qlge_dump_tx_desc(struct qlge_adapter *qdev, struct tx_buf_desc *tbd);
-void qlge_dump_ob_mac_iocb(struct qlge_adapter *qdev, struct ob_mac_iocb_req 
*ob_mac_iocb);
-void qlge_dump_ob_mac_rsp(struct qlge_adapter *qdev, struct ob_mac_iocb_rsp 
*ob_mac_rsp);
-#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) qlge_dump_ob_mac_iocb(qdev, 
ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) qlge_dump_ob_mac_rsp(qdev, 
ob_mac_rsp)
-#else
-#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp)
-#endif
-
-#ifdef QL_IB_DUMP
-void qlge_dump_ib_mac_rsp(struct qlge_adapter *qdev, struct ib_mac_iocb_rsp 
*ib_mac_rsp);
-#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) qlge_dump_ib_mac_rsp(qdev, 
ib_mac_rsp)
-#else
-#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp)
-#endif
-
-#ifdef QL_ALL_DUMP
-void qlge_dump_all(struct qlge_adapter *qdev);
-#define QL_DUMP_ALL(qdev) qlge_dump_all(qdev)
-#else
-#define QL_DUMP_ALL(qdev)
-#endif
-
 #endif /* _QLGE_H_ */
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 43bc9580da9e..37e593f0fd82 100644
--- a/

[PATCH v2 5/7] staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer

2020-10-14 Thread Coiby Xu
devlink health could be used to get coredump. No need to send so much
data to the kernel ring buffer.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/TODO   |  2 --
 drivers/staging/qlge/qlge.h |  3 ---
 drivers/staging/qlge/qlge_dbg.c | 11 ---
 drivers/staging/qlge/qlge_ethtool.c |  1 -
 drivers/staging/qlge/qlge_main.c|  2 --
 drivers/staging/qlge/qlge_mpi.c |  6 --
 6 files changed, 25 deletions(-)

diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO
index 5ac55664c3e2..e68c95f47754 100644
--- a/drivers/staging/qlge/TODO
+++ b/drivers/staging/qlge/TODO
@@ -18,8 +18,6 @@
   of questionable value. In particular, qlge_dbg.c has hundreds of lines of
   code bitrotting away in ifdef land (doesn't compile since commit
   18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago).
-* triggering an ethtool regdump will hexdump a 176k struct to dmesg depending
-  on some module parameters.
 * the flow control implementation in firmware is buggy (sends a flood of pause
   frames, resets the link, device and driver buffer queues become
   desynchronized), disable it by default
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 4a48bcc88fbd..5eb5c9a6fb84 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2145,7 +2145,6 @@ struct qlge_adapter {
u32 port_init;
u32 link_status;
struct qlge_mpi_coredump *mpi_coredump;
-   u32 core_is_dumped;
u32 link_config;
u32 led_config;
u32 max_frame_size;
@@ -2158,7 +2157,6 @@ struct qlge_adapter {
struct delayed_work mpi_work;
struct delayed_work mpi_port_cfg_work;
struct delayed_work mpi_idc_work;
-   struct delayed_work mpi_core_to_log;
struct completion ide_completion;
const struct nic_operations *nic_ops;
u16 device_id;
@@ -2249,7 +2247,6 @@ int qlge_write_cfg(struct qlge_adapter *qdev, void *ptr, 
int size, u32 bit,
 void qlge_queue_fw_error(struct qlge_adapter *qdev);
 void qlge_mpi_work(struct work_struct *work);
 void qlge_mpi_reset_work(struct work_struct *work);
-void qlge_mpi_core_to_log(struct work_struct *work);
 int qlge_wait_reg_rdy(struct qlge_adapter *qdev, u32 reg, u32 bit, u32 ebit);
 void qlge_queue_asic_error(struct qlge_adapter *qdev);
 void qlge_set_ethtool_ops(struct net_device *ndev);
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 3d904f15568d..43bc9580da9e 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1313,17 +1313,6 @@ void qlge_get_dump(struct qlge_adapter *qdev, void *buff)
}
 }
 
-/* Coredump to messages log file using separate worker thread */
-void qlge_mpi_core_to_log(struct work_struct *work)
-{
-   struct qlge_adapter *qdev =
-   container_of(work, struct qlge_adapter, mpi_core_to_log.work);
-
-   print_hex_dump(KERN_DEBUG, "Core is dumping to log file!\n",
-  DUMP_PREFIX_OFFSET, 32, 4, qdev->mpi_coredump,
-  sizeof(*qdev->mpi_coredump), false);
-}
-
 #ifdef QL_REG_DUMP
 static void qlge_dump_intr_states(struct qlge_adapter *qdev)
 {
diff --git a/drivers/staging/qlge/qlge_ethtool.c 
b/drivers/staging/qlge/qlge_ethtool.c
index 3e577e1bc27c..c65d58fe159b 100644
--- a/drivers/staging/qlge/qlge_ethtool.c
+++ b/drivers/staging/qlge/qlge_ethtool.c
@@ -617,7 +617,6 @@ static void qlge_get_regs(struct net_device *ndev,
struct qlge_adapter *qdev = netdev_priv(ndev);
 
qlge_get_dump(qdev, p);
-   qdev->core_is_dumped = 0;
if (!test_bit(QL_FRC_COREDUMP, >flags))
regs->len = sizeof(struct qlge_mpi_coredump);
else
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 7a4bae3c12d0..128dd2fa2d41 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3808,7 +3808,6 @@ static void qlge_cancel_all_work_sync(struct qlge_adapter 
*qdev)
cancel_delayed_work_sync(>mpi_reset_work);
cancel_delayed_work_sync(>mpi_work);
cancel_delayed_work_sync(>mpi_idc_work);
-   cancel_delayed_work_sync(>mpi_core_to_log);
cancel_delayed_work_sync(>mpi_port_cfg_work);
 }
 
@@ -4503,7 +4502,6 @@ static int qlge_init_device(struct pci_dev *pdev, struct 
qlge_adapter *qdev,
INIT_DELAYED_WORK(>mpi_work, qlge_mpi_work);
INIT_DELAYED_WORK(>mpi_port_cfg_work, qlge_mpi_port_cfg_work);
INIT_DELAYED_WORK(>mpi_idc_work, qlge_mpi_idc_work);
-   INIT_DELAYED_WORK(>mpi_core_to_log, qlge_mpi_core_to_log);
init_completion(>ide_completion);
mutex_init(>mpi_mutex);
 
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index e67d2f8652a3..7dd9e2de30e5 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -

[PATCH v2 3/7] staging: qlge: coredump via devlink health reporter

2020-10-14 Thread Coiby Xu
$ devlink health dump show DEVICE reporter coredump -p -j
{
"Core Registers": {
"segment": 1,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
"Test Logic Regs": {
"segment": 2,
"values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
},
"RMII Registers": {
"segment": 3,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
...
"Sem Registers": {
    "segment": 50,
"values": [ 0,0,0,0 ]
}
}

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_devlink.c | 130 ++--
 1 file changed, 124 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
index d9c71f45211f..b75ec5bff26a 100644
--- a/drivers/staging/qlge/qlge_devlink.c
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -2,16 +2,134 @@
 #include "qlge.h"
 #include "qlge_devlink.h"
 
-static int
-qlge_reporter_coredump(struct devlink_health_reporter *reporter,
-  struct devlink_fmsg *fmsg, void *priv_ctx,
-  struct netlink_ext_ack *extack)
+static int qlge_fill_seg_(struct devlink_fmsg *fmsg,
+ struct mpi_coredump_segment_header *seg_header,
+ u32 *reg_data)
 {
-   return 0;
+   int regs_num = (seg_header->seg_size
+   - sizeof(struct mpi_coredump_segment_header)) / 
sizeof(u32);
+   int err;
+   int i;
+
+   err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description);
+   if (err)
+   return err;
+   err = devlink_fmsg_obj_nest_start(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_start(fmsg, "values");
+   if (err)
+   return err;
+   for (i = 0; i < regs_num; i++) {
+   err = devlink_fmsg_u32_put(fmsg, *reg_data);
+   if (err)
+   return err;
+   reg_data++;
+   }
+   err = devlink_fmsg_obj_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_pair_nest_end(fmsg);
+   return err;
+}
+
+#define FILL_SEG(seg_hdr, seg_regs)\
+   do {\
+   err = qlge_fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \
+   if (err) {  \
+   kvfree(dump);   \
+   return err; \
+   }   \
+   } while (0)
+
+static int qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+ struct devlink_fmsg *fmsg, void *priv_ctx,
+ struct netlink_ext_ack *extack)
+{
+   int err = 0;
+
+   struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter);
+   struct qlge_mpi_coredump *dump;
+
+   if (!netif_running(qdev->ndev))
+   return 0;
+
+   dump = kvmalloc(sizeof(*dump), GFP_KERNEL);
+   if (!dump)
+   return -ENOMEM;
+
+   err = qlge_core_dump(qdev, dump);
+   if (err) {
+   kvfree(dump);
+   return err;
+   }
+
+   FILL_SEG(core_regs_seg_hdr, mpi_core_regs);
+   FILL_SEG(test_logic_regs_seg_hdr, test_logic_regs);
+   FILL_SEG(rmii_regs_seg_hdr, rmii_regs);
+   FILL_SEG(fcmac1_regs_seg_hdr, fcmac1_regs);
+   FILL_SEG(fcmac2_regs_seg_hdr, fcmac2_regs);
+   FILL_SEG(fc1_mbx_regs_seg_hdr, fc1_mbx_regs);
+   FILL_SEG(ide_regs_seg_hdr, ide_regs);
+   FILL_SEG(nic1_mbx_regs_seg_hdr, nic1_mbx_regs);
+   FILL_SEG(smbus_regs_seg_hdr, smbus_regs);
+   FILL_SEG(fc2_mbx_regs_seg_hdr, fc2_mbx_regs);
+   FILL_SEG(nic2_mbx_regs_seg_hdr, nic2_mbx_regs);
+   FILL_SEG(i2c_regs_seg_hdr, i2c_regs);
+   FILL_SEG(memc_regs_seg_hdr, memc_regs);
+   FILL_SEG(pbus_regs_seg_hdr, pbus_regs);
+   FILL_SEG(mde_regs_seg_hdr, mde_r

[PATCH v2 0/7] staging: qlge: Re-writing the debugging features

2020-10-14 Thread Coiby Xu
This patch set aims to avoid dumping registers, data structures and
coredump to dmesg and also to reduce the code size of the qlge driver.

As pointed out by Benjamin [1],

> At 2000 lines, qlge_dbg.c alone is larger than some entire ethernet
> drivers. Most of what it does is dump kernel data structures or pci
> memory mapped registers to dmesg. There are better facilities for that.
> My thinking is not simply to delete qlge_dbg.c but to replace it, making
> sure that most of the same information is still available. For data
> structures, crash or drgn can be used; possibly with a script for the
> latter which formats the data. For pci registers, they should be
> included in the ethtool register dump and a patch added to ethtool to
> pretty print them. That's what other drivers like e1000e do. For the
> "coredump", devlink health can be used.

So the debugging features are re-written following Benjamin's advice,
   - dump kernel data structures in drgn
   - use devlink to do coredump which also includes device status and
 general registers

[1] https://lkml.org/lkml/2020/6/30/19

v1 -> v2
- Call devlink_free when register_netdev fails [Willem de Bruijn]
- "scripts/checkpatch.pl --strict" for changes [Dan Carpente]
- Declares variables in "Reverse Christmas Tree" [Dan Carpente]
- Use the sizeof() directly  [Dan Carpente]
- Add SPDX-License-Identifier to qlge_devlink.{c,h}
- Rename ql_* to qlge_* [Benjamin Poirier]
- Update drivers/staging/qlge/TODO [Benjamin Poirier]
- struct qlge_adapter is now used as the private data struct of
  devlink instead of net_device [Benjamin Poirier]

RFC -> v1
 - select NET_DEVLINK in Kconfig [Benjamin Poirier]
 - Don't do a coredump when the interface is down [Shung-Hsi Yu]
 - Remove stray newlines [Benjamin Poirier]
 - force_coredump for devlink
 - Remove mpi_core_to_log which will output the coredump to the kernel
   ring buffer
 - Put drgn script under Documentation [Benjamin Poirier]
 - Rename qlge_health.* to qlge_devlink.*

Coiby Xu (7):
  staging: qlge: replace ql_* with qlge_* to avoid namespace clashes
with other qlogic drivers
  staging: qlge: Initialize devlink health dump framework
  staging: qlge: coredump via devlink health reporter
  staging: qlge: support force_coredump option for devlink health dump
  staging: qlge: remove mpi_core_to_log which sends coredump to the
kernel ring buffer
  staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land
  staging: qlge: add documentation for debugging qlge

 .../networking/device_drivers/index.rst   |1 +
 .../device_drivers/qlogic/index.rst   |   18 +
 .../networking/device_drivers/qlogic/qlge.rst |  118 ++
 MAINTAINERS   |6 +
 drivers/staging/qlge/Kconfig  |1 +
 drivers/staging/qlge/Makefile |2 +-
 drivers/staging/qlge/TODO |   10 -
 drivers/staging/qlge/qlge.h   |  216 +--
 drivers/staging/qlge/qlge_dbg.c   | 1650 +
 drivers/staging/qlge/qlge_devlink.c   |  156 ++
 drivers/staging/qlge/qlge_devlink.h   |9 +
 drivers/staging/qlge/qlge_ethtool.c   |  234 ++-
 drivers/staging/qlge/qlge_main.c  | 1302 ++---
 drivers/staging/qlge/qlge_mpi.c   |  356 ++--
 14 files changed, 1802 insertions(+), 2277 deletions(-)
 create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst
 create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst
 create mode 100644 drivers/staging/qlge/qlge_devlink.c
 create mode 100644 drivers/staging/qlge/qlge_devlink.h

--
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 2/7] staging: qlge: Initialize devlink health dump framework

2020-10-14 Thread Coiby Xu
Initialize devlink health dump framework for the qlge driver so the
coredump could be done via devlink.

struct qlge_adapter is now used as the private data struct of
struct devlink so it could exist independently of struct net_device
and devlink reload could be supported in the future.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/Kconfig|  1 +
 drivers/staging/qlge/Makefile   |  2 +-
 drivers/staging/qlge/qlge.h |  5 +++
 drivers/staging/qlge/qlge_devlink.c | 31 +++
 drivers/staging/qlge/qlge_devlink.h |  9 ++
 drivers/staging/qlge/qlge_main.c| 48 +
 6 files changed, 82 insertions(+), 14 deletions(-)
 create mode 100644 drivers/staging/qlge/qlge_devlink.c
 create mode 100644 drivers/staging/qlge/qlge_devlink.h

diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig
index a3cb25a3ab80..6d831ed67965 100644
--- a/drivers/staging/qlge/Kconfig
+++ b/drivers/staging/qlge/Kconfig
@@ -3,6 +3,7 @@
 config QLGE
tristate "QLogic QLGE 10Gb Ethernet Driver Support"
depends on ETHERNET && PCI
+   select NET_DEVLINK
help
This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
 
diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile
index 1dc2568e820c..07c1898a512e 100644
--- a/drivers/staging/qlge/Makefile
+++ b/drivers/staging/qlge/Makefile
@@ -5,4 +5,4 @@
 
 obj-$(CONFIG_QLGE) += qlge.o
 
-qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
+qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 6ee83e7efd7c..4a48bcc88fbd 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2060,6 +2060,10 @@ struct nic_operations {
int (*port_initialize)(struct qlge_adapter *qdev);
 };
 
+struct qlge_netdev_priv {
+   struct ql_adapter *qdev;
+};
+
 /*
  * The main Adapter structure definition.
  * This structure has all fields relevant to the hardware.
@@ -2077,6 +2081,7 @@ struct qlge_adapter {
struct pci_dev *pdev;
struct net_device *ndev;/* Parent NET device */
 
+   struct devlink_health_reporter *reporter;
/* Hardware information */
u32 chip_rev_id;
u32 fw_rev_id;
diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
new file mode 100644
index ..d9c71f45211f
--- /dev/null
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "qlge.h"
+#include "qlge_devlink.h"
+
+static int
+qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+  struct devlink_fmsg *fmsg, void *priv_ctx,
+  struct netlink_ext_ack *extack)
+{
+   return 0;
+}
+
+static const struct devlink_health_reporter_ops qlge_reporter_ops = {
+   .name = "dummy",
+   .dump = qlge_reporter_coredump,
+};
+
+void qlge_health_create_reporters(struct qlge_adapter *priv)
+{
+   struct devlink_health_reporter *reporter;
+   struct devlink *devlink;
+
+   devlink = priv_to_devlink(priv);
+   priv->reporter =
+   devlink_health_reporter_create(devlink, _reporter_ops,
+  0, priv);
+   if (IS_ERR(priv->reporter))
+   netdev_warn(priv->ndev,
+   "Failed to create reporter, err = %ld\n",
+   PTR_ERR(reporter));
+}
diff --git a/drivers/staging/qlge/qlge_devlink.h 
b/drivers/staging/qlge/qlge_devlink.h
new file mode 100644
index ..19078e1ac694
--- /dev/null
+++ b/drivers/staging/qlge/qlge_devlink.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef QLGE_DEVLINK_H
+#define QLGE_DEVLINK_H
+
+#include 
+
+void qlge_health_create_reporters(struct qlge_adapter *priv);
+
+#endif /* QLGE_DEVLINK_H */
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 19e72279b0ce..7a4bae3c12d0 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -42,6 +42,7 @@
 #include 
 
 #include "qlge.h"
+#include "qlge_devlink.h"
 
 char qlge_driver_name[] = DRV_NAME;
 const char qlge_driver_version[] = DRV_VERSION;
@@ -4382,10 +4383,10 @@ static void qlge_release_all(struct pci_dev *pdev)
pci_release_regions(pdev);
 }
 
-static int qlge_init_device(struct pci_dev *pdev, struct net_device *ndev,
+static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev,
int cards_found)
 {
-   struct qlge_adapter *qdev = netdev_priv(ndev);
+   struct net_device *ndev = qdev->ndev;
int err = 0;
 
memset((void *)qdev, 0, sizeof(*qdev));
@@ -4548,27 +4549,34 @@ static void qlge_timer(struct timer_list *t)
mod

[PATCH v2 7/7] staging: qlge: add documentation for debugging qlge

2020-10-14 Thread Coiby Xu
Instructions and examples on kernel data structures dumping and
coredump.

Signed-off-by: Coiby Xu 
---
 .../networking/device_drivers/index.rst   |   1 +
 .../device_drivers/qlogic/index.rst   |  18 +++
 .../networking/device_drivers/qlogic/qlge.rst | 118 ++
 MAINTAINERS   |   6 +
 4 files changed, 143 insertions(+)
 create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst
 create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst

diff --git a/Documentation/networking/device_drivers/index.rst 
b/Documentation/networking/device_drivers/index.rst
index a3113ffd7a16..d8279de7bf25 100644
--- a/Documentation/networking/device_drivers/index.rst
+++ b/Documentation/networking/device_drivers/index.rst
@@ -15,6 +15,7 @@ Contents:
ethernet/index
fddi/index
hamradio/index
+   qlogic/index
wan/index
wifi/index
 
diff --git a/Documentation/networking/device_drivers/qlogic/index.rst 
b/Documentation/networking/device_drivers/qlogic/index.rst
new file mode 100644
index ..ad05b04286e4
--- /dev/null
+++ b/Documentation/networking/device_drivers/qlogic/index.rst
@@ -0,0 +1,18 @@
+.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+QLogic QLGE Device Drivers
+===
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   qlge
+
+.. only::  subproject and html
+
+   Indices
+   ===
+
+   * :ref:`genindex`
diff --git a/Documentation/networking/device_drivers/qlogic/qlge.rst 
b/Documentation/networking/device_drivers/qlogic/qlge.rst
new file mode 100644
index ..0b888253d152
--- /dev/null
+++ b/Documentation/networking/device_drivers/qlogic/qlge.rst
@@ -0,0 +1,118 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===
+QLogic QLGE 10Gb Ethernet device driver
+===
+
+This driver use drgn and devlink for debugging.
+
+Dump kernel data structures in drgn
+---
+
+To dump kernel data structures, the following Python script can be used
+in drgn:
+
+.. code-block:: python
+
+   def align(x, a):
+   """the alignment a should be a power of 2
+   """
+   mask = a - 1
+   return (x+ mask) & ~mask
+
+   def struct_size(struct_type):
+   struct_str = "struct {}".format(struct_type)
+   return sizeof(Object(prog, struct_str, address=0x0))
+
+   def netdev_priv(netdevice):
+   NETDEV_ALIGN = 32
+   return netdevice.value_() + align(struct_size("net_device"), 
NETDEV_ALIGN)
+
+   name = 'xxx'
+   qlge_device = None
+   netdevices = prog['init_net'].dev_base_head.address_of_()
+   for netdevice in list_for_each_entry("struct net_device", netdevices, 
"dev_list"):
+   if netdevice.name.string_().decode('ascii') == name:
+   print(netdevice.name)
+
+   ql_adapter = Object(prog, "struct ql_adapter", 
address=netdev_priv(qlge_device))
+
+The struct ql_adapter will be printed in drgn as follows,
+
+>>> ql_adapter
+(struct ql_adapter){
+.ricb = (struct ricb){
+.base_cq = (u8)0,
+.flags = (u8)120,
+.mask = (__le16)26637,
+.hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 },
+.ipv6_hash_key = (__le32 [10]){},
+.ipv4_hash_key = (__le32 [4]){},
+},
+.flags = (unsigned long)0,
+.wol = (u32)0,
+.nic_stats = (struct nic_stats){
+.tx_pkts = (u64)0,
+.tx_bytes = (u64)0,
+.tx_mcast_pkts = (u64)0,
+.tx_bcast_pkts = (u64)0,
+.tx_ucast_pkts = (u64)0,
+.tx_ctl_pkts = (u64)0,
+.tx_pause_pkts = (u64)0,
+...
+},
+.active_vlans = (unsigned long [64]){
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615,
+18446619461681283072, 0, 42949673024, 2147483647,
+},
+.rx_ring = (struct rx_ring [17]){
+{
+.cqicb = (struct cqicb){
+.msix_vect = (u8)0,
+.reserved1 = (u8)0,
+.reserved2 = (u8)0,
+.flags = (u8)0,
+.len = (__le16)0,
+.rid = (__le16)0,
+...
+},
+

Re: [PATCH v1 2/6] staging: qlge: coredump via devlink health reporter

2020-10-12 Thread Coiby Xu

On Sat, Oct 10, 2020 at 10:22:30PM +0900, Benjamin Poirier wrote:

On 2020-10-10 18:02 +0800, Coiby Xu wrote:
[...]

> > + do {   \
> > + err = fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \
> > + if (err) { \
> > + kvfree(dump);  \
> > + return err;\
> > + }  \
> > + } while (0)
> > +
> > +static int qlge_reporter_coredump(struct devlink_health_reporter *reporter,
> > +   struct devlink_fmsg *fmsg, void *priv_ctx,
> > +   struct netlink_ext_ack *extack)
> > +{
> > + int err = 0;
> > +
> > + struct qlge_devlink *dev = devlink_health_reporter_priv(reporter);
>
> Please name this variable ql_devlink, like in qlge_probe().

I happened to find the following text in drivers/staging/qlge/TODO
> * in terms of namespace, the driver uses either qlge_, ql_ (used by
>  other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with
>  clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_"
>  prefix.


This comment applies to global identifiers, not local variables.


Thank you for the explanation! Are you suggesting we should choose
different naming styles so we better tell global identifiers from local
variables?




So I will adopt qlge_ instead. Besides I prefer qlge_dl to ql_devlink.


Up to you but personally, I think ql_devlink is better. In any case,
"dev" is too general and often used for struct net_device pointers
instead.


Thank you for the suggestion. Another reason to use qlge_dl is many
other network drivers supporting devlink interface also adopt this kind
of style.

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 5/6] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land

2020-10-12 Thread Coiby Xu

On Sat, Oct 10, 2020 at 10:40:55PM +0900, Benjamin Poirier wrote:

On 2020-10-10 18:00 +0800, Coiby Xu wrote:
[...]

>
> Please also update drivers/staging/qlge/TODO accordingly. There is still
> a lot of debugging code IMO (the netif_printk statements - kernel
> tracing can be used instead of those) but this patch is a substantial
> improvement.

Thank you for the reminding! To move qlge out of staging tree would be
interesting exercise for me:)


If you would like to work more on the driver, I would highly suggest
getting one or two adapters to be able to test your changes. They can be
had for relatively cheap on ebay. Just search for "qle8142".


Thank you for the info! Right now I don't have a desktop to install
this kind of adapter. I'll get one after settling the plan for a desktop.

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver

2020-10-12 Thread Coiby Xu

On Sat, Oct 10, 2020 at 10:48:55PM +0900, Benjamin Poirier wrote:

On 2020-10-10 18:24 +0800, Coiby Xu wrote:

On Sat, Oct 10, 2020 at 04:35:14PM +0900, Benjamin Poirier wrote:
> On 2020-10-08 19:58 +0800, Coiby Xu wrote:
> > Initialize devlink health dump framework for the dlge driver so the
> > coredump could be done via devlink.
> >
> > Signed-off-by: Coiby Xu 
> > ---
> >  drivers/staging/qlge/Kconfig|  1 +
> >  drivers/staging/qlge/Makefile   |  2 +-
> >  drivers/staging/qlge/qlge.h |  9 +++
> >  drivers/staging/qlge/qlge_devlink.c | 38 +
> >  drivers/staging/qlge/qlge_devlink.h |  8 ++
> >  drivers/staging/qlge/qlge_main.c| 28 +
> >  6 files changed, 85 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/staging/qlge/qlge_devlink.c
> >  create mode 100644 drivers/staging/qlge/qlge_devlink.h
> >
> > diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig
> > index a3cb25a3ab80..6d831ed67965 100644
> > --- a/drivers/staging/qlge/Kconfig
> > +++ b/drivers/staging/qlge/Kconfig
> > @@ -3,6 +3,7 @@
> >  config QLGE
> >   tristate "QLogic QLGE 10Gb Ethernet Driver Support"
> >   depends on ETHERNET && PCI
> > + select NET_DEVLINK
> >   help
> >   This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
> >
> > diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile
> > index 1dc2568e820c..07c1898a512e 100644
> > --- a/drivers/staging/qlge/Makefile
> > +++ b/drivers/staging/qlge/Makefile
> > @@ -5,4 +5,4 @@
> >
> >  obj-$(CONFIG_QLGE) += qlge.o
> >
> > -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
> > +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o 
qlge_devlink.o
> > diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
> > index b295990e361b..290e754450c5 100644
> > --- a/drivers/staging/qlge/qlge.h
> > +++ b/drivers/staging/qlge/qlge.h
> > @@ -2060,6 +2060,14 @@ struct nic_operations {
> >   int (*port_initialize)(struct ql_adapter *qdev);
> >  };
> >
> > +
> > +
> > +struct qlge_devlink {
> > +struct ql_adapter *qdev;
> > +struct net_device *ndev;
>
> This member should be removed, it is unused throughout the rest of the
> series. Indeed, it's simple to use qdev->ndev and that's what
> qlge_reporter_coredump() does.

It reminds me that I forgot to reply to one of your comments in RFC and
sorry for that,
> > +
> > +
> > +struct qlge_devlink {
> > +struct ql_adapter *qdev;
> > +struct net_device *ndev;
>
> I don't have experience implementing devlink callbacks but looking at
> some other devlink users (mlx4, ionic, ice), all of them use devlink
> priv space for their main private structure. That would be struct
> ql_adapter in this case. Is there a good reason to stray from that
> pattern?


Thanks for getting back to that comment.



struct ql_adapter which is created via alloc_etherdev_mq is the
private space of struct net_device so we can't use ql_adapter as the
the devlink private space simultaneously. Thus struct qlge_devlink is
required.


Looking at those drivers (mlx4, ionic, ice), the usage of
alloc_etherdev_mq() is not really an obstacle. Definitely, some members
would need to be moved from ql_adapter to qlge_devlink to use that
pattern.


I see what you mean now. I thought we were going to use struct ql_adapter
as the shared private structure of devlink and net_device. If we are
going to use ql_adapter as the private structure of devlink then we have
to define another private structure for net_device.


I think, but didn't check in depth, that in those drivers, the devlink
device is tied to the pci device and can exist independently of the
netdev, at least in principle.


You are right. Take drivers/net/ethernet/mellanox/mlxsw as an example,
devlink reload would first first unregister_netdev and then
register_netdev but struct devlink stays put. But I have yet to
understand when unregister/register_netdev is needed. Do we need to
add "devlink reload" for qlge?


In any case, I see now that some other drivers (bnxt, liquidio) have a
pattern similar to what you use so I guess that's acceptable too.


--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver

2020-10-12 Thread Coiby Xu

On Thu, Oct 08, 2020 at 08:22:44AM -0400, Willem de Bruijn wrote:

On Thu, Oct 8, 2020 at 7:58 AM Coiby Xu  wrote:


Initialize devlink health dump framework for the dlge driver so the
coredump could be done via devlink.

Signed-off-by: Coiby Xu 



@@ -4556,6 +4559,13 @@ static int qlge_probe(struct pci_dev *pdev,
struct ql_adapter *qdev = NULL;
static int cards_found;
int err = 0;
+   struct devlink *devlink;
+   struct qlge_devlink *ql_devlink;
+
+   devlink = devlink_alloc(_devlink_ops, sizeof(struct qlge_devlink));
+   if (!devlink)
+   return -ENOMEM;
+   ql_devlink = devlink_priv(devlink);

ndev = alloc_etherdev_mq(sizeof(struct ql_adapter),
 min(MAX_CPUS,


need to goto devlink_free instead of return -ENOMEM here, too.


devlink_alloc return NULL only if kzalloc return NULL. So we
shouldn't go to devlink_free which will call kfree.



@@ -4614,6 +4624,16 @@ static int qlge_probe(struct pci_dev *pdev,
free_netdev(ndev);
return err;


and here


But I should goto devlink_free here. Thank you for pointing out my
neglect.



}
+
+   err = devlink_register(devlink, >dev);
+   if (err) {
+   goto devlink_free;
+   }
+
+   qlge_health_create_reporters(ql_devlink);
+   ql_devlink->qdev = qdev;
+   ql_devlink->ndev = ndev;
+   qdev->ql_devlink = ql_devlink;
/* Start up the timer to trigger EEH if
 * the bus goes dead
 */
@@ -4624,6 +4644,10 @@ static int qlge_probe(struct pci_dev *pdev,
atomic_set(>lb_count, 0);
cards_found++;
return 0;
+
+devlink_free:
+   devlink_free(devlink);
+   return err;
 }


--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver

2020-10-10 Thread Coiby Xu

On Sat, Oct 10, 2020 at 04:35:14PM +0900, Benjamin Poirier wrote:

On 2020-10-08 19:58 +0800, Coiby Xu wrote:

Initialize devlink health dump framework for the dlge driver so the
coredump could be done via devlink.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/Kconfig|  1 +
 drivers/staging/qlge/Makefile   |  2 +-
 drivers/staging/qlge/qlge.h |  9 +++
 drivers/staging/qlge/qlge_devlink.c | 38 +
 drivers/staging/qlge/qlge_devlink.h |  8 ++
 drivers/staging/qlge/qlge_main.c| 28 +
 6 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/qlge/qlge_devlink.c
 create mode 100644 drivers/staging/qlge/qlge_devlink.h

diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig
index a3cb25a3ab80..6d831ed67965 100644
--- a/drivers/staging/qlge/Kconfig
+++ b/drivers/staging/qlge/Kconfig
@@ -3,6 +3,7 @@
 config QLGE
tristate "QLogic QLGE 10Gb Ethernet Driver Support"
depends on ETHERNET && PCI
+   select NET_DEVLINK
help
This driver supports QLogic ISP8XXX 10Gb Ethernet cards.

diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile
index 1dc2568e820c..07c1898a512e 100644
--- a/drivers/staging/qlge/Makefile
+++ b/drivers/staging/qlge/Makefile
@@ -5,4 +5,4 @@

 obj-$(CONFIG_QLGE) += qlge.o

-qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
+qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index b295990e361b..290e754450c5 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2060,6 +2060,14 @@ struct nic_operations {
int (*port_initialize)(struct ql_adapter *qdev);
 };

+
+
+struct qlge_devlink {
+struct ql_adapter *qdev;
+struct net_device *ndev;


This member should be removed, it is unused throughout the rest of the
series. Indeed, it's simple to use qdev->ndev and that's what
qlge_reporter_coredump() does.


It reminds me that I forgot to reply to one of your comments in RFC and
sorry for that,

+
+
+struct qlge_devlink {
+struct ql_adapter *qdev;
+struct net_device *ndev;


I don't have experience implementing devlink callbacks but looking at
some other devlink users (mlx4, ionic, ice), all of them use devlink
priv space for their main private structure. That would be struct
ql_adapter in this case. Is there a good reason to stray from that
pattern?


struct ql_adapter which is created via alloc_etherdev_mq is the
private space of struct net_device so we can't use ql_adapter as the
the devlink private space simultaneously. Thus struct qlge_devlink is
required.

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 2/6] staging: qlge: coredump via devlink health reporter

2020-10-10 Thread Coiby Xu

On Sat, Oct 10, 2020 at 04:48:09PM +0900, Benjamin Poirier wrote:

On 2020-10-08 19:58 +0800, Coiby Xu wrote:

$ devlink health dump show DEVICE reporter coredump -p -j
{
"Core Registers": {
"segment": 1,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
"Test Logic Regs": {
"segment": 2,
"values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
},
"RMII Registers": {
"segment": 3,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
...
"Sem Registers": {
    "segment": 50,
"values": [ 0,0,0,0 ]
}
}

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_devlink.c | 131 ++--
 1 file changed, 125 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
index aa45e7e368c0..91b6600b94a9 100644
--- a/drivers/staging/qlge/qlge_devlink.c
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -1,16 +1,135 @@
 #include "qlge.h"
 #include "qlge_devlink.h"

-static int
-qlge_reporter_coredump(struct devlink_health_reporter *reporter,
-   struct devlink_fmsg *fmsg, void *priv_ctx,
-   struct netlink_ext_ack *extack)
+static int fill_seg_(struct devlink_fmsg *fmsg,


Please include the "qlge_" prefix.


+   struct mpi_coredump_segment_header *seg_header,
+   u32 *reg_data)
 {
-   return 0;
+   int i;
+   int header_size = sizeof(struct mpi_coredump_segment_header);
+   int regs_num = (seg_header->seg_size - header_size) / sizeof(u32);
+   int err;
+
+   err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description);
+   if (err)
+   return err;
+   err = devlink_fmsg_obj_nest_start(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_start(fmsg, "values");
+   if (err)
+   return err;
+   for (i = 0; i < regs_num; i++) {
+   err = devlink_fmsg_u32_put(fmsg, *reg_data);
+   if (err)
+   return err;
+   reg_data++;
+   }
+   err = devlink_fmsg_obj_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_pair_nest_end(fmsg);
+   return err;
+}
+
+#define fill_seg(seg_hdr, seg_regs)   \


considering that this macro accesses local variables, it is not really
"function-like". I think an all-caps name would be better to tip-off the
reader.


Thank you for this suggestion!


+   do {   \
+   err = fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \
+   if (err) { \
+   kvfree(dump);  \
+   return err;\
+   }  \
+   } while (0)
+
+static int qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+ struct devlink_fmsg *fmsg, void *priv_ctx,
+ struct netlink_ext_ack *extack)
+{
+   int err = 0;
+
+   struct qlge_devlink *dev = devlink_health_reporter_priv(reporter);


Please name this variable ql_devlink, like in qlge_probe().


I happened to find the following text in drivers/staging/qlge/TODO

* in terms of namespace, the driver uses either qlge_, ql_ (used by
 other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with
 clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_"
 prefix.


So I will adopt qlge_ instead. Besides I prefer qlge_dl to ql_devlink.

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 5/6] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land

2020-10-10 Thread Coiby Xu

On Sat, Oct 10, 2020 at 05:01:26PM +0900, Benjamin Poirier wrote:

On 2020-10-08 19:58 +0800, Coiby Xu wrote:

The debugging code in the following ifdef land
 - QL_ALL_DUMP
 - QL_REG_DUMP
 - QL_DEV_DUMP
 - QL_CB_DUMP
 - QL_IB_DUMP
 - QL_OB_DUMP

becomes unnecessary because,
 - Device status and general registers can be obtained by ethtool.
 - Coredump can be done via devlink health reporter.
 - Structure related to the hardware (struct ql_adapter) can be obtained
   by crash or drgn.

Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h |  82 
 drivers/staging/qlge/qlge_dbg.c | 688 
 drivers/staging/qlge/qlge_ethtool.c |   2 -
 drivers/staging/qlge/qlge_main.c|   7 +-


Please also update drivers/staging/qlge/TODO accordingly. There is still
a lot of debugging code IMO (the netif_printk statements - kernel
tracing can be used instead of those) but this patch is a substantial
improvement.


Thank you for the reminding! To move qlge out of staging tree would be
interesting exercise for me:)

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 2/6] staging: qlge: coredump via devlink health reporter

2020-10-08 Thread Coiby Xu

On Thu, Oct 08, 2020 at 04:39:40PM +0300, Dan Carpenter wrote:

On Thu, Oct 08, 2020 at 07:58:04PM +0800, Coiby Xu wrote:

-static int
-qlge_reporter_coredump(struct devlink_health_reporter *reporter,
-   struct devlink_fmsg *fmsg, void *priv_ctx,
-   struct netlink_ext_ack *extack)
+static int fill_seg_(struct devlink_fmsg *fmsg,
+   struct mpi_coredump_segment_header *seg_header,
+   u32 *reg_data)
 {
-   return 0;
+   int i;
+   int header_size = sizeof(struct mpi_coredump_segment_header);


Please use the sizeof() directly in the code.  Don't introduce
indirection if you can help it.


+   int regs_num = (seg_header->seg_size - header_size) / sizeof(u32);
+   int err;
+



Thank you for the suggestion!

regards,
dan carpenter


--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver

2020-10-08 Thread Coiby Xu

On Thu, Oct 08, 2020 at 04:31:42PM +0300, Dan Carpenter wrote:

On Thu, Oct 08, 2020 at 07:58:03PM +0800, Coiby Xu wrote:

Initialize devlink health dump framework for the dlge driver so the
coredump could be done via devlink.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/Kconfig|  1 +
 drivers/staging/qlge/Makefile   |  2 +-
 drivers/staging/qlge/qlge.h |  9 +++
 drivers/staging/qlge/qlge_devlink.c | 38 +
 drivers/staging/qlge/qlge_devlink.h |  8 ++
 drivers/staging/qlge/qlge_main.c| 28 +
 6 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/qlge/qlge_devlink.c
 create mode 100644 drivers/staging/qlge/qlge_devlink.h

diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig
index a3cb25a3ab80..6d831ed67965 100644
--- a/drivers/staging/qlge/Kconfig
+++ b/drivers/staging/qlge/Kconfig
@@ -3,6 +3,7 @@
 config QLGE
tristate "QLogic QLGE 10Gb Ethernet Driver Support"
depends on ETHERNET && PCI
+   select NET_DEVLINK
help
This driver supports QLogic ISP8XXX 10Gb Ethernet cards.

diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile
index 1dc2568e820c..07c1898a512e 100644
--- a/drivers/staging/qlge/Makefile
+++ b/drivers/staging/qlge/Makefile
@@ -5,4 +5,4 @@

 obj-$(CONFIG_QLGE) += qlge.o

-qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
+qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index b295990e361b..290e754450c5 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2060,6 +2060,14 @@ struct nic_operations {
int (*port_initialize)(struct ql_adapter *qdev);
 };

+
+


Having multiple blank lines in a row leads to a static checker warning.
Please run `checkpatch.pl --strict` over your patches.


+struct qlge_devlink {
+struct ql_adapter *qdev;
+struct net_device *ndev;
+struct devlink_health_reporter *reporter;
+};
+
 /*
  * The main Adapter structure definition.
  * This structure has all fields relevant to the hardware.
@@ -2077,6 +2085,7 @@ struct ql_adapter {
struct pci_dev *pdev;
struct net_device *ndev;/* Parent NET device */

+   struct qlge_devlink *ql_devlink;
/* Hardware information */
u32 chip_rev_id;
u32 fw_rev_id;
diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
new file mode 100644
index ..aa45e7e368c0
--- /dev/null
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -0,0 +1,38 @@
+#include "qlge.h"
+#include "qlge_devlink.h"
+
+static int
+qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+   struct devlink_fmsg *fmsg, void *priv_ctx,
+   struct netlink_ext_ack *extack)
+{
+   return 0;
+}
+
+static const struct devlink_health_reporter_ops qlge_reporter_ops = {
+   .name = "dummy",
+   .dump = qlge_reporter_coredump,


Indented too far.


+};
+
+int qlge_health_create_reporters(struct qlge_devlink *priv)
+{
+   int err;
+


No blanks in the middle of declarations.


+   struct devlink_health_reporter *reporter;
+   struct devlink *devlink;


Generally this driver declares variables in "Reverse Christmas Tree"
order.  The names are orderred by the length of the line from longest
to shortest.

type long_name;
type medium;
type short;


+
+   devlink = priv_to_devlink(priv);
+   reporter =
+   devlink_health_reporter_create(devlink, _reporter_ops,
+  0,
+  priv);


Break this up like so:

reporter = devlink_health_reporter_create(devlink, _reporter_ops,
  0, priv);



+   if (IS_ERR(reporter)) {
+   netdev_warn(priv->ndev,
+   "Failed to create reporter, err = %ld\n",
+   PTR_ERR(reporter));
+   return PTR_ERR(reporter);


No point in returning an error if the caller doesn't check?


+   }
+   priv->reporter = reporter;
+
+   return err;


err is uninitialized.  "return 0;"


+}
diff --git a/drivers/staging/qlge/qlge_devlink.h 
b/drivers/staging/qlge/qlge_devlink.h
new file mode 100644
index ..c91f7a29e805
--- /dev/null
+++ b/drivers/staging/qlge/qlge_devlink.h
@@ -0,0 +1,8 @@
+#ifndef QLGE_DEVLINK_H
+#define QLGE_DEVLINK_H
+
+#include 
+
+int qlge_health_create_reporters(struct qlge_devlink *priv);
+
+#endif /* QLGE_DEVLINK_H */
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 27da386f9d87..135225530e51 100644
--- a/drivers/staging/qlge/qlge_main.c
++

Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver

2020-10-08 Thread Coiby Xu

On Thu, Oct 08, 2020 at 08:22:44AM -0400, Willem de Bruijn wrote:

On Thu, Oct 8, 2020 at 7:58 AM Coiby Xu  wrote:


Initialize devlink health dump framework for the dlge driver so the
coredump could be done via devlink.

Signed-off-by: Coiby Xu 



@@ -4556,6 +4559,13 @@ static int qlge_probe(struct pci_dev *pdev,
struct ql_adapter *qdev = NULL;
static int cards_found;
int err = 0;
+   struct devlink *devlink;
+   struct qlge_devlink *ql_devlink;
+
+   devlink = devlink_alloc(_devlink_ops, sizeof(struct qlge_devlink));
+   if (!devlink)
+   return -ENOMEM;
+   ql_devlink = devlink_priv(devlink);

ndev = alloc_etherdev_mq(sizeof(struct ql_adapter),
 min(MAX_CPUS,


need to goto devlink_free instead of return -ENOMEM here, too.


@@ -4614,6 +4624,16 @@ static int qlge_probe(struct pci_dev *pdev,
free_netdev(ndev);
return err;


and here


Thank you for reviewing this work and the speedy feedback! I'll fix it
in v2.

}
+
+   err = devlink_register(devlink, >dev);
+   if (err) {
+   goto devlink_free;
+   }
+
+   qlge_health_create_reporters(ql_devlink);
+   ql_devlink->qdev = qdev;
+   ql_devlink->ndev = ndev;
+   qdev->ql_devlink = ql_devlink;
/* Start up the timer to trigger EEH if
 * the bus goes dead
 */
@@ -4624,6 +4644,10 @@ static int qlge_probe(struct pci_dev *pdev,
atomic_set(>lb_count, 0);
cards_found++;
return 0;
+
+devlink_free:
+   devlink_free(devlink);
+   return err;
 }


--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v1 5/6] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land

2020-10-08 Thread Coiby Xu
The debugging code in the following ifdef land
 - QL_ALL_DUMP
 - QL_REG_DUMP
 - QL_DEV_DUMP
 - QL_CB_DUMP
 - QL_IB_DUMP
 - QL_OB_DUMP

becomes unnecessary because,
 - Device status and general registers can be obtained by ethtool.
 - Coredump can be done via devlink health reporter.
 - Structure related to the hardware (struct ql_adapter) can be obtained
   by crash or drgn.

Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h |  82 
 drivers/staging/qlge/qlge_dbg.c | 688 
 drivers/staging/qlge/qlge_ethtool.c |   2 -
 drivers/staging/qlge/qlge_main.c|   7 +-
 4 files changed, 1 insertion(+), 778 deletions(-)

diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 0a39801be15a..8aff3ba77730 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2285,86 +2285,4 @@ void ql_check_lb_frame(struct ql_adapter *qdev, struct 
sk_buff *skb);
 int ql_own_firmware(struct ql_adapter *qdev);
 int ql_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget);
 
-/* #define QL_ALL_DUMP */
-/* #define QL_REG_DUMP */
-/* #define QL_DEV_DUMP */
-/* #define QL_CB_DUMP */
-/* #define QL_IB_DUMP */
-/* #define QL_OB_DUMP */
-
-#ifdef QL_REG_DUMP
-void ql_dump_xgmac_control_regs(struct ql_adapter *qdev);
-void ql_dump_routing_entries(struct ql_adapter *qdev);
-void ql_dump_regs(struct ql_adapter *qdev);
-#define QL_DUMP_REGS(qdev) ql_dump_regs(qdev)
-#define QL_DUMP_ROUTE(qdev) ql_dump_routing_entries(qdev)
-#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) ql_dump_xgmac_control_regs(qdev)
-#else
-#define QL_DUMP_REGS(qdev)
-#define QL_DUMP_ROUTE(qdev)
-#define QL_DUMP_XGMAC_CONTROL_REGS(qdev)
-#endif
-
-#ifdef QL_STAT_DUMP
-void ql_dump_stat(struct ql_adapter *qdev);
-#define QL_DUMP_STAT(qdev) ql_dump_stat(qdev)
-#else
-#define QL_DUMP_STAT(qdev)
-#endif
-
-#ifdef QL_DEV_DUMP
-void ql_dump_qdev(struct ql_adapter *qdev);
-#define QL_DUMP_QDEV(qdev) ql_dump_qdev(qdev)
-#else
-#define QL_DUMP_QDEV(qdev)
-#endif
-
-#ifdef QL_CB_DUMP
-void ql_dump_wqicb(struct wqicb *wqicb);
-void ql_dump_tx_ring(struct tx_ring *tx_ring);
-void ql_dump_ricb(struct ricb *ricb);
-void ql_dump_cqicb(struct cqicb *cqicb);
-void ql_dump_rx_ring(struct rx_ring *rx_ring);
-void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id);
-#define QL_DUMP_RICB(ricb) ql_dump_ricb(ricb)
-#define QL_DUMP_WQICB(wqicb) ql_dump_wqicb(wqicb)
-#define QL_DUMP_TX_RING(tx_ring) ql_dump_tx_ring(tx_ring)
-#define QL_DUMP_CQICB(cqicb) ql_dump_cqicb(cqicb)
-#define QL_DUMP_RX_RING(rx_ring) ql_dump_rx_ring(rx_ring)
-#define QL_DUMP_HW_CB(qdev, size, bit, q_id) \
-   ql_dump_hw_cb(qdev, size, bit, q_id)
-#else
-#define QL_DUMP_RICB(ricb)
-#define QL_DUMP_WQICB(wqicb)
-#define QL_DUMP_TX_RING(tx_ring)
-#define QL_DUMP_CQICB(cqicb)
-#define QL_DUMP_RX_RING(rx_ring)
-#define QL_DUMP_HW_CB(qdev, size, bit, q_id)
-#endif
-
-#ifdef QL_OB_DUMP
-void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd);
-void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req 
*ob_mac_iocb);
-void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp 
*ob_mac_rsp);
-#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, 
ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, 
ob_mac_rsp)
-#else
-#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp)
-#endif
-
-#ifdef QL_IB_DUMP
-void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp 
*ib_mac_rsp);
-#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) ql_dump_ib_mac_rsp(qdev, 
ib_mac_rsp)
-#else
-#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp)
-#endif
-
-#ifdef QL_ALL_DUMP
-void ql_dump_all(struct ql_adapter *qdev);
-#define QL_DUMP_ALL(qdev) ql_dump_all(qdev)
-#else
-#define QL_DUMP_ALL(qdev)
-#endif
-
 #endif /* _QLGE_H_ */
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 989575743718..a02ecf8fb291 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1313,691 +1313,3 @@ void ql_get_dump(struct ql_adapter *qdev, void *buff)
ql_get_core_dump(qdev);
}
 }
-
-#ifdef QL_REG_DUMP
-static void ql_dump_intr_states(struct ql_adapter *qdev)
-{
-   int i;
-   u32 value;
-
-   for (i = 0; i < qdev->intr_count; i++) {
-   ql_write32(qdev, INTR_EN, qdev->intr_context[i].intr_read_mask);
-   value = ql_read32(qdev, INTR_EN);
-   netdev_err(qdev->ndev, "Interrupt %d is %s\n", i,
-  (value & INTR_EN_EN ? "enabled" : "disabled"));
-   }
-}
-
-#define DUMP_XGMAC(qdev, reg)  \
-do {   \
-   u32 data;   \
-   ql_read_xgmac_reg(qdev, reg, );  

[PATCH v1 2/6] staging: qlge: coredump via devlink health reporter

2020-10-08 Thread Coiby Xu
$ devlink health dump show DEVICE reporter coredump -p -j
{
"Core Registers": {
"segment": 1,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
"Test Logic Regs": {
"segment": 2,
"values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
},
"RMII Registers": {
"segment": 3,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
...
"Sem Registers": {
    "segment": 50,
"values": [ 0,0,0,0 ]
}
}

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_devlink.c | 131 ++--
 1 file changed, 125 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
index aa45e7e368c0..91b6600b94a9 100644
--- a/drivers/staging/qlge/qlge_devlink.c
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -1,16 +1,135 @@
 #include "qlge.h"
 #include "qlge_devlink.h"
 
-static int
-qlge_reporter_coredump(struct devlink_health_reporter *reporter,
-   struct devlink_fmsg *fmsg, void *priv_ctx,
-   struct netlink_ext_ack *extack)
+static int fill_seg_(struct devlink_fmsg *fmsg,
+   struct mpi_coredump_segment_header *seg_header,
+   u32 *reg_data)
 {
-   return 0;
+   int i;
+   int header_size = sizeof(struct mpi_coredump_segment_header);
+   int regs_num = (seg_header->seg_size - header_size) / sizeof(u32);
+   int err;
+
+   err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description);
+   if (err)
+   return err;
+   err = devlink_fmsg_obj_nest_start(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_start(fmsg, "values");
+   if (err)
+   return err;
+   for (i = 0; i < regs_num; i++) {
+   err = devlink_fmsg_u32_put(fmsg, *reg_data);
+   if (err)
+   return err;
+   reg_data++;
+   }
+   err = devlink_fmsg_obj_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_pair_nest_end(fmsg);
+   return err;
+}
+
+#define fill_seg(seg_hdr, seg_regs)   \
+   do {   \
+   err = fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \
+   if (err) { \
+   kvfree(dump);  \
+   return err;\
+   }  \
+   } while (0)
+
+static int qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+ struct devlink_fmsg *fmsg, void *priv_ctx,
+ struct netlink_ext_ack *extack)
+{
+   int err = 0;
+
+   struct qlge_devlink *dev = devlink_health_reporter_priv(reporter);
+   struct ql_adapter *qdev = dev->qdev;
+   struct ql_mpi_coredump *dump;
+
+   if (!netif_running(qdev->ndev))
+   return 0;
+
+   dump = kvmalloc(sizeof(*dump), GFP_KERNEL);
+   if (!dump)
+   return -ENOMEM;
+
+   err = ql_core_dump(qdev, dump);
+   if (err) {
+   kvfree(dump);
+   return err;
+   }
+
+   fill_seg(core_regs_seg_hdr, mpi_core_regs);
+   fill_seg(test_logic_regs_seg_hdr, test_logic_regs);
+   fill_seg(rmii_regs_seg_hdr, rmii_regs);
+   fill_seg(fcmac1_regs_seg_hdr, fcmac1_regs);
+   fill_seg(fcmac2_regs_seg_hdr, fcmac2_regs);
+   fill_seg(fc1_mbx_regs_seg_hdr, fc1_mbx_regs);
+   fill_seg(ide_regs_seg_hdr, ide_regs);
+   fill_seg(nic1_mbx_regs_seg_hdr, nic1_mbx_regs);
+   fill_seg(smbus_regs_seg_hdr, smbus_regs);
+   fill_seg(fc2_mbx_regs_seg_hdr, fc2_mbx_regs);
+   fill_seg(nic2_mbx_regs_seg_hdr, nic2_mbx_regs);
+   fill_seg(i2c_regs_seg_hdr, i2c_regs);
+   fill_seg(memc_regs_seg_hdr, memc_regs);
+   fill_seg(pbus_regs_seg_hdr, pbus_regs);
+   fill_seg(mde_regs_seg_hdr, md

[PATCH v1 6/6] staging: qlge: add documentation for debugging qlge

2020-10-08 Thread Coiby Xu
Instructions and examples on kernel data structures dumping and coredump.

Signed-off-by: Coiby Xu 
---
 .../networking/device_drivers/index.rst   |   1 +
 .../device_drivers/qlogic/index.rst   |  18 +++
 .../networking/device_drivers/qlogic/qlge.rst | 118 ++
 MAINTAINERS   |   6 +
 4 files changed, 143 insertions(+)
 create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst
 create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst

diff --git a/Documentation/networking/device_drivers/index.rst 
b/Documentation/networking/device_drivers/index.rst
index a3113ffd7a16..d8279de7bf25 100644
--- a/Documentation/networking/device_drivers/index.rst
+++ b/Documentation/networking/device_drivers/index.rst
@@ -15,6 +15,7 @@ Contents:
ethernet/index
fddi/index
hamradio/index
+   qlogic/index
wan/index
wifi/index
 
diff --git a/Documentation/networking/device_drivers/qlogic/index.rst 
b/Documentation/networking/device_drivers/qlogic/index.rst
new file mode 100644
index ..ad05b04286e4
--- /dev/null
+++ b/Documentation/networking/device_drivers/qlogic/index.rst
@@ -0,0 +1,18 @@
+.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+QLogic QLGE Device Drivers
+===
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   qlge
+
+.. only::  subproject and html
+
+   Indices
+   ===
+
+   * :ref:`genindex`
diff --git a/Documentation/networking/device_drivers/qlogic/qlge.rst 
b/Documentation/networking/device_drivers/qlogic/qlge.rst
new file mode 100644
index ..0b888253d152
--- /dev/null
+++ b/Documentation/networking/device_drivers/qlogic/qlge.rst
@@ -0,0 +1,118 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===
+QLogic QLGE 10Gb Ethernet device driver
+===
+
+This driver use drgn and devlink for debugging.
+
+Dump kernel data structures in drgn
+---
+
+To dump kernel data structures, the following Python script can be used
+in drgn:
+
+.. code-block:: python
+
+   def align(x, a):
+   """the alignment a should be a power of 2
+   """
+   mask = a - 1
+   return (x+ mask) & ~mask
+
+   def struct_size(struct_type):
+   struct_str = "struct {}".format(struct_type)
+   return sizeof(Object(prog, struct_str, address=0x0))
+
+   def netdev_priv(netdevice):
+   NETDEV_ALIGN = 32
+   return netdevice.value_() + align(struct_size("net_device"), 
NETDEV_ALIGN)
+
+   name = 'xxx'
+   qlge_device = None
+   netdevices = prog['init_net'].dev_base_head.address_of_()
+   for netdevice in list_for_each_entry("struct net_device", netdevices, 
"dev_list"):
+   if netdevice.name.string_().decode('ascii') == name:
+   print(netdevice.name)
+
+   ql_adapter = Object(prog, "struct ql_adapter", 
address=netdev_priv(qlge_device))
+
+The struct ql_adapter will be printed in drgn as follows,
+
+>>> ql_adapter
+(struct ql_adapter){
+.ricb = (struct ricb){
+.base_cq = (u8)0,
+.flags = (u8)120,
+.mask = (__le16)26637,
+.hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 },
+.ipv6_hash_key = (__le32 [10]){},
+.ipv4_hash_key = (__le32 [4]){},
+},
+.flags = (unsigned long)0,
+.wol = (u32)0,
+.nic_stats = (struct nic_stats){
+.tx_pkts = (u64)0,
+.tx_bytes = (u64)0,
+.tx_mcast_pkts = (u64)0,
+.tx_bcast_pkts = (u64)0,
+.tx_ucast_pkts = (u64)0,
+.tx_ctl_pkts = (u64)0,
+.tx_pause_pkts = (u64)0,
+...
+},
+.active_vlans = (unsigned long [64]){
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615,
+18446619461681283072, 0, 42949673024, 2147483647,
+},
+.rx_ring = (struct rx_ring [17]){
+{
+.cqicb = (struct cqicb){
+.msix_vect = (u8)0,
+.reserved1 = (u8)0,
+.reserved2 = (u8)0,
+.flags = (u8)0,
+.len = (__le16)0,
+.rid = (__le16)0,
+...
+},
+

[PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver

2020-10-08 Thread Coiby Xu
Initialize devlink health dump framework for the dlge driver so the
coredump could be done via devlink.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/Kconfig|  1 +
 drivers/staging/qlge/Makefile   |  2 +-
 drivers/staging/qlge/qlge.h |  9 +++
 drivers/staging/qlge/qlge_devlink.c | 38 +
 drivers/staging/qlge/qlge_devlink.h |  8 ++
 drivers/staging/qlge/qlge_main.c| 28 +
 6 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/qlge/qlge_devlink.c
 create mode 100644 drivers/staging/qlge/qlge_devlink.h

diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig
index a3cb25a3ab80..6d831ed67965 100644
--- a/drivers/staging/qlge/Kconfig
+++ b/drivers/staging/qlge/Kconfig
@@ -3,6 +3,7 @@
 config QLGE
tristate "QLogic QLGE 10Gb Ethernet Driver Support"
depends on ETHERNET && PCI
+   select NET_DEVLINK
help
This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
 
diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile
index 1dc2568e820c..07c1898a512e 100644
--- a/drivers/staging/qlge/Makefile
+++ b/drivers/staging/qlge/Makefile
@@ -5,4 +5,4 @@
 
 obj-$(CONFIG_QLGE) += qlge.o
 
-qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
+qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index b295990e361b..290e754450c5 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2060,6 +2060,14 @@ struct nic_operations {
int (*port_initialize)(struct ql_adapter *qdev);
 };
 
+
+
+struct qlge_devlink {
+struct ql_adapter *qdev;
+struct net_device *ndev;
+struct devlink_health_reporter *reporter;
+};
+
 /*
  * The main Adapter structure definition.
  * This structure has all fields relevant to the hardware.
@@ -2077,6 +2085,7 @@ struct ql_adapter {
struct pci_dev *pdev;
struct net_device *ndev;/* Parent NET device */
 
+   struct qlge_devlink *ql_devlink;
/* Hardware information */
u32 chip_rev_id;
u32 fw_rev_id;
diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
new file mode 100644
index ..aa45e7e368c0
--- /dev/null
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -0,0 +1,38 @@
+#include "qlge.h"
+#include "qlge_devlink.h"
+
+static int
+qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+   struct devlink_fmsg *fmsg, void *priv_ctx,
+   struct netlink_ext_ack *extack)
+{
+   return 0;
+}
+
+static const struct devlink_health_reporter_ops qlge_reporter_ops = {
+   .name = "dummy",
+   .dump = qlge_reporter_coredump,
+};
+
+int qlge_health_create_reporters(struct qlge_devlink *priv)
+{
+   int err;
+
+   struct devlink_health_reporter *reporter;
+   struct devlink *devlink;
+
+   devlink = priv_to_devlink(priv);
+   reporter =
+   devlink_health_reporter_create(devlink, _reporter_ops,
+  0,
+  priv);
+   if (IS_ERR(reporter)) {
+   netdev_warn(priv->ndev,
+   "Failed to create reporter, err = %ld\n",
+   PTR_ERR(reporter));
+   return PTR_ERR(reporter);
+   }
+   priv->reporter = reporter;
+
+   return err;
+}
diff --git a/drivers/staging/qlge/qlge_devlink.h 
b/drivers/staging/qlge/qlge_devlink.h
new file mode 100644
index ..c91f7a29e805
--- /dev/null
+++ b/drivers/staging/qlge/qlge_devlink.h
@@ -0,0 +1,8 @@
+#ifndef QLGE_DEVLINK_H
+#define QLGE_DEVLINK_H
+
+#include 
+
+int qlge_health_create_reporters(struct qlge_devlink *priv);
+
+#endif /* QLGE_DEVLINK_H */
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 27da386f9d87..135225530e51 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -42,6 +42,7 @@
 #include 
 
 #include "qlge.h"
+#include "qlge_devlink.h"
 
 char qlge_driver_name[] = DRV_NAME;
 const char qlge_driver_version[] = DRV_VERSION;
@@ -4549,6 +4550,8 @@ static void ql_timer(struct timer_list *t)
mod_timer(>timer, jiffies + (5 * HZ));
 }
 
+static const struct devlink_ops qlge_devlink_ops;
+
 static int qlge_probe(struct pci_dev *pdev,
  const struct pci_device_id *pci_entry)
 {
@@ -4556,6 +4559,13 @@ static int qlge_probe(struct pci_dev *pdev,
struct ql_adapter *qdev = NULL;
static int cards_found;
int err = 0;
+   struct devlink *devlink;
+   struct qlge_devlink *ql_devlink;
+
+   devlink = devlink_alloc(_devlink_ops, sizeof(struct qlge_devlink));
+   

[PATCH v1 0/6] staging: qlge: Re-writing the debugging features

2020-10-08 Thread Coiby Xu
This patch set aims to avoid dumping registers, data structures and
coredump to dmesg and also to reduce the code size of the qlge driver.

As pointed out by Benjamin [1],

> At 2000 lines, qlge_dbg.c alone is larger than some entire ethernet
> drivers. Most of what it does is dump kernel data structures or pci
> memory mapped registers to dmesg. There are better facilities for that.
> My thinking is not simply to delete qlge_dbg.c but to replace it, making
> sure that most of the same information is still available. For data
> structures, crash or drgn can be used; possibly with a script for the
> latter which formats the data. For pci registers, they should be
> included in the ethtool register dump and a patch added to ethtool to
> pretty print them. That's what other drivers like e1000e do. For the
> "coredump", devlink health can be used.

So the debugging features are re-written following Benjamin's advice,
   - dump kernel data structures in drgn
   - use devlink to do coredump which also includes device status and
 general registers

[1] https://lkml.org/lkml/2020/6/30/19

Change since RFC:
 - select NET_DEVLINK in Kconfig [Benjamin Poirier]
 - Don't do a coredump when the interface is down [Shung-Hsi Yu]
 - Remove stray newlines [Benjamin Poirier]
 - force_coredump for devlink
 - Remove mpi_core_to_log which will output the coredump to the kernel
   ring buffer
 - Put drgn script under Documentation [Benjamin Poirier]
 - Rename qlge_health.* to qlge_devlink.*

Coiby Xu (6):
  staging: qlge: Initialize devlink health dump framework for the dlge
driver
  staging: qlge: coredump via devlink health reporter
  staging: qlge: support force_coredump option for devlink health dump
  staging: qlge: remove mpi_core_to_log which sends coredump to the
kernel ring buffer
  staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land
  staging: qlge: add documentation for debugging qlge

 .../networking/device_drivers/index.rst   |   1 +
 .../device_drivers/qlogic/index.rst   |  18 +
 .../networking/device_drivers/qlogic/qlge.rst | 118 +++
 MAINTAINERS   |   6 +
 drivers/staging/qlge/Kconfig  |   1 +
 drivers/staging/qlge/Makefile |   2 +-
 drivers/staging/qlge/qlge.h   |  94 +--
 drivers/staging/qlge/qlge_dbg.c   | 699 --
 drivers/staging/qlge/qlge_devlink.c   | 164 
 drivers/staging/qlge/qlge_devlink.h   |   8 +
 drivers/staging/qlge/qlge_ethtool.c   |   3 -
 drivers/staging/qlge/qlge_main.c  |  37 +-
 drivers/staging/qlge/qlge_mpi.c   |   6 -
 13 files changed, 355 insertions(+), 802 deletions(-)
 create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst
 create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst
 create mode 100644 drivers/staging/qlge/qlge_devlink.c
 create mode 100644 drivers/staging/qlge/qlge_devlink.h

--
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v1 3/6] staging: qlge: support force_coredump option for devlink health dump

2020-10-08 Thread Coiby Xu
With force_coredump module paramter set, devlink health dump will reset
the MPI RISC first which takes 5 secs to be finished.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_devlink.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/staging/qlge/qlge_devlink.c 
b/drivers/staging/qlge/qlge_devlink.c
index 91b6600b94a9..54257468bc7f 100644
--- a/drivers/staging/qlge/qlge_devlink.c
+++ b/drivers/staging/qlge/qlge_devlink.c
@@ -56,10 +56,17 @@ static int qlge_reporter_coredump(struct 
devlink_health_reporter *reporter,
struct qlge_devlink *dev = devlink_health_reporter_priv(reporter);
struct ql_adapter *qdev = dev->qdev;
struct ql_mpi_coredump *dump;
+   wait_queue_head_t wait;
 
if (!netif_running(qdev->ndev))
return 0;
 
+   if (test_bit(QL_FRC_COREDUMP, >flags)) {
+   ql_queue_fw_error(qdev);
+   init_waitqueue_head();
+   wait_event_timeout(wait, 0, 5 * HZ);
+   }
+
dump = kvmalloc(sizeof(*dump), GFP_KERNEL);
if (!dump)
return -ENOMEM;
-- 
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v1 4/6] staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer

2020-10-08 Thread Coiby Xu
devlink health could be used to get coredump. No need to send so much
data to the kernel ring buffer.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h |  3 ---
 drivers/staging/qlge/qlge_dbg.c | 11 ---
 drivers/staging/qlge/qlge_ethtool.c |  1 -
 drivers/staging/qlge/qlge_main.c|  2 --
 drivers/staging/qlge/qlge_mpi.c |  6 --
 5 files changed, 23 deletions(-)

diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 290e754450c5..0a39801be15a 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2149,7 +2149,6 @@ struct ql_adapter {
u32 port_init;
u32 link_status;
struct ql_mpi_coredump *mpi_coredump;
-   u32 core_is_dumped;
u32 link_config;
u32 led_config;
u32 max_frame_size;
@@ -2162,7 +2161,6 @@ struct ql_adapter {
struct delayed_work mpi_work;
struct delayed_work mpi_port_cfg_work;
struct delayed_work mpi_idc_work;
-   struct delayed_work mpi_core_to_log;
struct completion ide_completion;
const struct nic_operations *nic_ops;
u16 device_id;
@@ -2253,7 +2251,6 @@ int ql_write_cfg(struct ql_adapter *qdev, void *ptr, int 
size, u32 bit,
 void ql_queue_fw_error(struct ql_adapter *qdev);
 void ql_mpi_work(struct work_struct *work);
 void ql_mpi_reset_work(struct work_struct *work);
-void ql_mpi_core_to_log(struct work_struct *work);
 int ql_wait_reg_rdy(struct ql_adapter *qdev, u32 reg, u32 bit, u32 ebit);
 void ql_queue_asic_error(struct ql_adapter *qdev);
 void ql_set_ethtool_ops(struct net_device *ndev);
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 42fd13990f3a..989575743718 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1314,17 +1314,6 @@ void ql_get_dump(struct ql_adapter *qdev, void *buff)
}
 }
 
-/* Coredump to messages log file using separate worker thread */
-void ql_mpi_core_to_log(struct work_struct *work)
-{
-   struct ql_adapter *qdev =
-   container_of(work, struct ql_adapter, mpi_core_to_log.work);
-
-   print_hex_dump(KERN_DEBUG, "Core is dumping to log file!\n",
-  DUMP_PREFIX_OFFSET, 32, 4, qdev->mpi_coredump,
-  sizeof(*qdev->mpi_coredump), false);
-}
-
 #ifdef QL_REG_DUMP
 static void ql_dump_intr_states(struct ql_adapter *qdev)
 {
diff --git a/drivers/staging/qlge/qlge_ethtool.c 
b/drivers/staging/qlge/qlge_ethtool.c
index d44b2dae9213..eed116d8895e 100644
--- a/drivers/staging/qlge/qlge_ethtool.c
+++ b/drivers/staging/qlge/qlge_ethtool.c
@@ -616,7 +616,6 @@ static void ql_get_regs(struct net_device *ndev,
struct ql_adapter *qdev = netdev_priv(ndev);
 
ql_get_dump(qdev, p);
-   qdev->core_is_dumped = 0;
if (!test_bit(QL_FRC_COREDUMP, >flags))
regs->len = sizeof(struct ql_mpi_coredump);
else
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 135225530e51..aaca740d46c4 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3808,7 +3808,6 @@ static void ql_cancel_all_work_sync(struct ql_adapter 
*qdev)
cancel_delayed_work_sync(>mpi_reset_work);
cancel_delayed_work_sync(>mpi_work);
cancel_delayed_work_sync(>mpi_idc_work);
-   cancel_delayed_work_sync(>mpi_core_to_log);
cancel_delayed_work_sync(>mpi_port_cfg_work);
 }
 
@@ -4504,7 +4503,6 @@ static int ql_init_device(struct pci_dev *pdev, struct 
net_device *ndev,
INIT_DELAYED_WORK(>mpi_work, ql_mpi_work);
INIT_DELAYED_WORK(>mpi_port_cfg_work, ql_mpi_port_cfg_work);
INIT_DELAYED_WORK(>mpi_idc_work, ql_mpi_idc_work);
-   INIT_DELAYED_WORK(>mpi_core_to_log, ql_mpi_core_to_log);
init_completion(>ide_completion);
mutex_init(>mpi_mutex);
 
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index 143a886080c5..1cea24201b17 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -1269,11 +1269,5 @@ void ql_mpi_reset_work(struct work_struct *work)
return;
}
 
-   if (qdev->mpi_coredump && !ql_core_dump(qdev, qdev->mpi_coredump)) {
-   netif_err(qdev, drv, qdev->ndev, "Core is dumped!\n");
-   qdev->core_is_dumped = 1;
-   queue_delayed_work(qdev->workqueue,
-  >mpi_core_to_log, 5 * HZ);
-   }
ql_soft_reset_mpi_risc(qdev);
 }
-- 
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 1/3] staging: greybus: fix warnings about endianness detected by sparse

2020-10-05 Thread Coiby Xu

On Tue, Oct 06, 2020 at 12:47:37AM +0530, Vaibhav Agarwal wrote:

On Sat, Oct 3, 2020 at 5:01 AM Coiby Xu  wrote:


This patch fix the following warnings from sparse,

$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 
[usertype] data_cport
drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] 
intf_cport_id
drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:691:41:expected unsigned int access
drivers/staging/greybus/audio_topology.c:691:41:got restricted __le32 
[usertype] access
drivers/staging/greybus/audio_topology.c:746:44: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:746:44:expected unsigned int
drivers/staging/greybus/audio_topology.c:746:44:got restricted __le32
drivers/staging/greybus/audio_topology.c:748:52: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:748:52:expected unsigned int
drivers/staging/greybus/audio_topology.c:748:52:got restricted __le32
drivers/staging/greybus/audio_topology.c:802:42: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:805:50: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:805:50:expected restricted __le32
drivers/staging/greybus/audio_topology.c:805:50:got unsigned int
drivers/staging/greybus/audio_topology.c:814:50: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:817:58: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:817:58:expected restricted __le32
drivers/staging/greybus/audio_topology.c:817:58:got unsigned int
drivers/staging/greybus/audio_topology.c:889:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:889:25:expected unsigned int access
drivers/staging/greybus/audio_topology.c:889:25:got restricted __le32 
[usertype] access

Suggested-by: Dan Carpenter 
Reviewed-by: Dan Carpenter 
Reviewed-by: Alex Elder 
Signed-off-by: Coiby Xu 
---

Hi Coiby,

Thanks for sharing the patch. Sorry, I could not reply to the v1 series.
Now, I have gone through the patches. Looks good (all 3 patches).

Reviewed-by: Vaibhav Agarwal 

--
Thanks,


Hi Vaibhav,

Thank you for reviewing these patches and giving the credit!

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [RFC 1/3] Initialize devlink health dump framework for the dlge driver

2020-10-04 Thread Coiby Xu

On Fri, Aug 21, 2020 at 11:08:22AM +0800, Coiby Xu wrote:

On Sun, Aug 16, 2020 at 11:56:40AM +0900, Benjamin Poirier wrote:

On 2020-08-15 00:05 +0800, Coiby Xu wrote:

Initialize devlink health dump framework for the dlge driver so the
coredump could be done via devlink.

Signed-off-by: Coiby Xu 
---
drivers/staging/qlge/Makefile  |  2 +-
drivers/staging/qlge/qlge.h|  9 +++
drivers/staging/qlge/qlge_health.c | 43 ++
drivers/staging/qlge/qlge_health.h |  2 ++
drivers/staging/qlge/qlge_main.c   | 21 +++
5 files changed, 76 insertions(+), 1 deletion(-)
create mode 100644 drivers/staging/qlge/qlge_health.c
create mode 100644 drivers/staging/qlge/qlge_health.h

diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile
index 1dc2568e820c..0a1e4c8dd546 100644
--- a/drivers/staging/qlge/Makefile
+++ b/drivers/staging/qlge/Makefile
@@ -5,4 +5,4 @@

obj-$(CONFIG_QLGE) += qlge.o

-qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
+qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_health.o
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index fc8c5ca8935d..055ded6dab60 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2061,6 +2061,14 @@ struct nic_operations {
int (*port_initialize) (struct ql_adapter *);
};



This patch doesn't apply over the latest staging tree. I think your tree
is missing commit d923bb6bf508 ("staging: qlge: qlge.h: Function
definition arguments should have names.")


Thank you for applying the patch to test it! I had incorrect
understanding about the word "RFC" and didn't do a rebase onto
the latest staging tree.




+
+
+struct qlge_devlink {
+struct ql_adapter *qdev;
+struct net_device *ndev;


I don't have experience implementing devlink callbacks but looking at
some other devlink users (mlx4, ionic, ice), all of them use devlink
priv space for their main private structure. That would be struct
ql_adapter in this case. Is there a good reason to stray from that
pattern?


+struct devlink_health_reporter *reporter;
+};
+
/*
 * The main Adapter structure definition.
 * This structure has all fields relevant to the hardware.
@@ -2078,6 +2086,7 @@ struct ql_adapter {
struct pci_dev *pdev;
struct net_device *ndev;/* Parent NET device */

+   struct qlge_devlink *devlink;
/* Hardware information */
u32 chip_rev_id;
u32 fw_rev_id;
diff --git a/drivers/staging/qlge/qlge_health.c 
b/drivers/staging/qlge/qlge_health.c
new file mode 100644
index ..292f6b1827e1
--- /dev/null
+++ b/drivers/staging/qlge/qlge_health.c
@@ -0,0 +1,43 @@
+#include "qlge.h"
+#include "qlge_health.h"
+
+static int
+qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+   struct devlink_fmsg *fmsg, void *priv_ctx,
+   struct netlink_ext_ack *extack)
+{
+   return 0;
+}
+
+static const struct devlink_health_reporter_ops qlge_reporter_ops = {
+   .name = "dummy",
+   .dump = qlge_reporter_coredump,
+};


I think
select NET_DEVLINK
should be added to drivers/staging/qlge/Kconfig


Thank you for reminding me!




+
+int qlge_health_create_reporters(struct qlge_devlink *priv)
+{
+   int err;
+
+   struct devlink_health_reporter *reporter;
+   struct devlink *devlink;
+
+   devlink = priv_to_devlink(priv);
+   reporter =
+   devlink_health_reporter_create(devlink, _reporter_ops,
+  0,
+  priv);
+   if (IS_ERR(reporter)) {
+   netdev_warn(priv->ndev,
+   "Failed to create reporter, err = %ld\n",
+   PTR_ERR(reporter));
+   return PTR_ERR(reporter);
+   }
+   priv->reporter = reporter;
+
+   if (err)
+   return err;
+
+   return 0;
+}
+
+


Stray newlines


Will fix it in v1.




diff --git a/drivers/staging/qlge/qlge_health.h 
b/drivers/staging/qlge/qlge_health.h
new file mode 100644
index ..07d3bafab845
--- /dev/null
+++ b/drivers/staging/qlge/qlge_health.h
@@ -0,0 +1,2 @@
+#include 
+int qlge_health_create_reporters(struct qlge_devlink *priv);


I would suggest to put this in qlge.h instead of creating a new file.


Although there are only two lines for now, is it possible qlge will add
more devlink code? If that's the case, a file to single out these code
is necessary as is the same to some other drivers,

   $ find drivers -name *health*.h
   drivers/net/ethernet/mellanox/mlx5/core/en/health.h

   $ find drivers -name *devlink*.h
   drivers/net/ethernet/huawei/hinic/hinic_devlink.h
   drivers/net/ethernet/mellanox/mlx5/core/devlink.h
   drivers/net/ethernet/mellanox/mlx5/core/en/devlink.h
   dr

Re: [PATCH v4] staging: qlge: fix build breakage with dumping enabled

2020-10-04 Thread Coiby Xu

On Sat, Oct 03, 2020 at 02:53:48PM +0900, Benjamin Poirier wrote:

On 2020-10-03 07:59 +0800, Coiby Xu wrote:

This fixes commit 0107635e15ac
("staging: qlge: replace pr_err with netdev_err") which introduced an
build breakage of missing `struct ql_adapter *qdev` for some functions
and a warning of type mismatch with dumping enabled, i.e.,

$ make CFLAGS_MODULE="-DQL_ALL_DUMP -DQL_OB_DUMP -DQL_CB_DUMP \
-DQL_IB_DUMP -DQL_REG_DUMP -DQL_DEV_DUMP" M=drivers/staging/qlge

qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’:
qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did 
you mean ‘cdev’?
 2051 |  netdev_err(qdev->ndev, "%s\n", __func__);
  | ^~~~
qlge_dbg.c: In function ‘ql_dump_routing_entries’:
qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but 
argument 3 has type ‘int’ [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ~^
  |  |
  |  char *
  | %d
 1436 |i, value);
  |~
  ||
  |int
qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ 
argument [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ^
  | |
  | unsigned int

Note that now ql_dump_rx_ring/ql_dump_tx_ring won't check if the passed
parameter is a null pointer.

Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err")
Reported-by: Benjamin Poirier 
Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---


Reviewed-by: Benjamin Poirier 


Thank you! Btw, I guess when this patch is picked, the "Reviewed-by" tag
will also be included. So I needn't to send another patch, am I right?

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4] staging: qlge: fix build breakage with dumping enabled

2020-10-02 Thread Coiby Xu
This fixes commit 0107635e15ac
("staging: qlge: replace pr_err with netdev_err") which introduced an
build breakage of missing `struct ql_adapter *qdev` for some functions
and a warning of type mismatch with dumping enabled, i.e.,

$ make CFLAGS_MODULE="-DQL_ALL_DUMP -DQL_OB_DUMP -DQL_CB_DUMP \
-DQL_IB_DUMP -DQL_REG_DUMP -DQL_DEV_DUMP" M=drivers/staging/qlge

qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’:
qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did 
you mean ‘cdev’?
 2051 |  netdev_err(qdev->ndev, "%s\n", __func__);
  | ^~~~
qlge_dbg.c: In function ‘ql_dump_routing_entries’:
qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but 
argument 3 has type ‘int’ [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ~^
  |  |
  |  char *
  | %d
 1436 |i, value);
  |~
  ||
  |int
qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ 
argument [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ^
  | |
  | unsigned int

Note that now ql_dump_rx_ring/ql_dump_tx_ring won't check if the passed
parameter is a null pointer.

Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err")
Reported-by: Benjamin Poirier 
Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h  | 20 ++--
 drivers/staging/qlge/qlge_dbg.c  | 28 ++--
 drivers/staging/qlge/qlge_main.c |  8 
 3 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 48f346503979..b295990e361b 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2337,21 +2337,21 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, 
u32 bit, u16 q_id);
 #endif

 #ifdef QL_OB_DUMP
-void ql_dump_tx_desc(struct tx_buf_desc *tbd);
-void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb);
-void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp);
-#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp)
+void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd);
+void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req 
*ob_mac_iocb);
+void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp 
*ob_mac_rsp);
+#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, 
ob_mac_iocb)
+#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, 
ob_mac_rsp)
 #else
-#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp)
+#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb)
+#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp)
 #endif

 #ifdef QL_IB_DUMP
-void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp);
-#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp)
+void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp 
*ib_mac_rsp);
+#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) ql_dump_ib_mac_rsp(qdev, 
ib_mac_rsp)
 #else
-#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp)
+#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp)
 #endif

 #ifdef QL_ALL_DUMP
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index a55bf0b3e9dc..42fd13990f3a 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1431,7 +1431,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
}
if (value)
netdev_err(qdev->ndev,
-  "%s: Routing Mask %d = 0x%.08x\n",
+  "Routing Mask %d = 0x%.08x\n",
   i, value);
}
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
@@ -1617,6 +1617,9 @@ void ql_dump_qdev(struct ql_adapter *qdev)
 #ifdef QL_CB_DUMP
 void ql_dump_wqicb(struct wqicb *wqicb)
 {
+   struct tx_ring *tx_ring = container_of(wqicb, struct tx_ring, wqicb);
+   struct ql_adapter *qdev = tx_ring->qdev;
+
netdev_err(qdev->ndev, "Dumping wqicb stuff...\n");
netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len));
netdev_err(qdev->ndev, "wqicb->flags = %x\n",
@@ -1632,8 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb)

 void ql_dump_tx_ring(struct tx_ring *tx_ring)
 {
-   if (!tx_ring)
-   return;
+   struct ql_adapter *qdev = tx_ring->qdev;
+
netdev_err(qdev->ndev, "= Dumping tx_ring %d 
===\n",
   tx_ring->wq_id);

[PATCH v2 1/3] staging: greybus: fix warnings about endianness detected by sparse

2020-10-02 Thread Coiby Xu
This patch fix the following warnings from sparse,

$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 
[usertype] data_cport
drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] 
intf_cport_id
drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:691:41:expected unsigned int access
drivers/staging/greybus/audio_topology.c:691:41:got restricted __le32 
[usertype] access
drivers/staging/greybus/audio_topology.c:746:44: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:746:44:expected unsigned int
drivers/staging/greybus/audio_topology.c:746:44:got restricted __le32
drivers/staging/greybus/audio_topology.c:748:52: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:748:52:expected unsigned int
drivers/staging/greybus/audio_topology.c:748:52:got restricted __le32
drivers/staging/greybus/audio_topology.c:802:42: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:805:50: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:805:50:expected restricted __le32
drivers/staging/greybus/audio_topology.c:805:50:got unsigned int
drivers/staging/greybus/audio_topology.c:814:50: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:817:58: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:817:58:expected restricted __le32
drivers/staging/greybus/audio_topology.c:817:58:got unsigned int
drivers/staging/greybus/audio_topology.c:889:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:889:25:expected unsigned int access
drivers/staging/greybus/audio_topology.c:889:25:got restricted __le32 
[usertype] access

Suggested-by: Dan Carpenter 
Reviewed-by: Dan Carpenter 
Reviewed-by: Alex Elder 
Signed-off-by: Coiby Xu 
---
 drivers/staging/greybus/audio_module.c   |  6 +++---
 drivers/staging/greybus/audio_topology.c | 18 +-
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/greybus/audio_module.c 
b/drivers/staging/greybus/audio_module.c
index 16f60256adb2..c52c4f361b90 100644
--- a/drivers/staging/greybus/audio_module.c
+++ b/drivers/staging/greybus/audio_module.c
@@ -219,7 +219,7 @@ static int gb_audio_add_data_connection(struct 
gbaudio_module_info *gbmodule,
 
greybus_set_drvdata(bundle, gbmodule);
dai->id = 0;
-   dai->data_cport = connection->intf_cport_id;
+   dai->data_cport = cpu_to_le16(connection->intf_cport_id);
dai->connection = connection;
list_add(>list, >data_list);
 
@@ -329,7 +329,7 @@ static int gb_audio_probe(struct gb_bundle *bundle,
if (ret) {
dev_err(dev,
"%d:Error while enabling %d:data connection\n",
-   ret, dai->data_cport);
+   ret, le16_to_cpu(dai->data_cport));
goto disable_data_connection;
}
}
@@ -451,7 +451,7 @@ static int gb_audio_resume(struct device *dev)
if (ret) {
dev_err(dev,
"%d:Error while enabling %d:data connection\n",
-   ret, dai->data_cport);
+   ret, le16_to_cpu(dai->data_cport));
return ret;
}
}
diff --git a/drivers/staging/greybus/audio_topology.c 
b/drivers/staging/greybus/audio_topology.c
index 83b38ae8908c..2091031659de 100644
--- a/drivers/staging/greybus/audio_topology.c
+++ b/drivers/staging/greybus/audio_topology.c
@@ -466,7 +466,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol 
*kcontrol,
goto exit;
 
/* update ucontrol */
-   if (gbvalue.value.integer_value[0] != val) {
+   if (le32_to_cpu(gbvalue.value.integer_value[0]) != val) {
for (wi = 0; wi < wlist->num_widgets; wi++) {
widget = wlist->widgets[wi];
snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol,
@@ -689,7 +689,7 @@ static int gbaudio_tplg_create_kcontrol(struct 
gbaudio_module_info *gb,
return -ENOMEM;
ctldata->ctl_id = ctl->id;
ctldata->data_cport = le16_t

[PATCH v2 2/3] staging: greybus: codecs: use SNDRV_PCM_FMTBIT_S16_LE for format bitmask

2020-10-02 Thread Coiby Xu
snd_soc_pcm_stream.formats should use the bitmask SNDRV_PCM_FMTBIT_*
instead of the sequential integers SNDRV_PCM_FORMAT_* as explained by
commit e712bfca1ac1f63f622f87c2f33b57608f2a4d19
("ASoC: codecs: use SNDRV_PCM_FMTBIT_* for format bitmask").

Found by sparse,

$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_codec.c:691:36: warning: incorrect type in 
initializer (different base types)
drivers/staging/greybus/audio_codec.c:691:36:expected unsigned long long 
[usertype] formats
drivers/staging/greybus/audio_codec.c:691:36:got restricted 
snd_pcm_format_t [usertype]
drivers/staging/greybus/audio_codec.c:701:36: warning: incorrect type in 
initializer (different base types)
drivers/staging/greybus/audio_codec.c:701:36:expected unsigned long long 
[usertype] formats
drivers/staging/greybus/audio_codec.c:701:36:got restricted 
snd_pcm_format_t [usertype]

Reviewed-by: Alex Elder 
Signed-off-by: Coiby Xu 
---
 drivers/staging/greybus/audio_codec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/greybus/audio_codec.c 
b/drivers/staging/greybus/audio_codec.c
index 74538f8c5fa4..494aa823e998 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -688,7 +688,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
.playback = {
.stream_name = "I2S 0 Playback",
.rates = SNDRV_PCM_RATE_48000,
-   .formats = SNDRV_PCM_FORMAT_S16_LE,
+   .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_max = 48000,
.rate_min = 48000,
.channels_min = 1,
@@ -698,7 +698,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
.capture = {
.stream_name = "I2S 0 Capture",
.rates = SNDRV_PCM_RATE_48000,
-   .formats = SNDRV_PCM_FORMAT_S16_LE,
+   .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_max = 48000,
.rate_min = 48000,
.channels_min = 1,
-- 
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 3/3] staging: greybus: use __force when assigning __u8 value to snd_ctl_elem_type_t

2020-10-02 Thread Coiby Xu
(struct gb_audio_ctl_elem_info*)->type has the type of __u8 so there is no
concern about the byte order. __force is safe to use.

Found by sparse,

$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_topology.c:185:24: warning: cast to restricted 
snd_ctl_elem_type_t

Suggested-by: Alex Elder 
Signed-off-by: Coiby Xu 
---
 drivers/staging/greybus/audio_topology.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/greybus/audio_topology.c 
b/drivers/staging/greybus/audio_topology.c
index 2091031659de..662e3e8b4b63 100644
--- a/drivers/staging/greybus/audio_topology.c
+++ b/drivers/staging/greybus/audio_topology.c
@@ -182,7 +182,7 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol 
*kcontrol,
/* update uinfo */
uinfo->access = data->access;
uinfo->count = data->vcount;
-   uinfo->type = (snd_ctl_elem_type_t)info->type;
+   uinfo->type = (__force snd_ctl_elem_type_t)info->type;
 
switch (info->type) {
case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
-- 
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 3/3] [PATCH] staging: greybus: __u8 is sufficient for snd_ctl_elem_type_t and snd_ctl_elem_iface_t

2020-09-25 Thread Coiby Xu

On Fri, Sep 25, 2020 at 10:57:27AM -0500, Alex Elder wrote:

On 9/25/20 9:07 AM, Coiby Xu wrote:

On Thu, Sep 24, 2020 at 01:00:57PM +0200, Greg Kroah-Hartman wrote:

On Thu, Sep 24, 2020 at 06:20:39PM +0800, Coiby Xu wrote:

Use __8 to replace int and remove the unnecessary __bitwise type
attribute.

Found by sparse,


. . .


diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index 535a7229e1d9..8e71a95644ab 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -950,7 +950,7 @@ struct snd_ctl_card_info {
 unsigned char components[128];    /* card components / fine
identification, delimited with one space (AC97 etc..) */
 };

-typedef int __bitwise snd_ctl_elem_type_t;
+typedef __u8 snd_ctl_elem_type_t;
 #define    SNDRV_CTL_ELEM_TYPE_NONE    ((__force
snd_ctl_elem_type_t) 0) /* invalid */
 #define    SNDRV_CTL_ELEM_TYPE_BOOLEAN    ((__force
snd_ctl_elem_type_t) 1) /* boolean type */
 #define    SNDRV_CTL_ELEM_TYPE_INTEGER    ((__force
snd_ctl_elem_type_t) 2) /* integer type */
@@ -960,7 +960,7 @@ typedef int __bitwise snd_ctl_elem_type_t;
 #define    SNDRV_CTL_ELEM_TYPE_INTEGER64    ((__force
snd_ctl_elem_type_t) 6) /* 64-bit integer type */
 #define    SNDRV_CTL_ELEM_TYPE_LAST    SNDRV_CTL_ELEM_TYPE_INTEGER64

-typedef int __bitwise snd_ctl_elem_iface_t;
+typedef __u8 snd_ctl_elem_iface_t;
 #define    SNDRV_CTL_ELEM_IFACE_CARD    ((__force
snd_ctl_elem_iface_t) 0) /* global control */
 #define    SNDRV_CTL_ELEM_IFACE_HWDEP    ((__force
snd_ctl_elem_iface_t) 1) /* hardware dependent device */
 #define    SNDRV_CTL_ELEM_IFACE_MIXER    ((__force
snd_ctl_elem_iface_t) 2) /* virtual mixer device */


I can't take a uapi sound header file patch along with a driver change,
these need to be independant.


Thank you and Alex for reminding me this is a change of public header!


And this is a userspace api, you just changed the size of an externally
facing variable, are you _SURE_ that is ok to do?


The reasons I make this change are, 1) using int to represent 7 enumeration
values seems to be overkill; 2) using one type could avoid worries
about byte order.


(1) might be a valid suggestion, but the file you suggest
changing is part of the Linux user space API, which you
basically can't change.

I'm fairly certain the user space API is defined to have
CPU-local byte order (unless specified explicitly otherwise)
so that is not a concern.


Thank you for sharing me about the byte order of user space API which
prompts me to examine where "info->type" comes from,

uinfo->type = (snd_ctl_elem_type_t)info->type;

Eventually it comes from the parsed topology data which is obtained via
gb_audio_gb_get_topology(gbmodule->mgmt_connection, ). But
since (struct gb_audio_ctl_elem_info*)->type has __u8 type, there is no
endianness concern. Then based on the principles of userspace API
shouldn't be modified and greybus is operating system independent, your
previous suggestion to use __force which means "I know what I'm doing"
is actually a good idea,

uinfo->type = (__force snd_ctl_elem_type_t)info->type;



I examine one userspace example (libalsa-intf/alsa_mixer.c [1]). This
change won't cause compiling breakage. But I don't the experience to
imagine any other bad consequence.


As a rule, once the user space API has been established, it
stays with us forever.  You can add to it, but modifying
(or removing) an existing interface is essentially forbidden.


Another way to avoid userspace API change is to let
"struct gb_audio_ctl_elem_info" use snd_ctl_elem_iface_t type which may
be more elegant than using "__force" as suggested by Alex,


The Greybus definitions were explicitly defined to be
operating system independent.  For that reason there are
(admittedly cumbersome) definitions of certain types and
values that essentially mimic those defined by Linux
exactly  That way Linux (or another system using Greybus)
can change its internal values without changing the
Greybus API definition.  (This addresses the concern you
mention below.)

What you are suggesting is not consistent with that
principle.

-Alex



$ git diff
diff --git a/include/linux/greybus/greybus_protocols.h
b/include/linux/greybus/greybus_protocols.h
index aeb8f9243545..7f6753ec7ef7 100644
--- a/include/linux/greybus/greybus_protocols.h
+++ b/include/linux/greybus/greybus_protocols.h
@@ -8,6 +8,7 @@
 #define __GREYBUS_PROTOCOLS_H

 #include 
+#include 

 /* Fixed IDs for control/svc protocols */

@@ -1997,7 +1998,7 @@ struct gb_audio_enumerated {
 } __packed;

 struct gb_audio_ctl_elem_info { /* See snd_ctl_elem_info in Linux
source */
-   __u8    type;   /* GB_AUDIO_CTL_ELEM_TYPE_* */
+   snd_ctl_elem_type_t type;   /*
GB_AUDIO_CTL_ELEM_TYPE_* */
    __le16  dimen[4];
    union {
    struct gb_audio_integer integer


Re: [greybus-dev] [PATCH 3/3] [PATCH] staging: greybus: __u8 is sufficient for snd_ctl_elem_type_t and snd_ctl_elem_iface_t

2020-09-25 Thread Coiby Xu

On Fri, Sep 25, 2020 at 11:02:23AM -0500, Alex Elder wrote:

On 9/25/20 9:11 AM, Coiby Xu wrote:

On Thu, Sep 24, 2020 at 10:54:50AM +, David Laight wrote:

From: Coiby Xu

Sent: 24 September 2020 11:21
Use __8 to replace int and remove the unnecessary __bitwise type
attribute.

Found by sparse,

...

diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index 535a7229e1d9..8e71a95644ab 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -950,7 +950,7 @@ struct snd_ctl_card_info {
 unsigned char components[128];    /* card components / fine
identification, delimited with one
space (AC97 etc..) */
 };

-typedef int __bitwise snd_ctl_elem_type_t;
+typedef __u8 snd_ctl_elem_type_t;
 #define    SNDRV_CTL_ELEM_TYPE_NONE    ((__force
snd_ctl_elem_type_t) 0) /* invalid */
 #define    SNDRV_CTL_ELEM_TYPE_BOOLEAN    ((__force
snd_ctl_elem_type_t) 1) /* boolean type */
 #define    SNDRV_CTL_ELEM_TYPE_INTEGER    ((__force
snd_ctl_elem_type_t) 2) /* integer type */


WTF is all that about anyway??
What is wrong with:
#define    SNDRV_CTL_ELEM_TYPE_NONE    0u /* invalid */


I'm sorry I don't quite understand you. Are you suggesting
SNDRV_CTL_ELEM_TYPE_NONE
isn't needed in the first place?


I think David is asking why it's defined the way it is,
and I'd guess it's to have the compiler issue an error
if you attempt to assign one of these values to a variable
or field of the wrong type.

No, you should not attempt to change this.


Thank you for the explanation!



-Alex

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton
Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



--
Best regards,
Coiby
___
greybus-dev mailing list
greybus-...@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/greybus-dev




--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 3/3] [PATCH] staging: greybus: __u8 is sufficient for snd_ctl_elem_type_t and snd_ctl_elem_iface_t

2020-09-25 Thread Coiby Xu

On Thu, Sep 24, 2020 at 10:54:50AM +, David Laight wrote:

From: Coiby Xu

Sent: 24 September 2020 11:21
Use __8 to replace int and remove the unnecessary __bitwise type attribute.

Found by sparse,

...

diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index 535a7229e1d9..8e71a95644ab 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -950,7 +950,7 @@ struct snd_ctl_card_info {
unsigned char components[128];  /* card components / fine 
identification, delimited with one
space (AC97 etc..) */
 };

-typedef int __bitwise snd_ctl_elem_type_t;
+typedef __u8 snd_ctl_elem_type_t;
 #defineSNDRV_CTL_ELEM_TYPE_NONE((__force snd_ctl_elem_type_t) 
0) /* invalid */
 #defineSNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 
1) /* boolean type */
 #defineSNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 
2) /* integer type */


WTF is all that about anyway??
What is wrong with:
#define SNDRV_CTL_ELEM_TYPE_NONE0u /* invalid */


I'm sorry I don't quite understand you. Are you suggesting 
SNDRV_CTL_ELEM_TYPE_NONE
isn't needed in the first place?


David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [greybus-dev] [PATCH 1/3] [PATCH] staging: greybus: fix warnings about endianness detected by sparse

2020-09-25 Thread Coiby Xu

On Thu, Sep 24, 2020 at 07:50:57AM -0500, Alex Elder wrote:

On 9/24/20 5:20 AM, Coiby Xu wrote:

This patch fix the following warnings from sparse,


You need to address Greg's comment.

But in general this looks good.  I have one comment below, which
you can address in v2.  If you (or others) disagree with it, I'm
fine with your code as-is.  Either way, you can add this:

Reviewed-by: Alex Elder 


Thank you fore reviewing this patch!




$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 
[usertype] data_cport
drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] 
intf_cport_id
drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in 
assignment (different base types)


. . .


diff --git a/drivers/staging/greybus/audio_topology.c 
b/drivers/staging/greybus/audio_topology.c
index 83b38ae8908c..56bf1a4f95ad 100644
--- a/drivers/staging/greybus/audio_topology.c
+++ b/drivers/staging/greybus/audio_topology.c
@@ -466,7 +466,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol 
*kcontrol,
goto exit;

/* update ucontrol */
-   if (gbvalue.value.integer_value[0] != val) {
+   if (gbvalue.value.integer_value[0] != cpu_to_le32(val)) {


It's equivalent, but I have a small preference to convert
the value from gbvalue into CPU byte order rather than
what you have here.


Thank you for the suggestion! I'll use CPU byte order when submitting
next version.



for (wi = 0; wi < wlist->num_widgets; wi++) {
widget = wlist->widgets[wi];
snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol,
@@ -689,7 +689,7 @@ static int gbaudio_tplg_create_kcontrol(struct 
gbaudio_module_info *gb,
return -ENOMEM;
ctldata->ctl_id = ctl->id;
ctldata->data_cport = le16_to_cpu(ctl->data_cport);
-   ctldata->access = ctl->access;
+   ctldata->access = le32_to_cpu(ctl->access);
ctldata->vcount = ctl->count_values;
ctldata->info = >info;
*kctl = (struct snd_kcontrol_new)
@@ -744,10 +744,10 @@ static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol 
*kcontrol,
return ret;
}

-   ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0];
+   ucontrol->value.enumerated.item[0] = 
le32_to_cpu(gbvalue.value.enumerated_item[0]);
if (e->shift_l != e->shift_r)
ucontrol->value.enumerated.item[1] =
-   gbvalue.value.enumerated_item[1];
+   le32_to_cpu(gbvalue.value.enumerated_item[1]);

return 0;
 }
@@ -801,10 +801,10 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol 
*kcontrol,
mask = e->mask << e->shift_l;

if (gbvalue.value.enumerated_item[0] !=
-   ucontrol->value.enumerated.item[0]) {
+   cpu_to_le32(ucontrol->value.enumerated.item[0])) {
change = 1;
gbvalue.value.enumerated_item[0] =
-   ucontrol->value.enumerated.item[0];
+   cpu_to_le32(ucontrol->value.enumerated.item[0]);
}

if (e->shift_l != e->shift_r) {
@@ -813,10 +813,10 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol 
*kcontrol,
val |= ucontrol->value.enumerated.item[1] << e->shift_r;
mask |= e->mask << e->shift_r;
if (gbvalue.value.enumerated_item[1] !=
-   ucontrol->value.enumerated.item[1]) {
+   cpu_to_le32(ucontrol->value.enumerated.item[1])) {
change = 1;
gbvalue.value.enumerated_item[1] =
-   ucontrol->value.enumerated.item[1];
+   cpu_to_le32(ucontrol->value.enumerated.item[1]);
}
}

@@ -887,7 +887,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct 
gbaudio_module_info *gb,
return -ENOMEM;
ctldata->ctl_id = ctl->id;
ctldata->data_cport = le16_to_cpu(ctl->data_cport);
-   ctldata->access = ctl->access;
+   ctldata->access = le32_to_cpu(ctl->access);
ctldata->vcount = ctl->count_values;
ctldata->info = >info;
*kctl = (struct snd_kcontrol_new)





--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 3/3] [PATCH] staging: greybus: __u8 is sufficient for snd_ctl_elem_type_t and snd_ctl_elem_iface_t

2020-09-25 Thread Coiby Xu

On Thu, Sep 24, 2020 at 01:00:57PM +0200, Greg Kroah-Hartman wrote:

On Thu, Sep 24, 2020 at 06:20:39PM +0800, Coiby Xu wrote:

Use __8 to replace int and remove the unnecessary __bitwise type attribute.

Found by sparse,

$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_topology.c:185:24: warning: cast to restricted 
snd_ctl_elem_type_t
drivers/staging/greybus/audio_topology.c:679:14: warning: restricted 
snd_ctl_elem_iface_t degrades to integer
drivers/staging/greybus/audio_topology.c:906:14: warning: restricted 
snd_ctl_elem_iface_t degrades to integer

Signed-off-by: Coiby Xu 
---
 drivers/staging/greybus/audio_topology.c | 2 +-
 include/uapi/sound/asound.h  | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/greybus/audio_topology.c 
b/drivers/staging/greybus/audio_topology.c
index 56bf1a4f95ad..f6023ff390c2 100644
--- a/drivers/staging/greybus/audio_topology.c
+++ b/drivers/staging/greybus/audio_topology.c
@@ -182,7 +182,7 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol 
*kcontrol,
/* update uinfo */
uinfo->access = data->access;
uinfo->count = data->vcount;
-   uinfo->type = (snd_ctl_elem_type_t)info->type;
+   uinfo->type = info->type;

switch (info->type) {
case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index 535a7229e1d9..8e71a95644ab 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -950,7 +950,7 @@ struct snd_ctl_card_info {
unsigned char components[128];  /* card components / fine 
identification, delimited with one space (AC97 etc..) */
 };

-typedef int __bitwise snd_ctl_elem_type_t;
+typedef __u8 snd_ctl_elem_type_t;
 #defineSNDRV_CTL_ELEM_TYPE_NONE((__force snd_ctl_elem_type_t) 
0) /* invalid */
 #defineSNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 
1) /* boolean type */
 #defineSNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 
2) /* integer type */
@@ -960,7 +960,7 @@ typedef int __bitwise snd_ctl_elem_type_t;
 #defineSNDRV_CTL_ELEM_TYPE_INTEGER64   ((__force snd_ctl_elem_type_t) 
6) /* 64-bit integer type */
 #defineSNDRV_CTL_ELEM_TYPE_LASTSNDRV_CTL_ELEM_TYPE_INTEGER64

-typedef int __bitwise snd_ctl_elem_iface_t;
+typedef __u8 snd_ctl_elem_iface_t;
 #defineSNDRV_CTL_ELEM_IFACE_CARD   ((__force snd_ctl_elem_iface_t) 
0) /* global control */
 #defineSNDRV_CTL_ELEM_IFACE_HWDEP  ((__force snd_ctl_elem_iface_t) 
1) /* hardware dependent device */
 #defineSNDRV_CTL_ELEM_IFACE_MIXER  ((__force snd_ctl_elem_iface_t) 
2) /* virtual mixer device */


I can't take a uapi sound header file patch along with a driver change,
these need to be independant.


Thank you and Alex for reminding me this is a change of public header!


And this is a userspace api, you just changed the size of an externally
facing variable, are you _SURE_ that is ok to do?


The reasons I make this change are, 1) using int to represent 7 enumeration
values seems to be overkill; 2) using one type could avoid worries
about byte order.

I examine one userspace example (libalsa-intf/alsa_mixer.c [1]). This
change won't cause compiling breakage. But I don't the experience to
imagine any other bad consequence.

Another way to avoid userspace API change is to let
"struct gb_audio_ctl_elem_info" use snd_ctl_elem_iface_t type which may
be more elegant than using "__force" as suggested by Alex,

$ git diff
diff --git a/include/linux/greybus/greybus_protocols.h 
b/include/linux/greybus/greybus_protocols.h
index aeb8f9243545..7f6753ec7ef7 100644
--- a/include/linux/greybus/greybus_protocols.h
+++ b/include/linux/greybus/greybus_protocols.h
@@ -8,6 +8,7 @@
 #define __GREYBUS_PROTOCOLS_H

 #include 
+#include 

 /* Fixed IDs for control/svc protocols */

@@ -1997,7 +1998,7 @@ struct gb_audio_enumerated {
 } __packed;

 struct gb_audio_ctl_elem_info { /* See snd_ctl_elem_info in Linux source */
-   __u8type;   /* GB_AUDIO_CTL_ELEM_TYPE_* */
+   snd_ctl_elem_type_t type;   /* 
GB_AUDIO_CTL_ELEM_TYPE_* */
__le16  dimen[4];
union {
struct gb_audio_integer integer

My only concern is if greybus authors have any special reason to not include
sound/asound.h in the first place and re-define things like 
SNDRV_CTL_ELEM_TYPE_*,

/* See SNDRV_CTL_ELEM_TYPE_* in Linux source */
#define GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN  0x01
#define GB_AUDIO_CTL_ELEM_TYPE_INTEGER  0x02

/* See SNDRV_CTL_ELEM_IFACE_* in Linux source */
#define GB_AUDIO_CTL_ELEM_IFACE_CARD0x00
...

/* SNDRV_CTL_ELEM_ACCESS_* in Linux source */
#define GB_AUDIO_ACCESS_READBIT(0)
...

[1] 
https://gitlab.com/Codeaurora/platform_hardware_qcom_audio/-/blob/aee603

[PATCH 3/3] [PATCH] staging: greybus: __u8 is sufficient for snd_ctl_elem_type_t and snd_ctl_elem_iface_t

2020-09-24 Thread Coiby Xu
Use __8 to replace int and remove the unnecessary __bitwise type attribute.

Found by sparse,

$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_topology.c:185:24: warning: cast to restricted 
snd_ctl_elem_type_t
drivers/staging/greybus/audio_topology.c:679:14: warning: restricted 
snd_ctl_elem_iface_t degrades to integer
drivers/staging/greybus/audio_topology.c:906:14: warning: restricted 
snd_ctl_elem_iface_t degrades to integer

Signed-off-by: Coiby Xu 
---
 drivers/staging/greybus/audio_topology.c | 2 +-
 include/uapi/sound/asound.h  | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/greybus/audio_topology.c 
b/drivers/staging/greybus/audio_topology.c
index 56bf1a4f95ad..f6023ff390c2 100644
--- a/drivers/staging/greybus/audio_topology.c
+++ b/drivers/staging/greybus/audio_topology.c
@@ -182,7 +182,7 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol 
*kcontrol,
/* update uinfo */
uinfo->access = data->access;
uinfo->count = data->vcount;
-   uinfo->type = (snd_ctl_elem_type_t)info->type;
+   uinfo->type = info->type;
 
switch (info->type) {
case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index 535a7229e1d9..8e71a95644ab 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -950,7 +950,7 @@ struct snd_ctl_card_info {
unsigned char components[128];  /* card components / fine 
identification, delimited with one space (AC97 etc..) */
 };
 
-typedef int __bitwise snd_ctl_elem_type_t;
+typedef __u8 snd_ctl_elem_type_t;
 #defineSNDRV_CTL_ELEM_TYPE_NONE((__force snd_ctl_elem_type_t) 
0) /* invalid */
 #defineSNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 
1) /* boolean type */
 #defineSNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 
2) /* integer type */
@@ -960,7 +960,7 @@ typedef int __bitwise snd_ctl_elem_type_t;
 #defineSNDRV_CTL_ELEM_TYPE_INTEGER64   ((__force snd_ctl_elem_type_t) 
6) /* 64-bit integer type */
 #defineSNDRV_CTL_ELEM_TYPE_LASTSNDRV_CTL_ELEM_TYPE_INTEGER64
 
-typedef int __bitwise snd_ctl_elem_iface_t;
+typedef __u8 snd_ctl_elem_iface_t;
 #defineSNDRV_CTL_ELEM_IFACE_CARD   ((__force snd_ctl_elem_iface_t) 
0) /* global control */
 #defineSNDRV_CTL_ELEM_IFACE_HWDEP  ((__force snd_ctl_elem_iface_t) 
1) /* hardware dependent device */
 #defineSNDRV_CTL_ELEM_IFACE_MIXER  ((__force snd_ctl_elem_iface_t) 
2) /* virtual mixer device */
-- 
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/3] staging: greybus: codecs: use SNDRV_PCM_FMTBIT_S16_LE for format bitmask

2020-09-24 Thread Coiby Xu
snd_soc_pcm_stream.formats should use the bitmask SNDRV_PCM_FMTBIT_*
instead of the sequential integers SNDRV_PCM_FORMAT_* as explained by
commit e712bfca1ac1f63f622f87c2f33b57608f2a4d19
("ASoC: codecs: use SNDRV_PCM_FMTBIT_* for format bitmask").

Found by sparse,

$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_codec.c:691:36: warning: incorrect type in 
initializer (different base types)
drivers/staging/greybus/audio_codec.c:691:36:expected unsigned long long 
[usertype] formats
drivers/staging/greybus/audio_codec.c:691:36:got restricted 
snd_pcm_format_t [usertype]
drivers/staging/greybus/audio_codec.c:701:36: warning: incorrect type in 
initializer (different base types)
drivers/staging/greybus/audio_codec.c:701:36:expected unsigned long long 
[usertype] formats
drivers/staging/greybus/audio_codec.c:701:36:got restricted 
snd_pcm_format_t [usertype]

Signed-off-by: Coiby Xu 
---
 drivers/staging/greybus/audio_codec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/greybus/audio_codec.c 
b/drivers/staging/greybus/audio_codec.c
index 74538f8c5fa4..494aa823e998 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -688,7 +688,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
.playback = {
.stream_name = "I2S 0 Playback",
.rates = SNDRV_PCM_RATE_48000,
-   .formats = SNDRV_PCM_FORMAT_S16_LE,
+   .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_max = 48000,
.rate_min = 48000,
.channels_min = 1,
@@ -698,7 +698,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
.capture = {
.stream_name = "I2S 0 Capture",
.rates = SNDRV_PCM_RATE_48000,
-   .formats = SNDRV_PCM_FORMAT_S16_LE,
+   .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_max = 48000,
.rate_min = 48000,
.channels_min = 1,
-- 
2.28.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/3] [PATCH] staging: greybus: fix warnings about endianness detected by sparse

2020-09-24 Thread Coiby Xu
This patch fix the following warnings from sparse,

$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 
[usertype] data_cport
drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] 
intf_cport_id
drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:691:41:expected unsigned int access
drivers/staging/greybus/audio_topology.c:691:41:got restricted __le32 
[usertype] access
drivers/staging/greybus/audio_topology.c:746:44: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:746:44:expected unsigned int
drivers/staging/greybus/audio_topology.c:746:44:got restricted __le32
drivers/staging/greybus/audio_topology.c:748:52: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:748:52:expected unsigned int
drivers/staging/greybus/audio_topology.c:748:52:got restricted __le32
drivers/staging/greybus/audio_topology.c:802:42: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:805:50: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:805:50:expected restricted __le32
drivers/staging/greybus/audio_topology.c:805:50:got unsigned int
drivers/staging/greybus/audio_topology.c:814:50: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:817:58: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:817:58:expected restricted __le32
drivers/staging/greybus/audio_topology.c:817:58:got unsigned int
drivers/staging/greybus/audio_topology.c:889:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:889:25:expected unsigned int access
drivers/staging/greybus/audio_topology.c:889:25:got restricted __le32 
[usertype] access

Suggested-by: Dan Carpenter 
Reviewed-by: Dan Carpenter 
Signed-off-by: Coiby Xu 
---
 drivers/staging/greybus/audio_module.c   |  6 +++---
 drivers/staging/greybus/audio_topology.c | 18 +-
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/greybus/audio_module.c 
b/drivers/staging/greybus/audio_module.c
index 16f60256adb2..c52c4f361b90 100644
--- a/drivers/staging/greybus/audio_module.c
+++ b/drivers/staging/greybus/audio_module.c
@@ -219,7 +219,7 @@ static int gb_audio_add_data_connection(struct 
gbaudio_module_info *gbmodule,
 
greybus_set_drvdata(bundle, gbmodule);
dai->id = 0;
-   dai->data_cport = connection->intf_cport_id;
+   dai->data_cport = cpu_to_le16(connection->intf_cport_id);
dai->connection = connection;
list_add(>list, >data_list);
 
@@ -329,7 +329,7 @@ static int gb_audio_probe(struct gb_bundle *bundle,
if (ret) {
dev_err(dev,
"%d:Error while enabling %d:data connection\n",
-   ret, dai->data_cport);
+   ret, le16_to_cpu(dai->data_cport));
goto disable_data_connection;
}
}
@@ -451,7 +451,7 @@ static int gb_audio_resume(struct device *dev)
if (ret) {
dev_err(dev,
"%d:Error while enabling %d:data connection\n",
-   ret, dai->data_cport);
+   ret, le16_to_cpu(dai->data_cport));
return ret;
}
}
diff --git a/drivers/staging/greybus/audio_topology.c 
b/drivers/staging/greybus/audio_topology.c
index 83b38ae8908c..56bf1a4f95ad 100644
--- a/drivers/staging/greybus/audio_topology.c
+++ b/drivers/staging/greybus/audio_topology.c
@@ -466,7 +466,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol 
*kcontrol,
goto exit;
 
/* update ucontrol */
-   if (gbvalue.value.integer_value[0] != val) {
+   if (gbvalue.value.integer_value[0] != cpu_to_le32(val)) {
for (wi = 0; wi < wlist->num_widgets; wi++) {
widget = wlist->widgets[wi];
snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol,
@@ -689,7 +689,7 @@ static int gbaudio_tplg_create_kcontrol(struct 
gbaudio_module_info *gb,
return -ENOMEM;
ctldata->ctl_id = ctl->id;
ctldata->data_cport = le16_t

Re: [PATCH] staging: greybus: fix warnings detected by sparse

2020-09-16 Thread Coiby Xu

On Mon, Aug 24, 2020 at 12:41:48PM +0300, Dan Carpenter wrote:

On Mon, Aug 24, 2020 at 10:50:59AM +0800, Coiby Xu wrote:

This patch fix the following warnings from sparse,

$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_codec.c:691:36: warning: incorrect type in 
initializer (different base types)
drivers/staging/greybus/audio_codec.c:691:36:expected unsigned long long 
[usertype] formats
drivers/staging/greybus/audio_codec.c:691:36:got restricted 
snd_pcm_format_t [usertype]
drivers/staging/greybus/audio_codec.c:701:36: warning: incorrect type in 
initializer (different base types)
drivers/staging/greybus/audio_codec.c:701:36:expected unsigned long long 
[usertype] formats
drivers/staging/greybus/audio_codec.c:701:36:got restricted 
snd_pcm_format_t [usertype]
drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 
[usertype] data_cport
drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] 
intf_cport_id
drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:691:41:expected unsigned int access
drivers/staging/greybus/audio_topology.c:691:41:got restricted __le32 
[usertype] access
drivers/staging/greybus/audio_topology.c:746:44: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:746:44:expected unsigned int
drivers/staging/greybus/audio_topology.c:746:44:got restricted __le32
drivers/staging/greybus/audio_topology.c:748:52: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:748:52:expected unsigned int
drivers/staging/greybus/audio_topology.c:748:52:got restricted __le32
drivers/staging/greybus/audio_topology.c:802:42: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:805:50: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:805:50:expected restricted __le32
drivers/staging/greybus/audio_topology.c:805:50:got unsigned int
drivers/staging/greybus/audio_topology.c:814:50: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:817:58: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:817:58:expected restricted __le32
drivers/staging/greybus/audio_topology.c:817:58:got unsigned int
drivers/staging/greybus/audio_topology.c:889:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:889:25:expected unsigned int access
drivers/staging/greybus/audio_topology.c:889:25:got restricted __le32 
[usertype] access

Signed-off-by: Coiby Xu 
---
 drivers/staging/greybus/audio_codec.c|  4 ++--
 drivers/staging/greybus/audio_module.c   |  2 +-
 drivers/staging/greybus/audio_topology.c | 18 +-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/greybus/audio_codec.c 
b/drivers/staging/greybus/audio_codec.c
index 74538f8c5fa4..494aa823e998 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -688,7 +688,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
.playback = {
.stream_name = "I2S 0 Playback",
.rates = SNDRV_PCM_RATE_48000,
-   .formats = SNDRV_PCM_FORMAT_S16_LE,
+   .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_max = 48000,
.rate_min = 48000,
.channels_min = 1,
@@ -698,7 +698,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
.capture = {
.stream_name = "I2S 0 Capture",
.rates = SNDRV_PCM_RATE_48000,
-   .formats = SNDRV_PCM_FORMAT_S16_LE,
+   .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_max = 48000,
.rate_min = 48000,
.channels_min = 1,


These changes need to be explained better.  We're changing formats from
2 to 1 << 2.

When you're writing commit messages, please imagine me as the target
audience.  I have a fairly decent understanding of the kernel and C, but
I don't know very much about the sound subsystem.


(Sorry for the late reply! I didn't notice my email client failed to
delivered this email.)

Thank you for showing me SNDRV_PCM_FORMAT_S16_LE != SNDRV_PCM_FMTBIT_S16_LE.
I thought they only differ in type so no domain knowledge is needed.


This code used to work, right?  How was i

Re: [PATCH v3] staging: qlge: fix build breakage with dumping enabled

2020-09-04 Thread Coiby Xu

On Thu, Sep 03, 2020 at 12:49:18PM +0900, Benjamin Poirier wrote:

On 2020-09-02 22:00 +0800, Coiby Xu wrote:

This fixes commit 0107635e15ac
("staging: qlge: replace pr_err with netdev_err") which introduced an
build breakage of missing `struct ql_adapter *qdev` for some functions
and a warning of type mismatch with dumping enabled, i.e.,

$ make CFLAGS_MODULE="QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 \
  QL_IB_DUMP=1 QL_REG_DUMP=1 QL_DEV_DUMP=1" M=drivers/staging/qlge

qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’:
qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did 
you mean ‘cdev’?
 2051 |  netdev_err(qdev->ndev, "%s\n", __func__);
  | ^~~~
qlge_dbg.c: In function ‘ql_dump_routing_entries’:
qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but 
argument 3 has type ‘int’ [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ~^
  |  |
  |  char *
  | %d
 1436 |i, value);
  |~
  ||
  |int
qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ 
argument [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ^
  | |
  | unsigned int

Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err")
Reported-by: Benjamin Poirier 
Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---


Thanks for following up on this issue.

[...]

@@ -1632,8 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb)

 void ql_dump_tx_ring(struct tx_ring *tx_ring)
 {
-   if (!tx_ring)
-   return;
+   struct ql_adapter *qdev = tx_ring->qdev;
+
netdev_err(qdev->ndev, "= Dumping tx_ring %d 
===\n",
   tx_ring->wq_id);
netdev_err(qdev->ndev, "tx_ring->base = %p\n", tx_ring->wq_base);


Did you actually check to confirm that the test can be removed?


Thank you for the reminding! For the current code, when ql_dump_tx_ring
is called, tx_ring would never be null.



This is something that you should mention in the changelog at the very
least since that change is not directly about fixing the build breakage
and if it's wrong, it can lead to null pointer deref.


I thought it is common practice in C that the caller makes sure
the passed parameter isn't a null pointer because a QEMU developer
also gave me the same advice after reviewing one of my patches for
QEMU a few weeks ago. I'll mention this in the commit message. Thank
you for the suggestion!


--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2] staging: qlge: fix build breakage with dumping enabled

2020-09-02 Thread Coiby Xu

On Thu, Aug 27, 2020 at 09:50:10AM +0900, Benjamin Poirier wrote:

On 2020-08-27 07:27 +0800, Coiby Xu wrote:

This fixes commit 0107635e15ac
("staging: qlge: replace pr_err with netdev_err") which introduced an
build breakage of missing `struct ql_adapter *qdev` for some functions
and a warning of type mismatch with dumping enabled, i.e.,

$ make CFLAGS_MODULE="QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 \
  QL_IB_DUMP=1 QL_REG_DUMP=1 QL_DEV_DUMP=1" M=drivers/staging/qlge

qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’:
qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did 
you mean ‘cdev’?
 2051 |  netdev_err(qdev->ndev, "%s\n", __func__);
  | ^~~~
qlge_dbg.c: In function ‘ql_dump_routing_entries’:
qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but 
argument 3 has type ‘int’ [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ~^
  |  |
  |  char *
  | %d
 1436 |i, value);
  |~
  ||
  |int
qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ 
argument [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ^
  | |
  | unsigned int

Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err")
Reported-by: Benjamin Poirier 
Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h  | 20 ++--
 drivers/staging/qlge/qlge_dbg.c  | 24 ++--
 drivers/staging/qlge/qlge_main.c |  8 
 3 files changed, 32 insertions(+), 20 deletions(-)


[...]

@@ -1632,6 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb)

 void ql_dump_tx_ring(struct tx_ring *tx_ring)
 {
+   struct ql_adapter *qdev = tx_ring->qdev;
+
if (!tx_ring)
return;


Given the null check for tx_ring, it seems unwise to dereference tx_ring
before the check.

Looking at ql_dump_all(), I'm not sure that the check is needed at all
though. Maybe it should be removed.

Same problem in ql_dump_rx_ring().


Thank you for the spotting this issue! I'll remove the check.




netdev_err(qdev->ndev, "= Dumping tx_ring %d 
===\n",
@@ -1657,6 +1662,8 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring)
 void ql_dump_ricb(struct ricb *ricb)
 {
int i;
+   struct ql_adapter *qdev =
+   container_of(ricb, struct ql_adapter, ricb);


Here, davem would point out that the variables are not declared in
"reverse xmas tree" order.


I'll make davem happy then:)

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3] staging: qlge: fix build breakage with dumping enabled

2020-09-02 Thread Coiby Xu
This fixes commit 0107635e15ac
("staging: qlge: replace pr_err with netdev_err") which introduced an
build breakage of missing `struct ql_adapter *qdev` for some functions
and a warning of type mismatch with dumping enabled, i.e.,

$ make CFLAGS_MODULE="QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 \
  QL_IB_DUMP=1 QL_REG_DUMP=1 QL_DEV_DUMP=1" M=drivers/staging/qlge

qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’:
qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did 
you mean ‘cdev’?
 2051 |  netdev_err(qdev->ndev, "%s\n", __func__);
  | ^~~~
qlge_dbg.c: In function ‘ql_dump_routing_entries’:
qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but 
argument 3 has type ‘int’ [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ~^
  |  |
  |  char *
  | %d
 1436 |i, value);
  |~
  ||
  |int
qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ 
argument [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ^
  | |
  | unsigned int

Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err")
Reported-by: Benjamin Poirier 
Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h  | 20 ++--
 drivers/staging/qlge/qlge_dbg.c  | 28 ++--
 drivers/staging/qlge/qlge_main.c |  8 
 3 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 483ce04789ed..7f6798b223ef 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2338,21 +2338,21 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, 
u32 bit, u16 q_id);
 #endif

 #ifdef QL_OB_DUMP
-void ql_dump_tx_desc(struct tx_buf_desc *tbd);
-void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb);
-void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp);
-#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp)
+void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd);
+void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req 
*ob_mac_iocb);
+void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp 
*ob_mac_rsp);
+#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, 
ob_mac_iocb)
+#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, 
ob_mac_rsp)
 #else
-#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp)
+#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb)
+#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp)
 #endif

 #ifdef QL_IB_DUMP
-void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp);
-#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp)
+void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp 
*ib_mac_rsp);
+#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) ql_dump_ib_mac_rsp(qdev, 
ib_mac_rsp)
 #else
-#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp)
+#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp)
 #endif

 #ifdef QL_ALL_DUMP
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index a55bf0b3e9dc..e139e15516fa 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1431,7 +1431,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
}
if (value)
netdev_err(qdev->ndev,
-  "%s: Routing Mask %d = 0x%.08x\n",
+  "Routing Mask %d = 0x%.08x\n",
   i, value);
}
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
@@ -1617,6 +1617,9 @@ void ql_dump_qdev(struct ql_adapter *qdev)
 #ifdef QL_CB_DUMP
 void ql_dump_wqicb(struct wqicb *wqicb)
 {
+   struct tx_ring *tx_ring = container_of(wqicb, struct tx_ring, wqicb);
+   struct ql_adapter *qdev = tx_ring->qdev;
+
netdev_err(qdev->ndev, "Dumping wqicb stuff...\n");
netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len));
netdev_err(qdev->ndev, "wqicb->flags = %x\n",
@@ -1632,8 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb)

 void ql_dump_tx_ring(struct tx_ring *tx_ring)
 {
-   if (!tx_ring)
-   return;
+   struct ql_adapter *qdev = tx_ring->qdev;
+
netdev_err(qdev->ndev, "= Dumping tx_ring %d 
===\n",
   tx_ring->wq_id);
netdev_err(qdev->ndev, "tx_ring->base = %p\n", tx_ring->wq_base);
@@ -1656,6

[PATCH v2] staging: qlge: fix build breakage with dumping enabled

2020-08-26 Thread Coiby Xu
This fixes commit 0107635e15ac
("staging: qlge: replace pr_err with netdev_err") which introduced an
build breakage of missing `struct ql_adapter *qdev` for some functions
and a warning of type mismatch with dumping enabled, i.e.,

$ make CFLAGS_MODULE="QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 \
  QL_IB_DUMP=1 QL_REG_DUMP=1 QL_DEV_DUMP=1" M=drivers/staging/qlge

qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’:
qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did 
you mean ‘cdev’?
 2051 |  netdev_err(qdev->ndev, "%s\n", __func__);
  | ^~~~
qlge_dbg.c: In function ‘ql_dump_routing_entries’:
qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but 
argument 3 has type ‘int’ [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ~^
  |  |
  |  char *
  | %d
 1436 |i, value);
  |~
  ||
  |int
qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ 
argument [-Wformat=]
 1435 |"%s: Routing Mask %d = 0x%.08x\n",
  | ^
  | |
  | unsigned int

Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err")
Reported-by: Benjamin Poirier 
Suggested-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h  | 20 ++--
 drivers/staging/qlge/qlge_dbg.c  | 24 ++--
 drivers/staging/qlge/qlge_main.c |  8 
 3 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 483ce04789ed..7f6798b223ef 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2338,21 +2338,21 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, 
u32 bit, u16 q_id);
 #endif

 #ifdef QL_OB_DUMP
-void ql_dump_tx_desc(struct tx_buf_desc *tbd);
-void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb);
-void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp);
-#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp)
+void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd);
+void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req 
*ob_mac_iocb);
+void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp 
*ob_mac_rsp);
+#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, 
ob_mac_iocb)
+#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, 
ob_mac_rsp)
 #else
-#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp)
+#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb)
+#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp)
 #endif

 #ifdef QL_IB_DUMP
-void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp);
-#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp)
+void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp 
*ib_mac_rsp);
+#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) ql_dump_ib_mac_rsp(qdev, 
ib_mac_rsp)
 #else
-#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp)
+#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp)
 #endif

 #ifdef QL_ALL_DUMP
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index a55bf0b3e9dc..e62ee4e2f118 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1431,7 +1431,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
}
if (value)
netdev_err(qdev->ndev,
-  "%s: Routing Mask %d = 0x%.08x\n",
+  "Routing Mask %d = 0x%.08x\n",
   i, value);
}
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
@@ -1617,6 +1617,9 @@ void ql_dump_qdev(struct ql_adapter *qdev)
 #ifdef QL_CB_DUMP
 void ql_dump_wqicb(struct wqicb *wqicb)
 {
+   struct tx_ring *tx_ring = container_of(wqicb, struct tx_ring, wqicb);
+   struct ql_adapter *qdev = tx_ring->qdev;
+
netdev_err(qdev->ndev, "Dumping wqicb stuff...\n");
netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len));
netdev_err(qdev->ndev, "wqicb->flags = %x\n",
@@ -1632,6 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb)

 void ql_dump_tx_ring(struct tx_ring *tx_ring)
 {
+   struct ql_adapter *qdev = tx_ring->qdev;
+
if (!tx_ring)
return;
netdev_err(qdev->ndev, "= Dumping tx_ring %d 
===\n",
@@ -1657,6 +1662,8 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring)
 void ql_dump_ricb(struct ricb *ricb)
 {
int i;
+   struct ql_adapter *q

Re: [PATCH] staging: qlge: fix build breakage with dumping enabled

2020-08-25 Thread Coiby Xu

On Fri, Aug 21, 2020 at 05:31:59PM +0900, Benjamin Poirier wrote:

On 2020-08-21 15:03 +0800, Coiby Xu wrote:

This fixes commit 0107635e15ac
("staging: qlge: replace pr_err with netdev_err") which introduced an
build breakage with dumping enabled, i.e.,

$ QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 QL_REG_DUMP=1 \
  QL_IB_DUMP=1 QL_DEV_DUMP=1 make M=drivers/staging/qlge

Fixes: 0107635e15ac ("taging: qlge: replace pr_err with netdev_err")

^ staging


Thank you for reminding me of the typo!


Reported-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h  | 42 
 drivers/staging/qlge/qlge_dbg.c  | 36 +--
 drivers/staging/qlge/qlge_main.c |  4 +--
 3 files changed, 41 insertions(+), 41 deletions(-)


[...]

@@ -1615,7 +1615,7 @@ void ql_dump_qdev(struct ql_adapter *qdev)
 #endif

 #ifdef QL_CB_DUMP
-void ql_dump_wqicb(struct wqicb *wqicb)
+void ql_dump_wqicb(struct ql_adapter *qdev, struct wqicb *wqicb)
 {


This can be fixed without adding another argument:

struct tx_ring *tx_ring = container_of(wqicb, struct tx_ring, wqicb);
struct ql_adapter *qdev = tx_ring->qdev;


netdev_err(qdev->ndev, "Dumping wqicb stuff...\n");
netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len));
@@ -1630,7 +1630,7 @@ void ql_dump_wqicb(struct wqicb *wqicb)
   (unsigned long long)le64_to_cpu(wqicb->cnsmr_idx_addr));
 }

-void ql_dump_tx_ring(struct tx_ring *tx_ring)
+void ql_dump_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring)
 {


This can be fixed without adding another argument:
struct ql_adapter *qdev;

if (!tx_ring)
return;

qdev = tx_ring->qdev;

... similar comment for the other instances.


Thank you for the simpler solution!

For QL_OB_DUMP and QL_IB_DUMP, `struct ql_adapter *qdev` can't be
obtained via container_of. So qdev are still directly passed to these
functions.

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: greybus: fix warnings detected by sparse

2020-08-23 Thread Coiby Xu
This patch fix the following warnings from sparse,

$ make C=2 drivers/staging/greybus/
drivers/staging/greybus/audio_codec.c:691:36: warning: incorrect type in 
initializer (different base types)
drivers/staging/greybus/audio_codec.c:691:36:expected unsigned long long 
[usertype] formats
drivers/staging/greybus/audio_codec.c:691:36:got restricted 
snd_pcm_format_t [usertype]
drivers/staging/greybus/audio_codec.c:701:36: warning: incorrect type in 
initializer (different base types)
drivers/staging/greybus/audio_codec.c:701:36:expected unsigned long long 
[usertype] formats
drivers/staging/greybus/audio_codec.c:701:36:got restricted 
snd_pcm_format_t [usertype]
drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 
[usertype] data_cport
drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] 
intf_cport_id
drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:691:41:expected unsigned int access
drivers/staging/greybus/audio_topology.c:691:41:got restricted __le32 
[usertype] access
drivers/staging/greybus/audio_topology.c:746:44: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:746:44:expected unsigned int
drivers/staging/greybus/audio_topology.c:746:44:got restricted __le32
drivers/staging/greybus/audio_topology.c:748:52: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:748:52:expected unsigned int
drivers/staging/greybus/audio_topology.c:748:52:got restricted __le32
drivers/staging/greybus/audio_topology.c:802:42: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:805:50: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:805:50:expected restricted __le32
drivers/staging/greybus/audio_topology.c:805:50:got unsigned int
drivers/staging/greybus/audio_topology.c:814:50: warning: restricted __le32 
degrades to integer
drivers/staging/greybus/audio_topology.c:817:58: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:817:58:expected restricted __le32
drivers/staging/greybus/audio_topology.c:817:58:got unsigned int
drivers/staging/greybus/audio_topology.c:889:25: warning: incorrect type in 
assignment (different base types)
drivers/staging/greybus/audio_topology.c:889:25:expected unsigned int access
drivers/staging/greybus/audio_topology.c:889:25:got restricted __le32 
[usertype] access

Signed-off-by: Coiby Xu 
---
 drivers/staging/greybus/audio_codec.c|  4 ++--
 drivers/staging/greybus/audio_module.c   |  2 +-
 drivers/staging/greybus/audio_topology.c | 18 +-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/greybus/audio_codec.c 
b/drivers/staging/greybus/audio_codec.c
index 74538f8c5fa4..494aa823e998 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -688,7 +688,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
.playback = {
.stream_name = "I2S 0 Playback",
.rates = SNDRV_PCM_RATE_48000,
-   .formats = SNDRV_PCM_FORMAT_S16_LE,
+   .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_max = 48000,
.rate_min = 48000,
.channels_min = 1,
@@ -698,7 +698,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
.capture = {
.stream_name = "I2S 0 Capture",
.rates = SNDRV_PCM_RATE_48000,
-   .formats = SNDRV_PCM_FORMAT_S16_LE,
+   .formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_max = 48000,
.rate_min = 48000,
.channels_min = 1,
diff --git a/drivers/staging/greybus/audio_module.c 
b/drivers/staging/greybus/audio_module.c
index 16f60256adb2..00848b84b022 100644
--- a/drivers/staging/greybus/audio_module.c
+++ b/drivers/staging/greybus/audio_module.c
@@ -219,7 +219,7 @@ static int gb_audio_add_data_connection(struct 
gbaudio_module_info *gbmodule,
 
greybus_set_drvdata(bundle, gbmodule);
dai->id = 0;
-   dai->data_cport = connection->intf_cport_id;
+   dai->data_cport = cpu_to_le16(connection->intf_cport_id);
dai->connection = connection;
list_add(>list, >data_list);
 
diff --git a/drivers/staging/greybus/audio_topology.c 
b/drivers/staging

[PATCH] staging: qlge: fix build breakage with dumping enabled

2020-08-21 Thread Coiby Xu
This fixes commit 0107635e15ac
("staging: qlge: replace pr_err with netdev_err") which introduced an
build breakage with dumping enabled, i.e.,

$ QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 QL_REG_DUMP=1 \
  QL_IB_DUMP=1 QL_DEV_DUMP=1 make M=drivers/staging/qlge

Fixes: 0107635e15ac ("taging: qlge: replace pr_err with netdev_err")
Reported-by: Benjamin Poirier 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h  | 42 
 drivers/staging/qlge/qlge_dbg.c  | 36 +--
 drivers/staging/qlge/qlge_main.c |  4 +--
 3 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 483ce04789ed..c72c1d2a00a8 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2315,37 +2315,37 @@ void ql_dump_qdev(struct ql_adapter *qdev);
 #endif
 
 #ifdef QL_CB_DUMP
-void ql_dump_wqicb(struct wqicb *wqicb);
-void ql_dump_tx_ring(struct tx_ring *tx_ring);
-void ql_dump_ricb(struct ricb *ricb);
-void ql_dump_cqicb(struct cqicb *cqicb);
-void ql_dump_rx_ring(struct rx_ring *rx_ring);
+void ql_dump_wqicb(struct ql_adapter *qdev, struct wqicb *wqicb);
+void ql_dump_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring);
+void ql_dump_ricb(struct ql_adapter *qdev, struct ricb *ricb);
+void ql_dump_cqicb(struct ql_adapter *qdev, struct cqicb *cqicb);
+void ql_dump_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring);
 void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id);
-#define QL_DUMP_RICB(ricb) ql_dump_ricb(ricb)
-#define QL_DUMP_WQICB(wqicb) ql_dump_wqicb(wqicb)
-#define QL_DUMP_TX_RING(tx_ring) ql_dump_tx_ring(tx_ring)
-#define QL_DUMP_CQICB(cqicb) ql_dump_cqicb(cqicb)
-#define QL_DUMP_RX_RING(rx_ring) ql_dump_rx_ring(rx_ring)
+#define QL_DUMP_RICB(qdev, ricb) ql_dump_ricb(qdev, ricb)
+#define QL_DUMP_WQICB(qdev, wqicb) ql_dump_wqicb(qdev, wqicb)
+#define QL_DUMP_TX_RING(qdev, tx_ring) ql_dump_tx_ring(qdev, tx_ring)
+#define QL_DUMP_CQICB(qdev, cqicb) ql_dump_cqicb(qdev, cqicb)
+#define QL_DUMP_RX_RING(qdev, rx_ring) ql_dump_rx_ring(qdev, rx_ring)
 #define QL_DUMP_HW_CB(qdev, size, bit, q_id) \
ql_dump_hw_cb(qdev, size, bit, q_id)
 #else
-#define QL_DUMP_RICB(ricb)
-#define QL_DUMP_WQICB(wqicb)
-#define QL_DUMP_TX_RING(tx_ring)
-#define QL_DUMP_CQICB(cqicb)
-#define QL_DUMP_RX_RING(rx_ring)
+#define QL_DUMP_RICB(qdev, ricb)
+#define QL_DUMP_WQICB(qdev, wqicb)
+#define QL_DUMP_TX_RING(qdev, tx_ring)
+#define QL_DUMP_CQICB(qdev, cqicb)
+#define QL_DUMP_RX_RING(qdev, rx_ring)
 #define QL_DUMP_HW_CB(qdev, size, bit, q_id)
 #endif
 
 #ifdef QL_OB_DUMP
 void ql_dump_tx_desc(struct tx_buf_desc *tbd);
-void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb);
-void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp);
-#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp)
+void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req 
*ob_mac_iocb);
+void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp 
*ob_mac_rsp);
+#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, 
ob_mac_iocb)
+#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, 
ob_mac_rsp)
 #else
-#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp)
+#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb)
+#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp)
 #endif
 
 #ifdef QL_IB_DUMP
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index a55bf0b3e9dc..123d3f7475ae 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1431,7 +1431,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
}
if (value)
netdev_err(qdev->ndev,
-  "%s: Routing Mask %d = 0x%.08x\n",
+  "Routing Mask %d = 0x%.08x\n",
   i, value);
}
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
@@ -1615,7 +1615,7 @@ void ql_dump_qdev(struct ql_adapter *qdev)
 #endif
 
 #ifdef QL_CB_DUMP
-void ql_dump_wqicb(struct wqicb *wqicb)
+void ql_dump_wqicb(struct ql_adapter *qdev, struct wqicb *wqicb)
 {
netdev_err(qdev->ndev, "Dumping wqicb stuff...\n");
netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len));
@@ -1630,7 +1630,7 @@ void ql_dump_wqicb(struct wqicb *wqicb)
   (unsigned long long)le64_to_cpu(wqicb->cnsmr_idx_addr));
 }
 
-void ql_dump_tx_ring(struct tx_ring *tx_ring)
+void ql_dump_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring)
 {
if (!tx_ring)
return;
@@ -1654,7 +1654,7 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring)
netdev_err(qdev->ndev, "tx_ring-

Re: [RFC 3/3] staging: qlge: clean up code that dump info to dmesg

2020-08-20 Thread Coiby Xu

On Sun, Aug 16, 2020 at 11:57:17AM +0900, Benjamin Poirier wrote:

On 2020-08-15 00:06 +0800, Coiby Xu wrote:

The related code are not necessary because,
- Device status and general registers can be obtained by ethtool.
- Coredump can be done via devlink health reporter.
- Structure related to the hardware (struct ql_adapter) can be obtained
  by crash or drgn.


I would suggest to add the drgn script from the cover letter to
Documentation/networking/device_drivers/qlogic/


Thank you for this suggestion! I planned to send a pull request to
https://github.com/osandov/drgn. This is a better idea.


I would also suggest to submit a separate patch now which fixes the
build breakage reported in <20200629053004.GA6165@f3> while you work on
removing that code.


I'll send a single patch to fix that issue before preparing for v1
of this work.



Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h |  82 
 drivers/staging/qlge/qlge_dbg.c | 672 
 drivers/staging/qlge/qlge_ethtool.c |   1 -
 drivers/staging/qlge/qlge_main.c|   6 -
 4 files changed, 761 deletions(-)


[...]

diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 058889687907..368394123d16 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1326,675 +1326,3 @@ void ql_mpi_core_to_log(struct work_struct *work)
   sizeof(*qdev->mpi_coredump), false);
 }

-#ifdef QL_REG_DUMP
-static void ql_dump_intr_states(struct ql_adapter *qdev)
-{

[...]

-   }
-}
-#endif


This leaves a stray newline at the end of the file and also does not
apply over latest staging.


I will fix it in v1. Thank you for reviewing this patch!

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [RFC 1/3] Initialize devlink health dump framework for the dlge driver

2020-08-20 Thread Coiby Xu

On Sun, Aug 16, 2020 at 11:56:40AM +0900, Benjamin Poirier wrote:

On 2020-08-15 00:05 +0800, Coiby Xu wrote:

Initialize devlink health dump framework for the dlge driver so the
coredump could be done via devlink.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/Makefile  |  2 +-
 drivers/staging/qlge/qlge.h|  9 +++
 drivers/staging/qlge/qlge_health.c | 43 ++
 drivers/staging/qlge/qlge_health.h |  2 ++
 drivers/staging/qlge/qlge_main.c   | 21 +++
 5 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/qlge/qlge_health.c
 create mode 100644 drivers/staging/qlge/qlge_health.h

diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile
index 1dc2568e820c..0a1e4c8dd546 100644
--- a/drivers/staging/qlge/Makefile
+++ b/drivers/staging/qlge/Makefile
@@ -5,4 +5,4 @@

 obj-$(CONFIG_QLGE) += qlge.o

-qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
+qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_health.o
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index fc8c5ca8935d..055ded6dab60 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2061,6 +2061,14 @@ struct nic_operations {
int (*port_initialize) (struct ql_adapter *);
 };



This patch doesn't apply over the latest staging tree. I think your tree
is missing commit d923bb6bf508 ("staging: qlge: qlge.h: Function
definition arguments should have names.")


Thank you for applying the patch to test it! I had incorrect
understanding about the word "RFC" and didn't do a rebase onto
the latest staging tree.




+
+
+struct qlge_devlink {
+struct ql_adapter *qdev;
+struct net_device *ndev;


I don't have experience implementing devlink callbacks but looking at
some other devlink users (mlx4, ionic, ice), all of them use devlink
priv space for their main private structure. That would be struct
ql_adapter in this case. Is there a good reason to stray from that
pattern?


+struct devlink_health_reporter *reporter;
+};
+
 /*
  * The main Adapter structure definition.
  * This structure has all fields relevant to the hardware.
@@ -2078,6 +2086,7 @@ struct ql_adapter {
struct pci_dev *pdev;
struct net_device *ndev;/* Parent NET device */

+   struct qlge_devlink *devlink;
/* Hardware information */
u32 chip_rev_id;
u32 fw_rev_id;
diff --git a/drivers/staging/qlge/qlge_health.c 
b/drivers/staging/qlge/qlge_health.c
new file mode 100644
index ..292f6b1827e1
--- /dev/null
+++ b/drivers/staging/qlge/qlge_health.c
@@ -0,0 +1,43 @@
+#include "qlge.h"
+#include "qlge_health.h"
+
+static int
+qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+   struct devlink_fmsg *fmsg, void *priv_ctx,
+   struct netlink_ext_ack *extack)
+{
+   return 0;
+}
+
+static const struct devlink_health_reporter_ops qlge_reporter_ops = {
+   .name = "dummy",
+   .dump = qlge_reporter_coredump,
+};


I think
select NET_DEVLINK
should be added to drivers/staging/qlge/Kconfig


Thank you for reminding me!




+
+int qlge_health_create_reporters(struct qlge_devlink *priv)
+{
+   int err;
+
+   struct devlink_health_reporter *reporter;
+   struct devlink *devlink;
+
+   devlink = priv_to_devlink(priv);
+   reporter =
+   devlink_health_reporter_create(devlink, _reporter_ops,
+  0,
+  priv);
+   if (IS_ERR(reporter)) {
+   netdev_warn(priv->ndev,
+   "Failed to create reporter, err = %ld\n",
+   PTR_ERR(reporter));
+   return PTR_ERR(reporter);
+   }
+   priv->reporter = reporter;
+
+   if (err)
+   return err;
+
+   return 0;
+}
+
+


Stray newlines


Will fix it in v1.




diff --git a/drivers/staging/qlge/qlge_health.h 
b/drivers/staging/qlge/qlge_health.h
new file mode 100644
index ..07d3bafab845
--- /dev/null
+++ b/drivers/staging/qlge/qlge_health.h
@@ -0,0 +1,2 @@
+#include 
+int qlge_health_create_reporters(struct qlge_devlink *priv);


I would suggest to put this in qlge.h instead of creating a new file.


Although there are only two lines for now, is it possible qlge will add
more devlink code? If that's the case, a file to single out these code
is necessary as is the same to some other drivers,

$ find drivers -name *health*.h
drivers/net/ethernet/mellanox/mlx5/core/en/health.h

$ find drivers -name *devlink*.h
drivers/net/ethernet/huawei/hinic/hinic_devlink.h
drivers/net/ethernet/mellanox/mlx5/core/devlink.h
drivers/net/ethernet/mellanox/mlx5/core/en/devlink.h
drivers/net/ethernet/intel/ice/ice_devlink.h
 

[RFC 3/3] staging: qlge: clean up code that dump info to dmesg

2020-08-14 Thread Coiby Xu
The related code are not necessary because,
- Device status and general registers can be obtained by ethtool.
- Coredump can be done via devlink health reporter.
- Structure related to the hardware (struct ql_adapter) can be obtained
  by crash or drgn.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge.h |  82 
 drivers/staging/qlge/qlge_dbg.c | 672 
 drivers/staging/qlge/qlge_ethtool.c |   1 -
 drivers/staging/qlge/qlge_main.c|   6 -
 4 files changed, 761 deletions(-)

diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index 055ded6dab60..8ed81ae0f9d8 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2288,86 +2288,4 @@ void ql_check_lb_frame(struct ql_adapter *, struct 
sk_buff *);
 int ql_own_firmware(struct ql_adapter *qdev);
 int ql_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget);

-/* #define QL_ALL_DUMP */
-/* #define QL_REG_DUMP */
-/* #define QL_DEV_DUMP */
-/* #define QL_CB_DUMP */
-/* #define QL_IB_DUMP */
-/* #define QL_OB_DUMP */
-
-#ifdef QL_REG_DUMP
-void ql_dump_xgmac_control_regs(struct ql_adapter *qdev);
-void ql_dump_routing_entries(struct ql_adapter *qdev);
-void ql_dump_regs(struct ql_adapter *qdev);
-#define QL_DUMP_REGS(qdev) ql_dump_regs(qdev)
-#define QL_DUMP_ROUTE(qdev) ql_dump_routing_entries(qdev)
-#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) ql_dump_xgmac_control_regs(qdev)
-#else
-#define QL_DUMP_REGS(qdev)
-#define QL_DUMP_ROUTE(qdev)
-#define QL_DUMP_XGMAC_CONTROL_REGS(qdev)
-#endif
-
-#ifdef QL_STAT_DUMP
-void ql_dump_stat(struct ql_adapter *qdev);
-#define QL_DUMP_STAT(qdev) ql_dump_stat(qdev)
-#else
-#define QL_DUMP_STAT(qdev)
-#endif
-
-#ifdef QL_DEV_DUMP
-void ql_dump_qdev(struct ql_adapter *qdev);
-#define QL_DUMP_QDEV(qdev) ql_dump_qdev(qdev)
-#else
-#define QL_DUMP_QDEV(qdev)
-#endif
-
-#ifdef QL_CB_DUMP
-void ql_dump_wqicb(struct wqicb *wqicb);
-void ql_dump_tx_ring(struct tx_ring *tx_ring);
-void ql_dump_ricb(struct ricb *ricb);
-void ql_dump_cqicb(struct cqicb *cqicb);
-void ql_dump_rx_ring(struct rx_ring *rx_ring);
-void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id);
-#define QL_DUMP_RICB(ricb) ql_dump_ricb(ricb)
-#define QL_DUMP_WQICB(wqicb) ql_dump_wqicb(wqicb)
-#define QL_DUMP_TX_RING(tx_ring) ql_dump_tx_ring(tx_ring)
-#define QL_DUMP_CQICB(cqicb) ql_dump_cqicb(cqicb)
-#define QL_DUMP_RX_RING(rx_ring) ql_dump_rx_ring(rx_ring)
-#define QL_DUMP_HW_CB(qdev, size, bit, q_id) \
-   ql_dump_hw_cb(qdev, size, bit, q_id)
-#else
-#define QL_DUMP_RICB(ricb)
-#define QL_DUMP_WQICB(wqicb)
-#define QL_DUMP_TX_RING(tx_ring)
-#define QL_DUMP_CQICB(cqicb)
-#define QL_DUMP_RX_RING(rx_ring)
-#define QL_DUMP_HW_CB(qdev, size, bit, q_id)
-#endif
-
-#ifdef QL_OB_DUMP
-void ql_dump_tx_desc(struct tx_buf_desc *tbd);
-void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb);
-void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp);
-#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp)
-#else
-#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb)
-#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp)
-#endif
-
-#ifdef QL_IB_DUMP
-void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp);
-#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp)
-#else
-#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp)
-#endif
-
-#ifdef QL_ALL_DUMP
-void ql_dump_all(struct ql_adapter *qdev);
-#define QL_DUMP_ALL(qdev) ql_dump_all(qdev)
-#else
-#define QL_DUMP_ALL(qdev)
-#endif
-
 #endif /* _QLGE_H_ */
diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 058889687907..368394123d16 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1326,675 +1326,3 @@ void ql_mpi_core_to_log(struct work_struct *work)
   sizeof(*qdev->mpi_coredump), false);
 }

-#ifdef QL_REG_DUMP
-static void ql_dump_intr_states(struct ql_adapter *qdev)
-{
-   int i;
-   u32 value;
-
-   for (i = 0; i < qdev->intr_count; i++) {
-   ql_write32(qdev, INTR_EN, qdev->intr_context[i].intr_read_mask);
-   value = ql_read32(qdev, INTR_EN);
-   pr_err("%s: Interrupt %d is %s\n",
-  qdev->ndev->name, i,
-  (value & INTR_EN_EN ? "enabled" : "disabled"));
-   }
-}
-
-#define DUMP_XGMAC(qdev, reg)  \
-do {   \
-   u32 data;   \
-   ql_read_xgmac_reg(qdev, reg, );\
-   pr_err("%s: %s = 0x%.08x\n", qdev->ndev->name, #reg, data); \
-} while (0)
-
-void ql_dump_xgmac_control_regs(struct ql_adapter *qdev)
-{
-   if (ql_sem_spinlock(qdev, qdev->xg_sem_mask)) {
-   pr_err("%s: Couldn't get xgmac sem\n", _

[RFC 2/3] staging: qlge: coredump via devlink health reporter

2020-08-14 Thread Coiby Xu
$ devlink health dump show DEVICE reporter coredump -p -j
{
"Core Registers": {
"segment": 1,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
"Test Logic Regs": {
"segment": 2,
"values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
},
"RMII Registers": {
"segment": 3,
"values": [ 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 ]
},
...
"Sem Registers": {
    "segment": 50,
"values": [ 0,0,0,0 ]
}
}

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_health.c | 125 +++--
 1 file changed, 119 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/qlge/qlge_health.c 
b/drivers/staging/qlge/qlge_health.c
index 292f6b1827e1..a146cca6a3dc 100644
--- a/drivers/staging/qlge/qlge_health.c
+++ b/drivers/staging/qlge/qlge_health.c
@@ -1,16 +1,129 @@
 #include "qlge.h"
 #include "qlge_health.h"

-static int
-qlge_reporter_coredump(struct devlink_health_reporter *reporter,
-   struct devlink_fmsg *fmsg, void *priv_ctx,
-   struct netlink_ext_ack *extack)
+static int fill_seg_(struct devlink_fmsg *fmsg,
+   struct mpi_coredump_segment_header *seg_header,
+   u32 *reg_data)
 {
-   return 0;
+   int i;
+   int header_size = sizeof(struct mpi_coredump_segment_header);
+   int regs_num = (seg_header->seg_size - header_size) / sizeof(u32);
+   int err;
+
+   err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description);
+   if (err)
+   return err;
+   err = devlink_fmsg_obj_nest_start(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_start(fmsg, "values");
+   if (err)
+   return err;
+   for (i = 0; i < regs_num; i++) {
+   err = devlink_fmsg_u32_put(fmsg, *reg_data);
+   if (err)
+   return err;
+   reg_data++;
+   }
+   err = devlink_fmsg_obj_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_arr_pair_nest_end(fmsg);
+   if (err)
+   return err;
+   err = devlink_fmsg_pair_nest_end(fmsg);
+   return err;
+}
+
+#define fill_seg(seg_hdr, seg_regs)   \
+   err = fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \
+   if (err) { \
+   kvfree(dump);  \
+   return err;\
+   }
+
+static int qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+ struct devlink_fmsg *fmsg, void *priv_ctx,
+ struct netlink_ext_ack *extack)
+{
+   int err = 0;
+
+   struct qlge_devlink *dev = devlink_health_reporter_priv(reporter);
+   struct ql_adapter *qdev = dev->qdev;
+   struct ql_mpi_coredump *dump = kvmalloc(sizeof(struct ql_mpi_coredump),
+   GFP_KERNEL);
+   if (!dump)
+   return -ENOMEM;
+
+   err = ql_core_dump(qdev, dump);
+   if (err) {
+   kvfree(dump);
+   return err;
+   }
+
+   fill_seg(core_regs_seg_hdr, mpi_core_regs);
+   fill_seg(test_logic_regs_seg_hdr, test_logic_regs);
+   fill_seg(rmii_regs_seg_hdr, rmii_regs);
+   fill_seg(fcmac1_regs_seg_hdr, fcmac1_regs);
+   fill_seg(fcmac2_regs_seg_hdr, fcmac2_regs);
+   fill_seg(fc1_mbx_regs_seg_hdr, fc1_mbx_regs);
+   fill_seg(ide_regs_seg_hdr, ide_regs);
+   fill_seg(nic1_mbx_regs_seg_hdr, nic1_mbx_regs);
+   fill_seg(smbus_regs_seg_hdr, smbus_regs);
+   fill_seg(fc2_mbx_regs_seg_hdr, fc2_mbx_regs);
+   fill_seg(nic2_mbx_regs_seg_hdr, nic2_mbx_regs);
+   fill_seg(i2c_regs_seg_hdr, i2c_regs);
+   fill_seg(memc_regs_seg_hdr, memc_regs);
+   fill_seg(pbus_regs_seg_hdr, pbus_regs);
+   fill_seg(mde_regs_seg_hdr, mde_regs);
+   fill_seg(nic_regs_seg_hdr, nic_regs);
+   fill_seg(nic2_regs_seg_hdr, nic2_regs);
+   fill_seg(xgmac1_seg_hdr, xgmac1);
+   fill_seg(xgmac2_seg_hdr, xgmac2);
+   fill_seg(code_ram_seg_h

[RFC 1/3] Initialize devlink health dump framework for the dlge driver

2020-08-14 Thread Coiby Xu
Initialize devlink health dump framework for the dlge driver so the
coredump could be done via devlink.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/Makefile  |  2 +-
 drivers/staging/qlge/qlge.h|  9 +++
 drivers/staging/qlge/qlge_health.c | 43 ++
 drivers/staging/qlge/qlge_health.h |  2 ++
 drivers/staging/qlge/qlge_main.c   | 21 +++
 5 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/qlge/qlge_health.c
 create mode 100644 drivers/staging/qlge/qlge_health.h

diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile
index 1dc2568e820c..0a1e4c8dd546 100644
--- a/drivers/staging/qlge/Makefile
+++ b/drivers/staging/qlge/Makefile
@@ -5,4 +5,4 @@
 
 obj-$(CONFIG_QLGE) += qlge.o
 
-qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
+qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_health.o
diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h
index fc8c5ca8935d..055ded6dab60 100644
--- a/drivers/staging/qlge/qlge.h
+++ b/drivers/staging/qlge/qlge.h
@@ -2061,6 +2061,14 @@ struct nic_operations {
int (*port_initialize) (struct ql_adapter *);
 };
 
+
+
+struct qlge_devlink {
+struct ql_adapter *qdev;
+struct net_device *ndev;
+struct devlink_health_reporter *reporter;
+};
+
 /*
  * The main Adapter structure definition.
  * This structure has all fields relevant to the hardware.
@@ -2078,6 +2086,7 @@ struct ql_adapter {
struct pci_dev *pdev;
struct net_device *ndev;/* Parent NET device */
 
+   struct qlge_devlink *devlink;
/* Hardware information */
u32 chip_rev_id;
u32 fw_rev_id;
diff --git a/drivers/staging/qlge/qlge_health.c 
b/drivers/staging/qlge/qlge_health.c
new file mode 100644
index ..292f6b1827e1
--- /dev/null
+++ b/drivers/staging/qlge/qlge_health.c
@@ -0,0 +1,43 @@
+#include "qlge.h"
+#include "qlge_health.h"
+
+static int
+qlge_reporter_coredump(struct devlink_health_reporter *reporter,
+   struct devlink_fmsg *fmsg, void *priv_ctx,
+   struct netlink_ext_ack *extack)
+{
+   return 0;
+}
+
+static const struct devlink_health_reporter_ops qlge_reporter_ops = {
+   .name = "dummy",
+   .dump = qlge_reporter_coredump,
+};
+
+int qlge_health_create_reporters(struct qlge_devlink *priv)
+{
+   int err;
+
+   struct devlink_health_reporter *reporter;
+   struct devlink *devlink;
+
+   devlink = priv_to_devlink(priv);
+   reporter =
+   devlink_health_reporter_create(devlink, _reporter_ops,
+  0,
+  priv);
+   if (IS_ERR(reporter)) {
+   netdev_warn(priv->ndev,
+   "Failed to create reporter, err = %ld\n",
+   PTR_ERR(reporter));
+   return PTR_ERR(reporter);
+   }
+   priv->reporter = reporter;
+
+   if (err)
+   return err;
+
+   return 0;
+}
+
+
diff --git a/drivers/staging/qlge/qlge_health.h 
b/drivers/staging/qlge/qlge_health.h
new file mode 100644
index ..07d3bafab845
--- /dev/null
+++ b/drivers/staging/qlge/qlge_health.h
@@ -0,0 +1,2 @@
+#include 
+int qlge_health_create_reporters(struct qlge_devlink *priv);
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 1650de13842f..b2be7f4b7dd6 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -42,6 +42,7 @@
 #include 
 
 #include "qlge.h"
+#include "qlge_health.h"
 
 char qlge_driver_name[] = DRV_NAME;
 const char qlge_driver_version[] = DRV_VERSION;
@@ -4550,6 +4551,8 @@ static void ql_timer(struct timer_list *t)
mod_timer(>timer, jiffies + (5 * HZ));
 }
 
+static const struct devlink_ops qlge_devlink_ops;
+
 static int qlge_probe(struct pci_dev *pdev,
  const struct pci_device_id *pci_entry)
 {
@@ -4557,6 +4560,13 @@ static int qlge_probe(struct pci_dev *pdev,
struct ql_adapter *qdev = NULL;
static int cards_found;
int err = 0;
+   struct devlink *devlink;
+   struct qlge_devlink *qlge_dl;
+
+   devlink = devlink_alloc(_devlink_ops, sizeof(struct qlge_devlink));
+   if (!devlink)
+   return -ENOMEM;
+   qlge_dl = devlink_priv(devlink);
 
ndev = alloc_etherdev_mq(sizeof(struct ql_adapter),
 min(MAX_CPUS,
@@ -4615,6 +4625,15 @@ static int qlge_probe(struct pci_dev *pdev,
free_netdev(ndev);
return err;
}
+
+   err = devlink_register(devlink, >dev);
+   if (err)
+   devlink_free(devlink);
+
+   qlge_health_create_reporters(qlge_dl);
+   qlge_dl->qdev = qdev;
+   qlge_dl-&

Re: [PATCH v2 4/4] staging: qlge: replace pr_err with netdev_err

2020-06-29 Thread Coiby Xu

On Mon, Jun 29, 2020 at 02:30:04PM +0900, Benjamin Poirier wrote:

On 2020-06-27 22:58 +0800, Coiby Xu wrote:
[...]

 void ql_dump_qdev(struct ql_adapter *qdev)
 {
@@ -1611,99 +1618,100 @@ void ql_dump_qdev(struct ql_adapter *qdev)
 #ifdef QL_CB_DUMP
 void ql_dump_wqicb(struct wqicb *wqicb)
 {
-   pr_err("Dumping wqicb stuff...\n");
-   pr_err("wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len));
-   pr_err("wqicb->flags = %x\n", le16_to_cpu(wqicb->flags));
-   pr_err("wqicb->cq_id_rss = %d\n",
-  le16_to_cpu(wqicb->cq_id_rss));
-   pr_err("wqicb->rid = 0x%x\n", le16_to_cpu(wqicb->rid));
-   pr_err("wqicb->wq_addr = 0x%llx\n",
-  (unsigned long long)le64_to_cpu(wqicb->addr));
-   pr_err("wqicb->wq_cnsmr_idx_addr = 0x%llx\n",
-  (unsigned long long)le64_to_cpu(wqicb->cnsmr_idx_addr));
+   netdev_err(qdev->ndev, "Dumping wqicb stuff...\n");


drivers/staging/qlge/qlge_dbg.c:1621:13: error: ‘qdev’ undeclared (first use in 
this function); did you mean ‘cdev’?
1621 |  netdev_err(qdev->ndev, "Dumping wqicb stuff...\n");
 | ^~~~
 | cdev

[...]
and many more like that

Anyways, qlge_dbg.h is a dumpster. It has hundreds of lines of code
bitrotting away in ifdef land. See this comment from David Miller on the
topic of ifdef'ed debugging code:
https://lore.kernel.org/netdev/20200303.145916.1506066510928020193.da...@davemloft.net/


Thank you for spotting this problem! This issue could be fixed by
passing qdev to ql_dump_wqicb. Or are you suggesting we completely
remove qlge_dbg since it's only for the purpose of debugging the driver
by the developer?

Btw, I'm curious how you make this compiling error occur. Do you manually 
trigger
it via "QL_CB_DUMP=1 make M=drivers/staging/qlge" or use some automate
tools?

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 1/4] fix trailing */ in block comment

2020-06-27 Thread Coiby Xu

On Sat, Jun 27, 2020 at 12:47:08PM +0200, Greg Kroah-Hartman wrote:

On Sat, Jun 27, 2020 at 06:14:44PM +0800, Coiby Xu wrote:

Remove trailing "*/" in block comments.

Signed-off-by: Coiby Xu 


The subject lines of all of your patches should match other patches for
this driver.  It should look like "staging: qlge: ..."

Please fix up and resend a v2 of this series.

thanks,

greg k-h


Thank you for pointing out this issue!

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 4/4] staging: qlge: replace pr_err with netdev_err

2020-06-27 Thread Coiby Xu
Replace all pr_errs with netdev_err.

Suggested-by: Joe Perches 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_dbg.c | 568 
 1 file changed, 289 insertions(+), 279 deletions(-)

diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 63e965966ced..32fbd30a6a2e 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -647,7 +647,7 @@ static void ql_get_mac_protocol_registers(struct ql_adapter 
*qdev, u32 *buf)
max_offset = MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT;
break;
default:
-   pr_err("Bad type!!! 0x%08x\n", type);
+   netdev_err(qdev->ndev, "Bad type!!! 0x%08x\n", type);
max_index = 0;
max_offset = 0;
break;
@@ -1335,9 +1335,8 @@ static void ql_dump_intr_states(struct ql_adapter *qdev)
for (i = 0; i < qdev->intr_count; i++) {
ql_write32(qdev, INTR_EN, qdev->intr_context[i].intr_read_mask);
value = ql_read32(qdev, INTR_EN);
-   pr_err("%s: Interrupt %d is %s\n",
-  qdev->ndev->name, i,
-  (value & INTR_EN_EN ? "enabled" : "disabled"));
+   netdev_err(qdev->ndev, "Interrupt %d is %s\n", i,
+  (value & INTR_EN_EN ? "enabled" : "disabled"));
}
 }

@@ -1345,13 +1344,14 @@ static void ql_dump_intr_states(struct ql_adapter *qdev)
 do {   \
u32 data;   \
ql_read_xgmac_reg(qdev, reg, );\
-   pr_err("%s: %s = 0x%.08x\n", qdev->ndev->name, #reg, data); \
+   netdev_err(qdev->ndev, "%s = 0x%.08x\n", #reg, data); \
 } while (0)

 void ql_dump_xgmac_control_regs(struct ql_adapter *qdev)
 {
if (ql_sem_spinlock(qdev, qdev->xg_sem_mask)) {
-   pr_err("%s: Couldn't get xgmac sem\n", __func__);
+   netdev_err(qdev->ndev, "%s: Couldn't get xgmac sem\n",
+  __func__);
return;
}
DUMP_XGMAC(qdev, PAUSE_SRC_LO);
@@ -1388,25 +1388,28 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
return;
for (i = 0; i < 4; i++) {
if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) 
{
-   pr_err("%s: Failed read of mac index register\n",
-  __func__);
+   netdev_err(qdev->ndev,
+  "%s: Failed read of mac index register\n",
+  __func__);
break;
}
if (value[0])
-   pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
-  qdev->ndev->name, i, value[1], value[0],
-  value[2]);
+   netdev_err(qdev->ndev,
+  "CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
+  i, value[1], value[0], value[2]);
}
for (i = 0; i < 32; i++) {
if (ql_get_mac_addr_reg
(qdev, MAC_ADDR_TYPE_MULTI_MAC, i, value)) {
-   pr_err("%s: Failed read of mac index register\n",
-  __func__);
+   netdev_err(qdev->ndev,
+  "%s: Failed read of mac index register\n",
+  __func__);
break;
}
if (value[0])
-   pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
-  qdev->ndev->name, i, value[1], value[0]);
+   netdev_err(qdev->ndev,
+  "MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
+  i, value[1], value[0]);
}
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 }
@@ -1422,23 +1425,25 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
for (i = 0; i < 16; i++) {
value = 0;
if (ql_get_routing_reg(qdev, i, )) {
-   pr_err("%s: Failed read of routing index register\n",
-  __func__);
+   netdev_err(qdev->ndev,
+  "%s: Failed read of routing index 
register\n",
+

[PATCH v2 0/4] staging: qlge: coding style fix for the qlge driver

2020-06-27 Thread Coiby Xu
v2
 - let all patches' subject lines match the pattern "staging: qlge: ..."

These patches fix three coding style problems for all files under
drivers/staging/qlge,
- trailing */ in block comment
- unnecessary else after return or break
- pr_err preferred over netdev_err

and a bug about releasing lock.

Coiby Xu (4):
  fix trailing */ in block comment
  fix else after return or break
  fix ql_sem_unlock
  replace pr_err with netdev_err

 drivers/staging/qlge/qlge_dbg.c  | 583 ---
 drivers/staging/qlge/qlge_main.c |  11 +-
 drivers/staging/qlge/qlge_mpi.c  |  14 +-
 3 files changed, 309 insertions(+), 299 deletions(-)

--
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 1/4] staging: qlge: fix trailing */ in block comment

2020-06-27 Thread Coiby Xu
Remove trailing "*/" in block comments.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_main.c |  3 ++-
 drivers/staging/qlge/qlge_mpi.c  | 10 ++
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 1650de13842f..aaecf2b0f9a1 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3244,7 +3244,8 @@ static void ql_set_irq_mask(struct ql_adapter *qdev, 
struct intr_context *ctx)
 */
ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id);
/* Add the TX ring(s) serviced by this vector
-* to the mask. */
+* to the mask.
+*/
for (j = 0; j < tx_rings_per_vector; j++) {
ctx->irq_mask |=
(1 << qdev->rx_ring[qdev->rss_ring_count +
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index 60c08d9cc034..3bb08d290525 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -389,7 +389,8 @@ static void ql_init_fw_done(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
  *  This can get called iteratively from the mpi_work thread
  *  when events arrive via an interrupt.
  *  It also gets called when a mailbox command is polling for
- *  it's completion. */
+ *  it's completion.
+ */
 static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
 {
int status;
@@ -520,7 +521,7 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
 * changed when a mailbox command is waiting
 * for a response and an AEN arrives and
 * is handled.
-* */
+*/
mbcp->out_count = orig_count;
return status;
 }
@@ -555,7 +556,8 @@ static int ql_mailbox_command(struct ql_adapter *qdev, 
struct mbox_params *mbcp)
 * here because some AEN might arrive while
 * we're waiting for the mailbox command to
 * complete. If more than 5 seconds expire we can
-* assume something is wrong. */
+* assume something is wrong.
+*/
count = jiffies + HZ * MAILBOX_TIMEOUT;
do {
/* Wait for the interrupt to come in. */
@@ -1178,7 +1180,7 @@ void ql_mpi_idc_work(struct work_struct *work)
/* Signal the resulting link up AEN
 * that the frame routing and mac addr
 * needs to be set.
-* */
+*/
set_bit(QL_CAM_RT_SET, >flags);
/* Do ACK if required */
if (timeout) {
--
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 2/4] staging: qlge: fix else after return or break

2020-06-27 Thread Coiby Xu
Remove unnecessary elses after return or break.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_dbg.c  | 23 ++-
 drivers/staging/qlge/qlge_main.c |  8 
 drivers/staging/qlge/qlge_mpi.c  |  4 ++--
 3 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 058889687907..87433510a224 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1391,12 +1391,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of mac index register\n",
   __func__);
return;
-   } else {
-   if (value[0])
-   pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
-  qdev->ndev->name, i, value[1], value[0],
-  value[2]);
}
+   if (value[0])
+   pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
+  qdev->ndev->name, i, value[1], value[0],
+  value[2]);
}
for (i = 0; i < 32; i++) {
if (ql_get_mac_addr_reg
@@ -1404,11 +1403,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of mac index register\n",
   __func__);
return;
-   } else {
-   if (value[0])
-   pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
-  qdev->ndev->name, i, value[1], value[0]);
}
+   if (value[0])
+   pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
+  qdev->ndev->name, i, value[1], value[0]);
}
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 }
@@ -1427,11 +1425,10 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of routing index register\n",
   __func__);
return;
-   } else {
-   if (value)
-   pr_err("%s: Routing Mask %d = 0x%.08x\n",
-  qdev->ndev->name, i, value);
}
+   if (value)
+   pr_err("%s: Routing Mask %d = 0x%.08x\n",
+  qdev->ndev->name, i, value);
}
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
 }
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index aaecf2b0f9a1..0054c454506b 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3778,10 +3778,10 @@ static int ql_wol(struct ql_adapter *qdev)
  "Failed to set magic packet on %s.\n",
  qdev->ndev->name);
return status;
-   } else
-   netif_info(qdev, drv, qdev->ndev,
-  "Enabled magic packet successfully on %s.\n",
-  qdev->ndev->name);
+   }
+   netif_info(qdev, drv, qdev->ndev,
+  "Enabled magic packet successfully on %s.\n",
+  qdev->ndev->name);

wol |= MB_WOL_MAGIC_PKT;
}
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index 3bb08d290525..fa178fc642a6 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -276,8 +276,8 @@ static void ql_link_up(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
netif_err(qdev, ifup, qdev->ndev,
  "Failed to init CAM/Routing tables.\n");
return;
-   } else
-   clear_bit(QL_CAM_RT_SET, >flags);
+   }
+   clear_bit(QL_CAM_RT_SET, >flags);
}

/* Queue up a worker to check the frame
--
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 3/4] staging: qlge: fix ql_sem_unlock

2020-06-27 Thread Coiby Xu
Some functions return without releasing the lock. Replace return with
break.

Suggested-by Dan Carpenter .

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_dbg.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 87433510a224..63e965966ced 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1390,7 +1390,7 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) 
{
pr_err("%s: Failed read of mac index register\n",
   __func__);
-   return;
+   break;
}
if (value[0])
pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
@@ -1402,7 +1402,7 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
(qdev, MAC_ADDR_TYPE_MULTI_MAC, i, value)) {
pr_err("%s: Failed read of mac index register\n",
   __func__);
-   return;
+   break;
}
if (value[0])
pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
@@ -1424,7 +1424,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
if (ql_get_routing_reg(qdev, i, )) {
pr_err("%s: Failed read of routing index register\n",
   __func__);
-   return;
+   break;
}
if (value)
pr_err("%s: Routing Mask %d = 0x%.08x\n",
--
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] staging: qlge: fix else after return or break

2020-06-27 Thread Coiby Xu

On Fri, Jun 26, 2020 at 05:06:33PM -0700, Joe Perches wrote:

On Sat, 2020-06-27 at 07:57 +0800, Coiby Xu wrote:

On Thu, Jun 25, 2020 at 03:13:14PM -0700, Joe Perches wrote:
> On Fri, 2020-06-26 at 05:57 +0800, Coiby Xu wrote:
> > Remove unnecessary elses after return or break.
>
> unrelated trivia:

[]

> looks like all of these could use netdev_err

[]

should we also replace all pr_errs with netdev_err in
ql_dump_* functions?


Ideally, anywhere a struct netdevice * is available, it should
be used to output netdev_ in preference to pr_.


Thank you for the explaining!

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/4] fix trailing */ in block comment

2020-06-27 Thread Coiby Xu
Remove trailing "*/" in block comments.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_main.c |  3 ++-
 drivers/staging/qlge/qlge_mpi.c  | 10 ++
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 1650de13842f..aaecf2b0f9a1 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3244,7 +3244,8 @@ static void ql_set_irq_mask(struct ql_adapter *qdev, 
struct intr_context *ctx)
 */
ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id);
/* Add the TX ring(s) serviced by this vector
-* to the mask. */
+* to the mask.
+*/
for (j = 0; j < tx_rings_per_vector; j++) {
ctx->irq_mask |=
(1 << qdev->rx_ring[qdev->rss_ring_count +
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index 60c08d9cc034..3bb08d290525 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -389,7 +389,8 @@ static void ql_init_fw_done(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
  *  This can get called iteratively from the mpi_work thread
  *  when events arrive via an interrupt.
  *  It also gets called when a mailbox command is polling for
- *  it's completion. */
+ *  it's completion.
+ */
 static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
 {
int status;
@@ -520,7 +521,7 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
 * changed when a mailbox command is waiting
 * for a response and an AEN arrives and
 * is handled.
-* */
+*/
mbcp->out_count = orig_count;
return status;
 }
@@ -555,7 +556,8 @@ static int ql_mailbox_command(struct ql_adapter *qdev, 
struct mbox_params *mbcp)
 * here because some AEN might arrive while
 * we're waiting for the mailbox command to
 * complete. If more than 5 seconds expire we can
-* assume something is wrong. */
+* assume something is wrong.
+*/
count = jiffies + HZ * MAILBOX_TIMEOUT;
do {
/* Wait for the interrupt to come in. */
@@ -1178,7 +1180,7 @@ void ql_mpi_idc_work(struct work_struct *work)
/* Signal the resulting link up AEN
 * that the frame routing and mac addr
 * needs to be set.
-* */
+*/
set_bit(QL_CAM_RT_SET, >flags);
/* Do ACK if required */
if (timeout) {
-- 
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/4] staging: qlge: coding style fix for the qlge driver

2020-06-27 Thread Coiby Xu
These patches fix three coding style problems for all files under
drivers/staging/qlge,
- trailing */ in block comment
- unnecessary else after return or break
- pr_err preferred over netdev_err

and a bug about releasing lock.

Coiby Xu (4):
  fix trailing */ in block comment
  fix else after return or break
  fix ql_sem_unlock
  replace pr_err with netdev_err

 drivers/staging/qlge/qlge_dbg.c  | 583 ---
 drivers/staging/qlge/qlge_main.c |  11 +-
 drivers/staging/qlge/qlge_mpi.c  |  14 +-
 3 files changed, 309 insertions(+), 299 deletions(-)

--
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/4] replace pr_err with netdev_err

2020-06-27 Thread Coiby Xu
Replace all pr_errs with netdev_err.

Suggested-by: Joe Perches 
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_dbg.c | 568 
 1 file changed, 289 insertions(+), 279 deletions(-)

diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 63e965966ced..32fbd30a6a2e 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -647,7 +647,7 @@ static void ql_get_mac_protocol_registers(struct ql_adapter 
*qdev, u32 *buf)
max_offset = MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT;
break;
default:
-   pr_err("Bad type!!! 0x%08x\n", type);
+   netdev_err(qdev->ndev, "Bad type!!! 0x%08x\n", type);
max_index = 0;
max_offset = 0;
break;
@@ -1335,9 +1335,8 @@ static void ql_dump_intr_states(struct ql_adapter *qdev)
for (i = 0; i < qdev->intr_count; i++) {
ql_write32(qdev, INTR_EN, qdev->intr_context[i].intr_read_mask);
value = ql_read32(qdev, INTR_EN);
-   pr_err("%s: Interrupt %d is %s\n",
-  qdev->ndev->name, i,
-  (value & INTR_EN_EN ? "enabled" : "disabled"));
+   netdev_err(qdev->ndev, "Interrupt %d is %s\n", i,
+  (value & INTR_EN_EN ? "enabled" : "disabled"));
}
 }
 
@@ -1345,13 +1344,14 @@ static void ql_dump_intr_states(struct ql_adapter *qdev)
 do {   \
u32 data;   \
ql_read_xgmac_reg(qdev, reg, );\
-   pr_err("%s: %s = 0x%.08x\n", qdev->ndev->name, #reg, data); \
+   netdev_err(qdev->ndev, "%s = 0x%.08x\n", #reg, data); \
 } while (0)
 
 void ql_dump_xgmac_control_regs(struct ql_adapter *qdev)
 {
if (ql_sem_spinlock(qdev, qdev->xg_sem_mask)) {
-   pr_err("%s: Couldn't get xgmac sem\n", __func__);
+   netdev_err(qdev->ndev, "%s: Couldn't get xgmac sem\n",
+  __func__);
return;
}
DUMP_XGMAC(qdev, PAUSE_SRC_LO);
@@ -1388,25 +1388,28 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
return;
for (i = 0; i < 4; i++) {
if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) 
{
-   pr_err("%s: Failed read of mac index register\n",
-  __func__);
+   netdev_err(qdev->ndev,
+  "%s: Failed read of mac index register\n",
+  __func__);
break;
}
if (value[0])
-   pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
-  qdev->ndev->name, i, value[1], value[0],
-  value[2]);
+   netdev_err(qdev->ndev,
+  "CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
+  i, value[1], value[0], value[2]);
}
for (i = 0; i < 32; i++) {
if (ql_get_mac_addr_reg
(qdev, MAC_ADDR_TYPE_MULTI_MAC, i, value)) {
-   pr_err("%s: Failed read of mac index register\n",
-  __func__);
+   netdev_err(qdev->ndev,
+  "%s: Failed read of mac index register\n",
+  __func__);
break;
}
if (value[0])
-   pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
-  qdev->ndev->name, i, value[1], value[0]);
+   netdev_err(qdev->ndev,
+  "MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
+  i, value[1], value[0]);
}
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 }
@@ -1422,23 +1425,25 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
for (i = 0; i < 16; i++) {
value = 0;
if (ql_get_routing_reg(qdev, i, )) {
-   pr_err("%s: Failed read of routing index register\n",
-  __func__);
+   netdev_err(qdev->ndev,
+  "%s: Failed read of routing index 
register\n",
+

[PATCH 2/4] fix else after return or break

2020-06-27 Thread Coiby Xu
Remove unnecessary elses after return or break.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_dbg.c  | 23 ++-
 drivers/staging/qlge/qlge_main.c |  8 
 drivers/staging/qlge/qlge_mpi.c  |  4 ++--
 3 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 058889687907..87433510a224 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1391,12 +1391,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of mac index register\n",
   __func__);
return;
-   } else {
-   if (value[0])
-   pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
-  qdev->ndev->name, i, value[1], value[0],
-  value[2]);
}
+   if (value[0])
+   pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
+  qdev->ndev->name, i, value[1], value[0],
+  value[2]);
}
for (i = 0; i < 32; i++) {
if (ql_get_mac_addr_reg
@@ -1404,11 +1403,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of mac index register\n",
   __func__);
return;
-   } else {
-   if (value[0])
-   pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
-  qdev->ndev->name, i, value[1], value[0]);
}
+   if (value[0])
+   pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
+  qdev->ndev->name, i, value[1], value[0]);
}
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 }
@@ -1427,11 +1425,10 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of routing index register\n",
   __func__);
return;
-   } else {
-   if (value)
-   pr_err("%s: Routing Mask %d = 0x%.08x\n",
-  qdev->ndev->name, i, value);
}
+   if (value)
+   pr_err("%s: Routing Mask %d = 0x%.08x\n",
+  qdev->ndev->name, i, value);
}
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
 }
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index aaecf2b0f9a1..0054c454506b 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3778,10 +3778,10 @@ static int ql_wol(struct ql_adapter *qdev)
  "Failed to set magic packet on %s.\n",
  qdev->ndev->name);
return status;
-   } else
-   netif_info(qdev, drv, qdev->ndev,
-  "Enabled magic packet successfully on %s.\n",
-  qdev->ndev->name);
+   }
+   netif_info(qdev, drv, qdev->ndev,
+  "Enabled magic packet successfully on %s.\n",
+  qdev->ndev->name);
 
wol |= MB_WOL_MAGIC_PKT;
}
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index 3bb08d290525..fa178fc642a6 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -276,8 +276,8 @@ static void ql_link_up(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
netif_err(qdev, ifup, qdev->ndev,
  "Failed to init CAM/Routing tables.\n");
return;
-   } else
-   clear_bit(QL_CAM_RT_SET, >flags);
+   }
+   clear_bit(QL_CAM_RT_SET, >flags);
}
 
/* Queue up a worker to check the frame
-- 
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/4] fix ql_sem_unlock

2020-06-27 Thread Coiby Xu
Some functions return without releasing the lock. Replace return with
break.

Suggested-by Dan Carpenter .

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_dbg.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 87433510a224..63e965966ced 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1390,7 +1390,7 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) 
{
pr_err("%s: Failed read of mac index register\n",
   __func__);
-   return;
+   break;
}
if (value[0])
pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
@@ -1402,7 +1402,7 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
(qdev, MAC_ADDR_TYPE_MULTI_MAC, i, value)) {
pr_err("%s: Failed read of mac index register\n",
   __func__);
-   return;
+   break;
}
if (value[0])
pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
@@ -1424,7 +1424,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
if (ql_get_routing_reg(qdev, i, )) {
pr_err("%s: Failed read of routing index register\n",
   __func__);
-   return;
+   break;
}
if (value)
pr_err("%s: Routing Mask %d = 0x%.08x\n",
-- 
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] staging: qlge: fix else after return or break

2020-06-26 Thread Coiby Xu

On Thu, Jun 25, 2020 at 03:13:14PM -0700, Joe Perches wrote:

On Fri, 2020-06-26 at 05:57 +0800, Coiby Xu wrote:

Remove unnecessary elses after return or break.


unrelated trivia:


diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c

[]

@@ -1391,12 +1391,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of mac index register\n",
   __func__);
return;
-   } else {
-   if (value[0])
-   pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
-  qdev->ndev->name, i, value[1], value[0],
-  value[2]);


looks like all of these could use netdev_err

netdev_err(qdev, "etc...",
   i, value[1], value[0], value[2]);

etc...


Should we also replace all pr_errs with netdev_err in
ql_dump_* functions? I'm not sure how we will use ql_dump_*. For example,
ql_dump_regs is not referred by any kernel source, so I guess it's for
the sole purpose of debugging the driver by the developer. But one
pr_err in ql_dump_routing_entries which is called by dl_dump_regs doesn't
prints out the device name whereas the other does,


void ql_dump_routing_entries(struct ql_adapter *qdev)
{
int i;
u32 value;

i = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
if (i)
return;
for (i = 0; i < 16; i++) {
value = 0;
if (ql_get_routing_reg(qdev, i, )) {
pr_err("%s: Failed read of routing index register\n",
   __func__);
break;
}
if (value)
pr_err("%s: Routing Mask %d = 0x%.08x\n",
   qdev->ndev->name, i, value);
}


--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] staging: qlge: fix else after return or break

2020-06-26 Thread Coiby Xu

On Thu, Jun 25, 2020 at 03:13:14PM -0700, Joe Perches wrote:

On Fri, 2020-06-26 at 05:57 +0800, Coiby Xu wrote:

Remove unnecessary elses after return or break.


unrelated trivia:


diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c

[]

@@ -1391,12 +1391,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of mac index register\n",
   __func__);
return;
-   } else {
-   if (value[0])
-   pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
-  qdev->ndev->name, i, value[1], value[0],
-  value[2]);


looks like all of these could use netdev_err

netdev_err(qdev, "etc...",
   i, value[1], value[0], value[2]);

etc...


Interestingly, scripts/checkpatch.pl couldn't detect this problem.
I once used printk(KERN_ALERT...) and the script would properly warn me
that,

WARNING: Prefer [subsystem eg: netdev]_alert([subsystem]dev, ... then 
dev_alert(dev, ... then pr_alert(...  to printk(KERN_ALERT .

I'll fix this issue when sending another version of the patches. Thank
you for the reminding!

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] staging: qlge: fix else after return or break

2020-06-26 Thread Coiby Xu

On Fri, Jun 26, 2020 at 11:34:36AM +0300, Dan Carpenter wrote:

On Fri, Jun 26, 2020 at 05:57:55AM +0800, Coiby Xu wrote:

@@ -1404,11 +1403,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of mac index register\n",
   __func__);
return;

   ^^

-   } else {
-   if (value[0])
-   pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
-  qdev->ndev->name, i, value[1], value[0]);
}
+   if (value[0])
+   pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
+  qdev->ndev->name, i, value[1], value[0]);
}
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);

   ^^^

 }
@@ -1427,11 +1425,10 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of routing index register\n",
   __func__);
return;

   ^^



-   } else {
-   if (value)
-   pr_err("%s: Routing Mask %d = 0x%.08x\n",
-  qdev->ndev->name, i, value);
}
+   if (value)
+   pr_err("%s: Routing Mask %d = 0x%.08x\n",
+  qdev->ndev->name, i, value);
}
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);

   

 }


This is not caused by your patch, but in these two functions we return
without dropping the lock.  There may be other places as well, but these
are the two I can see without leaving my email client.

Do you think you could fix that before we forget?  Just change the
return to a break to fix the bug.


Sure, I'll address this issue in the next series
of patches. Thank you for bringing up this issue!

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 1/2] fix trailing */ in block comment

2020-06-25 Thread Coiby Xu

On Thu, Jun 25, 2020 at 08:25:10PM +0300, Dan Carpenter wrote:

The subject isn't right (no subsystem prefix) and we need a commit
message.

regards,
dan carpenter


Thank you for pointing out the exact problems!

--
Best regards,
Coiby
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/2] staging: qlge: fix trailing */ in block comment

2020-06-25 Thread Coiby Xu
Remove trailing "*/" in block comments.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_main.c |  3 ++-
 drivers/staging/qlge/qlge_mpi.c  | 10 ++
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 1650de13842f..aaecf2b0f9a1 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3244,7 +3244,8 @@ static void ql_set_irq_mask(struct ql_adapter *qdev, 
struct intr_context *ctx)
 */
ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id);
/* Add the TX ring(s) serviced by this vector
-* to the mask. */
+* to the mask.
+*/
for (j = 0; j < tx_rings_per_vector; j++) {
ctx->irq_mask |=
(1 << qdev->rx_ring[qdev->rss_ring_count +
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index 60c08d9cc034..3bb08d290525 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -389,7 +389,8 @@ static void ql_init_fw_done(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
  *  This can get called iteratively from the mpi_work thread
  *  when events arrive via an interrupt.
  *  It also gets called when a mailbox command is polling for
- *  it's completion. */
+ *  it's completion.
+ */
 static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
 {
int status;
@@ -520,7 +521,7 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
 * changed when a mailbox command is waiting
 * for a response and an AEN arrives and
 * is handled.
-* */
+*/
mbcp->out_count = orig_count;
return status;
 }
@@ -555,7 +556,8 @@ static int ql_mailbox_command(struct ql_adapter *qdev, 
struct mbox_params *mbcp)
 * here because some AEN might arrive while
 * we're waiting for the mailbox command to
 * complete. If more than 5 seconds expire we can
-* assume something is wrong. */
+* assume something is wrong.
+*/
count = jiffies + HZ * MAILBOX_TIMEOUT;
do {
/* Wait for the interrupt to come in. */
@@ -1178,7 +1180,7 @@ void ql_mpi_idc_work(struct work_struct *work)
/* Signal the resulting link up AEN
 * that the frame routing and mac addr
 * needs to be set.
-* */
+*/
set_bit(QL_CAM_RT_SET, >flags);
/* Do ACK if required */
if (timeout) {
--
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] staging: qlge: fix else after return or break

2020-06-25 Thread Coiby Xu
Remove unnecessary elses after return or break.

Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_dbg.c  | 23 ++-
 drivers/staging/qlge/qlge_main.c |  8 
 drivers/staging/qlge/qlge_mpi.c  |  4 ++--
 3 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
index 058889687907..87433510a224 100644
--- a/drivers/staging/qlge/qlge_dbg.c
+++ b/drivers/staging/qlge/qlge_dbg.c
@@ -1391,12 +1391,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of mac index register\n",
   __func__);
return;
-   } else {
-   if (value[0])
-   pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
-  qdev->ndev->name, i, value[1], value[0],
-  value[2]);
}
+   if (value[0])
+   pr_err("%s: CAM index %d CAM Lookup Lower = 
0x%.08x:%.08x, Output = 0x%.08x\n",
+  qdev->ndev->name, i, value[1], value[0],
+  value[2]);
}
for (i = 0; i < 32; i++) {
if (ql_get_mac_addr_reg
@@ -1404,11 +1403,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of mac index register\n",
   __func__);
return;
-   } else {
-   if (value[0])
-   pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
-  qdev->ndev->name, i, value[1], value[0]);
}
+   if (value[0])
+   pr_err("%s: MCAST index %d CAM Lookup Lower = 
0x%.08x:%.08x\n",
+  qdev->ndev->name, i, value[1], value[0]);
}
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 }
@@ -1427,11 +1425,10 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
pr_err("%s: Failed read of routing index register\n",
   __func__);
return;
-   } else {
-   if (value)
-   pr_err("%s: Routing Mask %d = 0x%.08x\n",
-  qdev->ndev->name, i, value);
}
+   if (value)
+   pr_err("%s: Routing Mask %d = 0x%.08x\n",
+  qdev->ndev->name, i, value);
}
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
 }
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index aaecf2b0f9a1..0054c454506b 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3778,10 +3778,10 @@ static int ql_wol(struct ql_adapter *qdev)
  "Failed to set magic packet on %s.\n",
  qdev->ndev->name);
return status;
-   } else
-   netif_info(qdev, drv, qdev->ndev,
-  "Enabled magic packet successfully on %s.\n",
-  qdev->ndev->name);
+   }
+   netif_info(qdev, drv, qdev->ndev,
+  "Enabled magic packet successfully on %s.\n",
+  qdev->ndev->name);

wol |= MB_WOL_MAGIC_PKT;
}
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index 3bb08d290525..fa178fc642a6 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -276,8 +276,8 @@ static void ql_link_up(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
netif_err(qdev, ifup, qdev->ndev,
  "Failed to init CAM/Routing tables.\n");
return;
-   } else
-   clear_bit(QL_CAM_RT_SET, >flags);
+   }
+   clear_bit(QL_CAM_RT_SET, >flags);
}

/* Queue up a worker to check the frame
--
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/2] staging: qlge: coding style fix for the qlge driver

2020-06-25 Thread Coiby Xu
These two patches fix two coding style problems for all files under
drivers/staging/qlge as reported by checkpatch.pl,
- trailing */ in block comment
- unnecessary else after return or break

Coiby Xu (2):
  fix trailing */ in block comment
  fix else after return or break

 drivers/staging/qlge/qlge_dbg.c  | 23 ++-
 drivers/staging/qlge/qlge_main.c | 11 ++-
 drivers/staging/qlge/qlge_mpi.c  | 14 --
 3 files changed, 24 insertions(+), 24 deletions(-)

--
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/2] fix trailing */ in block comment

2020-06-25 Thread Coiby Xu
Signed-off-by: Coiby Xu 
---
 drivers/staging/qlge/qlge_main.c |  3 ++-
 drivers/staging/qlge/qlge_mpi.c  | 10 ++
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 1650de13842f..aaecf2b0f9a1 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -3244,7 +3244,8 @@ static void ql_set_irq_mask(struct ql_adapter *qdev, 
struct intr_context *ctx)
 */
ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id);
/* Add the TX ring(s) serviced by this vector
-* to the mask. */
+* to the mask.
+*/
for (j = 0; j < tx_rings_per_vector; j++) {
ctx->irq_mask |=
(1 << qdev->rx_ring[qdev->rss_ring_count +
diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c
index 60c08d9cc034..3bb08d290525 100644
--- a/drivers/staging/qlge/qlge_mpi.c
+++ b/drivers/staging/qlge/qlge_mpi.c
@@ -389,7 +389,8 @@ static void ql_init_fw_done(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
  *  This can get called iteratively from the mpi_work thread
  *  when events arrive via an interrupt.
  *  It also gets called when a mailbox command is polling for
- *  it's completion. */
+ *  it's completion.
+ */
 static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
 {
int status;
@@ -520,7 +521,7 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct 
mbox_params *mbcp)
 * changed when a mailbox command is waiting
 * for a response and an AEN arrives and
 * is handled.
-* */
+*/
mbcp->out_count = orig_count;
return status;
 }
@@ -555,7 +556,8 @@ static int ql_mailbox_command(struct ql_adapter *qdev, 
struct mbox_params *mbcp)
 * here because some AEN might arrive while
 * we're waiting for the mailbox command to
 * complete. If more than 5 seconds expire we can
-* assume something is wrong. */
+* assume something is wrong.
+*/
count = jiffies + HZ * MAILBOX_TIMEOUT;
do {
/* Wait for the interrupt to come in. */
@@ -1178,7 +1180,7 @@ void ql_mpi_idc_work(struct work_struct *work)
/* Signal the resulting link up AEN
 * that the frame routing and mac addr
 * needs to be set.
-* */
+*/
set_bit(QL_CAM_RT_SET, >flags);
/* Do ACK if required */
if (timeout) {
-- 
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


  1   2   >