1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 /**************************************************************************/
12 /**************************************************************************/
13 /**                                                                       */
14 /** NetX Component                                                        */
15 /**                                                                       */
16 /**   TSN shaper                                                          */
17 /**                                                                       */
18 /**************************************************************************/
19 /**************************************************************************/
20 
21 /* Include necessary system files.  */
22 #include "nx_shaper.h"
23 #include "nx_link.h"
24 
25 #ifdef NX_ENABLE_VLAN
26 /**************************************************************************/
27 /*                                                                        */
28 /*  FUNCTION                                               RELEASE        */
29 /*                                                                        */
30 /*    nx_shaper_create                                    PORTABLE C      */
31 /*                                                           6.4.0        */
32 /*  AUTHOR                                                                */
33 /*                                                                        */
34 /*    Yajun Xia, Microsoft Corporation                                    */
35 /*                                                                        */
36 /*  DESCRIPTION                                                           */
37 /*                                                                        */
38 /*    This function creates shaper in shaper container, and connects the  */
39 /*    shaper container with interface instance.                           */
40 /*                                                                        */
41 /*  INPUT                                                                 */
42 /*                                                                        */
43 /*    interface_ptr                         Pointer to interface instance */
44 /*    shaper_container                      Pinter to Shaper container    */
45 /*    shaper                                Pinter to Shaper              */
46 /*    shaper_type                           Shaper type                   */
47 /*    shaper_driver                         Driver entry of shaper        */
48 /*                                                                        */
49 /*  OUTPUT                                                                */
50 /*                                                                        */
51 /*    status                                Completion status             */
52 /*                                                                        */
53 /*  CALLS                                                                 */
54 /*                                                                        */
55 /*    None                                                                */
56 /*                                                                        */
57 /*  CALLED BY                                                             */
58 /*                                                                        */
59 /*    Application Code                                                    */
60 /*                                                                        */
61 /*  RELEASE HISTORY                                                       */
62 /*                                                                        */
63 /*    DATE              NAME                      DESCRIPTION             */
64 /*                                                                        */
65 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
66 /*                                                                        */
67 /**************************************************************************/
nx_shaper_create(NX_INTERFACE * interface_ptr,NX_SHAPER_CONTAINER * shaper_container,NX_SHAPER * shaper,UCHAR shaper_type,NX_SHAPER_DRIVER shaper_driver)68 UINT nx_shaper_create(NX_INTERFACE *interface_ptr,
69                       NX_SHAPER_CONTAINER *shaper_container,
70                       NX_SHAPER *shaper,
71                       UCHAR shaper_type,
72                       NX_SHAPER_DRIVER shaper_driver)
73 {
74 UINT                       i;
75 UINT                       status;
76 NX_SHAPER_DRIVER_PARAMETER driver_request;
77 
78     if ((interface_ptr == NX_NULL) ||
79         (shaper_container == NX_NULL) ||
80         (shaper == NX_NULL) ||
81         (shaper_type >= NX_SHAPER_TYPE_MAX) ||
82         (shaper_driver == NX_NULL))
83     {
84         return(NX_INVALID_PARAMETERS);
85     }
86 
87     if (shaper_container -> shaper_number >= NX_SHAPER_NUMBERS)
88     {
89         return(NX_NO_MORE_ENTRIES);
90     }
91 
92     for (i = 0; i < NX_SHAPER_NUMBERS; i++)
93     {
94         if (shaper_container -> shaper[i] == NX_NULL)
95         {
96             shaper_container -> shaper[i] = shaper;
97             shaper_container -> shaper[i] -> shaper_type = shaper_type;
98             shaper_container -> shaper[i] -> shaper_driver = shaper_driver;
99 
100             break;
101         }
102         shaper_container -> shaper_number++;
103     }
104 
105     if (i >= NX_SHAPER_NUMBERS)
106     {
107         return(NX_NO_MORE_ENTRIES);
108     }
109 
110     /* Bind the shaper_container with interface. */
111     if (interface_ptr -> shaper_container == NX_NULL)
112     {
113         interface_ptr -> shaper_container = shaper_container;
114     }
115 
116     /* Init process */
117     driver_request.nx_shaper_driver_command = NX_SHAPER_COMMAND_INIT;
118     driver_request.shaper_type = interface_ptr -> shaper_container -> shaper[i] -> shaper_type;
119     driver_request.nx_ip_driver_interface = interface_ptr;
120     driver_request.shaper_parameter = NX_NULL;
121 
122     status = interface_ptr -> shaper_container -> shaper[i] -> shaper_driver(&driver_request);
123     if (status != NX_SUCCESS)
124     {
125         return(status);
126     }
127 
128     /* Config process */
129     driver_request.nx_shaper_driver_command = NX_SHAPER_COMMAND_CONFIG;
130     driver_request.shaper_type = 0; /* not used in driver */
131     driver_request.nx_ip_driver_interface = interface_ptr;
132     driver_request.shaper_parameter = NX_NULL;
133 
134     status = interface_ptr -> shaper_container -> shaper[i] -> shaper_driver(&driver_request);
135 
136     return(status);
137 }
138 
139 /**************************************************************************/
140 /*                                                                        */
141 /*  FUNCTION                                               RELEASE        */
142 /*                                                                        */
143 /*    nx_shaper_delete                                    PORTABLE C      */
144 /*                                                           6.4.0        */
145 /*  AUTHOR                                                                */
146 /*                                                                        */
147 /*    Yajun Xia, Microsoft Corporation                                    */
148 /*                                                                        */
149 /*  DESCRIPTION                                                           */
150 /*                                                                        */
151 /*    This function deletes a shaper from interface instance, unlink the  */
152 /*    shaper container with IP interface when there is no shaper exists.  */
153 /*                                                                        */
154 /*  INPUT                                                                 */
155 /*                                                                        */
156 /*    interface_ptr                         Pointer to interface instance */
157 /*    shaper                                Pinter to Shaper              */
158 /*                                                                        */
159 /*  OUTPUT                                                                */
160 /*                                                                        */
161 /*    status                                Completion status             */
162 /*                                                                        */
163 /*  CALLS                                                                 */
164 /*                                                                        */
165 /*    None                                                                */
166 /*                                                                        */
167 /*  CALLED BY                                                             */
168 /*                                                                        */
169 /*    Application Code                                                    */
170 /*                                                                        */
171 /*  RELEASE HISTORY                                                       */
172 /*                                                                        */
173 /*    DATE              NAME                      DESCRIPTION             */
174 /*                                                                        */
175 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
176 /*                                                                        */
177 /**************************************************************************/
nx_shaper_delete(NX_INTERFACE * interface_ptr,NX_SHAPER * shaper)178 UINT nx_shaper_delete(NX_INTERFACE *interface_ptr, NX_SHAPER *shaper)
179 {
180 UINT i;
181 
182     if (interface_ptr == NX_NULL)
183     {
184         return(NX_INVALID_PARAMETERS);
185     }
186 
187     if (interface_ptr -> shaper_container == NX_NULL)
188     {
189 
190         /* None shaper existed. */
191         return(NX_SUCCESS);
192     }
193 
194     for (i = 0; i < NX_SHAPER_NUMBERS; i++)
195     {
196         if (interface_ptr -> shaper_container -> shaper[i] == shaper)
197         {
198             interface_ptr -> shaper_container -> shaper[i] = NX_NULL;
199             interface_ptr -> shaper_container -> shaper_number--;
200             break;
201         }
202     }
203 
204     if (i >= NX_SHAPER_NUMBERS)
205     {
206         return(NX_ENTRY_NOT_FOUND);
207     }
208 
209     if (interface_ptr -> shaper_container -> shaper_number == 0)
210     {
211 
212         /* No shaper existed, delete the shaper_container. */
213         interface_ptr -> shaper_container = NX_NULL;
214     }
215 
216     return(NX_SUCCESS);
217 }
218 
219 /**************************************************************************/
220 /*                                                                        */
221 /*  FUNCTION                                               RELEASE        */
222 /*                                                                        */
223 /*    nx_shaper_config                                    PORTABLE C      */
224 /*                                                           6.4.0        */
225 /*  AUTHOR                                                                */
226 /*                                                                        */
227 /*    Yajun Xia, Microsoft Corporation                                    */
228 /*                                                                        */
229 /*  DESCRIPTION                                                           */
230 /*                                                                        */
231 /*    This function configures the hardware parameters of shaper by       */
232 /*    network driver.                                                     */
233 /*                                                                        */
234 /*  INPUT                                                                 */
235 /*                                                                        */
236 /*    interface_ptr                         Pointer to interface instance */
237 /*    port_rate                             Port rate                     */
238 /*    shaper_capability                     Capability of shaper          */
239 /*    hw_queue_number                       Number of HW queues           */
240 /*    hw_queue                              Pointer to HW queue list      */
241 /*                                                                        */
242 /*  OUTPUT                                                                */
243 /*                                                                        */
244 /*    status                                Completion status             */
245 /*                                                                        */
246 /*  CALLS                                                                 */
247 /*                                                                        */
248 /*    nx_shaper_hw_queue_set                Set HW queue info             */
249 /*                                                                        */
250 /*  CALLED BY                                                             */
251 /*                                                                        */
252 /*    Network driver                                                      */
253 /*                                                                        */
254 /*  RELEASE HISTORY                                                       */
255 /*                                                                        */
256 /*    DATE              NAME                      DESCRIPTION             */
257 /*                                                                        */
258 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
259 /*                                                                        */
260 /**************************************************************************/
nx_shaper_config(NX_INTERFACE * interface_ptr,UINT port_rate,UCHAR shaper_capability,UCHAR hw_queue_number,NX_SHAPER_HW_QUEUE * hw_queue)261 UINT nx_shaper_config(NX_INTERFACE *interface_ptr,
262                       UINT port_rate,
263                       UCHAR shaper_capability,
264                       UCHAR hw_queue_number,
265                       NX_SHAPER_HW_QUEUE *hw_queue)
266 {
267 INT  i;
268 UINT status;
269 
270     interface_ptr -> shaper_container -> port_rate = port_rate;
271     interface_ptr -> shaper_container -> shaper_capability |= shaper_capability;
272     interface_ptr -> shaper_container -> hw_queue_number = hw_queue_number;
273     for (i = 0; i < hw_queue_number; i++)
274     {
275         status = nx_shaper_hw_queue_set(interface_ptr, hw_queue[i].hw_queue_id, hw_queue[i].priority, hw_queue[i].type);
276         if (status != NX_SUCCESS)
277         {
278             return(status);
279         }
280     }
281 
282     return(NX_SUCCESS);
283 }
284 
285 /**************************************************************************/
286 /*                                                                        */
287 /*  FUNCTION                                               RELEASE        */
288 /*                                                                        */
289 /*    nx_shaper_hw_queue_set                              PORTABLE C      */
290 /*                                                           6.4.0        */
291 /*  AUTHOR                                                                */
292 /*                                                                        */
293 /*    Yajun Xia, Microsoft Corporation                                    */
294 /*                                                                        */
295 /*  DESCRIPTION                                                           */
296 /*                                                                        */
297 /*    This function configures the hardware queue of shaper.              */
298 /*                                                                        */
299 /*  INPUT                                                                 */
300 /*                                                                        */
301 /*    interface_ptr                         Pointer to interface instance */
302 /*    hw_queue_id                           HW queue id                   */
303 /*    priority                              HW queue priority             */
304 /*    type                                  HW queue type                 */
305 /*                                                                        */
306 /*  OUTPUT                                                                */
307 /*                                                                        */
308 /*    status                                Completion status             */
309 /*                                                                        */
310 /*  CALLS                                                                 */
311 /*                                                                        */
312 /*    None                                                                */
313 /*                                                                        */
314 /*  CALLED BY                                                             */
315 /*                                                                        */
316 /*    nx_shaper_config                      Config the shaper HW params   */
317 /*                                                                        */
318 /*  RELEASE HISTORY                                                       */
319 /*                                                                        */
320 /*    DATE              NAME                      DESCRIPTION             */
321 /*                                                                        */
322 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
323 /*                                                                        */
324 /**************************************************************************/
nx_shaper_hw_queue_set(NX_INTERFACE * interface_ptr,UCHAR hw_queue_id,UCHAR priority,UCHAR type)325 UINT nx_shaper_hw_queue_set(NX_INTERFACE *interface_ptr, UCHAR hw_queue_id, UCHAR priority, UCHAR type)
326 {
327 UCHAR i, insert_id;
328 
329     if (interface_ptr -> shaper_container == NX_NULL)
330     {
331         return(NX_NOT_SUPPORTED);
332     }
333 
334     for (i = 0; i < interface_ptr -> shaper_container -> hw_queue_number; i++)
335     {
336 
337         /* If the hw queue is already configured, we should avoid the double config. */
338         if ((interface_ptr -> shaper_container -> hw_queue[i].hw_queue_id == hw_queue_id) &&
339             (interface_ptr -> shaper_container -> hw_queue[i].type != NX_SHAPER_HW_QUEUE_NONE))
340         {
341             if (interface_ptr -> shaper_container -> hw_queue[i].priority != priority)
342             {
343                 return(NX_INVALID_PARAMETERS);
344             }
345             else
346             {
347                 interface_ptr -> shaper_container -> hw_queue[i].type |= type;
348                 return(NX_SUCCESS);
349             }
350         }
351     }
352 
353     /* The queue is not configured, insert the queue to the queue list and sort. */
354     for (i = 0; i < interface_ptr -> shaper_container -> hw_queue_number; i++)
355     {
356         if (interface_ptr -> shaper_container -> hw_queue[i].type == NX_SHAPER_HW_QUEUE_NONE)
357         {
358             /* find the first unused place to insert */
359             break;
360         }
361 
362         if (interface_ptr -> shaper_container -> hw_queue[i].priority > priority)
363         {
364             /* find the first place to insert */
365             break;
366         }
367     }
368 
369     if (i == interface_ptr -> shaper_container -> hw_queue_number)
370     {
371         return(NX_NOT_SUCCESSFUL);
372     }
373 
374     insert_id = i;
375     for (i = (UCHAR)(interface_ptr -> shaper_container -> hw_queue_number - 1); i > insert_id; i--)
376     {
377         memcpy(&interface_ptr -> shaper_container -> hw_queue[i], &interface_ptr -> shaper_container -> hw_queue[i - 1],
378                sizeof(struct NX_SHAPER_HW_QUEUE_STRUCT)); /* use case of memcpy is verified. */
379     }
380 
381     interface_ptr -> shaper_container -> hw_queue[insert_id].hw_queue_id = hw_queue_id;
382     interface_ptr -> shaper_container -> hw_queue[insert_id].priority = priority;
383     interface_ptr -> shaper_container -> hw_queue[insert_id].type = type;
384 
385     return(NX_SUCCESS);
386 }
387 
388 /**************************************************************************/
389 /*                                                                        */
390 /*  FUNCTION                                               RELEASE        */
391 /*                                                                        */
392 /*    nx_shaper_default_mapping_get                       PORTABLE C      */
393 /*                                                           6.4.0        */
394 /*  AUTHOR                                                                */
395 /*                                                                        */
396 /*    Yajun Xia, Microsoft Corporation                                    */
397 /*                                                                        */
398 /*  DESCRIPTION                                                           */
399 /*                                                                        */
400 /*    This function gets the default pcp to HW queue mapping config.      */
401 /*                                                                        */
402 /*  INPUT                                                                 */
403 /*                                                                        */
404 /*    interface_ptr                         Pointer to interface instance */
405 /*    pcp_list                              Pointer to PCP list           */
406 /*    queue_id_list                         Pointer to Queue id list      */
407 /*    list_size                             Size of PCP list              */
408 /*                                                                        */
409 /*  OUTPUT                                                                */
410 /*                                                                        */
411 /*    status                                Completion status             */
412 /*                                                                        */
413 /*  CALLS                                                                 */
414 /*                                                                        */
415 /*    nx_shaper_hw_cbs_queue_number_get     Get number of CBS HW queue    */
416 /*                                                                        */
417 /*  CALLED BY                                                             */
418 /*                                                                        */
419 /*    Application Code                                                    */
420 /*                                                                        */
421 /*  RELEASE HISTORY                                                       */
422 /*                                                                        */
423 /*    DATE              NAME                      DESCRIPTION             */
424 /*                                                                        */
425 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
426 /*                                                                        */
427 /**************************************************************************/
nx_shaper_default_mapping_get(NX_INTERFACE * interface_ptr,UCHAR * pcp_list,UCHAR * queue_id_list,UCHAR list_size)428 UINT nx_shaper_default_mapping_get(NX_INTERFACE *interface_ptr, UCHAR *pcp_list, UCHAR *queue_id_list, UCHAR list_size)
429 {
430 UCHAR index = (UCHAR)(interface_ptr -> shaper_container -> hw_queue_number - 1);
431 UCHAR item_number = 0;
432 UCHAR hw_cbs_queue_number;
433 
434     if (interface_ptr -> shaper_container == NX_NULL)
435     {
436         return(NX_NOT_SUPPORTED);
437     }
438 
439     if (list_size != NX_SHAPER_MAPPING_LIST_SIZE)
440     {
441         return(NX_INVALID_PARAMETERS);
442     }
443 
444     memset(pcp_list, 0, list_size);
445     memset(queue_id_list, 0, list_size);
446 
447     if (nx_shaper_hw_cbs_queue_number_get(interface_ptr, &hw_cbs_queue_number) != NX_SUCCESS)
448     {
449         return(NX_NOT_SUPPORTED);
450     }
451 
452     if (hw_cbs_queue_number == 0)
453     {
454         /* no default config for this case */
455         return(NX_NOT_SUPPORTED);
456     }
457 
458     if ((hw_cbs_queue_number == 1) ||
459         ((hw_cbs_queue_number == 2) &&
460          (interface_ptr -> shaper_container -> hw_queue_number == 2)))
461     {
462         pcp_list[item_number] = NX_SHAPER_CLASS_B_PCP;
463         queue_id_list[item_number++] = index--;
464         switch (interface_ptr -> shaper_container -> hw_queue_number)
465         {
466         case 2:
467             /* nothing need to do */
468             break;
469 
470         case 3:
471             pcp_list[item_number] = 7;
472             queue_id_list[item_number++] = index;
473             pcp_list[item_number] = 6;
474             queue_id_list[item_number++] = index;
475             pcp_list[item_number] = 5;
476             queue_id_list[item_number++] = index;
477             pcp_list[item_number] = 4;
478             queue_id_list[item_number++] = index;
479             break;
480 
481         case 4:
482             pcp_list[item_number] = 7;
483             queue_id_list[item_number++] = index;
484             pcp_list[item_number] = 6;
485             queue_id_list[item_number++] = index--;
486             pcp_list[item_number] = 5;
487             queue_id_list[item_number++] = index;
488             pcp_list[item_number] = 4;
489             queue_id_list[item_number++] = index;
490             break;
491 
492         case 5:
493             pcp_list[item_number] = 7;
494             queue_id_list[item_number++] = index;
495             pcp_list[item_number] = 6;
496             queue_id_list[item_number++] = index--;
497             pcp_list[item_number] = 5;
498             queue_id_list[item_number++] = index;
499             pcp_list[item_number] = 4;
500             queue_id_list[item_number++] = index--;
501             pcp_list[item_number] = 3;
502             queue_id_list[item_number++] = index;
503             break;
504 
505         case 6:
506             pcp_list[item_number] = 7;
507             queue_id_list[item_number++] = index--;
508             pcp_list[item_number] = 6;
509             queue_id_list[item_number++] = index--;
510             pcp_list[item_number] = 5;
511             queue_id_list[item_number++] = index;
512             pcp_list[item_number] = 4;
513             queue_id_list[item_number++] = index--;
514             pcp_list[item_number] = 3;
515             queue_id_list[item_number++] = index;
516             break;
517         case 7:
518             pcp_list[item_number] = 7;
519             queue_id_list[item_number++] = index--;
520             pcp_list[item_number] = 6;
521             queue_id_list[item_number++] = index--;
522             pcp_list[item_number] = 5;
523             queue_id_list[item_number++] = index;
524             pcp_list[item_number] = 4;
525             queue_id_list[item_number++] = index--;
526             pcp_list[item_number] = 3;
527             queue_id_list[item_number++] = index--;
528             pcp_list[item_number] = 0;
529             queue_id_list[item_number++] = index;
530             break;
531         case 8:
532         default:
533             pcp_list[item_number] = 7;
534             queue_id_list[item_number++] = index--;
535             pcp_list[item_number] = 6;
536             queue_id_list[item_number++] = index--;
537             pcp_list[item_number] = 5;
538             queue_id_list[item_number++] = index--;
539             pcp_list[item_number] = 4;
540             queue_id_list[item_number++] = index--;
541             pcp_list[item_number] = 3;
542             queue_id_list[item_number++] = index--;
543             pcp_list[item_number] = 0;
544             queue_id_list[item_number++] = index;
545             break;
546         }
547     }
548     else
549     {
550         pcp_list[item_number] = NX_SHAPER_CLASS_A_PCP;
551         queue_id_list[item_number++] = index--;
552         pcp_list[item_number] = NX_SHAPER_CLASS_B_PCP;
553         queue_id_list[item_number++] = index--;
554 
555         switch (interface_ptr -> shaper_container -> hw_queue_number)
556         {
557         case 3:
558             /* nothing need to do */
559             break;
560         case 4:
561             pcp_list[item_number] = 7;
562             queue_id_list[item_number++] = index;
563             pcp_list[item_number] = 6;
564             queue_id_list[item_number++] = index;
565             pcp_list[item_number] = 5;
566             queue_id_list[item_number++] = index;
567             pcp_list[item_number] = 4;
568             queue_id_list[item_number++] = index;
569             break;
570         case 5:
571             pcp_list[item_number] = 7;
572             queue_id_list[item_number++] = index;
573             pcp_list[item_number] = 6;
574             queue_id_list[item_number++] = index--;
575             pcp_list[item_number] = 5;
576             queue_id_list[item_number++] = index;
577             pcp_list[item_number] = 4;
578             queue_id_list[item_number++] = index;
579             break;
580         case 6:
581             pcp_list[item_number] = 7;
582             queue_id_list[item_number++] = index--;
583             pcp_list[item_number] = 6;
584             queue_id_list[item_number++] = index--;
585             pcp_list[item_number] = 5;
586             queue_id_list[item_number++] = index;
587             pcp_list[item_number] = 4;
588             queue_id_list[item_number++] = index;
589             break;
590         case 7:
591             pcp_list[item_number] = 7;
592             queue_id_list[item_number++] = index--;
593             pcp_list[item_number] = 6;
594             queue_id_list[item_number++] = index--;
595             pcp_list[item_number] = 5;
596             queue_id_list[item_number++] = index--;
597             pcp_list[item_number] = 4;
598             queue_id_list[item_number++] = index;
599             break;
600         case 8:
601         default:
602             pcp_list[item_number] = 7;
603             queue_id_list[item_number++] = index--;
604             pcp_list[item_number] = 6;
605             queue_id_list[item_number++] = index--;
606             pcp_list[item_number] = 5;
607             queue_id_list[item_number++] = index--;
608             pcp_list[item_number] = 4;
609             queue_id_list[item_number++] = index--;
610             pcp_list[item_number] = 0;
611             queue_id_list[item_number++] = index;
612             break;
613         }
614     }
615 
616     return(NX_SUCCESS);
617 }
618 
619 /**************************************************************************/
620 /*                                                                        */
621 /*  FUNCTION                                               RELEASE        */
622 /*                                                                        */
623 /*    nx_shaper_current_mapping_get                       PORTABLE C      */
624 /*                                                           6.4.0        */
625 /*  AUTHOR                                                                */
626 /*                                                                        */
627 /*    Yajun Xia, Microsoft Corporation                                    */
628 /*                                                                        */
629 /*  DESCRIPTION                                                           */
630 /*                                                                        */
631 /*    This function gets the current pcp to HW queue mapping config.      */
632 /*                                                                        */
633 /*  INPUT                                                                 */
634 /*                                                                        */
635 /*    interface_ptr                         Pointer to interface instance */
636 /*    pcp_list                              Pointer to PCP list           */
637 /*    queue_id_list                         Pointer to Queue id list      */
638 /*    list_size                             Size of PCP list              */
639 /*                                                                        */
640 /*  OUTPUT                                                                */
641 /*                                                                        */
642 /*    status                                Completion status             */
643 /*                                                                        */
644 /*  CALLS                                                                 */
645 /*                                                                        */
646 /*    None                                                                */
647 /*                                                                        */
648 /*  CALLED BY                                                             */
649 /*                                                                        */
650 /*    Application Code                                                    */
651 /*                                                                        */
652 /*  RELEASE HISTORY                                                       */
653 /*                                                                        */
654 /*    DATE              NAME                      DESCRIPTION             */
655 /*                                                                        */
656 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
657 /*                                                                        */
658 /**************************************************************************/
nx_shaper_current_mapping_get(NX_INTERFACE * interface_ptr,UCHAR * pcp_list,UCHAR * queue_id_list,UCHAR list_size)659 UINT nx_shaper_current_mapping_get(NX_INTERFACE *interface_ptr, UCHAR *pcp_list, UCHAR *queue_id_list, UCHAR list_size)
660 {
661 UCHAR i, j;
662 
663     if (interface_ptr -> shaper_container == NX_NULL)
664     {
665         return(NX_NOT_SUPPORTED);
666     }
667 
668     if (list_size != NX_SHAPER_MAPPING_LIST_SIZE)
669     {
670         return(NX_INVALID_PARAMETERS);
671     }
672 
673     for (i = 0; i < list_size; i++)
674     {
675         pcp_list[i] = i;
676         for (j = 0; j < list_size; j++)
677         {
678             if (interface_ptr -> shaper_container -> hw_queue[j].hw_queue_id ==
679                 interface_ptr -> shaper_container -> queue_map[pcp_list[i]])
680             {
681                 queue_id_list[i] = j;
682                 break;
683             }
684         }
685         if (j == list_size)
686         {
687             return(NX_NOT_SUCCESSFUL);
688         }
689     }
690     return(NX_SUCCESS);
691 }
692 
693 /**************************************************************************/
694 /*                                                                        */
695 /*  FUNCTION                                               RELEASE        */
696 /*                                                                        */
697 /*    nx_shaper_hw_queue_number_get                       PORTABLE C      */
698 /*                                                           6.4.0        */
699 /*  AUTHOR                                                                */
700 /*                                                                        */
701 /*    Yajun Xia, Microsoft Corporation                                    */
702 /*                                                                        */
703 /*  DESCRIPTION                                                           */
704 /*                                                                        */
705 /*    This function gets the number of hardware queue.                    */
706 /*                                                                        */
707 /*  INPUT                                                                 */
708 /*                                                                        */
709 /*    interface_ptr                         Pointer to interface instance */
710 /*    hw_queue_number                       Pointer to HW queue number    */
711 /*                                                                        */
712 /*  OUTPUT                                                                */
713 /*                                                                        */
714 /*    status                                Completion status             */
715 /*                                                                        */
716 /*  CALLS                                                                 */
717 /*                                                                        */
718 /*    None                                                                */
719 /*                                                                        */
720 /*  CALLED BY                                                             */
721 /*                                                                        */
722 /*    Internal function                                                   */
723 /*                                                                        */
724 /*  RELEASE HISTORY                                                       */
725 /*                                                                        */
726 /*    DATE              NAME                      DESCRIPTION             */
727 /*                                                                        */
728 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
729 /*                                                                        */
730 /**************************************************************************/
nx_shaper_hw_queue_number_get(NX_INTERFACE * interface_ptr,UCHAR * hw_queue_number)731 UINT nx_shaper_hw_queue_number_get(NX_INTERFACE *interface_ptr, UCHAR *hw_queue_number)
732 {
733     if (interface_ptr -> shaper_container == NX_NULL)
734     {
735         return(NX_NOT_SUPPORTED);
736     }
737 
738     *hw_queue_number = interface_ptr -> shaper_container -> hw_queue_number;
739     return(NX_SUCCESS);
740 }
741 
742 /**************************************************************************/
743 /*                                                                        */
744 /*  FUNCTION                                               RELEASE        */
745 /*                                                                        */
746 /*    nx_shaper_hw_cbs_queue_number_get                   PORTABLE C      */
747 /*                                                           6.4.0        */
748 /*  AUTHOR                                                                */
749 /*                                                                        */
750 /*    Yajun Xia, Microsoft Corporation                                    */
751 /*                                                                        */
752 /*  DESCRIPTION                                                           */
753 /*                                                                        */
754 /*    This function gets the number of hardware queue that support CBS.   */
755 /*                                                                        */
756 /*  INPUT                                                                 */
757 /*                                                                        */
758 /*    interface_ptr                         Pointer to interface instance */
759 /*    hw_cbs_queue_number                   Pointer to CBS HW queue       */
760 /*                                          number                        */
761 /*                                                                        */
762 /*  OUTPUT                                                                */
763 /*                                                                        */
764 /*    status                                Completion status             */
765 /*                                                                        */
766 /*  CALLS                                                                 */
767 /*                                                                        */
768 /*    None                                                                */
769 /*                                                                        */
770 /*  CALLED BY                                                             */
771 /*                                                                        */
772 /*    nx_shaper_default_mapping_get                                       */
773 /*                                                                        */
774 /*  RELEASE HISTORY                                                       */
775 /*                                                                        */
776 /*    DATE              NAME                      DESCRIPTION             */
777 /*                                                                        */
778 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
779 /*                                                                        */
780 /**************************************************************************/
nx_shaper_hw_cbs_queue_number_get(NX_INTERFACE * interface_ptr,UCHAR * hw_cbs_queue_number)781 UINT nx_shaper_hw_cbs_queue_number_get(NX_INTERFACE *interface_ptr, UCHAR *hw_cbs_queue_number)
782 {
783 UCHAR i;
784 
785     *hw_cbs_queue_number = 0;
786     if (interface_ptr -> shaper_container == NX_NULL)
787     {
788         return(NX_NOT_SUPPORTED);
789     }
790 
791     for (i = 0; i < interface_ptr -> shaper_container -> hw_queue_number; i++)
792     {
793         if (interface_ptr -> shaper_container -> hw_queue[i].type & NX_SHAPER_HW_QUEUE_CBS)
794         {
795             (*hw_cbs_queue_number)++;
796         }
797     }
798 
799     return(NX_SUCCESS);
800 }
801 
802 /**************************************************************************/
803 /*                                                                        */
804 /*  FUNCTION                                               RELEASE        */
805 /*                                                                        */
806 /*    nx_shaper_port_rate_get                             PORTABLE C      */
807 /*                                                           6.4.0        */
808 /*  AUTHOR                                                                */
809 /*                                                                        */
810 /*    Yajun Xia, Microsoft Corporation                                    */
811 /*                                                                        */
812 /*  DESCRIPTION                                                           */
813 /*                                                                        */
814 /*    This function gets the port rate of the interface.                  */
815 /*                                                                        */
816 /*  INPUT                                                                 */
817 /*                                                                        */
818 /*    interface_ptr                         Pointer to interface instance */
819 /*    port_rate                             Pointer to port rate          */
820 /*                                                                        */
821 /*  OUTPUT                                                                */
822 /*                                                                        */
823 /*    status                                Completion status             */
824 /*                                                                        */
825 /*  CALLS                                                                 */
826 /*                                                                        */
827 /*    None                                                                */
828 /*                                                                        */
829 /*  CALLED BY                                                             */
830 /*                                                                        */
831 /*    Internal function                                                   */
832 /*                                                                        */
833 /*  RELEASE HISTORY                                                       */
834 /*                                                                        */
835 /*    DATE              NAME                      DESCRIPTION             */
836 /*                                                                        */
837 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
838 /*                                                                        */
839 /**************************************************************************/
nx_shaper_port_rate_get(NX_INTERFACE * interface_ptr,UINT * port_rate)840 UINT nx_shaper_port_rate_get(NX_INTERFACE *interface_ptr, UINT *port_rate)
841 {
842     if (interface_ptr -> shaper_container == NX_NULL)
843     {
844         return(NX_NOT_SUPPORTED);
845     }
846 
847     *port_rate = interface_ptr -> shaper_container -> port_rate;
848     return(NX_SUCCESS);
849 }
850 
851 /**************************************************************************/
852 /*                                                                        */
853 /*  FUNCTION                                               RELEASE        */
854 /*                                                                        */
855 /*    nx_shaper_mapping_set                               PORTABLE C      */
856 /*                                                           6.4.0        */
857 /*  AUTHOR                                                                */
858 /*                                                                        */
859 /*    Yajun Xia, Microsoft Corporation                                    */
860 /*                                                                        */
861 /*  DESCRIPTION                                                           */
862 /*                                                                        */
863 /*    This function configures the pcp to hardware queue mapping.         */
864 /*                                                                        */
865 /*  INPUT                                                                 */
866 /*                                                                        */
867 /*    interface_ptr                         Pointer to interface instance */
868 /*    pcp_list                              Pointer to PCP list           */
869 /*    queue_id_list                         Pointer to Queue id list      */
870 /*    list_size                             Size of PCP list              */
871 /*                                                                        */
872 /*  OUTPUT                                                                */
873 /*                                                                        */
874 /*    status                                Completion status             */
875 /*                                                                        */
876 /*  CALLS                                                                 */
877 /*                                                                        */
878 /*    None                                                                */
879 /*                                                                        */
880 /*  CALLED BY                                                             */
881 /*                                                                        */
882 /*    Application Code                                                    */
883 /*                                                                        */
884 /*  RELEASE HISTORY                                                       */
885 /*                                                                        */
886 /*    DATE              NAME                      DESCRIPTION             */
887 /*                                                                        */
888 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
889 /*                                                                        */
890 /**************************************************************************/
nx_shaper_mapping_set(NX_INTERFACE * interface_ptr,UCHAR * pcp_list,UCHAR * queue_id_list,UCHAR list_size)891 UINT nx_shaper_mapping_set(NX_INTERFACE *interface_ptr, UCHAR *pcp_list, UCHAR *queue_id_list, UCHAR list_size)
892 {
893 UCHAR pcp;
894 UCHAR queue_id;
895 UCHAR i;
896 
897     if (interface_ptr -> shaper_container == NX_NULL)
898     {
899         return(NX_NOT_SUPPORTED);
900     }
901 
902     if (list_size != NX_SHAPER_MAPPING_LIST_SIZE)
903     {
904         return(NX_INVALID_PARAMETERS);
905     }
906 
907     for (i = 0; i < list_size; i++)
908     {
909         pcp = pcp_list[i];
910         queue_id = queue_id_list[i];
911 
912         if ((pcp > NX_SHAPER_PCP_MAX) ||
913             (queue_id >= interface_ptr -> shaper_container -> hw_queue_number))
914         {
915             return(NX_INVALID_PARAMETERS);
916         }
917 
918         if ((pcp == 0) && (queue_id == 0))
919         {
920             /* no need to configure here */
921             continue;
922         }
923         interface_ptr -> shaper_container -> queue_map[pcp] =
924             interface_ptr -> shaper_container -> hw_queue[queue_id].hw_queue_id;
925     }
926 
927     return(NX_SUCCESS);
928 }
929 
930 /**************************************************************************/
931 /*                                                                        */
932 /*  FUNCTION                                               RELEASE        */
933 /*                                                                        */
934 /*    nx_shaper_cbs_parameter_set                         PORTABLE C      */
935 /*                                                           6.4.0        */
936 /*  AUTHOR                                                                */
937 /*                                                                        */
938 /*    Yajun Xia, Microsoft Corporation                                    */
939 /*                                                                        */
940 /*  DESCRIPTION                                                           */
941 /*                                                                        */
942 /*    This function configures the hardware parameters for CBS shaper.    */
943 /*                                                                        */
944 /*  INPUT                                                                 */
945 /*                                                                        */
946 /*    interface_ptr                         Pointer to interface instance */
947 /*    cbs_parameter                         Pointer to cbs parameter      */
948 /*    pcp                                   PCP                           */
949 /*                                                                        */
950 /*  OUTPUT                                                                */
951 /*                                                                        */
952 /*    status                                Completion status             */
953 /*                                                                        */
954 /*  CALLS                                                                 */
955 /*                                                                        */
956 /*    None                                                                */
957 /*                                                                        */
958 /*  CALLED BY                                                             */
959 /*                                                                        */
960 /*    Application Code                                                    */
961 /*                                                                        */
962 /*  RELEASE HISTORY                                                       */
963 /*                                                                        */
964 /*    DATE              NAME                      DESCRIPTION             */
965 /*                                                                        */
966 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
967 /*                                                                        */
968 /**************************************************************************/
nx_shaper_cbs_parameter_set(NX_INTERFACE * interface_ptr,NX_SHAPER_CBS_PARAMETER * cbs_parameter,UCHAR pcp)969 UINT nx_shaper_cbs_parameter_set(NX_INTERFACE *interface_ptr, NX_SHAPER_CBS_PARAMETER *cbs_parameter, UCHAR pcp)
970 {
971 UCHAR                      i;
972 UCHAR                      hw_queue_id;
973 UCHAR                      cbs_index;
974 NX_SHAPER_DRIVER_PARAMETER set_parameter;
975 UINT                       status;
976 
977     if (interface_ptr -> shaper_container == NX_NULL)
978     {
979         return(NX_NOT_SUPPORTED);
980     }
981 
982     for (i = 0; i < NX_SHAPER_NUMBERS; i++)
983     {
984         if ((interface_ptr -> shaper_container -> shaper[i] != NX_NULL) &&
985             (interface_ptr -> shaper_container -> shaper[i] -> shaper_type == NX_SHAPER_TYPE_CBS))
986         {
987             cbs_index = i;
988             break;
989         }
990     }
991 
992     if (i >= NX_SHAPER_NUMBERS)
993     {
994         return(NX_NOT_FOUND);
995     }
996 
997     hw_queue_id = interface_ptr -> shaper_container -> queue_map[pcp];
998 
999     for (i = (UCHAR)(interface_ptr -> shaper_container -> hw_queue_number - 1); i > 0; i--)
1000     {
1001         if (interface_ptr -> shaper_container -> hw_queue[i].hw_queue_id == hw_queue_id)
1002         {
1003             if ((interface_ptr -> shaper_container -> hw_queue[i].type & NX_SHAPER_HW_QUEUE_CBS) == 0)
1004             {
1005                 return(NX_NOT_SUPPORTED);
1006             }
1007             else
1008             {
1009                 break;
1010             }
1011         }
1012     }
1013 
1014     /* queue id 0 is assumed not support cbs */
1015     if (i == 0)
1016     {
1017         return(NX_NOT_SUPPORTED);
1018     }
1019 
1020     /* Save the cbs parameter */
1021     interface_ptr -> shaper_container -> shaper[cbs_index] -> cfg_pointer = (void *)cbs_parameter;
1022 
1023     cbs_parameter -> hw_queue_id = hw_queue_id;
1024 
1025     set_parameter.nx_shaper_driver_command = NX_SHAPER_COMMAND_PARAMETER_SET;
1026     set_parameter.shaper_type = NX_SHAPER_TYPE_CBS;         /* not used in driver */
1027     set_parameter.nx_ip_driver_interface = interface_ptr;
1028     set_parameter.shaper_parameter = (void *)cbs_parameter; /* not used in driver */
1029 
1030     status = interface_ptr -> shaper_container -> shaper[cbs_index] -> shaper_driver(&set_parameter);
1031 
1032     return(status);
1033 }
1034 
1035 /**************************************************************************/
1036 /*                                                                        */
1037 /*  FUNCTION                                               RELEASE        */
1038 /*                                                                        */
1039 /*    nx_shaper_hw_queue_id_get                           PORTABLE C      */
1040 /*                                                           6.4.0        */
1041 /*  AUTHOR                                                                */
1042 /*                                                                        */
1043 /*    Yajun Xia, Microsoft Corporation                                    */
1044 /*                                                                        */
1045 /*  DESCRIPTION                                                           */
1046 /*                                                                        */
1047 /*    This function gets the hardware queue id by network driver.         */
1048 /*                                                                        */
1049 /*  INPUT                                                                 */
1050 /*                                                                        */
1051 /*    interface_ptr                         Pointer to interface instance */
1052 /*    packet_ptr                            Pointer to packet             */
1053 /*    hw_queue_id                           Pointer to HW queue ID        */
1054 /*                                                                        */
1055 /*  OUTPUT                                                                */
1056 /*                                                                        */
1057 /*    status                                Completion status             */
1058 /*                                                                        */
1059 /*  CALLS                                                                 */
1060 /*                                                                        */
1061 /*    None                                                                */
1062 /*                                                                        */
1063 /*  CALLED BY                                                             */
1064 /*                                                                        */
1065 /*    Network driver                                                      */
1066 /*                                                                        */
1067 /*  RELEASE HISTORY                                                       */
1068 /*                                                                        */
1069 /*    DATE              NAME                      DESCRIPTION             */
1070 /*                                                                        */
1071 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
1072 /*                                                                        */
1073 /**************************************************************************/
nx_shaper_hw_queue_id_get(NX_INTERFACE * interface_ptr,NX_PACKET * packet_ptr,UCHAR * hw_queue_id)1074 UINT nx_shaper_hw_queue_id_get(NX_INTERFACE *interface_ptr, NX_PACKET *packet_ptr, UCHAR *hw_queue_id)
1075 {
1076 UCHAR *data_ptr = packet_ptr -> nx_packet_prepend_ptr;
1077 UCHAR  pcp = 0;
1078 
1079     if (interface_ptr -> shaper_container == NX_NULL)
1080     {
1081         return(NX_NOT_SUPPORTED);
1082     }
1083 
1084     /* Check VLAN tag.  */
1085     if (((data_ptr[12] << 8) | data_ptr[13]) == NX_LINK_ETHERNET_TPID)
1086     {
1087         /* VLAN tag is present.  */
1088 
1089         /* Get PCP */
1090         pcp = data_ptr[14] >> 5 & 0x07;
1091 
1092         /* Get hardware queue id for this packet */
1093         *hw_queue_id = interface_ptr -> shaper_container -> queue_map[pcp];
1094     }
1095     else
1096     {
1097 
1098         /* no VLAN tag in packet, send the packet to besteffort queue */
1099         *hw_queue_id = interface_ptr -> shaper_container -> queue_map[pcp];
1100     }
1101 
1102     return(NX_SUCCESS);
1103 }
1104 
1105 /**************************************************************************/
1106 /*                                                                        */
1107 /*  FUNCTION                                               RELEASE        */
1108 /*                                                                        */
1109 /*    nx_shaper_tas_parameter_set                         PORTABLE C      */
1110 /*                                                           6.4.0        */
1111 /*  AUTHOR                                                                */
1112 /*                                                                        */
1113 /*    Yajun Xia, Microsoft Corporation                                    */
1114 /*                                                                        */
1115 /*  DESCRIPTION                                                           */
1116 /*                                                                        */
1117 /*    This function configures the hardware parameters for TAS shaper.    */
1118 /*                                                                        */
1119 /*  INPUT                                                                 */
1120 /*                                                                        */
1121 /*    interface_ptr                         Pointer to interface instance */
1122 /*    tas_config                            Pointer to cbs parameter      */
1123 /*                                                                        */
1124 /*  OUTPUT                                                                */
1125 /*                                                                        */
1126 /*    status                                Completion status             */
1127 /*                                                                        */
1128 /*  CALLS                                                                 */
1129 /*                                                                        */
1130 /*    None                                                                */
1131 /*                                                                        */
1132 /*  CALLED BY                                                             */
1133 /*                                                                        */
1134 /*    Application Code                                                    */
1135 /*                                                                        */
1136 /*  RELEASE HISTORY                                                       */
1137 /*                                                                        */
1138 /*    DATE              NAME                      DESCRIPTION             */
1139 /*                                                                        */
1140 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
1141 /*                                                                        */
1142 /**************************************************************************/
nx_shaper_tas_parameter_set(NX_INTERFACE * interface_ptr,NX_SHAPER_TAS_CONFIG * tas_config)1143 UINT nx_shaper_tas_parameter_set(NX_INTERFACE *interface_ptr, NX_SHAPER_TAS_CONFIG *tas_config)
1144 {
1145 NX_SHAPER_TAS_PARAMETER    tas_parameter;
1146 UCHAR                      i, j, tas_index = NX_SHAPER_INVALID_INDEX;
1147 UINT                       front, end, step;
1148 UINT                       left = 0, right;
1149 UCHAR                      gcl_index;
1150 UCHAR                      hw_queue_id;
1151 NX_SHAPER_DRIVER_PARAMETER set_parameter;
1152 UINT                       status;
1153 UINT                       auto_fill_start;
1154 UCHAR                      fp_enable = NX_FALSE;
1155 NX_SHAPER_FP_PARAMETER    *fp_parameter;
1156 
1157     /* Initialize tas_parameter */
1158     memset(&tas_parameter, 0, sizeof(NX_SHAPER_TAS_PARAMETER));
1159 
1160     /* Initialize set_parameter */
1161     memset(&set_parameter, 0, sizeof(NX_SHAPER_DRIVER_PARAMETER));
1162 
1163     /* Find the TAS index. */
1164     for (i = 0; i < NX_SHAPER_NUMBERS; i++)
1165     {
1166         if ((interface_ptr -> shaper_container -> shaper[i] != NX_NULL) &&
1167             (interface_ptr -> shaper_container -> shaper[i] -> shaper_type == NX_SHAPER_TYPE_TAS))
1168         {
1169             tas_index = i;
1170         }
1171         else if ((interface_ptr -> shaper_container -> shaper[i] != NX_NULL) &&
1172                  (interface_ptr -> shaper_container -> shaper[i] -> shaper_type == NX_SHAPER_TYPE_FP))
1173         {
1174             fp_parameter = (NX_SHAPER_FP_PARAMETER *)interface_ptr -> shaper_container -> shaper[i] -> cfg_pointer;
1175             fp_enable = NX_TRUE;
1176             tas_parameter.fp_parameter = (void *)fp_parameter;
1177         }
1178     }
1179 
1180     if (tas_index == NX_SHAPER_INVALID_INDEX)
1181     {
1182         return(NX_NOT_FOUND);
1183     }
1184 
1185     auto_fill_start = 0;
1186     for (i = 0; i < tas_config -> traffic_count; i++)
1187     {
1188         if (tas_config -> traffic[i].time_offset + tas_config -> traffic[i].duration > auto_fill_start)
1189         {
1190             auto_fill_start = tas_config -> traffic[i].time_offset + tas_config -> traffic[i].duration;
1191         }
1192     }
1193 
1194     /* Transform the application input into driver input. */
1195     front = 0;
1196     if (tas_config -> auto_fill_status == NX_SHAPER_TAS_IDLE_CYCLE_AUTO_FILL_DISABLED)
1197     {
1198         end = auto_fill_start;
1199     }
1200     else
1201     {
1202         end = tas_config -> cycle_time;
1203     }
1204     gcl_index = 0;
1205 
1206     tas_parameter.base_time = tas_config -> base_time;
1207     tas_parameter.cycle_time = tas_config -> cycle_time;
1208     tas_parameter.cycle_time_extension = tas_config -> cycle_time / 2;
1209 
1210     /*
1211         Input:(Cycle time: 1000us, Cycle extension: default (half of cycle time), FP: disabled)
1212                     slot 0                                  slot 1
1213         P3(us) |-------200(O)-------|--------------------------800(C)--------------------|
1214         P2(us) |-------300(O)--------------------|-------------700(C)--------------------|
1215         Output:
1216                     slot(GCL)0        slot(GCL)1            slot(GCL)2
1217         P3(us) |-------200(O)-------|--100(C)----|-------------700(C)--------------------|
1218         P2(us) |-------200(O)-------|--100(O)----|-------------700(C)--------------------|
1219         PX(us) |-------200(C)-------|--100(C)----|-------------700(C)--------------------|
1220 
1221         Example:
1222                 tas_config.base_time = 0;
1223                 tas_config.cycle_time = 1000;
1224                 tas_config.auto_fill_status = NX_SHAPER_TAS_IDLE_CYCLE_AUTO_FILL_WITH_CLOSE;
1225                 tas_config.gcl_length = 2;
1226 
1227                 tas_config.traffic[0].pcp = 3;
1228                 tas_config.traffic[0].time_offset = 0;
1229                 tas_config.traffic[0].duration = 200;
1230                 tas_config.traffic[0].traffic_control = NX_SHAPER_TRAFFIC_OPEN;
1231 
1232                 tas_config.traffic[1].pcp = 2;
1233                 tas_config.traffic[1].time_offset = 0;
1234                 tas_config.traffic[1].duration = 300;
1235                 tas_config.traffic[1].traffic_control = NX_SHAPER_TRAFFIC_OPEN;
1236      */
1237 
1238     /* Split cycle into slots */
1239     while (front < end)
1240     {
1241         step = end - front;
1242         for (i = 0; i < tas_config -> traffic_count; i++)
1243         {
1244             if ((tas_config -> traffic[i].time_offset > front) && (step > tas_config -> traffic[i].time_offset - front))
1245             {
1246                 step = tas_config -> traffic[i].time_offset - front;
1247             }
1248             else if ((tas_config -> traffic[i].time_offset + tas_config -> traffic[i].duration > front) &&
1249                      (step > tas_config -> traffic[i].time_offset + tas_config -> traffic[i].duration - front))
1250             {
1251                 step = tas_config -> traffic[i].time_offset + tas_config -> traffic[i].duration - front;
1252             }
1253             else if (step > end - front)
1254             {
1255                 step = end - front;
1256             }
1257         }
1258 
1259         if (front >= auto_fill_start)
1260         {
1261             tas_parameter.gcl[gcl_index].gate_control |= NX_SHAPER_GCL_AUTO_FILL_FLAG;
1262         }
1263         tas_parameter.gcl_length++;
1264         tas_parameter.gcl[gcl_index++].duration = step;
1265         front = front + step;
1266     }
1267 
1268     /* Config the gate_control on different slot */
1269     for (i = 0; i < tas_parameter.gcl_length; i++)
1270     {
1271         right = left + tas_parameter.gcl[i].duration;
1272         for (j = 0; j < tas_config -> traffic_count; j++)
1273         {
1274             if ((right <= tas_config -> traffic[j].time_offset) || (left >= tas_config -> traffic[j].time_offset + tas_config -> traffic[j].duration))
1275             {
1276                 continue;
1277             }
1278 
1279             /* Get the hw queue id from pcp */
1280             hw_queue_id = interface_ptr -> shaper_container -> queue_map[tas_config -> traffic[j].pcp];
1281             if (tas_config -> traffic[j].traffic_control == NX_SHAPER_TRAFFIC_OPEN)
1282             {
1283                 tas_parameter.gcl[i].gate_control |= (UCHAR)(1 << hw_queue_id);
1284             }
1285         }
1286 
1287         if (tas_parameter.gcl[i].gate_control & NX_SHAPER_GCL_AUTO_FILL_FLAG)
1288         {
1289             if (tas_config -> auto_fill_status == NX_SHAPER_TAS_IDLE_CYCLE_AUTO_FILL_WITH_OPEN)
1290             {
1291                 tas_parameter.gcl[i].gate_control = 0xFF;
1292             }
1293             else
1294             {
1295                 tas_parameter.gcl[i].gate_control &= ~NX_SHAPER_GCL_AUTO_FILL_FLAG;
1296             }
1297         }
1298 
1299         /* If fp is enabled, set the hold/release state based on the express queue status. */
1300         if (fp_enable)
1301         {
1302             /*
1303                For a GCE with set-hold, all queues opened must be Express queues. For a GCE with
1304                set-release all queues opened must be Preemptable queues. The same queue cannot
1305                be open in both a set-hold and a set-release operation.
1306              */
1307             if (tas_parameter.gcl[i].gate_control & fp_parameter -> express_queue_bitmap)
1308             {
1309                 tas_parameter.gcl[i].operation = NX_SHAPER_GATE_OPERATION_HOLD;
1310             }
1311             else
1312             {
1313                 tas_parameter.gcl[i].operation = NX_SHAPER_GATE_OPERATION_RELEASE;
1314             }
1315         }
1316         else
1317         {
1318             tas_parameter.gcl[i].operation = NX_SHAPER_GATE_OPERATION_SET;
1319         }
1320 
1321         left = right;
1322     }
1323 
1324     /* save the tas parameter */
1325     interface_ptr -> shaper_container -> shaper[tas_index] -> cfg_pointer = (void *)tas_config;
1326 
1327     /* Set the object(tas_param) of NX_SHAPER_TAS_PARAMETER */
1328     set_parameter.nx_shaper_driver_command = NX_SHAPER_COMMAND_PARAMETER_SET;
1329     set_parameter.shaper_type = NX_SHAPER_TYPE_TAS;          /* not used in driver */
1330     set_parameter.nx_ip_driver_interface = interface_ptr;
1331     set_parameter.shaper_parameter = (void *)&tas_parameter; /* not used in driver */
1332 
1333     status = interface_ptr -> shaper_container -> shaper[tas_index] -> shaper_driver(&set_parameter);
1334 
1335     return(status);
1336 }
1337 
1338 /**************************************************************************/
1339 /*                                                                        */
1340 /*  FUNCTION                                               RELEASE        */
1341 /*                                                                        */
1342 /*    nx_shaper_express_queue_set                         PORTABLE C      */
1343 /*                                                           6.4.0        */
1344 /*  AUTHOR                                                                */
1345 /*                                                                        */
1346 /*    Yajun Xia, Microsoft Corporation                                    */
1347 /*                                                                        */
1348 /*  DESCRIPTION                                                           */
1349 /*                                                                        */
1350 /*    This function configures the express queue for frame preemption.    */
1351 /*                                                                        */
1352 /*  INPUT                                                                 */
1353 /*                                                                        */
1354 /*    interface_ptr                         Pointer to interface instance */
1355 /*    express_queue_bitmap                  Pointer to express queue      */
1356 /*                                          bitmap                        */
1357 /*                                                                        */
1358 /*  OUTPUT                                                                */
1359 /*                                                                        */
1360 /*    status                                Completion status             */
1361 /*                                                                        */
1362 /*  CALLS                                                                 */
1363 /*                                                                        */
1364 /*    None                                                                */
1365 /*                                                                        */
1366 /*  CALLED BY                                                             */
1367 /*                                                                        */
1368 /*    nx_shaper_fp_parameter_set            FP parameter set              */
1369 /*                                                                        */
1370 /*  RELEASE HISTORY                                                       */
1371 /*                                                                        */
1372 /*    DATE              NAME                      DESCRIPTION             */
1373 /*                                                                        */
1374 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
1375 /*                                                                        */
1376 /**************************************************************************/
nx_shaper_express_queue_set(NX_INTERFACE * interface_ptr,UCHAR * express_queue_bitmap,UCHAR pcp)1377 UINT nx_shaper_express_queue_set(NX_INTERFACE *interface_ptr, UCHAR *express_queue_bitmap, UCHAR pcp)
1378 {
1379 UCHAR         hw_queue_id;
1380 NX_INTERFACE *parent_interface;
1381 
1382     if (interface_ptr -> nx_interface_parent_ptr != NX_NULL)
1383     {
1384         parent_interface = interface_ptr -> nx_interface_parent_ptr;
1385     }
1386     else
1387     {
1388         parent_interface = interface_ptr;
1389     }
1390 
1391     if (parent_interface -> shaper_container == NX_NULL)
1392     {
1393         return(NX_NOT_SUCCESSFUL);
1394     }
1395 
1396     hw_queue_id = parent_interface -> shaper_container -> queue_map[pcp];
1397     *express_queue_bitmap |= (UCHAR)(1 << hw_queue_id);
1398 
1399     return(NX_SUCCESS);
1400 }
1401 
1402 /**************************************************************************/
1403 /*                                                                        */
1404 /*  FUNCTION                                               RELEASE        */
1405 /*                                                                        */
1406 /*    nx_shaper_sdu_tx_time_get                           PORTABLE C      */
1407 /*                                                           6.4.0        */
1408 /*  AUTHOR                                                                */
1409 /*                                                                        */
1410 /*    Yajun Xia, Microsoft Corporation                                    */
1411 /*                                                                        */
1412 /*  DESCRIPTION                                                           */
1413 /*                                                                        */
1414 /*    This function gets the sdu transmit time.                           */
1415 /*                                                                        */
1416 /*  INPUT                                                                 */
1417 /*                                                                        */
1418 /*    interface_ptr                         Pointer to interface instance */
1419 /*    sdu_size                              SDU size                      */
1420 /*    tx_time                               Pointer to transmit time      */
1421 /*                                                                        */
1422 /*  OUTPUT                                                                */
1423 /*                                                                        */
1424 /*    status                                Completion status             */
1425 /*                                                                        */
1426 /*  CALLS                                                                 */
1427 /*                                                                        */
1428 /*    None                                                                */
1429 /*                                                                        */
1430 /*  CALLED BY                                                             */
1431 /*                                                                        */
1432 /*    nx_shaper_fp_parameter_set                                          */
1433 /*                                                                        */
1434 /*  RELEASE HISTORY                                                       */
1435 /*                                                                        */
1436 /*    DATE              NAME                      DESCRIPTION             */
1437 /*                                                                        */
1438 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
1439 /*                                                                        */
1440 /**************************************************************************/
nx_shaper_sdu_tx_time_get(NX_INTERFACE * interface_ptr,UINT sdu_size,UINT * tx_time)1441 UINT nx_shaper_sdu_tx_time_get(NX_INTERFACE *interface_ptr, UINT sdu_size, UINT *tx_time)
1442 {
1443 UINT tmp;
1444 
1445     tmp = sdu_size * 8;
1446     tmp = tmp * 1000;
1447     if (interface_ptr -> shaper_container -> port_rate != 0)
1448     {
1449         tmp = tmp / interface_ptr -> shaper_container -> port_rate;
1450     }
1451     else
1452     {
1453         return(NX_NOT_SUCCESSFUL);
1454     }
1455 
1456     *tx_time = tmp;
1457     return(NX_SUCCESS);
1458 }
1459 
1460 /**************************************************************************/
1461 /*                                                                        */
1462 /*  FUNCTION                                               RELEASE        */
1463 /*                                                                        */
1464 /*    nx_shaper_fp_parameter_set                          PORTABLE C      */
1465 /*                                                           6.4.0        */
1466 /*  AUTHOR                                                                */
1467 /*                                                                        */
1468 /*    Yajun Xia, Microsoft Corporation                                    */
1469 /*                                                                        */
1470 /*  DESCRIPTION                                                           */
1471 /*                                                                        */
1472 /*    This function sets the frame preemption parameter, when used with   */
1473 /*    other shapers, FP parameter should be set before other shapers.     */
1474 /*                                                                        */
1475 /*  INPUT                                                                 */
1476 /*                                                                        */
1477 /*    interface_ptr                         Pointer to interface instance */
1478 /*    fp_parameter                          Pointer to FP parameter       */
1479 /*                                                                        */
1480 /*  OUTPUT                                                                */
1481 /*                                                                        */
1482 /*    status                                Completion status             */
1483 /*                                                                        */
1484 /*  CALLS                                                                 */
1485 /*                                                                        */
1486 /*    nx_shaper_express_queue_set           Set express queue info        */
1487 /*    nx_shaper_sdu_tx_time_get             Get sdu transmit time         */
1488 /*                                                                        */
1489 /*  CALLED BY                                                             */
1490 /*                                                                        */
1491 /*    Application Code                                                    */
1492 /*                                                                        */
1493 /*  RELEASE HISTORY                                                       */
1494 /*                                                                        */
1495 /*    DATE              NAME                      DESCRIPTION             */
1496 /*                                                                        */
1497 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
1498 /*                                                                        */
1499 /**************************************************************************/
nx_shaper_fp_parameter_set(NX_INTERFACE * interface_ptr,NX_SHAPER_FP_PARAMETER * fp_parameter)1500 UINT nx_shaper_fp_parameter_set(NX_INTERFACE *interface_ptr, NX_SHAPER_FP_PARAMETER *fp_parameter)
1501 {
1502 UINT                       status;
1503 NX_SHAPER_DRIVER_PARAMETER set_parameter;
1504 UINT                       i;
1505 UINT                       fp_index = NX_SHAPER_INVALID_INDEX;
1506 UINT                       min_ha, max_ra;
1507 UCHAR                      express_queue_bitmap = 0, pcp;
1508 
1509 
1510     /* Set the express queue bitmap. */
1511     for (i = 0; i <= NX_SHAPER_PCP_MAX; i++)
1512     {
1513         if (fp_parameter -> express_queue_bitmap & (1 << i))
1514         {
1515             pcp = (UCHAR)i;
1516 
1517             status = nx_shaper_express_queue_set(interface_ptr, &express_queue_bitmap, pcp);
1518             if (status != NX_SUCCESS)
1519             {
1520                 return(status);
1521             }
1522         }
1523     }
1524     fp_parameter -> express_queue_bitmap = express_queue_bitmap;
1525 
1526     /* Set the object(fp_param) of NX_SHAPER_FP_PARAMETER */
1527     set_parameter.nx_shaper_driver_command = NX_SHAPER_COMMAND_PARAMETER_SET;
1528     set_parameter.shaper_type = NX_SHAPER_TYPE_FP; /* not used in driver */
1529     set_parameter.nx_ip_driver_interface = interface_ptr;
1530 
1531     nx_shaper_sdu_tx_time_get(interface_ptr, NX_SHAPER_DEFAULT_MIN_FRAGMENTABLE_SDU_SIZE, &min_ha);
1532     nx_shaper_sdu_tx_time_get(interface_ptr, NX_SHAPER_DEFAULT_MIN_SDU_SIZE, &max_ra);
1533 
1534     if (fp_parameter -> ha < min_ha)
1535     {
1536         fp_parameter -> ha = min_ha;
1537     }
1538     if (fp_parameter -> ra > max_ra)
1539     {
1540         fp_parameter -> ra = max_ra;
1541     }
1542 
1543     set_parameter.shaper_parameter = (void *)fp_parameter; /* not used in driver */
1544 
1545     for (i = 0; i < NX_SHAPER_NUMBERS; i++)
1546     {
1547         if ((interface_ptr -> shaper_container -> shaper[i] != NX_NULL) &&
1548             (interface_ptr -> shaper_container -> shaper[i] -> shaper_type == NX_SHAPER_TYPE_FP))
1549         {
1550 
1551             fp_index = i;
1552             break;
1553         }
1554     }
1555 
1556     if (fp_index == NX_SHAPER_INVALID_INDEX)
1557     {
1558         return(NX_NOT_SUCCESSFUL);
1559     }
1560 
1561     /* save the fp parameter */
1562     interface_ptr -> shaper_container -> shaper[fp_index] -> cfg_pointer = (void *)fp_parameter;
1563 
1564     status = interface_ptr -> shaper_container -> shaper[fp_index] -> shaper_driver(&set_parameter);
1565 
1566     return(status);
1567 }
1568 #endif /* NX_ENABLE_VLAN */
1569