summaryrefslogtreecommitdiff
path: root/cesar/cl/src/receive.c
blob: 3b38f10456d0e9a961bb99cb7459d0c2724fa25e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* Cesar project {{{
 *
 * Copyright (C) 2012 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    cl/src/receive.c
 * \brief   Functions to handle data coming into the CL
 * \ingroup cl
 */
#include "common/std.h"
#include "common/defs/ethernet.h"

#include "common/ipmbox/msg.h"
#include "common/ipmbox/protocol.h"

#include "lib/bitstream.h"
#include "lib/seq_check.h"

#include "mac/common/ntb.h"
#include "hal/ipmbox/ipmbox.h"
#include "hal/gpio/gpio.h"

#include "hle/tools/tools.h"

#include "cl/cl.h"
#include "cl/data_rate.h"
#include "cl/bridge_table.h"

#include "cl/inc/trace.h"
#include "cl/inc/context.h"
#include "cl/inc/send.h"
#include "cl/inc/receive.h"
#include "config/cl.h"

void ARCH_ILRAM_PRIO (3)
cl_sar_data_recv (cl_t *ctx, u8 *buffer, uint length, mfs_rx_t *mfs)
{
    dbg_claim (ctx);
    dbg_claim (buffer);
    dbg_claim (mfs);

    /* Check sequence number of throughput. */
    lib_seq_check_packet (&ctx->seq_check_rx_ctx, buffer, length);

    /* Increase bytes count. */
    ctx->stats.rx_data_bytes += length;

    mac_t smac, dmac;
    bitstream_direct_read_macs (buffer, &dmac, &smac);
    CL_TRACE (DATA_RECV, phy_date (), buffer, TRACE_U64 (dmac),
              TRACE_U64 (smac), length);

    /* Create IPMbox message. */
    ipmbox_msg_data_t msg;
    msg.header = ipmbox_msg_create_header_data (length, 0);
    msg.buffer_addr = (u32) buffer;
    ipmbox_tx_data (ctx->ipmbox, (u32 *) &msg, IPMBOX_MSG_DATA_WORDS);

#if !CONFIG_CL_EOC_ROUTE
    cl_brg_rx_add (ctx, smac, mfs->common.tei);
#else
    bool ok = true;
    if (MAC_TEI_IS_EOC_CCO(ctx->mac_config->tei))
        ok = cl_eoc_mactotei_entry_insert (ctx, smac, mfs->common.tei);
    dbg_assert (ok);
#endif

    if (mac_is_multicast (dmac) && dmac != MAC_BROADCAST)
        ctx->stats.rx_data_multicast++;
    else
        ctx->stats.rx_data++;

    /* update data rate informations associated to the RX
     * from the associated sta to the local sta */
    cl_compute_datarate_on_sta (ctx, PARENT_OF (mfs_t, rx, mfs), length);
    /* Debug info. */
    GPIO_TOGGLE (LED_CL_RX);
}

void
cl_sar_mme_recv (cl_t *ctx, u8 *buffer, uint length, mfs_rx_t *mfs,
                 bool encryption)
{
    dbg_claim (ctx);
    dbg_claim (mfs);
    dbg_claim (buffer);
    ctx->stats.rx_mme++;
    (*ctx->mbx->cb) (ctx->mbx->user_data, mfs->common.tei,
                     buffer, length, encryption);
    CL_TRACE (MME_RECV, phy_date (), length, buffer, true);
    /* Debug info. */
    GPIO_TOGGLE (LED_CL_RX);
}

void ARCH_ILRAM_PRIO (3)
cl_ipmbox_data_recv (cl_t *ctx, u32 *msg_buffer, uint nb_words)
{
    /* Check parameters. */
    dbg_claim (msg_buffer);
    dbg_claim (nb_words);

    ipmbox_msg_data_t *msg = (ipmbox_msg_data_t *) msg_buffer;
    ipmbox_msg_data_t *msg_end = msg + nb_words / IPMBOX_MSG_DATA_WORDS;
    for ( ; msg != msg_end; msg++)
    {
        u32 length = ipmbox_msg_get_data_length (msg->header);
        u32 vlan_prio = ipmbox_msg_get_data_prio_tag (msg->header);
        cl_data_send (ctx, (u8 *) msg->buffer_addr, length, vlan_prio,
                      mac_ntb ());
    }
}

void
cl_lib_seq_check_rx_cb (void *user, uint vlan_outer, uint vlan_inner,
                        uint seq_expected, uint seq_actual)
{
    dbg_assert (user);
    trace_do (cl_t *ctx = (cl_t *) user);
    CL_TRACE (SEQ_CHECK_RX, vlan_outer, vlan_inner, seq_expected, seq_actual);
}