/** * init_qpn_table - initialize the QP number table for a device * @qpt: the QPN table */ static int init_qpn_table(struct hfi1_devdata *dd, struct hfi1_qpn_table *qpt) { u32 offset, qpn, i; struct qpn_map *map; int ret = 0; spin_lock_init(&qpt->lock); qpt->last = 0; qpt->incr = 1 << dd->qos_shift; /* insure we don't assign QPs from KDETH 64K window */ qpn = kdeth_qp << 16; qpt->nmaps = qpn / BITS_PER_PAGE; /* This should always be zero */ offset = qpn & BITS_PER_PAGE_MASK; map = &qpt->map[qpt->nmaps]; dd_dev_info(dd, "Reserving QPNs for KDETH window from 0x%x to 0x%x\n", qpn, qpn + 65535); for (i = 0; i < 65536; i++) { if (!map->page) { get_map_page(qpt, map); if (!map->page) { ret = -ENOMEM; break; } } set_bit(offset, map->page); offset++; if (offset == BITS_PER_PAGE) { /* next page */ qpt->nmaps++; map++; offset = 0; } } return ret; }
int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, struct kobject *kobj) { struct hfi1_pportdata *ppd; struct hfi1_devdata *dd = dd_from_ibdev(ibdev); int ret; if (!port_num || port_num > dd->num_pports) { dd_dev_err(dd, "Skipping infiniband class with invalid port %u\n", port_num); return -ENODEV; } ppd = &dd->pport[port_num - 1]; ret = kobject_init_and_add(&ppd->sc2vl_kobj, &hfi1_sc2vl_ktype, kobj, "sc2vl"); if (ret) { dd_dev_err(dd, "Skipping sc2vl sysfs info, (err %d) port %u\n", ret, port_num); goto bail; } kobject_uevent(&ppd->sc2vl_kobj, KOBJ_ADD); ret = kobject_init_and_add(&ppd->sl2sc_kobj, &hfi1_sl2sc_ktype, kobj, "sl2sc"); if (ret) { dd_dev_err(dd, "Skipping sl2sc sysfs info, (err %d) port %u\n", ret, port_num); goto bail_sc2vl; } kobject_uevent(&ppd->sl2sc_kobj, KOBJ_ADD); ret = kobject_init_and_add(&ppd->vl2mtu_kobj, &hfi1_vl2mtu_ktype, kobj, "vl2mtu"); if (ret) { dd_dev_err(dd, "Skipping vl2mtu sysfs info, (err %d) port %u\n", ret, port_num); goto bail_sl2sc; } kobject_uevent(&ppd->vl2mtu_kobj, KOBJ_ADD); ret = kobject_init_and_add(&ppd->pport_cc_kobj, &port_cc_ktype, kobj, "CCMgtA"); if (ret) { dd_dev_err(dd, "Skipping Congestion Control sysfs info, (err %d) port %u\n", ret, port_num); goto bail_vl2mtu; } kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); if (ret) { dd_dev_err(dd, "Skipping Congestion Control setting sysfs info, (err %d) port %u\n", ret, port_num); goto bail_cc; } ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_table_bin_attr); if (ret) { dd_dev_err(dd, "Skipping Congestion Control table sysfs info, (err %d) port %u\n", ret, port_num); goto bail_cc_entry_bin; } dd_dev_info(dd, "Congestion Control Agent enabled for port %d\n", port_num); return 0; bail_cc_entry_bin: sysfs_remove_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); bail_cc: kobject_put(&ppd->pport_cc_kobj); bail_vl2mtu: kobject_put(&ppd->vl2mtu_kobj); bail_sl2sc: kobject_put(&ppd->sl2sc_kobj); bail_sc2vl: kobject_put(&ppd->sc2vl_kobj); bail: return ret; }