/**************************************************************
$Workfile:   ptmf.c  $
***************************************************************
**							    										
**	Filename    : amur_io.c	  		    									
**	Description : c source file defining the lower level Amur read/write
**	Author	    : Lalit Chaudhari					   
**	Date	    : Feb 13 2002								
**	Notes	    :		  	   		    										
**      References  : 					    											 	
**	Revision History :				    										
**							    												
****************************************************************/


/* #includes */
#include "vxWorks.h"
#include <stdio.h>

//--------------------------------------------------------
void tiww (int phyaddr, int portnum, int regaddr, int data) {
    printf ("ptmf write port: %d  reg: 0x%x  data: 0x%x\n", portnum,regaddr,data);
}
//--------------------------------------------------------
int config_ptmf (int num_of_ch) {
   int i, k;
	
//index 0x06 registers
   k = 0;
   for (i=0; i<num_of_ch; i++) {
       tiw (0, 0, (0xc0+i), (k<<6)|i); // mdio phy addr & enable register
       k = get_next_port (k);
    }

   tiw (0, 0, 0xd0, num_of_ch); // utopia PHYs active register
   tiw (0, 0, 0xd1, 0x3);       // utopia config register0
   
//index 0x05 registers
   k = 1;
   for (i=1; i<num_of_ch; i++) {
       tiw (0, 0, (0xa0+k), (0x20+k)); // mdio phy addr & enable register
       k = get_next_port (k);
    }
   
//index 0x11 registers
   k = 0;
   for (i=0; i<num_of_ch; i++) {  // ethernet port registers
	    printf ("\tConfiguring PTMF port %d\n", k);

        if ((k%2) == 0) {
            tiw (0, k, 0x221, 0x0081);
            tiw (0, k, 0x223, 0x0091);
        }
        else {
            tiw (0, k, 0x221, 0x0089);
            tiw (0, k, 0x223, 0x0099);
        }
        tiw (0, k, 0x222, 0x1060);
        tiw (0, k, 0x224, 0x0060);
        tiw (0, k, 0x226, 0x0001);
        tiw (0, k, 0x220, 0x7f03);
        k = get_next_port (k);
    }

	printf ("\tPTMF configured for %d ports\n", num_of_ch);
}
//----------------------------------------------------------------
int get_next_port (int current_port) {
    if (current_port == 1)
        return 4;
    else if (current_port==5)
        return 8;
    else if (current_port==9)
        return 12;
    else
        return (current_port+1);
}

//----------------------------------------------------------------
void softrst (int prtnum)
{
    tiw (0, prtnum, 0x225, 0x03);
    tiw (0, prtnum, 0x225, 0x43);
    tiw (0, prtnum, 0x225, 0x41);
    tiw (0, prtnum, 0x225, 0x01);
    tiw (0, prtnum, 0x225, 0x41);
    tiw (0, prtnum, 0x225, 0x43);
    tiw (0, prtnum, 0x225, 0x03);
}
//--------------------------------------------------------
int test_ptmf_config () {
   int tmp;
   int error = 0;
	
//index 0x06 registers
   tiw (0, 0, 0xc0,0x0000);  //xmii port 0 -> utopia phy 0
   tiw (0, 0, 0xc1,0x0101);  //xmii port 4 -> utopia phy 1
   tiw (0, 0, 0xc2,0x0202);  //xmii port 8 -> utopia phy 2
   tiw (0, 0, 0xc3,0x0303);  //xmii port 12 -> utopia phy 3
   tiw (0, 0, 0xd0,0x0004);  // UPAR
   tiw (0, 0, 0xd1,0x0003);  // UCR0
   tiw (0, 0, 0xd2,0x0000);  // UCR1
   tiw (0, 0, 0xd3,0x0000);  // HSBR0

//index 0x05 registers
   tiw (0, 0, 0xa4,0x0024);  // PHY1 addr
   tiw (0, 0, 0xa8,0x0028);  // PHY2 addr
   tiw (0, 0, 0xac,0x002c);  // PHY3 addr

//index 0x11 registers
//port 0 config
   tiw (0, 0, 0x221,0x0101);  // TFCR0
   tiw (0, 0, 0x222,0x11e0);  // TFCR1
   tiw (0, 0, 0x223,0x0121);  // RFCR0
   tiw (0, 0, 0x224,0x00e0);  // RFCR1
   tiw (0, 0, 0x226,0x0001);  // DBGR
   tiw (0, 0, 0x220,0x7f03);  // XPCR

//port 4 config
   tiw (0, 4, 0x221,0x0101);  // TFCR0
   tiw (0, 4, 0x222,0x11e0);  // TFCR1
   tiw (0, 4, 0x223,0x0121);  // RFCR0
   tiw (0, 4, 0x224,0x00e0);  // RFCR1
   tiw (0, 4, 0x226,0x0001);  // DBGR
   tiw (0, 4, 0x220,0x7f03);  // XPCR

//port 8 config
   tiw (0, 8, 0x221,0x0101);  // TFCR0
   tiw (0, 8, 0x222,0x11e0);  // TFCR1
   tiw (0, 8, 0x223,0x0121);  // RFCR0
   tiw (0, 8, 0x224,0x00e0);  // RFCR1
   tiw (0, 8, 0x226,0x0001);  // DBGR	
   tiw (0, 8, 0x220,0x7f03);  // XPCR

//port 12 config
   tiw (0, 12, 0x221,0x0101);  // TFCR0
   tiw (0, 12, 0x222,0x11e0);  // TFCR1
   tiw (0, 12, 0x223,0x0121);  // RFCR0
   tiw (0, 12, 0x224,0x00e0);  // RFCR1
   tiw (0, 12, 0x226,0x0001);  // DBGR
   tiw (0, 12, 0x220,0x7f03);  // XPCR

   if (error)
	printf ("\t***** ERROR in programming PTMF\n");
   else
	printf ("\tPTMF programmed correctly\n");
}
//----------------------------------------------------------------
void ptmf_ptm () {
    tiw (0,0,0xd1,1);
    tiw (0,0,0xd3,0x7e);
    printf ("PTMF is now in PTM mode\n");
}
//------------------------------------------------------------
int stats (int port) {
   int stat_array[48];
   int i;
   int address;
   int k;
   char reg_name [48][35] =    {"Ethernet Tx frame count[15:0]      ", 
				"Ethernet Tx frame count[31:16]     ",
				"Octets transmitted counter         ",
				"Octets transmitted counter         ",
				"Ethernet dropped frame count       ",
				"Ethernet dropped frame count       ",
				"Alignment error counter            ",
				"Alignment error counter            ",
				"Frame too long counter             ",
				"Frame too long counter             ",
				"Rx error count                     ",
				"Rx error count                     ",
				"Ethernet CRC error count           ",
				"Ethernet CRC error count           ",
				"junk                               ",
				"junk                               ",
				"Carrier sense error counter        ",
				"Carrier sense error counter        ",
				"Broadcast frame counter            ",
				"Broadcast frame counter            ",
				"Tx pause frame counter             ",
				"Ethernet Rx frame counter          ",
				"Ethernet Rx frame counter          ",
				"Octets received counter            ",
				"Octets received counter            ",
				"Rx HDLC error frame counter        ",
				"Rx HDLC error frame counter        ",
				"Rx HDLC invalid frame counter      ",
				"Rx HDLC invalid frame counter      ",
				"Rx pause frame counter             ",
				"junk                               ",
				"junk                               ",
				"Rx HDLC dropped frame counter      ",
				"Rx HDLC dropped frame counter      ",
				"HD late collision counter          ",
				"HD late collision counter          ",
				"HD excess collision counter        ",
				"HD excess collision counter        ",
				"HD single collision counter        ",
				"HD single collision counter        ",
				"HD multi collision counter         ",
				"HD multi collision counter         ",
				"HD def trans counter               ",
				"HD def trans counter               ",
				"Tx_fifo read pointer               ",
				"Tx_fifo write pointer              ",
				"Rx_fifo read pointer               ",
				"Rx_fifo write pointer              "
};




   for (i = 0; i <= 43; i++) {
	address = (i + 0x250)&0x3ff;
	stat_array[i] = tir(0, port&0x1f, address);
   }

stat_array[44] = tir (0,port&0x1f, 0x240);
stat_array[45] = tir (0,port&0x1f, 0x241);
stat_array[46] = tir (0,port&0x1f, 0x242);
stat_array[47] = tir (0,port&0x1f, 0x243);

   printf("-------------------------------------------------------\n");
   printf ("AMUR Address\t Data\tRegister name\n");
   printf("-------------------------------------------------------\n");
   for (i = 0; i <= 43; i++) {
	address = (i + 0x250)&0x3ff;
	if (((address&0xf) != 0xe) && ((address&0xf) != 0xf)) {
	printf ("   %x\t\t %x\t",address&0x3ff,stat_array[i]&0xffff);
	for (k = 0; k <= 34; k++) {
	printf ("%c",reg_name[i][k]);
	}
	printf ("\n");
	}
   }
	address = 0x240;
   	for (i = 44; i <= 47; i++) {
	printf ("   %x\t\t %x\t",address&0x3ff,stat_array[i]&0xffff);
	for (k = 0; k <= 34; k++) {
	printf ("%c",reg_name[i][k]);
	}
	address = address + 1;
	printf ("\n");
	}
   printf("--------------------------------------------------------\n");
}
//------------------------------------------------------------
void set_ptmf_u25mhz () {
  //set clock freq to 25 mhz
  tiw (0, 0, 0x105, 0xc3);
  tiw (0, 0, 0x106, 0x343);
  tiw (0, 0, 0x106, 0x303);
}
//------------------------------------------------------------
void set_ptmf_c104mhz () {
  //set core clock freq to 104 mhz
  tiw (0, 0, 0x104, 0xcc);
  tiw (0, 0, 0x106, 0x313);
  tiw (0, 0, 0x106, 0x303);
}

    
