/*
* Microchip ENC28J60 ethernet driver (MAC + PHY)
*
* Copyright (C) 2007 Eurek srl
* Author: Claudio Lanconelli <lanconelli.claudio@eptar.com>
* based on enc28j60.c written by David Anders for 2.4 kernel version
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* $Id: enc28j60.c,v 1.22 2007/12/20 10:47:01 claudio Exp $
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/tcp.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include "enc28j60_hw.h"
#define DRV_NAME "enc28j60"
#define DRV_VERSION "1.01"
#define SPI_OPLEN 1
#define ENC28J60_MSG_DEFAULT \
(NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_LINK)
/* Buffer size required for the largest SPI transfer (i.e., reading a
* frame). */
#define SPI_TRANSFER_BUF_LEN (4 + MAX_FRAMELEN)
#define TX_TIMEOUT (4 * HZ)
/* Max TX retries in case of collision as suggested by errata datasheet */
#define MAX_TX_RETRYCOUNT 16
enum {
RXFILTER_NORMAL,
RXFILTER_MULTI,
RXFILTER_PROMISC
};
/* Driver local data */
struct enc28j60_net {
struct net_device *netdev;
struct spi_device *spi;
struct mutex lock;
struct sk_buff *tx_skb;
struct work_struct tx_work;
struct work_struct irq_work;
struct work_struct setrx_work;
struct work_struct restart_work;
u8 bank; /* current register bank selected */
u16 next_pk_ptr; /* next packet pointer within FIFO */
u16 max_pk_counter; /* statistics: max packet counter */
u16 tx_retry_count;
bool hw_enable;
bool full_duplex;
int rxfilter;
u32 msg_enable;
u8 spi_transfer_buf[SPI_TRANSFER_BUF_LEN];
};
/* use ethtool to change the level for any given device */
static struct {
u32 msg_enable;
} debug = { -1 };
/*
* SPI read buffer
* wait for the SPI transfer and copy received data to destination
*/
static int
spi_read_buf(struct enc28j60_net *priv, int len, u8 *data)
{
u8 *rx_buf = priv->spi_transfer_buf + 4;
u8 *tx_buf = priv->spi_transfer_buf;
struct spi_transfer t = {
.tx_buf =
|