Thread (4 messages) 4 messages, 2 authors, 2021-12-24

Re: [PATCH v8, 2/2] net: Add dm9051 driver

From: Andrew Lunn <andrew@lunn.ch>
Date: 2021-12-24 18:37:14
Also in: lkml, netdev

+config DM9051
+	tristate "DM9051 SPI support"
+	select PHYLIB
+	depends on SPI
+	select CRC32
+	select MII
Since you are using PHYLIB, you should not require MII.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
+#include <linux/phy.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/cache.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/iopoll.h>
+#include <linux/of_gpio.h>
+#include <linux/spi/spi.h>
+
+#include "dm9051.h"
+
+static int msg_enable = NETIF_MSG_PROBE |
+			NETIF_MSG_LINK |
+			NETIF_MSG_IFDOWN |
+			NETIF_MSG_IFUP |
+			NETIF_MSG_RX_ERR |
+			NETIF_MSG_TX_ERR;
+
+module_param(msg_enable, int, 0);
+MODULE_PARM_DESC(msg_enable, "Message mask bitmapped");
No module parameters please. You have the need ethtool ops to control
this.
+
+/* spi low level code */
+static inline int dm9051_xfer(struct board_info *db, u8 cmd, u8 *txb, u8 *rxb, unsigned int len)
No inline functions in C code, let the compiler decide.
+{
+	struct device *dev = &db->spidev->dev;
+	int ret;
+
+	db->cmd[0] = cmd;
+	db->spi_xfer2[0].tx_buf = &db->cmd[0];
+	db->spi_xfer2[0].rx_buf = NULL;
+	db->spi_xfer2[0].len = 1;
+	if (!rxb) {
+		db->spi_xfer2[1].tx_buf = txb;
+		db->spi_xfer2[1].rx_buf = NULL;
+		db->spi_xfer2[1].len = len;
+	} else {
+		db->spi_xfer2[1].tx_buf = txb;
+		db->spi_xfer2[1].rx_buf = rxb;
+		db->spi_xfer2[1].len = len;
+	}
Nit pick, but i would invert the logic here, to make it more natural.
+	ret = spi_sync(db->spidev, &db->spi_msg);
+	if (ret < 0)
+		dev_err(dev, "spi burst cmd 0x%02x, ret=%d\n", cmd, ret);
+	return ret;
+}
+
+static u8 dm9051_ior(struct board_info *db, unsigned int reg)
+{
+	int ret;
+	u8 rxb[1];
+
+	ret = dm9051_xfer(db, DM_SPI_RD | reg, NULL, rxb, 1);
+	if (ret < 0)
+		return 0xff;
No, return the error code which dm9051_xfer() returns.
+	return rxb[0];
+}
+
+static void dm9051_iow(struct board_info *db, unsigned int reg, unsigned int val)
+{
+	u8 txb[1];
+
+	txb[0] = val;
+	dm9051_xfer(db, DM_SPI_WR | reg, txb, NULL, 1);
This should be an int function, which returns 0, or the error code
which dm9051_xfer() returns.
+}
+
+static int dm9051_inblk(struct board_info *db, u8 *buff, unsigned int len)
+{
+	int ret;
+	u8 txb[1];
+
+	ret = dm9051_xfer(db, DM_SPI_RD | DM_SPI_MRCMD, txb, buff, len);
+	return ret;
+}
+
+static void dm9051_dumpblk(struct board_info *db, unsigned int len)
+{
+	while (len--)
+		dm9051_ior(db, DM_SPI_MRCMD);
and here you need to look for an error from dm9051_ior() and return it
to the caller etc.
+static int dm9051_phy_read(struct board_info *db, int reg, int *pvalue)
+{
+	int ret;
+	u8 check_val;
+
+	dm9051_iow(db, DM9051_EPAR, DM9051_PHY | reg);
+	dm9051_iow(db, DM9051_EPCR, EPCR_ERPRR | EPCR_EPOS);
+	ret = read_poll_timeout(dm9051_ior, check_val, !(check_val & EPCR_ERRE), 100, 10000,
+				true, db, DM9051_EPCR);
+	dm9051_iow(db, DM9051_EPCR, 0x0);
+	if (ret) {
+		netdev_err(db->ndev, "timeout read phy register\n");
+		return -ETIMEDOUT;
+	}
You should check for an error before doing the dm9051_iow(). And don't
return -ETIMEDOUT, return whatever read_poll_timeout() returns as an
error code.

Your error handling in this driver needs a lot of work. Please improve
it for the next submission. Error codes need returning as far as
possible up the call stack.

	 Andrew
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help