int ethernet_send() {

#if NEW_LOGIC
  if(tx_produce_offset < 0) { // no buffer active
    return -1;
  }

  // ensure there is a link
  if(!ethernet_link()) {
    return -2;
  }

  // we have been writing in to a buffer, so finalise it
  int size = tx_produce_offset;
  int index = LPC_EMAC->TxProduceIndex;
  txdesc[index].Ctrl = (tx_produce_offset-1) | (TCTRL_INT | TCTRL_LAST);

  // Increment ProduceIndex to allow it to be sent
  // We can only do this if the next slot is free
  int next = rinc(index, NUM_TX_FRAG);
  while(next == LPC_EMAC->TxConsumeIndex) {
    for(int i=0; i<1000; i++) { __NOP(); }
  }

  LPC_EMAC->TxProduceIndex = next;
  tx_produce_offset = -1;
  return size;

#else
    int s = send_size;
    txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT | TCTRL_LAST);
    send_idx  = rinc(send_idx, NUM_TX_FRAG);
    LPC_EMAC->TxProduceIndex = send_idx;
    send_doff =  0;
    send_idx  = -1;
    send_size =  0;
    return s;
#endif
}
Ejemplo n.º 2
0
int ethernet_read(char *data, int dlen) {
#if NEW_LOGIC
  // Check we have a valid buffer to read
  if(rx_consume_offset < 0) {
    return 0;
  }

  // Assume 1 fragment block
  uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info;
  int size = (info & RINFO_SIZE) + 1 - 4; // exclude checksum

  int remaining = size - rx_consume_offset;
  int requested = dlen;
  int ncopy = min(remaining, requested);

  void *psrc = (void *)(rxdesc[LPC_EMAC->RxConsumeIndex].Packet + rx_consume_offset);
  void *pdst = (void *)(data);

  if(data != NULL && ncopy > 0) {
    memcpy(pdst, psrc, ncopy);
  }

  rx_consume_offset += ncopy;

  return ncopy;
#else
    int          slen;
    int          copy   = 0;
    unsigned int more;
    unsigned int info;
    void        *pdst, *psrc;
    int          doff = 0;
    
    if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex || receive_idx == -1) {
        return 0;
    }
    
    do {
        info =   rxstat[receive_idx].Info;
        more = !(info & RINFO_LAST_FLAG);
        slen =  (info & RINFO_SIZE) + 1;
        
        if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) {
            /* Invalid frame, ignore it and free buffer. */
            receive_idx = rinc(receive_idx, NUM_RX_FRAG);
        } else {
            
            copy = min(slen - receive_soff, dlen - doff);
            psrc = (void *)(rxdesc[receive_idx].Packet + receive_soff);
            pdst = (void *)(data + doff);
            
            if(data != NULL) {
                /* check if Buffer available */
                memcpy(pdst, psrc, copy);
            }
            
            receive_soff += copy;
            doff += copy;
            
            if((more && (receive_soff == slen))) {
                receive_idx = rinc(receive_idx, NUM_RX_FRAG);
                receive_soff = 0;
            }
        }
    } while(more && !(doff == dlen) && !receive_soff);
    
    return doff;
#endif
}
Ejemplo n.º 3
0
int ethernet_write(const char *data, int slen) {

#if NEW_LOGIC

   if(tx_produce_offset < 0) { // mark as active if not already
     tx_produce_offset = 0;
   }

   int index = LPC_EMAC->TxProduceIndex;

   int remaining = ETH_MAX_FLEN - tx_produce_offset - 4; // bytes written plus checksum
   int requested = slen;
   int ncopy = min(remaining, requested);

   void *pdst = (void *)(txdesc[index].Packet + tx_produce_offset);
   void *psrc = (void *)(data);

   if(ncopy > 0 ){
     if(data != NULL) {
       memcpy(pdst, psrc, ncopy);
     } else {
       memset(pdst, 0, ncopy);
     }
   }

   tx_produce_offset += ncopy;

   return ncopy;

#else
    void       *pdst, *psrc;
    const int   dlen = ETH_FRAG_SIZE;
    int         copy = 0;
    int         soff = 0;

    if(send_idx == -1) {
        send_idx = LPC_EMAC->TxProduceIndex;
    }

    if(slen + send_doff > ethernet_MTU_SIZE) {
       return -1;
    }

    do {
        copy = min(slen - soff, dlen - send_doff);
        pdst = (void *)(txdesc[send_idx].Packet + send_doff);
        psrc = (void *)(data + soff);
        if(send_doff + copy > ETH_FRAG_SIZE) {
            txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT);
            send_idx = rinc(send_idx, NUM_TX_FRAG);
            send_doff = 0;
        }

        if(data != NULL) {
            memcpy(pdst, psrc, copy);
        } else {
            memset(pdst, 0, copy);
        }

        soff += copy;
        send_doff += copy;
        send_size += copy;
    } while(soff != slen);

    return soff;
#endif
}