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 
49 extern uint16_t    FM_MAC_GetMaxFrameLength(t_Handle FmMac);
50 
51 
52 /****************************************/
53 /*       static functions               */
54 /****************************************/
55 static 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 
63 static 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 
70 static 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 
89 static 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 
125 static 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 
191 static 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 
220 static 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 
232 static 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 
244 static 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 
256 static 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 
268 static 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 
280 static 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 
292 static 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 
304 static 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 
316 static 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 
329 static 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 
351 static 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 
363 static 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 
378 static 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 
393 static 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 
421 static 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 
445 void 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 
464 void 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 
481 t_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 
528 t_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 
565 t_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 
585 t_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 
621 t_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 
641 t_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 
683 t_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 
703 t_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 
729 t_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 
753 t_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 
780 t_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 
805 t_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 
831 t_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 
851 t_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 
871 t_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 
897 t_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 
920 t_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 
944 t_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 /****************************************/
971 t_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