Example #1
0
static void loop(struct vi_state* vi_state)
{
  ef_event evs[EF_VI_EVENT_POLL_MIN_EVS];
  ef_vi* vi = &vi_state->vi;
  int i;

  pthread_mutex_lock(&ready_mutex);
  ++ready_cnt;
  pthread_cond_signal(&ready_cond);
  pthread_mutex_unlock(&ready_mutex);

  while( 1 ) {
    int n_ev = ef_eventq_poll(vi, evs, sizeof(evs) / sizeof(evs[0]));
    for( i = 0; i < n_ev; ++i )
      switch( EF_EVENT_TYPE(evs[i]) ) {
      case EF_EVENT_TYPE_RX:
        /* This code does not handle jumbos. */
        assert(EF_EVENT_RX_SOP(evs[i]) != 0);
        assert(EF_EVENT_RX_CONT(evs[i]) == 0);
        handle_rx(vi_state, EF_EVENT_RX_RQ_ID(evs[i]),
                  EF_EVENT_RX_BYTES(evs[i]) - ef_vi_receive_prefix_len(vi));
        break;
      case EF_EVENT_TYPE_RX_DISCARD:
        handle_rx_discard(vi_state, EF_EVENT_RX_DISCARD_RQ_ID(evs[i]),
                          EF_EVENT_RX_DISCARD_TYPE(evs[i]));
        break;
      default:
        LOGE("ERROR: unexpected event %d\n", (int) EF_EVENT_TYPE(evs[i]));
        break;
      }
    vi_refill_rx_ring(vi_state);
  }
}
Example #2
0
/* The main loop.  Poll each VI handling various types of events and
 * then try to refill them. */
static void main_loop(void)
{
  int i, j, k;

  while( 1 ) {
    for( i = 0; i < 2; ++i ) {
      ef_vi* vi = &vis[i].vi;
      ef_event evs[EF_VI_EVENT_POLL_MIN_EVS];
      int n_ev = ef_eventq_poll(vi, evs, sizeof(evs) / sizeof(evs[0]));
      for( j = 0; j < n_ev; ++j ) {
        switch( EF_EVENT_TYPE(evs[j]) ) {
        case EF_EVENT_TYPE_RX:
          /* This code does not handle jumbos. */
          assert(EF_EVENT_RX_SOP(evs[j]) != 0);
          assert(EF_EVENT_RX_CONT(evs[j]) == 0);
          handle_rx(i, EF_EVENT_RX_RQ_ID(evs[j]),
                    EF_EVENT_RX_BYTES(evs[j]) -
                    ef_vi_receive_prefix_len(vi));
          break;
        case EF_EVENT_TYPE_TX: {
          ef_request_id ids[EF_VI_TRANSMIT_BATCH];
          int ntx = ef_vi_transmit_unbundle(vi, &evs[j], ids);
          for( k = 0; k < ntx; ++k )
            complete_tx(i, ids[k]);
          break;
        }
        case EF_EVENT_TYPE_RX_DISCARD:
          handle_rx_discard(EF_EVENT_RX_DISCARD_RQ_ID(evs[j]),
                            EF_EVENT_RX_DISCARD_TYPE(evs[j]));
          break;
        default:
          LOGE("ERROR: unexpected event %d\n", (int) EF_EVENT_TYPE(evs[j]));
          break;
        }
      }
      vi_refill_rx_ring(i);
    }
  }
}
Example #3
0
static void rx_wait(void)
{
  ef_request_id ids[EF_VI_TRANSMIT_BATCH];
  ef_event      evs[EF_VI_EVENT_POLL_MIN_EVS];
  int           n_ev, i;

  while( 1 ) {
    n_ev = ef_eventq_poll(&vi, evs, sizeof(evs) / sizeof(evs[0]));
    if( n_ev > 0 )
      for( i = 0; i < n_ev; ++i )
        switch( EF_EVENT_TYPE(evs[i]) ) {
        case EF_EVENT_TYPE_RX:
          TEST(EF_EVENT_RX_SOP(evs[i]) == 1);
          TEST(EF_EVENT_RX_CONT(evs[i]) == 0);
          TEST((int) (rx_posted - rx_completed) > 0);
          ++rx_completed;
          return;
        case EF_EVENT_TYPE_TX:
          ef_vi_transmit_unbundle(&vi, &evs[i], ids);
          break;
        case EF_EVENT_TYPE_RX_DISCARD:
          fprintf(stderr, "ERROR: RX_DISCARD type=%d\n",
                  EF_EVENT_RX_DISCARD_TYPE(evs[i]));
          break;
        case EF_EVENT_TYPE_TX_ERROR:
          fprintf(stderr, "ERROR: TX_ERROR type=%d\n",
                  EF_EVENT_TX_ERROR_TYPE(evs[i]));
          break;
        default:
          fprintf(stderr, "ERROR: unexpected event "EF_EVENT_FMT"\n",
                  EF_EVENT_PRI_ARG(evs[i]));
          break;
        }
    else if( cfg_wait )
      TRY(ef_eventq_wait(&vi, driver_handle, ef_eventq_current(&vi), 0));
  }
}
Example #4
0
static void rx_wait(void)
{
  ef_request_id ids[EF_VI_TRANSMIT_BATCH];
  ef_event      evs[EF_VI_EVENT_POLL_MIN_EVS];
  int           n_ev, i;

  while( 1 ) {
    n_ev = ef_eventq_poll(&vi, evs, sizeof(evs) / sizeof(evs[0]));
    if( n_ev > 0 ) {
      for( i = 0; i < n_ev; ++i )
        switch( EF_EVENT_TYPE(evs[i]) ) {
        case EF_EVENT_TYPE_RX:
          TEST(EF_EVENT_RX_SOP(evs[i]) == 1);
          TEST(EF_EVENT_RX_CONT(evs[i]) == 0);
          TEST((int) (rx_posted - rx_completed) > 0);
          ++rx_completed;
          return;
        case EF_EVENT_TYPE_TX:
          ef_vi_transmit_unbundle(&vi, &evs[i], ids);
          break;
        case EF_EVENT_TYPE_RX_DISCARD:
          fprintf(stderr, "ERROR: RX_DISCARD type=%d\n",
                  EF_EVENT_RX_DISCARD_TYPE(evs[i]));
          break;
        case EF_EVENT_TYPE_TX_ERROR:
          fprintf(stderr, "ERROR: TX_ERROR type=%d\n",
                  EF_EVENT_TX_ERROR_TYPE(evs[i]));
          break;
        default:
          fprintf(stderr, "ERROR: unexpected event "EF_EVENT_FMT"\n",
                  EF_EVENT_PRI_ARG(evs[i]));
          break;
        }
    }
    else if( cfg_eventq_wait ) {
      TRY(ef_eventq_wait(&vi, driver_handle, ef_eventq_current(&vi), 0));
    }
    else if( cfg_fd_wait ) {
      TRY(ef_vi_prime(&vi, driver_handle, ef_eventq_current(&vi)));
      struct pollfd pollfd = {
        .fd      = driver_handle,
        .events  = POLLIN,
        .revents = 0,
      };
      TRY(poll(&pollfd, 1, -1));
    }
  }
}


static void tx_send(void)
{
  struct pkt_buf* pb = pkt_bufs[FIRST_TX_BUF];
  ef_vi_transmit(&vi, pb->dma_buf_addr, tx_frame_len, 0);
}

/**********************************************************************/

static void pong_test(void)
{
  int i;

  rx_post_8();

  for( i = 0; i < cfg_iter; ++i ) {
    rx_wait();
    tx_send();
    if( i % 8 == 0 )
      rx_post_8();
  }
}