76bfb933990409b75aed9d9784dfa6cd4f753bea
[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 static 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 Void rlcTmrExpiry(PTR cb,S16 tmrEvnt)
298 {
299 /* kw005.201 added support for L2 Measurement */
300
301    switch (tmrEvnt)
302    {
303       case RLC_EVT_UMUL_REORD_TMR:
304       {
305          RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
306          rlcUmmReOrdTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
307
308          break;
309       }
310       case RLC_EVT_AMUL_REORD_TMR:
311       {
312          RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
313          rlcAmmReOrdTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
314          break;
315       }
316       case RLC_EVT_AMUL_STA_PROH_TMR:
317       {
318          RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
319          rlcAmmStaProTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
320
321          break;
322       }
323       case RLC_EVT_AMDL_POLL_RETX_TMR:
324       {
325          RlcDlRbCb *dlRbCb = (RlcDlRbCb *)cb;
326          RlcCb *gCb = RLC_GET_RLCCB(dlRbCb->inst);
327          
328          rlcAmmPollRetxTmrExp(gCb, dlRbCb);
329
330          gCb->genSts.protTimeOut++;
331          break;
332       }
333       case RLC_EVT_WAIT_BNDCFM:
334       {
335          rlcBndTmrExpiry(cb);
336          break;
337       }
338       /* kw005.201 L2 Measurement support */
339       default:
340       {
341          break;
342       }
343    }
344
345    return;
346 }
347
348 /**
349  * @brief Handler to check if the timer is running
350  *       
351  * @param[in] gCb       Pointer to the RLC instance control block
352  * @param[in] cb        Control block depending on the type of the timer event. 
353  *                      It can be uplink/downlink rbCb or rgu sap control block
354  * @param[in] tmrEvnt   Timer event to be started
355  *
356  * @return  Bool indicating whether the timer is running or not
357  *      -# ROK 
358  *      -# RFAILED 
359 */
360 bool rlcChkTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt)
361 {
362    switch (tmrEvnt)
363    {
364       case RLC_EVT_UMUL_REORD_TMR:
365       {
366          return (((RlcUlRbCb *)cb)->m.umUl.reOrdTmr.tmrEvnt == 
367                   RLC_EVT_UMUL_REORD_TMR);
368       }
369       case RLC_EVT_AMUL_REORD_TMR:
370       {
371          return (((RlcUlRbCb *)cb)->m.amUl.reOrdTmr.tmrEvnt == 
372                   RLC_EVT_AMUL_REORD_TMR);
373       }
374       case RLC_EVT_AMUL_STA_PROH_TMR:
375       {
376          return (((RlcUlRbCb *)cb)->m.amUl.staProhTmr.tmrEvnt == 
377                   RLC_EVT_AMUL_STA_PROH_TMR);
378       } 
379       case RLC_EVT_AMDL_POLL_RETX_TMR:
380       {
381          return (((RlcDlRbCb *)cb)->m.amDl.pollRetxTmr.tmrEvnt == 
382                   RLC_EVT_AMDL_POLL_RETX_TMR);
383       } 
384       case RLC_EVT_WAIT_BNDCFM:
385       {
386          return (((RlcRguSapCb *)cb)->bndTmr.tmrEvnt == RLC_EVT_WAIT_BNDCFM);
387       }
388       default:
389       {
390          DU_LOG("\nRLC : rlcChkTmr: Invalid tmr Evnt [%d]", tmrEvnt);
391       }
392    } 
393
394    return FALSE;
395 }
396
397 /**
398  * @brief Handler to do processing on expiry of the bind timer
399  *
400  * @details
401  *    This function processes the RLC bind timer expiry. If the number of 
402  *    retries is less than the maximum retry counter, bind request is sent 
403  *    again, else an alarm is raised to the layer manager.
404  *       
405  * @param[in] cb  Pointer to the Rgu sap
406  *
407  * @return  Void
408 */
409 static Void rlcBndTmrExpiry(PTR cb)
410 {
411    RlcRguSapCb *rguSapCb; 
412
413    rguSapCb = (RlcRguSapCb *) cb;
414
415    if (rguSapCb->state == RLC_SAP_BINDING)
416    {
417       if (rguSapCb->retryCnt < RLC_MAX_SAP_BND_RETRY)
418       {
419          /* start timer to wait for bind confirm */
420          rlcStartTmr(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
421                     (PTR)rguSapCb, 
422                     RLC_EVT_WAIT_BNDCFM);
423          
424          /* Send bind request */
425          rguSapCb->retryCnt++;
426          RlcLiRguBndReq (&rguSapCb->pst, rguSapCb->suId, rguSapCb->spId);
427       }
428       else
429       {
430          rguSapCb->retryCnt = 0;
431          rguSapCb->state = RLC_SAP_CFG;
432
433          /* Send alarm to the layer manager */
434 #ifdef LTE_L2_MEAS
435          rlcLmmSendAlarm(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
436                         LCM_CATEGORY_INTERFACE, 
437                         LCM_EVENT_BND_FAIL,
438                         LCM_CAUSE_TMR_EXPIRED, 
439                         0, 
440                         0, 
441                         0);
442 #else
443          rlcLmmSendAlarm(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
444                         LCM_CATEGORY_INTERFACE, 
445                         LCM_EVENT_BND_FAIL,
446                         LCM_CAUSE_TMR_EXPIRED, 
447                         0, /* suId */
448                         0 /* ueId */);
449 #endif
450       }
451    }
452
453    return;
454 }
455
456
457 \f  
458 /********************************************************************30**
459   
460          End of file
461 **********************************************************************/