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_secy.c
35 
36  @Description   FM MACSEC SECY 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 
45 #include "fm_macsec_secy.h"
46 
47 
48 /****************************************/
49 /*       static functions               */
50 /****************************************/
51 static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
52 {
53     t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
54 
55     UNUSED(id);
56     SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
57 
58     if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
59         p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED);
60 }
61 
62 static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
63 {
64     t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
65 
66     UNUSED(id);
67     SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
68 
69     if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
70         p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN);
71 }
72 
73 static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY)
74 {
75     if (!p_FmMacsecSecY->f_Exception)
76         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
77 
78     if (!p_FmMacsecSecY->f_Event)
79         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided"));
80 
81     if (!p_FmMacsecSecY->numOfRxSc)
82         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'"));
83 
84 
85     return E_OK;
86 }
87 
88 static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY             *p_FmMacsecSecY,
89                                      macsecSCI_t                sci,
90                                      e_FmMacsecSecYCipherSuite  cipherSuite,
91                                      e_ScType                   type)
92 {
93     t_SecYSc        *p_ScTable;
94     void            *p_Params;
95     uint32_t        numOfSc,i;
96     t_Error         err = E_OK;
97     t_RxScParams    rxScParams;
98     t_TxScParams    txScParams;
99 
100     ASSERT_COND(p_FmMacsecSecY);
101     ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
102 
103     if (type == e_SC_RX)
104     {
105         memset(&rxScParams, 0, sizeof(rxScParams));
106         i                                   = (NUM_OF_RX_SC - 1);
107         p_ScTable                           = p_FmMacsecSecY->p_RxSc;
108         numOfSc                             = p_FmMacsecSecY->numOfRxSc;
109         rxScParams.confidentialityOffset    = p_FmMacsecSecY->confidentialityOffset;
110         rxScParams.replayProtect            = p_FmMacsecSecY->replayProtect;
111         rxScParams.replayWindow             = p_FmMacsecSecY->replayWindow;
112         rxScParams.validateFrames           = p_FmMacsecSecY->validateFrames;
113         rxScParams.cipherSuite              = cipherSuite;
114         p_Params = &rxScParams;
115     }
116     else
117     {
118         memset(&txScParams, 0, sizeof(txScParams));
119         i                                   = (NUM_OF_TX_SC - 1);
120         p_ScTable                           = p_FmMacsecSecY->p_TxSc;
121         numOfSc                             = p_FmMacsecSecY->numOfTxSc;
122         txScParams.sciInsertionMode         = p_FmMacsecSecY->sciInsertionMode;
123         txScParams.protectFrames            = p_FmMacsecSecY->protectFrames;
124         txScParams.confidentialityEnable    = p_FmMacsecSecY->confidentialityEnable;
125         txScParams.confidentialityOffset    = p_FmMacsecSecY->confidentialityOffset;
126         txScParams.cipherSuite              = cipherSuite;
127         p_Params = &txScParams;
128     }
129 
130     for (i=0;i<numOfSc;i++)
131         if (!p_ScTable[i].inUse)
132             break;
133     if (i == numOfSc)
134     {
135         REPORT_ERROR(MAJOR, E_FULL, ("FM MACSEC SECY SC"));
136         return NULL;
137     }
138 
139     if (type == e_SC_RX)
140     {
141         ((t_RxScParams *)p_Params)->scId = p_ScTable[i].scId;
142         ((t_RxScParams *)p_Params)->sci  = sci;
143         if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK)
144         {
145             REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
146             return NULL;
147         }
148     }
149     else
150     {
151         ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId;
152         ((t_TxScParams *)p_Params)->sci  = sci;
153         if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK)
154         {
155             REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
156             return NULL;
157         }
158     }
159 
160     p_ScTable[i].inUse = TRUE;
161     return &p_ScTable[i];
162 }
163 
164 static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type)
165 {
166     t_Error         err = E_OK;
167 
168     ASSERT_COND(p_FmMacsecSecY);
169     ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
170     ASSERT_COND(p_FmSecYSc);
171 
172     if (type == e_SC_RX)
173     {
174         if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
175             RETURN_ERROR(MINOR, err, NO_MSG);
176     }
177     else
178         if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
179             RETURN_ERROR(MINOR, err, NO_MSG);
180 
181     p_FmSecYSc->inUse = FALSE;
182 
183     return err;
184 }
185 
186 /****************************************/
187 /*       API Init unit functions        */
188 /****************************************/
189 t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam)
190 {
191     t_FmMacsecSecY  *p_FmMacsecSecY;
192 
193     /* Allocate FM MACSEC structure */
194     p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY));
195     if (!p_FmMacsecSecY)
196     {
197         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure"));
198         return NULL;
199     }
200     memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY));
201 
202     /* Allocate the FM MACSEC driver's parameters structure */
203     p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam));
204     if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam)
205     {
206         XX_Free(p_FmMacsecSecY);
207         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters"));
208         return NULL;
209     }
210     memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam));
211 
212     /* Initialize FM MACSEC SECY parameters which will be kept by the driver */
213     p_FmMacsecSecY->h_FmMacsec              = p_FmMacsecSecYParam->h_FmMacsec;
214     p_FmMacsecSecY->f_Event                 = p_FmMacsecSecYParam->f_Event;
215     p_FmMacsecSecY->f_Exception             = p_FmMacsecSecYParam->f_Exception;
216     p_FmMacsecSecY->h_App                   = p_FmMacsecSecYParam->h_App;
217     p_FmMacsecSecY->confidentialityEnable   = DEFAULT_confidentialityEnable;
218     p_FmMacsecSecY->confidentialityOffset   = DEFAULT_confidentialityOffset;
219     p_FmMacsecSecY->validateFrames          = DEFAULT_validateFrames;
220     p_FmMacsecSecY->replayProtect           = DEFAULT_replayEnable;
221     p_FmMacsecSecY->replayWindow            = DEFAULT_replayWindow;
222     p_FmMacsecSecY->protectFrames           = DEFAULT_protectFrames;
223     p_FmMacsecSecY->sciInsertionMode        = DEFAULT_sciInsertionMode;
224     p_FmMacsecSecY->isPointToPoint          = DEFAULT_ptp;
225     p_FmMacsecSecY->numOfRxSc               = p_FmMacsecSecYParam->numReceiveChannels;
226     p_FmMacsecSecY->numOfTxSc               = DEFAULT_numOfTxSc;
227     p_FmMacsecSecY->exceptions              = DEFAULT_exceptions;
228     p_FmMacsecSecY->events                  = DEFAULT_events;
229 
230     memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams,
231            &p_FmMacsecSecYParam->txScParams,
232            sizeof(t_FmMacsecSecYSCParams));
233     return p_FmMacsecSecY;
234 }
235 
236 t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY)
237 {
238     t_FmMacsecSecY              *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
239     t_FmMacsecSecYDriverParam   *p_FmMacsecSecYDriverParam = NULL;
240     uint32_t                    rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j;
241     t_Error                     err;
242 
243     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
244     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE);
245 
246     CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters);
247 
248     p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam;
249 
250     if ((p_FmMacsecSecY->isPointToPoint) &&
251         ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK))
252         RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point"));
253 
254     /* Rx Sc Allocation */
255     p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
256     if (!p_FmMacsecSecY->p_RxSc)
257         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
258     memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
259     if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
260     {
261         if (p_FmMacsecSecY->p_TxSc)
262             XX_Free(p_FmMacsecSecY->p_TxSc);
263         if (p_FmMacsecSecY->p_RxSc)
264             XX_Free(p_FmMacsecSecY->p_RxSc);
265         return ERROR_CODE(err);
266     }
267     for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
268     {
269         p_FmMacsecSecY->p_RxSc[i].scId  = rxScIds[i];
270         p_FmMacsecSecY->p_RxSc[i].type  = e_SC_RX;
271         for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
272             p_FmMacsecSecY->p_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
273     }
274 
275     /* Tx Sc Allocation */
276     p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
277     if (!p_FmMacsecSecY->p_TxSc)
278         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
279     memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
280 
281     if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
282     {
283         if (p_FmMacsecSecY->p_TxSc)
284             XX_Free(p_FmMacsecSecY->p_TxSc);
285         if (p_FmMacsecSecY->p_RxSc)
286             XX_Free(p_FmMacsecSecY->p_RxSc);
287         return ERROR_CODE(err);
288     }
289     for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++)
290     {
291         p_FmMacsecSecY->p_TxSc[i].scId  = txScIds[i];
292         p_FmMacsecSecY->p_TxSc[i].type  = e_SC_TX;
293         for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
294             p_FmMacsecSecY->p_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
295         FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
296                              e_FM_MACSEC_MOD_SC_TX,
297                              (uint8_t)txScIds[i],
298                              e_FM_INTR_TYPE_ERR,
299                              FmMacsecSecYExceptionsIsr,
300                              p_FmMacsecSecY);
301         FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
302                              e_FM_MACSEC_MOD_SC_TX,
303                              (uint8_t)txScIds[i],
304                              e_FM_INTR_TYPE_NORMAL,
305                              FmMacsecSecYEventsIsr,
306                              p_FmMacsecSecY);
307 
308         if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
309             FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE);
310         if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
311             FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE);
312     }
313 
314     FmMacsecSecYCreateSc(p_FmMacsecSecY,
315                          p_FmMacsecSecYDriverParam->txScParams.sci,
316                          p_FmMacsecSecYDriverParam->txScParams.cipherSuite,
317                          e_SC_TX);
318     XX_Free(p_FmMacsecSecYDriverParam);
319     p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL;
320 
321     return E_OK;
322 }
323 
324 t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY)
325 {
326     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
327     t_Error         err             = E_OK;
328     uint32_t        rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i;
329 
330     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
331     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
332 
333     if (p_FmMacsecSecY->isPointToPoint)
334         FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE);
335     if (p_FmMacsecSecY->p_RxSc)
336     {
337         for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
338             rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId;
339         if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
340             return ERROR_CODE(err);
341         XX_Free(p_FmMacsecSecY->p_RxSc);
342     }
343     if (p_FmMacsecSecY->p_TxSc)
344     {
345        FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX);
346 
347        for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++) {
348              txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId;
349             FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
350                                  e_FM_MACSEC_MOD_SC_TX,
351                                  (uint8_t)txScIds[i],
352                                  e_FM_INTR_TYPE_ERR);
353             FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
354                                  e_FM_MACSEC_MOD_SC_TX,
355                                  (uint8_t)txScIds[i],
356                                  e_FM_INTR_TYPE_NORMAL);
357 
358             if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
359                 FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE);
360             if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
361                 FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE);
362        }
363 
364         if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
365             return ERROR_CODE(err);
366         XX_Free(p_FmMacsecSecY->p_TxSc);
367     }
368 
369     XX_Free(p_FmMacsecSecY);
370 
371     return err;
372 }
373 
374 t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode)
375 {
376     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
377 
378     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
379     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
380 
381     p_FmMacsecSecY->sciInsertionMode = sciInsertionMode;
382 
383     return E_OK;
384 }
385 
386 t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames)
387 {
388     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
389 
390     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
391     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
392 
393     p_FmMacsecSecY->protectFrames = protectFrames;
394 
395     return E_OK;
396 }
397 
398 t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow)
399 {
400     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
401 
402     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
403     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
404 
405     p_FmMacsecSecY->replayProtect   = replayProtect;
406     p_FmMacsecSecY->replayWindow    = replayWindow;
407 
408     return E_OK;
409 }
410 
411 t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames)
412 {
413     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
414 
415     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
416     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
417 
418     p_FmMacsecSecY->validateFrames = validateFrames;
419 
420     return E_OK;
421 }
422 
423 t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset)
424 {
425     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
426 
427     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
428     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
429 
430     p_FmMacsecSecY->confidentialityEnable = confidentialityEnable;
431     p_FmMacsecSecY->confidentialityOffset = confidentialityOffset;
432 
433     return E_OK;
434 }
435 
436 t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY)
437 {
438     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
439 
440     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
441     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
442 
443     p_FmMacsecSecY->numOfRxSc = 1;
444     p_FmMacsecSecY->isPointToPoint = TRUE;
445     p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP;
446 
447     return E_OK;
448 }
449 
450 t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable)
451 {
452     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
453     uint32_t        bitMask         = 0;
454 
455     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
456     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
457 
458     GET_EXCEPTION_FLAG(bitMask, exception);
459     if (bitMask)
460     {
461         if (enable)
462             p_FmMacsecSecY->exceptions |= bitMask;
463         else
464             p_FmMacsecSecY->exceptions &= ~bitMask;
465     }
466     else
467         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
468 
469     return E_OK;
470 }
471 
472 t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
473 {
474     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
475     uint32_t        bitMask         = 0;
476 
477     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
478     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
479 
480     GET_EVENT_FLAG(bitMask, event);
481     if (bitMask)
482     {
483         if (enable)
484             p_FmMacsecSecY->events |= bitMask;
485         else
486             p_FmMacsecSecY->events &= ~bitMask;
487     }
488     else
489         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
490 
491     return E_OK;
492 }
493 
494 t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams)
495 {
496     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
497 
498     SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
499     SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
500     SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL);
501     SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
502 
503     return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX);
504 }
505 
506 t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
507 {
508     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
509     t_SecYSc        *p_FmSecYSc     = (t_SecYSc *)h_Sc;
510 
511     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
512     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
513     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
514     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
515 
516     return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX);
517 }
518 
519 t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
520 {
521     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
522     t_SecYSc        *p_FmSecYSc     = (t_SecYSc *)h_Sc;
523     t_Error         err = E_OK;
524 
525     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
526     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
527     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
528     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
529     SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
530 
531     if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
532         RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an));
533 
534     if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK)
535         RETURN_ERROR(MINOR, err, NO_MSG);
536 
537     p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
538     return err;
539 }
540 
541 t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
542 {
543     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
544     t_SecYSc        *p_FmSecYSc     = (t_SecYSc *)h_Sc;
545     t_Error         err             = E_OK;
546 
547     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
548     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
549     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
550     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
551     SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
552 
553     if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
554         RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
555 
556     if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
557         RETURN_ERROR(MINOR, err, NO_MSG);
558 
559     p_FmSecYSc->numOfSa--;
560     p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
561     /* TODO - check if statistics need to be read*/
562     return err;
563 }
564 
565 t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
566 {
567     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
568     t_SecYSc        *p_FmSecYSc     = (t_SecYSc *)h_Sc;
569     t_Error         err = E_OK;
570 
571     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
572     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
573     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
574     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
575     SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
576 
577     if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
578         RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
579 
580     if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
581         RETURN_ERROR(MINOR, err, NO_MSG);
582 
583     p_FmSecYSc->sa[an].active = TRUE;
584     return err;
585 }
586 
587 t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
588 {
589     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
590     t_SecYSc        *p_FmSecYSc     = (t_SecYSc *)h_Sc;
591     t_Error         err = E_OK;
592 
593     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
594     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
595     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
596     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
597     SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
598 
599     if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
600         RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
601 
602     if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
603         RETURN_ERROR(MINOR, err, NO_MSG);
604 
605     p_FmSecYSc->sa[an].active = FALSE;
606     return err;
607 }
608 
609 t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN)
610 {
611     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
612     t_SecYSc        *p_FmSecYSc     = (t_SecYSc *)h_Sc;
613     t_Error         err = E_OK;
614 
615     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
616     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
617     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
618     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
619     SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
620 
621     if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
622         RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
623 
624     if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK)
625         RETURN_ERROR(MINOR, err, NO_MSG);
626 
627     return err;
628 }
629 
630 t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN)
631 {
632     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
633     t_SecYSc        *p_FmSecYSc     = (t_SecYSc *)h_Sc;
634     t_Error         err = E_OK;
635 
636     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
637     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
638     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
639     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
640     SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
641 
642     if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
643         RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
644 
645     if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK)
646         RETURN_ERROR(MINOR, err, NO_MSG);
647 
648     return err;
649 }
650 
651 t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key)
652 {
653     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
654     t_SecYSc        *p_FmSecYSc     = (t_SecYSc *)h_Sc;
655     t_Error         err = E_OK;
656 
657     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
658     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
659     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
660     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
661     SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
662 
663     if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
664         RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
665 
666     if (p_FmSecYSc->sa[an].active)
667         if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
668             RETURN_ERROR(MINOR, err, NO_MSG);
669 
670     /* TODO - statistics should be read */
671 
672     if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK)
673         RETURN_ERROR(MINOR, err, NO_MSG);
674 
675     if (p_FmSecYSc->sa[an].active)
676         if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
677             RETURN_ERROR(MINOR, err, NO_MSG);
678     return err;
679 }
680 
681 
682 t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key)
683 {
684     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
685     t_SecYSc        *p_FmSecYSc;
686     t_Error         err = E_OK;
687 
688     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
689     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
690     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
691     p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
692     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
693     SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
694 
695     if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
696         RETURN_ERROR(MINOR, err, ("An %d is already assigned",an));
697 
698     if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK)
699         RETURN_ERROR(MINOR, err, NO_MSG);
700 
701     p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
702     return err;
703 }
704 
705 t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an)
706 {
707     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
708     t_SecYSc        *p_FmSecYSc;
709     t_Error         err = E_OK;
710 
711     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
712     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
713     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
714     p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
715     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
716     SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
717 
718     if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
719         RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
720 
721     if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
722         RETURN_ERROR(MINOR, err, NO_MSG);
723 
724     p_FmSecYSc->numOfSa--;
725     p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
726     /* TODO - check if statistics need to be read*/
727     return err;
728 }
729 
730 t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key)
731 {
732     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
733     t_SecYSc        *p_FmSecYSc;
734     macsecAN_t      currentAn;
735     t_Error         err = E_OK;
736 
737     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
738     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
739     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
740     p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
741     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
742     SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
743 
744     if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
745                                      p_FmSecYSc->scId,
746                                      &currentAn)) != E_OK)
747         RETURN_ERROR(MINOR, err, NO_MSG);
748 
749     if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
750                                      p_FmSecYSc->scId,
751                                      p_FmSecYSc->sa[nextActiveAn].saId,
752                                      nextActiveAn)) != E_OK)
753         RETURN_ERROR(MINOR, err, NO_MSG);
754 
755     /* TODO - statistics should be read */
756 
757     if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK)
758         RETURN_ERROR(MINOR, err, NO_MSG);
759 
760     return err;
761 }
762 
763 t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an)
764 {
765     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
766     t_SecYSc        *p_FmSecYSc;
767     t_Error         err = E_OK;
768 
769     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
770     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
771     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
772     p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
773     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
774     SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
775 
776     if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
777         RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
778 
779     if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
780                                      p_FmSecYSc->scId,
781                                      p_FmSecYSc->sa[an].saId,
782                                      an)) != E_OK)
783         RETURN_ERROR(MINOR, err, NO_MSG);
784 
785     return err;
786 }
787 
788 t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An)
789 {
790     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
791     t_SecYSc        *p_FmSecYSc;
792     t_Error         err = E_OK;
793 
794     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
795     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
796     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
797     p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
798     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
799     SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
800 
801     if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
802                                      p_FmSecYSc->scId,
803                                      p_An)) != E_OK)
804         RETURN_ERROR(MINOR, err, NO_MSG);
805 
806     return err;
807 }
808 
809 t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId)
810 {
811     t_SecYSc        *p_FmSecYSc = (t_SecYSc *)h_Sc;
812     t_Error         err = E_OK;
813 
814     SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE);
815     SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE);
816     SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
817     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
818 #ifdef DISABLE_SANITY_CHECKS
819     UNUSED(h_FmMacsecSecY);
820 #endif /* DISABLE_SANITY_CHECKS */
821 
822     *p_ScPhysId = p_FmSecYSc->scId;
823     return err;
824 }
825 
826 t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId)
827 {
828     t_FmMacsecSecY  *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
829     t_SecYSc        *p_FmSecYSc;
830     t_Error         err = E_OK;
831 
832     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
833     SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
834     SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
835     p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
836     SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
837 
838     *p_ScPhysId = p_FmSecYSc->scId;
839     return err;
840 }
841 
842 t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable)
843 {
844    UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable);
845    RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
846 }
847 
848 t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
849 {
850     UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable);
851     RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
852 }
853 
854 t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics)
855 {
856     UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
857     RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
858 }
859 
860 t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics)
861 {
862     UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics);
863     RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
864 }
865 
866 t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics)
867 {
868     UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics);
869     RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
870 }
871 
872 t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics)
873 {
874     UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
875     RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
876 }
877 
878 t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics)
879 {
880     UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics);
881     RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
882 }
883 
884