view src/g23m-fad/tcpip/rnet/rnet_rt/rnet_rt_atp.c @ 76:a2052ac75672

l1_small_asm.S: import from Citrine
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 20 Jul 2018 05:56:58 +0000
parents d393cd9bb723
children
line wrap: on
line source

/**
 * @file    rnet_rt_atp.c
 *
 * Coding of the ATP point-to-point network interface for RNET_RT,
 *
 * @author  Regis Feneon
 * @version 0.1
 */

/*
 * $Id: rnet_rt_atp.c,v 1.4 2002/12/05 10:02:19 rf Exp $
 * $Name:  $
 *
 * History:
 *
 *  Date        Author        Modification
 *  --------------------------------------------------
 *  5/6/2002    Regis Feneon  Create
 *  6/9/2002    Regis Feneon  Select default route
 *    on local interface address if no destination address
 * 12/5/2002    Regis Feneon  Flow control handling
 * (C) Copyright 2002 by TI, All Rights Reserved
 *
 */

#include "rnet_cfg.h"
#ifdef RNET_CFG_REAL_TRANSPORT

#include "rnet_rt_i.h"
#include "rnet_trace_i.h"
#include "rnet_rt_atp_i.h"
#include "atp_api.h"
#include "atp_messages.h"
#include "rnet_atp_info.h"

static int atpOpen( NGifnet *netp)
{
  T_ATP_RET ret;
  T_ATP_CALLBACK return_path;
  T_ATP_ENTITY_MODE mode = { CMD_SUPPORT_OFF, TXT_MODE, COPY_ON };

  /* interface already running ? */
  if( netp->if_flags & NG_IFF_RUNNING) {
    RNET_RT_SEND_TRACE("RNET_RT: WINNET_open: already running",RV_TRACE_LEVEL_ERROR);
    return( NG_EALREADY);
  }

  /* register to ATP */
  return_path.addr_id = rnet_rt_env_ctrl_blk_p->addr_id;
  return_path.callback_func = NULL;

  ret = atp_reg( (UINT8*) "RNET_RT",
                 return_path,
                 mode,
                 &((T_RNET_RT_ATP_IFNET *) netp)->atp_sw_id);
  if( ret != RV_OK) {
    return( NG_ENODEV);
  }
  /* set a local port... */
  ((T_RNET_RT_ATP_IFNET *) netp)->atp_port_nb = 1;

  netp->if_flags |= NG_IFF_RUNNING;

  /* use NG_IFF_OACTIVE flag for flow control */
  netp->if_flags &= ~NG_IFF_OACTIVE;

  return( NG_EOK);
}

static int atpClose( NGifnet *netp)
{
  /* interface should be running to be closed */
  if( !(netp->if_flags & NG_IFF_RUNNING)) {
    return( NG_EALREADY);
  }
  /* clear flags */
  netp->if_flags &= ~NG_IFF_RUNNING;

  /* deregister to ATP */
  atp_dereg( ((T_RNET_RT_ATP_IFNET *) netp)->atp_sw_id);

  return( NG_EOK);
}

static int atpOutput( NGifnet *netp, NGbuf *bufp, NGuint addr)
{
  UINT32 wlen;
  int err;

//    RNET_RT_SEND_TRACE("RNET_RT: In atpOutput",RV_TRACE_LEVEL_ERROR);

  /* point-to-point interfaces dont use destination address */
  ((void)addr);

  /* Interface must be up and running */
  if ( (netp->if_flags & (NG_IFF_RUNNING|NG_IFF_UP)) !=
    (NG_IFF_RUNNING|NG_IFF_UP)) {
    err = NG_ENETDOWN;
  }
  else {
    /* send IP packet to ATP if output is on... */
    /* ...else discard the packet */
    if( !(netp->if_flags & NG_IFF_OACTIVE)) {
      atp_send_data( ((T_RNET_RT_ATP_IFNET *) netp)->atp_sw_id,
                     ((T_RNET_RT_ATP_IFNET *) netp)->atp_port_nb,
                     bufp->buf_datap,
                     bufp->buf_datalen,
                     &wlen);
    }
    err = NG_EOK;
  }
  /* release buffer */
  ngBufOutputFree( bufp);
  return( err);
}

static int atpCntl( NGifnet *netp, int cmd, int opt, void *arg)
{
  int ret;
  NGbuf *bufp;
  UINT32 rlen, left;
  UINT8 tmpbuf[16];
  T_RNET_RT_ATP_CUSTOM_INFO *cinfo;
  T_ATP_NO_COPY_INFO no_copy_info = { 0 }; /* not used */
  static const T_ATP_PORT_INFO info = {
    DATA_CONFIG,
    ATP_NO_RING_TYPE,
//  old version received from NexGen and modified 5/Dec/2002 : 0,
    ATP_RX_FLOW_UNMASK | ATP_TX_FLOW_UNMASK,
    0
  };

//    RNET_RT_SEND_TRACE("RNET_RT: in atpCntl",RV_TRACE_LEVEL_ERROR);

  if( opt == NG_RNETIFO_HANDLE_MSG) {
    /* handle ATP messages */
    switch( ((T_RV_HDR *)arg)->msg_id) {
    case ATP_OPEN_PORT_IND:

    RNET_RT_SEND_TRACE("RNET_RT: receive OPEN_PORT_IND",RV_TRACE_LEVEL_ERROR);
      cinfo = (T_RNET_RT_ATP_CUSTOM_INFO *)
        ((T_ATP_OPEN_PORT_IND *) arg)->custom_info_p;
      /* if interface is already up, or if no associated data,
         open is not accepted */
      if( ((netp->if_flags & (NG_IFF_UP|NG_IFF_RUNNING)) != NG_IFF_RUNNING) ||
          (cinfo == NULL)) {

        atp_open_port_rsp( ((T_ATP_OPEN_PORT_IND *) arg)->initiator_id,
                           ((T_ATP_OPEN_PORT_IND *) arg)->initiator_port_nb,
                           ((T_RNET_RT_ATP_IFNET *) netp)->atp_sw_id,
                           ((T_RNET_RT_ATP_IFNET *) netp)->atp_port_nb,
                           info,
                           no_copy_info,
                           NULL,
                           OPEN_PORT_NOK);
      }
      else {

        /* send confirmation to ATP client */
        ((T_RNET_RT_ATP_IFNET *) netp)->atp_client_sw_id =
          ((T_ATP_OPEN_PORT_IND *) arg)->initiator_id;
        ((T_RNET_RT_ATP_IFNET *) netp)->atp_client_port_nb =
          ((T_ATP_OPEN_PORT_IND *) arg)->initiator_port_nb;

    no_copy_info.packet_mode = NORMAL_PACKET; /* No L2CAP packet... */
    no_copy_info.rx_mb = no_copy_info.tx_mb = RVF_INVALID_MB_ID;

        ret = atp_open_port_rsp( ((T_ATP_OPEN_PORT_IND *) arg)->initiator_id,
                                 ((T_ATP_OPEN_PORT_IND *) arg)->initiator_port_nb,
                                 ((T_RNET_RT_ATP_IFNET *) netp)->atp_sw_id,
                                 ((T_RNET_RT_ATP_IFNET *) netp)->atp_port_nb,
                                 info,
                                 no_copy_info,
                                 NULL,
                                 OPEN_PORT_OK);
        if( ret == RV_OK) {

          /* interface is ready to send and receive packets */
          netp->if_flags |= NG_IFF_UP;
          /* set MTU */
          netp->if_mtu = cinfo->mtu;
          /* Activating the link addresses */
          ngIfGenCntl( netp, NG_CNTL_SET, NG_IFO_ADDR, &cinfo->local_addr);
          ngIfGenCntl( netp, NG_CNTL_SET, NG_IFO_DSTADDR, &cinfo->dest_addr);
          /* set default route */
          if( cinfo->dest_addr == 0) {

            (void)(ngProto_IP.pr_cntl_f( NG_CNTL_SET, NG_IPO_ROUTE_DEFAULT,
              (NGuint *) &cinfo->local_addr));
          }
          else {

           (void)(ngProto_IP.pr_cntl_f( NG_CNTL_SET, NG_IPO_ROUTE_DEFAULT,
             (NGuint *) &cinfo->dest_addr));
          }
          /* set DNS configuration */
          (void)(ngProto_RESOLV.pr_cntl_f( NG_CNTL_SET, NG_RSLVO_SERV1_IPADDR, &cinfo->dns1));
          (void)(ngProto_RESOLV.pr_cntl_f( NG_CNTL_SET, NG_RSLVO_SERV2_IPADDR, &cinfo->dns2));
        }
      }
      /* release custom information buffer */
      if( cinfo != NULL) {
        atp_free_buffer( cinfo);
      }

      break;
    case ATP_PORT_CLOSED:
    RNET_RT_SEND_TRACE("RNET_RT: receive PORT_CLOSED",RV_TRACE_LEVEL_ERROR);
      if( (netp->if_flags & (NG_IFF_RUNNING|NG_IFF_UP)) !=
        (NG_IFF_RUNNING|NG_IFF_UP)) {
        /* interface already down */
        break;
      }
      /* set interface down */
      netp->if_flags &= ~NG_IFF_UP;
      /* call ip layer */
      (void)(ngProto_IP.pr_cntl_f( NG_CNTL_SET, NG_IPO_NETDOWN, netp));
      break;
    case ATP_DATA_RDY:
      /* allocate buffer for receiving new packet */
    RNET_RT_SEND_TRACE("RNET_RT: receive DATA_RDY",RV_TRACE_LEVEL_ERROR);
      ngBufAlloc( bufp);
      if( bufp != NULL) {
        /* get new data */
        bufp->buf_flags |= NG_PROTO_IP;
        bufp->buf_datap = ((NGubyte *) bufp) + ngBufDataOffset;
        ret = atp_get_data( ((T_RNET_RT_ATP_IFNET *) netp)->atp_sw_id,
                            ((T_RNET_RT_ATP_IFNET *) netp)->atp_port_nb,
                            (UINT8 *) bufp->buf_datap,
                            ngBufDataMax,
                            &rlen,
                            &left);
        if( (ret != RV_OK) || (rlen == 0)) {
          netp->if_ierrors++;
          ngBufFree( bufp);
        }
      else {
//  rnet_debug[0] = '\0' ;
//  for(rnet_ind=0;rnet_ind<48;rnet_ind++) {
//    char tmp[3] ;
//    sprintf(tmp, "%.2x", bufp->buf_datap[rnet_ind]);
//    strcat(rnet_debug, tmp) ;
//  }

//    RNET_RT_SEND_TRACE("RNET_RT: receive content",RV_TRACE_LEVEL_ERROR);
//    RNET_RT_SEND_TRACE(rnet_debug, RV_TRACE_LEVEL_ERROR);
//  rvf_delay(RVF_MS_TO_TICKS(100));

          /* get length of packet */
          bufp->buf_datalen = rlen;
          /* start IP processing */
          ngIfGenInput( netp, bufp, 1);
        }
      }
      else {
        /* skip packet */
        netp->if_ierrors++;
        atp_get_data( ((T_RNET_RT_ATP_IFNET *) netp)->atp_sw_id,
                      ((T_RNET_RT_ATP_IFNET *) netp)->atp_port_nb,
                      tmpbuf,
                      sizeof( tmpbuf),
                      &rlen,
                      &left);
      }
      break;
    case ATP_SIGNAL_CHANGED:
      /* handle flow control flags */
    RNET_RT_SEND_TRACE("RNET_RT: receive SIGNAL_CHANGED",RV_TRACE_LEVEL_ERROR);
//  rvf_delay(RVF_MS_TO_TICKS(1000));
      if( ((T_ATP_SIGNAL_CHANGED *) arg)->mask & ATP_TX_FLOW_UNMASK) {
        if( ((T_ATP_SIGNAL_CHANGED *) arg)->signal & ATP_TX_FLOW_ON) {
          /* enable transimissions */
          netp->if_flags &= ~NG_IFF_OACTIVE;
        }
        else {
          /* disable transmissions */
          netp->if_flags |= NG_IFF_OACTIVE;
        }
      }
      break;
    default:
      /* unknown message */
  RNET_TRACE_MEDIUM_PARAM("RNET_RT: receive default ",((T_RV_HDR *)arg)->msg_id);

      return( NG_EINVAL);
    }
    return( NG_EOK);
  }
  else {
    RNET_RT_SEND_TRACE("RNET_RT: opt not handle msg", RV_TRACE_LEVEL_ERROR);
    return( ngIfGenCntl( netp, cmd, opt, arg));
  }
}

/********************************************************************/
/* Driver entry point */

const NGnetdrv rnet_rt_netdrv_atp = {
  "ATP",
  NG_IFT_PPP,
  NG_IFF_POINTOPOINT|NG_IFF_MULTICAST,
  RNET_RT_ATP_MTU,
  0,
  NULL,
  atpOpen,
  atpClose,
  atpOutput,
  NULL,
  atpCntl
};

#endif /* ifdef RNET_CFG_REAL_TRANSPORT */