1/*
2 * Copyright 2008-2015 Freescale Semiconductor Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above copyright
9 *       notice, this list of conditions and the following disclaimer in the
10 *       documentation and/or other materials provided with the distribution.
11 *     * Neither the name of Freescale Semiconductor nor the
12 *       names of its contributors may be used to endorse or promote products
13 *       derived from this software without specific prior written permission.
14 *
15 *
16 * ALTERNATIVELY, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") as published by the Free Software
18 * Foundation, either version 2 of that License or (at your option) any
19 * later version.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/******************************************************************************
34 @File          fm_macsec.c
35
36 @Description   FM MACSEC driver routines implementation.
37*//***************************************************************************/
38
39#include "std_ext.h"
40#include "error_ext.h"
41#include "xx_ext.h"
42#include "string_ext.h"
43#include "sprint_ext.h"
44#include "fm_mac_ext.h"
45
46#include "fm_macsec_master.h"
47
48
49extern uint16_t    FM_MAC_GetMaxFrameLength(t_Handle FmMac);
50
51
52/****************************************/
53/*       static functions               */
54/****************************************/
55static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec)
56{
57    if (!p_FmMacsec->f_Exception)
58        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
59
60    return E_OK;
61}
62
63static void UnimplementedIsr(t_Handle h_Arg, uint32_t id)
64{
65    UNUSED(h_Arg); UNUSED(id);
66
67    REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
68}
69
70static void MacsecEventIsr(t_Handle h_FmMacsec)
71{
72    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
73    uint32_t    events,event,i;
74
75    SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
76
77    events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr);
78    events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever);
79    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events);
80
81    for (i=0; i<NUM_OF_TX_SC; i++)
82        if (events & FM_MACSEC_EV_TX_SC_NEXT_PN(i))
83        {
84            GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_NORMAL, event);
85            p_FmMacsec->intrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i);
86        }
87}
88
89static void MacsecErrorIsr(t_Handle h_FmMacsec)
90{
91    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
92    uint32_t    errors,error,i;
93
94    SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
95
96    errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err);
97    errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer);
98    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors);
99
100    for (i=0; i<NUM_OF_TX_SC; i++)
101        if (errors & FM_MACSEC_EX_TX_SC(i))
102        {
103            GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_ERR, error);
104            p_FmMacsec->intrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i);
105        }
106
107    if (errors & FM_MACSEC_EX_ECC)
108    {
109        uint8_t     eccType;
110        uint32_t    tmpReg;
111
112        tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec);
113        ASSERT_COND(tmpReg & MECC_CAP);
114        eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT);
115
116        if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC))
117            p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC);
118        else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC))
119            p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC);
120        else
121            WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg);
122    }
123}
124
125static t_Error MacsecInit(t_Handle h_FmMacsec)
126{
127    t_FmMacsec                  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
128    t_FmMacsecDriverParam       *p_FmMacsecDriverParam = NULL;
129    uint32_t                    tmpReg,i,macId;
130
131    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
132    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
133
134    CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters);
135
136    p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam;
137
138    for (i=0;i<e_FM_MACSEC_EV_DUMMY_LAST;i++)
139        p_FmMacsec->intrMng[i].f_Isr = UnimplementedIsr;
140
141    tmpReg = 0;
142    tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)|
143              (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT)           |
144              (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT)                        |
145              (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT)              |
146              (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) |
147              (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT)                              |
148              (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT)                              |
149              (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT)                                 |
150              (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT);
151    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
152
153    tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac);
154    /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL.
155     * In addition, the SCI (8 bytes) overhead might be subtracted as well. */
156    tmpReg -= p_FmMacsecDriverParam->mflSubtract;
157    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg);
158
159    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr);
160
161    if (!p_FmMacsec->userExceptions)
162        p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
163    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
164
165    p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC;
166    if (p_FmMacsecDriverParam->reservedSc0)
167        p_FmMacsec->numRxScAvailable --;
168    p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC;
169
170    XX_Free(p_FmMacsecDriverParam);
171    p_FmMacsec->p_FmMacsecDriverParam = NULL;
172
173    FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
174    FmRegisterIntr(p_FmMacsec->h_Fm,
175                   e_FM_MOD_MACSEC,
176                   (uint8_t)macId,
177                   e_FM_INTR_TYPE_NORMAL,
178                   MacsecEventIsr,
179                   p_FmMacsec);
180
181    FmRegisterIntr(p_FmMacsec->h_Fm,
182                   e_FM_MOD_MACSEC,
183                   0,
184                   e_FM_INTR_TYPE_ERR,
185                   MacsecErrorIsr,
186                   p_FmMacsec);
187
188    return E_OK;
189}
190
191static t_Error MacsecFree(t_Handle h_FmMacsec)
192{
193    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
194    uint32_t    macId;
195
196    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
197    SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
198
199    FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
200    FmUnregisterIntr(p_FmMacsec->h_Fm,
201                   e_FM_MOD_MACSEC,
202                   (uint8_t)macId,
203                   e_FM_INTR_TYPE_NORMAL);
204
205    FmUnregisterIntr(p_FmMacsec->h_Fm,
206                   e_FM_MOD_MACSEC,
207                   0,
208                   e_FM_INTR_TYPE_ERR);
209
210    if (p_FmMacsec->rxScSpinLock)
211        XX_FreeSpinlock(p_FmMacsec->rxScSpinLock);
212    if (p_FmMacsec->txScSpinLock)
213        XX_FreeSpinlock(p_FmMacsec->txScSpinLock);
214
215    XX_Free(p_FmMacsec);
216
217    return E_OK;
218}
219
220static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
221{
222    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
223
224    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
225    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
226
227    p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode;
228
229    return E_OK;
230}
231
232static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
233{
234    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
235
236    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
237    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
238
239    p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled;
240
241    return E_OK;
242}
243
244static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
245{
246    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
247
248    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
249    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
250
251    p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled;
252
253    return E_OK;
254}
255
256static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
257{
258    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
259
260    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
261    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
262
263    p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled;
264
265    return E_OK;
266}
267
268static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
269{
270    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
271
272    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
273    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
274
275    p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled;
276
277    return E_OK;
278}
279
280static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
281{
282    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
283
284    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
285    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
286
287    p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode;
288
289    return E_OK;
290}
291
292static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
293{
294    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
295
296    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
297    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
298
299    p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr;
300
301    return E_OK;
302}
303
304static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec)
305{
306    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
307
308    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
309    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
310
311    p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE;
312
313    return E_OK;
314}
315
316static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec)
317{
318    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
319
320    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
321    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
322
323    p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE;
324    p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE;
325
326    return E_OK;
327}
328
329static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
330{
331    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
332    uint32_t    bitMask = 0;
333
334    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
335    SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
336
337    GET_USER_EXCEPTION_FLAG(bitMask, exception);
338    if (bitMask)
339    {
340        if (enable)
341            p_FmMacsec->userExceptions |= bitMask;
342        else
343            p_FmMacsec->userExceptions &= ~bitMask;
344    }
345    else
346        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
347
348    return E_OK;
349}
350
351static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
352{
353    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
354
355    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
356    SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
357
358    *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1);
359
360    return E_OK;
361}
362
363static t_Error MacsecEnable(t_Handle h_FmMacsec)
364{
365    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
366    uint32_t    tmpReg;
367
368    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
369    SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
370
371    tmpReg  = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
372    tmpReg |= CFG_BYPN;
373    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
374
375    return E_OK;
376}
377
378static t_Error MacsecDisable(t_Handle h_FmMacsec)
379{
380    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
381    uint32_t    tmpReg;
382
383    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
384    SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
385
386    tmpReg  = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
387    tmpReg &= ~CFG_BYPN;
388    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
389
390    return E_OK;
391}
392
393static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
394{
395    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
396    uint32_t    bitMask;
397
398    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
399    SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
400
401    GET_USER_EXCEPTION_FLAG(bitMask, exception);
402    if (bitMask)
403    {
404        if (enable)
405            p_FmMacsec->userExceptions |= bitMask;
406        else
407            p_FmMacsec->userExceptions &= ~bitMask;
408    }
409    else
410        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
411
412    if (!p_FmMacsec->userExceptions)
413        p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
414    else
415        p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC;
416    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
417
418    return E_OK;
419}
420
421static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver)
422{
423    p_FmMacsecControllerDriver->f_FM_MACSEC_Init                                            = MacsecInit;
424    p_FmMacsecControllerDriver->f_FM_MACSEC_Free                                            = MacsecFree;
425    p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment                  = MacsecConfigUnknownSciFrameTreatment;
426    p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment                 = MacsecConfigInvalidTagsFrameTreatment;
427    p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment    = MacsecConfigEncryptWithNoChangedTextFrameTreatment;
428    p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment                       = MacsecConfigUntagFrameTreatment;
429    p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment    = MacsecConfigChangedTextWithNoEncryptFrameTreatment;
430    p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment                = MacsecConfigOnlyScbIsSetFrameTreatment;
431    p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold                     = MacsecConfigPnExhaustionThreshold;
432    p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable                            = MacsecConfigKeysUnreadable;
433    p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI                          = MacsecConfigSectagWithoutSCI;
434    p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException                                 = MacsecConfigException;
435    p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision                                     = MacsecGetRevision;
436    p_FmMacsecControllerDriver->f_FM_MACSEC_Enable                                          = MacsecEnable;
437    p_FmMacsecControllerDriver->f_FM_MACSEC_Disable                                         = MacsecDisable;
438    p_FmMacsecControllerDriver->f_FM_MACSEC_SetException                                    = MacsecSetException;
439}
440
441/****************************************/
442/*       Inter-Module functions         */
443/****************************************/
444
445void FmMacsecRegisterIntr(t_Handle                h_FmMacsec,
446                          e_FmMacsecEventModules  module,
447                          uint8_t                 modId,
448                          e_FmIntrType            intrType,
449                          void (*f_Isr) (t_Handle h_Arg, uint32_t id),
450                          t_Handle                h_Arg)
451{
452    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
453    uint8_t     event= 0;
454
455    SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
456
457    GET_MACSEC_MODULE_EVENT(module, modId, intrType, event);
458
459    ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
460    p_FmMacsec->intrMng[event].f_Isr = f_Isr;
461    p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg;
462}
463
464void FmMacsecUnregisterIntr(t_Handle                h_FmMacsec,
465                            e_FmMacsecEventModules  module,
466                            uint8_t                 modId,
467                            e_FmIntrType            intrType)
468{
469    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
470    uint8_t     event= 0;
471
472    SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
473
474    GET_MACSEC_MODULE_EVENT(module, modId,intrType, event);
475
476    ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
477    p_FmMacsec->intrMng[event].f_Isr = NULL;
478    p_FmMacsec->intrMng[event].h_SrcHandle = NULL;
479}
480
481t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds)
482{
483    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
484    t_Error     err = E_OK;
485    bool        *p_ScTable;
486    uint32_t    *p_ScAvailable,i;
487
488    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
489    SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
490    SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
491
492    if (type == e_SC_RX)
493    {
494        p_ScTable       = (bool *)p_FmMacsec->rxScTable;
495        p_ScAvailable   = &p_FmMacsec->numRxScAvailable;
496        i               = (NUM_OF_RX_SC - 1);
497    }
498    else
499    {
500        p_ScTable       = (bool *)p_FmMacsec->txScTable;
501        p_ScAvailable   = &p_FmMacsec->numTxScAvailable;
502        i               = (NUM_OF_TX_SC - 1);
503
504    }
505    if (*p_ScAvailable < numOfScs)
506        RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available"));
507
508    if (isPtp)
509    {
510        i = 0;
511        if (p_ScTable[i])
512            RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available"));
513    }
514
515    for (;numOfScs;i--)
516    {
517        if (p_ScTable[i])
518            continue;
519        numOfScs --;
520        (*p_ScAvailable)--;
521        p_ScIds[numOfScs] = i;
522        p_ScTable[i] = TRUE;
523    }
524
525    return err;
526}
527
528t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds)
529{
530    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
531    t_Error     err = E_OK;
532    bool        *p_ScTable;
533    uint32_t    *p_ScAvailable,maxNumOfSc,i;
534
535    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
536    SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
537    SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
538
539    if (type == e_SC_RX)
540    {
541        p_ScTable       = (bool *)p_FmMacsec->rxScTable;
542        p_ScAvailable   = &p_FmMacsec->numRxScAvailable;
543        maxNumOfSc      = NUM_OF_RX_SC;
544    }
545    else
546    {
547        p_ScTable       = (bool *)p_FmMacsec->txScTable;
548        p_ScAvailable   = &p_FmMacsec->numTxScAvailable;
549        maxNumOfSc      = NUM_OF_TX_SC;
550    }
551
552    if ((*p_ScAvailable + numOfScs) > maxNumOfSc)
553        RETURN_ERROR(MINOR, E_FULL, ("Too much SCs"));
554
555    for (i=0;i<numOfScs;i++)
556    {
557        p_ScTable[p_ScIds[i]] = FALSE;
558        (*p_ScAvailable)++;
559    }
560
561    return err;
562
563}
564
565t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable)
566{
567    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
568    uint32_t    tmpReg = 0;
569
570    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
571
572    tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
573    if (enable && (tmpReg & CFG_S0I))
574        RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode"));
575
576    if (enable)
577        tmpReg |= CFG_S0I;
578    else
579        tmpReg &= ~CFG_S0I;
580    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
581
582    return E_OK;
583}
584
585t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams)
586{
587    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
588    t_Error     err = E_OK;
589    uint32_t    tmpReg = 0, intFlags;
590
591    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
592    SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE);
593    SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
594
595    intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
596
597    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId);
598    tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg);
599    if (tmpReg & RX_SCCFG_SCI_EN_MASK)
600    {
601        XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
602        RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId));
603    }
604
605    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci));
606    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci));
607    tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK);
608    tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK);
609    tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK);
610    tmpReg |= RX_SCCFG_SCI_EN_MASK;
611    tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT);
612    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
613
614    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow);
615
616    XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
617
618    return err;
619}
620
621t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId)
622{
623    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
624    t_Error     err = E_OK;
625    uint32_t    tmpReg = 0, intFlags;
626
627    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
628    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
629
630    intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
631
632    tmpReg &= ~RX_SCCFG_SCI_EN_MASK;
633    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
634    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
635
636    XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
637
638    return err;
639}
640
641t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams)
642{
643    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
644    t_Error     err = E_OK;
645    uint32_t    tmpReg = 0, intFlags;
646    bool        alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE;
647
648    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
649    SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE);
650    SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
651
652    intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
653
654    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId);
655
656    tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
657    if (tmpReg & TX_SCCFG_SCE_MASK)
658    {
659        XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
660        RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId));
661    }
662
663    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci));
664    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci));
665    alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG);
666    useES            = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA);
667
668    tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK);
669    tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK);
670    tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK);
671    tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK);
672    tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK);
673    tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK);
674    tmpReg |= TX_SCCFG_SCE_MASK;
675    tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT);
676    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
677
678    XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
679
680    return err;
681}
682
683t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId)
684{
685    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
686    t_Error     err = E_OK;
687    uint32_t    tmpReg = 0, intFlags;
688
689    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
690    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
691
692    intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
693
694    tmpReg &= ~TX_SCCFG_SCE_MASK;
695    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
696    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
697
698    XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
699
700    return err;
701}
702
703t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
704{
705    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
706    t_Error     err = E_OK;
707    uint32_t    tmpReg = 0, intFlags;
708
709    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
710    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
711    SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
712
713    intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
714
715    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
716    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn);
717    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn);
718    MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t));
719
720    tmpReg |= RX_SACFG_ACTIVE;
721    tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK);
722    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
723
724    XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
725
726    return err;
727}
728
729t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key)
730{
731    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
732    t_Error     err = E_OK;
733    uint32_t    tmpReg = 0, intFlags;
734
735    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
736    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
737    SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
738
739    intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
740
741    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
742    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn);
743    MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t));
744
745    tmpReg |= TX_SACFG_ACTIVE;
746    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
747
748    XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
749
750    return err;
751}
752
753t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
754{
755    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
756    t_Error     err = E_OK;
757    uint32_t    tmpReg = 0, i, intFlags;
758
759    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
760    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
761    SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
762
763    intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
764
765    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
766    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0);
767    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0);
768    for (i=0; i<4; i++)
769        WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0);
770
771    tmpReg |= RX_SACFG_ACTIVE;
772    tmpReg &= ~RX_SACFG_EN_MASK;
773    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
774
775    XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
776
777    return err;
778}
779
780t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
781{
782    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
783    t_Error     err = E_OK;
784    uint32_t    tmpReg = 0, i, intFlags;
785
786    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
787    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
788    SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
789
790    intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
791
792    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
793    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0);
794    for (i=0; i<4; i++)
795        WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0);
796
797    tmpReg |= TX_SACFG_ACTIVE;
798    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
799
800    XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
801
802    return err;
803}
804
805t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive)
806{
807    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
808    t_Error     err = E_OK;
809    uint32_t    tmpReg = 0, intFlags;
810
811    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
812    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
813    SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
814
815    intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
816
817    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
818    tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs);
819    if (enableReceive)
820        tmpReg |= RX_SACFG_EN_MASK;
821    else
822        tmpReg &= ~RX_SACFG_EN_MASK;
823
824    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
825
826    XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
827
828    return err;
829}
830
831t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN)
832{
833    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
834    t_Error     err = E_OK;
835    uint32_t    intFlags;
836
837    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
838    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
839    SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
840
841    intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
842
843    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
844    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN);
845
846    XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
847
848    return err;
849}
850
851t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN)
852{
853    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
854    t_Error     err = E_OK;
855    uint32_t    intFlags;
856
857    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
858    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
859    SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
860
861    intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
862
863    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
864    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN);
865
866    XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
867
868    return err;
869}
870
871t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an)
872{
873    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
874    t_Error     err = E_OK;
875    uint32_t    tmpReg = 0, intFlags;
876
877    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
878    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
879    SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
880
881    intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
882
883    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
884
885    tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
886
887    tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK);
888    tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK);
889
890    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
891
892    XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
893
894    return err;
895}
896
897t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An)
898{
899    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
900    t_Error     err = E_OK;
901    uint32_t    tmpReg = 0, intFlags;
902
903    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
904    SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
905    SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
906
907    intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
908
909    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
910
911    tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
912
913    XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
914
915    *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT);
916
917    return err;
918}
919
920t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable)
921{
922    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
923    uint32_t    bitMask;
924
925    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
926    SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
927
928    GET_EXCEPTION_FLAG(bitMask, exception, scId);
929    if (bitMask)
930    {
931        if (enable)
932            p_FmMacsec->exceptions |= bitMask;
933        else
934            p_FmMacsec->exceptions &= ~bitMask;
935    }
936    else
937        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
938
939    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
940
941    return E_OK;
942}
943
944t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable)
945{
946    t_FmMacsec  *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
947    uint32_t    bitMask;
948
949    SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
950    SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
951
952    GET_EVENT_FLAG(bitMask, event, scId);
953    if (bitMask)
954    {
955        if (enable)
956            p_FmMacsec->events |= bitMask;
957        else
958            p_FmMacsec->events &= ~bitMask;
959    }
960    else
961        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
962
963    WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events);
964
965    return E_OK;
966}
967
968/****************************************/
969/*       API Init unit functions        */
970/****************************************/
971t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam)
972{
973    t_FmMacsec  *p_FmMacsec;
974    uint32_t    macId;
975
976    /* Allocate FM MACSEC structure */
977    p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec));
978    if (!p_FmMacsec)
979    {
980        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure"));
981        return NULL;
982    }
983    memset(p_FmMacsec, 0, sizeof(t_FmMacsec));
984    InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver);
985
986    /* Allocate the FM MACSEC driver's parameters structure */
987    p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam));
988    if (!p_FmMacsec->p_FmMacsecDriverParam)
989    {
990        XX_Free(p_FmMacsec);
991        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters"));
992        return NULL;
993    }
994    memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam));
995
996    /* Initialize FM MACSEC parameters which will be kept by the driver */
997    p_FmMacsec->h_Fm            = p_FmMacsecParam->h_Fm;
998    p_FmMacsec->h_FmMac         = p_FmMacsecParam->nonGuestParams.h_FmMac;
999    p_FmMacsec->p_FmMacsecRegs  = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr);
1000    p_FmMacsec->f_Exception     = p_FmMacsecParam->nonGuestParams.f_Exception;
1001    p_FmMacsec->h_App           = p_FmMacsecParam->nonGuestParams.h_App;
1002    p_FmMacsec->userExceptions  = DEFAULT_userExceptions;
1003    p_FmMacsec->exceptions      = DEFAULT_exceptions;
1004    p_FmMacsec->events          = DEFAULT_events;
1005    p_FmMacsec->rxScSpinLock    = XX_InitSpinlock();
1006    p_FmMacsec->txScSpinLock    = XX_InitSpinlock();
1007
1008    /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */
1009    p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode                           = DEFAULT_unknownSciFrameTreatment;
1010    p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled                = DEFAULT_invalidTagsFrameTreatment;
1011    p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled   = DEFAULT_encryptWithNoChangedTextFrameTreatment;
1012    p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode                                = DEFAULT_untagFrameTreatment;
1013    p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable                                = DEFAULT_keysUnreadable;
1014    p_FmMacsec->p_FmMacsecDriverParam->reservedSc0                                   = DEFAULT_sc0ReservedForPTP;
1015    p_FmMacsec->p_FmMacsecDriverParam->byPassMode                                    = !DEFAULT_normalMode;
1016    p_FmMacsec->p_FmMacsecDriverParam->pnExhThr                                      = DEFAULT_pnExhThr;
1017    p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead                                = DEFAULT_sectagOverhead;
1018    p_FmMacsec->p_FmMacsecDriverParam->mflSubtract                                   = DEFAULT_mflSubtract;
1019    /* build the FM MACSEC master IPC address */
1020    memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE);
1021    FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId);
1022    if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master",
1023        FmGetId(p_FmMacsec->h_Fm),macId) != 24)
1024    {
1025        XX_Free(p_FmMacsec->p_FmMacsecDriverParam);
1026        XX_Free(p_FmMacsec);
1027        REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
1028        return NULL;
1029    }
1030    return p_FmMacsec;
1031}
1032