14
14
struct mlx5_sd {
15
15
u32 group_id ;
16
16
u8 host_buses ;
17
+ struct mlx5_devcom_comp_dev * devcom ;
18
+ bool primary ;
19
+ union {
20
+ struct { /* primary */
21
+ struct mlx5_core_dev * secondaries [MLX5_SD_MAX_GROUP_SZ - 1 ];
22
+ };
23
+ struct { /* secondary */
24
+ struct mlx5_core_dev * primary_dev ;
25
+ };
26
+ };
17
27
};
18
28
19
29
static int mlx5_sd_get_host_buses (struct mlx5_core_dev * dev )
@@ -26,13 +36,29 @@ static int mlx5_sd_get_host_buses(struct mlx5_core_dev *dev)
26
36
return sd -> host_buses ;
27
37
}
28
38
39
+ static struct mlx5_core_dev * mlx5_sd_get_primary (struct mlx5_core_dev * dev )
40
+ {
41
+ struct mlx5_sd * sd = mlx5_get_sd (dev );
42
+
43
+ if (!sd )
44
+ return dev ;
45
+
46
+ return sd -> primary ? dev : sd -> primary_dev ;
47
+ }
48
+
29
49
struct mlx5_core_dev *
30
50
mlx5_sd_primary_get_peer (struct mlx5_core_dev * primary , int idx )
31
51
{
52
+ struct mlx5_sd * sd ;
53
+
32
54
if (idx == 0 )
33
55
return primary ;
34
56
35
- return NULL ;
57
+ if (idx >= mlx5_sd_get_host_buses (primary ))
58
+ return NULL ;
59
+
60
+ sd = mlx5_get_sd (primary );
61
+ return sd -> secondaries [idx - 1 ];
36
62
}
37
63
38
64
int mlx5_sd_ch_ix_get_dev_ix (struct mlx5_core_dev * dev , int ch_ix )
@@ -136,15 +162,93 @@ static void sd_cleanup(struct mlx5_core_dev *dev)
136
162
kfree (sd );
137
163
}
138
164
165
+ static int sd_register (struct mlx5_core_dev * dev )
166
+ {
167
+ struct mlx5_devcom_comp_dev * devcom , * pos ;
168
+ struct mlx5_core_dev * peer , * primary ;
169
+ struct mlx5_sd * sd , * primary_sd ;
170
+ int err , i ;
171
+
172
+ sd = mlx5_get_sd (dev );
173
+ devcom = mlx5_devcom_register_component (dev -> priv .devc , MLX5_DEVCOM_SD_GROUP ,
174
+ sd -> group_id , NULL , dev );
175
+ if (!devcom )
176
+ return - ENOMEM ;
177
+
178
+ sd -> devcom = devcom ;
179
+
180
+ if (mlx5_devcom_comp_get_size (devcom ) != sd -> host_buses )
181
+ return 0 ;
182
+
183
+ mlx5_devcom_comp_lock (devcom );
184
+ mlx5_devcom_comp_set_ready (devcom , true);
185
+ mlx5_devcom_comp_unlock (devcom );
186
+
187
+ if (!mlx5_devcom_for_each_peer_begin (devcom )) {
188
+ err = - ENODEV ;
189
+ goto err_devcom_unreg ;
190
+ }
191
+
192
+ primary = dev ;
193
+ mlx5_devcom_for_each_peer_entry (devcom , peer , pos )
194
+ if (peer -> pdev -> bus -> number < primary -> pdev -> bus -> number )
195
+ primary = peer ;
196
+
197
+ primary_sd = mlx5_get_sd (primary );
198
+ primary_sd -> primary = true;
199
+ i = 0 ;
200
+ /* loop the secondaries */
201
+ mlx5_devcom_for_each_peer_entry (primary_sd -> devcom , peer , pos ) {
202
+ struct mlx5_sd * peer_sd = mlx5_get_sd (peer );
203
+
204
+ primary_sd -> secondaries [i ++ ] = peer ;
205
+ peer_sd -> primary = false;
206
+ peer_sd -> primary_dev = primary ;
207
+ }
208
+
209
+ mlx5_devcom_for_each_peer_end (devcom );
210
+ return 0 ;
211
+
212
+ err_devcom_unreg :
213
+ mlx5_devcom_comp_lock (sd -> devcom );
214
+ mlx5_devcom_comp_set_ready (sd -> devcom , false);
215
+ mlx5_devcom_comp_unlock (sd -> devcom );
216
+ mlx5_devcom_unregister_component (sd -> devcom );
217
+ return err ;
218
+ }
219
+
220
+ static void sd_unregister (struct mlx5_core_dev * dev )
221
+ {
222
+ struct mlx5_sd * sd = mlx5_get_sd (dev );
223
+
224
+ mlx5_devcom_comp_lock (sd -> devcom );
225
+ mlx5_devcom_comp_set_ready (sd -> devcom , false);
226
+ mlx5_devcom_comp_unlock (sd -> devcom );
227
+ mlx5_devcom_unregister_component (sd -> devcom );
228
+ }
229
+
139
230
int mlx5_sd_init (struct mlx5_core_dev * dev )
140
231
{
232
+ struct mlx5_sd * sd = mlx5_get_sd (dev );
141
233
int err ;
142
234
143
235
err = sd_init (dev );
144
236
if (err )
145
237
return err ;
146
238
239
+ sd = mlx5_get_sd (dev );
240
+ if (!sd )
241
+ return 0 ;
242
+
243
+ err = sd_register (dev );
244
+ if (err )
245
+ goto err_sd_cleanup ;
246
+
147
247
return 0 ;
248
+
249
+ err_sd_cleanup :
250
+ sd_cleanup (dev );
251
+ return err ;
148
252
}
149
253
150
254
void mlx5_sd_cleanup (struct mlx5_core_dev * dev )
@@ -154,12 +258,26 @@ void mlx5_sd_cleanup(struct mlx5_core_dev *dev)
154
258
if (!sd )
155
259
return ;
156
260
261
+ sd_unregister (dev );
157
262
sd_cleanup (dev );
158
263
}
159
264
160
265
struct auxiliary_device * mlx5_sd_get_adev (struct mlx5_core_dev * dev ,
161
266
struct auxiliary_device * adev ,
162
267
int idx )
163
268
{
164
- return adev ;
269
+ struct mlx5_sd * sd = mlx5_get_sd (dev );
270
+ struct mlx5_core_dev * primary ;
271
+
272
+ if (!sd )
273
+ return adev ;
274
+
275
+ if (!mlx5_devcom_comp_is_ready (sd -> devcom ))
276
+ return NULL ;
277
+
278
+ primary = mlx5_sd_get_primary (dev );
279
+ if (dev == primary )
280
+ return adev ;
281
+
282
+ return & primary -> priv .adev [idx ]-> adev ;
165
283
}
0 commit comments