123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701 |
- /*
- This software is available to you under a choice of one of two
- licenses. You may choose to be licensed under the terms of the GNU
- General Public License (GPL) Version 2, available at
- <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
- license, available in the LICENSE.TXT file accompanying this
- software. These details are also available at
- <http://openib.org/license.html>.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
-
- Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
- */
-
- #include "mt23108.h"
- #include "ib_driver.h"
- #include <gpxe/pci.h>
-
- struct device_buffers_st {
- union recv_wqe_u mads_qp_rcv_queue[NUM_MADS_RCV_WQES]
- __attribute__ ((aligned(RECV_WQE_U_ALIGN)));
- union recv_wqe_u ipoib_qp_rcv_queue[NUM_IPOIB_RCV_WQES]
- __attribute__ ((aligned(RECV_WQE_U_ALIGN)));
- union ud_send_wqe_u mads_qp_snd_queue[NUM_MADS_SND_WQES]
- __attribute__ ((aligned(UD_SEND_WQE_U_ALIGN)));
- union ud_send_wqe_u ipoib_qp_snd_queue[NUM_IPOIB_SND_WQES]
- __attribute__ ((aligned(UD_SEND_WQE_U_ALIGN)));
- u8 inprm_buf[INPRM_BUF_SZ] __attribute__ ((aligned(INPRM_BUF_ALIGN)));
- u8 outprm_buf[OUTPRM_BUF_SZ]
- __attribute__ ((aligned(OUTPRM_BUF_ALIGN)));
- struct eqe_t eq_buf[1 << LOG2_EQ_SZ]
- __attribute__ ((aligned(sizeof(struct eqe_t))));
- union cqe_st mads_snd_cq_buf[NUM_MADS_SND_CQES]
- __attribute__ ((aligned(sizeof(union cqe_st))));
- union cqe_st ipoib_snd_cq_buf[NUM_IPOIB_SND_CQES]
- __attribute__ ((aligned(sizeof(union cqe_st))));
- union cqe_st mads_rcv_cq_buf[NUM_MADS_RCV_CQES]
- __attribute__ ((aligned(sizeof(union cqe_st))));
- union cqe_st ipoib_rcv_cq_buf[NUM_IPOIB_RCV_CQES]
- __attribute__ ((aligned(sizeof(union cqe_st))));
- union ud_av_u av_array[NUM_AVS]
- __attribute__ ((aligned(ADDRESS_VECTOR_ST_ALIGN)));
- } __attribute__ ((packed));
-
- #define STRUCT_ALIGN_SZ 4096
- #define SRC_BUF_SZ (sizeof(struct device_buffers_st) + STRUCT_ALIGN_SZ - 1)
-
- /* the following must be kept in this order
- for the memory region to cover the buffers */
- static u8 src_buf[SRC_BUF_SZ];
- static struct ib_buffers_st ib_buffers;
- static __u32 memreg_size;
- /* end of order constraint */
-
- static struct dev_pci_struct tavor_pci_dev;
- static struct device_buffers_st *dev_buffers_p;
- static struct device_ib_data_st dev_ib_data;
-
- static int gw_write_cr(__u32 addr, __u32 data)
- {
- writel(htonl(data), tavor_pci_dev.cr_space + addr);
- return 0;
- }
-
- static int gw_read_cr(__u32 addr, __u32 * result)
- {
- *result = ntohl(readl(tavor_pci_dev.cr_space + addr));
- return 0;
- }
-
- static int reset_hca(void)
- {
- return gw_write_cr(TAVOR_RESET_OFFSET, 1);
- }
-
- static int find_mlx_bridge(__u8 hca_bus, __u8 * br_bus_p, __u8 * br_devfn_p)
- {
- int bus;
- int dev;
- int devfn;
- int rc;
- __u16 vendor, dev_id;
- __u8 sec_bus;
-
- for (bus = 0; bus < 256; ++bus) {
- for (dev = 0; dev < 32; ++dev) {
- devfn = (dev << 3);
- rc = pcibios_read_config_word(bus, devfn, PCI_VENDOR_ID,
- &vendor);
- if (rc)
- return rc;
-
- if (vendor != MELLANOX_VENDOR_ID)
- continue;
-
- rc = pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID,
- &dev_id);
- if (rc)
- return rc;
-
- if (dev_id != TAVOR_BRIDGE_DEVICE_ID)
- continue;
-
- rc = pcibios_read_config_byte(bus, devfn,
- PCI_SECONDARY_BUS,
- &sec_bus);
- if (rc)
- return rc;
-
- if (sec_bus == hca_bus) {
- *br_bus_p = bus;
- *br_devfn_p = devfn;
- return 0;
- }
- }
- }
-
- return -1;
- }
-
- static int ib_device_init(struct pci_device *dev)
- {
- int i;
- int rc;
- __u8 br_bus, br_devfn;
-
- tprintf("");
-
- memset(&dev_ib_data, 0, sizeof dev_ib_data);
-
- /* save bars */
- tprintf("bus=%d devfn=0x%x", dev->bus, dev->devfn);
- for (i = 0; i < 6; ++i) {
- tavor_pci_dev.dev.bar[i] =
- pci_bar_start(dev, PCI_BASE_ADDRESS_0 + (i << 2));
- tprintf("bar[%d]= 0x%08lx", i, tavor_pci_dev.dev.bar[i]);
- }
-
- tprintf("");
- /* save config space */
- for (i = 0; i < 64; ++i) {
- rc = pci_read_config_dword(dev, i << 2,
- &tavor_pci_dev.dev.
- dev_config_space[i]);
- if (rc) {
- eprintf("");
- return rc;
- }
- tprintf("config[%d]= 0x%08lx", i << 2,
- tavor_pci_dev.dev.dev_config_space[i]);
- }
-
- tprintf("");
- tavor_pci_dev.dev.dev = dev;
-
- tprintf("");
- if (dev->dev_id == TAVOR_DEVICE_ID) {
-
- rc = find_mlx_bridge(dev->bus, &br_bus, &br_devfn);
- if (rc) {
- eprintf("");
- return rc;
- }
-
- tavor_pci_dev.br.bus = br_bus;
- tavor_pci_dev.br.devfn = br_devfn;
-
- tprintf("bus=%d devfn=0x%x", br_bus, br_devfn);
- /* save config space */
- for (i = 0; i < 64; ++i) {
- rc = pcibios_read_config_dword(br_bus, br_devfn, i << 2,
- &tavor_pci_dev.br.
- dev_config_space[i]);
- if (rc) {
- eprintf("");
- return rc;
- }
- tprintf("config[%d]= 0x%08lx", i << 2,
- tavor_pci_dev.br.dev_config_space[i]);
- }
- }
-
- tprintf("");
-
- /* map cr-space */
- tavor_pci_dev.cr_space = ioremap(tavor_pci_dev.dev.bar[0], 0x100000);
- if (!tavor_pci_dev.cr_space) {
- eprintf("");
- return -1;
- }
-
- /* map uar */
- tavor_pci_dev.uar =
- ioremap(tavor_pci_dev.dev.bar[2] + UAR_IDX * 0x1000, 0x1000);
- if (!tavor_pci_dev.uar) {
- eprintf("");
- return -1;
- }
- tprintf("uar_base (pa:va) = 0x%lx 0x%lx",
- tavor_pci_dev.dev.bar[2] + UAR_IDX * 0x1000, tavor_pci_dev.uar);
-
- tprintf("");
-
- return 0;
- }
-
- static inline unsigned long lalign(unsigned long buf, unsigned long align)
- {
- return (unsigned long)((buf + align - 1) &
- (~(((unsigned long)align) - 1)));
- }
-
- static int init_dev_data(void)
- {
- unsigned long tmp;
-
- tmp = lalign(virt_to_bus(src_buf), STRUCT_ALIGN_SZ);
-
- dev_buffers_p = bus_to_virt(tmp);
- memreg_size = (__u32) (&memreg_size) - (__u32) dev_buffers_p;
- tprintf("src_buf=0x%lx, dev_buffers_p=0x%lx, memreg_size=0x%x", src_buf,
- dev_buffers_p, memreg_size);
-
- return 0;
- }
-
- static int restore_config(void)
- {
- int i;
- int rc;
-
- if (tavor_pci_dev.dev.dev->dev_id == TAVOR_DEVICE_ID) {
- for (i = 0; i < 64; ++i) {
- rc = pcibios_write_config_dword(tavor_pci_dev.br.bus,
- tavor_pci_dev.br.devfn,
- i << 2,
- tavor_pci_dev.br.
- dev_config_space[i]);
- if (rc) {
- return rc;
- }
- }
- }
-
- for (i = 0; i < 64; ++i) {
- if (i != 22 && i != 23) {
- rc = pci_write_config_dword(tavor_pci_dev.dev.dev,
- i << 2,
- tavor_pci_dev.dev.
- dev_config_space[i]);
- if (rc) {
- return rc;
- }
- }
- }
- return 0;
- }
-
- static void prep_init_hca_buf(const struct init_hca_st *init_hca_p, void *buf)
- {
- /*struct init_hca_param_st */ void *p = buf;
- void *tmp;
-
- memset(buf, 0, MT_STRUCT_SIZE(tavorprm_init_hca_st));
-
- tmp =
- p + MT_BYTE_OFFSET(tavorprm_init_hca_st,
- qpc_eec_cqc_eqc_rdb_parameters);
-
- INS_FLD(init_hca_p->qpc_base_addr_h, tmp, tavorprm_qpcbaseaddr_st,
- qpc_base_addr_h);
- INS_FLD(init_hca_p->
- qpc_base_addr_l >> (32 -
- (MT_BIT_SIZE
- (tavorprm_qpcbaseaddr_st,
- qpc_base_addr_l))), tmp,
- tavorprm_qpcbaseaddr_st, qpc_base_addr_l);
- INS_FLD(init_hca_p->log_num_of_qp, tmp, tavorprm_qpcbaseaddr_st,
- log_num_of_qp);
-
- INS_FLD(init_hca_p->cqc_base_addr_h, tmp, tavorprm_qpcbaseaddr_st,
- cqc_base_addr_h);
- INS_FLD(init_hca_p->
- cqc_base_addr_l >> (32 -
- (MT_BIT_SIZE
- (tavorprm_qpcbaseaddr_st,
- cqc_base_addr_l))), tmp,
- tavorprm_qpcbaseaddr_st, cqc_base_addr_l);
- INS_FLD(init_hca_p->log_num_of_cq, tmp, tavorprm_qpcbaseaddr_st,
- log_num_of_cq);
-
- INS_FLD(init_hca_p->eqc_base_addr_h, tmp, tavorprm_qpcbaseaddr_st,
- eqc_base_addr_h);
- INS_FLD(init_hca_p->
- eqc_base_addr_l >> (32 -
- (MT_BIT_SIZE
- (tavorprm_qpcbaseaddr_st,
- eqc_base_addr_l))), tmp,
- tavorprm_qpcbaseaddr_st, eqc_base_addr_l);
- INS_FLD(LOG2_EQS, tmp, tavorprm_qpcbaseaddr_st, log_num_eq);
-
- INS_FLD(init_hca_p->srqc_base_addr_h, tmp, tavorprm_qpcbaseaddr_st,
- srqc_base_addr_h);
- INS_FLD(init_hca_p->
- srqc_base_addr_l >> (32 -
- (MT_BIT_SIZE
- (tavorprm_qpcbaseaddr_st,
- srqc_base_addr_l))), tmp,
- tavorprm_qpcbaseaddr_st, srqc_base_addr_l);
- INS_FLD(init_hca_p->log_num_of_srq, tmp, tavorprm_qpcbaseaddr_st,
- log_num_of_srq);
-
- INS_FLD(init_hca_p->eqpc_base_addr_h, tmp, tavorprm_qpcbaseaddr_st,
- eqpc_base_addr_h);
- INS_FLD(init_hca_p->eqpc_base_addr_l, tmp, tavorprm_qpcbaseaddr_st,
- eqpc_base_addr_l);
-
- INS_FLD(init_hca_p->eeec_base_addr_h, tmp, tavorprm_qpcbaseaddr_st,
- eeec_base_addr_h);
- INS_FLD(init_hca_p->eeec_base_addr_l, tmp, tavorprm_qpcbaseaddr_st,
- eeec_base_addr_l);
-
- tmp = p + MT_BYTE_OFFSET(tavorprm_init_hca_st, multicast_parameters);
-
- INS_FLD(init_hca_p->mc_base_addr_h, tmp, tavorprm_multicastparam_st,
- mc_base_addr_h);
- INS_FLD(init_hca_p->mc_base_addr_l, tmp, tavorprm_multicastparam_st,
- mc_base_addr_l);
-
- INS_FLD(init_hca_p->log_mc_table_entry_sz, tmp,
- tavorprm_multicastparam_st, log_mc_table_entry_sz);
- INS_FLD(init_hca_p->log_mc_table_sz, tmp, tavorprm_multicastparam_st,
- log_mc_table_sz);
- INS_FLD(init_hca_p->mc_table_hash_sz, tmp, tavorprm_multicastparam_st,
- mc_table_hash_sz);
-
- tmp = p + MT_BYTE_OFFSET(tavorprm_init_hca_st, tpt_parameters);
-
- INS_FLD(init_hca_p->mpt_base_addr_h, tmp, tavorprm_tptparams_st,
- mpt_base_adr_h);
- INS_FLD(init_hca_p->mpt_base_addr_l, tmp, tavorprm_tptparams_st,
- mpt_base_adr_l);
- INS_FLD(init_hca_p->log_mpt_sz, tmp, tavorprm_tptparams_st, log_mpt_sz);
-
- INS_FLD(init_hca_p->mtt_base_addr_h, tmp, tavorprm_tptparams_st,
- mtt_base_addr_h);
- INS_FLD(init_hca_p->mtt_base_addr_l, tmp, tavorprm_tptparams_st,
- mtt_base_addr_l);
-
- tmp = p + MT_BYTE_OFFSET(tavorprm_init_hca_st, uar_parameters);
- INS_FLD(tavor_pci_dev.dev.bar[3], tmp, tavorprm_uar_params_st,
- uar_base_addr_h);
- INS_FLD(tavor_pci_dev.dev.bar[2] & 0xfff00000, tmp,
- tavorprm_uar_params_st, uar_base_addr_l);
-
- }
-
- static void prep_sw2hw_mpt_buf(void *buf, __u32 mkey)
- {
- INS_FLD(1, buf, tavorprm_mpt_st, m_io);
- INS_FLD(1, buf, tavorprm_mpt_st, lw);
- INS_FLD(1, buf, tavorprm_mpt_st, lr);
- INS_FLD(1, buf, tavorprm_mpt_st, pa);
- INS_FLD(1, buf, tavorprm_mpt_st, r_w);
-
- INS_FLD(mkey, buf, tavorprm_mpt_st, mem_key);
- INS_FLD(GLOBAL_PD, buf, tavorprm_mpt_st, pd);
-
- INS_FLD(virt_to_bus(dev_buffers_p), buf, tavorprm_mpt_st,
- start_address_l);
- INS_FLD(memreg_size, buf, tavorprm_mpt_st, reg_wnd_len_l);
- }
-
- static void prep_sw2hw_eq_buf(void *buf, struct eqe_t *eq)
- {
- memset(buf, 0, MT_STRUCT_SIZE(tavorprm_eqc_st));
-
- INS_FLD(2, buf, tavorprm_eqc_st, st); /* fired */
- INS_FLD(virt_to_bus(eq), buf, tavorprm_eqc_st, start_address_l);
- INS_FLD(LOG2_EQ_SZ, buf, tavorprm_eqc_st, log_eq_size);
- INS_FLD(UAR_IDX, buf, tavorprm_eqc_st, usr_page);
- INS_FLD(GLOBAL_PD, buf, tavorprm_eqc_st, pd);
- INS_FLD(dev_ib_data.mkey, buf, tavorprm_eqc_st, lkey);
- }
-
- static void init_eq_buf(void *eq_buf)
- {
- int num_eqes = 1 << LOG2_EQ_SZ;
-
- memset(eq_buf, 0xff, num_eqes * sizeof(struct eqe_t));
- }
-
- static void prep_init_ib_buf(void *buf)
- {
- __u32 *ptr = (__u32 *) buf;
-
- ptr[0] = 0x4310;
- ptr[1] = 1;
- ptr[2] = 64;
- }
-
- static void prep_sw2hw_cq_buf(void *buf, __u8 eqn, __u32 cqn,
- union cqe_st *cq_buf)
- {
- __u32 *ptr = (__u32 *) buf;
-
- ptr[2] = virt_to_bus(cq_buf);
- ptr[3] = (LOG2_CQ_SZ << 24) | UAR_IDX;
- ptr[4] = eqn;
- ptr[5] = eqn;
- ptr[6] = dev_ib_data.pd;
- ptr[7] = dev_ib_data.mkey;
- ptr[12] = cqn;
- }
-
- static void prep_rst2init_qpee_buf(void *buf, __u32 snd_cqn, __u32 rcv_cqn,
- __u32 qkey)
- {
- struct qp_ee_state_tarnisition_st *prm;
- void *tmp;
-
- prm = (struct qp_ee_state_tarnisition_st *)buf;
-
- INS_FLD(3, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st, st); /* service type = UD */
- INS_FLD(3, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st, pm_state); /* required for UD QP */
- INS_FLD(UAR_IDX, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st,
- usr_page);
- INS_FLD(dev_ib_data.pd, &prm->ctx,
- tavorprm_queue_pair_ee_context_entry_st, pd);
- INS_FLD(dev_ib_data.mkey, &prm->ctx,
- tavorprm_queue_pair_ee_context_entry_st, wqe_lkey);
- INS_FLD(1, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st, ssc); /* generate send CQE */
- INS_FLD(1, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st, rsc); /* generate receive CQE */
- INS_FLD(snd_cqn, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st,
- cqn_snd);
- INS_FLD(rcv_cqn, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st,
- cqn_rcv);
- INS_FLD(qkey, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st,
- q_key);
-
- tmp =
- (void *)(&prm->ctx) +
- MT_BYTE_OFFSET(tavorprm_queue_pair_ee_context_entry_st,
- primary_address_path);
- INS_FLD(dev_ib_data.port, tmp, tavorprm_address_path_st, port_number);
-
- INS_FLD(4, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st, mtu);
- INS_FLD(0xb, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st,
- msg_max);
- }
-
- static void prep_init2rtr_qpee_buf(void *buf)
- {
- struct qp_ee_state_tarnisition_st *prm;
-
- prm = (struct qp_ee_state_tarnisition_st *)buf;
-
- INS_FLD(4, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st, mtu);
- INS_FLD(0xb, &prm->ctx, tavorprm_queue_pair_ee_context_entry_st,
- msg_max);
- }
-
- static void init_av_array()
- {
- int i;
-
- dev_ib_data.udav.av_array = dev_buffers_p->av_array;
- dev_ib_data.udav.udav_next_free = FL_EOL;
- for (i = 0; i < NUM_AVS; ++i) {
- dev_ib_data.udav.av_array[i].ud_av.next_free =
- dev_ib_data.udav.udav_next_free;
- dev_ib_data.udav.udav_next_free = i;
- }
- tprintf("dev_ib_data.udav.udav_next_free=%d", i);
- }
-
- static int setup_hca(__u8 port, void **eq_p)
- {
- int rc;
- __u32 key, in_key;
- __u32 *inprm;
- struct eqe_t *eq_buf;
- __u32 event_mask;
- void *cfg;
- int ret = 0;
- __u8 eqn;
- struct dev_lim_st dev_lim;
- struct init_hca_st init_hca;
- __u32 offset, base_h, base_l;
- const __u32 delta = 0x400000;
- struct query_fw_st qfw;
-
- tprintf("called");
-
- init_dev_data();
-
- rc = reset_hca();
- if (rc) {
- ret = -1;
- eprintf("");
- goto exit;
- } else {
- tprintf("reset_hca() success");
- }
-
- mdelay(1000); /* wait for 1 sec */
-
- rc = restore_config();
- if (rc) {
- ret = -1;
- eprintf("");
- goto exit;
- } else {
- tprintf("restore_config() success");
- }
-
- dev_ib_data.pd = GLOBAL_PD;
- dev_ib_data.port = port;
-
- /* execute system enable command */
- rc = cmd_sys_en();
- if (rc) {
- ret = -1;
- eprintf("");
- goto exit;
- } else {
- tprintf("cmd_sys_en() success");
- }
-
- rc= cmd_query_fw(&qfw);
- if (rc) {
- ret = -1;
- eprintf("");
- goto exit;
- } else {
- tprintf("cmd_query_fw() success");
-
- if (print_info) {
- printf("FW ver = %d.%d.%d\n",
- qfw.fw_rev_major,
- qfw.fw_rev_minor,
- qfw.fw_rev_subminor);
- }
- tprintf("fw_rev_major=%d", qfw.fw_rev_major);
- tprintf("fw_rev_minor=%d", qfw.fw_rev_minor);
- tprintf("fw_rev_subminor=%d", qfw.fw_rev_subminor);
- tprintf("error_buf_start_h=0x%x", qfw.error_buf_start_h);
- tprintf("error_buf_start_l=0x%x", qfw.error_buf_start_l);
- tprintf("error_buf_size=%d", qfw.error_buf_size);
- }
-
- if (qfw.error_buf_start_h) {
- eprintf("too high physical address");
- ret = -1;
- goto exit;
- }
-
- dev_ib_data.error_buf_addr= ioremap(qfw.error_buf_start_l,
- qfw.error_buf_size*4);
- dev_ib_data.error_buf_size= qfw.error_buf_size;
- if (!dev_ib_data.error_buf_addr) {
- eprintf("");
- ret = -1;
- goto exit;
- }
-
-
- rc = cmd_query_dev_lim(&dev_lim);
- if (rc) {
- ret = -1;
- eprintf("");
- goto exit;
- } else {
- tprintf("cmd_query_dev_lim() success");
- tprintf("log2_rsvd_qps=%x", dev_lim.log2_rsvd_qps);
- tprintf("qpc_entry_sz=%x", dev_lim.qpc_entry_sz);
- tprintf("log2_rsvd_srqs=%x", dev_lim.log2_rsvd_srqs);
- tprintf("srq_entry_sz=%x", dev_lim.srq_entry_sz);
- tprintf("log2_rsvd_ees=%x", dev_lim.log2_rsvd_ees);
- tprintf("eec_entry_sz=%x", dev_lim.eec_entry_sz);
- tprintf("log2_rsvd_cqs=%x", dev_lim.log2_rsvd_cqs);
- tprintf("cqc_entry_sz=%x", dev_lim.cqc_entry_sz);
- tprintf("log2_rsvd_mtts=%x", dev_lim.log2_rsvd_mtts);
- tprintf("mtt_entry_sz=%x", dev_lim.mtt_entry_sz);
- tprintf("log2_rsvd_mrws=%x", dev_lim.log2_rsvd_mrws);
- tprintf("mpt_entry_sz=%x", dev_lim.mpt_entry_sz);
- tprintf("eqc_entry_sz=%x", dev_lim.eqc_entry_sz);
- }
-
- /* set the qp and cq numbers according
- to the results of query_dev_lim */
- dev_ib_data.mads_qp.qpn = (1 << dev_lim.log2_rsvd_qps) +
- +QPN_BASE + MADS_QPN_SN;
- dev_ib_data.ipoib_qp.qpn = (1 << dev_lim.log2_rsvd_qps) +
- +QPN_BASE + IPOIB_QPN_SN;
-
- dev_ib_data.mads_qp.snd_cq.cqn = (1 << dev_lim.log2_rsvd_cqs) +
- MADS_SND_CQN_SN;
- dev_ib_data.mads_qp.rcv_cq.cqn = (1 << dev_lim.log2_rsvd_cqs) +
- MADS_RCV_CQN_SN;
-
- dev_ib_data.ipoib_qp.snd_cq.cqn = (1 << dev_lim.log2_rsvd_cqs) +
- IPOIB_SND_CQN_SN;
- dev_ib_data.ipoib_qp.rcv_cq.cqn = (1 << dev_lim.log2_rsvd_cqs) +
- IPOIB_RCV_CQN_SN;
-
- /* disable SRQ */
- cfg = (void *)dev_buffers_p->inprm_buf;
- memset(cfg, 0, MT_STRUCT_SIZE(tavorprm_mod_stat_cfg_st));
- INS_FLD(1, cfg, tavorprm_mod_stat_cfg_st, srq_m); //cfg->srq_m = 1;
- rc = cmd_mod_stat_cfg(cfg);
- if (rc) {
- ret = -1;
- eprintf("");
- goto exit;
- } else {
- tprintf("cmd_mod_stat_cfg() success");
- }
-
- /* prepare the init_hca params to pass
- to prep_init_hca_buf */
- memset(&init_hca, 0, sizeof init_hca);
- offset = 0;
- base_h = tavor_pci_dev.dev.bar[5] & 0xfffffff0;
- base_l = tavor_pci_dev.dev.bar[4] & 0xfffffff0;
-
- tprintf("base_h=0x%lx, base_l=0x%lx", base_h, base_l);
-
- init_hca.qpc_base_addr_h = base_h;
- init_hca.qpc_base_addr_l = base_l + offset;
- init_hca.log_num_of_qp = dev_lim.log2_rsvd_qps + 1;
- offset += delta;
-
- init_hca.eec_base_addr_h = base_h;
- init_hca.eec_base_addr_l = base_l + offset;
- init_hca.log_num_of_ee = dev_lim.log2_rsvd_ees;
- offset += delta;
-
- init_hca.srqc_base_addr_h = base_h;
- init_hca.srqc_base_addr_l = base_l + offset;
- init_hca.log_num_of_srq = dev_lim.log2_rsvd_srqs;
- offset += delta;
-
- init_hca.cqc_base_addr_h = base_h;
- init_hca.cqc_base_addr_l = base_l + offset;
- init_hca.log_num_of_cq = dev_lim.log2_rsvd_cqs + 1;
- offset += delta;
-
- init_hca.eqpc_base_addr_h = base_h;
- init_hca.eqpc_base_addr_l = base_l + offset;
- offset += delta;
-
- init_hca.eeec_base_addr_h = base_h;
- init_hca.eeec_base_addr_l = base_l + offset;
- offset += delta;
-
- init_hca.eqc_base_addr_h = base_h;
- init_hca.eqc_base_addr_l = base_l + offset;
- init_hca.log_num_of_eq = LOG2_EQS;
- offset += delta;
-
- init_hca.rdb_base_addr_h = base_h;
- init_hca.rdb_base_addr_l = base_l + offset;
- offset += delta;
-
- init_hca.mc_base_addr_h = base_h;
- init_hca.mc_base_addr_l = base_l + offset;
- init_hca.log_mc_table_entry_sz = LOG2_MC_ENTRY;
- init_hca.mc_table_hash_sz = 0;
- init_hca.log_mc_table_sz = LOG2_MC_GROUPS;
- offset += delta;
-
- init_hca.mpt_base_addr_h = base_h;
- init_hca.mpt_base_addr_l = base_l + offset;
- init_hca.log_mpt_sz = dev_lim.log2_rsvd_mrws + 1;
- offset += delta;
-
- init_hca.mtt_base_addr_h = base_h;
- init_hca.mtt_base_addr_l = base_l + offset;
-
- /* this buffer is used for all the commands */
- inprm = (void *)dev_buffers_p->inprm_buf;
- /* excute init_hca command */
- prep_init_hca_buf(&init_hca, inprm);
-
- rc = cmd_init_hca(inprm, MT_STRUCT_SIZE(tavorprm_init_hca_st));
- if (rc) {
- ret = -1;
- eprintf("");
- goto undo_sys_en;
- } else
- tprintf("cmd_init_hca() success");
-
- /* register a single memory region which covers
- 4 GB of the address space which will be used
- throughout the driver */
- memset(inprm, 0, SW2HW_MPT_IBUF_SZ);
- in_key = MKEY_PREFIX + (1 << dev_lim.log2_rsvd_mrws);
- prep_sw2hw_mpt_buf(inprm, in_key);
- rc = cmd_sw2hw_mpt(&key, in_key, inprm, SW2HW_MPT_IBUF_SZ);
- if (rc) {
- ret = -1;
- eprintf("");
- goto undo_init_hca;
- } else {
- tprintf("cmd_sw2hw_mpt() success, key=0x%lx", key);
- }
- dev_ib_data.mkey = key;
-
- eqn = EQN;
- /* allocate a single EQ which will receive
- all the events */
- eq_buf = dev_buffers_p->eq_buf;
- init_eq_buf(eq_buf); /* put in HW ownership */
- prep_sw2hw_eq_buf(inprm, eq_buf);
- rc = cmd_sw2hw_eq(SW2HW_EQ_IBUF_SZ);
- if (rc) {
- ret = -1;
- eprintf("");
- goto undo_sw2hw_mpt;
- } else
- tprintf("cmd_sw2hw_eq() success");
-
- event_mask = (1 << XDEV_EV_TYPE_CQ_COMP) |
- (1 << XDEV_EV_TYPE_CQ_ERR) |
- (1 << XDEV_EV_TYPE_LOCAL_WQ_CATAS_ERR) |
- (1 << XDEV_EV_TYPE_PORT_ERR) |
- (1 << XDEV_EV_TYPE_LOCAL_WQ_INVALID_REQ_ERR) |
- (1 << XDEV_EV_TYPE_LOCAL_WQ_ACCESS_VIOL_ERR) |
- (1 << TAVOR_IF_EV_TYPE_OVERRUN);
- rc = cmd_map_eq(eqn, event_mask, 1);
- if (rc) {
- ret = -1;
- eprintf("");
- goto undo_sw2hw_eq;
- } else
- tprintf("cmd_map_eq() success");
-
- dev_ib_data.eq.eqn = eqn;
- dev_ib_data.eq.eq_buf = eq_buf;
- dev_ib_data.eq.cons_idx = 0;
- dev_ib_data.eq.eq_size = 1 << LOG2_EQ_SZ;
- *eq_p = &dev_ib_data.eq;
-
- memset(inprm, 0, INIT_IB_IBUF_SZ);
- prep_init_ib_buf(inprm);
- rc = cmd_init_ib(port, inprm, INIT_IB_IBUF_SZ);
- if (rc) {
- ret = -1;
- eprintf("");
- goto undo_sw2hw_eq;
- } else
- tprintf("cmd_init_ib() success");
-
- init_av_array();
- tprintf("init_av_array() done");
-
- goto exit;
-
- undo_sw2hw_eq:
- rc = cmd_hw2sw_eq(EQN);
- if (rc) {
- eprintf("");
- } else
- tprintf("cmd_hw2sw_eq() success");
-
- undo_sw2hw_mpt:
- rc = cmd_hw2sw_mpt(key);
- if (rc)
- eprintf("");
- else
- tprintf("cmd_hw2sw_mpt() success key=0x%lx", key);
-
- undo_init_hca:
- rc = cmd_close_hca(0);
- if (rc) {
- eprintf("");
- goto undo_sys_en;
- } else
- tprintf("cmd_close_hca() success");
-
- undo_sys_en:
- rc = cmd_sys_dis();
- if (rc) {
- eprintf("");
- goto undo_sys_en;
- } else
- tprintf("cmd_sys_dis() success");
- goto exit;
-
- exit:
- return ret;
- }
-
- static void *get_inprm_buf(void)
- {
- return dev_buffers_p->inprm_buf;
- }
-
- static void *get_outprm_buf(void)
- {
- return dev_buffers_p->outprm_buf;
- }
-
- static void *get_send_wqe_buf(void *wqe, __u8 index)
- {
- struct ud_send_wqe_st *snd_wqe = wqe;
-
- return bus_to_virt(snd_wqe->mpointer[index].local_addr_l);
- }
-
- static void *get_rcv_wqe_buf(void *wqe, __u8 index)
- {
- struct recv_wqe_st *rcv_wqe = wqe;
-
- return bus_to_virt(be32_to_cpu(rcv_wqe->mpointer[index].local_addr_l));
- }
-
- static void modify_av_params(struct ud_av_st *av,
- __u16 dlid,
- __u8 g,
- __u8 sl, __u8 rate, union ib_gid_u *gid, __u32 qpn)
- {
- memset(&av->av, 0, sizeof av->av);
- INS_FLD(dev_ib_data.port, &av->av, tavorprm_ud_address_vector_st,
- port_number);
- INS_FLD(dev_ib_data.pd, &av->av, tavorprm_ud_address_vector_st, pd);
- INS_FLD(dlid, &av->av, tavorprm_ud_address_vector_st, rlid);
- INS_FLD(g, &av->av, tavorprm_ud_address_vector_st, g);
- INS_FLD(sl, &av->av, tavorprm_ud_address_vector_st, sl);
- INS_FLD(3, &av->av, tavorprm_ud_address_vector_st, msg);
-
- if (rate >= 3)
- INS_FLD(0, &av->av, tavorprm_ud_address_vector_st, max_stat_rate); /* 4x */
- else
- INS_FLD(1, &av->av, tavorprm_ud_address_vector_st, max_stat_rate); /* 1x */
-
- cpu_to_be_buf(&av->av, sizeof(av->av));
- if (g) {
- if (gid) {
- INS_FLD(*((__u32 *) (&gid->raw[0])), &av->av,
- tavorprm_ud_address_vector_st, rgid_127_96);
- INS_FLD(*((__u32 *) (&gid->raw[4])), &av->av,
- tavorprm_ud_address_vector_st, rgid_95_64);
- INS_FLD(*((__u32 *) (&gid->raw[8])), &av->av,
- tavorprm_ud_address_vector_st, rgid_63_32);
- INS_FLD(*((__u32 *) (&gid->raw[12])), &av->av,
- tavorprm_ud_address_vector_st, rgid_31_0);
- } else {
- INS_FLD(0, &av->av, tavorprm_ud_address_vector_st,
- rgid_127_96);
- INS_FLD(0, &av->av, tavorprm_ud_address_vector_st,
- rgid_95_64);
- INS_FLD(0, &av->av, tavorprm_ud_address_vector_st,
- rgid_63_32);
- INS_FLD(0, &av->av, tavorprm_ud_address_vector_st,
- rgid_31_0);
- }
- } else {
- INS_FLD(0, &av->av, tavorprm_ud_address_vector_st, rgid_127_96);
- INS_FLD(0, &av->av, tavorprm_ud_address_vector_st, rgid_95_64);
- INS_FLD(0, &av->av, tavorprm_ud_address_vector_st, rgid_63_32);
- INS_FLD(2, &av->av, tavorprm_ud_address_vector_st, rgid_31_0);
- }
- av->dest_qp = qpn;
- }
-
- static void init_cq_buf(union cqe_st *cq_buf, __u8 num_cqes)
- {
- memset(cq_buf, 0xff, num_cqes * sizeof cq_buf[0]);
- }
-
- static int post_rcv_buf(struct udqp_st *qp, struct recv_wqe_st *rcv_wqe)
- {
- struct recv_doorbell_st dbell;
- int rc;
- __u32 tmp[2];
- struct recv_wqe_st *tmp_wqe = (struct recv_wqe_st *)tmp;
- __u32 *ptr_dst;
-
- memset(&dbell, 0, sizeof dbell);
- INS_FLD(sizeof(*rcv_wqe) >> 4, &dbell, tavorprm_receive_doorbell_st,
- nds);
- INS_FLD(virt_to_bus(rcv_wqe) >> 6, &dbell, tavorprm_receive_doorbell_st,
- nda);
- INS_FLD(qp->qpn, &dbell, tavorprm_receive_doorbell_st, qpn);
- INS_FLD(1, &dbell, tavorprm_receive_doorbell_st, credits);
-
- if (qp->last_posted_rcv_wqe) {
- memcpy(tmp, qp->last_posted_rcv_wqe, sizeof(tmp));
- be_to_cpu_buf(tmp, sizeof(tmp));
- INS_FLD(1, tmp_wqe->next, wqe_segment_next_st, dbd);
- INS_FLD(sizeof(*rcv_wqe) >> 4, tmp_wqe->next,
- wqe_segment_next_st, nds);
- INS_FLD(virt_to_bus(rcv_wqe) >> 6, tmp_wqe->next,
- wqe_segment_next_st, nda_31_6);
- /* this is not really opcode but since the struct
- is used for both send and receive, in receive this bit must be 1
- which coinsides with nopcode */
- INS_FLD(1, tmp_wqe->next, wqe_segment_next_st, nopcode);
-
- cpu_to_be_buf(tmp, sizeof(tmp));
-
- ptr_dst = (__u32 *) (qp->last_posted_rcv_wqe);
- ptr_dst[0] = tmp[0];
- ptr_dst[1] = tmp[1];
- }
- rc = cmd_post_doorbell(&dbell, POST_RCV_OFFSET);
- if (!rc) {
- qp->last_posted_rcv_wqe = rcv_wqe;
- }
-
- return rc;
- }
-
- static int post_send_req(void *qph, void *wqeh, __u8 num_gather)
- {
- struct send_doorbell_st dbell;
- int rc;
- struct udqp_st *qp = qph;
- struct ud_send_wqe_st *snd_wqe = wqeh;
- struct next_control_seg_st tmp;
- __u32 *psrc, *pdst;
- __u32 nds;
-
- tprintf("snd_wqe=0x%lx, virt_to_bus(snd_wqe)=0x%lx", snd_wqe,
- virt_to_bus(snd_wqe));
-
- memset(&dbell, 0, sizeof dbell);
- INS_FLD(XDEV_NOPCODE_SEND, &dbell, tavorprm_send_doorbell_st, nopcode);
- INS_FLD(1, &dbell, tavorprm_send_doorbell_st, f);
- INS_FLD(virt_to_bus(snd_wqe) >> 6, &dbell, tavorprm_send_doorbell_st,
- nda);
- nds =
- (sizeof(snd_wqe->next) + sizeof(snd_wqe->udseg) +
- sizeof(snd_wqe->mpointer[0]) * num_gather) >> 4;
- INS_FLD(nds, &dbell, tavorprm_send_doorbell_st, nds);
- INS_FLD(qp->qpn, &dbell, tavorprm_send_doorbell_st, qpn);
-
- tprintf("0= %lx", ((__u32 *) ((void *)(&dbell)))[0]);
- tprintf("1= %lx", ((__u32 *) ((void *)(&dbell)))[1]);
-
- if (qp->last_posted_snd_wqe) {
- memcpy(&tmp, &qp->last_posted_snd_wqe->next, sizeof tmp);
- be_to_cpu_buf(&tmp, sizeof tmp);
- INS_FLD(1, &tmp, wqe_segment_next_st, dbd);
- INS_FLD(virt_to_bus(snd_wqe) >> 6, &tmp, wqe_segment_next_st,
- nda_31_6);
- INS_FLD(nds, &tmp, wqe_segment_next_st, nds);
-
- psrc = (__u32 *) (&tmp);
- pdst = (__u32 *) (&qp->last_posted_snd_wqe->next);
- pdst[0] = htonl(psrc[0]);
- pdst[1] = htonl(psrc[1]);
- }
-
- rc = cmd_post_doorbell(&dbell, POST_SND_OFFSET);
- if (!rc) {
- qp->last_posted_snd_wqe = snd_wqe;
- }
-
- return rc;
- }
-
- static int create_mads_qp(void **qp_pp, void **snd_cq_pp, void **rcv_cq_pp)
- {
- __u8 i;
- int rc;
- struct udqp_st *qp;
-
- qp = &dev_ib_data.mads_qp;
-
- /* set the pointer to the receive WQEs buffer */
- qp->rcv_wq = dev_buffers_p->mads_qp_rcv_queue;
-
- qp->send_buf_sz = MAD_BUF_SZ;
- qp->rcv_buf_sz = MAD_BUF_SZ;
-
- qp->recv_wqe_alloc_idx = 0;
- qp->max_recv_wqes = NUM_MADS_RCV_WQES;
- qp->recv_wqe_cur_free = NUM_MADS_RCV_WQES;
-
- /* iterrate through the list */
- for (i = 0; i < NUM_MADS_RCV_WQES; ++i) {
- /* clear the WQE */
- memset(&qp->rcv_wq[i], 0, sizeof(qp->rcv_wq[i]));
-
- qp->rcv_wq[i].wqe_cont.qp = qp;
- qp->rcv_bufs[i] = ib_buffers.rcv_mad_buf[i];
- }
-
- /* set the pointer to the send WQEs buffer */
- qp->snd_wq = dev_buffers_p->mads_qp_snd_queue;
-
- qp->snd_wqe_alloc_idx = 0;
- qp->max_snd_wqes = NUM_MADS_SND_WQES;
- qp->snd_wqe_cur_free = NUM_MADS_SND_WQES;
-
- /* iterrate through the list */
- for (i = 0; i < NUM_MADS_SND_WQES; ++i) {
- /* clear the WQE */
- memset(&qp->snd_wq[i], 0, sizeof(qp->snd_wq[i]));
-
- /* link the WQE to the free list */
- qp->snd_wq[i].wqe_cont.qp = qp;
- qp->snd_bufs[i] = ib_buffers.send_mad_buf[i];
- }
-
- /* qp number and cq numbers are already set up */
- qp->snd_cq.cq_buf = dev_buffers_p->mads_snd_cq_buf;
- qp->rcv_cq.cq_buf = dev_buffers_p->mads_rcv_cq_buf;
- qp->snd_cq.num_cqes = NUM_MADS_SND_CQES;
- qp->rcv_cq.num_cqes = NUM_MADS_RCV_CQES;
- qp->qkey = GLOBAL_QKEY;
- rc = create_udqp(qp);
- if (!rc) {
- *qp_pp = qp;
- *snd_cq_pp = &qp->snd_cq;
- *rcv_cq_pp = &qp->rcv_cq;
- }
-
- return rc;
- }
-
- static int create_ipoib_qp(void **qp_pp,
- void **snd_cq_pp, void **rcv_cq_pp, __u32 qkey)
- {
- __u8 i;
- int rc;
- struct udqp_st *qp;
- qp = &dev_ib_data.ipoib_qp;
-
- /* set the pointer to the receive WQEs buffer */
- qp->rcv_wq = dev_buffers_p->ipoib_qp_rcv_queue;
-
- qp->rcv_buf_sz = IPOIB_RCV_BUF_SZ;
-
- qp->recv_wqe_alloc_idx = 0;
- qp->max_recv_wqes = NUM_IPOIB_RCV_WQES;
- qp->recv_wqe_cur_free = NUM_IPOIB_RCV_WQES;
-
- /* iterrate through the list */
- for (i = 0; i < NUM_IPOIB_RCV_WQES; ++i) {
- /* clear the WQE */
- memset(&qp->rcv_wq[i], 0, sizeof(qp->rcv_wq[i]));
-
- /* update data */
- qp->rcv_wq[i].wqe_cont.qp = qp;
- qp->rcv_bufs[i] = ib_buffers.ipoib_rcv_buf[i];
- tprintf("rcv_buf=%lx", qp->rcv_bufs[i]);
- }
-
- /* init send queue WQEs list */
- /* set the list empty */
- qp->snd_wqe_alloc_idx = 0;
- qp->max_snd_wqes = NUM_IPOIB_SND_WQES;
- qp->snd_wqe_cur_free = NUM_IPOIB_SND_WQES;
-
- /* set the pointer to the send WQEs buffer */
- qp->snd_wq = dev_buffers_p->ipoib_qp_snd_queue;
-
- /* iterrate through the list */
- for (i = 0; i < NUM_IPOIB_SND_WQES; ++i) {
- /* clear the WQE */
- memset(&qp->snd_wq[i], 0, sizeof(qp->snd_wq[i]));
-
- /* update data */
- qp->snd_wq[i].wqe_cont.qp = qp;
- qp->snd_bufs[i] = ib_buffers.send_ipoib_buf[i];
- qp->send_buf_sz = 4;
- }
-
- /* qp number and cq numbers are already set up */
-
- qp->snd_cq.cq_buf = dev_buffers_p->ipoib_snd_cq_buf;
- qp->rcv_cq.cq_buf = dev_buffers_p->ipoib_rcv_cq_buf;
- qp->snd_cq.num_cqes = NUM_IPOIB_SND_CQES;
- qp->rcv_cq.num_cqes = NUM_IPOIB_RCV_CQES;
- qp->qkey = qkey;
- rc = create_udqp(qp);
- if (!rc) {
- *qp_pp = qp;
- *snd_cq_pp = &qp->snd_cq;
- *rcv_cq_pp = &qp->rcv_cq;
- }
-
- return rc;
- }
-
- static int create_udqp(struct udqp_st *qp)
- {
- int rc, ret = 0;
- void *inprm;
- struct recv_wqe_st *rcv_wqe;
-
- inprm = dev_buffers_p->inprm_buf;
-
- /* create send CQ */
- init_cq_buf(qp->snd_cq.cq_buf, qp->snd_cq.num_cqes);
- qp->snd_cq.cons_idx = 0;
- memset(inprm, 0, SW2HW_CQ_IBUF_SZ);
- prep_sw2hw_cq_buf(inprm, dev_ib_data.eq.eqn, qp->snd_cq.cqn,
- qp->snd_cq.cq_buf);
- rc = cmd_sw2hw_cq(qp->snd_cq.cqn, inprm, SW2HW_CQ_IBUF_SZ);
- if (rc) {
- ret = -1;
- eprintf("");
- goto exit;
- }
-
- /* create receive CQ */
- init_cq_buf(qp->rcv_cq.cq_buf, qp->rcv_cq.num_cqes);
- qp->rcv_cq.cons_idx = 0;
- memset(inprm, 0, SW2HW_CQ_IBUF_SZ);
- prep_sw2hw_cq_buf(inprm, dev_ib_data.eq.eqn, qp->rcv_cq.cqn,
- qp->rcv_cq.cq_buf);
- rc = cmd_sw2hw_cq(qp->rcv_cq.cqn, inprm, SW2HW_CQ_IBUF_SZ);
- if (rc) {
- ret = -1;
- eprintf("");
- goto undo_snd_cq;
- }
-
- memset(inprm, 0, QPCTX_IBUF_SZ);
- prep_rst2init_qpee_buf(inprm, qp->snd_cq.cqn, qp->rcv_cq.cqn, qp->qkey);
- rc = cmd_rst2init_qpee(qp->qpn, inprm, QPCTX_IBUF_SZ);
- if (rc) {
- ret = -1;
- eprintf("");
- goto undo_rcv_cq;
- }
-
- qp->last_posted_rcv_wqe = NULL;
- qp->last_posted_snd_wqe = NULL;
-
- /* post all the buffers to the receive queue */
- while (1) {
- /* allocate wqe */
- rcv_wqe = alloc_rcv_wqe(qp);
- if (!rcv_wqe)
- break;
-
- /* post the buffer */
- rc = post_rcv_buf(qp, rcv_wqe);
- if (rc) {
- ret = -1;
- eprintf("");
- goto undo_rcv_cq;
- }
- }
-
- memset(inprm, 0, QPCTX_IBUF_SZ);
- prep_init2rtr_qpee_buf(inprm);
- rc = cmd_init2rtr_qpee(qp->qpn, inprm, QPCTX_IBUF_SZ);
- if (rc) {
- ret = -1;
- eprintf("");
- goto undo_rcv_cq;
- }
-
- memset(inprm, 0, QPCTX_IBUF_SZ);
- rc = cmd_rtr2rts_qpee(qp->qpn, inprm, QPCTX_IBUF_SZ);
- if (rc) {
- ret = -1;
- eprintf("");
- goto undo_rcv_cq;
- }
-
- goto exit;
-
- undo_rcv_cq:
- rc = cmd_hw2sw_cq(qp->rcv_cq.cqn);
- if (rc)
- eprintf("");
-
- undo_snd_cq:
- rc = cmd_hw2sw_cq(qp->snd_cq.cqn);
- if (rc)
- eprintf("");
-
- exit:
- return ret;
- }
-
- static int destroy_udqp(struct udqp_st *qp)
- {
- int rc;
-
- rc = cmd_2err_qpee(qp->qpn);
- if (rc) {
- eprintf("");
- return rc;
- }
- tprintf("cmd_2err_qpee(0x%lx) success", qp->qpn);
-
- rc = cmd_2rst_qpee(qp->qpn);
- if (rc) {
- eprintf("");
- return rc;
- }
- tprintf("cmd_2rst_qpee(0x%lx) success", qp->qpn);
-
- rc = cmd_hw2sw_cq(qp->rcv_cq.cqn);
- if (rc) {
- eprintf("");
- return rc;
- }
- tprintf("cmd_hw2sw_cq(0x%lx) success", qp->snd_cq.cqn);
-
- rc = cmd_hw2sw_cq(qp->snd_cq.cqn);
- if (rc) {
- eprintf("");
- return rc;
- }
- tprintf("cmd_hw2sw_cq(0x%lx) success", qp->rcv_cq.cqn);
-
- return rc;
- }
-
- static void prep_send_wqe_buf(void *qph,
- void *avh,
- void *wqeh,
- const void *buf,
- unsigned int offset, __u16 len, __u8 e)
- {
- struct udqp_st *qp = qph;
- struct ud_av_st *av = avh;
- struct ud_send_wqe_st *wqe = wqeh;
-
- INS_FLD(e, wqe->next.control, wqe_segment_ctrl_send_st, e);
- INS_FLD(1, wqe->next.control, wqe_segment_ctrl_send_st, always1);
-
- wqe->udseg.av_add_h = 0;
- wqe->udseg.av_add_l = virt_to_bus(&av->av);
- wqe->udseg.dest_qp = av->dest_qp;
- wqe->udseg.lkey = dev_ib_data.mkey;
- wqe->udseg.qkey = qp->qkey;
-
- if (buf) {
- memcpy(bus_to_virt(wqe->mpointer[0].local_addr_l) + offset, buf,
- len);
- len += offset;
- }
- wqe->mpointer[0].byte_count = len;
- wqe->mpointer[0].lkey = dev_ib_data.mkey;
-
- cpu_to_be_buf(wqe, sizeof *wqe);
- }
-
- static void *alloc_ud_av(void)
- {
- u8 next_free;
-
- if (dev_ib_data.udav.udav_next_free == FL_EOL) {
- return NULL;
- }
-
- next_free = dev_ib_data.udav.udav_next_free;
- dev_ib_data.udav.udav_next_free =
- dev_buffers_p->av_array[next_free].ud_av.next_free;
- tprintf("allocated udav %d", next_free);
- return &dev_buffers_p->av_array[next_free].ud_av;
- }
-
- static void free_ud_av(void *avh)
- {
- union ud_av_u *avu;
- __u8 idx, old_idx;
- struct ud_av_st *av = avh;
-
- avu = (union ud_av_u *)av;
-
- idx = avu - dev_buffers_p->av_array;
- tprintf("freeing udav idx=%d", idx);
- old_idx = dev_ib_data.udav.udav_next_free;
- dev_ib_data.udav.udav_next_free = idx;
- avu->ud_av.next_free = old_idx;
- }
-
- static int update_cq_cons_idx(struct cq_st *cq)
- {
- struct cq_dbell_st dbell;
- int rc;
-
- memset(&dbell, 0, sizeof dbell);
- INS_FLD(cq->cqn, &dbell, tavorprm_cq_cmd_doorbell_st, cqn);
- INS_FLD(CQ_DBELL_CMD_INC_CONS_IDX, &dbell, tavorprm_cq_cmd_doorbell_st,
- cq_cmd);
- rc = cmd_post_doorbell(&dbell, CQ_DBELL_OFFSET);
- return rc;
- }
-
- static int poll_cq(void *cqh, union cqe_st *cqe_p, u8 * num_cqes)
- {
- union cqe_st cqe;
- int rc;
- u32 *ptr;
- struct cq_st *cq = cqh;
-
- if (cq->cqn < 0x80 || cq->cqn > 0x83) {
- eprintf("");
- return -1;
- }
- ptr = (u32 *) (&(cq->cq_buf[cq->cons_idx]));
- barrier();
- if ((ptr[7] & 0x80000000) == 0) {
- cqe = cq->cq_buf[cq->cons_idx];
- be_to_cpu_buf(&cqe, sizeof(cqe));
- *cqe_p = cqe;
- ptr[7] = 0x80000000;
- barrier();
- cq->cons_idx = (cq->cons_idx + 1) % cq->num_cqes;
- rc = update_cq_cons_idx(cq);
- if (rc) {
- return rc;
- }
- *num_cqes = 1;
- } else
- *num_cqes = 0;
-
- return 0;
- }
-
- static void dev2ib_cqe(struct ib_cqe_st *ib_cqe_p, union cqe_st *cqe_p)
- {
- __u8 opcode;
- __u32 wqe_addr_ba;
-
- opcode =
- EX_FLD(cqe_p->good_cqe, tavorprm_completion_queue_entry_st, opcode);
- if (opcode >= CQE_ERROR_OPCODE)
- ib_cqe_p->is_error = 1;
- else
- ib_cqe_p->is_error = 0;
-
- ib_cqe_p->is_send =
- EX_FLD(cqe_p->good_cqe, tavorprm_completion_queue_entry_st, s);
- wqe_addr_ba =
- EX_FLD(cqe_p->good_cqe, tavorprm_completion_queue_entry_st,
- wqe_adr) << 6;
- ib_cqe_p->wqe = bus_to_virt(wqe_addr_ba);
-
- // if (ib_cqe_p->is_send) {
- // be_to_cpu_buf(ib_cqe_p->wqe, sizeof(struct ud_send_wqe_st));
- // }
- // else {
- // be_to_cpu_buf(ib_cqe_p->wqe, sizeof(struct recv_wqe_st));
- // }
- ib_cqe_p->count =
- EX_FLD(cqe_p->good_cqe, tavorprm_completion_queue_entry_st,
- byte_cnt);
- }
-
- static int ib_poll_cq(void *cqh, struct ib_cqe_st *ib_cqe_p, u8 * num_cqes)
- {
- int rc;
- union cqe_st cqe;
- struct cq_st *cq = cqh;
- __u8 opcode;
-
- rc = poll_cq(cq, &cqe, num_cqes);
- if (rc || ((*num_cqes) == 0)) {
- return rc;
- }
-
- dev2ib_cqe(ib_cqe_p, &cqe);
-
- opcode =
- EX_FLD(cqe.good_cqe, tavorprm_completion_queue_entry_st, opcode);
- if (opcode >= CQE_ERROR_OPCODE) {
- struct ud_send_wqe_st *wqe_p, wqe;
- __u32 *ptr;
- unsigned int i;
-
- wqe_p =
- bus_to_virt(EX_FLD
- (cqe.error_cqe,
- tavorprm_completion_with_error_st,
- wqe_addr) << 6);
- eprintf("syndrome=0x%lx",
- EX_FLD(cqe.error_cqe, tavorprm_completion_with_error_st,
- syndrome));
- eprintf("wqe_addr=0x%lx", wqe_p);
- eprintf("wqe_size=0x%lx",
- EX_FLD(cqe.error_cqe, tavorprm_completion_with_error_st,
- wqe_size));
- eprintf("myqpn=0x%lx",
- EX_FLD(cqe.error_cqe, tavorprm_completion_with_error_st,
- myqpn));
- eprintf("db_cnt=0x%lx",
- EX_FLD(cqe.error_cqe, tavorprm_completion_with_error_st,
- db_cnt));
- memcpy(&wqe, wqe_p, sizeof wqe);
- be_to_cpu_buf(&wqe, sizeof wqe);
-
- eprintf("dumping wqe...");
- ptr = (__u32 *) (&wqe);
- for (i = 0; i < sizeof wqe; i += 4) {
- printf("%lx : ", ptr[i >> 2]);
- }
-
- }
-
- return rc;
- }
-
- /* always work on ipoib qp */
- static int add_qp_to_mcast_group(union ib_gid_u mcast_gid, __u8 add)
- {
- void *mg;
- __u8 *tmp;
- int rc;
- __u16 mgid_hash;
- void *mgmqp_p;
-
- tmp = dev_buffers_p->inprm_buf;
- memcpy(tmp, mcast_gid.raw, 16);
- be_to_cpu_buf(tmp, 16);
- rc = cmd_mgid_hash(tmp, &mgid_hash);
- if (!rc) {
- mg = (void *)dev_buffers_p->inprm_buf;
- memset(mg, 0, MT_STRUCT_SIZE(tavorprm_mgm_entry_st));
- INS_FLD(mcast_gid.as_u32.dw[0], mg, tavorprm_mgm_entry_st, mgid_128_96); // memcpy(&mg->mgid_128_96, &mcast_gid.raw[0], 4);
- INS_FLD(mcast_gid.as_u32.dw[1], mg, tavorprm_mgm_entry_st, mgid_95_64); // memcpy(&mg->mgid_95_64, &mcast_gid.raw[4], 4);
- INS_FLD(mcast_gid.as_u32.dw[2], mg, tavorprm_mgm_entry_st, mgid_63_32); //memcpy(&mg->mgid_63_32, &mcast_gid.raw[8], 4);
- INS_FLD(mcast_gid.as_u32.dw[3], mg, tavorprm_mgm_entry_st, mgid_31_0); //memcpy(&mg->mgid_31_0, &mcast_gid.raw[12], 4);
- be_to_cpu_buf(mg + MT_BYTE_OFFSET(tavorprm_mgm_entry_st, mgid_128_96), 16); //be_to_cpu_buf(&mg->mgid_128_96, 16);
- mgmqp_p = mg + MT_BYTE_OFFSET(tavorprm_mgm_entry_st, mgmqp_0);
- INS_FLD(dev_ib_data.ipoib_qp.qpn, mgmqp_p, tavorprm_mgmqp_st, qpn_i); //mg->mgmqp[0].qpn = dev_ib_data.ipoib_qp.qpn;
- INS_FLD(add, mgmqp_p, tavorprm_mgmqp_st, qi); //mg->mgmqp[0].valid = add ? 1 : 0;
- rc = cmd_write_mgm(mg, mgid_hash);
- }
- return rc;
- }
-
- static int clear_interrupt(void)
- {
- __u32 ecr;
- int ret = 0;
-
- if (gw_read_cr(0x80704, &ecr)) {
- eprintf("");
- } else {
- if (ecr) {
- ret = 1;
- }
- }
- gw_write_cr(0xf00d8, 0x80000000); /* clear int */
- gw_write_cr(0x8070c, 0xffffffff);
-
- return ret;
- }
-
- static struct ud_send_wqe_st *alloc_send_wqe(udqp_t qph)
- {
- struct udqp_st *qp = qph;
- __u8 new_entry;
- struct ud_send_wqe_st *wqe;
-
- if (qp->snd_wqe_cur_free == 0) {
- return NULL;
- }
- new_entry = qp->snd_wqe_alloc_idx;
-
- wqe = &qp->snd_wq[new_entry].wqe;
- qp->snd_wqe_cur_free--;
- qp->snd_wqe_alloc_idx = (qp->snd_wqe_alloc_idx + 1) % qp->max_snd_wqes;
-
- memset(wqe, 0, sizeof *wqe);
-
- wqe->mpointer[0].local_addr_l = virt_to_bus(qp->snd_bufs[new_entry]);
-
- return wqe;
- }
-
- /*
- * alloc_rcv_wqe
- *
- * Note: since we work directly on the work queue, wqes
- * are left in big endian
- */
- static struct recv_wqe_st *alloc_rcv_wqe(struct udqp_st *qp)
- {
- __u8 new_entry;
- struct recv_wqe_st *wqe;
-
- if (qp->recv_wqe_cur_free == 0) {
- return NULL;
- }
-
- new_entry = qp->recv_wqe_alloc_idx;
- wqe = &qp->rcv_wq[new_entry].wqe;
-
- qp->recv_wqe_cur_free--;
- qp->recv_wqe_alloc_idx =
- (qp->recv_wqe_alloc_idx + 1) % qp->max_recv_wqes;
-
- memset(wqe, 0, sizeof *wqe);
-
- /* GRH is always required */
- wqe->mpointer[0].local_addr_h = 0;
- wqe->mpointer[0].local_addr_l = virt_to_bus(qp->rcv_bufs[new_entry]);
- wqe->mpointer[0].lkey = dev_ib_data.mkey;
- wqe->mpointer[0].byte_count = GRH_SIZE;
-
- wqe->mpointer[1].local_addr_h = 0;
- wqe->mpointer[1].local_addr_l =
- virt_to_bus(qp->rcv_bufs[new_entry] + GRH_SIZE);
- wqe->mpointer[1].lkey = dev_ib_data.mkey;
- wqe->mpointer[1].byte_count = qp->rcv_buf_sz;
-
- tprintf("rcv_buf=%lx\n", qp->rcv_bufs[new_entry]);
-
- /* we do it only on the data segment since the control
- segment is always owned by HW */
- cpu_to_be_buf(wqe, sizeof *wqe);
-
- // tprintf("alloc wqe= 0x%x", wqe);
- return wqe;
- }
-
- static int free_send_wqe(struct ud_send_wqe_st *wqe)
- {
- union ud_send_wqe_u *wqe_u;
- struct udqp_st *qp;
-
- wqe_u = (union ud_send_wqe_u *)wqe;
- qp = wqe_u->wqe_cont.qp;
-
- if (qp->snd_wqe_cur_free >= qp->max_snd_wqes) {
- return -1;
- }
-
- qp->snd_wqe_cur_free++;
-
- return 0;
- }
-
- static int free_rcv_wqe(struct recv_wqe_st *wqe)
- {
- union recv_wqe_u *wqe_u;
- struct udqp_st *qp;
-
- wqe_u = (union recv_wqe_u *)wqe;
- qp = wqe_u->wqe_cont.qp;
-
- if (qp->recv_wqe_cur_free >= qp->max_recv_wqes) {
- return -1;
- }
-
- qp->recv_wqe_cur_free++;
-
- return 0;
- }
-
- static int free_wqe(void *wqe)
- {
- int rc = 0;
- struct recv_wqe_st *rcv_wqe;
-
- // tprintf("free wqe= 0x%x", wqe);
- if ((wqe >= (void *)(dev_ib_data.ipoib_qp.rcv_wq)) &&
- (wqe <
- (void *)(&dev_ib_data.ipoib_qp.rcv_wq[NUM_IPOIB_RCV_WQES]))) {
- /* ipoib receive wqe */
- free_rcv_wqe(wqe);
- rcv_wqe = alloc_rcv_wqe(&dev_ib_data.ipoib_qp);
- if (rcv_wqe) {
- rc = post_rcv_buf(&dev_ib_data.ipoib_qp, rcv_wqe);
- if (rc) {
- eprintf("");
- }
- }
- } else if (wqe >= (void *)(dev_ib_data.ipoib_qp.snd_wq) &&
- wqe <
- (void *)(&dev_ib_data.ipoib_qp.snd_wq[NUM_IPOIB_SND_WQES])) {
- /* ipoib send wqe */
- free_send_wqe(wqe);
- } else if (wqe >= (void *)(dev_ib_data.mads_qp.rcv_wq) &&
- wqe <
- (void *)(&dev_ib_data.mads_qp.rcv_wq[NUM_MADS_RCV_WQES])) {
- /* mads receive wqe */
- free_rcv_wqe(wqe);
- rcv_wqe = alloc_rcv_wqe(&dev_ib_data.mads_qp);
- if (rcv_wqe) {
- rc = post_rcv_buf(&dev_ib_data.mads_qp, rcv_wqe);
- if (rc) {
- eprintf("");
- }
- }
- } else if (wqe >= (void *)(dev_ib_data.mads_qp.snd_wq) &&
- wqe <
- (void *)(&dev_ib_data.mads_qp.snd_wq[NUM_MADS_SND_WQES])) {
- /* mads send wqe */
- free_send_wqe(wqe);
- } else {
- rc = -1;
- eprintf("");
- }
-
- return rc;
- }
-
- static int update_eq_cons_idx(struct eq_st *eq)
- {
- struct eq_dbell_st dbell;
- int rc;
-
- memset(&dbell, 0, sizeof dbell);
- INS_FLD(dev_ib_data.eq.eqn, &dbell, tavorprm_eq_cmd_doorbell_st, eqn);
- INS_FLD(EQ_DBELL_CMD_SET_CONS_IDX, &dbell, tavorprm_eq_cmd_doorbell_st,
- eq_cmd);
- INS_FLD(eq->cons_idx, &dbell, tavorprm_eq_cmd_doorbell_st, eq_param);
- rc = cmd_post_doorbell(&dbell, EQ_DBELL_OFFSET);
-
- return rc;
- }
-
- static void dev2ib_eqe(struct ib_eqe_st *ib_eqe_p, void *eqe_p)
- {
- void *tmp;
-
- ib_eqe_p->event_type =
- EX_FLD(eqe_p, tavorprm_event_queue_entry_st, event_type);
-
- tmp = eqe_p + MT_BYTE_OFFSET(tavorprm_event_queue_entry_st, event_data);
- ib_eqe_p->cqn = EX_FLD(tmp, tavorprm_completion_event_st, cqn);
- }
-
- static int poll_eq(struct ib_eqe_st *ib_eqe_p, __u8 * num_eqes)
- {
- struct eqe_t eqe;
- __u8 owner;
- int rc;
- __u32 *ptr;
- struct eq_st *eq = &dev_ib_data.eq;
-
- ptr = (__u32 *) (&(eq->eq_buf[eq->cons_idx]));
- tprintf("cons)idx=%d, addr(eqe)=%x, val=0x%x", eq->cons_idx, virt_to_bus(ptr), ptr[7]);
- owner = (ptr[7] & 0x80000000) ? OWNER_HW : OWNER_SW;
- if (owner == OWNER_SW) {
- tprintf("got eqe");
- eqe = eq->eq_buf[eq->cons_idx];
- be_to_cpu_buf(&eqe, sizeof(eqe));
- dev2ib_eqe(ib_eqe_p, &eqe);
- ptr[7] |= 0x80000000;
- eq->eq_buf[eq->cons_idx] = eqe;
- eq->cons_idx = (eq->cons_idx + 1) % eq->eq_size;
- rc = update_eq_cons_idx(eq);
- if (rc) {
- return -1;
- }
- *num_eqes = 1;
- } else {
- *num_eqes = 0;
- }
- return 0;
- }
-
- static int ib_device_close(void)
- {
- iounmap(tavor_pci_dev.uar);
- iounmap(tavor_pci_dev.cr_space);
- iounmap(dev_ib_data.error_buf_addr);
- return 0;
- }
-
- static __u32 dev_get_qpn(void *qph)
- {
- struct udqp_st *qp = qph;
-
- return qp->qpn;
- }
-
- static void dev_post_dbell(void *dbell, __u32 offset)
- {
- __u32 *ptr;
- unsigned long address;
-
- ptr = dbell;
- tprintf("ptr[0]= 0x%lx", ptr[0]);
- tprintf("ptr[1]= 0x%lx", ptr[1]);
- address = (unsigned long)(tavor_pci_dev.uar) + offset;
- tprintf("va=0x%lx pa=0x%lx", address,
- virt_to_bus((const void *)address));
- writel(htonl(ptr[0]), tavor_pci_dev.uar + offset);
- barrier();
- address += 4;
- tprintf("va=0x%lx pa=0x%lx", address,
- virt_to_bus((const void *)address));
- writel(htonl(ptr[1]), tavor_pci_dev.uar + offset + 4);
- }
-
|