/* ==========================================================================
 * Copyright (C) 2002 Analog Devices Inc. All rights reserved
 *
 * The information and source code contained herein is the exclusive property
 * of Analog Devices and may not be disclosed, examined or reproduced in whole
 * or in part without the explicit written authorization from Analog Devices.
 *
 * ===========================================================================*/

/******************************************************************************
 * File Name     : fusiv_bme.c
 * Author        :
 * Description   : This file contains the code for sending ioctls to
 *                 configure  BME.
 ******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>

#if 0
#include "bmehwapi.h"
#include <dapi_parms.h>
#include <string.h>
#ifndef USE_VXWORKS /* IXDP425 */
#include <v2pthread.h>
#define EOS '\0'
#endif

#include "dapi.h"
#include "apiosmacro.h"
#include "bsp.h"
#endif
// #include "hic2.h"
#ifdef ALASKA
// #include "../../../../../../bmedriver/bmedriver.h"


/* LOCAL DECLARATIONS */
typedef struct read_write_info
{
      unsigned int bme_addr;
      unsigned int bme_offset;
      unsigned char bme_wr_data;
      unsigned int bme_rd_data;
}read_write_info_t;

#define BME_WRITE              0x1
#define BME_READ               0x2
#define BME_RESET              0x3
#define BME_HOLD_CPU           0x4
#define BME_RELEASE_CPU        0x5
#define BME_CLEAR_DMA_STAUS    0x6
#define BME_LED_ON             0x7
#define BME_LED_OFF            0x8
#define BME_LINE_RATE          0x9
int bme_fd;

int writeControlPort(unsigned char *base,unsigned int offset,unsigned char data);
unsigned char  readControlPort(unsigned char *base,unsigned int offset,unsigned char *data);

unsigned char send_bme_linerates(unsigned int up_rate,unsigned int down_rate);
int set_vdsl_link(int);
void vdslLED(char flag);
int vdsl_link_up(void);
int vdsl_link_down(void);

#define SHMSZ  sizeof(int)

/* EXTERN DECLARATIONS */
extern char vdslLinkStatus;
extern int autoStart;

int bme_device_open()
{
     if ((bme_fd = open("/dev/bme", O_RDWR)) < 0)
     {
        printf("bme_device_open() : Failed to open /dev/bme\n");
        return -1;
     }
     return 0;
}
void delay( int val)
{
     int i;
     for(i=0;i<val;i++);
     return;
}

int writeControlPort(unsigned char *base,unsigned int offset,unsigned char data)
{
     int ret_val=-1;
     read_write_info_t wr_data;


     wr_data.bme_addr = (unsigned int *)base;
     wr_data.bme_offset = offset;
     wr_data.bme_wr_data = data;

     ret_val = ioctl(bme_fd, BME_WRITE, &wr_data);
     if (ret_val == -1)
     {
        printf("writeControlPort() :ioctl Failed \n");
        return -1;
     }
     return 0;

}
unsigned char  readControlPort(unsigned char *base,unsigned int offset,unsigned char *data)
{
     int ret_val=-1;
     unsigned char read_data;
     read_write_info_t rd_data;

     rd_data.bme_addr = (unsigned int *)base;
     rd_data.bme_offset = offset;
     ret_val = ioctl(bme_fd, BME_READ, &rd_data);
     if (ret_val == -1)
     {
        printf("readControlPort() :ioctl Failed \n");
        return -1;
     }

     read_data = *((unsigned char *)&(rd_data.bme_rd_data));
     *data = *((unsigned char *)&rd_data.bme_rd_data);
     return read_data;

}
unsigned char  send_bme_linerates(unsigned int up_rate,unsigned int down_rate)
{
     int ret_val=-1;
     read_write_info_t rd_data;

     rd_data.bme_addr = up_rate;
     rd_data.bme_offset = down_rate;
     ret_val = ioctl(bme_fd, BME_LINE_RATE, &rd_data);
     if (ret_val == -1)
     {
        printf("send_bme_linerates() :ioctl Failed \n");
        return -1;
     }

     return 0;

}
void fusiv_bmeHWRest()
{
     int ret_val=-1;

     ret_val = ioctl(bme_fd, BME_RESET, 0);
     if (ret_val == -1)
     {
        printf("bmeHWReset() :ioctl Failed \n");
        return ;
     }
#ifdef DEBUG
     printf ("\nBME Reset done successfully!");
#endif
     return;
}
void fusiv_relBmeCpu(unsigned char enable)
{
     int ret_val=-1;

     if(!enable)
     {
        ret_val = ioctl(bme_fd, BME_HOLD_CPU, 0);
        if (ret_val == -1)
        {
           printf("relBmeCpu() :ioctl Failed \n");
           return ;
        }
#ifdef DEBUG
        printf ("\nBME hold done successfully!");
#endif
     }
     else
     {
        ret_val = ioctl(bme_fd, BME_RELEASE_CPU, 0);
        if (ret_val == -1)
        {
           printf("relBmeCpu() :ioctl Failed \n");
           return ;
        }
#ifdef DEBUG
        printf ("\nBME release done successfully!");
#endif
     }
     return ;
}
void clearDmaStatus()
{
    int ret_val =-1;

    ret_val = ioctl(bme_fd, BME_CLEAR_DMA_STAUS, 0);
    if (ret_val == -1)
    {
           printf("clearDmaStatus() :ioctl Failed \n");
           return ;
     }
     return ;
}
void vdslLED(char flag)
{
    int ret_val =-1;
    
    if(flag)
    {
       ret_val = ioctl(bme_fd, BME_LED_ON, 0);
       if (ret_val == -1)
       {
           printf("LED ON() :ioctl Failed \n");
           return ;
       }
       return ;
    }
    ret_val = ioctl(bme_fd, BME_LED_OFF, 0);
    if (ret_val == -1)
    {
         printf("LED OFF() :ioctl Failed \n");
         return ;
    }
    return ;
}

int vdsl_link_up()
{
    printf("\r\n VDSL Link Established \n");
    fflush(stdout);
    vdslLinkStatus =1;
    autoStart = 1;
    system("ifconfig eth1 up");
    set_vdsl_link(1); //for ppprestore
    vdslLED(1);
    return 0;
}

int vdsl_link_down()
{
    printf("\r\n VDSL Link FAILED\n");
    fflush(stdout);
    vdslLinkStatus =0;
//    autoStart = 0;
    system("ifconfig eth1 down");
    set_vdsl_link(0); //for ppprestore
    vdslLED(0);
    return 0;
}
int set_vdsl_link(int link_status)
{
   int shmid;
   key_t shmkey;
   int *shm;

   shmkey = 5678;

   /* Create a segment */
   if ( (shmid = shmget(shmkey, SHMSZ, IPC_CREAT | 0666) ) < 0)
   {
	perror("set_vdsl_link");
	return -1;
   }

   /* Attach the segment to our data space */

   if ((shm = shmat(shmid, 0, 0)) == -1)
   {
	perror("set_vdsl_link");
	return -1;
   }

   /* time to update the flag */

   *shm = link_status;
   return 0;
}
#endif // ALASKA
