RLC BO, BO response and DL Data handling. [Issue-ID: ODUHIGH-181]
[o-du/l2.git] / src / 5gnrrlc / kw_tmr.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18
19 /********************************************************************20**
20   
21         Name:    RLC - TMR module file
22     
23         Type:    C source file
24   
25         Desc:    Source code for timer functions such as, 
26
27                  - rlcStartTmr
28                  - rlcStopTmr
29                  - rlcTmrExpiry
30                  - rlcBndTmrExpiry  
31                   
32         File:    kw_tmr.c
33   
34 *********************************************************************21*/
35
36 /* header (.h) include files */
37 #include "common_def.h"
38 #include "lkw.h"           /* LKW defines */
39 #include "ckw.h"           /* CKW defines */
40 #include "kwu.h"           /* KWU defines */
41 #include "rgu.h"           /* RGU defines */
42 #include "kw_env.h"        /* RLC environment options */
43
44 #include "kw.h"            /* RLC defines */
45 #include "kw_err.h"        /* Error defines */
46 #include "kw_ul.h"
47 #include "kw_udx.h"
48 #include "kw_dl.h"
49
50 /* extern (.x) include files */
51 #include "lkw.x"           /* LKW */
52 #include "ckw.x"           /* CKW */
53 #include "kwu.x"           /* KWU */
54 #include "rgu.x"           /* RGU */
55
56 #include "kw.x"
57 #include "kw_udx.x"
58 #include "kw_dl.x"
59 #include "kw_ul.x"
60
61 /** 
62  * @file gp_tmr.c
63  * @brief RLC Timer Module
64 */
65
66 /**
67  * @def RLC_TMR_CALCUATE_WAIT
68  *
69  *    This macro calculates and assigns wait time based on the value of the 
70  *    timer and the timer resolution. Timer value of 0 signifies that the
71  *    timer is not configured
72  *
73  * @param[out] _wait   Time for which to arm the timer changed to proper 
74  *                     value according to the resolution
75  * @param[in] _tmrVal   Value of the timer
76  * @param[in] _timerRes   Resolution of the timer
77  *
78 */
79 #define RLC_TMR_CALCUATE_WAIT(_wait, _tmrVal, _timerRes)       \
80 {                                                             \
81    (_wait) = ((_tmrVal) * SS_TICKS_SEC)/((_timerRes) * 1000); \
82    if((0 != (_tmrVal)) && (0 == (_wait)))                     \
83    {                                                          \
84       (_wait) = 1;                                            \
85    }                                                          \
86 }
87
88 /* private function declarations */
89 PRIVATE Void rlcBndTmrExpiry(PTR cb);
90
91 /**
92  * @brief Handler to start timer
93  *       
94  * @param[in] gCb       Pointer to the RLC instance control block
95  * @param[in] cb        Control block depending on the type of the timer event. 
96  *                      It can be uplink/downlink rbCb or rgu sap control block
97  * @param[in] tmrEvnt   Timer event to be started
98  *
99  * @return  Void
100 */
101 void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt)
102 {
103 /* kw005.201 added support for L2 Measurement */
104 #ifdef LTE_L2_MEAS
105    RlcL2MeasEvtCb *measEvtCb = NULLP;
106 #endif
107
108    CmTmrArg arg;
109    arg.wait = 0;
110
111    /* kw002.201 Adjusting the wait time as per timeRes configured by layer manager */
112    switch (tmrEvnt)
113    {
114       case RLC_EVT_UMUL_REORD_TMR:
115       {
116          RlcUmUl* umUl = &(((RlcUlRbCb *)cb)->m.umUl);
117          /* kw005.201 Changed wait calculation ccpu00117634*/ 
118          RLC_TMR_CALCUATE_WAIT(arg.wait, umUl->reOrdTmrInt, gCb->genCfg.timeRes);
119
120          arg.timers = &umUl->reOrdTmr;
121          arg.max = RLC_MAX_UM_TMR;
122          break;
123       }
124       case RLC_EVT_AMUL_REORD_TMR:
125       {
126          RlcAmUl* amUl = &(((RlcUlRbCb *)cb)->m.amUl);
127          /* kw005.201 Changed wait calculation ccpu00117634*/ 
128          RLC_TMR_CALCUATE_WAIT(arg.wait, amUl->reOrdTmrInt, gCb->genCfg.timeRes);         
129
130          arg.timers = &amUl->reOrdTmr;
131          arg.max = RLC_MAX_AM_TMR;
132          break;
133       }
134       case RLC_EVT_AMUL_STA_PROH_TMR:
135       {
136          RlcAmUl* amUl = &(((RlcUlRbCb *)cb)->m.amUl);
137          /* kw005.201 Changed wait calculation ccpu00117634*/ 
138          RLC_TMR_CALCUATE_WAIT(arg.wait,
139                               amUl->staProhTmrInt,
140                               gCb->genCfg.timeRes);                  
141
142          arg.timers = &amUl->staProhTmr;
143          arg.max = RLC_MAX_AM_TMR;
144          break;
145       } 
146       case RLC_EVT_AMDL_POLL_RETX_TMR:
147       {
148          RlcAmDl* amDl = &(((RlcDlRbCb *)cb)->m.amDl);
149          /* kw005.201 Changed wait calculation ccpu00117634*/ 
150          RLC_TMR_CALCUATE_WAIT(arg.wait, 
151                               amDl->pollRetxTmrInt, 
152                               gCb->genCfg.timeRes);                  
153
154          arg.timers = &amDl->pollRetxTmr;
155          arg.max = RLC_MAX_AM_TMR;
156          break;
157       } 
158       case RLC_EVT_WAIT_BNDCFM:
159       {
160          RlcRguSapCb* rguSap = (RlcRguSapCb *)cb;
161          /* kw005.201 Changed wait calculation ccpu00117634*/ 
162          RLC_TMR_CALCUATE_WAIT(arg.wait, rguSap->bndTmrInt, gCb->genCfg.timeRes);                  
163
164          arg.timers = &rguSap->bndTmr;
165          arg.max = RLC_MAX_RGUSAP_TMR;
166          break;
167       }
168 /* kw005.201 added support for L2 Measurement */
169 #ifdef LTE_L2_MEAS
170       case RLC_EVT_L2_TMR:
171       {
172          measEvtCb = (RlcL2MeasEvtCb *)cb;
173          /* kw005.201 Changed wait calculation ccpu00117634*/ 
174          RLC_TMR_CALCUATE_WAIT(arg.wait, 
175                               measEvtCb->l2TmrCfg.val, 
176                               gCb->genCfg.timeRes);                  
177
178          arg.timers = &measEvtCb->l2Tmr;
179          arg.max = RLC_L2_MAX_TIMERS;
180          break;
181       }
182 #endif
183       default:
184       {
185          DU_LOG("\nRLC : rlcStartTmr: Invalid tmr Evnt [%d]", tmrEvnt);
186       }
187    } 
188
189    if(arg.wait != 0)
190    {
191       arg.tqCp   = &gCb->rlcTqCp;
192       arg.tq     = gCb->rlcTq;
193       arg.cb     = cb;
194       arg.evnt   = tmrEvnt;
195       arg.tNum   = 0;
196
197       cmPlcCbTq(&arg);
198    }
199
200    return;
201 }
202
203 /**
204  * @brief Handler to stop a timer
205  *       
206  * @param[in] gCb       Pointer to the RLC instance control block
207  * @param[in] cb        Control block depending on the type of the timer event. 
208  *                      It can be uplink/downlink rbCb or rgu sap control block
209  * @param[in] tmrType   Timer event to be started
210  *
211  * @return  Void
212 */
213 void rlcStopTmr(RlcCb *gCb, PTR cb, uint8_t tmrType)
214 {
215    CmTmrArg   arg;
216 /* kw005.201 added support for L2 Measurement */
217 #ifdef LTE_L2_MEAS
218    RlcL2MeasEvtCb *measEvtCb = NULLP;
219 #endif
220
221    arg.timers = NULLP;
222
223    switch (tmrType)
224    {
225       case RLC_EVT_UMUL_REORD_TMR:
226       {
227          arg.timers  = &((RlcUlRbCb *)cb)->m.umUl.reOrdTmr;
228          arg.max = RLC_MAX_UM_TMR;
229          break;
230       }
231       case RLC_EVT_AMUL_REORD_TMR:
232       {
233          arg.timers = &((RlcUlRbCb *)cb)->m.amUl.reOrdTmr;
234          arg.max = RLC_MAX_AM_TMR;
235          break;
236       }
237       case RLC_EVT_AMUL_STA_PROH_TMR:
238       {
239          arg.timers = &((RlcUlRbCb *)cb)->m.amUl.staProhTmr;
240          arg.max = RLC_MAX_AM_TMR;
241          break;
242       } 
243       case RLC_EVT_AMDL_POLL_RETX_TMR:
244       {
245          arg.timers = &((RlcDlRbCb *)cb)->m.amDl.pollRetxTmr;
246          arg.max = RLC_MAX_AM_TMR;
247          break;
248       } 
249       case RLC_EVT_WAIT_BNDCFM:
250       {
251          arg.timers = &((RlcRguSapCb *)cb)->bndTmr;
252          arg.max = RLC_MAX_RGUSAP_TMR;
253          break;
254       }
255 /* kw005.201 added support for L2 Measurement */
256 #ifdef LTE_L2_MEAS
257       case RLC_EVT_L2_TMR:
258       {
259          measEvtCb = (RlcL2MeasEvtCb *)cb;
260          arg.timers   = &measEvtCb->l2Tmr;
261          arg.max  = RLC_L2_MAX_TIMERS;
262          break;
263       }
264 #endif
265       default:
266       {
267          DU_LOG("\nRLC : rlcStopTmr: Invalid tmr Evnt[%d]", tmrType);
268       }
269    } 
270    if (tmrType != TMR0)
271    {
272       arg.tqCp   = &gCb->rlcTqCp;
273       arg.tq     = gCb->rlcTq;
274       arg.cb     = cb;
275       arg.evnt   = tmrType;
276       arg.wait   = 0;
277       arg.tNum   = 0;
278       cmRmvCbTq(&arg);
279    }
280    
281    return;
282 }
283
284 /**
285  * @brief Handler to invoke events on expiry of timer.
286  *
287  * @details
288  *    This function is used to handle expiry of timer,it invokes relevant 
289  *    functions.
290  *       
291  * @param[in] cb        Control block depending on the type of the timer event. 
292  *                      It can be uplink/downlink rbCb or rgu sap control block
293  * @param[in] tmrEvnt   Timer event to be started
294  *
295  * @return  Void
296 */
297 #ifdef ANSI
298 Void rlcTmrExpiry
299 (
300 PTR   cb,
301 S16   tmrEvnt 
302 )
303 #else
304 Void rlcTmrExpiry (cb, tmrEvnt)
305 PTR   cb;
306 S16   tmrEvnt;
307 #endif
308 {
309 /* kw005.201 added support for L2 Measurement */
310    TRC2(rlcTmrExpiry)
311
312    switch (tmrEvnt)
313    {
314       case RLC_EVT_UMUL_REORD_TMR:
315       {
316          RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
317          rlcUmmReOrdTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
318
319          break;
320       }
321       case RLC_EVT_AMUL_REORD_TMR:
322       {
323          RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
324          rlcAmmReOrdTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
325          break;
326       }
327       case RLC_EVT_AMUL_STA_PROH_TMR:
328       {
329          RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
330          rlcAmmStaProTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
331
332          break;
333       }
334       case RLC_EVT_AMDL_POLL_RETX_TMR:
335       {
336          RlcDlRbCb *dlRbCb = (RlcDlRbCb *)cb;
337          RlcCb *gCb = RLC_GET_RLCCB(dlRbCb->inst);
338          
339          rlcAmmPollRetxTmrExp(gCb, dlRbCb);
340
341          gCb->genSts.protTimeOut++;
342          break;
343       }
344       case RLC_EVT_WAIT_BNDCFM:
345       {
346          rlcBndTmrExpiry(cb);
347          break;
348       }
349       /* kw005.201 L2 Measurement support */
350       default:
351       {
352          break;
353       }
354    }
355
356    RETVOID;
357 }
358
359 /**
360  * @brief Handler to check if the timer is running
361  *       
362  * @param[in] gCb       Pointer to the RLC instance control block
363  * @param[in] cb        Control block depending on the type of the timer event. 
364  *                      It can be uplink/downlink rbCb or rgu sap control block
365  * @param[in] tmrEvnt   Timer event to be started
366  *
367  * @return  Bool indicating whether the timer is running or not
368  *      -# ROK 
369  *      -# RFAILED 
370 */
371 bool rlcChkTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt)
372 {
373    switch (tmrEvnt)
374    {
375       case RLC_EVT_UMUL_REORD_TMR:
376       {
377          return (((RlcUlRbCb *)cb)->m.umUl.reOrdTmr.tmrEvnt == 
378                   RLC_EVT_UMUL_REORD_TMR);
379       }
380       case RLC_EVT_AMUL_REORD_TMR:
381       {
382          return (((RlcUlRbCb *)cb)->m.amUl.reOrdTmr.tmrEvnt == 
383                   RLC_EVT_AMUL_REORD_TMR);
384       }
385       case RLC_EVT_AMUL_STA_PROH_TMR:
386       {
387          return (((RlcUlRbCb *)cb)->m.amUl.staProhTmr.tmrEvnt == 
388                   RLC_EVT_AMUL_STA_PROH_TMR);
389       } 
390       case RLC_EVT_AMDL_POLL_RETX_TMR:
391       {
392          return (((RlcDlRbCb *)cb)->m.amDl.pollRetxTmr.tmrEvnt == 
393                   RLC_EVT_AMDL_POLL_RETX_TMR);
394       } 
395       case RLC_EVT_WAIT_BNDCFM:
396       {
397          return (((RlcRguSapCb *)cb)->bndTmr.tmrEvnt == RLC_EVT_WAIT_BNDCFM);
398       }
399       default:
400       {
401          DU_LOG("\nRLC : rlcChkTmr: Invalid tmr Evnt [%d]", tmrEvnt);
402       }
403    } 
404
405    return FALSE;
406 }
407
408 /**
409  * @brief Handler to do processing on expiry of the bind timer
410  *
411  * @details
412  *    This function processes the RLC bind timer expiry. If the number of 
413  *    retries is less than the maximum retry counter, bind request is sent 
414  *    again, else an alarm is raised to the layer manager.
415  *       
416  * @param[in] cb  Pointer to the Rgu sap
417  *
418  * @return  Void
419 */
420 #ifdef ANSI
421 PRIVATE Void rlcBndTmrExpiry
422 (
423 PTR cb
424 )
425 #else
426 PRIVATE Void rlcBndTmrExpiry(cb)
427 PTR cb;
428 #endif
429 {
430    RlcRguSapCb *rguSapCb; 
431
432    TRC2(rlcBndTmrExpiry)
433
434    rguSapCb = (RlcRguSapCb *) cb;
435
436    if (rguSapCb->state == RLC_SAP_BINDING)
437    {
438       if (rguSapCb->retryCnt < RLC_MAX_SAP_BND_RETRY)
439       {
440          /* start timer to wait for bind confirm */
441          rlcStartTmr(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
442                     (PTR)rguSapCb, 
443                     RLC_EVT_WAIT_BNDCFM);
444          
445          /* Send bind request */
446          rguSapCb->retryCnt++;
447          RlcLiRguBndReq (&rguSapCb->pst, rguSapCb->suId, rguSapCb->spId);
448       }
449       else
450       {
451          rguSapCb->retryCnt = 0;
452          rguSapCb->state = RLC_SAP_CFG;
453
454          /* Send alarm to the layer manager */
455 #ifdef LTE_L2_MEAS
456          rlcLmmSendAlarm(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
457                         LCM_CATEGORY_INTERFACE, 
458                         LCM_EVENT_BND_FAIL,
459                         LCM_CAUSE_TMR_EXPIRED, 
460                         0, 
461                         0, 
462                         0);
463 #else
464          rlcLmmSendAlarm(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
465                         LCM_CATEGORY_INTERFACE, 
466                         LCM_EVENT_BND_FAIL,
467                         LCM_CAUSE_TMR_EXPIRED, 
468                         0, /* suId */
469                         0 /* ueId */);
470 #endif
471       }
472    }
473
474    RETVOID;
475 }
476
477
478 \f  
479 /********************************************************************30**
480   
481          End of file
482 **********************************************************************/