fw/l1: Add a queue for traffic frame to send to network (TRAFFIC_REQ)
[osmocom-bb.git] / src / target / firmware / include / layer1 / sync.h
1 #ifndef _L1_SYNC_H
2 #define _L1_SYNC_H
3
4 #include <osmocom/core/linuxlist.h>
5 #include <osmocom/gsm/gsm_utils.h>
6 #include <layer1/tdma_sched.h>
7 #include <layer1/mframe_sched.h>
8 #include <l1ctl_proto.h>
9
10 /* structure representing L1 sync information about a cell */
11 struct l1_cell_info {
12         /* on which ARFCN (+band) is the cell? */
13         uint16_t        arfcn;
14         /* what's the BSIC of the cell (from SCH burst decoding) */
15         uint8_t         bsic;
16         /* Combined or non-combined CCCH */
17         uint8_t         ccch_mode; /* enum ccch_mode */
18         /* whats the delta of the cells current GSM frame number
19          * compared to our current local frame number */
20         int32_t         fn_offset;
21         /* how much does the TPU need adjustment (delta) to synchronize
22          * with the cells burst */
23         uint32_t        time_alignment;
24         /* FIXME: should we also store the AFC value? */
25 };
26
27 enum l1s_chan {
28         L1S_CHAN_MAIN,
29         L1S_CHAN_SACCH,
30         L1S_CHAN_TRAFFIC,
31         _NUM_L1S_CHAN
32 };
33
34 enum l1_compl {
35         L1_COMPL_FB,
36         L1_COMPL_RACH,
37         L1_COMPL_TX_NB,
38         L1_COMPL_TX_TCH,
39 };
40
41 typedef void l1_compl_cb(enum l1_compl c);
42
43 #define L1S_NUM_COMPL           32
44 #define L1S_NUM_NEIGH_CELL      6
45
46 struct l1s_h0 {
47         uint16_t arfcn;
48 };
49
50 struct l1s_h1 {
51         uint8_t hsn;
52         uint8_t maio;
53         uint8_t n;
54         uint16_t ma[64];
55 };
56
57 struct l1s_state {
58         struct gsm_time current_time;   /* current GSM time */
59         struct gsm_time next_time;      /* GSM time at next TMDMA irq */
60
61         /* the cell on which we are camping right now */
62         struct l1_cell_info serving_cell;
63
64         /* neighbor cell sync info */
65         struct l1_cell_info neigh_cell[L1S_NUM_NEIGH_CELL];
66
67         /* TDMA scheduler */
68         struct tdma_scheduler tdma_sched;
69
70         /* Multiframe scheduler */
71         struct mframe_scheduler mframe_sched;
72
73         /* The current TPU offset register */
74         uint32_t        tpu_offset;
75         int32_t         tpu_offset_correction;
76
77         /* TX parameters */
78         int8_t          ta;
79         uint8_t         tx_power;
80
81         /* TCH */
82         uint8_t         tch_mode;
83         uint8_t         tch_sync;
84
85         /* Transmit queues of pending packets for main DCCH and ACCH */
86         struct llist_head tx_queue[_NUM_L1S_CHAN];
87         struct msgb *tx_meas;
88
89         /* Which L1A completions are scheduled right now */
90         uint32_t scheduled_compl;
91         /* callbacks for each of the completions */
92         l1_compl_cb *completion[L1S_NUM_COMPL];
93
94         /* Structures below are for L1-task specific parameters, used
95          * to communicate between l1-sync and l1-async (l23_api) */
96         struct {
97                 uint8_t mode;   /* FB_MODE 0/1 */
98         } fb;
99
100         struct {
101                 /* power measurement l1 task */
102                 unsigned int mode;
103                 union {
104                         struct {
105                                 uint16_t arfcn_start;
106                                 uint16_t arfcn_next;
107                                 uint16_t arfcn_end;
108                         } range;
109                 };
110                 struct msgb *msg;
111         } pm;
112
113         struct {
114                 uint8_t         ra;
115         } rach;
116
117         struct {
118                 enum {
119                         GSM_DCHAN_NONE = 0,
120                         GSM_DCHAN_SDCCH_4,
121                         GSM_DCHAN_SDCCH_8,
122                         GSM_DCHAN_TCH_H,
123                         GSM_DCHAN_TCH_F,
124                         GSM_DCHAN_UNKNOWN,
125                 } type;
126
127                 uint8_t scn;
128                 uint8_t tsc;
129                 uint8_t tn;
130                 uint8_t h;
131
132                 union {
133                         struct l1s_h0 h0;
134                         struct l1s_h1 h1;
135                 };
136
137                 uint8_t st_tsc;
138                 uint8_t st_tn;
139                 uint8_t st_h;
140
141                 union {
142                         struct l1s_h0 st_h0;
143                         struct l1s_h1 st_h1;
144                 };
145         } dedicated;
146
147         /* neighbour cell power measurement process */
148         struct {
149                 uint8_t n, second;
150                 uint8_t pos;
151                 uint8_t running;
152                 uint16_t band_arfcn[64];
153                 uint8_t level[64];
154         } neigh_pm;
155 };
156
157 extern struct l1s_state l1s;
158
159 struct l1s_meas_hdr {
160         uint16_t snr;           /* signal/noise ratio */
161         int16_t toa_qbit;       /* time of arrival (qbits) */
162         int16_t pm_dbm8;        /* power level in dbm/8 */
163         int16_t freq_err;       /* Frequency error in Hz */
164 };
165
166 int16_t l1s_snr_int(uint16_t snr);
167 uint16_t l1s_snr_fract(uint16_t snr);
168
169 void l1s_dsp_abort(void);
170
171 void l1s_tx_apc_helper(uint16_t arfcn);
172
173 /* schedule a completion */
174 void l1s_compl_sched(enum l1_compl c);
175
176 void l1s_init(void);
177
178 /* reset the layer1 as part of synchronizing to a new cell */
179 void l1s_reset(void);
180
181 /* init.c */
182 void layer1_init(void);
183
184 /* A debug macro to print every TDMA frame */
185 #ifdef DEBUG_EVERY_TDMA
186 #define putchart(x) putchar(x)
187 #else
188 #define putchart(x)
189 #endif
190
191 /* Convert an angle in fx1.15 notatinon into Hz */
192 #define BITFREQ_DIV_2PI         43104   /* 270kHz / 2 * pi */
193 #define BITFREQ_DIV_PI          86208   /* 270kHz / pi */
194 #define ANG2FREQ_SCALING        (2<<15) /* 2^15 scaling factor for fx1.15 */
195 #define ANGLE_TO_FREQ(angle)    ((int16_t)angle * BITFREQ_DIV_PI / ANG2FREQ_SCALING)
196
197 void l1s_reset_hw(void);
198 void synchronize_tdma(struct l1_cell_info *cinfo);
199 void l1s_time_inc(struct gsm_time *time, uint32_t delta_fn);
200 void l1s_time_dump(const struct gsm_time *time);
201
202 #endif /* _L1_SYNC_H */