Beispiel #1
0
static void dwmac_desc_enh_release_tx_bufs( dwmac_common_context *self )
{
  volatile dwmac_desc_ext *p_enh     = (volatile dwmac_desc_ext *) self->dma_tx;
  const size_t             NUM_DESCS = (size_t) self->bsd_config->xbuf_count;
  unsigned int             i;


  assert( p_enh != NULL );

  for ( i = 0; i < NUM_DESCS; ++i ) {
    if ( p_enh[i].etx.des0_3.des1 != 0 ) {
      struct mbuf *dummy;

      assert( self->mbuf_addr_tx[i] != NULL );

      MFREE( self->mbuf_addr_tx[i], dummy );
      (void) dummy;
      memset( __DEVOLATILE( void *,
                            &p_enh[i].etx ), 0, sizeof( dwmac_desc_ext ) );
    }
  }

  self->dma_tx = (volatile dwmac_desc *) p_enh;
  DWMAC_COMMON_DSB();
}
Beispiel #2
0
static void dwmac_desc_enh_release_tx_ownership(
  dwmac_common_context *self,
  const unsigned int    idx_tx )
{
  volatile dwmac_desc_ext *p_enh = (volatile dwmac_desc_ext *) self->dma_tx;


  DWMAC_COMMON_DSB();
  p_enh[idx_tx].erx.des0_3.des0 |= DWMAC_DESC_ETX_DES0_OWN_BIT;
}
Beispiel #3
0
static int dwmac_desc_enh_create_rx_desc( dwmac_common_context *self )
{
  int          eno        = 0;
  const size_t NUM_DESCS  = (size_t) self->bsd_config->rbuf_count;
  const size_t SIZE_DESCS = NUM_DESCS * sizeof( dwmac_desc_ext );
  void        *desc_mem   = NULL;


  assert( NULL == self->dma_rx );

  /* Allocate an array of mbuf pointers */
  self->mbuf_addr_rx = calloc( NUM_DESCS, sizeof( struct mbuf * ) );

  if ( self->mbuf_addr_rx == NULL ) {
    eno = ENOMEM;
  }

  /* Allocate an array of dma descriptors */
  if ( eno == 0 ) {
    eno = ( self->CFG->CALLBACK.mem_alloc_nocache )(
      self->arg,
      &desc_mem,
      SIZE_DESCS
      );
  }

  if ( eno == 0 ) {
    if ( desc_mem != NULL ) {
      memset( desc_mem, 0, SIZE_DESCS );
      DWMAC_COMMON_DSB();
    } else {
      eno = ENOMEM;
    }
  }

  if ( eno == 0 ) {
    self->dma_rx = (volatile dwmac_desc *) desc_mem;
    DWMAC_COMMON_DSB();
  }

  return eno;
}
Beispiel #4
0
static int dwmac_desc_enh_create_tx_desc( dwmac_common_context *self )
{
  int          eno        = 0;
  void        *mem_desc   = NULL;
  const size_t NUM_DESCS  = (size_t) self->bsd_config->xbuf_count;
  const size_t SIZE_DESCS = NUM_DESCS * sizeof( dwmac_desc_ext );


  assert( self->dma_tx == NULL );

  /* Allocate an array of mbuf pointers */
  self->mbuf_addr_tx = calloc( NUM_DESCS, sizeof( struct mbuf * ) );

  if ( self->mbuf_addr_tx == NULL ) {
    eno = ENOMEM;
  }

  if ( eno == 0 ) {
    eno = ( self->CFG->CALLBACK.mem_alloc_nocache )(
      self->arg,
      &mem_desc,
      SIZE_DESCS
      );
  }

  if ( eno == 0 ) {
    if ( mem_desc != NULL ) {
      memset( mem_desc, 0, SIZE_DESCS );
      DWMAC_COMMON_DSB();
    } else {
      eno = ENOMEM;
    }
  }

  if ( eno == 0 ) {
    self->dma_tx = mem_desc;
    DWMAC_COMMON_DSB();
  }

  return eno;
}
Beispiel #5
0
static void dwmac_desc_enh_init_rx_desc(
  dwmac_common_context *self,
  const unsigned int    index )
{
  volatile dwmac_desc_ext *p_enh       =
    (volatile dwmac_desc_ext *) self->dma_rx;
  const size_t             NUM_DESCS   = (size_t) self->bsd_config->rbuf_count;
  char                    *clust_start =
    mtod( self->mbuf_addr_rx[index], char * );


  assert( NULL != p_enh );

  DWMAC_COMMON_DSB();

  rtems_cache_invalidate_multiple_data_lines(
    clust_start,
    DWMAC_DESC_COM_BUF_SIZE + ETHER_ALIGN
    );

  if ( self->mbuf_addr_rx[index] != NULL ) {
    p_enh[index].erx.des0_3.des1 = DWMAC_DESC_ERX_DES1_RECEIVE_BUFF_1_SIZE_SET(
      p_enh->erx.des0_3.des1,
      DWMAC_DESC_COM_BUF_SIZE );
  } else {
    p_enh[index].erx.des0_3.des1 = DWMAC_DESC_ERX_DES1_RECEIVE_BUFF_1_SIZE_SET(
      p_enh->erx.des0_3.des1,
      0 );
  }

  p_enh[index].erx.des0_3.des2 = (uint32_t) clust_start;

  /* The network controller supports adding a second data buffer to
   * p_enh->erx.des0_3.des3. For simplicity reasons we will not do this */
  dwmac_desc_enh_rx_set_on_ring_chain( &p_enh[index],
                                       ( index == NUM_DESCS - 1 ) );
  DWMAC_COMMON_DSB();
  p_enh[index].erx.des0_3.des0 = DWMAC_DESC_ERX_DES0_OWN_BIT;
}
Beispiel #6
0
static bool dwmac_desc_enh_am_i_tx_owner(
  dwmac_common_context *self,
  const unsigned int    idx_tx )
{
  volatile dwmac_desc_ext *p_enh = (volatile dwmac_desc_ext *) self->dma_tx;
  bool                     am_i_owner;


  DWMAC_COMMON_DSB();
  am_i_owner =
    ( p_enh[idx_tx].etx.des0_3.des0 & DWMAC_DESC_ETX_DES0_OWN_BIT ) == 0;

  return am_i_owner;
}
Beispiel #7
0
static void dwmac_desc_enh_init_tx_desc( dwmac_common_context *self )
{
  volatile dwmac_desc_ext *p_enh     = (volatile dwmac_desc_ext *) self->dma_tx;
  const size_t             NUM_DESCS = (size_t) self->bsd_config->xbuf_count;
  unsigned int             i;


  assert( p_enh != NULL );

  for ( i = 0; i < NUM_DESCS; ++i ) {
    dwmac_desc_enh_tx_set_on_ring_chain( &p_enh[i], ( i == NUM_DESCS - 1 ) );
  }

  self->dma_tx = (volatile dwmac_desc *) &p_enh[0];
  DWMAC_COMMON_DSB();
}
Beispiel #8
0
static int dwmac_desc_enh_destroy_rx_desc( dwmac_common_context *self )
{
  int                  eno    = 0;
  volatile dwmac_desc *dma_rx = self->dma_rx;


  if ( self->mbuf_addr_rx != NULL ) {
    free( self->mbuf_addr_rx, 0 );
    self->mbuf_addr_rx = NULL;
  }

  if ( dma_rx != NULL ) {
    eno          = self->CFG->CALLBACK.mem_free_nocache( self->arg, dma_rx );
    self->dma_rx = NULL;
  }

  DWMAC_COMMON_DSB();

  return eno;
}
Beispiel #9
0
static int dwmac_desc_enh_destroy_tx_desc( dwmac_common_context *self )
{
  int   eno      = 0;
  void *mem_desc = __DEVOLATILE( void *, self->dma_tx );


  if ( self->mbuf_addr_tx != NULL ) {
    free( self->mbuf_addr_tx, 0 );
    self->mbuf_addr_tx = NULL;
  }

  if ( mem_desc != NULL ) {
    eno          = self->CFG->CALLBACK.mem_free_nocache( self->arg, mem_desc );
    mem_desc     = NULL;
    self->dma_tx = (volatile dwmac_desc *) mem_desc;
  }

  DWMAC_COMMON_DSB();

  return eno;
}