/*
	drivers/net/tulip/pnic2.c

	Copyright 2000,2001  The Linux Kernel Team
	Written/copyright 1994-2001 by Donald Becker.
        Modified to hep support PNIC_II by Kevin B. Hendricks

	This software may be used and distributed according to the terms
	of the GNU General Public License, incorporated herein by reference.

        Please submit bugs to http://bugzilla.kernel.org/ .
*/


/* Understanding the PNIC_II - everything is this file is based
 * on the PNIC_II_PDF datasheet which is sorely lacking in detail
 *
 * As I understand things, here are the registers and bits that
 * explain the masks and constants used in this file that are
 * either different from the 21142/3 or important for basic operation.
 *
 *
 * CSR 6  (mask = 0xfe3bd1fd of bits not to change)
 * -----
 * Bit 24    - SCR
 * Bit 23    - PCS
 * Bit 22    - TTM (Trasmit Threshold Mode)
 * Bit 18    - Port Select
 * Bit 13    - Start - 1, Stop - 0 Transmissions
 * Bit 11:10 - Loop Back Operation Mode
 * Bit 9     - Full Duplex mode (Advertise 10BaseT-FD is CSR14<7> is set)
 * Bit 1     - Start - 1, Stop - 0 Receive
 *
 *
 * CSR 14  (mask = 0xfff0ee39 of bits not to change)
 * ------
 * Bit 19    - PAUSE-Pause
 * Bit 18    - Advertise T4
 * Bit 17    - Advertise 100baseTx-FD
 * Bit 16    - Advertise 100baseTx-HD
 * Bit 12    - LTE - Link Test Enable
 * Bit 7     - ANE - Auto Negotiate Enable
 * Bit 6     - HDE - Advertise 10baseT-HD
 * Bit 2     - Reset to Power down - kept as 1 for normal operation
 * Bit 1     -  Loop Back enable for 10baseT MCC
 *
 *
 * CSR 12
 * ------
 * Bit 25    - Partner can do T4
 * Bit 24    - Partner can do 100baseTx-FD
 * Bit 23    - Partner can do 100baseTx-HD
 * Bit 22    - Partner can do 10baseT-FD
 * Bit 21    - Partner can do 10baseT-HD
 * Bit 15    - LPN is 1 if all above bits are valid other wise 0
 * Bit 14:12 - autonegotiation state (write 001 to start autonegotiate)
 * Bit 3     - Autopolarity state
 * Bit 2     - LS10B - link state of 10baseT 0 - good, 1 - failed
 * Bit 1     - LS100B - link state of 100baseT 0 - good, 1 - failed
 *
 *
 * Data Port Selection Info
 *-------------------------
 *
 * CSR14<7>   CSR6<18>    CSR6<22>    CSR6<23>    CSR6<24>   MODE/PORT
 *   1           0           0 (X)       0 (X)       1        NWAY
 *   0           0           1           0 (X)       0        10baseT
 *   0           1           0           1           1 (X)    100baseT
 *
 *
 */



#include "tulip.h"
#include <linux/delay.h>


void pnic2_timer(unsigned long data)
{
	struct net_device *dev = (struct net_device *)data;
	struct tulip_private *tp = netdev_priv(dev);
	void __iomem *ioaddr = tp->base_addr;
	int next_tick = 60*HZ;

	if (tulip_debug > 3)
		dev_info(&dev->dev, "PNIC2 negotiation status %08x\n",
			 ioread32(ioaddr + CSR12));

	if (next_tick) {
		mod_timer(&tp->timer, RUN_AT(next_tick));
	}
}


void pnic2_start_nway(struct net_device *dev)
{
	struct tulip_private *tp = netdev_priv(dev);
	void __iomem *ioaddr = tp->base_addr;
        int csr14;
        int csr12;

        /* set up what to advertise during the negotiation */

        /* load in csr14  and mask off bits not to touch
         * comment at top of file explains mask value
         */
	csr14 = (ioread32(ioaddr + CSR14) & 0xfff0ee39);

        /* bit 17 - advetise 100baseTx-FD */
        if (tp->sym_advertise & 0x0100) csr14 |= 0x00020000;

        /* bit 16 - advertise 100baseTx-HD */
        if (tp->sym_advertise & 0x0080) csr14 |= 0x00010000;

        /* bit 6 - advertise 10baseT-HD */
        if (tp->sym_advertise & 0x0020) csr14 |= 0x00000040;

        /* Now set bit 12 Link Test Enable, Bit 7 Autonegotiation Enable
         * and bit 0 Don't PowerDown 10baseT
         */
        csr14 |= 0x00001184;

	if (tulip_debug > 1)
		netdev_dbg(dev, "Restarting PNIC2 autonegotiation, csr14=%08x\n",
			   csr14);

        /* tell pnic2_lnk_change we are doing an nway negotiation */
	dev->if_port = 0;
	tp->nway = tp->mediasense = 1;
	tp->nwayset = tp->lpar = 0;

        /* now we have to set up csr6 for NWAY state */

	tp->csr6 = ioread32(ioaddr + CSR6);
	if (tulip_debug > 1)
		netdev_dbg(dev, "On Entry to Nway, csr6=%08x\n", tp->csr6);

        /* mask off any bits not to touch
         * comment at top of file explains mask value
         */
	tp->csr6 = tp->csr6 & 0xfe3bd1fd;

        /* don't forget that bit 9 is also used for advertising */
        /* advertise 10baseT-FD for the negotiation (bit 9) */
        if (tp->sym_advertise & 0x0040) tp->csr6 |= 0x00000200;

        /* set bit 24 for nway negotiation mode ...
         * see Data Port Selection comment at top of file
         * and "Stop" - reset both Transmit (bit 13) and Receive (bit 1)
         */
        tp->csr6 |= 0x01000000;
	iowrite32(csr14, ioaddr + CSR14);
	iowrite32(tp->csr6, ioaddr + CSR6);
        udelay(100);

        /* all set up so now force the negotiation to begin */

        /* read in current values and mask off all but the
	 * Autonegotiation bits 14:12.  Writing a 001 to those bits
         * should start the autonegotiation
         */
        csr12 = (ioread32(ioaddr + CSR12) & 0xffff8fff);
        csr12 |= 0x1000;
	iowrite32(csr12, ioaddr + CSR12);
}



void pnic2_lnk_change(struct net_device *dev, int csr5)
{
	struct tulip_private *tp = netdev_priv(dev);
	void __iomem *ioaddr = tp->base_addr;
        int csr14;

        /* read the staus register to find out what is up */
	int csr12 = ioread32(ioaddr + CSR12);

	if (tulip_debug > 1)
		dev_info(&dev->dev,
			 "PNIC2 link status interrupt %08x,  CSR5 %x, %08x\n",
			 csr12, csr5, ioread32(ioaddr + CSR14));

	/* If NWay finished and we have a negotiated partner capability.
         * check bits 14:12 for bit pattern 101 - all is good
         */
	if (tp->nway  &&  !tp->nwayset) {

	        /* we did an auto negotiation */

                if ((csr12 & 0x7000) == 0x5000) {

	               /* negotiation ended successfully */

	               /* get the link partners reply and mask out all but
                        * bits 24-21 which show the partners capabilities
                        * and match those to what we advertised
                        *
                        * then begin to interpret the results of the negotiation.
                        * Always go in this order : (we are ignoring T4 for now)
                        *     100baseTx-FD, 100baseTx-HD, 10baseT-FD, 10baseT-HD
                        */

		        int negotiated = ((csr12 >> 16) & 0x01E0) & tp->sym_advertise;
		        tp->lpar = (csr12 >> 16);
		        tp->nwayset = 1;

                        if (negotiated & 0x0100)        dev->if_port = 5;
		        else if (negotiated & 0x0080)	dev->if_port = 3;
		        else if (negotiated & 0x0040)	dev->if_port = 4;
			else if (negotiated & 0x0020)	dev->if_port = 0;
			else {
			     if (tulip_debug > 1)
				     dev_info(&dev->dev,
					      "funny autonegotiate result csr12 %08x advertising %04x\n",
					      csr12, tp->sym_advertise);
			     tp->nwayset = 0;
			     /* so check  if 100baseTx link state is okay */
			     if ((csr12 & 2) == 0  &&  (tp->sym_advertise & 0x0180))
			       dev->if_port = 3;
			}

			/* now record the duplex that was negotiated */
			tp->full_duplex = 0;
			if ((dev->if_port == 4) || (dev->if_port == 5))
			       tp->full_duplex = 1;

			if (tulip_debug > 1) {
			       if (tp->nwayset)
				       dev_info(&dev->dev,
						"Switching to %s based on link negotiation %04x & %04x = %04x\n",
						medianame[dev->if_port],
						tp->sym_advertise, tp->lpar,
						negotiated);
			}

                        /* remember to turn off bit 7 - autonegotiate
                         * enable so we can properly end nway mode and
                         * set duplex (ie. use csr6<9> again)
                         */
	                csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f);
                        iowrite32(csr14,ioaddr + CSR14);


                        /* now set the data port and operating mode
			 * (see the Data Port Selection comments at
			 * the top of the file
			 */

			/* get current csr6 and mask off bits not to touch */
			/* see comment at top of file */

			tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd);

			/* so if using if_port 3 or 5 then select the 100baseT
			 * port else select the 10baseT port.
			 * See the Data Port Selection table at the top
			 * of the file which was taken from the PNIC_II.PDF
			 * datasheet
			 */
			if (dev->if_port & 1) tp->csr6 |= 0x01840000;
			else tp->csr6 |= 0x00400000;

			/* now set the full duplex bit appropriately */
			if (tp->full_duplex) tp->csr6 |= 0x00000200;

			iowrite32(1, ioaddr + CSR13);

			if (tulip_debug > 2)
				netdev_dbg(dev, "Setting CSR6 %08x/%x CSR12 %08x\n",
					   tp->csr6,
					   ioread32(ioaddr + CSR6),
					   ioread32(ioaddr + CSR12));

			/* now the following actually writes out the
			 * new csr6 values
			 */
			tulip_start_rxtx(tp);

                        return;

	        } else {
	                dev_info(&dev->dev,
				 "Autonegotiation failed, using %s, link beat status %04x\n",
				 medianame[dev->if_port], csr12);

                        /* remember to turn off bit 7 - autonegotiate
                         * enable so we don't forget
                         */
	                csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f);
                        iowrite32(csr14,ioaddr + CSR14);

                        /* what should we do when autonegotiate fails?
                         * should we try again or default to baseline
                         * case.  I just don't know.
                         *
                         * for now default to some baseline case
                         */

	                 dev->if_port = 0;
                         tp->nway = 0;
                         tp->nwayset = 1;

                         /* set to 10baseTx-HD - see Data Port Selection
                          * comment given at the top of the file
                          */
	                 tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd);
                         tp->csr6 |= 0x00400000;

	                 tulip_restart_rxtx(tp);

                         return;

		}
	}

	if ((tp->nwayset  &&  (csr5 & 0x08000000) &&
	     (dev->if_port == 3  ||  dev->if_port == 5) &&
	     (csr12 & 2) == 2) || (tp->nway && (csr5 & (TPLnkFail)))) {

		/* Link blew? Maybe restart NWay. */

		if (tulip_debug > 2)
			netdev_dbg(dev, "Ugh! Link blew?\n");

		del_timer_sync(&tp->timer);
		pnic2_start_nway(dev);
		tp->timer.expires = RUN_AT(3*HZ);
		add_timer(&tp->timer);

                return;
	}


        if (dev->if_port == 3  ||  dev->if_port == 5) {

	        /* we are at 100mb and a potential link change occurred */

		if (tulip_debug > 1)
			dev_info(&dev->dev, "PNIC2 %s link beat %s\n",
				 medianame[dev->if_port],
				 (csr12 & 2) ? "failed" : "good");

                /* check 100 link beat */

                tp->nway = 0;
                tp->nwayset = 1;

                /* if failed then try doing an nway to get in sync */
		if ((csr12 & 2)  &&  ! tp->medialock) {
			del_timer_sync(&tp->timer);
			pnic2_start_nway(dev);
			tp->timer.expires = RUN_AT(3*HZ);
       			add_timer(&tp->timer);
                }

                return;
        }

	if (dev->if_port == 0  ||  dev->if_port == 4) {

	        /* we are at 10mb and a potential link change occurred */

		if (tulip_debug > 1)
			dev_info(&dev->dev, "PNIC2 %s link beat %s\n",
				 medianame[dev->if_port],
				 (csr12 & 4) ? "failed" : "good");


                tp->nway = 0;
                tp->nwayset = 1;

                /* if failed, try doing an nway to get in sync */
		if ((csr12 & 4)  &&  ! tp->medialock) {
			del_timer_sync(&tp->timer);
			pnic2_start_nway(dev);
			tp->timer.expires = RUN_AT(3*HZ);
       			add_timer(&tp->timer);
                }

                return;
        }


	if (tulip_debug > 1)
		dev_info(&dev->dev, "PNIC2 Link Change Default?\n");

        /* if all else fails default to trying 10baseT-HD */
	dev->if_port = 0;

        /* make sure autonegotiate enable is off */
	csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f);
        iowrite32(csr14,ioaddr + CSR14);

        /* set to 10baseTx-HD - see Data Port Selection
         * comment given at the top of the file
         */
	tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd);
        tp->csr6 |= 0x00400000;

	tulip_restart_rxtx(tp);
}

