Changeset 9120

Show
Ignore:
Timestamp:
08/01/08 01:57:03
Author:
eb
Message:

work-in-progress on transmit

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • usrp2/branches/developers/eb/merge-wip/host-ng/lib/eth_buffer.cc

    r9115 r9120  
    247247  } 
    248248 
     249  eth_buffer::result 
     250  eth_buffer::tx_framev(const eth_iovec *iov, int iovcnt, int flags) 
     251  { 
     252    DEBUG_LOG("T"); 
     253 
     254    if (flags & EF_DONTWAIT)    // FIXME: implement flags 
     255      throw std::runtime_error("tx_frame: EF_DONTWAIT not implemented"); 
     256 
     257    int res = d_ethernet->write_packetv(iov, iovcnt); 
     258    if (res < 0) 
     259      return EB_ERROR; 
     260 
     261    return EB_OK; 
     262  } 
     263 
    249264  void 
    250265  eth_buffer::release_frame(void *base) 
  • usrp2/branches/developers/eb/merge-wip/host-ng/lib/eth_buffer.h

    r9115 r9120  
    2323 
    2424#include "pktfilter.h" 
    25 #include "eth_common.h" 
     25#include <eth_common.h> 
    2626#include <boost/utility.hpp> 
    2727#include <vector> 
  • usrp2/branches/developers/eb/merge-wip/host-ng/lib/ethernet.cc

    r8591 r9120  
    183183    return retval; 
    184184  } 
     185 
     186  int 
     187  ethernet::write_packetv(const eth_iovec *iov, size_t iovlen) 
     188  { 
     189    struct msghdr mh; 
     190    memset(&mh, 0, sizeof(mh)); 
     191    mh.msg_iov = const_cast<eth_iovec*>(iov); 
     192    mh.msg_iovlen = iovlen; 
     193 
     194    int retval = sendmsg(d_fd, &mh, 0); 
     195    if (retval < 0){ 
     196      if (errno == EINTR) 
     197        return write_packetv(iov, iovlen); 
     198       
     199      perror("ethernet:write_packetv: send"); 
     200      return -1; 
     201    } 
     202    return retval; 
     203  } 
    185204   
    186205  bool 
  • usrp2/branches/developers/eb/merge-wip/host-ng/lib/ethernet.h

    r8591 r9120  
    2222#include <string> 
    2323#include <vector> 
     24#include <eth_common.h> 
    2425 
    2526namespace usrp2 { 
     
    104105     */ 
    105106    int write_packet (const void *buf, int buflen); 
     107 
     108    /* 
     109     * \brief Write ethernet packet to interface. 
     110     * 
     111     * \param iov       scatter/gather array 
     112     * \param iovlen    number of elements in iov 
     113     * 
     114     * \returns number of bytes written or -1 if trouble. 
     115     * 
     116     * Packet must begin with 14-byte ethhdr, but does not include the FCS. 
     117     */ 
     118    int write_packetv (const eth_iovec *iov, size_t iovlen); 
     119 
    106120  }; 
    107121   
  • usrp2/branches/developers/eb/merge-wip/host-ng/lib/usrp2_impl.cc

    r9118 r9120  
    2323#include <usrp2/usrp2.h> 
    2424#include <usrp2/tune_result.h> 
     25#include <usrp2/copiers.h> 
    2526#include <gruel/inet.h> 
    2627#include <usrp2_types.h> 
     
    743744  } 
    744745 
    745  
    746  
    747746  bool 
    748747  usrp2::impl::tx_complex_float(unsigned int channel, 
     
    751750                                const tx_metadata *metadata) 
    752751  { 
    753     throw std::runtime_error("not implemented"); 
     752    uint32_t items[nsamples]; 
     753    copy_host_complex_float_to_u2_complex_16(nsamples, samples, items); 
     754    return tx_raw(channel, items, nsamples, metadata); 
    754755  } 
    755756 
     
    760761                                const tx_metadata *metadata) 
    761762  { 
    762     throw std::runtime_error("not implemented"); 
     763#ifdef WORDS_BIGENDIAN 
     764 
     765    // Already binary equivalent to 16-bit I/Q on the wire. 
     766    // No conversion required. 
     767 
     768    assert(sizeof(samples[0]) == sizeof(uint32_t)); 
     769    return tx_raw(channel, (const uint32_t *) samples, nsamples, metadata); 
     770 
     771#else 
     772 
     773    uint32_t items[nsamples]; 
     774    copy_host_complex_16_to_u2_complex_16(nsamples, samples, items); 
     775    return tx_raw(channel, items, nsamples, metadata); 
     776 
     777#endif 
    763778  } 
    764779 
     
    769784                      const tx_metadata *metadata) 
    770785  { 
    771     throw std::runtime_error("not implemented"); 
    772   } 
     786    if (nitems == 0) 
     787      return true; 
     788 
     789    // FIXME there's the possibility that we send fewer than 9 items in a frame. 
     790    // That would end up glitching the transmitter, since the ethernet will pad to 
     791    // 64-bytes total (9 items).  We really need some part of the stack to 
     792    // carry the real length (thdr?). 
     793 
     794    // fragment as necessary then fire away 
     795 
     796    size_t nframes = (nitems + U2_MAX_SAMPLES - 1) / U2_MAX_SAMPLES; 
     797    size_t last_frame = nframes - 1; 
     798    u2_eth_packet_t     hdrs; 
     799 
     800    size_t n = 0; 
     801    for (size_t fn = 0; fn < nframes; fn++){ 
     802      uint32_t timestamp = 0; 
     803      uint32_t flags = 0; 
     804 
     805      if (fn == 0){ 
     806        timestamp = metadata->timestamp; 
     807        if (metadata->send_now) 
     808          flags |= U2P_TX_IMMEDIATE; 
     809        if (metadata->start_of_burst) 
     810          flags |= U2P_TX_START_OF_BURST; 
     811      } 
     812      if (fn > 0){ 
     813        flags |= U2P_TX_IMMEDIATE; 
     814      } 
     815      if (fn == last_frame){ 
     816        if (metadata->end_of_burst) 
     817          flags |= U2P_TX_END_OF_BURST; 
     818      } 
     819 
     820      init_etf_hdrs(&hdrs, d_addr, flags, channel, timestamp); 
     821 
     822      size_t i = std::min((size_t) U2_MAX_SAMPLES, nitems - n); 
     823 
     824      eth_iovec iov[2]; 
     825      iov[0].iov_base = &hdrs; 
     826      iov[0].iov_len = sizeof(hdrs); 
     827      iov[1].iov_base = const_cast<uint32_t *>(&items[n]); 
     828      iov[1].iov_len = i * sizeof(uint32_t); 
     829 
     830      if (d_eth_buf->tx_framev(iov, 2) != eth_buffer::EB_OK){ 
     831        return false; 
     832      } 
     833 
     834      n += i; 
     835    } 
     836 
     837    return true; 
     838  } 
     839 
    773840 
    774841} // namespace usrp2