Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top...
[debian/gnuradio] / usrp2 / firmware / include / usrp2_eth_packet.h
diff --git a/usrp2/firmware/include/usrp2_eth_packet.h b/usrp2/firmware/include/usrp2_eth_packet.h
new file mode 100644 (file)
index 0000000..ca13d61
--- /dev/null
@@ -0,0 +1,374 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008 Free Software Foundation, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INCLUDED_USRP2_ETH_PACKET_H
+#define INCLUDED_USRP2_ETH_PACKET_H
+
+#include "usrp2_cdefs.h"
+#include "usrp2_bytesex.h"
+#include "usrp2_mac_addr.h"
+#include "usrp2_mimo_config.h"
+
+__U2_BEGIN_DECLS
+
+#define U2_ETHERTYPE           0xBEEF  // used in our frames
+#define        MAC_CTRL_ETHERTYPE      0x8808  // used in PAUSE frames
+
+/*
+ * All these data structures are BIG-ENDIAN on the wire
+ */
+
+// FIXME gcc specific.  Really ought to come from compiler.h
+#define _AL4   __attribute__((aligned (4)))
+
+/*
+ * \brief The classic 14-byte ethernet header
+ */
+typedef struct {
+  u2_mac_addr_t dst;
+  u2_mac_addr_t src;
+  uint16_t     ethertype;
+} __attribute__((packed)) u2_eth_hdr_t;
+
+/*!
+ * \brief USRP2 transport header
+ *
+ * This enables host->usrp2 flow control and dropped packet detection.
+ */
+typedef struct {
+  uint16_t     flags;          // MBZ, may be used for channel in future
+  uint16_t     fifo_status;    // free space in Rx fifo in 32-bit lines
+  uint8_t      seqno;          // sequence number of this packet
+  uint8_t      ack;            // sequence number of next packet expected
+} __attribute__((packed)) u2_transport_hdr_t;
+
+
+/*
+ * The fixed payload header of a USRP2 ethernet packet...
+ *
+ * Basically there's 1 word of flags and routing info, and 1 word
+ * of timestamp that specifies when the data was received, or
+ * when it should be transmitted. The data samples follow immediately.
+ *
+ * Transmit packets (from host to U2)
+ * 
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |  Chan   |                    mbz                        |I|S|E|
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           Timestamp                           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *
+ * Received packets (from U2 to host)
+ *
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |  Chan   |                    mbz                              |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           Timestamp                           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *  mbz == must be zero
+ */
+
+typedef struct {
+  uint32_t     word0;          // flags etc
+  uint32_t     timestamp;      // time of rx or tx (100 MHz)
+} u2_fixed_hdr_t;
+
+
+#define U2P_CHAN_MASK          0x1f
+#define        U2P_CHAN_SHIFT          27
+
+#define U2P_TX_IMMEDIATE       0x00000004  // send samples NOW, else at timestamp
+#define U2P_TX_START_OF_BURST  0x00000002  // this frame is the start of a burst
+#define        U2P_TX_END_OF_BURST     0x00000001  // this frame is the end of a burst
+
+#define        U2P_ALL_FLAGS           0x00000007
+
+#define        CONTROL_CHAN            0x1f
+
+static inline int
+u2p_chan(u2_fixed_hdr_t *p)
+{
+  return (ntohl(p->word0) >> U2P_CHAN_SHIFT) & U2P_CHAN_MASK;
+}
+
+inline static uint32_t
+u2p_word0(u2_fixed_hdr_t *p)
+{
+  return ntohl(p->word0);
+}
+
+inline static uint32_t
+u2p_timestamp(u2_fixed_hdr_t *p)
+{
+  return ntohl(p->timestamp);
+}
+
+inline static void
+u2p_set_word0(u2_fixed_hdr_t *p, int flags, int chan)
+{
+  p->word0 = htonl((flags & U2P_ALL_FLAGS)
+                  | ((chan & U2P_CHAN_MASK) << U2P_CHAN_SHIFT));
+}
+
+inline static void
+u2p_set_timestamp(u2_fixed_hdr_t *p, uint32_t ts)
+{
+  p->timestamp = htonl(ts);
+}
+
+/*!
+ * \brief consolidated packet: ethernet header + transport header + fixed header
+ */
+typedef struct {
+  u2_eth_hdr_t         ehdr;
+  u2_transport_hdr_t   thdr;
+  u2_fixed_hdr_t       fixed;
+} u2_eth_packet_t;
+
+/*
+ * full load of samples:
+ *   ethernet header + transport header + fixed header + maximum number of samples.
+ *   sizeof(u2_eth_samples_t) == 1512
+ *   (payload is 1498 bytes, two bytes shorter than 1500 byte MTU)
+ */
+
+#define U2_MAX_SAMPLES 371
+
+typedef struct {
+  u2_eth_packet_t      hdrs;
+  uint32_t             samples[U2_MAX_SAMPLES];
+} u2_eth_samples_t;
+
+/*
+ * Opcodes for control channel
+ *
+ * Reply opcodes are the same as the request opcode with the OP_REPLY_BIT set (0x80).
+ */
+#define OP_REPLY_BIT             0x80
+
+#define        OP_EOP                       0  // marks last subpacket in packet
+
+#define OP_ID                       1
+#define        OP_ID_REPLY                  (OP_ID | OP_REPLY_BIT)
+#define        OP_BURN_MAC_ADDR             2
+#define OP_BURN_MAC_ADDR_REPLY      (OP_BURN_MAC_ADDR | OP_REPLY_BIT)
+#define        OP_READ_TIME                 3  // What time is it? (100 MHz counter)
+#define        OP_READ_TIME_REPLY           (OP_READ_TIME | OP_REPLY_BIT)
+#define        OP_CONFIG_RX_V2              4
+#define        OP_CONFIG_RX_REPLY_V2        (OP_CONFIG_RX_V2 | OP_REPLY_BIT)
+#define        OP_CONFIG_TX_V2              5
+#define        OP_CONFIG_TX_REPLY_V2        (OP_CONFIG_TX_V2 | OP_REPLY_BIT)
+#define        OP_START_RX_STREAMING        6
+#define        OP_START_RX_STREAMING_REPLY  (OP_START_RX_STREAMING | OP_REPLY_BIT)
+#define        OP_STOP_RX                   7
+#define        OP_STOP_RX_REPLY             (OP_STOP_RX | OP_REPLY_BIT)
+#define        OP_CONFIG_MIMO               8
+#define OP_CONFIG_MIMO_REPLY        (OP_CONFIG_MIMO | OP_REPLY_BIT)
+
+
+//#define OP_WRITE_REG          xx     // not implemented
+//#define OP_WRITE_REG_MASKED    xx
+//#define OP_READ_REG           xx
+//#define OP_READ_REG_REPLY      xx
+
+/*
+ * All subpackets are a multiple of 4 bytes long.
+ * All subpackets start with an 8-bit opcode, an 8-bit len and an 8-bit rid.
+ */
+
+
+/*!
+ * \brief Generic request and reply packet
+ *
+ * Used by:
+ *  OP_EOP, OP_BURN_MAC_ADDR_REPLY, OP_START_RX_STREAMING_REPLY,
+ *  OP_STOP_RX_REPLY
+ */
+typedef struct {
+  uint8_t      opcode;
+  uint8_t      len;
+  uint8_t      rid;
+  uint8_t      ok;             // bool
+} _AL4 op_generic_t;
+
+/*!
+ * \brief Reply info from a USRP2
+ */
+typedef struct {
+  uint8_t      opcode;
+  uint8_t      len;
+  uint8_t      rid;
+  uint8_t      mbz;
+  u2_mac_addr_t        addr;
+  uint16_t     hw_rev;
+  uint8_t      fpga_md5sum[16];
+  uint8_t      sw_md5sum[16];
+} _AL4 op_id_reply_t;
+
+typedef struct {
+  uint8_t      opcode;
+  uint8_t      len;
+  uint8_t      rid;
+  uint8_t      mbz;
+  uint32_t     items_per_frame;  // # of 32-bit data items; MTU=1500: [9,371]
+} _AL4 op_start_rx_streaming_t;
+
+typedef struct {
+  uint8_t      opcode;
+  uint8_t      len;
+  uint8_t      rid;
+  u2_mac_addr_t        addr;
+} _AL4 op_burn_mac_addr_t;
+
+typedef struct {
+  uint8_t      opcode;
+  uint8_t      len;
+  uint8_t      rid;
+  uint8_t      mbz;
+  uint32_t     time;
+} _AL4 op_read_time_reply_t;
+
+
+/*!
+ * \brief Configure receiver
+ */
+typedef struct {
+  uint8_t      opcode;
+  uint8_t      len;
+  uint8_t      rid;
+  uint8_t      mbz;
+  // bitmask indicating which of the following fields are valid
+  uint16_t     valid;
+  uint16_t     gain;           // fxpt_db (Q9.7)
+  uint32_t     freq_hi;        // high 32-bits of 64-bit fxpt_freq (Q44.20)
+  uint32_t     freq_lo;        // low  32-bits of 64-bit fxpt_freq (Q44.20)
+  uint32_t     decim;          // desired decimation factor (NOT -1)
+  uint32_t     scale_iq;       // (scale_i << 16) | scale_q [16.0 format]
+} _AL4 op_config_rx_v2_t;
+
+// bitmask for "valid" field.  If the bit is set, there's
+// meaningful data in the corresonding field.
+
+#define        CFGV_GAIN               0x0001  // gain field is valid
+#define        CFGV_FREQ               0x0002  // target_freq field is valid
+#define        CFGV_INTERP_DECIM       0x0004  // interp or decim is valid
+#define        CFGV_SCALE_IQ           0x0008  // scale_iq is valid
+
+/*!
+ * \brief Reply to receiver configuration
+ */
+typedef struct {
+  uint8_t      opcode;
+  uint8_t      len;
+  uint8_t      rid;
+  uint8_t      mbz;
+
+  uint16_t     ok;             // config was successful (bool)
+  uint16_t     inverted;       // spectrum is inverted (bool)
+
+  // RF frequency that corresponds to DC in the IF (fxpt_freq)
+  uint32_t     baseband_freq_hi;
+  uint32_t     baseband_freq_lo;
+  // DDC frequency (fxpt_freq)
+  uint32_t     ddc_freq_hi;
+  uint32_t     ddc_freq_lo;
+  // residual frequency (fxpt_freq)
+  uint32_t     residual_freq_hi;
+  uint32_t     residual_freq_lo;
+
+} _AL4 op_config_rx_reply_v2_t;
+
+/*!
+ *  \brief Configure transmitter
+ */
+typedef struct {
+  uint8_t      opcode;
+  uint8_t      len;
+  uint8_t      rid;
+  uint8_t      mbz;
+
+  // bitmask indicating which of the following fields are valid
+  uint16_t     valid;
+  uint16_t     gain;           // fxpt_db (Q9.7)
+  uint32_t     freq_hi;        // high 32-bits of 64-bit fxpt_freq (Q44.20)
+  uint32_t     freq_lo;        // low  32-bits of 64-bit fxpt_freq (Q44.20)
+  uint32_t     interp;         // desired interpolation factor (NOT -1)
+  uint32_t     scale_iq;       // (scale_i << 16) | scale_q [16.0 format]
+} _AL4 op_config_tx_v2_t;
+
+/*!
+ * \brief Reply to configure transmitter
+ */
+typedef struct {
+  uint8_t      opcode;
+  uint8_t      len;
+  uint8_t      rid;
+  uint8_t      mbz;
+
+  uint16_t     ok;             // config was successful (bool)
+  uint16_t     inverted;       // spectrum is inverted (bool)
+
+  // RF frequency that corresponds to DC in the IF (fxpt_freq)
+  uint32_t     baseband_freq_hi;
+  uint32_t     baseband_freq_lo;
+  // DUC frequency (fxpt_freq)
+  uint32_t     duc_freq_hi;
+  uint32_t     duc_freq_lo;
+  // residual frequency (fxpt_freq)
+  uint32_t     residual_freq_hi;
+  uint32_t     residual_freq_lo;
+
+} _AL4 op_config_tx_reply_v2_t;
+
+/*!
+ * \brief Configure MIMO clocking, etc (uses generic reply)
+ */
+typedef struct {
+  uint8_t      opcode;
+  uint8_t      len;
+  uint8_t      rid;
+  uint8_t      flags;  // from usrp_mimo_config.h
+} op_config_mimo_t;
+
+
+/*
+ * ================================================================
+ *             union of all of subpacket types
+ * ================================================================
+ */
+typedef union {
+
+  op_generic_t                 op_generic;
+  op_id_reply_t                        op_id_reply;
+  op_start_rx_streaming_t      op_start_rx_streaming;
+  op_burn_mac_addr_t           op_burn_mac_addr;
+  op_read_time_reply_t         op_read_time_reply;
+  op_config_rx_v2_t            op_config_rx_v2;
+  op_config_rx_reply_v2_t      op_config_rx_reply_v2;
+  op_config_tx_v2_t            op_config_tx_v2;
+  op_config_tx_reply_v2_t      op_config_tx_reply_v2;
+  op_config_mimo_t             op_config_mimo;
+
+} u2_subpkt_t;
+
+
+__U2_END_DECLS
+
+#endif /* INCLUDED_USRP2_ETH_PACKET_H */