/*
* 3c595.c -- 3COM 3C595 Fast Etherlink III PCI driver for etherboot
*
* Copyright (C) 2000 Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
* All rights reserved.
* Mar. 14, 2000
*
*  This software may be used, modified, copied, distributed, and sold, in
*  both source and binary form provided that the above copyright and these
*  terms are retained. Under no circumstances are the authors responsible for
*  the proper functioning of this software, nor do the authors assume any
*  responsibility for damages incurred with its use.
*
* This code is based on Martin Renters' etherboot-4.4.3 3c509.c and 
* Herb Peyerl's FreeBSD 3.4-RELEASE if_vx.c driver.
*
*  Copyright (C) 1993-1994, David Greenman, Martin Renters.
*  Copyright (C) 1993-1995, Andres Vega Garcia.
*  Copyright (C) 1995, Serge Babkin.
*
*  Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
*
*/

/* #define EDEBUG */

#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "3c595.h"
#include "timer.h"

static unsigned short	eth_nic_base, eth_asic_base;
static unsigned short	vx_connector, vx_connectors;

static struct connector_entry {
  int bit;
  char *name;
} conn_tab[VX_CONNECTORS] = {
#define CONNECTOR_UTP   0
  { 0x08, "utp"},
#define CONNECTOR_AUI   1
  { 0x20, "aui"},
/* dummy */
  { 0, "???"},
#define CONNECTOR_BNC   3
  { 0x10, "bnc"},
#define CONNECTOR_TX    4
  { 0x02, "tx"},
#define CONNECTOR_FX    5
  { 0x04, "fx"},
#define CONNECTOR_MII   6
  { 0x40, "mii"},
  { 0, "???"}
};

static void vxgetlink(void);
static void vxsetlink(void);

#define	udelay(n)	waiton_timer2(((n)*TICKS_PER_MS)/1000)

/**************************************************************************
ETH_RESET - Reset adapter
***************************************************************************/
static void t595_reset(struct nic *nic)
{
	int i, j;

	/***********************************************************
			Reset 3Com 595 card
	*************************************************************/

	/* stop card */
	outw(RX_DISABLE, BASE + VX_COMMAND);
	outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
	VX_BUSY_WAIT;
	outw(TX_DISABLE, BASE + VX_COMMAND);
	outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
	udelay(8000);
	outw(RX_RESET, BASE + VX_COMMAND);
	VX_BUSY_WAIT;
	outw(TX_RESET, BASE + VX_COMMAND);
	VX_BUSY_WAIT;
	outw(C_INTR_LATCH, BASE + VX_COMMAND);
	outw(SET_RD_0_MASK, BASE + VX_COMMAND);
	outw(SET_INTR_MASK, BASE + VX_COMMAND);
	outw(SET_RX_FILTER, BASE + VX_COMMAND);

	/*
	* initialize card
	*/
	VX_BUSY_WAIT;

	GO_WINDOW(0);

	/* Disable the card */
/*	outw(0, BASE + VX_W0_CONFIG_CTRL); */

	/* Configure IRQ to none */
/*	outw(SET_IRQ(0), BASE + VX_W0_RESOURCE_CFG); */

	/* Enable the card */
/*	outw(ENABLE_DRQ_IRQ, BASE + VX_W0_CONFIG_CTRL); */

	GO_WINDOW(2);

	/* Reload the ether_addr. */
	for (i = 0; i < ETH_ALEN; i++)
		outb(nic->node_addr[i], BASE + VX_W2_ADDR_0 + i);

	outw(RX_RESET, BASE + VX_COMMAND);
	VX_BUSY_WAIT;
	outw(TX_RESET, BASE + VX_COMMAND);
	VX_BUSY_WAIT;

	/* Window 1 is operating window */
	GO_WINDOW(1);
	for (i = 0; i < 31; i++)
		inb(BASE + VX_W1_TX_STATUS);

	outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
		S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
	outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
		S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);

/*
 * Attempt to get rid of any stray interrupts that occured during
 * configuration.  On the i386 this isn't possible because one may
 * already be queued.  However, a single stray interrupt is
 * unimportant.
 */

	outw(ACK_INTR | 0xff, BASE + VX_COMMAND);

	outw(SET_RX_FILTER | FIL_INDIVIDUAL |
	    FIL_BRDCST, BASE + VX_COMMAND);

	vxsetlink();
/*{
	int i,j;
	i = CONNECTOR_TX;
	GO_WINDOW(3);
	j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
	outl(BASE + VX_W3_INTERNAL_CFG, j | (i <<INTERNAL_CONNECTOR_BITS));
        GO_WINDOW(4);
        outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
        GO_WINDOW(1);
}*/

	/* start tranciever and receiver */
	outw(RX_ENABLE, BASE + VX_COMMAND);
	outw(TX_ENABLE, BASE + VX_COMMAND);

}

/**************************************************************************
ETH_TRANSMIT - Transmit a frame
***************************************************************************/
static char padmap[] = {
	0, 3, 2, 1};

static void t595_transmit(
struct nic *nic,
const char *d,			/* Destination */
unsigned int t,			/* Type */
unsigned int s,			/* size */
const char *p)			/* Packet */
{
	register int len;
	int pad;
	int status;

#ifdef EDEBUG
	printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
#endif

	/* swap bytes of type */
	t= htons(t);

	len=s+ETH_HLEN; /* actual length of packet */
	pad = padmap[len & 3];

	/*
	* The 3c595 automatically pads short packets to minimum ethernet length,
	* but we drop packets that are too large. Perhaps we should truncate
	* them instead?
	*/
	if (len + pad > ETH_FRAME_LEN) {
		return;
	}

	/* drop acknowledgements */
	while(( status=inb(BASE + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
		if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
			outw(TX_RESET, BASE + VX_COMMAND);
			outw(TX_ENABLE, BASE + VX_COMMAND);
		}

		outb(0x0, BASE + VX_W1_TX_STATUS);
	}

	while (inw(BASE + VX_W1_FREE_TX) < len + pad + 4) {
		/* no room in FIFO */
	}

	outw(len, BASE + VX_W1_TX_PIO_WR_1);
	outw(0x0, BASE + VX_W1_TX_PIO_WR_1);	/* Second dword meaningless */

	/* write packet */
	outsw(BASE + VX_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
	outsw(BASE + VX_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
	outw(t, BASE + VX_W1_TX_PIO_WR_1);
	outsw(BASE + VX_W1_TX_PIO_WR_1, p, s / 2);
	if (s & 1)
		outb(*(p+s - 1), BASE + VX_W1_TX_PIO_WR_1);

	while (pad--)
		outb(0, BASE + VX_W1_TX_PIO_WR_1);	/* Padding */

        /* wait for Tx complete */
        while((inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
                ;
}

/**************************************************************************
ETH_POLL - Wait for a frame
***************************************************************************/
static int t595_poll(struct nic *nic)
{
	/* common variables */
	unsigned short type = 0;	/* used by EDEBUG */
	/* variables for 3C595 */
	short status, cst;
	register short rx_fifo;

	cst=inw(BASE + VX_STATUS);

#ifdef EDEBUG
	if(cst & 0x1FFF)
		printf("-%hX-",cst);
#endif

	if( (cst & S_RX_COMPLETE)==0 ) {
		/* acknowledge  everything */
		outw(ACK_INTR | cst, BASE + VX_COMMAND);
		outw(C_INTR_LATCH, BASE + VX_COMMAND);

		return 0;
	}

	status = inw(BASE + VX_W1_RX_STATUS);
#ifdef EDEBUG
	printf("*%hX*",status);
#endif

	if (status & ERR_RX) {
		outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
		return 0;
	}

	rx_fifo = status & RX_BYTES_MASK;
	if (rx_fifo==0)
		return 0;

		/* read packet */
#ifdef EDEBUG
	printf("[l=%d",rx_fifo);
#endif
	insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
	if(rx_fifo & 1)
		nic->packet[rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
	nic->packetlen=rx_fifo;

	while(1) {
		status = inw(BASE + VX_W1_RX_STATUS);
#ifdef EDEBUG
		printf("*%hX*",status);
#endif
		rx_fifo = status & RX_BYTES_MASK;

		if(rx_fifo>0) {
			insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);
			if(rx_fifo & 1)
				nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
			nic->packetlen+=rx_fifo;
#ifdef EDEBUG
			printf("+%d",rx_fifo);
#endif
		}
		if(( status & RX_INCOMPLETE )==0) {
#ifdef EDEBUG
			printf("=%d",nic->packetlen);
#endif
			break;
		}
		udelay(1000);
	}

	/* acknowledge reception of packet */
	outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
	while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS);
#ifdef EDEBUG
	type = (nic->packet[12]<<8) | nic->packet[13];
	if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
	    nic->packet[5] == 0xFF*ETH_ALEN)
		printf(",t=%hX,b]",type);
	else
		printf(",t=%hX]",type);
#endif
	return 1;
}


/*************************************************************************
	3Com 595 - specific routines
**************************************************************************/

static int
eeprom_rdy()
{
	int i;

	for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++)
		udelay(1000);
	if (i >= MAX_EEPROMBUSY) {
	        /* printf("3c595: eeprom failed to come ready.\n"); */
		printf("3c595: eeprom is busy.\n"); /* memory in EPROM is tight */
		return (0);
	}
	return (1);
}

/*
 * get_e: gets a 16 bits word from the EEPROM. we must have set the window
 * before
 */
static int
get_e(offset)
int offset;
{
	if (!eeprom_rdy())
		return (0xffff);
	outw(EEPROM_CMD_RD | offset, BASE + VX_W0_EEPROM_COMMAND);
	if (!eeprom_rdy())
		return (0xffff);
	return (inw(BASE + VX_W0_EEPROM_DATA));
}

static void            
vxgetlink(void)
{
    int n, k;

    GO_WINDOW(3);
    vx_connectors = inw(BASE + VX_W3_RESET_OPT) & 0x7f;
    for (n = 0, k = 0; k < VX_CONNECTORS; k++) {
      if (vx_connectors & conn_tab[k].bit) {
        if (n > 0) {
          printf("/");
	}
        printf(conn_tab[k].name);
        n++;
      }
    }
    if (vx_connectors == 0) {
        printf("no connectors!");
        return;
    }
    GO_WINDOW(3);
    vx_connector = (inl(BASE + VX_W3_INTERNAL_CFG) 
                        & INTERNAL_CONNECTOR_MASK) 
                        >> INTERNAL_CONNECTOR_BITS;
    if (vx_connector & 0x10) {
        vx_connector &= 0x0f;
        printf("[*%s*]", conn_tab[vx_connector].name);
        printf(": disable 'auto select' with DOS util!");
    } else {
        printf("[*%s*]", conn_tab[vx_connector].name);
    }
}

static void            
vxsetlink(void)
{       
    int i, j, k;
    char *reason, *warning;
    static short prev_flags;
    static char prev_conn = -1;

    if (prev_conn == -1) {
        prev_conn = vx_connector;
    }

    i = vx_connector;       /* default in EEPROM */
    reason = "default";
    warning = 0;

    if ((vx_connectors & conn_tab[vx_connector].bit) == 0) {
        warning = "strange connector type in EEPROM.";
        reason = "forced";
        i = CONNECTOR_UTP;
    }

        if (warning != 0) {
            printf("warning: %s\n", warning);
        }
        printf("selected %s. (%s)\n", conn_tab[i].name, reason);

    /* Set the selected connector. */
    GO_WINDOW(3);
    j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
    outl(j | (i <<INTERNAL_CONNECTOR_BITS), BASE + VX_W3_INTERNAL_CFG);

    /* First, disable all. */
    outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
    udelay(8000);
    GO_WINDOW(4);
    outw(0, BASE + VX_W4_MEDIA_TYPE);

    /* Second, enable the selected one. */
    switch(i) {
      case CONNECTOR_UTP:
        GO_WINDOW(4);
        outw(ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
        break;
      case CONNECTOR_BNC:
        outw(START_TRANSCEIVER,BASE + VX_COMMAND);
        udelay(8000);
        break;
      case CONNECTOR_TX:
      case CONNECTOR_FX:
        GO_WINDOW(4);
        outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
        break;
      default:  /* AUI and MII fall here */
        break;
    }
    GO_WINDOW(1); 
}

static void t595_disable(struct nic *nic)
{
    outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
    udelay(8000);
    GO_WINDOW(4);
    outw(0, BASE + VX_W4_MEDIA_TYPE);
    GO_WINDOW(1);
}

/**************************************************************************
ETH_PROBE - Look for an adapter
***************************************************************************/
struct nic *t595_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
{
	int i;
	unsigned short *p;

	if (probeaddrs == 0 || probeaddrs[0] == 0)
		return 0;
/*	eth_nic_base = probeaddrs[0] & ~3; */
	eth_nic_base = pci->ioaddr;

	GO_WINDOW(0);
	outw(GLOBAL_RESET, BASE + VX_COMMAND);
	VX_BUSY_WAIT;

	vxgetlink();

/*
	printf("\nEEPROM:");
	for (i = 0; i < (EEPROMSIZE/2); i++) {
	  printf("%hX:", get_e(i));
	}
	printf("\n");
*/
	/*
	* Read the station address from the eeprom
	*/
	p = (unsigned short *) nic->node_addr;
	for (i = 0; i < 3; i++) {
		GO_WINDOW(0);
		p[i] = htons(get_e(EEPROM_OEM_ADDR_0 + i));
		GO_WINDOW(2);
		outw(ntohs(p[i]), BASE + VX_W2_ADDR_0 + (i * 2));
	}

	printf("Ethernet address: %!\n", nic->node_addr);

	t595_reset(nic);
	nic->reset = t595_reset;
	nic->poll = t595_poll;
	nic->transmit = t595_transmit;
	nic->disable = t595_disable;
	return nic;

}

/*
 * Local variables:
 *  c-basic-offset: 8
 * End:
 */

