linux/drivers/net/ethernet/xircom/xirc2ps_cs.c

/* [xirc2ps_cs.c wk 03.11.99] (1.40 1999/11/18 00:06:03)
 * Xircom CreditCard Ethernet Adapter IIps driver
 * Xircom Realport 10/100 (RE-100) driver 
 *
 * This driver supports various Xircom CreditCard Ethernet adapters
 * including the CE2, CE IIps, RE-10, CEM28, CEM33, CE33, CEM56,
 * CE3-100, CE3B, RE-100, REM10BT, and REM56G-100.
 *
 * 2000-09-24 <[email protected]> The Xircom CE3B-100 may not
 * autodetect the media properly. In this case use the
 * if_port=1 (for 10BaseT) or if_port=4 (for 100BaseT) options
 * to force the media type.
 * 
 * Written originally by Werner Koch based on David Hinds' skeleton of the
 * PCMCIA driver.
 *
 * Copyright (c) 1997,1998 Werner Koch (dd9jn)
 *
 * This driver 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.
 *
 * It is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 *
 * ALTERNATIVELY, this driver may be distributed under the terms of
 * the following license, in which case the provisions of this license
 * are required INSTEAD OF the GNU General Public License.  (This clause
 * is necessary due to a potential bad interaction between the GPL and
 * the restrictions contained in a BSD-style copyright.)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, and the entire permission notice in its entirety,
 *    including the disclaimer of warranties.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define pr_fmt(fmt)

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/ioport.h>
#include <linux/bitops.h>
#include <linux/mii.h>

#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h>

#include <asm/io.h>
#include <linux/uaccess.h>

#ifndef MANFID_COMPAQ
  #define MANFID_COMPAQ
  #define MANFID_COMPAQ2
#endif

#include <pcmcia/ds.h>

/* Time in jiffies before concluding Tx hung */
#define TX_TIMEOUT

/****************
 * Some constants used to access the hardware
 */

/* Register offsets and value constans */
#define XIRCREG_CR
enum xirc_cr {};
#define XIRCREG_ESR
enum xirc_esr {};
#define XIRCREG_PR
#define XIRCREG_EDP
#define XIRCREG_ISR
enum xirc_isr {};
#define XIRCREG1_IMR0
#define XIRCREG1_IMR1
#define XIRCREG0_TSO
#define XIRCREG0_TRS
#define XIRCREG0_DO
#define XIRCREG0_RSR
enum xirc_rsr {};
#define XIRCREG0_PTR
#define XIRCREG0_RBC
#define XIRCREG1_ECR
enum xirc_ecr {};
#define XIRCREG2_RBS
#define XIRCREG2_LED
/* values for the leds:    Bits 2-0 for led 1
 *  0 disabled		   Bits 5-3 for led 2
 *  1 collision
 *  2 noncollision
 *  3 link_detected
 *  4 incor_polarity
 *  5 jabber
 *  6 auto_assertion
 *  7 rx_tx_activity
 */
#define XIRCREG2_MSR

#define XIRCREG4_GPR0
#define XIRCREG4_GPR1
#define XIRCREG2_GPR2
#define XIRCREG4_BOV
#define XIRCREG4_LMA
#define XIRCREG4_LMD
/* MAC register can only by accessed with 8 bit operations */
#define XIRCREG40_CMD0
enum xirc_cmd {};
#define XIRCREG5_RHSA0
#define XIRCREG40_RXST0
#define XIRCREG40_TXST0
#define XIRCREG40_TXST1
#define XIRCREG40_RMASK0
#define XIRCREG40_TMASK0
#define XIRCREG40_TMASK1
#define XIRCREG42_SWC0
#define XIRCREG42_SWC1
#define XIRCREG42_BOC
#define XIRCREG44_TDR0
#define XIRCREG44_TDR1
#define XIRCREG44_RXBC_LO
#define XIRCREG44_RXBC_HI
#define XIRCREG45_REV
#define XIRCREG50_IA

static const char *if_names[] =;

/* card types */
#define XIR_UNKNOWN
#define XIR_CE
#define XIR_CE2
#define XIR_CE3
#define XIR_CEM
#define XIR_CEM2
#define XIR_CEM3
#define XIR_CEM33
#define XIR_CEM56M
#define XIR_CEM56
#define XIR_CM28
#define XIR_CM33
#define XIR_CM56
#define XIR_CG
#define XIR_CBE
/*====================================================================*/

/* Module parameters */

MODULE_DESCRIPTION();
MODULE_LICENSE();

#define INT_MODULE_PARM(n, v)

INT_MODULE_PARM(if_port,	0);
INT_MODULE_PARM(full_duplex,	0);
INT_MODULE_PARM(do_sound, 	1);
INT_MODULE_PARM(lockup_hack,	0);  /* anti lockup hack */

/*====================================================================*/

/* We do not process more than these number of bytes during one
 * interrupt. (Of course we receive complete packets, so this is not
 * an exact value).
 * Something between 2000..22000; first value gives best interrupt latency,
 * the second enables the usage of the complete on-chip buffer. We use the
 * high value as the initial value.
 */
static unsigned maxrx_bytes =;

/* MII management prototypes */
static void mii_idle(unsigned int ioaddr);
static void mii_putbit(unsigned int ioaddr, unsigned data);
static int  mii_getbit(unsigned int ioaddr);
static void mii_wbits(unsigned int ioaddr, unsigned data, int len);
static unsigned mii_rd(unsigned int ioaddr, u_char phyaddr, u_char phyreg);
static void mii_wr(unsigned int ioaddr, u_char phyaddr, u_char phyreg,
		   unsigned data, int len);

static int has_ce2_string(struct pcmcia_device * link);
static int xirc2ps_config(struct pcmcia_device * link);
static void xirc2ps_release(struct pcmcia_device * link);
static void xirc2ps_detach(struct pcmcia_device *p_dev);

static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id);

struct local_info {};

/****************
 * Some more prototypes
 */
static netdev_tx_t do_start_xmit(struct sk_buff *skb,
				       struct net_device *dev);
static void xirc_tx_timeout(struct net_device *dev, unsigned int txqueue);
static void xirc2ps_tx_timeout_task(struct work_struct *work);
static void set_addresses(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static int set_card_type(struct pcmcia_device *link);
static int do_config(struct net_device *dev, struct ifmap *map);
static int do_open(struct net_device *dev);
static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static const struct ethtool_ops netdev_ethtool_ops;
static void hardreset(struct net_device *dev);
static void do_reset(struct net_device *dev, int full);
static int init_mii(struct net_device *dev);
static void do_powerdown(struct net_device *dev);
static int do_stop(struct net_device *dev);

/*=============== Helper functions =========================*/
#define SelectPage(pgnr)
#define GetByte(reg)
#define GetWord(reg)
#define PutByte(reg,value)
#define PutWord(reg,value)

/*====== Functions used for debugging =================================*/
#if 0 /* reading regs may change system status */
static void
PrintRegisters(struct net_device *dev)
{
    unsigned int ioaddr = dev->base_addr;

    if (pc_debug > 1) {
	int i, page;

	printk(KERN_DEBUG pr_fmt("Register  common: "));
	for (i = 0; i < 8; i++)
	    pr_cont(" %2.2x", GetByte(i));
	pr_cont("\n");
	for (page = 0; page <= 8; page++) {
	    printk(KERN_DEBUG pr_fmt("Register page %2x: "), page);
	    SelectPage(page);
	    for (i = 8; i < 16; i++)
		pr_cont(" %2.2x", GetByte(i));
	    pr_cont("\n");
	}
	for (page=0x40 ; page <= 0x5f; page++) {
		if (page == 0x43 || (page >= 0x46 && page <= 0x4f) ||
		    (page >= 0x51 && page <=0x5e))
			continue;
	    printk(KERN_DEBUG pr_fmt("Register page %2x: "), page);
	    SelectPage(page);
	    for (i = 8; i < 16; i++)
		pr_cont(" %2.2x", GetByte(i));
	    pr_cont("\n");
	}
    }
}
#endif /* 0 */

/*============== MII Management functions ===============*/

/****************
 * Turn around for read
 */
static void
mii_idle(unsigned int ioaddr)
{}

/****************
 * Write a bit to MDI/O
 */
static void
mii_putbit(unsigned int ioaddr, unsigned data)
{}

/****************
 * Get a bit from MDI/O
 */
static int
mii_getbit(unsigned int ioaddr)
{}

static void
mii_wbits(unsigned int ioaddr, unsigned data, int len)
{}

static unsigned
mii_rd(unsigned int ioaddr,	u_char phyaddr, u_char phyreg)
{}

static void
mii_wr(unsigned int ioaddr, u_char phyaddr, u_char phyreg, unsigned data,
       int len)
{}

/*============= Main bulk of functions	=========================*/

static const struct net_device_ops netdev_ops =;

static int
xirc2ps_probe(struct pcmcia_device *link)
{} /* xirc2ps_attach */

static void
xirc2ps_detach(struct pcmcia_device *link)
{} /* xirc2ps_detach */

/****************
 * Detect the type of the card. s is the buffer with the data of tuple 0x20
 * Returns: 0 := not supported
 *		       mediaid=11 and prodid=47
 * Media-Id bits:
 *  Ethernet	    0x01
 *  Tokenring	    0x02
 *  Arcnet	    0x04
 *  Wireless	    0x08
 *  Modem	    0x10
 *  GSM only	    0x20
 * Prod-Id bits:
 *  Pocket	    0x10
 *  External	    0x20
 *  Creditcard	    0x40
 *  Cardbus	    0x80
 *
 */
static int
set_card_type(struct pcmcia_device *link)
{}

/****************
 * There are some CE2 cards out which claim to be a CE card.
 * This function looks for a "CE2" in the 3rd version field.
 * Returns: true if this is a CE2
 */
static int
has_ce2_string(struct pcmcia_device * p_dev)
{}

static int
xirc2ps_config_modem(struct pcmcia_device *p_dev, void *priv_data)
{}

static int
xirc2ps_config_check(struct pcmcia_device *p_dev, void *priv_data)
{}


static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
			     tuple_t *tuple,
			     void *priv)
{
	struct net_device *dev = priv;

	if (tuple->TupleDataLen != 13)
		return -EINVAL;
	if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) ||
		(tuple->TupleData[2] != 6))
		return -EINVAL;
	/* another try	(James Lehmer's CE2 version 4.1)*/
	dev_addr_mod(dev, 2, &tuple->TupleData[2], 4);
	return 0;
};


static int
xirc2ps_config(struct pcmcia_device * link)
{} /* xirc2ps_config */

static void
xirc2ps_release(struct pcmcia_device *link)
{} /* xirc2ps_release */

/*====================================================================*/


static int xirc2ps_suspend(struct pcmcia_device *link)
{}

static int xirc2ps_resume(struct pcmcia_device *link)
{}


/*====================================================================*/

/****************
 * This is the Interrupt service route.
 */
static irqreturn_t
xirc2ps_interrupt(int irq, void *dev_id)
{} /* xirc2ps_interrupt */

/*====================================================================*/

static void
xirc2ps_tx_timeout_task(struct work_struct *work)
{}

static void
xirc_tx_timeout(struct net_device *dev, unsigned int txqueue)
{}

static netdev_tx_t
do_start_xmit(struct sk_buff *skb, struct net_device *dev)
{}

struct set_address_info {};

static void set_address(struct set_address_info *sa_info, const char *addr)
{}

/****************
 * Set all addresses: This first one is the individual address,
 * the next 9 addresses are taken from the multicast list and
 * the rest is filled with the individual address.
 */
static void set_addresses(struct net_device *dev)
{}

/****************
 * Set or clear the multicast filter for this adaptor.
 * We can filter up to 9 addresses, if more are requested we set
 * multicast promiscuous mode.
 */

static void
set_multicast_list(struct net_device *dev)
{}

static int
do_config(struct net_device *dev, struct ifmap *map)
{}

/****************
 * Open the driver
 */
static int
do_open(struct net_device *dev)
{}

static void netdev_get_drvinfo(struct net_device *dev,
			       struct ethtool_drvinfo *info)
{}

static const struct ethtool_ops netdev_ethtool_ops =;

static int
do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{}

static void
hardreset(struct net_device *dev)
{}

static void
do_reset(struct net_device *dev, int full)
{}

/****************
 * Initialize the Media-Independent-Interface
 * Returns: True if we have a good MII
 */
static int
init_mii(struct net_device *dev)
{}

static void
do_powerdown(struct net_device *dev)
{}

static int
do_stop(struct net_device *dev)
{}

static const struct pcmcia_device_id xirc2ps_ids[] =;
MODULE_DEVICE_TABLE(pcmcia, xirc2ps_ids);


static struct pcmcia_driver xirc2ps_cs_driver =;
module_pcmcia_driver();

#ifndef MODULE
static int __init setup_xirc2ps_cs(char *str)
{}

__setup();
#endif