int ehca_query_gid(struct ib_device *ibdev, u8 port, int index, union ib_gid *gid) { int ret = 0; u64 h_ret; struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device); struct hipz_query_port *rblock; if (index < 0 || index > 255) { ehca_err(&shca->ib_device, "Invalid index: %x.", index); return -EINVAL; } rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; } h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock); if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "Can't query port properties"); ret = -EINVAL; goto query_gid1; } memcpy(&gid->raw[0], &rblock->gid_prefix, sizeof(u64)); memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64)); query_gid1: ehca_free_fw_ctrlblock(rblock); return ret; }
int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) { int ret = 0; u64 h_ret; struct ehca_shca *shca; struct hipz_query_port *rblock; shca = container_of(ibdev, struct ehca_shca, ib_device); if (index > 16) { ehca_err(&shca->ib_device, "Invalid index: %x.", index); return -EINVAL; } rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; } h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock); if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "Can't query port properties"); ret = -EINVAL; goto query_pkey1; } memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16)); query_pkey1: ehca_free_fw_ctrlblock(rblock); return ret; }
int ehca_query_sma_attr(struct ehca_shca *shca, u8 port, struct ehca_sma_attr *attr) { int ret = 0; u64 h_ret; struct hipz_query_port *rblock; rblock = ehca_alloc_fw_ctrlblock(GFP_ATOMIC); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; } h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock); if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "Can't query port properties"); ret = -EINVAL; goto query_sma_attr1; } memset(attr, 0, sizeof(struct ehca_sma_attr)); attr->lid = rblock->lid; attr->lmc = rblock->lmc; attr->sm_sl = rblock->sm_sl; attr->sm_lid = rblock->sm_lid; attr->pkey_tbl_len = rblock->pkey_tbl_len; memcpy(attr->pkeys, rblock->pkey_entries, sizeof(attr->pkeys)); query_sma_attr1: ehca_free_fw_ctrlblock(rblock); return ret; }
int ehca_modify_port(struct ib_device *ibdev, u8 port, int port_modify_mask, struct ib_port_modify *props) { int ret = 0; struct ehca_shca *shca; struct hipz_query_port *rblock; u32 cap; u64 hret; shca = container_of(ibdev, struct ehca_shca, ib_device); if ((props->set_port_cap_mask | props->clr_port_cap_mask) & ~allowed_port_caps) { ehca_err(&shca->ib_device, "Non-changeable bits set in masks " "set=%x clr=%x allowed=%x", props->set_port_cap_mask, props->clr_port_cap_mask, allowed_port_caps); return -EINVAL; } if (mutex_lock_interruptible(&shca->modify_mutex)) return -ERESTARTSYS; rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); ret = -ENOMEM; goto modify_port1; } hret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock); if (hret != H_SUCCESS) { ehca_err(&shca->ib_device, "Can't query port properties"); ret = -EINVAL; goto modify_port2; } cap = (rblock->capability_mask | props->set_port_cap_mask) & ~props->clr_port_cap_mask; hret = hipz_h_modify_port(shca->ipz_hca_handle, port, cap, props->init_type, port_modify_mask); if (hret != H_SUCCESS) { ehca_err(&shca->ib_device, "Modify port failed h_ret=%lli", hret); ret = -EINVAL; } modify_port2: ehca_free_fw_ctrlblock(rblock); modify_port1: mutex_unlock(&shca->modify_mutex); return ret; }
int ehca_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *props) { int ret = 0; u64 h_ret; struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device); struct hipz_query_port *rblock; rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; } h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock); if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "Can't query port properties"); ret = -EINVAL; goto query_port1; } memset(props, 0, sizeof(struct ib_port_attr)); props->active_mtu = props->max_mtu = map_mtu(shca, rblock->max_mtu); props->port_cap_flags = rblock->capability_mask; props->gid_tbl_len = rblock->gid_tbl_len; if (rblock->max_msg_sz) props->max_msg_sz = rblock->max_msg_sz; else props->max_msg_sz = 0x1 << 31; props->bad_pkey_cntr = rblock->bad_pkey_cntr; props->qkey_viol_cntr = rblock->qkey_viol_cntr; props->pkey_tbl_len = rblock->pkey_tbl_len; props->lid = rblock->lid; props->sm_lid = rblock->sm_lid; props->lmc = rblock->lmc; props->sm_sl = rblock->sm_sl; props->subnet_timeout = rblock->subnet_timeout; props->init_type_reply = rblock->init_type_reply; props->max_vl_num = map_number_of_vls(shca, rblock->vl_cap); if (rblock->state && rblock->phys_width) { props->phys_state = rblock->phys_pstate; props->state = rblock->phys_state; props->active_width = rblock->phys_width; props->active_speed = rblock->phys_speed; } else { /* old firmware releases don't report physical * port info, so use default values */ props->phys_state = 5; props->state = rblock->state; props->active_width = IB_WIDTH_12X; props->active_speed = IB_SPEED_SDR; } query_port1: ehca_free_fw_ctrlblock(rblock); return ret; }
int ehca_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *props) { int ret = 0; u64 h_ret; struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device); struct hipz_query_port *rblock; rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; } h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock); if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "Can't query port properties"); ret = -EINVAL; goto query_port1; } memset(props, 0, sizeof(struct ib_port_attr)); props->state = rblock->state; switch (rblock->max_mtu) { case 0x1: props->active_mtu = props->max_mtu = IB_MTU_256; break; case 0x2: props->active_mtu = props->max_mtu = IB_MTU_512; break; case 0x3: props->active_mtu = props->max_mtu = IB_MTU_1024; break; case 0x4: props->active_mtu = props->max_mtu = IB_MTU_2048; break; case 0x5: props->active_mtu = props->max_mtu = IB_MTU_4096; break; default: ehca_err(&shca->ib_device, "Unknown MTU size: %x.", rblock->max_mtu); break; } props->port_cap_flags = rblock->capability_mask; props->gid_tbl_len = rblock->gid_tbl_len; props->max_msg_sz = rblock->max_msg_sz; props->bad_pkey_cntr = rblock->bad_pkey_cntr; props->qkey_viol_cntr = rblock->qkey_viol_cntr; props->pkey_tbl_len = rblock->pkey_tbl_len; props->lid = rblock->lid; props->sm_lid = rblock->sm_lid; props->lmc = rblock->lmc; props->sm_sl = rblock->sm_sl; props->subnet_timeout = rblock->subnet_timeout; props->init_type_reply = rblock->init_type_reply; props->active_width = IB_WIDTH_12X; props->active_speed = 0x1; /* at the moment (logical) link state is always LINK_UP */ props->phys_state = 0x5; query_port1: ehca_free_fw_ctrlblock(rblock); return ret; }