Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"

/*
 * 
 * mcc.c
 *
 * This is the driver for the Multi-Channel Communications Controller
 * of the MPC8260.  This version is constructed for the EST SBC8260 to
 * handle data from an interface to an offboard T1 framer.  The driver
 * supports MCC2 + TDM A:2 (channel 128) which is connected to the
 * external interface.
 *
 * Neville Chandler
 * Lucent Technologies - Bell Labs
 * March 2001
 *
 */

#define PKT_LEN                 40
#define MPC82XX_INIT_DELAY      0x10000   

#define HPIC            0xFC000000
#define HPIA            0xFC000010
#define HPID_A          0xFC000020
#define HPID            0xFC000030


#include "mcc2.h"

static ssize_t mcc2_read( struct file *, char *, size_t, loff_t * );
static ssize_t mcc2_write( struct file *, const char *, size_t, loff_t *);
static loff_t mcc2_lseek( struct file *, loff_t, int );
static int mcc2_release( struct inode *, struct file * );
static ssize_t mcc2_ioctl( struct inode *, struct file *, unsigned int, unsigned long );
//static ssize_t mcc2_ioctl( struct inode *, struct file *, unsigned int, char * );

void MPC82xxCpmInit( void );
void PortInit( void );
void PortSelectPin( unsigned short );

void InitMemAlloc( void );
void HeapCreate( U32, U32, U32, U32, char *);
void HeapCreate( U32, U32, U32, U32, char *);
void *HeapSearchMem( U32, U32);
void *HeapAllocMem( U32, U32);
void HeapFreeMem( U32, void *);

void InitLinkedList( void );
boolean DwCreateList( ListDB * );
void *DwMalloc( U32 );
void DwFree( U32, void * );

void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);

#define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)

extern int ppc_spurious_interrupts;
extern int ppc_second_irq;
extern struct irqaction *ppc_irq_action[NR_IRQS];
extern unsigned int ppc_local_bh_count[NR_CPUS];
extern unsigned int ppc_local_irq_count[NR_CPUS];
extern unsigned int ppc_cached_irq_mask[NR_MASK_WORDS];
extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
extern atomic_t ppc_n_lost_interrupts;

//static void disp_led( unsigned char );

void    Mcc2Init( void );
void    MccDisable( unsigned char );
void    MccEnable( unsigned char, unsigned char, unsigned char );
void    MccRiscCmd( unsigned char, dwv_RISC_OPCODE, unsigned char );
boolean MccTest( void );
int     MccTxBuffer( unsigned char, unsigned char, char *, unsigned short, unsigned short );
extern  U32 PpcDisable( void );
extern  void PpcMsrRestore( U32 );

static  int     mcc2_major = MCC_MAJOR;

static  BOOLEAN insertBD_T( BD_PFIFO *, BD_P );
static  BOOLEAN removBD_T( BD_PFIFO *, BD_P * );
BOOLEAN empty(volatile register FIFO *);
int     insert( FIFO *, char * );
int     remove( FIFO *, char ** );
void    AppInit( void );

#define physaddr(ADDR)  (0x60020000 | ((ADDR) << 23) | (2 << 18))
  
mcc_iorw_t mcc_iorw;

#if 0
typedef struct mcc_io {
        unsigned int    cmd;
        unsigned int    address;
        unsigned int    *buf;
        int             ind;
        int             nbytes;
        siramctl_t      SiRam;
        cpmux_t         CpMux;
        mcc_t           Mcc_T;
        iop8260_t       Io_Ports;
} mcc_iorw_t;
#endif

static void
ioctl_parm( unsigned int loop_mode )
{

        /* Setup the SIMODE Register */
        Si2Regs->SiAmr = SIxMR_SAD_BANK0_FIRST_HALF    |  /* SADx  */
                         loop_mode                     |  /* SDMx  */
                         SIxMR_NO_BIT_RX_SYNC_DELAY    |  /* RFSDx */
                         SIxMR_DSC_CH_DATA_CLK_EQU     |  /* DSCx  */
                         SIxMR_CRT_SPEPARATE_PINS      |  /* CRTx  */
                         SIxMR_SLx_NORMAL_OPERATION    |  /* SLx   */
                         SIxMR_CE_TX_RISING_RX_FALLING |  /* CEx   */
                         SIxMR_FE_FALLING_EDGE         |  /* FEx   */
                         SIxMR_GM_GCI_SCIT_MODE        |  /* GMx   */
                         SIxMR_NO_BIT_TX_SYNC_DELAY;      /* TFSDx */
}

#if 0
static void
disp_led( unsigned char byte )
{
     //int i;

     *leds = byte;
     //for(i=0; i<1000; i++);

}
#endif



static ssize_t
mcc2_ioctl( struct inode *inode, struct file *file,
                              unsigned int ioctl_cmd,           // IOCTL number
                              unsigned long param )
//                            char *param )                     // IOCTL parameter
{
        static unsigned char mode;
        char cp, *cptr;
        void *vptr;
        unsigned long *lptr;
        int i, j;
        unsigned int ld;
        unsigned long lng;
        volatile immap_t *Mmap;

        cptr = (char *)param;
        mode = (unsigned char)*cptr;
        Mmap = ((volatile immap_t *)IMAP_ADDR);
        switch(ioctl_cmd)
        {
                case IOCTL_SET_MODE:
                            //mode = (unsigned char)*param;
                            mode = ((mcc_iorw_t *)param)->cmd;
                            switch( mode )
                            {
                                case NORMAL_OPERATION:
                                        /* Setup the SIMODE Register */
                                        D( printk("mcc2_ioctl: ioctl set NORMAL_OPERATION mode\n"); )
                                        ioctl_parm( (unsigned int)SIxMR_SDM_NORMAL_OPERATION );         /* SDMx  */
                                        break;

                                case AUTOMATIC_ECHO:
                                        /* Setup the SIMODE Register */
                                        D( printk("mcc2_ioctl: ioctl set AUTOMATIC_ECHO mode\n"); )
                                        ioctl_parm( (unsigned int)SIxMR_SDM_AUTOMATIC_ECHO );           /* SDMx  */
                                        break;

                                case INTERNAL_LOOPBACK:
                                        /* Setup the SIMODE Register */
                                        D( printk("mcc2_ioctl: ioctl set INTERNAL_LOOPBACK mode\n"); )
                                        ioctl_parm( (unsigned int)SIxMR_SDM_INTERNAL_LOOPBACK );        /* SDMx  */
                                        break;

                                case LOOPBACK_CONTROL:
                                        /* Setup the SIMODE Register */
                                        D( printk("mcc2_ioctl: ioctl set LOOPBACK_CONTROL mode\n"); )
                                        ioctl_parm( (unsigned int)SIxMR_SDM_LOOPBACK_CONTROL );         /* SDMx  */
                                        break;


                                default:
                                        printk("mcc2_ioctl: Error, unrecognized ioctl parameter, device operation unchanged.\n");
                                        break;

                            }
                        break;

                case IOCTL_RWX_MODE:
                        mode = ((mcc_iorw_t *)param)->cmd;
                        switch(mode)
                        {
                                case HPI_RD:
                                        lng = (long)(((mcc_iorw_t *)param)->address);
                                        lptr =  ((unsigned long *)lng);
                                        vptr = (void *)lptr;
                                        if (copy_to_user( (((mcc_iorw_t *)param)->buf), (void *)vptr, (((mcc_iorw_t *)param)->nbytes))) {
                                                printk("mcc2_ioctl: Failed during  read from hpi.\n");
                                                return -EFAULT;
                                        }
                                        break; 
                                        
                                                                          
                                case HPI_WR:
                                        lng = (long)(((mcc_iorw_t *)param)->address);
                                        lptr =  ((unsigned long *)lng);
                                        vptr = (void *)lptr;
                                        if (copy_from_user( (void *)vptr, (((mcc_iorw_t *)param)->buf), (((mcc_iorw_t *)param)->nbytes))) {
                                                printk("mcc2_ioctl: Failed during  write to hpi\n");
                                                return -EFAULT;
                                        }
                                        break; 
                                        


                                case FPGA_RD:
                                        lng = (long)(((mcc_iorw_t *)param)->address);
                                        lptr =  ((unsigned long *)lng);
                                        vptr = (void *)lptr;
                                        if (copy_to_user( (((mcc_iorw_t *)param)->buf), (void *)vptr, (((mcc_iorw_t *)param)->nbytes))) {
                                                printk("mcc2_ioctl: Failed during  read from FPGA.\n");
                                                return -EFAULT;
                                        }
                                        break;


                                case FPGA_WR:
                                        lng = (long)(((mcc_iorw_t *)param)->address);
                                        lptr =  ((unsigned long *)lng);
                                        vptr = (void *)lptr;
                                        if (copy_from_user( (void *)vptr, (((mcc_iorw_t *)param)->buf), (((mcc_iorw_t *)param)->nbytes))) {
                                                printk("mcc2_ioctl: Failed during  write to FPGA\n");
                                                return -EFAULT;
                                        }
                                        break;




                           
                                case MEM_MODR:
                                        cptr = (char *)Mmap;
                                        cptr += ((mcc_iorw_t *)param)->address;
                                        if (copy_to_user( (((mcc_iorw_t *)param)->buf), (void *)cptr, (((mcc_iorw_t *)param)->nbytes))) {
                                                printk("mcc2_ioctl: Failed during read of read-modify memory\n");
                                                return -EFAULT;
                                        }
                                        break;

                                case MEM_MODW:
                                        cptr = (char *)Mmap;
                                        cptr += ((mcc_iorw_t *)param)->address;
                                        if (copy_from_user( (void *)cptr, (((mcc_iorw_t *)param)->buf), (((mcc_iorw_t *)param)->nbytes))) {
                                                printk("mcc2_ioctl: Failed during modify of read-modify memory\n");
                                                return -EFAULT;
                                        }
                                        break;

                                case IO_PORTS:
                                        break;
                                case SI_RAM_CTL1:
                                        break;
                                case SI_RAM_CTL2:
                                        if (copy_to_user( (void *)param, (siramctl_t *)&(Mmap->im_siramctl2), sizeof(siramctl_t))) {
                                                printk("mcc2_ioctl: Failed to copy SI_RAM_CTL2 struct\n");
                                                return -EFAULT;
                                        }
                                        break;



                                default:
                                        break;
                        }
                        break;

                                default:
                                        //if (copy_to_user((void *)param, &mode, sizeof(mode)))
                                        printk("We are at the end ...\n");
                                        return -EFAULT;
                                        break;
                        }
                        break;

                default:
                        break;
        }

        return 0;
}


////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////

static ssize_t
mcc2_open( struct inode *inode, struct file *file )
{
        MOD_INC_USE_COUNT;
        return 0;
}



////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////

static int
mcc2_release( struct inode *inode, struct file *file )
{
        MOD_DEC_USE_COUNT;
        return 0;
}






#ifndef MODULE

////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////

long
mcc2_init( long mem_start, long mem_end )
{

        if ((mcc2_major = register_chrdev(MCC_MAJOR, MCC_NAME, &mcc2_fops)))
                printk("mcc2_init: Unable to get major for mcc2 device %d\n", MCC_MAJOR);
        else {
                //MPC82xxSiuInit();
                MPC82xxCpmInit();
        }
        return mem_start;
}

#else