1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef _MULTICAST_LS10_H_
25 #define _MULTICAST_LS10_H_
26 
27 #define NVSWITCH_MC_TCP_LIST_SIZE_LS10          NVSWITCH_NUM_LINKS_LS10 / 2
28 #define NVSWITCH_MC_MAX_SPRAY_LS10              16
29 #define NVSWITCH_MC_NUM_COLUMNS_LS10            6
30 #define NVSWITCH_MC_NUM_COLUMN_PAIRS_LS10       NVSWITCH_MC_NUM_COLUMNS_LS10 / 2
31 #define NVSWITCH_MC_PORTS_PER_COLUMN_LS10       11
32 #define NVSWITCH_MC_MIN_PORTS_PER_GROUP_LS10    1
33 
34 #define PRIMARY_REPLICA_NONE                    0
35 #define PRIMARY_REPLICA_EVEN                    1
36 #define PRIMARY_REPLICA_ODD                     2
37 
38 #define NVSWITCH_MC_INVALID                     0xFF
39 
40 #define NVSWITCH_MC_NULL_PORT_LS10              0xF
41 
42 //
43 // Debug and trace print toggles
44 // To enable tracing, define NVSWITCH_MC_TRACE
45 //
46 #if defined(DEVELOP) || defined(DEBUG) || defined(NV_MODS)
47 #define NVSWITCH_MC_DEBUG                       1
48 #endif
49 
50 typedef struct {
51     NvU32 column;
52     NvU32 port_offset;
53 } NVSWITCH_COLUMN_PORT_OFFSET_LS10;
54 
55 typedef struct {
56     NvU8      tcp;           // Tile column pair
57     NvU8      tcpEPort;      // Port index within even column
58     NvU8      tcpEVCHop;     // VC selection
59     NvU8      tcpOPort;      // Port index within odd column
60     NvU8      tcpOVCHop;     // VC selection
61     NvU8      roundSize;     // This is no longer part of the hardware structure. We retain it here
62                              // because it is useful in various loops
63     NvU8      primaryReplica;// This field is not in hardware. This code uses it to
64                              // track which port should be primary, so that it can make a pass over
65                              // the assembled tcp directive list and adjust portFlag and
66                              // continueRound as needed to indicate primary replica
67                              // valid values are:
68                              //         PRIMARY_REPLICA_NONE (0b00): no primary replica in tcp
69                              //         PRIMARY_REPLICA_EVEN (0b01): even (0) port is primary replica
70                              //         PRIMARY_REPLICA_ODD  (0b10): odd  (1) port is primary replica
71     NvBool    tcpEAltPath :1;// Alternative to select from odd column
72     NvBool    tcpOAltPath :1;// Alternative to select from even column
73     NvBool    lastRound   :1;// last TCP directive of the last round in this multicast string
74                              // could be multiple strings in case of spray
75     NvBool    continueRound:1;// dual meaning:
76                              // 1) if lastRound = 1 and continueRound = 1, primary replica is in
77                              // this TCP directive and portFlag = 0/1 selects even/odd port
78                              // 2) if lastRound = 0 there are more TCP directives for this round.
79     NvBool    portFlag    :1;// triple meaning:
80                              // 1) if lastRound = 1 and continueRound = 1, primary replica is in
81                              // this TCP directive and portFlag = 0/1 selects even/odd port
82                              // 2) If the previous TCP directive was not used to select the even/odd
83                              // port of its predecessor, and if portFlag of the previous TCP
84                              // directive = 1, portFlag of this TCP directive = 0/1 selects
85                              // the even/odd port of its predecessor
86                              // 3) if the previous TCP directive's portFlag = 0, and if it was not
87                              // used to select the even or odd port of its predecessor, this TCP
88                              // directive's portFlag == 1, this TCP directive contains the
89                              // primary replica, and the next TCP directive's portFlag = 0/1
90                              // selects the even/odd port of this TCP directive
91 } NVSWITCH_TCP_DIRECTIVE_LS10;
92 
93 typedef struct {
94     NvU8        index;
95     NvBool      use_extended_table;
96     NvU8        mcpl_size;
97     NvU8        num_spray_groups;
98     NvU8        ext_ptr;
99     NvBool      no_dyn_rsp;
100     NvBool      ext_ptr_valid;
101     NvBool      valid;
102     NVSWITCH_TCP_DIRECTIVE_LS10 directives[NVSWITCH_MC_TCP_LIST_SIZE_LS10];
103     NvU8        spray_group_ptrs[NVSWITCH_MC_MAX_SPRAY_LS10];
104 } NVSWITCH_MC_RID_ENTRY_LS10;
105 
106 NvlStatus nvswitch_mc_build_mcp_list_ls10(nvswitch_device *device, NvU32 *port_list,
107                                             NvU32 *ports_per_spray_string,
108                                             NvU32 *pri_replica_offsets, NvBool *replica_valid_array,
109                                             NvU8 *vchop_array,
110                                             NVSWITCH_MC_RID_ENTRY_LS10 *table_entry,
111                                             NvU32 *entries_used);
112 
113 NvlStatus nvswitch_mc_unwind_directives_ls10(nvswitch_device *device,
114                                              NVSWITCH_TCP_DIRECTIVE_LS10 directives[NVSWITCH_MC_TCP_LIST_SIZE_LS10],
115                                              NvU32 ports[NVSWITCH_MC_MAX_PORTS],
116                                              NvU8 vc_hop[NVSWITCH_MC_MAX_PORTS],
117                                              NvU32 ports_per_spray_group[NVSWITCH_MC_MAX_SPRAYGROUPS],
118                                              NvU32 replica_offset[NVSWITCH_MC_MAX_SPRAYGROUPS],
119                                              NvBool replica_valid[NVSWITCH_MC_MAX_SPRAYGROUPS]);
120 
121 NvlStatus nvswitch_mc_invalidate_mc_rid_entry_ls10(nvswitch_device *device, NvU32 port, NvU32 index,
122                                                     NvBool use_extended_table, NvBool zero);
123 
124 NvlStatus nvswitch_mc_program_mc_rid_entry_ls10(nvswitch_device *device, NvU32 port,
125                                                 NVSWITCH_MC_RID_ENTRY_LS10 *table_entry,
126                                                 NvU32 directive_list_size);
127 
128 NvlStatus nvswitch_mc_read_mc_rid_entry_ls10(nvswitch_device *device, NvU32 port,
129                                              NVSWITCH_MC_RID_ENTRY_LS10 *table_entry);
130 #endif //_MULTICAST_LS10_H_
131