fix cleanup flow for memfree devices
[etherboot.git] / src / drivers / net / mlx_ipoib / cmdif_mt25218.c
1 /*
2   This software is available to you under a choice of one of two
3   licenses.  You may choose to be licensed under the terms of the GNU
4   General Public License (GPL) Version 2, available at
5   <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6   license, available in the LICENSE.TXT file accompanying this
7   software.  These details are also available at
8   <http://openib.org/license.html>.
9
10   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   SOFTWARE.
18
19   Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20 */
21 #include "cmdif.h"
22 #include "cmdif_priv.h"
23 #include "mt25218.h"
24
25 /*
26  *  cmd_write_mgm
27  */
28 static int cmd_write_mgm(void *mg, __u16 index)
29 {
30         int rc;
31         command_fields_t cmd_desc;
32
33         memset(&cmd_desc, 0, sizeof cmd_desc);
34         cmd_desc.opcode = MEMFREE_CMD_WRITE_MGM;
35         cmd_desc.in_trans = TRANS_MAILBOX;
36         cmd_desc.in_param_size = MT_STRUCT_SIZE(arbelprm_mgm_entry_st);
37         cmd_desc.in_param = (__u32 *) mg;
38         cmd_desc.input_modifier = index;
39
40         rc = cmd_invoke(&cmd_desc);
41
42         return rc;
43 }
44
45 /*
46  *  cmd_mod_stat_cfg
47  */
48 static int cmd_mod_stat_cfg(void)
49 {
50         int rc;
51         command_fields_t cmd_desc;
52
53         memset(&cmd_desc, 0, sizeof cmd_desc);
54         cmd_desc.opcode = MEMFREE_CMD_MOD_STAT_CFG;
55         cmd_desc.in_trans = TRANS_MAILBOX;
56         cmd_desc.in_param_size = MT_STRUCT_SIZE(arbelprm_mod_stat_cfg_st);
57         cmd_desc.in_param = get_inprm_buf();
58         memset(cmd_desc.in_param, 0, cmd_desc.in_param_size);
59
60         rc = cmd_invoke(&cmd_desc);
61
62         return rc;
63 }
64
65 /*
66  *  cmd_query_fw
67  */
68 static int cmd_query_fw(struct query_fw_st *qfw)
69 {
70         int rc;
71         command_fields_t cmd_desc;
72
73         memset(&cmd_desc, 0, sizeof cmd_desc);
74
75         cmd_desc.opcode = MEMFREE_CMD_QUERY_FW;
76         cmd_desc.out_trans = TRANS_MAILBOX;
77         cmd_desc.out_param = get_outprm_buf();
78         cmd_desc.out_param_size = MT_STRUCT_SIZE(arbelprm_query_fw_st);
79
80         rc = cmd_invoke(&cmd_desc);
81         if (!rc) {
82                 qfw->fw_rev_major =
83                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, fw_rev_major);
84                 qfw->fw_rev_minor =
85                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, fw_rev_minor);
86                 qfw->fw_rev_subminor =
87                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, fw_rev_subminor);
88
89                 qfw->error_buf_start_h =
90                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, error_buf_start_h);
91                 qfw->error_buf_start_l =
92                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, error_buf_start_l);
93                 qfw->error_buf_size =
94                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, error_buf_size);
95
96                 qfw->fw_pages =
97                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st, fw_pages);
98                 qfw->eq_ci_table.addr_h =
99                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st,
100                            eq_set_ci_base_addr_h);
101                 qfw->eq_ci_table.addr_l =
102                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st,
103                            eq_set_ci_base_addr_l);
104                 qfw->clear_int_addr.addr_h =
105                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st,
106                            clr_int_base_addr_h);
107                 qfw->clear_int_addr.addr_l =
108                     EX_FLD(cmd_desc.out_param, arbelprm_query_fw_st,
109                            clr_int_base_addr_l);
110         }
111
112         return rc;
113 }
114
115 /*
116  *  cmd_query_adapter
117  */
118 static int cmd_query_adapter(struct query_adapter_st *qa)
119 {
120         int rc;
121         command_fields_t cmd_desc;
122
123         memset(&cmd_desc, 0, sizeof cmd_desc);
124
125         cmd_desc.opcode = MEMFREE_CMD_QUERY_ADAPTER;
126         cmd_desc.out_trans = TRANS_MAILBOX;
127         cmd_desc.out_param = get_outprm_buf();
128         cmd_desc.out_param_size = MT_STRUCT_SIZE(arbelprm_query_adapter_st);
129
130         rc = cmd_invoke(&cmd_desc);
131         if (!rc) {
132                 qa->intapin =
133                     EX_FLD(cmd_desc.out_param, arbelprm_query_adapter_st,
134                            intapin);
135         }
136
137         return rc;
138 }
139
140 /*
141  *  cmd_enable_lam
142  */
143 static int cmd_enable_lam(void)
144 {
145         int rc;
146         command_fields_t cmd_desc;
147
148         memset(&cmd_desc, 0, sizeof cmd_desc);
149
150         cmd_desc.opcode = MEMFREE_CMD_ENABLE_LAM;
151         cmd_desc.opcode_modifier = 1;   /* zero locally attached memory */
152         cmd_desc.input_modifier = 0;    /* disable fast refresh */
153         cmd_desc.out_trans = TRANS_MAILBOX;
154         cmd_desc.out_param = get_outprm_buf();
155         cmd_desc.out_param_size = MT_STRUCT_SIZE(arbelprm_enable_lam_st);
156
157         rc = cmd_invoke(&cmd_desc);
158         if (rc) {
159         }
160
161         return rc;
162 }
163
164 /*
165  *  cmd_map_fa
166  */
167 static int cmd_map_fa(struct map_icm_st *map_fa_p)
168 {
169         int rc;
170         command_fields_t cmd_desc;
171         unsigned int in_param_size, i;
172         unsigned long off;
173
174         if (map_fa_p->num_vpm > MAX_VPM_PER_CALL) {
175                 return -1;
176         }
177
178         memset(&cmd_desc, 0, sizeof cmd_desc);
179
180         cmd_desc.opcode = MEMFREE_CMD_MAP_FA;
181         cmd_desc.input_modifier = map_fa_p->num_vpm;
182         cmd_desc.in_trans = TRANS_MAILBOX;
183         cmd_desc.in_param = get_inprm_buf();
184         in_param_size =
185             MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) *
186             map_fa_p->num_vpm;
187         cmd_desc.in_param_size = in_param_size;
188         memset(cmd_desc.in_param, 0, in_param_size);
189
190         for (i = 0; i < map_fa_p->num_vpm; ++i) {
191                 off = (unsigned long)(cmd_desc.in_param) +
192                     MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) * i;
193                 INS_FLD(map_fa_p->vpm_arr[i].va_h, off,
194                         arbelprm_virtual_physical_mapping_st, va_h);
195                 INS_FLD(map_fa_p->vpm_arr[i].va_l >> 12, off,
196                         arbelprm_virtual_physical_mapping_st, va_l);
197                 INS_FLD(map_fa_p->vpm_arr[i].pa_h, off,
198                         arbelprm_virtual_physical_mapping_st, pa_h);
199                 INS_FLD(map_fa_p->vpm_arr[i].pa_l >> 12, off,
200                         arbelprm_virtual_physical_mapping_st, pa_l);
201                 INS_FLD(map_fa_p->vpm_arr[i].log2_size, off,
202                         arbelprm_virtual_physical_mapping_st, log2size);
203         }
204
205         rc = cmd_invoke(&cmd_desc);
206
207         return rc;
208 }
209
210 /*
211  *  cmd_unmap_fa
212  */
213 static int cmd_unmap_fa(void)
214 {
215         int rc;
216         command_fields_t cmd_desc;
217
218         memset(&cmd_desc, 0, sizeof cmd_desc);
219
220         cmd_desc.opcode = MEMFREE_CMD_UNMAP_FA;
221
222         rc = cmd_invoke(&cmd_desc);
223
224         return rc;
225 }
226
227 /*
228  *  cmd_run_fw
229  */
230 static int cmd_run_fw(void)
231 {
232         int rc;
233         command_fields_t cmd_desc;
234
235         memset(&cmd_desc, 0, sizeof cmd_desc);
236
237         cmd_desc.opcode = MEMFREE_CMD_RUN_FW;
238         rc = cmd_invoke(&cmd_desc);
239
240         return rc;
241 }
242
243 /*
244  *  cmd_set_icm_size
245  */
246 static int cmd_set_icm_size(__u32 icm_size, __u32 * aux_pages_p)
247 {
248         int rc;
249         command_fields_t cmd_desc;
250         __u32 iprm[2], oprm[2];
251
252         memset(&cmd_desc, 0, sizeof cmd_desc);
253
254         cmd_desc.opcode = MEMFREE_CMD_SET_ICM_SIZE;
255
256         iprm[1] = icm_size;
257         iprm[0] = 0;
258         cmd_desc.in_trans = TRANS_IMMEDIATE;
259         cmd_desc.in_param = iprm;
260         cmd_desc.out_trans = TRANS_IMMEDIATE;
261         cmd_desc.out_param = oprm;
262         rc = cmd_invoke(&cmd_desc);
263         if (!rc) {
264                 if (oprm[0]) {
265                         /* too many pages required */
266                         return -1;
267                 }
268                 *aux_pages_p = oprm[1];
269         }
270
271         return rc;
272 }
273
274 /*
275  *  cmd_map_icm_aux
276  */
277 static int cmd_map_icm_aux(struct map_icm_st *map_icm_aux_p)
278 {
279         int rc;
280         command_fields_t cmd_desc;
281         unsigned int in_param_size, i;
282         unsigned long off;
283
284         if (map_icm_aux_p->num_vpm > MAX_VPM_PER_CALL) {
285                 return -1;
286         }
287
288         memset(&cmd_desc, 0, sizeof cmd_desc);
289
290         cmd_desc.opcode = MEMFREE_CMD_MAP_ICM_AUX;
291         cmd_desc.input_modifier = map_icm_aux_p->num_vpm;
292         cmd_desc.in_trans = TRANS_MAILBOX;
293         cmd_desc.in_param = get_inprm_buf();
294         in_param_size =
295             MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) *
296             map_icm_aux_p->num_vpm;
297         cmd_desc.in_param_size = in_param_size;
298         memset(cmd_desc.in_param, 0, in_param_size);
299
300         for (i = 0; i < map_icm_aux_p->num_vpm; ++i) {
301                 off = (unsigned long)(cmd_desc.in_param) +
302                     MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) * i;
303                 INS_FLD(map_icm_aux_p->vpm_arr[i].va_h, off,
304                         arbelprm_virtual_physical_mapping_st, va_h);
305                 INS_FLD(map_icm_aux_p->vpm_arr[i].va_l >> 12, off,
306                         arbelprm_virtual_physical_mapping_st, va_l);
307                 INS_FLD(map_icm_aux_p->vpm_arr[i].pa_h, off,
308                         arbelprm_virtual_physical_mapping_st, pa_h);
309                 INS_FLD(map_icm_aux_p->vpm_arr[i].pa_l >> 12, off,
310                         arbelprm_virtual_physical_mapping_st, pa_l);
311                 INS_FLD(map_icm_aux_p->vpm_arr[i].log2_size, off,
312                         arbelprm_virtual_physical_mapping_st, log2size);
313         }
314
315         rc = cmd_invoke(&cmd_desc);
316
317         return rc;
318 }
319
320
321 /*
322  *  cmd_unmap_icm_aux
323  */
324 static int cmd_unmap_icm_aux(void)
325 {
326         int rc;
327         command_fields_t cmd_desc;
328
329         memset(&cmd_desc, 0, sizeof cmd_desc);
330
331         cmd_desc.opcode = MEMFREE_CMD_UNMAP_ICM_AUX;
332
333         rc = cmd_invoke(&cmd_desc);
334
335         return rc;
336 }
337
338 /*
339  *  cmd_map_icm
340  */
341 static int cmd_map_icm(struct map_icm_st *map_icm_p)
342 {
343         int rc;
344         command_fields_t cmd_desc;
345         unsigned int in_param_size, i;
346         unsigned long off;
347
348         if (map_icm_p->num_vpm > MAX_VPM_PER_CALL) {
349                 return -1;
350         }
351
352         memset(&cmd_desc, 0, sizeof cmd_desc);
353
354         cmd_desc.opcode = MEMFREE_CMD_MAP_ICM;
355         cmd_desc.input_modifier = map_icm_p->num_vpm;
356         cmd_desc.in_trans = TRANS_MAILBOX;
357         cmd_desc.in_param = get_inprm_buf();
358         in_param_size =
359             MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) *
360             map_icm_p->num_vpm;
361         cmd_desc.in_param_size = in_param_size;
362         memset(cmd_desc.in_param, 0, in_param_size);
363
364         for (i = 0; i < map_icm_p->num_vpm; ++i) {
365                 off = (unsigned long)(cmd_desc.in_param) +
366                     MT_STRUCT_SIZE(arbelprm_virtual_physical_mapping_st) * i;
367                 INS_FLD(map_icm_p->vpm_arr[i].va_h, off,
368                         arbelprm_virtual_physical_mapping_st, va_h);
369                 INS_FLD(map_icm_p->vpm_arr[i].va_l >> 12, off,
370                         arbelprm_virtual_physical_mapping_st, va_l);
371                 INS_FLD(map_icm_p->vpm_arr[i].pa_h, off,
372                         arbelprm_virtual_physical_mapping_st, pa_h);
373                 INS_FLD(map_icm_p->vpm_arr[i].pa_l >> 12, off,
374                         arbelprm_virtual_physical_mapping_st, pa_l);
375                 INS_FLD(map_icm_p->vpm_arr[i].log2_size, off,
376                         arbelprm_virtual_physical_mapping_st, log2size);
377         }
378
379         rc = cmd_invoke(&cmd_desc);
380
381         return rc;
382 }
383
384
385
386 /*
387  *  cmd_unmap_icm
388  */
389 static int cmd_unmap_icm(struct map_icm_st *map_icm_p)
390 {
391         int rc;
392         command_fields_t cmd_desc;
393         __u32 iprm[2];
394
395         memset(&cmd_desc, 0, sizeof cmd_desc);
396
397         cmd_desc.opcode = MEMFREE_CMD_UNMAP_ICM;
398         iprm[0] = map_icm_p->vpm_arr[0].va_h;
399         iprm[1] = map_icm_p->vpm_arr[0].va_l;
400         cmd_desc.in_param = iprm;
401         cmd_desc.in_trans = TRANS_IMMEDIATE;
402         cmd_desc.input_modifier = 1 << map_icm_p->vpm_arr[0].log2_size;
403
404         rc = cmd_invoke(&cmd_desc);
405
406         return rc;
407 }
408
409 /*
410  *  cmd_query_dev_lim
411  */
412 static int cmd_query_dev_lim(struct dev_lim_st *dev_lim_p)
413 {
414         int rc;
415         command_fields_t cmd_desc;
416
417         memset(&cmd_desc, 0, sizeof cmd_desc);
418
419         cmd_desc.opcode = MEMFREE_CMD_QUERY_DEV_LIM;
420         cmd_desc.out_trans = TRANS_MAILBOX;
421         cmd_desc.out_param = get_outprm_buf();
422         cmd_desc.out_param_size = MT_STRUCT_SIZE(arbelprm_query_dev_lim_st);
423
424         rc = cmd_invoke(&cmd_desc);
425         if (!rc) {
426                 dev_lim_p->log2_rsvd_qps =
427                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
428                            log2_rsvd_qps);
429                 dev_lim_p->qpc_entry_sz =
430                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
431                            qpc_entry_sz);
432
433                 dev_lim_p->log2_rsvd_srqs =
434                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
435                            log2_rsvd_srqs);
436                 dev_lim_p->srq_entry_sz =
437                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
438                            srq_entry_sz);
439
440                 dev_lim_p->log2_rsvd_ees =
441                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
442                            log2_rsvd_ees);
443                 dev_lim_p->eec_entry_sz =
444                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
445                            eec_entry_sz);
446
447                 dev_lim_p->log2_rsvd_cqs =
448                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
449                            log2_rsvd_cqs);
450                 dev_lim_p->cqc_entry_sz =
451                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
452                            cqc_entry_sz);
453
454                 dev_lim_p->log2_rsvd_mtts =
455                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
456                            log2_rsvd_mtts);
457                 dev_lim_p->mtt_entry_sz =
458                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
459                            mtt_entry_sz);
460
461                 dev_lim_p->log2_rsvd_mrws =
462                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
463                            log2_rsvd_mrws);
464                 dev_lim_p->mpt_entry_sz =
465                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
466                            mpt_entry_sz);
467
468                 dev_lim_p->log2_rsvd_rdbs =
469                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
470                            log2_rsvd_rdbs);
471
472                 dev_lim_p->eqc_entry_sz =
473                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
474                            eqc_entry_sz);
475
476                 dev_lim_p->max_icm_size_l =
477                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
478                            max_icm_size_l);
479                 dev_lim_p->max_icm_size_h =
480                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
481                            max_icm_size_h);
482
483                 dev_lim_p->num_rsvd_uars =
484                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
485                            num_rsvd_uars);
486                 dev_lim_p->uar_sz =
487                     EX_FLD(cmd_desc.out_param, arbelprm_query_dev_lim_st,
488                            uar_sz);
489         }
490
491         return rc;
492 }