root / usrp2 / firmware / apps / bitrot / tx_drop.c @ e0fcbaee
History | View | Annotate | Download (5.9 kB)
| 1 | e0fcbaee | jcorgan | /*
|
|---|---|---|---|
| 2 | e0fcbaee | jcorgan | * Copyright 2007,2008 Free Software Foundation, Inc. |
| 3 | e0fcbaee | jcorgan | * |
| 4 | e0fcbaee | jcorgan | * This program is free software: you can redistribute it and/or modify |
| 5 | e0fcbaee | jcorgan | * it under the terms of the GNU General Public License as published by |
| 6 | e0fcbaee | jcorgan | * the Free Software Foundation, either version 3 of the License, or |
| 7 | e0fcbaee | jcorgan | * (at your option) any later version. |
| 8 | e0fcbaee | jcorgan | * |
| 9 | e0fcbaee | jcorgan | * This program is distributed in the hope that it will be useful, |
| 10 | e0fcbaee | jcorgan | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | e0fcbaee | jcorgan | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | e0fcbaee | jcorgan | * GNU General Public License for more details. |
| 13 | e0fcbaee | jcorgan | * |
| 14 | e0fcbaee | jcorgan | * You should have received a copy of the GNU General Public License |
| 15 | e0fcbaee | jcorgan | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | e0fcbaee | jcorgan | */ |
| 17 | e0fcbaee | jcorgan | |
| 18 | e0fcbaee | jcorgan | #ifdef HAVE_CONFIG_H
|
| 19 | e0fcbaee | jcorgan | #include "config.h" |
| 20 | e0fcbaee | jcorgan | #endif
|
| 21 | e0fcbaee | jcorgan | |
| 22 | e0fcbaee | jcorgan | #include "u2_init.h" |
| 23 | e0fcbaee | jcorgan | #include "memory_map.h" |
| 24 | e0fcbaee | jcorgan | #include "spi.h" |
| 25 | e0fcbaee | jcorgan | #include "hal_io.h" |
| 26 | e0fcbaee | jcorgan | #include "buffer_pool.h" |
| 27 | e0fcbaee | jcorgan | #include "pic.h" |
| 28 | e0fcbaee | jcorgan | #include "bool.h" |
| 29 | e0fcbaee | jcorgan | #include "ethernet.h" |
| 30 | e0fcbaee | jcorgan | #include "nonstdio.h" |
| 31 | e0fcbaee | jcorgan | #include "usrp2_eth_packet.h" |
| 32 | e0fcbaee | jcorgan | #include "dbsm.h" |
| 33 | e0fcbaee | jcorgan | #include "app_common.h" |
| 34 | e0fcbaee | jcorgan | #include "print_rmon_regs.h" |
| 35 | e0fcbaee | jcorgan | #include <stddef.h> |
| 36 | e0fcbaee | jcorgan | #include <stdlib.h> |
| 37 | e0fcbaee | jcorgan | #include <string.h> |
| 38 | e0fcbaee | jcorgan | |
| 39 | e0fcbaee | jcorgan | |
| 40 | e0fcbaee | jcorgan | /*
|
| 41 | e0fcbaee | jcorgan | * Like tx_only.c, but we discard data packets instead of sending them to the |
| 42 | e0fcbaee | jcorgan | * DSP TX pipeline. |
| 43 | e0fcbaee | jcorgan | */ |
| 44 | e0fcbaee | jcorgan | |
| 45 | e0fcbaee | jcorgan | int total_rx_pkts = 0; |
| 46 | e0fcbaee | jcorgan | int total_rx_bytes = 0; |
| 47 | e0fcbaee | jcorgan | |
| 48 | e0fcbaee | jcorgan | |
| 49 | e0fcbaee | jcorgan | static int timer_delta = MASTER_CLK_RATE/1000; // tick at 1kHz |
| 50 | e0fcbaee | jcorgan | |
| 51 | e0fcbaee | jcorgan | /*
|
| 52 | e0fcbaee | jcorgan | * This program can respond to queries from the host |
| 53 | e0fcbaee | jcorgan | * and stream rx samples. |
| 54 | e0fcbaee | jcorgan | * |
| 55 | e0fcbaee | jcorgan | * Buffer 1 is used by the cpu to send frames to the host. |
| 56 | e0fcbaee | jcorgan | * Buffers 2 and 3 are used to double-buffer the DSP Rx to eth flow |
| 57 | e0fcbaee | jcorgan | * Buffers 4 and 5 are used to double-buffer the eth to DSP Tx eth flow |
| 58 | e0fcbaee | jcorgan | */ |
| 59 | e0fcbaee | jcorgan | //#define CPU_RX_BUF 0 // eth -> cpu
|
| 60 | e0fcbaee | jcorgan | //#define CPU_TX_BUF 1 // cpu -> eth
|
| 61 | e0fcbaee | jcorgan | |
| 62 | e0fcbaee | jcorgan | #define DSP_RX_BUF_0 2 // dsp rx -> eth (double buffer) |
| 63 | e0fcbaee | jcorgan | #define DSP_RX_BUF_1 3 // dsp rx -> eth |
| 64 | e0fcbaee | jcorgan | #define DSP_TX_BUF_0 4 // eth -> dsp tx (double buffer) |
| 65 | e0fcbaee | jcorgan | #define DSP_TX_BUF_1 5 // eth -> dsp tx |
| 66 | e0fcbaee | jcorgan | |
| 67 | e0fcbaee | jcorgan | |
| 68 | e0fcbaee | jcorgan | /*
|
| 69 | e0fcbaee | jcorgan | * ================================================================ |
| 70 | e0fcbaee | jcorgan | * configure DSP TX double buffering state machine |
| 71 | e0fcbaee | jcorgan | * ================================================================ |
| 72 | e0fcbaee | jcorgan | */ |
| 73 | e0fcbaee | jcorgan | |
| 74 | e0fcbaee | jcorgan | // 4 lines of ethernet hdr + 2 lines (word0 + timestamp)
|
| 75 | e0fcbaee | jcorgan | // DSP Tx reads word0 (flags) + timestamp followed by samples
|
| 76 | e0fcbaee | jcorgan | |
| 77 | e0fcbaee | jcorgan | #define DSP_TX_FIRST_LINE 4 |
| 78 | e0fcbaee | jcorgan | #define DSP_TX_SAMPLES_PER_FRAME 250 // not used except w/ debugging |
| 79 | e0fcbaee | jcorgan | #define DSP_TX_EXTRA_LINES 2 // reads word0 + timestamp |
| 80 | e0fcbaee | jcorgan | |
| 81 | e0fcbaee | jcorgan | // Receive from ethernet
|
| 82 | e0fcbaee | jcorgan | buf_cmd_args_t dsp_tx_recv_args = {
|
| 83 | e0fcbaee | jcorgan | PORT_ETH, |
| 84 | e0fcbaee | jcorgan | 0,
|
| 85 | e0fcbaee | jcorgan | BP_LAST_LINE |
| 86 | e0fcbaee | jcorgan | }; |
| 87 | e0fcbaee | jcorgan | |
| 88 | e0fcbaee | jcorgan | // send to DSP Tx
|
| 89 | e0fcbaee | jcorgan | buf_cmd_args_t dsp_tx_send_args = {
|
| 90 | e0fcbaee | jcorgan | PORT_DSP, |
| 91 | e0fcbaee | jcorgan | DSP_TX_FIRST_LINE, // starts just past ethernet header
|
| 92 | e0fcbaee | jcorgan | 0 // filled in from last_line register |
| 93 | e0fcbaee | jcorgan | }; |
| 94 | e0fcbaee | jcorgan | |
| 95 | e0fcbaee | jcorgan | dbsm_t dsp_tx_sm; // the state machine
|
| 96 | e0fcbaee | jcorgan | |
| 97 | e0fcbaee | jcorgan | |
| 98 | e0fcbaee | jcorgan | // ----------------------------------------------------------------
|
| 99 | e0fcbaee | jcorgan | |
| 100 | e0fcbaee | jcorgan | |
| 101 | e0fcbaee | jcorgan | // The mac address of the host we're sending to.
|
| 102 | e0fcbaee | jcorgan | u2_mac_addr_t host_mac_addr; |
| 103 | e0fcbaee | jcorgan | |
| 104 | e0fcbaee | jcorgan | |
| 105 | e0fcbaee | jcorgan | void
|
| 106 | e0fcbaee | jcorgan | timer_irq_handler(unsigned irq)
|
| 107 | e0fcbaee | jcorgan | {
|
| 108 | e0fcbaee | jcorgan | hal_set_timeout(timer_delta); // schedule next timeout
|
| 109 | e0fcbaee | jcorgan | } |
| 110 | e0fcbaee | jcorgan | |
| 111 | e0fcbaee | jcorgan | // Tx DSP underrun
|
| 112 | e0fcbaee | jcorgan | void
|
| 113 | e0fcbaee | jcorgan | underrun_irq_handler(unsigned irq)
|
| 114 | e0fcbaee | jcorgan | {
|
| 115 | e0fcbaee | jcorgan | putchar('U');
|
| 116 | e0fcbaee | jcorgan | |
| 117 | e0fcbaee | jcorgan | dbsm_stop(&dsp_tx_sm); |
| 118 | e0fcbaee | jcorgan | dsp_tx_regs->clear_state = 1;
|
| 119 | e0fcbaee | jcorgan | dbsm_start(&dsp_tx_sm); // restart sm so we're listening to ethernet again
|
| 120 | e0fcbaee | jcorgan | |
| 121 | e0fcbaee | jcorgan | // putstr("\nirq: underrun\n");
|
| 122 | e0fcbaee | jcorgan | } |
| 123 | e0fcbaee | jcorgan | |
| 124 | e0fcbaee | jcorgan | |
| 125 | e0fcbaee | jcorgan | void
|
| 126 | e0fcbaee | jcorgan | start_rx_cmd(const u2_mac_addr_t *host, op_start_rx_t *p)
|
| 127 | e0fcbaee | jcorgan | {
|
| 128 | e0fcbaee | jcorgan | } |
| 129 | e0fcbaee | jcorgan | |
| 130 | e0fcbaee | jcorgan | void
|
| 131 | e0fcbaee | jcorgan | stop_rx_cmd(void)
|
| 132 | e0fcbaee | jcorgan | {
|
| 133 | e0fcbaee | jcorgan | } |
| 134 | e0fcbaee | jcorgan | |
| 135 | e0fcbaee | jcorgan | static void |
| 136 | e0fcbaee | jcorgan | setup_tx() |
| 137 | e0fcbaee | jcorgan | {
|
| 138 | e0fcbaee | jcorgan | dsp_tx_regs->clear_state = 1;
|
| 139 | e0fcbaee | jcorgan | bp_clear_buf(DSP_TX_BUF_0); |
| 140 | e0fcbaee | jcorgan | bp_clear_buf(DSP_TX_BUF_1); |
| 141 | e0fcbaee | jcorgan | |
| 142 | e0fcbaee | jcorgan | int tx_scale = 256; |
| 143 | e0fcbaee | jcorgan | int interp = 32; |
| 144 | e0fcbaee | jcorgan | |
| 145 | e0fcbaee | jcorgan | op_config_tx_t def_config; |
| 146 | e0fcbaee | jcorgan | memset(&def_config, 0, sizeof(def_config)); |
| 147 | e0fcbaee | jcorgan | def_config.phase_inc = 408021893; // 9.5 MHz [2**32 * fc/fsample] |
| 148 | e0fcbaee | jcorgan | def_config.scale_iq = (tx_scale << 16) | tx_scale;
|
| 149 | e0fcbaee | jcorgan | def_config.interp = interp; |
| 150 | e0fcbaee | jcorgan | |
| 151 | e0fcbaee | jcorgan | // setup Tx DSP regs
|
| 152 | e0fcbaee | jcorgan | config_tx_cmd(&def_config); |
| 153 | e0fcbaee | jcorgan | } |
| 154 | e0fcbaee | jcorgan | |
| 155 | e0fcbaee | jcorgan | |
| 156 | e0fcbaee | jcorgan | inline static void |
| 157 | e0fcbaee | jcorgan | buffer_irq_handler(unsigned irq)
|
| 158 | e0fcbaee | jcorgan | {
|
| 159 | e0fcbaee | jcorgan | uint32_t status = buffer_pool_status->status; |
| 160 | e0fcbaee | jcorgan | |
| 161 | e0fcbaee | jcorgan | if (status & BPS_ERROR_ALL){
|
| 162 | e0fcbaee | jcorgan | // FIXME rare path, handle error conditions
|
| 163 | e0fcbaee | jcorgan | putstr("Errors! status = ");
|
| 164 | e0fcbaee | jcorgan | puthex32_nl(status); |
| 165 | e0fcbaee | jcorgan | |
| 166 | e0fcbaee | jcorgan | printf("total_rx_pkts = %d\n", total_rx_pkts);
|
| 167 | e0fcbaee | jcorgan | printf("total_rx_bytes = %d\n", total_rx_bytes);
|
| 168 | e0fcbaee | jcorgan | |
| 169 | e0fcbaee | jcorgan | print_rmon_regs(); |
| 170 | e0fcbaee | jcorgan | |
| 171 | e0fcbaee | jcorgan | if (status & (BPS_ERROR(DSP_TX_BUF_0) | BPS_ERROR(DSP_TX_BUF_1))){
|
| 172 | e0fcbaee | jcorgan | dbsm_stop(&dsp_tx_sm); |
| 173 | e0fcbaee | jcorgan | dsp_tx_regs->clear_state = 1; // try to restart |
| 174 | e0fcbaee | jcorgan | dbsm_start(&dsp_tx_sm); |
| 175 | e0fcbaee | jcorgan | return;
|
| 176 | e0fcbaee | jcorgan | } |
| 177 | e0fcbaee | jcorgan | } |
| 178 | e0fcbaee | jcorgan | |
| 179 | e0fcbaee | jcorgan | dbsm_process_status(&dsp_tx_sm, status); |
| 180 | e0fcbaee | jcorgan | |
| 181 | e0fcbaee | jcorgan | if (status & BPS_DONE(CPU_TX_BUF)){
|
| 182 | e0fcbaee | jcorgan | bp_clear_buf(CPU_TX_BUF); |
| 183 | e0fcbaee | jcorgan | } |
| 184 | e0fcbaee | jcorgan | } |
| 185 | e0fcbaee | jcorgan | |
| 186 | e0fcbaee | jcorgan | |
| 187 | e0fcbaee | jcorgan | /*
|
| 188 | e0fcbaee | jcorgan | * Called when an ethernet packet is received. |
| 189 | e0fcbaee | jcorgan | * |
| 190 | e0fcbaee | jcorgan | * Claim that we handled all the packets, |
| 191 | e0fcbaee | jcorgan | * dropping those destined for the TX DSP chain |
| 192 | e0fcbaee | jcorgan | * on the ground. |
| 193 | e0fcbaee | jcorgan | */ |
| 194 | e0fcbaee | jcorgan | bool
|
| 195 | e0fcbaee | jcorgan | nop_eth_pkt_inspector(dbsm_t *sm, int bufno)
|
| 196 | e0fcbaee | jcorgan | {
|
| 197 | e0fcbaee | jcorgan | hal_toggle_leds(0x1);
|
| 198 | e0fcbaee | jcorgan | |
| 199 | e0fcbaee | jcorgan | u2_eth_packet_t *pkt = (u2_eth_packet_t *) buffer_ram(bufno); |
| 200 | e0fcbaee | jcorgan | size_t byte_len = (buffer_pool_status->last_line[bufno] - 1) * 4; |
| 201 | e0fcbaee | jcorgan | |
| 202 | e0fcbaee | jcorgan | total_rx_pkts++; |
| 203 | e0fcbaee | jcorgan | total_rx_bytes += byte_len; |
| 204 | e0fcbaee | jcorgan | |
| 205 | e0fcbaee | jcorgan | // inspect rcvd frame and figure out what do do.
|
| 206 | e0fcbaee | jcorgan | |
| 207 | e0fcbaee | jcorgan | if (pkt->ehdr.ethertype != U2_ETHERTYPE)
|
| 208 | e0fcbaee | jcorgan | return true; // ignore, probably bogus PAUSE frame from MAC |
| 209 | e0fcbaee | jcorgan | |
| 210 | e0fcbaee | jcorgan | int chan = u2p_chan(&pkt->fixed);
|
| 211 | e0fcbaee | jcorgan | |
| 212 | e0fcbaee | jcorgan | switch (chan){
|
| 213 | e0fcbaee | jcorgan | case CONTROL_CHAN:
|
| 214 | e0fcbaee | jcorgan | handle_control_chan_frame(pkt, byte_len); |
| 215 | e0fcbaee | jcorgan | return true; // we handled the packet |
| 216 | e0fcbaee | jcorgan | break;
|
| 217 | e0fcbaee | jcorgan | |
| 218 | e0fcbaee | jcorgan | case 0: |
| 219 | e0fcbaee | jcorgan | default:
|
| 220 | e0fcbaee | jcorgan | return true; // We handled the data by dropping it :) |
| 221 | e0fcbaee | jcorgan | break;
|
| 222 | e0fcbaee | jcorgan | } |
| 223 | e0fcbaee | jcorgan | } |
| 224 | e0fcbaee | jcorgan | |
| 225 | e0fcbaee | jcorgan | |
| 226 | e0fcbaee | jcorgan | int
|
| 227 | e0fcbaee | jcorgan | main(void)
|
| 228 | e0fcbaee | jcorgan | {
|
| 229 | e0fcbaee | jcorgan | u2_init(); |
| 230 | e0fcbaee | jcorgan | |
| 231 | e0fcbaee | jcorgan | // setup tx gpio bits for GPIOM_FPGA_1 -- fpga debug output
|
| 232 | e0fcbaee | jcorgan | hal_gpio_set_tx_mode(15, 0, GPIOM_FPGA_1); |
| 233 | e0fcbaee | jcorgan | hal_gpio_set_rx_mode(15, 0, GPIOM_FPGA_1); |
| 234 | e0fcbaee | jcorgan | |
| 235 | e0fcbaee | jcorgan | putstr("\ntx_drop\n");
|
| 236 | e0fcbaee | jcorgan | |
| 237 | e0fcbaee | jcorgan | // Control LEDs
|
| 238 | e0fcbaee | jcorgan | hal_set_leds(0x0, 0x3); |
| 239 | e0fcbaee | jcorgan | |
| 240 | e0fcbaee | jcorgan | pic_register_handler(IRQ_UNDERRUN, underrun_irq_handler); |
| 241 | e0fcbaee | jcorgan | |
| 242 | e0fcbaee | jcorgan | ethernet_register_link_changed_callback(link_changed_callback); |
| 243 | e0fcbaee | jcorgan | ethernet_init(); |
| 244 | e0fcbaee | jcorgan | |
| 245 | e0fcbaee | jcorgan | // initialize double buffering state machine for ethernet -> DSP Tx
|
| 246 | e0fcbaee | jcorgan | |
| 247 | e0fcbaee | jcorgan | dbsm_init(&dsp_tx_sm, DSP_TX_BUF_0, |
| 248 | e0fcbaee | jcorgan | &dsp_tx_recv_args, &dsp_tx_send_args, |
| 249 | e0fcbaee | jcorgan | nop_eth_pkt_inspector); |
| 250 | e0fcbaee | jcorgan | |
| 251 | e0fcbaee | jcorgan | // program tx registers
|
| 252 | e0fcbaee | jcorgan | setup_tx(); |
| 253 | e0fcbaee | jcorgan | |
| 254 | e0fcbaee | jcorgan | // kick off the state machine
|
| 255 | e0fcbaee | jcorgan | dbsm_start(&dsp_tx_sm); |
| 256 | e0fcbaee | jcorgan | |
| 257 | e0fcbaee | jcorgan | while(1){ |
| 258 | e0fcbaee | jcorgan | buffer_irq_handler(0);
|
| 259 | e0fcbaee | jcorgan | } |
| 260 | e0fcbaee | jcorgan | } |