/* drivers/net/ks8651.c
*
* Copyright 2009 Simtec Electronics
* http://www.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#define DEBUG
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/cache.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/spi/spi.h>
#include "ks8851.h"
/**
* struct ks8851_rxctrl - KS8851 driver rx control
* @mchash: Multicast hash-table data.
* @rxcr1: KS_RXCR1 register setting
* @rxcr2: KS_RXCR2 register setting
*
* Representation of the settings needs to control the receive filtering
* such as the multicast hash-filter and the receive register settings. This
* is used to make the job of working out if the receive settings change and
* then issuing the new settings to the worker that will send the necessary
* commands.
*/
struct ks8851_rxctrl {
u16 mchash[4];
u16 rxcr1;
u16 rxcr2;
};
/**
* union ks8851_tx_hdr - tx header data
* @txb: The header as bytes
* @txw: The header as 16bit, little-endian words
*
* A dual representation of the tx header data to allow
* access to individual bytes, and to allow 16bit accesses
* with 16bit alignment.
*/
union ks8851_tx_hdr {
u8 txb[6];
__le16 txw[3];
};
/**
* struct ks8851_net - KS8851 driver private data
* @netdev: The network device we're bound to
* @spidev: The spi device we're bound to.
* @lock: Lock to ensure that the device is not accessed when busy.
* @statelock: Lock on this structure for tx list.
* @mii: The MII state information for the mii calls.
* @rxctrl: RX settings for @rxctrl_work.
* @tx_work: Work queue for tx packets
* @irq_work: Work queue for servicing interrupts
* @rxctrl_work: Work queue for updating RX mode and multicast lists
* @txq: Queue of packets for transmission.
* @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1.
* @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2.
* @txh: Space for generating packet TX header in DMA-able data
* @rxd: Space for receiving SPI data, in DMA-able space.
* @txd: Space for transmitting SPI data, in DMA-able space.
* @msg_enable: The message flags controlling driver output (see ethtool).
* @fid: Incrementing frame id tag.
* @rc_ier: Cached copy of KS_IER.
* @rc_rxqcr: Cached copy of KS_RXQCR.
*
* The @lock ensures that the chip is protected when certain operations are
* in progress. When the read or write packet transfer is in progress, most
* of the chip registers are not ccessible until the transfer is finished and
* the DMA has been de-asserted.
*
* 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
* or one of the work queues.
*
* We align the buffers we may use for rx/tx to ensure that if the SPI driver
* wants to DMA map them, it will not have any problems with data the driver
* modifies.
*/
struct ks8851_net {
struct net_device *netdev;
struct spi_device *spidev;
struct mutex lock;
spinlock_t statelock;
union ks8851_tx_hdr txh ____cacheline_aligned;
u8 rxd[8];
u8 txd[8];
u32 msg_enable ____cacheline_aligned;
u16 tx_space;
u8 fid;
u16 rc_ier;
u16 rc_rxqcr;
struct mii_if_info mii;
struct ks8851_rxctrl rxctrl;
struct work_struct tx_work;
struct work_struct irq_work;
struct work_struct rxctrl_work;
struct sk_buff_head txq;
struct spi_message spi_msg1;
struct spi_message spi_msg2;
struct spi_transfer spi_xfer1;
struct spi_transfer spi_xfer2[2];
};
static int msg_enable;
#define ks_info(_ks, _msg...) dev_info(&(_ks)->spidev->dev, _msg)
#define ks_warn(_ks, _msg...) dev_warn(&(_ks)->spidev->dev, _msg)
#define ks_dbg(_ks, _msg...) dev_dbg(&(_ks)->spidev->dev, _msg)
#define ks_err(_ks, _msg...) dev_err(&(_ks)->spidev->dev, _msg)