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>.
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
19 Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
23 #include "ib_driver.h"
26 #define MOD_INC(counter, max_count) (counter) = ((counter)+1) & ((max_count) - 1)
28 #define breakpoint {volatile __u32 *p=(__u32 *)0x1234;printf("breakpoint\n");do {} while((*p) != 0x1234);}
30 #define WRITE_BYTE_VOL(addr, off, val) \
32 (*((volatile __u8 *)(((volatile __u8 *)(addr)) + off))) = (val); \
35 #define WRITE_WORD_VOL(addr, off, val) \
37 (*((volatile __u16 *)(((volatile __u8 *)(addr)) + off))) = (val); \
40 #define WRITE_DWORD_VOL(addr, off, val) \
42 (*((volatile __u32 *)(((volatile __u8 *)(addr)) + off))) = (val); \
45 struct device_buffers_st {
46 /* inprm and outprm do not have alignnemet constraint sice that
47 is acheived programatically */
48 u8 inprm_buf[INPRM_BUF_SZ];
49 u8 outprm_buf[OUTPRM_BUF_SZ];
50 union recv_wqe_u mads_qp_rcv_queue[NUM_MADS_RCV_WQES]
51 __attribute__ ((aligned(RECV_WQE_U_ALIGN)));
52 union recv_wqe_u ipoib_qp_rcv_queue[NUM_IPOIB_RCV_WQES]
53 __attribute__ ((aligned(RECV_WQE_U_ALIGN)));
54 union ud_send_wqe_u mads_qp_snd_queue[NUM_MADS_SND_WQES]
55 __attribute__ ((aligned(UD_SEND_WQE_U_ALIGN)));
56 union ud_send_wqe_u ipoib_qp_snd_queue[NUM_IPOIB_SND_WQES]
57 __attribute__ ((aligned(UD_SEND_WQE_U_ALIGN)));
58 struct eqe_t eq_buf[1 << LOG2_EQ_SZ]
59 __attribute__ ((aligned(sizeof(struct eqe_t))));
60 union cqe_st mads_snd_cq_buf[NUM_MADS_SND_CQES]
61 __attribute__ ((aligned(sizeof(union cqe_st))));
62 union cqe_st ipoib_snd_cq_buf[NUM_IPOIB_SND_CQES]
63 __attribute__ ((aligned(sizeof(union cqe_st))));
64 union cqe_st mads_rcv_cq_buf[NUM_MADS_RCV_CQES]
65 __attribute__ ((aligned(sizeof(union cqe_st))));
66 union cqe_st ipoib_rcv_cq_buf[NUM_IPOIB_RCV_CQES]
67 __attribute__ ((aligned(sizeof(union cqe_st))));
68 union ud_av_u av_array[NUM_AVS];
69 } __attribute__ ((packed));
71 #define STRUCT_ALIGN_SZ 4096
72 #define SRC_BUF_SZ (sizeof(struct device_buffers_st) + STRUCT_ALIGN_SZ - 1)
74 /* the following must be kept in this order
75 for the memory region to cover the buffers */
76 static u8 src_buf[SRC_BUF_SZ];
77 static struct ib_buffers_st ib_buffers;
78 static __u32 memreg_size;
79 /* end of order constraint */
81 struct phys_mem_desc_st {
86 static struct phys_mem_desc_st phys_mem;
88 static struct dev_pci_struct memfree_pci_dev;
89 static struct device_buffers_st *dev_buffers_p;
90 static struct device_ib_data_st dev_ib_data;
92 static int gw_write_cr(__u32 addr, __u32 data)
94 writel(htonl(data), memfree_pci_dev.cr_space + addr);
98 static int gw_read_cr(__u32 addr, __u32 * result)
100 *result = ntohl(readl(memfree_pci_dev.cr_space + addr));
104 static int reset_hca(void)
106 return gw_write_cr(MEMFREE_RESET_OFFSET, 1);
109 static int ib_device_init(struct pci_device *dev)
116 memset(&dev_ib_data, 0, sizeof dev_ib_data);
119 tprintf("bus=%d devfn=0x%x", dev->bus, dev->devfn);
120 for (i = 0; i < 6; ++i) {
121 memfree_pci_dev.dev.bar[i] =
122 pci_bar_start(dev, PCI_BASE_ADDRESS_0 + (i << 2));
123 tprintf("bar[%d]= 0x%08lx", i, memfree_pci_dev.dev.bar[i]);
127 /* save config space */
128 for (i = 0; i < 64; ++i) {
129 rc = pci_read_config_dword(dev, i << 2,
130 &memfree_pci_dev.dev.
131 dev_config_space[i]);
136 tprintf("config[%d]= 0x%08lx", i << 2,
137 memfree_pci_dev.dev.dev_config_space[i]);
141 memfree_pci_dev.dev.dev = dev;
144 memfree_pci_dev.cr_space =
145 ioremap(memfree_pci_dev.dev.bar[0], 0x100000);
146 if (!memfree_pci_dev.cr_space) {
152 memfree_pci_dev.uar =
153 ioremap(memfree_pci_dev.dev.bar[2] + UAR_IDX * 0x1000, 0x1000);
154 if (!memfree_pci_dev.uar) {
158 tprintf("uar_base (pa:va) = 0x%lx 0x%lx",
159 memfree_pci_dev.dev.bar[2] + UAR_IDX * 0x1000,
160 memfree_pci_dev.uar);
167 static inline unsigned long lalign(unsigned long buf, unsigned long align)
169 return (unsigned long)((buf + align - 1) &
170 (~(((unsigned long)align) - 1)));
173 static int init_dev_data(void)
176 unsigned long reserve_size = 32 * 1024 * 1024;
178 tmp = lalign(virt_to_bus(src_buf), STRUCT_ALIGN_SZ);
180 dev_buffers_p = bus_to_virt(tmp);
181 memreg_size = (__u32) (&memreg_size) - (__u32) dev_buffers_p;
182 tprintf("src_buf=0x%lx, dev_buffers_p=0x%lx, memreg_size=0x%x", src_buf,
183 dev_buffers_p, memreg_size);
185 tprintf("inprm: va=0x%lx, pa=0x%lx", dev_buffers_p->inprm_buf,
186 virt_to_bus(dev_buffers_p->inprm_buf));
187 tprintf("outprm: va=0x%lx, pa=0x%lx", dev_buffers_p->outprm_buf,
188 virt_to_bus(dev_buffers_p->outprm_buf));
191 (virt_to_phys(_text) - reserve_size) & (~(reserve_size - 1));
198 static int restore_config(void)
203 for (i = 0; i < 64; ++i) {
204 if (i != 22 && i != 23) {
205 rc = pci_write_config_dword(memfree_pci_dev.dev.dev,
208 dev_config_space[i]);
217 static void prep_init_hca_buf(struct init_hca_st *init_hca_p, void *buf)
222 memset(buf, 0, MT_STRUCT_SIZE(arbelprm_init_hca_st));
224 ptr = (unsigned long)buf +
225 MT_BYTE_OFFSET(arbelprm_init_hca_st,
226 qpc_eec_cqc_eqc_rdb_parameters);
228 shift = 32 - MT_BIT_SIZE(arbelprm_qpcbaseaddr_st, qpc_base_addr_l);
229 INS_FLD(init_hca_p->qpc_base_addr_h, ptr, arbelprm_qpcbaseaddr_st,
231 INS_FLD(init_hca_p->qpc_base_addr_l >> shift, ptr,
232 arbelprm_qpcbaseaddr_st, qpc_base_addr_l);
233 INS_FLD(init_hca_p->log_num_of_qp, ptr, arbelprm_qpcbaseaddr_st,
236 shift = 32 - MT_BIT_SIZE(arbelprm_qpcbaseaddr_st, eec_base_addr_l);
237 INS_FLD(init_hca_p->eec_base_addr_h, ptr, arbelprm_qpcbaseaddr_st,
239 INS_FLD(init_hca_p->eec_base_addr_l >> shift, ptr,
240 arbelprm_qpcbaseaddr_st, eec_base_addr_l);
241 INS_FLD(init_hca_p->log_num_of_ee, ptr, arbelprm_qpcbaseaddr_st,
244 shift = 32 - MT_BIT_SIZE(arbelprm_qpcbaseaddr_st, srqc_base_addr_l);
245 INS_FLD(init_hca_p->srqc_base_addr_h, ptr, arbelprm_qpcbaseaddr_st,
247 INS_FLD(init_hca_p->srqc_base_addr_l >> shift, ptr,
248 arbelprm_qpcbaseaddr_st, srqc_base_addr_l);
249 INS_FLD(init_hca_p->log_num_of_srq, ptr, arbelprm_qpcbaseaddr_st,
252 shift = 32 - MT_BIT_SIZE(arbelprm_qpcbaseaddr_st, cqc_base_addr_l);
253 INS_FLD(init_hca_p->cqc_base_addr_h, ptr, arbelprm_qpcbaseaddr_st,
255 INS_FLD(init_hca_p->cqc_base_addr_l >> shift, ptr,
256 arbelprm_qpcbaseaddr_st, cqc_base_addr_l);
257 INS_FLD(init_hca_p->log_num_of_cq, ptr, arbelprm_qpcbaseaddr_st,
260 INS_FLD(init_hca_p->eqpc_base_addr_h, ptr, arbelprm_qpcbaseaddr_st,
262 INS_FLD(init_hca_p->eqpc_base_addr_l, ptr, arbelprm_qpcbaseaddr_st,
265 INS_FLD(init_hca_p->eeec_base_addr_h, ptr, arbelprm_qpcbaseaddr_st,
267 INS_FLD(init_hca_p->eeec_base_addr_l, ptr, arbelprm_qpcbaseaddr_st,
270 shift = 32 - MT_BIT_SIZE(arbelprm_qpcbaseaddr_st, eqc_base_addr_l);
271 INS_FLD(init_hca_p->eqc_base_addr_h, ptr, arbelprm_qpcbaseaddr_st,
273 INS_FLD(init_hca_p->eqc_base_addr_l >> shift, ptr,
274 arbelprm_qpcbaseaddr_st, eqc_base_addr_l);
275 INS_FLD(init_hca_p->log_num_of_eq, ptr, arbelprm_qpcbaseaddr_st,
278 INS_FLD(init_hca_p->rdb_base_addr_h, ptr, arbelprm_qpcbaseaddr_st,
280 INS_FLD(init_hca_p->rdb_base_addr_l, ptr, arbelprm_qpcbaseaddr_st,
283 ptr = (unsigned long)buf +
284 MT_BYTE_OFFSET(arbelprm_init_hca_st, multicast_parameters);
286 INS_FLD(init_hca_p->mc_base_addr_h, ptr, arbelprm_multicastparam_st,
288 INS_FLD(init_hca_p->mc_base_addr_l, ptr, arbelprm_multicastparam_st,
290 INS_FLD(init_hca_p->log_mc_table_entry_sz, ptr,
291 arbelprm_multicastparam_st, log_mc_table_entry_sz);
292 INS_FLD(init_hca_p->mc_table_hash_sz, ptr, arbelprm_multicastparam_st,
294 INS_FLD(init_hca_p->log_mc_table_sz, ptr, arbelprm_multicastparam_st,
297 ptr = (unsigned long)buf +
298 MT_BYTE_OFFSET(arbelprm_init_hca_st, tpt_parameters);
300 INS_FLD(init_hca_p->mpt_base_addr_h, ptr, arbelprm_tptparams_st,
302 INS_FLD(init_hca_p->mpt_base_addr_l, ptr, arbelprm_tptparams_st,
304 INS_FLD(init_hca_p->log_mpt_sz, ptr, arbelprm_tptparams_st, log_mpt_sz);
305 INS_FLD(init_hca_p->mtt_base_addr_h, ptr, arbelprm_tptparams_st,
307 INS_FLD(init_hca_p->mtt_base_addr_l, ptr, arbelprm_tptparams_st,
310 ptr = (unsigned long)buf +
311 MT_BYTE_OFFSET(arbelprm_init_hca_st, uar_parameters);
313 INS_FLD(init_hca_p->log_max_uars, ptr, arbelprm_uar_params_st,
318 static void prep_sw2hw_mpt_buf(void *buf, __u32 mkey)
320 INS_FLD(1, buf, arbelprm_mpt_st, lw);
321 INS_FLD(1, buf, arbelprm_mpt_st, lr);
322 INS_FLD(1, buf, arbelprm_mpt_st, pa);
323 INS_FLD(1, buf, arbelprm_mpt_st, r_w);
324 INS_FLD(mkey, buf, arbelprm_mpt_st, mem_key);
325 INS_FLD(GLOBAL_PD, buf, arbelprm_mpt_st, pd);
326 INS_FLD(virt_to_bus(dev_buffers_p), buf, arbelprm_mpt_st,
328 INS_FLD(memreg_size, buf, arbelprm_mpt_st, reg_wnd_len_l);
331 static void prep_sw2hw_eq_buf(void *buf, struct eqe_t *eq_buf)
333 memset(buf, 0, MT_STRUCT_SIZE(arbelprm_eqc_st));
335 INS_FLD(0xa, buf, arbelprm_eqc_st, st); /* fired */
336 INS_FLD(virt_to_bus(eq_buf), buf, arbelprm_eqc_st, start_address_l);
337 INS_FLD(LOG2_EQ_SZ, buf, arbelprm_eqc_st, log_eq_size);
338 INS_FLD(GLOBAL_PD, buf, arbelprm_eqc_st, pd);
339 INS_FLD(dev_ib_data.mkey, buf, arbelprm_eqc_st, lkey);
342 static void init_eq_buf(void *eq_buf)
344 struct eqe_t *eq = eq_buf;
345 int i, num_eqes = 1 << LOG2_EQ_SZ;
347 memset(eq, 0, num_eqes * sizeof eq[0]);
348 for (i = 0; i < num_eqes; ++i)
349 WRITE_BYTE_VOL(&eq[i], EQE_OWNER_OFFSET, EQE_OWNER_VAL_HW);
352 static void prep_init_ib_buf(void *buf)
354 memset(buf, 0, MT_STRUCT_SIZE(arbelprm_init_ib_st));
356 INS_FLD(MTU_2048, buf, arbelprm_init_ib_st, mtu_cap);
357 INS_FLD(3, buf, arbelprm_init_ib_st, port_width_cap);
358 INS_FLD(1, buf, arbelprm_init_ib_st, vl_cap);
359 INS_FLD(1, buf, arbelprm_init_ib_st, max_gid);
360 INS_FLD(64, buf, arbelprm_init_ib_st, max_pkey);
363 static void prep_sw2hw_cq_buf(void *buf, __u8 eqn,
365 union cqe_st *cq_buf,
366 __u32 cq_ci_db_record, __u32 cq_state_db_record)
368 memset(buf, 0, MT_STRUCT_SIZE(arbelprm_completion_queue_context_st));
370 INS_FLD(0xA, buf, arbelprm_completion_queue_context_st, st);
371 INS_FLD(virt_to_bus(cq_buf), buf, arbelprm_completion_queue_context_st,
373 INS_FLD(LOG2_CQ_SZ, buf, arbelprm_completion_queue_context_st,
375 INS_FLD(dev_ib_data.uar_idx, buf, arbelprm_completion_queue_context_st,
377 INS_FLD(eqn, buf, arbelprm_completion_queue_context_st, c_eqn);
378 INS_FLD(GLOBAL_PD, buf, arbelprm_completion_queue_context_st, pd);
379 INS_FLD(dev_ib_data.mkey, buf, arbelprm_completion_queue_context_st,
381 INS_FLD(cqn, buf, arbelprm_completion_queue_context_st, cqn);
382 INS_FLD(cq_ci_db_record, buf, arbelprm_completion_queue_context_st,
384 INS_FLD(cq_state_db_record, buf, arbelprm_completion_queue_context_st,
388 static void prep_rst2init_qpee_buf(void *buf,
396 __u32 snd_wqe_base_adr_l,
397 __u32 snd_db_record_index,
398 __u32 rcv_wqe_base_adr_l,
399 __u32 rcv_db_record_index)
403 struct qp_ee_state_tarnisition_st *prm = buf;
405 memset(buf, 0, sizeof *prm);
407 tprintf("snd_cqn=0x%lx", snd_cqn);
408 tprintf("rcv_cqn=0x%lx", rcv_cqn);
409 tprintf("qkey=0x%lx", qkey);
410 tprintf("log_rq_size=0x%lx", log_rq_size);
411 tprintf("log_rq_stride=0x%lx", log_rq_stride);
412 tprintf("log_sq_size=0x%lx", log_sq_size);
413 tprintf("log_sq_stride=0x%lx", log_sq_stride);
414 tprintf("snd_wqe_base_adr_l=0x%lx", snd_wqe_base_adr_l);
415 tprintf("snd_db_record_index=0x%lx", snd_db_record_index);
416 tprintf("rcv_wqe_base_adr_l=0x%lx", rcv_wqe_base_adr_l);
417 tprintf("rcv_db_record_index=0x%lx", rcv_db_record_index);
420 INS_FLD(TS_UD, tmp, arbelprm_queue_pair_ee_context_entry_st, st);
421 INS_FLD(PM_STATE_MIGRATED, tmp, arbelprm_queue_pair_ee_context_entry_st,
423 INS_FLD(1, tmp, arbelprm_queue_pair_ee_context_entry_st, de);
424 INS_FLD(MTU_2048, tmp, arbelprm_queue_pair_ee_context_entry_st, mtu);
425 INS_FLD(11, tmp, arbelprm_queue_pair_ee_context_entry_st, msg_max);
426 INS_FLD(log_rq_size, tmp, arbelprm_queue_pair_ee_context_entry_st,
428 INS_FLD(log_rq_stride, tmp, arbelprm_queue_pair_ee_context_entry_st,
430 INS_FLD(log_sq_size, tmp, arbelprm_queue_pair_ee_context_entry_st,
432 INS_FLD(log_sq_stride, tmp, arbelprm_queue_pair_ee_context_entry_st,
434 INS_FLD(dev_ib_data.uar_idx, tmp,
435 arbelprm_queue_pair_ee_context_entry_st, usr_page);
436 INS_FLD(GLOBAL_PD, tmp, arbelprm_queue_pair_ee_context_entry_st, pd);
437 INS_FLD(dev_ib_data.mkey, tmp, arbelprm_queue_pair_ee_context_entry_st,
439 INS_FLD(1, tmp, arbelprm_queue_pair_ee_context_entry_st, ssc);
440 INS_FLD(snd_cqn, tmp, arbelprm_queue_pair_ee_context_entry_st, cqn_snd);
442 32 - MT_BIT_SIZE(arbelprm_queue_pair_ee_context_entry_st,
444 INS_FLD(snd_wqe_base_adr_l >> shift, tmp,
445 arbelprm_queue_pair_ee_context_entry_st, snd_wqe_base_adr_l);
446 INS_FLD(snd_db_record_index, tmp,
447 arbelprm_queue_pair_ee_context_entry_st, snd_db_record_index);
448 INS_FLD(1, tmp, arbelprm_queue_pair_ee_context_entry_st, rsc);
449 INS_FLD(rcv_cqn, tmp, arbelprm_queue_pair_ee_context_entry_st, cqn_rcv);
451 32 - MT_BIT_SIZE(arbelprm_queue_pair_ee_context_entry_st,
453 INS_FLD(rcv_wqe_base_adr_l >> shift, tmp,
454 arbelprm_queue_pair_ee_context_entry_st, rcv_wqe_base_adr_l);
455 INS_FLD(rcv_db_record_index, tmp,
456 arbelprm_queue_pair_ee_context_entry_st, rcv_db_record_index);
457 INS_FLD(qkey, tmp, arbelprm_queue_pair_ee_context_entry_st, q_key);
460 (__u8 *) (&prm->ctx) +
461 MT_BYTE_OFFSET(arbelprm_queue_pair_ee_context_entry_st,
462 primary_address_path);
463 INS_FLD(dev_ib_data.port, tmp, arbelprm_address_path_st, port_number);
467 static void prep_init2rtr_qpee_buf(void *buf)
469 struct qp_ee_state_tarnisition_st *prm;
471 prm = (struct qp_ee_state_tarnisition_st *)buf;
473 memset(prm, 0, sizeof *prm);
475 INS_FLD(MTU_2048, &prm->ctx, arbelprm_queue_pair_ee_context_entry_st,
477 INS_FLD(11, &prm->ctx, arbelprm_queue_pair_ee_context_entry_st,
481 static void init_av_array(void)
488 static int my_log2(unsigned long arg)
494 return INT_MIN; /* log2(0) = -infinity */
510 static unsigned long get_req_icm_pages(unsigned long log2_reserved,
511 unsigned long app_rsrc,
512 unsigned long entry_size,
513 unsigned long *log2_entries_p)
516 unsigned long log2_entries;
518 log2_entries = my_log2((1 << log2_reserved) + app_rsrc);
519 *log2_entries_p = log2_entries;
520 size = (1 << log2_entries) * entry_size;
522 return (size + 4095) >> 12;
525 static void init_uar_context(void *uar_context_va)
528 /* clear all uar context */
529 memset(uar_context_va, 0, 4096);
531 ptr = uar_context_va + MADS_RCV_CQ_ARM_DB_IDX * 8;
532 INS_FLD_TO_BE(UAR_RES_CQ_ARM, ptr, arbelprm_cq_arm_db_record_st, res);
533 INS_FLD_TO_BE(dev_ib_data.mads_qp.rcv_cq.cqn, ptr,
534 arbelprm_cq_arm_db_record_st, cq_number);
536 ptr = uar_context_va + MADS_SND_CQ_ARM_DB_IDX * 8;
537 INS_FLD_TO_BE(UAR_RES_CQ_ARM, ptr, arbelprm_cq_arm_db_record_st, res);
538 INS_FLD_TO_BE(dev_ib_data.mads_qp.snd_cq.cqn, ptr,
539 arbelprm_cq_arm_db_record_st, cq_number);
541 ptr = uar_context_va + IPOIB_RCV_CQ_ARM_DB_IDX * 8;
542 INS_FLD_TO_BE(UAR_RES_CQ_ARM, ptr, arbelprm_cq_arm_db_record_st, res);
543 INS_FLD_TO_BE(dev_ib_data.ipoib_qp.rcv_cq.cqn, ptr,
544 arbelprm_cq_arm_db_record_st, cq_number);
546 ptr = uar_context_va + IPOIB_SND_CQ_ARM_DB_IDX * 8;
547 INS_FLD_TO_BE(UAR_RES_CQ_ARM, ptr, arbelprm_cq_arm_db_record_st, res);
548 INS_FLD_TO_BE(dev_ib_data.ipoib_qp.snd_cq.cqn, ptr,
549 arbelprm_cq_arm_db_record_st, cq_number);
551 ptr = uar_context_va + MADS_SND_QP_DB_IDX * 8;
552 INS_FLD_TO_BE(UAR_RES_SQ_DBELL, ptr, arbelprm_qp_db_record_st, res);
553 INS_FLD_TO_BE(dev_ib_data.mads_qp.qpn, ptr, arbelprm_qp_db_record_st,
556 ptr = uar_context_va + IPOIB_SND_QP_DB_IDX * 8;
557 INS_FLD_TO_BE(UAR_RES_SQ_DBELL, ptr, arbelprm_qp_db_record_st, res);
558 INS_FLD_TO_BE(dev_ib_data.ipoib_qp.qpn, ptr, arbelprm_qp_db_record_st,
561 ptr = uar_context_va + GROUP_SEP_IDX * 8;
562 INS_FLD_TO_BE(UAR_RES_GROUP_SEP, ptr, arbelprm_cq_arm_db_record_st,
565 ptr = uar_context_va + MADS_RCV_QP_DB_IDX * 8;
566 INS_FLD_TO_BE(UAR_RES_RQ_DBELL, ptr, arbelprm_qp_db_record_st, res);
567 INS_FLD_TO_BE(dev_ib_data.mads_qp.qpn, ptr, arbelprm_qp_db_record_st,
570 ptr = uar_context_va + IPOIB_RCV_QP_DB_IDX * 8;
571 INS_FLD_TO_BE(UAR_RES_RQ_DBELL, ptr, arbelprm_qp_db_record_st, res);
572 INS_FLD_TO_BE(dev_ib_data.ipoib_qp.qpn, ptr, arbelprm_qp_db_record_st,
575 ptr = uar_context_va + MADS_RCV_CQ_CI_DB_IDX * 8;
576 INS_FLD_TO_BE(UAR_RES_CQ_SET_CI, ptr, arbelprm_cq_ci_db_record_st, res);
577 INS_FLD_TO_BE(dev_ib_data.mads_qp.rcv_cq.cqn, ptr,
578 arbelprm_cq_ci_db_record_st, cq_number);
580 ptr = uar_context_va + MADS_SND_CQ_CI_DB_IDX * 8;
581 INS_FLD_TO_BE(UAR_RES_CQ_SET_CI, ptr, arbelprm_cq_ci_db_record_st, res);
582 INS_FLD_TO_BE(dev_ib_data.mads_qp.snd_cq.cqn, ptr,
583 arbelprm_cq_ci_db_record_st, cq_number);
585 ptr = uar_context_va + IPOIB_RCV_CQ_CI_DB_IDX * 8;
586 INS_FLD_TO_BE(UAR_RES_CQ_SET_CI, ptr, arbelprm_cq_ci_db_record_st, res);
587 INS_FLD_TO_BE(dev_ib_data.ipoib_qp.rcv_cq.cqn, ptr,
588 arbelprm_cq_ci_db_record_st, cq_number);
590 ptr = uar_context_va + IPOIB_SND_CQ_CI_DB_IDX * 8;
591 INS_FLD_TO_BE(UAR_RES_CQ_SET_CI, ptr, arbelprm_cq_ci_db_record_st, res);
592 INS_FLD_TO_BE(dev_ib_data.ipoib_qp.snd_cq.cqn, ptr,
593 arbelprm_cq_ci_db_record_st, cq_number);
597 static int setup_hca(__u8 port, void **eq_p)
601 struct query_fw_st qfw;
602 struct map_icm_st map_obj;
603 struct dev_lim_st dev_lim;
604 struct init_hca_st init_hca;
606 unsigned long icm_start, icm_size, tmp;
607 unsigned long log2_entries;
609 __u32 mem_key, key, tmp_key;
612 struct eqe_t *eq_buf;
614 unsigned long bus_addr;
615 struct query_adapter_st qa;
616 __u8 log_max_uars = 1;
617 void *uar_context_va;
618 __u32 uar_context_pa;
622 inprm = get_inprm_buf();
629 tprintf("reset_hca() success");
632 mdelay(1000); /* wait for 1 sec */
634 rc = restore_config();
639 tprintf("restore_config() success");
642 dev_ib_data.pd = GLOBAL_PD;
643 dev_ib_data.port = port;
644 dev_ib_data.qkey = GLOBAL_QKEY;
646 rc = cmd_query_fw(&qfw);
652 tprintf("cmd_query_fw() success");
655 printf("FW ver = %d.%d.%d\n",
658 qfw.fw_rev_subminor);
661 tprintf("fw_rev_major=%d", qfw.fw_rev_major);
662 tprintf("fw_rev_minor=%d", qfw.fw_rev_minor);
663 tprintf("fw_rev_subminor=%d", qfw.fw_rev_subminor);
664 tprintf("error_buf_start_h=0x%x", qfw.error_buf_start_h);
665 tprintf("error_buf_start_l=0x%x", qfw.error_buf_start_l);
666 tprintf("error_buf_size=%d", qfw.error_buf_size);
672 ((unsigned long)((u64) qfw.error_buf_start_h << 32) | qfw.
674 dev_ib_data.error_buf_addr= ioremap(bus_addr,
675 qfw.error_buf_size*4);
676 dev_ib_data.error_buf_size= qfw.error_buf_size;
677 if (!dev_ib_data.error_buf_addr) {
684 ((unsigned long)((u64) qfw.clear_int_addr.addr_h << 32) | qfw.
685 clear_int_addr.addr_l);
686 dev_ib_data.clr_int_addr = bus_to_virt(bus_addr);
688 rc = cmd_enable_lam();
689 if (rc == 0x22 /* LAM_NOT_PRE -- need to put a name here */ ) {
691 } else if (rc == 0) {
698 log2_pages = my_log2(qfw.fw_pages);
700 memset(&map_obj, 0, sizeof map_obj);
702 map_obj.vpm_arr[0].log2_size = log2_pages;
703 map_obj.vpm_arr[0].pa_l = phys_mem.base + phys_mem.offset;
704 rc = cmd_map_fa(&map_obj);
709 phys_mem.offset += 1 << (log2_pages + 12);
718 rc = cmd_mod_stat_cfg();
725 rc = cmd_query_dev_lim(&dev_lim);
732 dev_ib_data.uar_idx = dev_lim.num_rsvd_uars;
734 tprintf("max_icm_size_h=0x%lx", dev_lim.max_icm_size_h);
735 tprintf("max_icm_size_l=0x%lx", dev_lim.max_icm_size_l);
737 memset(&init_hca, 0, sizeof init_hca);
741 icm_start += ((dev_lim.num_rsvd_uars + 1) << 12);
742 icm_size += ((dev_lim.num_rsvd_uars + 1) << 12);
744 tmp = get_req_icm_pages(dev_lim.log2_rsvd_qps,
746 dev_lim.qpc_entry_sz, &log2_entries);
747 init_hca.qpc_base_addr_l = icm_start;
748 init_hca.log_num_of_qp = log2_entries;
749 icm_start += (tmp << 12);
750 icm_size += (tmp << 12);
752 init_hca.eqpc_base_addr_l = icm_start;
753 icm_start += (tmp << 12);
754 icm_size += (tmp << 12);
756 tmp = get_req_icm_pages(dev_lim.log2_rsvd_srqs,
757 0, dev_lim.srq_entry_sz, &log2_entries);
758 init_hca.srqc_base_addr_l = icm_start;
759 init_hca.log_num_of_srq = log2_entries;
760 icm_start += (tmp << 12);
761 icm_size += (tmp << 12);
763 tmp = get_req_icm_pages(dev_lim.log2_rsvd_ees,
764 0, dev_lim.eec_entry_sz, &log2_entries);
765 init_hca.eec_base_addr_l = icm_start;
766 init_hca.log_num_of_ee = log2_entries;
767 icm_start += (tmp << 12);
768 icm_size += (tmp << 12);
770 init_hca.eeec_base_addr_l = icm_start;
771 icm_start += (tmp << 12);
772 icm_size += (tmp << 12);
774 tmp = get_req_icm_pages(dev_lim.log2_rsvd_cqs,
776 dev_lim.cqc_entry_sz, &log2_entries);
777 init_hca.cqc_base_addr_l = icm_start;
778 init_hca.log_num_of_cq = log2_entries;
779 icm_start += (tmp << 12);
780 icm_size += (tmp << 12);
782 tmp = get_req_icm_pages(dev_lim.log2_rsvd_mtts,
783 0, dev_lim.mtt_entry_sz, &log2_entries);
784 init_hca.mtt_base_addr_l = icm_start;
785 icm_start += (tmp << 12);
786 icm_size += (tmp << 12);
788 tmp = get_req_icm_pages(dev_lim.log2_rsvd_mrws,
789 1, dev_lim.mpt_entry_sz, &log2_entries);
790 init_hca.mpt_base_addr_l = icm_start;
791 init_hca.log_mpt_sz = log2_entries;
792 icm_start += (tmp << 12);
793 icm_size += (tmp << 12);
795 tmp = get_req_icm_pages(dev_lim.log2_rsvd_rdbs, 1, 32, /* size of rdb entry */
797 init_hca.rdb_base_addr_l = icm_start;
798 icm_start += (tmp << 12);
799 icm_size += (tmp << 12);
801 init_hca.eqc_base_addr_l = icm_start;
802 init_hca.log_num_of_eq = LOG2_EQS;
803 tmp = dev_lim.eqc_entry_sz * (1 << LOG2_EQS);
807 init_hca.mc_base_addr_l = icm_start;
808 init_hca.log_mc_table_entry_sz =
809 my_log2(MT_STRUCT_SIZE(arbelprm_mgm_entry_st));
810 init_hca.mc_table_hash_sz = 8;
811 init_hca.log_mc_table_sz = 3;
813 (MT_STRUCT_SIZE(arbelprm_mgm_entry_st) * init_hca.mc_table_hash_sz);
815 (MT_STRUCT_SIZE(arbelprm_mgm_entry_st) * init_hca.mc_table_hash_sz);
817 rc = cmd_set_icm_size(icm_size, &aux_pages);
824 memset(&map_obj, 0, sizeof map_obj);
826 map_obj.vpm_arr[0].pa_l = phys_mem.base + phys_mem.offset;
827 map_obj.vpm_arr[0].log2_size = my_log2(aux_pages);
828 rc = cmd_map_icm_aux(&map_obj);
834 phys_mem.offset += (1 << (map_obj.vpm_arr[0].log2_size + 12));
836 uar_context_pa = phys_mem.base + phys_mem.offset +
837 dev_ib_data.uar_idx * 4096;
838 uar_context_va = phys_to_virt(uar_context_pa);
839 tprintf("uar_context: va=0x%lx, pa=0x%lx", uar_context_va,
841 dev_ib_data.uar_context_base = uar_context_va;
843 memset(&map_obj, 0, sizeof map_obj);
845 map_obj.vpm_arr[0].pa_l = phys_mem.base + phys_mem.offset;
846 map_obj.vpm_arr[0].log2_size = my_log2((icm_size + 4095) >> 12);
847 rc = cmd_map_icm(&map_obj);
853 phys_mem.offset += (1 << (map_obj.vpm_arr[0].log2_size + 12));
855 init_hca.log_max_uars = log_max_uars;
856 tprintf("inprm: va=0x%lx, pa=0x%lx", inprm, virt_to_bus(inprm));
857 prep_init_hca_buf(&init_hca, inprm);
858 rc = cmd_init_hca(inprm, MT_STRUCT_SIZE(arbelprm_init_hca_st));
865 rc = cmd_query_adapter(&qa);
870 dev_ib_data.clr_int_data = 1 << qa.intapin;
872 tmp_key = 1 << dev_lim.log2_rsvd_mrws | MKEY_PREFIX;
873 mem_key = 1 << (dev_lim.log2_rsvd_mrws + 8) | (MKEY_PREFIX >> 24);
874 prep_sw2hw_mpt_buf(inprm, tmp_key);
875 rc = cmd_sw2hw_mpt(&key, 1 << dev_lim.log2_rsvd_mrws, inprm,
882 tprintf("cmd_sw2hw_mpt() success, key=0x%lx", mem_key);
884 dev_ib_data.mkey = mem_key;
887 /* allocate a single EQ which will receive
889 eq_buf = dev_buffers_p->eq_buf;
890 init_eq_buf(eq_buf); /* put in HW ownership */
891 prep_sw2hw_eq_buf(inprm, eq_buf);
892 rc = cmd_sw2hw_eq(SW2HW_EQ_IBUF_SZ);
898 tprintf("cmd_sw2hw_eq() success");
900 event_mask = (1 << XDEV_EV_TYPE_CQ_COMP) |
901 (1 << XDEV_EV_TYPE_CQ_ERR) |
902 (1 << XDEV_EV_TYPE_LOCAL_WQ_CATAS_ERR) |
903 (1 << XDEV_EV_TYPE_PORT_ERR) |
904 (1 << XDEV_EV_TYPE_LOCAL_WQ_INVALID_REQ_ERR) |
905 (1 << XDEV_EV_TYPE_LOCAL_WQ_ACCESS_VIOL_ERR) |
906 (1 << TAVOR_IF_EV_TYPE_OVERRUN);
907 rc = cmd_map_eq(eqn, event_mask, 1);
913 tprintf("cmd_map_eq() success");
915 dev_ib_data.eq.eqn = eqn;
916 dev_ib_data.eq.eq_buf = eq_buf;
917 dev_ib_data.eq.cons_counter = 0;
918 dev_ib_data.eq.eq_size = 1 << LOG2_EQ_SZ;
920 ((unsigned long)((u64) qfw.eq_ci_table.addr_h << 32) | qfw.
923 dev_ib_data.eq.ci_base_base_addr = bus_to_virt(bus_addr);
924 *eq_p = &dev_ib_data.eq;
926 prep_init_ib_buf(inprm);
927 rc = cmd_init_ib(port, inprm, INIT_IB_IBUF_SZ);
933 tprintf("cmd_init_ib() success");
936 tprintf("init_av_array() done");
938 /* set the qp and cq numbers according
939 to the results of query_dev_lim */
940 dev_ib_data.mads_qp.qpn = (1 << dev_lim.log2_rsvd_qps) +
941 +QPN_BASE + MADS_QPN_SN;
942 dev_ib_data.ipoib_qp.qpn = (1 << dev_lim.log2_rsvd_qps) +
943 +QPN_BASE + IPOIB_QPN_SN;
945 dev_ib_data.mads_qp.snd_cq.cqn = (1 << dev_lim.log2_rsvd_cqs) +
947 dev_ib_data.mads_qp.rcv_cq.cqn = (1 << dev_lim.log2_rsvd_cqs) +
950 dev_ib_data.ipoib_qp.snd_cq.cqn = (1 << dev_lim.log2_rsvd_cqs) +
952 dev_ib_data.ipoib_qp.rcv_cq.cqn = (1 << dev_lim.log2_rsvd_cqs) +
955 init_uar_context(uar_context_va);
961 rc = cmd_hw2sw_eq(eqn);
965 tprintf("cmd_hw2sw_eq() success");
968 rc = cmd_hw2sw_mpt(tmp_key);
981 static void *get_inprm_buf(void)
983 return dev_buffers_p->inprm_buf;
986 static void *get_outprm_buf(void)
988 return dev_buffers_p->outprm_buf;
991 static void *get_send_wqe_buf(void *wqe, __u8 index)
993 struct ud_send_wqe_st *snd_wqe = wqe;
995 return bus_to_virt(be32_to_cpu(snd_wqe->mpointer[index].local_addr_l));
998 static void *get_rcv_wqe_buf(void *wqe, __u8 index)
1000 struct recv_wqe_st *rcv_wqe = wqe;
1002 return bus_to_virt(be32_to_cpu(rcv_wqe->mpointer[index].local_addr_l));
1005 static void modify_av_params(struct ud_av_st *av,
1008 __u8 sl, __u8 rate, union ib_gid_u *gid, __u32 qpn)
1010 memset(&av->av, 0, sizeof av->av);
1012 INS_FLD_TO_BE(dev_ib_data.port, &av->av, arbelprm_ud_address_vector_st,
1014 INS_FLD_TO_BE(dev_ib_data.pd, &av->av, arbelprm_ud_address_vector_st,
1016 INS_FLD_TO_BE(dlid, &av->av, arbelprm_ud_address_vector_st, rlid);
1017 INS_FLD_TO_BE(g, &av->av, arbelprm_ud_address_vector_st, g);
1018 INS_FLD_TO_BE(sl, &av->av, arbelprm_ud_address_vector_st, sl);
1019 INS_FLD_TO_BE(3, &av->av, arbelprm_ud_address_vector_st, msg);
1022 INS_FLD_TO_BE(0, &av->av, arbelprm_ud_address_vector_st, max_stat_rate); /* 4x */
1024 INS_FLD_TO_BE(1, &av->av, arbelprm_ud_address_vector_st, max_stat_rate); /* 1x */
1028 INS_FLD(*((__u32 *) (&gid->raw[0])), &av->av,
1029 arbelprm_ud_address_vector_st, rgid_127_96);
1030 INS_FLD(*((__u32 *) (&gid->raw[4])), &av->av,
1031 arbelprm_ud_address_vector_st, rgid_95_64);
1032 INS_FLD(*((__u32 *) (&gid->raw[8])), &av->av,
1033 arbelprm_ud_address_vector_st, rgid_63_32);
1034 INS_FLD(*((__u32 *) (&gid->raw[12])), &av->av,
1035 arbelprm_ud_address_vector_st, rgid_31_0);
1037 INS_FLD(0, &av->av, arbelprm_ud_address_vector_st,
1039 INS_FLD(0, &av->av, arbelprm_ud_address_vector_st,
1041 INS_FLD(0, &av->av, arbelprm_ud_address_vector_st,
1043 INS_FLD(0, &av->av, arbelprm_ud_address_vector_st,
1047 INS_FLD(0, &av->av, arbelprm_ud_address_vector_st, rgid_127_96);
1048 INS_FLD(0, &av->av, arbelprm_ud_address_vector_st, rgid_95_64);
1049 INS_FLD(0, &av->av, arbelprm_ud_address_vector_st, rgid_63_32);
1050 INS_FLD(2, &av->av, arbelprm_ud_address_vector_st, rgid_31_0);
1053 av->qkey = dev_ib_data.qkey;
1056 static void init_cq_buf(union cqe_st *cq_buf, __u8 num_cqes)
1060 memset(cq_buf, 0, sizeof(union cqe_st) * num_cqes);
1061 for (i = 0; i < num_cqes; ++i) {
1062 WRITE_BYTE_VOL(&cq_buf[i], CQE_OWNER_OFFSET, CQE_OWNER_VAL_HW);
1066 static int post_rcv_buf(struct udqp_st *qp, struct recv_wqe_st *rcv_wqe)
1070 /* put a valid lkey */
1071 for (i = 0; i < MAX_SCATTER; ++i) {
1072 rcv_wqe->mpointer[i].lkey = cpu_to_be32(dev_ib_data.mkey);
1075 qp->post_rcv_counter++;
1076 WRITE_WORD_VOL(qp->rcv_uar_context, 2, htons(qp->post_rcv_counter));
1081 static int post_send_req(void *qph, void *wqeh, __u8 num_gather)
1084 struct udqp_st *qp = qph;
1085 struct ud_send_wqe_st *snd_wqe = wqeh;
1086 struct send_doorbell_st dbell;
1089 qp->post_send_counter++;
1091 WRITE_WORD_VOL(qp->send_uar_context, 2, htons(qp->post_send_counter));
1093 memset(&dbell, 0, sizeof dbell);
1094 INS_FLD(XDEV_NOPCODE_SEND, &dbell, arbelprm_send_doorbell_st, nopcode);
1095 INS_FLD(1, &dbell, arbelprm_send_doorbell_st, f);
1096 INS_FLD(qp->post_send_counter - 1, &dbell, arbelprm_send_doorbell_st,
1098 INS_FLD(1, &dbell, arbelprm_send_doorbell_st, wqe_cnt);
1099 nds = (sizeof(snd_wqe->next) +
1100 sizeof(snd_wqe->udseg) +
1101 sizeof(snd_wqe->mpointer[0]) * num_gather) >> 4;
1102 INS_FLD(nds, &dbell, arbelprm_send_doorbell_st, nds);
1103 INS_FLD(qp->qpn, &dbell, arbelprm_send_doorbell_st, qpn);
1105 if (qp->last_posted_snd_wqe) {
1107 &qp->last_posted_snd_wqe->next.next,
1108 arbelprm_wqe_segment_next_st, nds);
1110 &qp->last_posted_snd_wqe->next.next,
1111 arbelprm_wqe_segment_next_st, f);
1112 INS_FLD_TO_BE(XDEV_NOPCODE_SEND,
1113 &qp->last_posted_snd_wqe->next.next,
1114 arbelprm_wqe_segment_next_st, nopcode);
1117 rc = cmd_post_doorbell(&dbell, POST_SND_OFFSET);
1119 qp->last_posted_snd_wqe = snd_wqe;
1126 static int create_mads_qp(void **qp_pp, void **snd_cq_pp, void **rcv_cq_pp)
1128 __u8 i, next_i, j, k;
1135 qp = &dev_ib_data.mads_qp;
1137 /* set the pointer to the receive WQEs buffer */
1138 qp->rcv_wq = dev_buffers_p->mads_qp_rcv_queue;
1140 qp->send_buf_sz = MAD_BUF_SZ;
1141 qp->rcv_buf_sz = MAD_BUF_SZ;
1143 qp->max_recv_wqes = NUM_MADS_RCV_WQES; /* max wqes in this work queue */
1144 qp->recv_wqe_cur_free = NUM_MADS_RCV_WQES; /* current free wqes */
1145 qp->recv_wqe_alloc_idx = 0; /* index from wqes can be allocated if there are free wqes */
1147 qp->rcv_uar_context =
1148 dev_ib_data.uar_context_base + 8 * MADS_RCV_QP_DB_IDX;
1149 qp->send_uar_context =
1150 dev_ib_data.uar_context_base + 8 * MADS_SND_QP_DB_IDX;
1152 memset(&qp->rcv_wq[0], 0, NUM_MADS_RCV_WQES * sizeof(qp->rcv_wq[0]));
1153 nds = sizeof(qp->rcv_wq[0].wqe) >> 4;
1154 /* iterrate through the list */
1155 for (j = 0, i = 0, next_i = 1;
1156 j < NUM_MADS_RCV_WQES;
1157 MOD_INC(i, NUM_MADS_RCV_WQES), MOD_INC(next_i, NUM_MADS_RCV_WQES),
1160 qp->rcv_bufs[i] = ib_buffers.rcv_mad_buf[i];
1161 /* link the WQE to the next one */
1162 bus_addr = virt_to_bus(&qp->rcv_wq[next_i].wqe);
1163 ptr = qp->rcv_wq[i].wqe.control +
1164 MT_BYTE_OFFSET(arbelprm_wqe_segment_ctrl_recv_st,
1166 INS_FLD(bus_addr >> 6, ptr, arbelprm_recv_wqe_segment_next_st,
1168 INS_FLD(nds, ptr, arbelprm_recv_wqe_segment_next_st, nds);
1170 /* set the allocated buffers */
1171 qp->rcv_bufs[i] = ib_buffers.rcv_mad_buf[i];
1172 bus_addr = virt_to_bus(qp->rcv_bufs[i]);
1173 qp->rcv_wq[i].wqe.mpointer[0].local_addr_l = bus_addr;
1174 qp->rcv_wq[i].wqe.mpointer[0].byte_count = GRH_SIZE;
1175 bus_addr = virt_to_bus(qp->rcv_bufs[i] + GRH_SIZE);
1176 qp->rcv_wq[i].wqe.mpointer[1].local_addr_l = bus_addr;
1177 qp->rcv_wq[i].wqe.mpointer[1].byte_count = MAD_BUF_SZ;
1179 for (k = 0; k < (((sizeof(qp->rcv_wq[i])) >> 4) - 1); ++k) {
1180 qp->rcv_wq[i].wqe.mpointer[k].lkey = INVALID_WQE_LKEY;
1183 cpu_to_be_buf(&qp->rcv_wq[0],
1184 NUM_MADS_RCV_WQES * sizeof(qp->rcv_wq[0]));
1186 for (i = 0; i < qp->max_recv_wqes; ++i) {
1187 qp->rcv_wq[i].wqe_cont.qp = qp;
1190 /* set the pointer to the send WQEs buffer */
1191 qp->snd_wq = dev_buffers_p->mads_qp_snd_queue;
1193 qp->snd_wqe_alloc_idx = 0;
1194 qp->max_snd_wqes = NUM_MADS_SND_WQES;
1195 qp->snd_wqe_cur_free = NUM_MADS_SND_WQES;
1197 memset(&qp->snd_wq[0], 0, NUM_MADS_SND_WQES * sizeof(qp->snd_wq[i]));
1198 /* iterrate through the list */
1199 for (j = 0, i = 0, next_i = 1;
1200 j < NUM_MADS_RCV_WQES;
1201 MOD_INC(i, NUM_MADS_SND_WQES), MOD_INC(next_i, NUM_MADS_SND_WQES),
1204 /* link the WQE to the next one */
1205 bus_addr = virt_to_bus(&qp->snd_wq[next_i].wqe_cont.wqe);
1206 INS_FLD(bus_addr >> 6, &qp->snd_wq[i].wqe_cont.wqe.next.next,
1207 arbelprm_wqe_segment_next_st, nda_31_6);
1209 /* set the allocated buffers */
1210 qp->snd_bufs[i] = ib_buffers.send_mad_buf[i];
1211 bus_addr = virt_to_bus(qp->snd_bufs[i]);
1212 qp->snd_wq[i].wqe_cont.wqe.mpointer[0].local_addr_l = bus_addr;
1213 qp->snd_wq[i].wqe_cont.wqe.mpointer[0].lkey = dev_ib_data.mkey;
1214 qp->snd_wq[i].wqe_cont.wqe.mpointer[0].byte_count =
1219 cpu_to_be_buf(&qp->snd_wq[0],
1220 NUM_MADS_SND_WQES * sizeof(qp->snd_wq[i]));
1222 for (i = 0; i < qp->max_snd_wqes; ++i) {
1223 qp->snd_wq[i].wqe_cont.qp = qp;
1226 /* qp number and cq numbers are already set up */
1227 qp->snd_cq.cq_buf = dev_buffers_p->mads_snd_cq_buf;
1228 qp->rcv_cq.cq_buf = dev_buffers_p->mads_rcv_cq_buf;
1229 qp->snd_cq.num_cqes = NUM_MADS_SND_CQES;
1230 qp->rcv_cq.num_cqes = NUM_MADS_RCV_CQES;
1231 qp->snd_cq.arm_db_ctx_idx = MADS_SND_CQ_ARM_DB_IDX;
1232 qp->snd_cq.ci_db_ctx_idx = MADS_SND_CQ_CI_DB_IDX;
1233 qp->rcv_cq.arm_db_ctx_idx = MADS_RCV_CQ_ARM_DB_IDX;
1234 qp->rcv_cq.ci_db_ctx_idx = MADS_RCV_CQ_CI_DB_IDX;
1235 qp->rcv_db_record_index = MADS_RCV_QP_DB_IDX;
1236 qp->snd_db_record_index = MADS_SND_QP_DB_IDX;
1237 qp->qkey = GLOBAL_QKEY;
1238 rc = create_udqp(qp);
1241 *snd_cq_pp = &qp->snd_cq;
1242 *rcv_cq_pp = &qp->rcv_cq;
1248 static int create_ipoib_qp(void **qp_pp,
1249 void **snd_cq_pp, void **rcv_cq_pp, __u32 qkey)
1251 __u8 i, next_i, j, k;
1258 qp = &dev_ib_data.ipoib_qp;
1260 /* set the pointer to the receive WQEs buffer */
1261 qp->rcv_wq = dev_buffers_p->ipoib_qp_rcv_queue;
1263 qp->send_buf_sz = IPOIB_SND_BUF_SZ;
1264 qp->rcv_buf_sz = IPOIB_RCV_BUF_SZ;
1266 qp->max_recv_wqes = NUM_IPOIB_RCV_WQES;
1267 qp->recv_wqe_cur_free = NUM_IPOIB_RCV_WQES;
1269 qp->rcv_uar_context =
1270 dev_ib_data.uar_context_base + 8 * IPOIB_RCV_QP_DB_IDX;
1271 qp->send_uar_context =
1272 dev_ib_data.uar_context_base + 8 * IPOIB_SND_QP_DB_IDX;
1274 memset(&qp->rcv_wq[0], 0, NUM_IPOIB_RCV_WQES * sizeof(qp->rcv_wq[0]));
1275 nds = sizeof(qp->rcv_wq[0].wqe) >> 4;
1276 /* iterrate through the list */
1277 for (j = 0, i = 0, next_i = 1;
1278 j < NUM_IPOIB_RCV_WQES;
1279 MOD_INC(i, NUM_IPOIB_RCV_WQES), MOD_INC(next_i,
1280 NUM_IPOIB_RCV_WQES), ++j) {
1282 /* link the WQE to the next one */
1283 bus_addr = virt_to_bus(&qp->rcv_wq[next_i].wqe);
1284 ptr = qp->rcv_wq[i].wqe.control +
1285 MT_BYTE_OFFSET(arbelprm_wqe_segment_ctrl_recv_st,
1287 INS_FLD(bus_addr >> 6, ptr, arbelprm_recv_wqe_segment_next_st,
1289 INS_FLD(nds, ptr, arbelprm_recv_wqe_segment_next_st, nds);
1291 /* set the allocated buffers */
1292 qp->rcv_bufs[i] = ib_buffers.ipoib_rcv_buf[i];
1293 bus_addr = virt_to_bus(qp->rcv_bufs[i]);
1294 qp->rcv_wq[i].wqe.mpointer[0].local_addr_l = bus_addr;
1295 qp->rcv_wq[i].wqe.mpointer[0].byte_count = GRH_SIZE;
1296 bus_addr = virt_to_bus(qp->rcv_bufs[i] + GRH_SIZE);
1297 qp->rcv_wq[i].wqe.mpointer[1].local_addr_l = bus_addr;
1298 qp->rcv_wq[i].wqe.mpointer[1].byte_count = IPOIB_RCV_BUF_SZ;
1300 for (k = 0; k < (((sizeof(qp->rcv_wq[i].wqe)) >> 4) - 1); ++k) {
1301 qp->rcv_wq[i].wqe.mpointer[k].lkey = INVALID_WQE_LKEY;
1304 cpu_to_be_buf(&qp->rcv_wq[0],
1305 NUM_IPOIB_RCV_WQES * sizeof(qp->rcv_wq[0]));
1307 for (i = 0; i < qp->max_recv_wqes; ++i) {
1308 qp->rcv_wq[i].wqe_cont.qp = qp;
1311 /* set the pointer to the send WQEs buffer */
1312 qp->snd_wq = dev_buffers_p->ipoib_qp_snd_queue;
1314 qp->snd_wqe_alloc_idx = 0;
1315 qp->max_snd_wqes = NUM_IPOIB_SND_WQES;
1316 qp->snd_wqe_cur_free = NUM_IPOIB_SND_WQES;
1318 memset(&qp->snd_wq[0], 0, NUM_IPOIB_SND_WQES * sizeof(qp->snd_wq[i]));
1319 /* iterrate through the list */
1320 for (j = 0, i = 0, next_i = 1;
1321 j < NUM_IPOIB_RCV_WQES;
1322 MOD_INC(i, NUM_IPOIB_SND_WQES), MOD_INC(next_i,
1323 NUM_IPOIB_SND_WQES), ++j) {
1325 /* link the WQE to the next one */
1326 bus_addr = virt_to_bus(&qp->snd_wq[next_i].wqe_cont.wqe);
1327 INS_FLD(bus_addr >> 6, &qp->snd_wq[i].wqe_cont.wqe.next.next,
1328 arbelprm_wqe_segment_next_st, nda_31_6);
1330 /* set the allocated buffers */
1331 qp->snd_bufs[i] = ib_buffers.send_ipoib_buf[i];
1332 bus_addr = virt_to_bus(qp->snd_bufs[i]);
1333 qp->snd_wq[i].wqe_cont.wqe.mpointer[0].local_addr_l = bus_addr;
1334 qp->snd_wq[i].wqe_cont.wqe.mpointer[0].lkey = dev_ib_data.mkey;
1337 cpu_to_be_buf(&qp->snd_wq[0],
1338 NUM_IPOIB_SND_WQES * sizeof(qp->snd_wq[i]));
1340 for (i = 0; i < qp->max_snd_wqes; ++i) {
1341 qp->snd_wq[i].wqe_cont.qp = qp;
1344 /* qp number and cq numbers are already set up */
1345 qp->snd_cq.cq_buf = dev_buffers_p->ipoib_snd_cq_buf;
1346 qp->rcv_cq.cq_buf = dev_buffers_p->ipoib_rcv_cq_buf;
1347 qp->snd_cq.num_cqes = NUM_IPOIB_SND_CQES;
1348 qp->rcv_cq.num_cqes = NUM_IPOIB_RCV_CQES;
1349 qp->snd_cq.arm_db_ctx_idx = IPOIB_SND_CQ_ARM_DB_IDX;
1350 qp->snd_cq.ci_db_ctx_idx = IPOIB_SND_CQ_CI_DB_IDX;
1351 qp->rcv_cq.arm_db_ctx_idx = IPOIB_RCV_CQ_ARM_DB_IDX;
1352 qp->rcv_cq.ci_db_ctx_idx = IPOIB_RCV_CQ_CI_DB_IDX;
1353 qp->rcv_db_record_index = IPOIB_RCV_QP_DB_IDX;
1354 qp->snd_db_record_index = IPOIB_SND_QP_DB_IDX;
1356 rc = create_udqp(qp);
1359 *snd_cq_pp = &qp->snd_cq;
1360 *rcv_cq_pp = &qp->rcv_cq;
1366 static int create_udqp(struct udqp_st *qp)
1370 struct recv_wqe_st *rcv_wqe;
1372 inprm = dev_buffers_p->inprm_buf;
1374 qp->rcv_cq.arm_db_ctx_pointer =
1375 dev_ib_data.uar_context_base + 8 * qp->rcv_cq.arm_db_ctx_idx;
1376 qp->rcv_cq.ci_db_ctx_pointer =
1377 dev_ib_data.uar_context_base + 8 * qp->rcv_cq.ci_db_ctx_idx;
1378 qp->snd_cq.arm_db_ctx_pointer =
1379 dev_ib_data.uar_context_base + 8 * qp->snd_cq.arm_db_ctx_idx;
1380 qp->snd_cq.ci_db_ctx_pointer =
1381 dev_ib_data.uar_context_base + 8 * qp->snd_cq.ci_db_ctx_idx;
1383 /* create send CQ */
1384 init_cq_buf(qp->snd_cq.cq_buf, qp->snd_cq.num_cqes);
1385 qp->snd_cq.cons_counter = 0;
1386 prep_sw2hw_cq_buf(inprm,
1390 qp->snd_cq.ci_db_ctx_idx, qp->snd_cq.arm_db_ctx_idx);
1392 rc = cmd_sw2hw_cq(qp->snd_cq.cqn, inprm, SW2HW_CQ_IBUF_SZ);
1399 /* create receive CQ */
1400 init_cq_buf(qp->rcv_cq.cq_buf, qp->rcv_cq.num_cqes);
1401 qp->rcv_cq.cons_counter = 0;
1402 memset(inprm, 0, SW2HW_CQ_IBUF_SZ);
1403 prep_sw2hw_cq_buf(inprm,
1407 qp->rcv_cq.ci_db_ctx_idx, qp->rcv_cq.arm_db_ctx_idx);
1409 rc = cmd_sw2hw_cq(qp->rcv_cq.cqn, inprm, SW2HW_CQ_IBUF_SZ);
1416 prep_rst2init_qpee_buf(inprm,
1420 my_log2(qp->max_recv_wqes),
1421 my_log2(sizeof(qp->rcv_wq[0])) - 4,
1422 my_log2(qp->max_snd_wqes),
1423 my_log2(sizeof(qp->snd_wq[0])) - 4,
1424 virt_to_bus(qp->snd_wq),
1425 qp->snd_db_record_index,
1426 virt_to_bus(qp->rcv_wq),
1427 qp->rcv_db_record_index);
1429 rc = cmd_rst2init_qpee(qp->qpn, inprm, QPCTX_IBUF_SZ);
1436 qp->last_posted_rcv_wqe = NULL;
1437 qp->last_posted_snd_wqe = NULL;
1439 /* post all the buffers to the receive queue */
1442 rcv_wqe = alloc_rcv_wqe(qp);
1446 /* post the buffer */
1447 rc = post_rcv_buf(qp, rcv_wqe);
1455 prep_init2rtr_qpee_buf(inprm);
1456 rc = cmd_init2rtr_qpee(qp->qpn, inprm, QPCTX_IBUF_SZ);
1463 memset(inprm, 0, QPCTX_IBUF_SZ);
1464 rc = cmd_rtr2rts_qpee(qp->qpn, inprm, QPCTX_IBUF_SZ);
1474 rc = cmd_hw2sw_cq(qp->rcv_cq.cqn);
1479 rc = cmd_hw2sw_cq(qp->snd_cq.cqn);
1487 static int destroy_udqp(struct udqp_st *qp)
1491 rc = cmd_2err_qpee(qp->qpn);
1496 tprintf("cmd_2err_qpee(0x%lx) success", qp->qpn);
1498 rc = cmd_2rst_qpee(qp->qpn);
1503 tprintf("cmd_2rst_qpee(0x%lx) success", qp->qpn);
1505 rc = cmd_hw2sw_cq(qp->rcv_cq.cqn);
1510 tprintf("cmd_hw2sw_cq(0x%lx) success", qp->snd_cq.cqn);
1512 rc = cmd_hw2sw_cq(qp->snd_cq.cqn);
1517 tprintf("cmd_hw2sw_cq(0x%lx) success", qp->rcv_cq.cqn);
1522 static void prep_send_wqe_buf(void *qph,
1526 unsigned int offset, __u16 len, __u8 e)
1528 struct ud_send_wqe_st *snd_wqe = wqeh;
1529 struct ud_av_st *av = avh;
1533 /* suppress warnings */
1534 INS_FLD_TO_BE(e, &snd_wqe->next.control,
1535 arbelprm_wqe_segment_ctrl_send_st, e);
1536 INS_FLD_TO_BE(1, &snd_wqe->next.control,
1537 arbelprm_wqe_segment_ctrl_send_st, always1);
1538 INS_FLD_TO_BE(1, &snd_wqe->next.next, arbelprm_wqe_segment_next_st,
1540 memcpy(&snd_wqe->udseg, &av->av, sizeof av->av);
1541 INS_FLD_TO_BE(av->dest_qp, snd_wqe->udseg.av,
1542 arbelprm_wqe_segment_ud_st, destination_qp);
1543 INS_FLD_TO_BE(av->qkey, snd_wqe->udseg.av, arbelprm_wqe_segment_ud_st,
1548 (be32_to_cpu(snd_wqe->mpointer[0].local_addr_l)) +
1552 snd_wqe->mpointer[0].byte_count = cpu_to_be32(len);
1555 static void *alloc_ud_av(void)
1559 if (dev_ib_data.udav.udav_next_free == FL_EOL) {
1563 next_free = dev_ib_data.udav.udav_next_free;
1564 dev_ib_data.udav.udav_next_free =
1565 dev_buffers_p->av_array[next_free].ud_av.next_free;
1566 tprintf("allocated udav %d", next_free);
1567 return &dev_buffers_p->av_array[next_free].ud_av;
1570 static void free_ud_av(void *avh)
1574 struct ud_av_st *av = avh;
1576 avu = (union ud_av_u *)av;
1578 idx = avu - dev_buffers_p->av_array;
1579 tprintf("freeing udav idx=%d", idx);
1580 old_idx = dev_ib_data.udav.udav_next_free;
1581 dev_ib_data.udav.udav_next_free = idx;
1582 avu->ud_av.next_free = old_idx;
1585 static int update_cq_cons_idx(struct cq_st *cq)
1587 /* write doorbell record */
1588 WRITE_DWORD_VOL(cq->ci_db_ctx_pointer, 0, htonl(cq->cons_counter));
1591 INS_FLD_TO_BE(cq->cons_counter,
1592 cq->ci_db_ctx_pointer,
1593 arbelprm_cq_arm_db_record_st,
1596 INS_FLD_TO_BE(cq->cqn,
1597 cq->ci_db_ctx_pointer,
1598 arbelprm_cq_arm_db_record_st,
1602 cq->ci_db_ctx_pointer,
1603 arbelprm_cq_arm_db_record_st,
1609 static int poll_cq(void *cqh, union cqe_st *cqe_p, u8 * num_cqes)
1614 struct cq_st *cq = cqh;
1615 __u32 cons_idx = cq->cons_counter & (cq->num_cqes - 1);
1617 ptr = (u32 *) (&(cq->cq_buf[cons_idx]));
1619 if ((ptr[7] & 0x80000000) == 0) {
1620 cqe = cq->cq_buf[cons_idx];
1621 be_to_cpu_buf(&cqe, sizeof(cqe));
1623 ptr[7] = 0x80000000;
1626 rc = update_cq_cons_idx(cq);
1637 static void dev2ib_cqe(struct ib_cqe_st *ib_cqe_p, union cqe_st *cqe_p)
1643 EX_FLD(cqe_p->good_cqe, arbelprm_completion_queue_entry_st, opcode);
1644 if (opcode >= CQE_ERROR_OPCODE)
1645 ib_cqe_p->is_error = 1;
1647 ib_cqe_p->is_error = 0;
1650 EX_FLD(cqe_p->good_cqe, arbelprm_completion_queue_entry_st, s);
1652 EX_FLD(cqe_p->good_cqe, arbelprm_completion_queue_entry_st,
1654 ib_cqe_p->wqe = bus_to_virt(wqe_addr_ba);
1657 EX_FLD(cqe_p->good_cqe, arbelprm_completion_queue_entry_st,
1661 static int ib_poll_cq(void *cqh, struct ib_cqe_st *ib_cqe_p, u8 * num_cqes)
1665 struct cq_st *cq = cqh;
1668 rc = poll_cq(cq, &cqe, num_cqes);
1669 if (rc || ((*num_cqes) == 0)) {
1673 dev2ib_cqe(ib_cqe_p, &cqe);
1676 EX_FLD(cqe.good_cqe, arbelprm_completion_queue_entry_st, opcode);
1677 if (opcode >= CQE_ERROR_OPCODE) {
1678 struct ud_send_wqe_st *wqe_p, wqe;
1685 arbelprm_completion_with_error_st,
1687 eprintf("syndrome=0x%lx",
1688 EX_FLD(cqe.error_cqe, arbelprm_completion_with_error_st,
1690 eprintf("vendor_syndrome=0x%lx",
1691 EX_FLD(cqe.error_cqe, arbelprm_completion_with_error_st,
1693 eprintf("wqe_addr=0x%lx", wqe_p);
1694 eprintf("myqpn=0x%lx",
1695 EX_FLD(cqe.error_cqe, arbelprm_completion_with_error_st,
1697 memcpy(&wqe, wqe_p, sizeof wqe);
1698 be_to_cpu_buf(&wqe, sizeof wqe);
1700 eprintf("dumping wqe...");
1701 ptr = (__u32 *) (&wqe);
1702 for (i = 0; i < sizeof wqe; i += 4) {
1703 printf("%lx : ", ptr[i >> 2]);
1711 /* always work on ipoib qp */
1712 static int add_qp_to_mcast_group(union ib_gid_u mcast_gid, __u8 add)
1720 tmp = dev_buffers_p->inprm_buf;
1721 memcpy(tmp, mcast_gid.raw, 16);
1722 be_to_cpu_buf(tmp, 16);
1723 rc = cmd_mgid_hash(tmp, &mgid_hash);
1725 mg = (void *)dev_buffers_p->inprm_buf;
1726 memset(mg, 0, MT_STRUCT_SIZE(arbelprm_mgm_entry_st));
1727 INS_FLD(mcast_gid.as_u32.dw[0], mg, arbelprm_mgm_entry_st,
1729 INS_FLD(mcast_gid.as_u32.dw[1], mg, arbelprm_mgm_entry_st,
1731 INS_FLD(mcast_gid.as_u32.dw[2], mg, arbelprm_mgm_entry_st,
1733 INS_FLD(mcast_gid.as_u32.dw[3], mg, arbelprm_mgm_entry_st,
1736 MT_BYTE_OFFSET(arbelprm_mgm_entry_st,
1738 mgmqp_p = mg + MT_BYTE_OFFSET(arbelprm_mgm_entry_st, mgmqp_0);
1739 INS_FLD(dev_ib_data.ipoib_qp.qpn, mgmqp_p, arbelprm_mgmqp_st,
1741 INS_FLD(add, mgmqp_p, arbelprm_mgmqp_st, qi);
1742 rc = cmd_write_mgm(mg, mgid_hash);
1747 static int clear_interrupt(void)
1749 writel(dev_ib_data.clr_int_data, dev_ib_data.clr_int_addr);
1753 static struct ud_send_wqe_st *alloc_send_wqe(udqp_t qph)
1755 struct udqp_st *qp = qph;
1758 if (qp->snd_wqe_cur_free) {
1759 qp->snd_wqe_cur_free--;
1760 idx = qp->snd_wqe_alloc_idx;
1761 qp->snd_wqe_alloc_idx =
1762 (qp->snd_wqe_alloc_idx + 1) & (qp->max_snd_wqes - 1);
1763 return &qp->snd_wq[idx].wqe_cont.wqe;
1769 static struct recv_wqe_st *alloc_rcv_wqe(struct udqp_st *qp)
1773 if (qp->recv_wqe_cur_free) {
1774 qp->recv_wqe_cur_free--;
1775 idx = qp->recv_wqe_alloc_idx;
1776 qp->recv_wqe_alloc_idx =
1777 (qp->recv_wqe_alloc_idx + 1) & (qp->max_recv_wqes - 1);
1778 return &qp->rcv_wq[idx].wqe_cont.wqe;
1784 static int free_send_wqe(struct ud_send_wqe_st *wqe)
1786 struct udqp_st *qp = ((struct ude_send_wqe_cont_st *)wqe)->qp;
1787 qp->snd_wqe_cur_free++;
1792 static int free_rcv_wqe(struct recv_wqe_st *wqe)
1794 struct udqp_st *qp = ((struct recv_wqe_cont_st *)wqe)->qp;
1795 qp->recv_wqe_cur_free++;
1800 static int free_wqe(void *wqe)
1803 struct recv_wqe_st *rcv_wqe;
1805 // tprintf("free wqe= 0x%x", wqe);
1806 if ((wqe >= (void *)(dev_ib_data.ipoib_qp.rcv_wq)) &&
1808 (void *)(&dev_ib_data.ipoib_qp.rcv_wq[NUM_IPOIB_RCV_WQES]))) {
1809 /* ipoib receive wqe */
1811 rcv_wqe = alloc_rcv_wqe(&dev_ib_data.ipoib_qp);
1813 rc = post_rcv_buf(&dev_ib_data.ipoib_qp, rcv_wqe);
1818 } else if (wqe >= (void *)(dev_ib_data.ipoib_qp.snd_wq) &&
1820 (void *)(&dev_ib_data.ipoib_qp.snd_wq[NUM_IPOIB_SND_WQES])) {
1821 /* ipoib send wqe */
1823 } else if (wqe >= (void *)(dev_ib_data.mads_qp.rcv_wq) &&
1825 (void *)(&dev_ib_data.mads_qp.rcv_wq[NUM_MADS_RCV_WQES])) {
1826 /* mads receive wqe */
1828 rcv_wqe = alloc_rcv_wqe(&dev_ib_data.mads_qp);
1830 rc = post_rcv_buf(&dev_ib_data.mads_qp, rcv_wqe);
1835 } else if (wqe >= (void *)(dev_ib_data.mads_qp.snd_wq) &&
1837 (void *)(&dev_ib_data.mads_qp.snd_wq[NUM_MADS_SND_WQES])) {
1848 static int update_eq_cons_idx(struct eq_st *eq)
1850 writel(eq->cons_counter, eq->ci_base_base_addr);
1854 static void dev2ib_eqe(struct ib_eqe_st *ib_eqe_p, struct eqe_t *eqe_p)
1858 ib_eqe_p->event_type =
1859 EX_FLD(eqe_p, arbelprm_event_queue_entry_st, event_type);
1861 tmp = eqe_p + MT_BYTE_OFFSET(arbelprm_event_queue_entry_st, event_data);
1862 ib_eqe_p->cqn = EX_FLD(tmp, arbelprm_completion_event_st, cqn);
1865 static int poll_eq(struct ib_eqe_st *ib_eqe_p, __u8 * num_eqes)
1871 struct eq_st *eq = &dev_ib_data.eq;
1872 __u32 cons_idx = eq->cons_counter & (eq->eq_size - 1);
1874 ptr = (u32 *) (&(eq->eq_buf[cons_idx]));
1875 owner = (ptr[7] & 0x80000000) ? OWNER_HW : OWNER_SW;
1876 if (owner == OWNER_SW) {
1877 eqe = eq->eq_buf[cons_idx];
1878 be_to_cpu_buf(&eqe, sizeof(eqe));
1879 dev2ib_eqe(ib_eqe_p, &eqe);
1880 ptr[7] |= 0x80000000;
1881 eq->eq_buf[cons_idx] = eqe;
1883 rc = update_eq_cons_idx(eq);
1894 static int ib_device_close(void)
1896 iounmap(memfree_pci_dev.uar);
1897 iounmap(memfree_pci_dev.cr_space);
1901 static __u32 dev_get_qpn(void *qph)
1903 struct udqp_st *qp = qph;
1908 static void dev_post_dbell(void *dbell, __u32 offset)
1911 unsigned long address;
1915 if (((ptr[0] >> 24) & 0xff) != 1) {
1918 tprintf("ptr[0]= 0x%lx", ptr[0]);
1919 tprintf("ptr[1]= 0x%lx", ptr[1]);
1920 address = (unsigned long)(memfree_pci_dev.uar) + offset;
1921 tprintf("va=0x%lx pa=0x%lx", address,
1922 virt_to_bus((const void *)address));
1923 writel(htonl(ptr[0]), memfree_pci_dev.uar + offset);
1926 tprintf("va=0x%lx pa=0x%lx", address,
1927 virt_to_bus((const void *)address));
1928 writel(htonl(ptr[1]), address /*memfree_pci_dev.uar + offset + 4 */ );