From: Marek Vasut <marex@denx.de>
To: netdev@vger.kernel.org
Cc: Marek Vasut <marex@denx.de>, Andrew Lunn <andrew@lunn.ch>,
"David S . Miller" <davem@davemloft.net>,
Lukas Wunner <lukas@wunner.de>, Petr Stetiar <ynezz@true.cz>,
YueHaibing <yuehaibing@huawei.com>
Subject: [PATCH V7 16/19] net: ks8851: Implement register, FIFO, lock accessor callbacks
Date: Fri, 29 May 2020 00:21:43 +0200 [thread overview]
Message-ID: <20200528222146.348805-17-marex@denx.de> (raw)
In-Reply-To: <20200528222146.348805-1-marex@denx.de>
The register and FIFO accessors are bus specific, so is locking.
Implement callbacks so that each variant of the KS8851 can implement
matching accessors and locking, and use the rest of the common code.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: Lukas Wunner <lukas@wunner.de>
Cc: Petr Stetiar <ynezz@true.cz>
Cc: YueHaibing <yuehaibing@huawei.com>
---
V4: New patch
V5: No change
V6: No change
V7: Add kerneldoc entries for new struct ks8851_net fields
and for ks argument to ks8851_rx_skb{,_spi}()
---
drivers/net/ethernet/micrel/ks8851.c | 178 +++++++++++++++++++++++----
1 file changed, 156 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c
index baf424f9893b..1fa907d5dd5b 100644
--- a/drivers/net/ethernet/micrel/ks8851.c
+++ b/drivers/net/ethernet/micrel/ks8851.c
@@ -81,6 +81,15 @@ union ks8851_tx_hdr {
* @vdd_reg: Optional regulator supplying the chip
* @vdd_io: Optional digital power supply for IO
* @gpio: Optional reset_n gpio
+ * @lock: Bus access lock callback
+ * @unlock: Bus access unlock callback
+ * @rdreg16: 16bit register read callback
+ * @wrreg16: 16bit register write callback
+ * @rdfifo: FIFO read callback
+ * @wrfifo: FIFO write callback
+ * @start_xmit: start_xmit() implementation callback
+ * @rx_skb: rx_skb() implementation callback
+ * @flush_tx_work: flush_tx_work() implementation callback
*
* The @statelock is used to protect information in the structure which may
* need to be accessed via several sources, such as the network driver layer
@@ -117,6 +126,24 @@ struct ks8851_net {
struct regulator *vdd_reg;
struct regulator *vdd_io;
int gpio;
+
+ void (*lock)(struct ks8851_net *ks,
+ unsigned long *flags);
+ void (*unlock)(struct ks8851_net *ks,
+ unsigned long *flags);
+ unsigned int (*rdreg16)(struct ks8851_net *ks,
+ unsigned int reg);
+ void (*wrreg16)(struct ks8851_net *ks,
+ unsigned int reg, unsigned int val);
+ void (*rdfifo)(struct ks8851_net *ks, u8 *buff,
+ unsigned int len);
+ void (*wrfifo)(struct ks8851_net *ks,
+ struct sk_buff *txp, bool irq);
+ netdev_tx_t (*start_xmit)(struct sk_buff *skb,
+ struct net_device *dev);
+ void (*rx_skb)(struct ks8851_net *ks,
+ struct sk_buff *skb);
+ void (*flush_tx_work)(struct ks8851_net *ks);
};
/**
@@ -161,13 +188,13 @@ static int msg_enable;
#define MK_OP(_byteen, _reg) (BYTE_EN(_byteen) | (_reg) << (8+2) | (_reg) >> 6)
/**
- * ks8851_lock - register access lock
+ * ks8851_lock_spi - register access lock for SPI
* @ks: The chip state
* @flags: Spinlock flags
*
* Claim chip register access lock
*/
-static void ks8851_lock(struct ks8851_net *ks, unsigned long *flags)
+static void ks8851_lock_spi(struct ks8851_net *ks, unsigned long *flags)
{
struct ks8851_net_spi *kss = to_ks8851_spi(ks);
@@ -175,19 +202,43 @@ static void ks8851_lock(struct ks8851_net *ks, unsigned long *flags)
}
/**
- * ks8851_unlock - register access unlock
+ * ks8851_unlock_spi - register access unlock for SPI
* @ks: The chip state
* @flags: Spinlock flags
*
* Release chip register access lock
*/
-static void ks8851_unlock(struct ks8851_net *ks, unsigned long *flags)
+static void ks8851_unlock_spi(struct ks8851_net *ks, unsigned long *flags)
{
struct ks8851_net_spi *kss = to_ks8851_spi(ks);
mutex_unlock(&kss->lock);
}
+/**
+ * ks8851_lock - register access lock
+ * @ks: The chip state
+ * @flags: Spinlock flags
+ *
+ * Claim chip register access lock
+ */
+static void ks8851_lock(struct ks8851_net *ks, unsigned long *flags)
+{
+ ks->lock(ks, flags);
+}
+
+/**
+ * ks8851_unlock - register access unlock
+ * @ks: The chip state
+ * @flags: Spinlock flags
+ *
+ * Release chip register access lock
+ */
+static void ks8851_unlock(struct ks8851_net *ks, unsigned long *flags)
+{
+ ks->unlock(ks, flags);
+}
+
/* SPI register read/write calls.
*
* All these calls issue SPI transactions to access the chip's registers. They
@@ -196,14 +247,15 @@ static void ks8851_unlock(struct ks8851_net *ks, unsigned long *flags)
*/
/**
- * ks8851_wrreg16 - write 16bit register value to chip
+ * ks8851_wrreg16_spi - write 16bit register value to chip via SPI
* @ks: The chip state
* @reg: The register address
* @val: The value to write
*
* Issue a write to put the value @val into the register specified in @reg.
*/
-static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val)
+static void ks8851_wrreg16_spi(struct ks8851_net *ks, unsigned int reg,
+ unsigned int val)
{
struct ks8851_net_spi *kss = to_ks8851_spi(ks);
struct spi_transfer *xfer = &kss->spi_xfer1;
@@ -223,6 +275,20 @@ static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val)
netdev_err(ks->netdev, "spi_sync() failed\n");
}
+/**
+ * ks8851_wrreg16 - write 16bit register value to chip
+ * @ks: The chip state
+ * @reg: The register address
+ * @val: The value to write
+ *
+ * Issue a write to put the value @val into the register specified in @reg.
+ */
+static void ks8851_wrreg16(struct ks8851_net *ks, unsigned int reg,
+ unsigned int val)
+{
+ ks->wrreg16(ks, reg, val);
+}
+
/**
* ks8851_rdreg - issue read register command and return the data
* @ks: The device state
@@ -276,13 +342,14 @@ static void ks8851_rdreg(struct ks8851_net *ks, unsigned op,
}
/**
- * ks8851_rdreg16 - read 16 bit register from device
+ * ks8851_rdreg16_spi - read 16 bit register from device via SPI
* @ks: The chip information
* @reg: The register address
*
* Read a 16bit register from the chip, returning the result
*/
-static unsigned ks8851_rdreg16(struct ks8851_net *ks, unsigned reg)
+static unsigned int ks8851_rdreg16_spi(struct ks8851_net *ks,
+ unsigned int reg)
{
__le16 rx = 0;
@@ -290,6 +357,19 @@ static unsigned ks8851_rdreg16(struct ks8851_net *ks, unsigned reg)
return le16_to_cpu(rx);
}
+/**
+ * ks8851_rdreg16 - read 16 bit register from device
+ * @ks: The chip information
+ * @reg: The register address
+ *
+ * Read a 16bit register from the chip, returning the result
+ */
+static unsigned int ks8851_rdreg16(struct ks8851_net *ks,
+ unsigned int reg)
+{
+ return ks->rdreg16(ks, reg);
+}
+
/**
* ks8851_soft_reset - issue one of the soft reset to the device
* @ks: The device state.
@@ -429,7 +509,7 @@ static void ks8851_init_mac(struct ks8851_net *ks, struct device_node *np)
}
/**
- * ks8851_rdfifo - read data from the receive fifo
+ * ks8851_rdfifo_spi - read data from the receive fifo via SPI
* @ks: The device state.
* @buff: The buffer address
* @len: The length of the data to read
@@ -437,7 +517,8 @@ static void ks8851_init_mac(struct ks8851_net *ks, struct device_node *np)
* Issue an RXQ FIFO read command and read the @len amount of data from
* the FIFO into the buffer specified by @buff.
*/
-static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len)
+static void ks8851_rdfifo_spi(struct ks8851_net *ks, u8 *buff,
+ unsigned int len)
{
struct ks8851_net_spi *kss = to_ks8851_spi(ks);
struct spi_transfer *xfer = kss->spi_xfer2;
@@ -482,14 +563,25 @@ static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt)
}
/**
- * ks8851_rx_skb - receive skbuff
+ * ks8851_rx_skb_spi - receive skbuff for SPI
+ * @ks: The device state
* @skb: The skbuff
*/
-static void ks8851_rx_skb(struct sk_buff *skb)
+static void ks8851_rx_skb_spi(struct ks8851_net *ks, struct sk_buff *skb)
{
netif_rx_ni(skb);
}
+/**
+ * ks8851_rx_skb - receive skbuff
+ * @ks: The device state
+ * @skb: The skbuff
+ */
+static void ks8851_rx_skb(struct ks8851_net *ks, struct sk_buff *skb)
+{
+ ks->rx_skb(ks, skb);
+}
+
/**
* ks8851_rx_pkts - receive packets from the host
* @ks: The device information.
@@ -552,13 +644,13 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
rxpkt = skb_put(skb, rxlen) - 8;
- ks8851_rdfifo(ks, rxpkt, rxalign + 8);
+ ks->rdfifo(ks, rxpkt, rxalign + 8);
if (netif_msg_pktdata(ks))
ks8851_dbg_dumpkkt(ks, rxpkt);
skb->protocol = eth_type_trans(skb, ks->netdev);
- ks8851_rx_skb(skb);
+ ks8851_rx_skb(ks, skb);
ks->netdev->stats.rx_packets++;
ks->netdev->stats.rx_bytes += rxlen;
@@ -682,7 +774,7 @@ static inline unsigned calc_txlen(unsigned len)
}
/**
- * ks8851_wrpkt - write packet to TX FIFO
+ * ks8851_wrpkt_spi - write packet to TX FIFO via SPI
* @ks: The device state.
* @txp: The sk_buff to transmit.
* @irq: IRQ on completion of the packet.
@@ -692,7 +784,8 @@ static inline unsigned calc_txlen(unsigned len)
* needs, such as IRQ on completion. Send the header and the packet data to
* the device.
*/
-static void ks8851_wrpkt(struct ks8851_net *ks, struct sk_buff *txp, bool irq)
+static void ks8851_wrpkt_spi(struct ks8851_net *ks, struct sk_buff *txp,
+ bool irq)
{
struct ks8851_net_spi *kss = to_ks8851_spi(ks);
struct spi_transfer *xfer = kss->spi_xfer2;
@@ -770,7 +863,7 @@ static void ks8851_tx_work(struct work_struct *work)
if (txb != NULL) {
ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
- ks8851_wrpkt(ks, txb, last);
+ ks->wrfifo(ks, txb, last);
ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
@@ -782,16 +875,26 @@ static void ks8851_tx_work(struct work_struct *work)
}
/**
- * ks8851_flush_tx_work - flush outstanding TX work
+ * ks8851_flush_tx_work_spi - flush outstanding TX work for SPI
* @ks: The device state
*/
-static void ks8851_flush_tx_work(struct ks8851_net *ks)
+static void ks8851_flush_tx_work_spi(struct ks8851_net *ks)
{
struct ks8851_net_spi *kss = to_ks8851_spi(ks);
flush_work(&kss->tx_work);
}
+/**
+ * ks8851_flush_tx_work - flush outstanding TX work
+ * @ks: The device state
+ */
+static void ks8851_flush_tx_work(struct ks8851_net *ks)
+{
+ if (ks->flush_tx_work)
+ ks->flush_tx_work(ks);
+}
+
/**
* ks8851_net_open - open network device
* @dev: The network device being opened.
@@ -925,7 +1028,7 @@ static int ks8851_net_stop(struct net_device *dev)
}
/**
- * ks8851_start_xmit - transmit packet
+ * ks8851_start_xmit_spi - transmit packet using SPI
* @skb: The buffer to transmit
* @dev: The device used to transmit the packet.
*
@@ -937,8 +1040,8 @@ static int ks8851_net_stop(struct net_device *dev)
* and secondly so we can round up more than one packet to transmit which
* means we can try and avoid generating too many transmit done interrupts.
*/
-static netdev_tx_t ks8851_start_xmit(struct sk_buff *skb,
- struct net_device *dev)
+static netdev_tx_t ks8851_start_xmit_spi(struct sk_buff *skb,
+ struct net_device *dev)
{
struct ks8851_net *ks = netdev_priv(dev);
unsigned needed = calc_txlen(skb->len);
@@ -966,6 +1069,27 @@ static netdev_tx_t ks8851_start_xmit(struct sk_buff *skb,
return ret;
}
+/**
+ * ks8851_start_xmit - transmit packet
+ * @skb: The buffer to transmit
+ * @dev: The device used to transmit the packet.
+ *
+ * Called by the network layer to transmit the @skb. Queue the packet for
+ * the device and schedule the necessary work to transmit the packet when
+ * it is free.
+ *
+ * We do this to firstly avoid sleeping with the network device locked,
+ * and secondly so we can round up more than one packet to transmit which
+ * means we can try and avoid generating too many transmit done interrupts.
+ */
+static netdev_tx_t ks8851_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct ks8851_net *ks = netdev_priv(dev);
+
+ return ks->start_xmit(skb, dev);
+}
+
/**
* ks8851_rxctrl_work - work handler to change rx mode
* @work: The work structure this belongs to.
@@ -1591,6 +1715,16 @@ static int ks8851_probe(struct spi_device *spi)
ks = netdev_priv(netdev);
+ ks->lock = ks8851_lock_spi;
+ ks->unlock = ks8851_unlock_spi;
+ ks->rdreg16 = ks8851_rdreg16_spi;
+ ks->wrreg16 = ks8851_wrreg16_spi;
+ ks->rdfifo = ks8851_rdfifo_spi;
+ ks->wrfifo = ks8851_wrpkt_spi;
+ ks->start_xmit = ks8851_start_xmit_spi;
+ ks->rx_skb = ks8851_rx_skb_spi;
+ ks->flush_tx_work = ks8851_flush_tx_work_spi;
+
#define STD_IRQ (IRQ_LCI | /* Link Change */ \
IRQ_TXI | /* TX done */ \
IRQ_RXI | /* RX done */ \
--
2.25.1
next prev parent reply other threads:[~2020-05-28 22:23 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-28 22:21 [PATCH V7 00/19] net: ks8851: Unify KS8851 SPI and MLL drivers Marek Vasut
2020-05-28 22:21 ` [PATCH V7 01/19] net: ks8851: Factor out spi->dev in probe()/remove() Marek Vasut
2020-05-28 22:21 ` [PATCH V7 02/19] net: ks8851: Rename ndev to netdev in probe Marek Vasut
2020-05-28 22:21 ` [PATCH V7 03/19] net: ks8851: Replace dev_err() with netdev_err() in IRQ handler Marek Vasut
2020-05-28 22:21 ` [PATCH V7 04/19] net: ks8851: Pass device node into ks8851_init_mac() Marek Vasut
2020-05-28 22:26 ` Andrew Lunn
2020-05-28 22:21 ` [PATCH V7 05/19] net: ks8851: Use devm_alloc_etherdev() Marek Vasut
2020-05-28 22:21 ` [PATCH V7 06/19] net: ks8851: Use dev_{get,set}_drvdata() Marek Vasut
2020-05-28 22:21 ` [PATCH V7 07/19] net: ks8851: Remove ks8851_rdreg32() Marek Vasut
2020-05-28 22:27 ` Andrew Lunn
2020-05-28 22:21 ` [PATCH V7 08/19] net: ks8851: Use 16-bit writes to program MAC address Marek Vasut
2020-05-28 22:21 ` [PATCH V7 09/19] net: ks8851: Use 16-bit read of RXFC register Marek Vasut
2020-05-28 22:29 ` Andrew Lunn
2020-05-28 22:21 ` [PATCH V7 10/19] net: ks8851: Factor out bus lock handling Marek Vasut
2020-05-28 22:21 ` [PATCH V7 11/19] net: ks8851: Factor out SKB receive function Marek Vasut
2020-05-28 22:29 ` Andrew Lunn
2020-05-28 22:21 ` [PATCH V7 12/19] net: ks8851: Split out SPI specific entries in struct ks8851_net Marek Vasut
2020-05-28 22:21 ` [PATCH V7 13/19] net: ks8851: Split out SPI specific code from probe() and remove() Marek Vasut
2020-05-28 22:21 ` [PATCH V7 14/19] net: ks8851: Factor out TX work flush function Marek Vasut
2020-05-28 22:21 ` [PATCH V7 15/19] net: ks8851: Permit overridding interrupt enable register Marek Vasut
2020-05-28 22:21 ` Marek Vasut [this message]
2020-05-28 22:21 ` [PATCH V7 17/19] net: ks8851: Separate SPI operations into separate file Marek Vasut
2020-05-28 22:21 ` [PATCH V7 18/19] net: ks8851: Implement Parallel bus operations Marek Vasut
2020-05-28 22:35 ` Andrew Lunn
2020-05-28 22:21 ` [PATCH V7 19/19] net: ks8851: Remove ks8851_mll.c Marek Vasut
2020-05-28 22:33 ` Andrew Lunn
2020-05-28 23:30 ` [PATCH V7 00/19] net: ks8851: Unify KS8851 SPI and MLL drivers David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200528222146.348805-17-marex@denx.de \
--to=marex@denx.de \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=lukas@wunner.de \
--cc=netdev@vger.kernel.org \
--cc=ynezz@true.cz \
--cc=yuehaibing@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).