diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2011-04-24 11:20:48 +0200 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2011-07-28 21:30:50 +0200 |
commit | 643aad2ef4b0677b95aa94f5eb7a2d01db1fe004 (patch) | |
tree | a2c74e818f4b8b8a5d1d099cc859e1642f95717e /src/target | |
parent | c7d20dfc41e907c38c015a0bfacb1f79f399b875 (diff) |
fw/l1: Add a queue for traffic frame to send to network (TRAFFIC_REQ)
Also hard limit to maximum 4 pending frames (should not happen !), the
upstream is supposed to do its own flow control.
Written-by: Andreas Eversberg <jolly@eversberg.eu>
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Diffstat (limited to 'src/target')
-rw-r--r-- | src/target/firmware/include/layer1/sync.h | 1 | ||||
-rw-r--r-- | src/target/firmware/layer1/l23_api.c | 27 |
2 files changed, 28 insertions, 0 deletions
diff --git a/src/target/firmware/include/layer1/sync.h b/src/target/firmware/include/layer1/sync.h index 8ed2cb1e..4247dabe 100644 --- a/src/target/firmware/include/layer1/sync.h +++ b/src/target/firmware/include/layer1/sync.h @@ -27,6 +27,7 @@ struct l1_cell_info { enum l1s_chan { L1S_CHAN_MAIN, L1S_CHAN_SACCH, + L1S_CHAN_TRAFFIC, _NUM_L1S_CHAN }; diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c index 3baba171..2a22db8f 100644 --- a/src/target/firmware/layer1/l23_api.c +++ b/src/target/firmware/layer1/l23_api.c @@ -303,6 +303,7 @@ static void l1ctl_rx_dm_rel_req(struct msgb *msg) l1s.dedicated.type = GSM_DCHAN_NONE; l1a_txq_msgb_flush(&l1s.tx_queue[L1S_CHAN_MAIN]); l1a_txq_msgb_flush(&l1s.tx_queue[L1S_CHAN_SACCH]); + l1a_txq_msgb_flush(&l1s.tx_queue[L1S_CHAN_TRAFFIC]); l1a_meas_msgb_set(NULL); dsp_load_ciph_param(0, NULL); l1a_tch_mode_set(GSM48_CMODE_SIGN); @@ -517,6 +518,28 @@ static void l1ctl_rx_neigh_pm_req(struct msgb *msg) mframe_enable(MF_TASK_NEIGH_PM51); } +/* receive a L1CTL_TRAFFIC_REQ from L23 */ +static void l1ctl_rx_traffic_req(struct msgb *msg) +{ + struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->data; + struct l1ctl_info_ul *ul = (struct l1ctl_info_ul *) l1h->data; + struct l1ctl_traffic_req *tr = (struct l1ctl_traffic_req *) ul->payload; + int num = 0; + + /* printd("L1CTL_TRAFFIC_REQ\n"); */ /* Very verbose, can overwelm serial */ + + msg->l2h = tr->data; + + num = l1a_txq_msgb_count(&l1s.tx_queue[L1S_CHAN_TRAFFIC]); + if (num >= 4) { + printd("dropping traffic frame\n"); + msgb_free(msg); + return; + } + + l1a_txq_msgb_enq(&l1s.tx_queue[L1S_CHAN_TRAFFIC], msg); +} + /* callback from SERCOMM when L2 sends a message to L1 */ static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg) { @@ -580,6 +603,10 @@ static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg) case L1CTL_NEIGH_PM_REQ: l1ctl_rx_neigh_pm_req(msg); break; + case L1CTL_TRAFFIC_REQ: + l1ctl_rx_traffic_req(msg); + /* we have to keep the msgb, not free it! */ + goto exit_nofree; } exit_msgbfree: |