162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* drivers/net/ethernet/micrel/ks8851.c 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright 2009 Simtec Electronics 562306a36Sopenharmony_ci * http://www.simtec.co.uk/ 662306a36Sopenharmony_ci * Ben Dooks <ben@simtec.co.uk> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/interrupt.h> 1262306a36Sopenharmony_ci#include <linux/module.h> 1362306a36Sopenharmony_ci#include <linux/kernel.h> 1462306a36Sopenharmony_ci#include <linux/netdevice.h> 1562306a36Sopenharmony_ci#include <linux/etherdevice.h> 1662306a36Sopenharmony_ci#include <linux/ethtool.h> 1762306a36Sopenharmony_ci#include <linux/cache.h> 1862306a36Sopenharmony_ci#include <linux/crc32.h> 1962306a36Sopenharmony_ci#include <linux/mii.h> 2062306a36Sopenharmony_ci#include <linux/regulator/consumer.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include <linux/spi/spi.h> 2362306a36Sopenharmony_ci#include <linux/gpio.h> 2462306a36Sopenharmony_ci#include <linux/of_gpio.h> 2562306a36Sopenharmony_ci#include <linux/of_net.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#include "ks8851.h" 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistatic int msg_enable; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/** 3262306a36Sopenharmony_ci * struct ks8851_net_spi - KS8851 SPI driver private data 3362306a36Sopenharmony_ci * @lock: Lock to ensure that the device is not accessed when busy. 3462306a36Sopenharmony_ci * @tx_work: Work queue for tx packets 3562306a36Sopenharmony_ci * @ks8851: KS8851 driver common private data 3662306a36Sopenharmony_ci * @spidev: The spi device we're bound to. 3762306a36Sopenharmony_ci * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. 3862306a36Sopenharmony_ci * @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2. 3962306a36Sopenharmony_ci * @spi_xfer1: @spi_msg1 SPI transfer structure 4062306a36Sopenharmony_ci * @spi_xfer2: @spi_msg2 SPI transfer structure 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * The @lock ensures that the chip is protected when certain operations are 4362306a36Sopenharmony_ci * in progress. When the read or write packet transfer is in progress, most 4462306a36Sopenharmony_ci * of the chip registers are not ccessible until the transfer is finished and 4562306a36Sopenharmony_ci * the DMA has been de-asserted. 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_cistruct ks8851_net_spi { 4862306a36Sopenharmony_ci struct ks8851_net ks8851; 4962306a36Sopenharmony_ci struct mutex lock; 5062306a36Sopenharmony_ci struct work_struct tx_work; 5162306a36Sopenharmony_ci struct spi_device *spidev; 5262306a36Sopenharmony_ci struct spi_message spi_msg1; 5362306a36Sopenharmony_ci struct spi_message spi_msg2; 5462306a36Sopenharmony_ci struct spi_transfer spi_xfer1; 5562306a36Sopenharmony_ci struct spi_transfer spi_xfer2[2]; 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci#define to_ks8851_spi(ks) container_of((ks), struct ks8851_net_spi, ks8851) 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci/* SPI frame opcodes */ 6162306a36Sopenharmony_ci#define KS_SPIOP_RD 0x00 6262306a36Sopenharmony_ci#define KS_SPIOP_WR 0x40 6362306a36Sopenharmony_ci#define KS_SPIOP_RXFIFO 0x80 6462306a36Sopenharmony_ci#define KS_SPIOP_TXFIFO 0xC0 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* shift for byte-enable data */ 6762306a36Sopenharmony_ci#define BYTE_EN(_x) ((_x) << 2) 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* turn register number and byte-enable mask into data for start of packet */ 7062306a36Sopenharmony_ci#define MK_OP(_byteen, _reg) \ 7162306a36Sopenharmony_ci (BYTE_EN(_byteen) | (_reg) << (8 + 2) | (_reg) >> 6) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/** 7462306a36Sopenharmony_ci * ks8851_lock_spi - register access lock 7562306a36Sopenharmony_ci * @ks: The chip state 7662306a36Sopenharmony_ci * @flags: Spinlock flags 7762306a36Sopenharmony_ci * 7862306a36Sopenharmony_ci * Claim chip register access lock 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_cistatic void ks8851_lock_spi(struct ks8851_net *ks, unsigned long *flags) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci struct ks8851_net_spi *kss = to_ks8851_spi(ks); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci mutex_lock(&kss->lock); 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/** 8862306a36Sopenharmony_ci * ks8851_unlock_spi - register access unlock 8962306a36Sopenharmony_ci * @ks: The chip state 9062306a36Sopenharmony_ci * @flags: Spinlock flags 9162306a36Sopenharmony_ci * 9262306a36Sopenharmony_ci * Release chip register access lock 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_cistatic void ks8851_unlock_spi(struct ks8851_net *ks, unsigned long *flags) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci struct ks8851_net_spi *kss = to_ks8851_spi(ks); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci mutex_unlock(&kss->lock); 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/* SPI register read/write calls. 10262306a36Sopenharmony_ci * 10362306a36Sopenharmony_ci * All these calls issue SPI transactions to access the chip's registers. They 10462306a36Sopenharmony_ci * all require that the necessary lock is held to prevent accesses when the 10562306a36Sopenharmony_ci * chip is busy transferring packet data (RX/TX FIFO accesses). 10662306a36Sopenharmony_ci */ 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci/** 10962306a36Sopenharmony_ci * ks8851_wrreg16_spi - write 16bit register value to chip via SPI 11062306a36Sopenharmony_ci * @ks: The chip state 11162306a36Sopenharmony_ci * @reg: The register address 11262306a36Sopenharmony_ci * @val: The value to write 11362306a36Sopenharmony_ci * 11462306a36Sopenharmony_ci * Issue a write to put the value @val into the register specified in @reg. 11562306a36Sopenharmony_ci */ 11662306a36Sopenharmony_cistatic void ks8851_wrreg16_spi(struct ks8851_net *ks, unsigned int reg, 11762306a36Sopenharmony_ci unsigned int val) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci struct ks8851_net_spi *kss = to_ks8851_spi(ks); 12062306a36Sopenharmony_ci struct spi_transfer *xfer = &kss->spi_xfer1; 12162306a36Sopenharmony_ci struct spi_message *msg = &kss->spi_msg1; 12262306a36Sopenharmony_ci __le16 txb[2]; 12362306a36Sopenharmony_ci int ret; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci txb[0] = cpu_to_le16(MK_OP(reg & 2 ? 0xC : 0x03, reg) | KS_SPIOP_WR); 12662306a36Sopenharmony_ci txb[1] = cpu_to_le16(val); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci xfer->tx_buf = txb; 12962306a36Sopenharmony_ci xfer->rx_buf = NULL; 13062306a36Sopenharmony_ci xfer->len = 4; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci ret = spi_sync(kss->spidev, msg); 13362306a36Sopenharmony_ci if (ret < 0) 13462306a36Sopenharmony_ci netdev_err(ks->netdev, "spi_sync() failed\n"); 13562306a36Sopenharmony_ci} 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci/** 13862306a36Sopenharmony_ci * ks8851_rdreg - issue read register command and return the data 13962306a36Sopenharmony_ci * @ks: The device state 14062306a36Sopenharmony_ci * @op: The register address and byte enables in message format. 14162306a36Sopenharmony_ci * @rxb: The RX buffer to return the result into 14262306a36Sopenharmony_ci * @rxl: The length of data expected. 14362306a36Sopenharmony_ci * 14462306a36Sopenharmony_ci * This is the low level read call that issues the necessary spi message(s) 14562306a36Sopenharmony_ci * to read data from the register specified in @op. 14662306a36Sopenharmony_ci */ 14762306a36Sopenharmony_cistatic void ks8851_rdreg(struct ks8851_net *ks, unsigned int op, 14862306a36Sopenharmony_ci u8 *rxb, unsigned int rxl) 14962306a36Sopenharmony_ci{ 15062306a36Sopenharmony_ci struct ks8851_net_spi *kss = to_ks8851_spi(ks); 15162306a36Sopenharmony_ci struct spi_transfer *xfer; 15262306a36Sopenharmony_ci struct spi_message *msg; 15362306a36Sopenharmony_ci __le16 *txb = (__le16 *)ks->txd; 15462306a36Sopenharmony_ci u8 *trx = ks->rxd; 15562306a36Sopenharmony_ci int ret; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci txb[0] = cpu_to_le16(op | KS_SPIOP_RD); 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci if (kss->spidev->master->flags & SPI_MASTER_HALF_DUPLEX) { 16062306a36Sopenharmony_ci msg = &kss->spi_msg2; 16162306a36Sopenharmony_ci xfer = kss->spi_xfer2; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci xfer->tx_buf = txb; 16462306a36Sopenharmony_ci xfer->rx_buf = NULL; 16562306a36Sopenharmony_ci xfer->len = 2; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci xfer++; 16862306a36Sopenharmony_ci xfer->tx_buf = NULL; 16962306a36Sopenharmony_ci xfer->rx_buf = trx; 17062306a36Sopenharmony_ci xfer->len = rxl; 17162306a36Sopenharmony_ci } else { 17262306a36Sopenharmony_ci msg = &kss->spi_msg1; 17362306a36Sopenharmony_ci xfer = &kss->spi_xfer1; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci xfer->tx_buf = txb; 17662306a36Sopenharmony_ci xfer->rx_buf = trx; 17762306a36Sopenharmony_ci xfer->len = rxl + 2; 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci ret = spi_sync(kss->spidev, msg); 18162306a36Sopenharmony_ci if (ret < 0) 18262306a36Sopenharmony_ci netdev_err(ks->netdev, "read: spi_sync() failed\n"); 18362306a36Sopenharmony_ci else if (kss->spidev->master->flags & SPI_MASTER_HALF_DUPLEX) 18462306a36Sopenharmony_ci memcpy(rxb, trx, rxl); 18562306a36Sopenharmony_ci else 18662306a36Sopenharmony_ci memcpy(rxb, trx + 2, rxl); 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci/** 19062306a36Sopenharmony_ci * ks8851_rdreg16_spi - read 16 bit register from device via SPI 19162306a36Sopenharmony_ci * @ks: The chip information 19262306a36Sopenharmony_ci * @reg: The register address 19362306a36Sopenharmony_ci * 19462306a36Sopenharmony_ci * Read a 16bit register from the chip, returning the result 19562306a36Sopenharmony_ci */ 19662306a36Sopenharmony_cistatic unsigned int ks8851_rdreg16_spi(struct ks8851_net *ks, unsigned int reg) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci __le16 rx = 0; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci ks8851_rdreg(ks, MK_OP(reg & 2 ? 0xC : 0x3, reg), (u8 *)&rx, 2); 20162306a36Sopenharmony_ci return le16_to_cpu(rx); 20262306a36Sopenharmony_ci} 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci/** 20562306a36Sopenharmony_ci * ks8851_rdfifo_spi - read data from the receive fifo via SPI 20662306a36Sopenharmony_ci * @ks: The device state. 20762306a36Sopenharmony_ci * @buff: The buffer address 20862306a36Sopenharmony_ci * @len: The length of the data to read 20962306a36Sopenharmony_ci * 21062306a36Sopenharmony_ci * Issue an RXQ FIFO read command and read the @len amount of data from 21162306a36Sopenharmony_ci * the FIFO into the buffer specified by @buff. 21262306a36Sopenharmony_ci */ 21362306a36Sopenharmony_cistatic void ks8851_rdfifo_spi(struct ks8851_net *ks, u8 *buff, unsigned int len) 21462306a36Sopenharmony_ci{ 21562306a36Sopenharmony_ci struct ks8851_net_spi *kss = to_ks8851_spi(ks); 21662306a36Sopenharmony_ci struct spi_transfer *xfer = kss->spi_xfer2; 21762306a36Sopenharmony_ci struct spi_message *msg = &kss->spi_msg2; 21862306a36Sopenharmony_ci u8 txb[1]; 21962306a36Sopenharmony_ci int ret; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci netif_dbg(ks, rx_status, ks->netdev, 22262306a36Sopenharmony_ci "%s: %d@%p\n", __func__, len, buff); 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci /* set the operation we're issuing */ 22562306a36Sopenharmony_ci txb[0] = KS_SPIOP_RXFIFO; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci xfer->tx_buf = txb; 22862306a36Sopenharmony_ci xfer->rx_buf = NULL; 22962306a36Sopenharmony_ci xfer->len = 1; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci xfer++; 23262306a36Sopenharmony_ci xfer->rx_buf = buff; 23362306a36Sopenharmony_ci xfer->tx_buf = NULL; 23462306a36Sopenharmony_ci xfer->len = len; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci ret = spi_sync(kss->spidev, msg); 23762306a36Sopenharmony_ci if (ret < 0) 23862306a36Sopenharmony_ci netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); 23962306a36Sopenharmony_ci} 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci/** 24262306a36Sopenharmony_ci * ks8851_wrfifo_spi - write packet to TX FIFO via SPI 24362306a36Sopenharmony_ci * @ks: The device state. 24462306a36Sopenharmony_ci * @txp: The sk_buff to transmit. 24562306a36Sopenharmony_ci * @irq: IRQ on completion of the packet. 24662306a36Sopenharmony_ci * 24762306a36Sopenharmony_ci * Send the @txp to the chip. This means creating the relevant packet header 24862306a36Sopenharmony_ci * specifying the length of the packet and the other information the chip 24962306a36Sopenharmony_ci * needs, such as IRQ on completion. Send the header and the packet data to 25062306a36Sopenharmony_ci * the device. 25162306a36Sopenharmony_ci */ 25262306a36Sopenharmony_cistatic void ks8851_wrfifo_spi(struct ks8851_net *ks, struct sk_buff *txp, 25362306a36Sopenharmony_ci bool irq) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci struct ks8851_net_spi *kss = to_ks8851_spi(ks); 25662306a36Sopenharmony_ci struct spi_transfer *xfer = kss->spi_xfer2; 25762306a36Sopenharmony_ci struct spi_message *msg = &kss->spi_msg2; 25862306a36Sopenharmony_ci unsigned int fid = 0; 25962306a36Sopenharmony_ci int ret; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci netif_dbg(ks, tx_queued, ks->netdev, "%s: skb %p, %d@%p, irq %d\n", 26262306a36Sopenharmony_ci __func__, txp, txp->len, txp->data, irq); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci fid = ks->fid++; 26562306a36Sopenharmony_ci fid &= TXFR_TXFID_MASK; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci if (irq) 26862306a36Sopenharmony_ci fid |= TXFR_TXIC; /* irq on completion */ 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci /* start header at txb[1] to align txw entries */ 27162306a36Sopenharmony_ci ks->txh.txb[1] = KS_SPIOP_TXFIFO; 27262306a36Sopenharmony_ci ks->txh.txw[1] = cpu_to_le16(fid); 27362306a36Sopenharmony_ci ks->txh.txw[2] = cpu_to_le16(txp->len); 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci xfer->tx_buf = &ks->txh.txb[1]; 27662306a36Sopenharmony_ci xfer->rx_buf = NULL; 27762306a36Sopenharmony_ci xfer->len = 5; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci xfer++; 28062306a36Sopenharmony_ci xfer->tx_buf = txp->data; 28162306a36Sopenharmony_ci xfer->rx_buf = NULL; 28262306a36Sopenharmony_ci xfer->len = ALIGN(txp->len, 4); 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci ret = spi_sync(kss->spidev, msg); 28562306a36Sopenharmony_ci if (ret < 0) 28662306a36Sopenharmony_ci netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci/** 29062306a36Sopenharmony_ci * calc_txlen - calculate size of message to send packet 29162306a36Sopenharmony_ci * @len: Length of data 29262306a36Sopenharmony_ci * 29362306a36Sopenharmony_ci * Returns the size of the TXFIFO message needed to send 29462306a36Sopenharmony_ci * this packet. 29562306a36Sopenharmony_ci */ 29662306a36Sopenharmony_cistatic unsigned int calc_txlen(unsigned int len) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci return ALIGN(len + 4, 4); 29962306a36Sopenharmony_ci} 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci/** 30262306a36Sopenharmony_ci * ks8851_rx_skb_spi - receive skbuff 30362306a36Sopenharmony_ci * @ks: The device state 30462306a36Sopenharmony_ci * @skb: The skbuff 30562306a36Sopenharmony_ci */ 30662306a36Sopenharmony_cistatic void ks8851_rx_skb_spi(struct ks8851_net *ks, struct sk_buff *skb) 30762306a36Sopenharmony_ci{ 30862306a36Sopenharmony_ci netif_rx(skb); 30962306a36Sopenharmony_ci} 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci/** 31262306a36Sopenharmony_ci * ks8851_tx_work - process tx packet(s) 31362306a36Sopenharmony_ci * @work: The work strucutre what was scheduled. 31462306a36Sopenharmony_ci * 31562306a36Sopenharmony_ci * This is called when a number of packets have been scheduled for 31662306a36Sopenharmony_ci * transmission and need to be sent to the device. 31762306a36Sopenharmony_ci */ 31862306a36Sopenharmony_cistatic void ks8851_tx_work(struct work_struct *work) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci unsigned int dequeued_len = 0; 32162306a36Sopenharmony_ci struct ks8851_net_spi *kss; 32262306a36Sopenharmony_ci unsigned short tx_space; 32362306a36Sopenharmony_ci struct ks8851_net *ks; 32462306a36Sopenharmony_ci unsigned long flags; 32562306a36Sopenharmony_ci struct sk_buff *txb; 32662306a36Sopenharmony_ci bool last; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci kss = container_of(work, struct ks8851_net_spi, tx_work); 32962306a36Sopenharmony_ci ks = &kss->ks8851; 33062306a36Sopenharmony_ci last = skb_queue_empty(&ks->txq); 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci ks8851_lock_spi(ks, &flags); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci while (!last) { 33562306a36Sopenharmony_ci txb = skb_dequeue(&ks->txq); 33662306a36Sopenharmony_ci last = skb_queue_empty(&ks->txq); 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci if (txb) { 33962306a36Sopenharmony_ci dequeued_len += calc_txlen(txb->len); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci ks8851_wrreg16_spi(ks, KS_RXQCR, 34262306a36Sopenharmony_ci ks->rc_rxqcr | RXQCR_SDA); 34362306a36Sopenharmony_ci ks8851_wrfifo_spi(ks, txb, last); 34462306a36Sopenharmony_ci ks8851_wrreg16_spi(ks, KS_RXQCR, ks->rc_rxqcr); 34562306a36Sopenharmony_ci ks8851_wrreg16_spi(ks, KS_TXQCR, TXQCR_METFE); 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci ks8851_done_tx(ks, txb); 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci } 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci tx_space = ks8851_rdreg16_spi(ks, KS_TXMIR); 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci spin_lock(&ks->statelock); 35462306a36Sopenharmony_ci ks->queued_len -= dequeued_len; 35562306a36Sopenharmony_ci ks->tx_space = tx_space; 35662306a36Sopenharmony_ci spin_unlock(&ks->statelock); 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci ks8851_unlock_spi(ks, &flags); 35962306a36Sopenharmony_ci} 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci/** 36262306a36Sopenharmony_ci * ks8851_flush_tx_work_spi - flush outstanding TX work 36362306a36Sopenharmony_ci * @ks: The device state 36462306a36Sopenharmony_ci */ 36562306a36Sopenharmony_cistatic void ks8851_flush_tx_work_spi(struct ks8851_net *ks) 36662306a36Sopenharmony_ci{ 36762306a36Sopenharmony_ci struct ks8851_net_spi *kss = to_ks8851_spi(ks); 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci flush_work(&kss->tx_work); 37062306a36Sopenharmony_ci} 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci/** 37362306a36Sopenharmony_ci * ks8851_start_xmit_spi - transmit packet using SPI 37462306a36Sopenharmony_ci * @skb: The buffer to transmit 37562306a36Sopenharmony_ci * @dev: The device used to transmit the packet. 37662306a36Sopenharmony_ci * 37762306a36Sopenharmony_ci * Called by the network layer to transmit the @skb. Queue the packet for 37862306a36Sopenharmony_ci * the device and schedule the necessary work to transmit the packet when 37962306a36Sopenharmony_ci * it is free. 38062306a36Sopenharmony_ci * 38162306a36Sopenharmony_ci * We do this to firstly avoid sleeping with the network device locked, 38262306a36Sopenharmony_ci * and secondly so we can round up more than one packet to transmit which 38362306a36Sopenharmony_ci * means we can try and avoid generating too many transmit done interrupts. 38462306a36Sopenharmony_ci */ 38562306a36Sopenharmony_cistatic netdev_tx_t ks8851_start_xmit_spi(struct sk_buff *skb, 38662306a36Sopenharmony_ci struct net_device *dev) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci unsigned int needed = calc_txlen(skb->len); 38962306a36Sopenharmony_ci struct ks8851_net *ks = netdev_priv(dev); 39062306a36Sopenharmony_ci netdev_tx_t ret = NETDEV_TX_OK; 39162306a36Sopenharmony_ci struct ks8851_net_spi *kss; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci kss = to_ks8851_spi(ks); 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci netif_dbg(ks, tx_queued, ks->netdev, 39662306a36Sopenharmony_ci "%s: skb %p, %d@%p\n", __func__, skb, skb->len, skb->data); 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci spin_lock(&ks->statelock); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci if (ks->queued_len + needed > ks->tx_space) { 40162306a36Sopenharmony_ci netif_stop_queue(dev); 40262306a36Sopenharmony_ci ret = NETDEV_TX_BUSY; 40362306a36Sopenharmony_ci } else { 40462306a36Sopenharmony_ci ks->queued_len += needed; 40562306a36Sopenharmony_ci skb_queue_tail(&ks->txq, skb); 40662306a36Sopenharmony_ci } 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci spin_unlock(&ks->statelock); 40962306a36Sopenharmony_ci if (ret == NETDEV_TX_OK) 41062306a36Sopenharmony_ci schedule_work(&kss->tx_work); 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci return ret; 41362306a36Sopenharmony_ci} 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_cistatic int ks8851_probe_spi(struct spi_device *spi) 41662306a36Sopenharmony_ci{ 41762306a36Sopenharmony_ci struct device *dev = &spi->dev; 41862306a36Sopenharmony_ci struct ks8851_net_spi *kss; 41962306a36Sopenharmony_ci struct net_device *netdev; 42062306a36Sopenharmony_ci struct ks8851_net *ks; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci netdev = devm_alloc_etherdev(dev, sizeof(struct ks8851_net_spi)); 42362306a36Sopenharmony_ci if (!netdev) 42462306a36Sopenharmony_ci return -ENOMEM; 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci spi->bits_per_word = 8; 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci kss = netdev_priv(netdev); 42962306a36Sopenharmony_ci ks = &kss->ks8851; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci ks->lock = ks8851_lock_spi; 43262306a36Sopenharmony_ci ks->unlock = ks8851_unlock_spi; 43362306a36Sopenharmony_ci ks->rdreg16 = ks8851_rdreg16_spi; 43462306a36Sopenharmony_ci ks->wrreg16 = ks8851_wrreg16_spi; 43562306a36Sopenharmony_ci ks->rdfifo = ks8851_rdfifo_spi; 43662306a36Sopenharmony_ci ks->wrfifo = ks8851_wrfifo_spi; 43762306a36Sopenharmony_ci ks->start_xmit = ks8851_start_xmit_spi; 43862306a36Sopenharmony_ci ks->rx_skb = ks8851_rx_skb_spi; 43962306a36Sopenharmony_ci ks->flush_tx_work = ks8851_flush_tx_work_spi; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci#define STD_IRQ (IRQ_LCI | /* Link Change */ \ 44262306a36Sopenharmony_ci IRQ_TXI | /* TX done */ \ 44362306a36Sopenharmony_ci IRQ_RXI | /* RX done */ \ 44462306a36Sopenharmony_ci IRQ_SPIBEI | /* SPI bus error */ \ 44562306a36Sopenharmony_ci IRQ_TXPSI | /* TX process stop */ \ 44662306a36Sopenharmony_ci IRQ_RXPSI) /* RX process stop */ 44762306a36Sopenharmony_ci ks->rc_ier = STD_IRQ; 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci kss->spidev = spi; 45062306a36Sopenharmony_ci mutex_init(&kss->lock); 45162306a36Sopenharmony_ci INIT_WORK(&kss->tx_work, ks8851_tx_work); 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci /* initialise pre-made spi transfer messages */ 45462306a36Sopenharmony_ci spi_message_init(&kss->spi_msg1); 45562306a36Sopenharmony_ci spi_message_add_tail(&kss->spi_xfer1, &kss->spi_msg1); 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci spi_message_init(&kss->spi_msg2); 45862306a36Sopenharmony_ci spi_message_add_tail(&kss->spi_xfer2[0], &kss->spi_msg2); 45962306a36Sopenharmony_ci spi_message_add_tail(&kss->spi_xfer2[1], &kss->spi_msg2); 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci netdev->irq = spi->irq; 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci return ks8851_probe_common(netdev, dev, msg_enable); 46462306a36Sopenharmony_ci} 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_cistatic void ks8851_remove_spi(struct spi_device *spi) 46762306a36Sopenharmony_ci{ 46862306a36Sopenharmony_ci ks8851_remove_common(&spi->dev); 46962306a36Sopenharmony_ci} 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_cistatic const struct of_device_id ks8851_match_table[] = { 47262306a36Sopenharmony_ci { .compatible = "micrel,ks8851" }, 47362306a36Sopenharmony_ci { } 47462306a36Sopenharmony_ci}; 47562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, ks8851_match_table); 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_cistatic struct spi_driver ks8851_driver = { 47862306a36Sopenharmony_ci .driver = { 47962306a36Sopenharmony_ci .name = "ks8851", 48062306a36Sopenharmony_ci .of_match_table = ks8851_match_table, 48162306a36Sopenharmony_ci .pm = &ks8851_pm_ops, 48262306a36Sopenharmony_ci }, 48362306a36Sopenharmony_ci .probe = ks8851_probe_spi, 48462306a36Sopenharmony_ci .remove = ks8851_remove_spi, 48562306a36Sopenharmony_ci}; 48662306a36Sopenharmony_cimodule_spi_driver(ks8851_driver); 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ciMODULE_DESCRIPTION("KS8851 Network driver"); 48962306a36Sopenharmony_ciMODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 49062306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_cimodule_param_named(message, msg_enable, int, 0); 49362306a36Sopenharmony_ciMODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)"); 49462306a36Sopenharmony_ciMODULE_ALIAS("spi:ks8851"); 495