/** * amdgpu_ring_init - init driver ring struct. * * @adev: amdgpu_device pointer * @ring: amdgpu_ring structure holding ring information * @max_ndw: maximum number of dw for ring alloc * @nop: nop packet for this ring * * Initialize the driver information for the selected ring (all asics). * Returns 0 on success, error on failure. */ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, unsigned max_dw, u32 nop, u32 align_mask, struct amdgpu_irq_src *irq_src, unsigned irq_type, enum amdgpu_ring_type ring_type) { int r; if (ring->adev == NULL) { if (adev->num_rings >= AMDGPU_MAX_RINGS) return -EINVAL; ring->adev = adev; ring->idx = adev->num_rings++; adev->rings[ring->idx] = ring; r = amdgpu_fence_driver_init_ring(ring, amdgpu_sched_hw_submission); if (r) return r; } r = amdgpu_wb_get(adev, &ring->rptr_offs); if (r) { dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r); return r; } r = amdgpu_wb_get(adev, &ring->wptr_offs); if (r) { dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r); return r; } r = amdgpu_wb_get(adev, &ring->fence_offs); if (r) { dev_err(adev->dev, "(%d) ring fence_offs wb alloc failed\n", r); return r; } r = amdgpu_wb_get(adev, &ring->cond_exe_offs); if (r) { dev_err(adev->dev, "(%d) ring cond_exec_polling wb alloc failed\n", r); return r; } ring->cond_exe_gpu_addr = adev->wb.gpu_addr + (ring->cond_exe_offs * 4); ring->cond_exe_cpu_addr = &adev->wb.wb[ring->cond_exe_offs]; r = amdgpu_fence_driver_start_ring(ring, irq_src, irq_type); if (r) { dev_err(adev->dev, "failed initializing fences (%d).\n", r); return r; } ring->ring_size = roundup_pow_of_two(max_dw * 4 * amdgpu_sched_hw_submission); ring->align_mask = align_mask; ring->nop = nop; ring->type = ring_type; /* Allocate ring buffer */ if (ring->ring_obj == NULL) { r = amdgpu_bo_create_kernel(adev, ring->ring_size, PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, &ring->ring_obj, &ring->gpu_addr, (void **)&ring->ring); if (r) { dev_err(adev->dev, "(%d) ring create failed\n", r); return r; } memset((void *)ring->ring, 0, ring->ring_size); } ring->ptr_mask = (ring->ring_size / 4) - 1; ring->max_dw = max_dw; if (amdgpu_debugfs_ring_init(adev, ring)) { DRM_ERROR("Failed to register debugfs file for rings !\n"); } return 0; }
static int iwch_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata) { #ifdef notyet struct iwch_cq *chp = to_iwch_cq(cq); struct t3_cq oldcq, newcq; int ret; PDBG("%s ib_cq %p cqe %d\n", __func__, cq, cqe); /* We don't downsize... */ if (cqe <= cq->cqe) return 0; /* create new t3_cq with new size */ cqe = roundup_pow_of_two(cqe+1); newcq.size_log2 = ilog2(cqe); /* Dont allow resize to less than the current wce count */ if (cqe < Q_COUNT(chp->cq.rptr, chp->cq.wptr)) { return -ENOMEM; } /* Quiesce all QPs using this CQ */ ret = iwch_quiesce_qps(chp); if (ret) { return ret; } ret = cxio_create_cq(&chp->rhp->rdev, &newcq); if (ret) { return ret; } /* copy CQEs */ memcpy(newcq.queue, chp->cq.queue, (1 << chp->cq.size_log2) * sizeof(struct t3_cqe)); /* old iwch_qp gets new t3_cq but keeps old cqid */ oldcq = chp->cq; chp->cq = newcq; chp->cq.cqid = oldcq.cqid; /* resize new t3_cq to update the HW context */ ret = cxio_resize_cq(&chp->rhp->rdev, &chp->cq); if (ret) { chp->cq = oldcq; return ret; } chp->ibcq.cqe = (1<<chp->cq.size_log2) - 1; /* destroy old t3_cq */ oldcq.cqid = newcq.cqid; ret = cxio_destroy_cq(&chp->rhp->rdev, &oldcq); if (ret) { printk(KERN_ERR MOD "%s - cxio_destroy_cq failed %d\n", __func__, ret); } /* add user hooks here */ /* resume qps */ ret = iwch_resume_qps(chp); return ret; #else return -ENOSYS; #endif }
static unsigned next_power(unsigned n, unsigned min) { return roundup_pow_of_two(max(n, min)); }
static int __init sh7780_pci_init(void) { struct pci_channel *chan = &sh7780_pci_controller; phys_addr_t memphys; size_t memsize; unsigned int id; const char *type; int ret, i; printk(KERN_NOTICE "PCI: Starting initialization.\n"); chan->reg_base = 0xfe040000; /* Enable CPU access to the PCIC registers. */ __raw_writel(PCIECR_ENBL, PCIECR); /* Reset */ __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST, chan->reg_base + SH4_PCICR); /* * Wait for it to come back up. The spec says to allow for up to * 1 second after toggling the reset pin, but in practice 100ms * is more than enough. */ mdelay(100); id = __raw_readw(chan->reg_base + PCI_VENDOR_ID); if (id != PCI_VENDOR_ID_RENESAS) { printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id); return -ENODEV; } id = __raw_readw(chan->reg_base + PCI_DEVICE_ID); type = (id == PCI_DEVICE_ID_RENESAS_SH7763) ? "SH7763" : (id == PCI_DEVICE_ID_RENESAS_SH7780) ? "SH7780" : (id == PCI_DEVICE_ID_RENESAS_SH7781) ? "SH7781" : (id == PCI_DEVICE_ID_RENESAS_SH7785) ? "SH7785" : NULL; if (unlikely(!type)) { printk(KERN_ERR "PCI: Found an unsupported Renesas host " "controller, device id 0x%04x.\n", id); return -EINVAL; } printk(KERN_NOTICE "PCI: Found a Renesas %s host " "controller, revision %d.\n", type, __raw_readb(chan->reg_base + PCI_REVISION_ID)); /* * Now throw it in to register initialization mode and * start the real work. */ __raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR); memphys = __pa(memory_start); memsize = roundup_pow_of_two(memory_end - memory_start); /* * If there's more than 512MB of memory, we need to roll over to * LAR1/LSR1. */ if (memsize > SZ_512M) { __raw_writel(memphys + SZ_512M, chan->reg_base + SH4_PCILAR1); __raw_writel((((memsize - SZ_512M) - SZ_1M) & 0x1ff00000) | 1, chan->reg_base + SH4_PCILSR1); memsize = SZ_512M; } else { /* * Otherwise just zero it out and disable it. */ __raw_writel(0, chan->reg_base + SH4_PCILAR1); __raw_writel(0, chan->reg_base + SH4_PCILSR1); } /* * LAR0/LSR0 covers up to the first 512MB, which is enough to * cover all of lowmem on most platforms. */ __raw_writel(memphys, chan->reg_base + SH4_PCILAR0); __raw_writel(((memsize - SZ_1M) & 0x1ff00000) | 1, chan->reg_base + SH4_PCILSR0); /* * Hook up the ERR and SERR IRQs. */ ret = sh7780_pci_setup_irqs(chan); if (unlikely(ret)) return ret; /* * Disable the cache snoop controller for non-coherent DMA. */ __raw_writel(0, chan->reg_base + SH7780_PCICSCR0); __raw_writel(0, chan->reg_base + SH7780_PCICSAR0); __raw_writel(0, chan->reg_base + SH7780_PCICSCR1); __raw_writel(0, chan->reg_base + SH7780_PCICSAR1); /* * Setup the memory BARs */ for (i = 1; i < chan->nr_resources; i++) { struct resource *res = chan->resources + i; resource_size_t size; if (unlikely(res->flags & IORESOURCE_IO)) continue; /* * Make sure we're in the right physical addressing mode * for dealing with the resource. */ if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) { chan->nr_resources--; continue; } size = resource_size(res); /* * The MBMR mask is calculated in units of 256kB, which * keeps things pretty simple. */ __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18, chan->reg_base + SH7780_PCIMBMR(i - 1)); __raw_writel(res->start, chan->reg_base + SH7780_PCIMBR(i - 1)); } /* * And I/O. */ __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0); __raw_writel(0, chan->reg_base + SH7780_PCIIOBR); __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR); __raw_writew(PCI_COMMAND_SERR | PCI_COMMAND_WAIT | \ PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | \ PCI_COMMAND_MEMORY, chan->reg_base + PCI_COMMAND); /* * Initialization mode complete, release the control register and * enable round robin mode to stop device overruns/starvation. */ __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO, chan->reg_base + SH4_PCICR); ret = register_pci_controller(chan); if (unlikely(ret)) goto err; sh7780_pci66_init(chan); printk(KERN_NOTICE "PCI: Running at %dMHz.\n", (__raw_readw(chan->reg_base + PCI_STATUS) & PCI_STATUS_66MHZ) ? 66 : 33); return 0; err: sh7780_pci_teardown_irqs(chan); return ret; }
static int rps_sock_flow_sysctl(ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { unsigned int orig_size, size; int ret, i; ctl_table tmp = { .data = &size, .maxlen = sizeof(size), .mode = table->mode }; struct rps_sock_flow_table *orig_sock_table, *sock_table; static DEFINE_MUTEX(sock_flow_mutex); mutex_lock(&sock_flow_mutex); orig_sock_table = rcu_dereference_protected(rps_sock_flow_table, lockdep_is_held(&sock_flow_mutex)); size = orig_size = orig_sock_table ? orig_sock_table->mask + 1 : 0; ret = proc_dointvec(&tmp, write, buffer, lenp, ppos); if (write) { if (size) { if (size > 1<<30) { /* Enforce limit to prevent overflow */ mutex_unlock(&sock_flow_mutex); return -EINVAL; } size = roundup_pow_of_two(size); if (size != orig_size) { sock_table = vmalloc(RPS_SOCK_FLOW_TABLE_SIZE(size)); if (!sock_table) { mutex_unlock(&sock_flow_mutex); return -ENOMEM; } sock_table->mask = size - 1; } else sock_table = orig_sock_table; for (i = 0; i < size; i++) sock_table->ents[i] = RPS_NO_CPU; } else sock_table = NULL; if (sock_table != orig_sock_table) { rcu_assign_pointer(rps_sock_flow_table, sock_table); if (sock_table) static_key_slow_inc(&rps_needed); if (orig_sock_table) { static_key_slow_dec(&rps_needed); synchronize_rcu(); vfree(orig_sock_table); } } } mutex_unlock(&sock_flow_mutex); return ret; } #endif /* CONFIG_RPS */ static struct ctl_table net_core_table[] = { #ifdef CONFIG_NET { .procname = "wmem_max", .data = &sysctl_wmem_max, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec }, { .procname = "rmem_max",
static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) { struct hw_mode_spec *spec = &rt2x00dev->spec; int status; if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags)) return 0; /* * Initialize HW modes. */ status = rt2x00lib_probe_hw_modes(rt2x00dev, spec); if (status) return status; /* * Initialize HW fields. */ rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues; /* * Initialize extra TX headroom required. */ rt2x00dev->hw->extra_tx_headroom = max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM, rt2x00dev->ops->extra_tx_headroom); /* * Take TX headroom required for alignment into account. */ if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags)) rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE; else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; /* * Tell mac80211 about the size of our private STA structure. */ rt2x00dev->hw->sta_data_size = sizeof(struct rt2x00_sta); /* * Allocate tx status FIFO for driver use. */ if (test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags)) { /* * Allocate the txstatus fifo. In the worst case the tx * status fifo has to hold the tx status of all entries * in all tx queues. Hence, calculate the kfifo size as * tx_queues * entry_num and round up to the nearest * power of 2. */ int kfifo_size = roundup_pow_of_two(rt2x00dev->ops->tx_queues * rt2x00dev->ops->tx->entry_num * sizeof(u32)); status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size, GFP_KERNEL); if (status) return status; } /* * Initialize tasklets if used by the driver. Tasklets are * disabled until the interrupts are turned on. The driver * has to handle that. */ #define RT2X00_TASKLET_INIT(taskletname) \ if (rt2x00dev->ops->lib->taskletname) { \ tasklet_init(&rt2x00dev->taskletname, \ rt2x00dev->ops->lib->taskletname, \ (unsigned long)rt2x00dev); \ } RT2X00_TASKLET_INIT(txstatus_tasklet); RT2X00_TASKLET_INIT(pretbtt_tasklet); RT2X00_TASKLET_INIT(tbtt_tasklet); RT2X00_TASKLET_INIT(rxdone_tasklet); RT2X00_TASKLET_INIT(autowake_tasklet); #undef RT2X00_TASKLET_INIT /* * Register HW. */ status = ieee80211_register_hw(rt2x00dev->hw); if (status) return status; set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags); return 0; }
int mt76x2_register_device(struct mt76x2_dev *dev) { struct ieee80211_hw *hw = mt76_hw(dev); struct wiphy *wiphy = hw->wiphy; void *status_fifo; int fifo_size; int i, ret; fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x2_tx_status)); status_fifo = devm_kzalloc(dev->mt76.dev, fifo_size, GFP_KERNEL); if (!status_fifo) return -ENOMEM; kfifo_init(&dev->txstatus_fifo, status_fifo, fifo_size); INIT_DELAYED_WORK(&dev->cal_work, mt76x2_phy_calibrate); INIT_DELAYED_WORK(&dev->mac_work, mt76x2_mac_work); mt76x2_init_device(dev); ret = mt76x2_init_hardware(dev); if (ret) return ret; for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) { u8 *addr = dev->macaddr_list[i].addr; memcpy(addr, dev->mt76.macaddr, ETH_ALEN); if (!i) continue; addr[0] |= BIT(1); addr[0] ^= ((i - 1) << 2); } wiphy->addresses = dev->macaddr_list; wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list); wiphy->iface_combinations = if_comb; wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); wiphy->reg_notifier = mt76x2_regd_notifier; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | #ifdef CONFIG_MAC80211_MESH BIT(NL80211_IFTYPE_MESH_POINT) | #endif BIT(NL80211_IFTYPE_ADHOC); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS); mt76x2_dfs_init_detector(dev); /* init led callbacks */ dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness; dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink; ret = mt76_register_device(&dev->mt76, true, mt76x2_rates, ARRAY_SIZE(mt76x2_rates)); if (ret) goto fail; mt76x2_init_debugfs(dev); mt76x2_init_txpower(dev, &dev->mt76.sband_2g.sband); mt76x2_init_txpower(dev, &dev->mt76.sband_5g.sband); return 0; fail: mt76x2_stop_hardware(dev); return ret; }
static int rps_sock_flow_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { unsigned int orig_size, size; int ret, i; struct ctl_table tmp = { .data = &size, .maxlen = sizeof(size), .mode = table->mode }; struct rps_sock_flow_table *orig_sock_table, *sock_table; static DEFINE_MUTEX(sock_flow_mutex); mutex_lock(&sock_flow_mutex); orig_sock_table = rcu_dereference_protected(rps_sock_flow_table, lockdep_is_held(&sock_flow_mutex)); size = orig_size = orig_sock_table ? orig_sock_table->mask + 1 : 0; ret = proc_dointvec(&tmp, write, buffer, lenp, ppos); if (write) { if (size) { if (size > 1<<29) { /* Enforce limit to prevent overflow */ mutex_unlock(&sock_flow_mutex); return -EINVAL; } size = roundup_pow_of_two(size); if (size != orig_size) { sock_table = vmalloc(RPS_SOCK_FLOW_TABLE_SIZE(size)); if (!sock_table) { mutex_unlock(&sock_flow_mutex); return -ENOMEM; } rps_cpu_mask = roundup_pow_of_two(nr_cpu_ids) - 1; sock_table->mask = size - 1; } else sock_table = orig_sock_table; for (i = 0; i < size; i++) sock_table->ents[i] = RPS_NO_CPU; } else sock_table = NULL; if (sock_table != orig_sock_table) { rcu_assign_pointer(rps_sock_flow_table, sock_table); if (sock_table) { static_key_slow_inc(&rps_needed); static_key_slow_inc(&rfs_needed); } if (orig_sock_table) { static_key_slow_dec(&rps_needed); static_key_slow_dec(&rfs_needed); synchronize_rcu(); vfree(orig_sock_table); } } } mutex_unlock(&sock_flow_mutex); return ret; } #endif /* CONFIG_RPS */ #ifdef CONFIG_NET_FLOW_LIMIT static DEFINE_MUTEX(flow_limit_update_mutex); static int flow_limit_cpu_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { struct sd_flow_limit *cur; struct softnet_data *sd; cpumask_var_t mask; int i, len, ret = 0; if (!alloc_cpumask_var(&mask, GFP_KERNEL)) return -ENOMEM; if (write) { ret = cpumask_parse_user(buffer, *lenp, mask); if (ret) goto done; mutex_lock(&flow_limit_update_mutex); len = sizeof(*cur) + netdev_flow_limit_table_len; for_each_possible_cpu(i) { sd = &per_cpu(softnet_data, i); cur = rcu_dereference_protected(sd->flow_limit, lockdep_is_held(&flow_limit_update_mutex)); if (cur && !cpumask_test_cpu(i, mask)) { RCU_INIT_POINTER(sd->flow_limit, NULL); synchronize_rcu(); kfree(cur); } else if (!cur && cpumask_test_cpu(i, mask)) { cur = kzalloc_node(len, GFP_KERNEL, cpu_to_node(i)); if (!cur) { /* not unwinding previous changes */ ret = -ENOMEM; goto write_unlock; } cur->num_buckets = netdev_flow_limit_table_len; rcu_assign_pointer(sd->flow_limit, cur); } } write_unlock: mutex_unlock(&flow_limit_update_mutex); } else { char kbuf[128]; if (*ppos || !*lenp) { *lenp = 0; goto done; } cpumask_clear(mask); rcu_read_lock(); for_each_possible_cpu(i) { sd = &per_cpu(softnet_data, i); if (rcu_dereference(sd->flow_limit)) cpumask_set_cpu(i, mask); } rcu_read_unlock(); len = min(sizeof(kbuf) - 1, *lenp); len = scnprintf(kbuf, len, "%*pb", cpumask_pr_args(mask)); if (!len) { *lenp = 0; goto done; } if (len < *lenp) kbuf[len++] = '\n'; if (copy_to_user(buffer, kbuf, len)) { ret = -EFAULT; goto done; } *lenp = len; *ppos += len; } done: free_cpumask_var(mask); return ret; }
static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, struct t4_cq *rcq, struct t4_cq *scq, struct c4iw_dev_ucontext *uctx) { int user = (uctx != &rdev->uctx); struct fw_ri_res_wr *res_wr; struct fw_ri_res *res; int wr_len; struct c4iw_wr_wait wr_wait; struct sk_buff *skb; int ret; int eqsize; wq->sq.qid = c4iw_get_qpid(rdev, uctx); if (!wq->sq.qid) return -ENOMEM; wq->rq.qid = c4iw_get_qpid(rdev, uctx); if (!wq->rq.qid) { ret = -ENOMEM; goto free_sq_qid; } if (!user) { wq->sq.sw_sq = kzalloc(wq->sq.size * sizeof *wq->sq.sw_sq, GFP_KERNEL); if (!wq->sq.sw_sq) { ret = -ENOMEM; goto free_rq_qid; } wq->rq.sw_rq = kzalloc(wq->rq.size * sizeof *wq->rq.sw_rq, GFP_KERNEL); if (!wq->rq.sw_rq) { ret = -ENOMEM; goto free_sw_sq; } } /* * RQT must be a power of 2. */ wq->rq.rqt_size = roundup_pow_of_two(wq->rq.size); wq->rq.rqt_hwaddr = c4iw_rqtpool_alloc(rdev, wq->rq.rqt_size); if (!wq->rq.rqt_hwaddr) { ret = -ENOMEM; goto free_sw_rq; } ret = alloc_sq(rdev, &wq->sq, user); if (ret) goto free_hwaddr; memset(wq->sq.queue, 0, wq->sq.memsize); dma_unmap_addr_set(&wq->sq, mapping, wq->sq.dma_addr); wq->rq.queue = dma_alloc_coherent(&(rdev->lldi.pdev->dev), wq->rq.memsize, &(wq->rq.dma_addr), GFP_KERNEL); if (!wq->rq.queue) { ret = -ENOMEM; goto free_sq; } PDBG("%s sq base va 0x%p pa 0x%llx rq base va 0x%p pa 0x%llx\n", __func__, wq->sq.queue, (unsigned long long)virt_to_phys(wq->sq.queue), wq->rq.queue, (unsigned long long)virt_to_phys(wq->rq.queue)); memset(wq->rq.queue, 0, wq->rq.memsize); dma_unmap_addr_set(&wq->rq, mapping, wq->rq.dma_addr); wq->db = rdev->lldi.db_reg; wq->gts = rdev->lldi.gts_reg; if (user) { wq->sq.udb = (u64)pci_resource_start(rdev->lldi.pdev, 2) + (wq->sq.qid << rdev->qpshift); wq->sq.udb &= PAGE_MASK; wq->rq.udb = (u64)pci_resource_start(rdev->lldi.pdev, 2) + (wq->rq.qid << rdev->qpshift); wq->rq.udb &= PAGE_MASK; } wq->rdev = rdev; wq->rq.msn = 1; /* build fw_ri_res_wr */ wr_len = sizeof *res_wr + 2 * sizeof *res; skb = alloc_skb(wr_len, GFP_KERNEL); if (!skb) { ret = -ENOMEM; goto free_dma; } set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0); res_wr = (struct fw_ri_res_wr *)__skb_put(skb, wr_len); memset(res_wr, 0, wr_len); res_wr->op_nres = cpu_to_be32( FW_WR_OP(FW_RI_RES_WR) | V_FW_RI_RES_WR_NRES(2) | FW_WR_COMPL(1)); res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); res_wr->cookie = (unsigned long) &wr_wait; res = res_wr->res; res->u.sqrq.restype = FW_RI_RES_TYPE_SQ; res->u.sqrq.op = FW_RI_RES_OP_WRITE; /* * eqsize is the number of 64B entries plus the status page size. */ eqsize = wq->sq.size * T4_SQ_NUM_SLOTS + T4_EQ_STATUS_ENTRIES; res->u.sqrq.fetchszm_to_iqid = cpu_to_be32( V_FW_RI_RES_WR_HOSTFCMODE(0) | /* no host cidx updates */ V_FW_RI_RES_WR_CPRIO(0) | /* don't keep in chip cache */ V_FW_RI_RES_WR_PCIECHN(0) | /* set by uP at ri_init time */ (t4_sq_onchip(&wq->sq) ? F_FW_RI_RES_WR_ONCHIP : 0) | V_FW_RI_RES_WR_IQID(scq->cqid)); res->u.sqrq.dcaen_to_eqsize = cpu_to_be32( V_FW_RI_RES_WR_DCAEN(0) | V_FW_RI_RES_WR_DCACPU(0) | V_FW_RI_RES_WR_FBMIN(2) | V_FW_RI_RES_WR_FBMAX(2) | V_FW_RI_RES_WR_CIDXFTHRESHO(0) | V_FW_RI_RES_WR_CIDXFTHRESH(0) | V_FW_RI_RES_WR_EQSIZE(eqsize)); res->u.sqrq.eqid = cpu_to_be32(wq->sq.qid); res->u.sqrq.eqaddr = cpu_to_be64(wq->sq.dma_addr); res++; res->u.sqrq.restype = FW_RI_RES_TYPE_RQ; res->u.sqrq.op = FW_RI_RES_OP_WRITE; /* * eqsize is the number of 64B entries plus the status page size. */ eqsize = wq->rq.size * T4_RQ_NUM_SLOTS + T4_EQ_STATUS_ENTRIES; res->u.sqrq.fetchszm_to_iqid = cpu_to_be32( V_FW_RI_RES_WR_HOSTFCMODE(0) | /* no host cidx updates */ V_FW_RI_RES_WR_CPRIO(0) | /* don't keep in chip cache */ V_FW_RI_RES_WR_PCIECHN(0) | /* set by uP at ri_init time */ V_FW_RI_RES_WR_IQID(rcq->cqid)); res->u.sqrq.dcaen_to_eqsize = cpu_to_be32( V_FW_RI_RES_WR_DCAEN(0) | V_FW_RI_RES_WR_DCACPU(0) | V_FW_RI_RES_WR_FBMIN(2) | V_FW_RI_RES_WR_FBMAX(2) | V_FW_RI_RES_WR_CIDXFTHRESHO(0) | V_FW_RI_RES_WR_CIDXFTHRESH(0) | V_FW_RI_RES_WR_EQSIZE(eqsize)); res->u.sqrq.eqid = cpu_to_be32(wq->rq.qid); res->u.sqrq.eqaddr = cpu_to_be64(wq->rq.dma_addr); c4iw_init_wr_wait(&wr_wait); ret = c4iw_ofld_send(rdev, skb); if (ret) goto free_dma; ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, wq->sq.qid, __func__); if (ret) goto free_dma; PDBG("%s sqid 0x%x rqid 0x%x kdb 0x%p squdb 0x%llx rqudb 0x%llx\n", __func__, wq->sq.qid, wq->rq.qid, wq->db, (unsigned long long)wq->sq.udb, (unsigned long long)wq->rq.udb); return 0; free_dma: dma_free_coherent(&(rdev->lldi.pdev->dev), wq->rq.memsize, wq->rq.queue, dma_unmap_addr(&wq->rq, mapping)); free_sq: dealloc_sq(rdev, &wq->sq); free_hwaddr: c4iw_rqtpool_free(rdev, wq->rq.rqt_hwaddr, wq->rq.rqt_size); free_sw_rq: kfree(wq->rq.sw_rq); free_sw_sq: kfree(wq->sq.sw_sq); free_rq_qid: c4iw_put_qpid(rdev, wq->rq.qid, uctx); free_sq_qid: c4iw_put_qpid(rdev, wq->sq.qid, uctx); return ret; }
/** * __ir_input_register() - sets the IR keycode table and add the handlers * for keymap table get/set * @input_dev: the struct input_dev descriptor of the device * @rc_tab: the struct ir_scancode_table table of scancode/keymap * * This routine is used to initialize the input infrastructure * to work with an IR. * It will register the input/evdev interface for the device and * register the syfs code for IR class */ int __ir_input_register(struct input_dev *input_dev, const struct ir_scancode_table *rc_tab, struct ir_dev_props *props, const char *driver_name) { struct ir_input_dev *ir_dev; int rc; if (rc_tab->scan == NULL || !rc_tab->size) return -EINVAL; ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); if (!ir_dev) return -ENOMEM; ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name); if (!ir_dev->driver_name) { rc = -ENOMEM; goto out_dev; } input_dev->getkeycode = ir_getkeycode; input_dev->setkeycode = ir_setkeycode; input_set_drvdata(input_dev, ir_dev); ir_dev->input_dev = input_dev; spin_lock_init(&ir_dev->rc_tab.lock); spin_lock_init(&ir_dev->keylock); setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); ir_dev->rc_tab.name = rc_tab->name; ir_dev->rc_tab.ir_type = rc_tab->ir_type; ir_dev->rc_tab.alloc = roundup_pow_of_two(rc_tab->size * sizeof(struct ir_scancode)); ir_dev->rc_tab.scan = kmalloc(ir_dev->rc_tab.alloc, GFP_KERNEL); ir_dev->rc_tab.size = ir_dev->rc_tab.alloc / sizeof(struct ir_scancode); if (props) { ir_dev->props = props; if (props->open) input_dev->open = ir_open; if (props->close) input_dev->close = ir_close; } if (!ir_dev->rc_tab.scan) { rc = -ENOMEM; goto out_name; } IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", ir_dev->rc_tab.size, ir_dev->rc_tab.alloc); set_bit(EV_KEY, input_dev->evbit); set_bit(EV_REP, input_dev->evbit); set_bit(EV_MSC, input_dev->evbit); set_bit(MSC_SCAN, input_dev->mscbit); if (ir_setkeytable(input_dev, &ir_dev->rc_tab, rc_tab)) { rc = -ENOMEM; goto out_table; } rc = ir_register_class(input_dev); if (rc < 0) goto out_table; if (ir_dev->props) if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { rc = ir_raw_event_register(input_dev); if (rc < 0) goto out_event; } IR_dprintk(1, "Registered input device on %s for %s remote%s.\n", driver_name, rc_tab->name, (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? " in raw mode" : ""); /* * Default delay of 250ms is too short for some protocols, expecially * since the timeout is currently set to 250ms. Increase it to 500ms, * to avoid wrong repetition of the keycodes. */ input_dev->rep[REP_DELAY] = 500; return 0; out_event: ir_unregister_class(input_dev); out_table: kfree(ir_dev->rc_tab.scan); out_name: kfree(ir_dev->driver_name); out_dev: kfree(ir_dev); return rc; }
static struct kmem_cache * __init zfcp_cache_hw_align(const char *name, unsigned long size) { return kmem_cache_create(name, size, roundup_pow_of_two(size), 0, NULL); }
static int choke_change(struct Qdisc *sch, struct nlattr *opt) { struct choke_sched_data *q = qdisc_priv(sch); struct nlattr *tb[TCA_CHOKE_MAX + 1]; const struct tc_red_qopt *ctl; int err; struct sk_buff **old = NULL; unsigned int mask; u32 max_P; if (opt == NULL) return -EINVAL; err = nla_parse_nested(tb, TCA_CHOKE_MAX, opt, choke_policy); if (err < 0) return err; if (tb[TCA_CHOKE_PARMS] == NULL || tb[TCA_CHOKE_STAB] == NULL) return -EINVAL; max_P = tb[TCA_CHOKE_MAX_P] ? nla_get_u32(tb[TCA_CHOKE_MAX_P]) : 0; ctl = nla_data(tb[TCA_CHOKE_PARMS]); if (ctl->limit > CHOKE_MAX_QUEUE) return -EINVAL; mask = roundup_pow_of_two(ctl->limit + 1) - 1; if (mask != q->tab_mask) { struct sk_buff **ntab; ntab = kcalloc(mask + 1, sizeof(struct sk_buff *), GFP_KERNEL | __GFP_NOWARN); if (!ntab) ntab = vzalloc((mask + 1) * sizeof(struct sk_buff *)); if (!ntab) return -ENOMEM; sch_tree_lock(sch); old = q->tab; if (old) { unsigned int oqlen = sch->q.qlen, tail = 0; while (q->head != q->tail) { struct sk_buff *skb = q->tab[q->head]; q->head = (q->head + 1) & q->tab_mask; if (!skb) continue; if (tail < mask) { ntab[tail++] = skb; continue; } qdisc_qstats_backlog_dec(sch, skb); --sch->q.qlen; qdisc_drop(skb, sch); } qdisc_tree_decrease_qlen(sch, oqlen - sch->q.qlen); q->head = 0; q->tail = tail; } q->tab_mask = mask; q->tab = ntab; } else sch_tree_lock(sch); q->flags = ctl->flags; q->limit = ctl->limit; red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog, ctl->Scell_log, nla_data(tb[TCA_CHOKE_STAB]), max_P); red_set_vars(&q->vars); if (q->head == q->tail) red_end_of_idle_period(&q->vars); sch_tree_unlock(sch); choke_free(old); return 0; }
static struct ath10k_ce_ring * ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_ce_ring *src_ring; u32 nentries = attr->src_nentries; dma_addr_t base_addr; nentries = roundup_pow_of_two(nentries); src_ring = kzalloc(sizeof(*src_ring) + (nentries * sizeof(*src_ring->per_transfer_context)), GFP_KERNEL); if (src_ring == NULL) return ERR_PTR(-ENOMEM); src_ring->nentries = nentries; src_ring->nentries_mask = nentries - 1; /* * Legacy platforms that do not support cache * coherent DMA are unsupported */ src_ring->base_addr_owner_space_unaligned = dma_alloc_coherent(ar->dev, (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), &base_addr, GFP_KERNEL); if (!src_ring->base_addr_owner_space_unaligned) { kfree(src_ring); return ERR_PTR(-ENOMEM); } src_ring->base_addr_ce_space_unaligned = base_addr; src_ring->base_addr_owner_space = PTR_ALIGN( src_ring->base_addr_owner_space_unaligned, CE_DESC_RING_ALIGN); src_ring->base_addr_ce_space = ALIGN( src_ring->base_addr_ce_space_unaligned, CE_DESC_RING_ALIGN); /* * Also allocate a shadow src ring in regular * mem to use for faster access. */ src_ring->shadow_base_unaligned = kmalloc((nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), GFP_KERNEL); if (!src_ring->shadow_base_unaligned) { dma_free_coherent(ar->dev, (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), src_ring->base_addr_owner_space, src_ring->base_addr_ce_space); kfree(src_ring); return ERR_PTR(-ENOMEM); } src_ring->shadow_base = PTR_ALIGN( src_ring->shadow_base_unaligned, CE_DESC_RING_ALIGN); return src_ring; }
/** * __ir_input_register() - sets the IR keycode table and add the handlers * for keymap table get/set * @input_dev: the struct input_dev descriptor of the device * @rc_tab: the struct ir_scancode_table table of scancode/keymap * * This routine is used to initialize the input infrastructure * to work with an IR. * It will register the input/evdev interface for the device and * register the syfs code for IR class */ int __ir_input_register(struct input_dev *input_dev, const struct ir_scancode_table *rc_tab, const struct ir_dev_props *props, const char *driver_name) { struct ir_input_dev *ir_dev; int rc; if (rc_tab->scan == NULL || !rc_tab->size) return -EINVAL; ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); if (!ir_dev) return -ENOMEM; ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name); if (!ir_dev->driver_name) { rc = -ENOMEM; goto out_dev; } input_dev->getkeycode = ir_getkeycode; input_dev->setkeycode = ir_setkeycode; input_set_drvdata(input_dev, ir_dev); ir_dev->input_dev = input_dev; spin_lock_init(&ir_dev->rc_tab.lock); spin_lock_init(&ir_dev->keylock); setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); ir_dev->rc_tab.name = rc_tab->name; ir_dev->rc_tab.ir_type = rc_tab->ir_type; ir_dev->rc_tab.alloc = roundup_pow_of_two(rc_tab->size * sizeof(struct ir_scancode)); ir_dev->rc_tab.scan = kmalloc(ir_dev->rc_tab.alloc, GFP_KERNEL); ir_dev->rc_tab.size = ir_dev->rc_tab.alloc / sizeof(struct ir_scancode); if (props) { ir_dev->props = props; if (props->open) input_dev->open = ir_open; if (props->close) input_dev->close = ir_close; } if (!ir_dev->rc_tab.scan) { rc = -ENOMEM; goto out_name; } IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", ir_dev->rc_tab.size, ir_dev->rc_tab.alloc); set_bit(EV_KEY, input_dev->evbit); set_bit(EV_REP, input_dev->evbit); if (ir_setkeytable(input_dev, &ir_dev->rc_tab, rc_tab)) { rc = -ENOMEM; goto out_table; } rc = ir_register_class(input_dev); if (rc < 0) goto out_table; if (ir_dev->props) if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { rc = ir_raw_event_register(input_dev); if (rc < 0) goto out_event; } IR_dprintk(1, "Registered input device on %s for %s remote.\n", driver_name, rc_tab->name); return 0; out_event: ir_unregister_class(input_dev); out_table: kfree(ir_dev->rc_tab.scan); out_name: kfree(ir_dev->driver_name); out_dev: kfree(ir_dev); return rc; }
/* Called from syscall */ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) { u32 value_size = attr->value_size; struct bpf_stack_map *smap; u64 cost, n_buckets; int err; if (!capable(CAP_SYS_ADMIN)) return ERR_PTR(-EPERM); if (attr->map_flags) return ERR_PTR(-EINVAL); /* check sanity of attributes */ if (attr->max_entries == 0 || attr->key_size != 4 || value_size < 8 || value_size % 8 || value_size / 8 > sysctl_perf_event_max_stack) return ERR_PTR(-EINVAL); /* hash table size must be power of 2 */ n_buckets = roundup_pow_of_two(attr->max_entries); cost = n_buckets * sizeof(struct stack_map_bucket *) + sizeof(*smap); if (cost >= U32_MAX - PAGE_SIZE) return ERR_PTR(-E2BIG); smap = kzalloc(cost, GFP_USER | __GFP_NOWARN); if (!smap) { smap = vzalloc(cost); if (!smap) return ERR_PTR(-ENOMEM); } err = -E2BIG; cost += n_buckets * (value_size + sizeof(struct stack_map_bucket)); if (cost >= U32_MAX - PAGE_SIZE) goto free_smap; smap->map.map_type = attr->map_type; smap->map.key_size = attr->key_size; smap->map.value_size = value_size; smap->map.max_entries = attr->max_entries; smap->n_buckets = n_buckets; smap->map.pages = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT; err = bpf_map_precharge_memlock(smap->map.pages); if (err) goto free_smap; err = get_callchain_buffers(); if (err) goto free_smap; err = prealloc_elems_and_freelist(smap); if (err) goto put_buffers; return &smap->map; put_buffers: put_callchain_buffers(); free_smap: kvfree(smap); return ERR_PTR(err); }
int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, u64 *pbl_tbl, int num_pbls, bool block) { struct bnxt_qplib_rcfw *rcfw = res->rcfw; struct cmdq_register_mr req; struct creq_register_mr_resp resp; u16 cmd_flags = 0, level; int pg_ptrs, pages, i, rc; dma_addr_t **pbl_ptr; u32 pg_size; if (num_pbls) { pg_ptrs = roundup_pow_of_two(num_pbls); pages = pg_ptrs >> MAX_PBL_LVL_1_PGS_SHIFT; if (!pages) pages++; if (pages > MAX_PBL_LVL_1_PGS) { dev_err(&res->pdev->dev, "QPLIB: SP: Reg MR pages "); dev_err(&res->pdev->dev, "requested (0x%x) exceeded max (0x%x)", pages, MAX_PBL_LVL_1_PGS); return -ENOMEM; } /* Free the hwq if it already exist, must be a rereg */ if (mr->hwq.max_elements) bnxt_qplib_free_hwq(res->pdev, &mr->hwq); mr->hwq.max_elements = pages; rc = bnxt_qplib_alloc_init_hwq(res->pdev, &mr->hwq, NULL, 0, &mr->hwq.max_elements, PAGE_SIZE, 0, PAGE_SIZE, HWQ_TYPE_CTX); if (rc) { dev_err(&res->pdev->dev, "SP: Reg MR memory allocation failed"); return -ENOMEM; } /* Write to the hwq */ pbl_ptr = (dma_addr_t **)mr->hwq.pbl_ptr; for (i = 0; i < num_pbls; i++) pbl_ptr[PTR_PG(i)][PTR_IDX(i)] = (pbl_tbl[i] & PAGE_MASK) | PTU_PTE_VALID; } RCFW_CMD_PREP(req, REGISTER_MR, cmd_flags); /* Configure the request */ if (mr->hwq.level == PBL_LVL_MAX) { level = 0; req.pbl = 0; pg_size = PAGE_SIZE; } else { level = mr->hwq.level + 1; req.pbl = cpu_to_le64(mr->hwq.pbl[PBL_LVL_0].pg_map_arr[0]); pg_size = mr->hwq.pbl[PBL_LVL_0].pg_size; } req.log2_pg_size_lvl = (level << CMDQ_REGISTER_MR_LVL_SFT) | ((ilog2(pg_size) << CMDQ_REGISTER_MR_LOG2_PG_SIZE_SFT) & CMDQ_REGISTER_MR_LOG2_PG_SIZE_MASK); req.access = (mr->flags & 0xFFFF); req.va = cpu_to_le64(mr->va); req.key = cpu_to_le32(mr->lkey); req.mr_size = cpu_to_le64(mr->total_size); rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp, NULL, block); if (rc) goto fail; return 0; fail: if (mr->hwq.max_elements) bnxt_qplib_free_hwq(res->pdev, &mr->hwq); return rc; }
struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd, struct ib_srq_init_attr *init_attr, struct ib_udata *udata) { struct mlx5_ib_dev *dev = to_mdev(pd->device); struct mlx5_ib_srq *srq; int desc_size; int buf_size; int err; struct mlx5_create_srq_mbox_in *uninitialized_var(in); int uninitialized_var(inlen); int is_xrc; u32 flgs, xrcdn; /* Sanity check SRQ size before proceeding */ if (init_attr->attr.max_wr >= dev->mdev.caps.max_srq_wqes) { mlx5_ib_dbg(dev, "max_wr %d, cap %d\n", init_attr->attr.max_wr, dev->mdev.caps.max_srq_wqes); return ERR_PTR(-EINVAL); } srq = kmalloc(sizeof(*srq), GFP_KERNEL); if (!srq) return ERR_PTR(-ENOMEM); mutex_init(&srq->mutex); spin_lock_init(&srq->lock); srq->msrq.max = roundup_pow_of_two(init_attr->attr.max_wr + 1); srq->msrq.max_gs = init_attr->attr.max_sge; desc_size = sizeof(struct mlx5_wqe_srq_next_seg) + srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg); desc_size = roundup_pow_of_two(desc_size); desc_size = max_t(int, 32, desc_size); srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) / sizeof(struct mlx5_wqe_data_seg); srq->msrq.wqe_shift = ilog2(desc_size); buf_size = srq->msrq.max * desc_size; mlx5_ib_dbg(dev, "desc_size 0x%x, req wr 0x%x, srq size 0x%x, max_gs 0x%x, max_avail_gather 0x%x\n", desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs, srq->msrq.max_avail_gather); if (pd->uobject) err = create_srq_user(pd, srq, &in, udata, buf_size, &inlen); else err = create_srq_kernel(dev, srq, &in, buf_size, &inlen); if (err) { mlx5_ib_warn(dev, "create srq %s failed, err %d\n", pd->uobject ? "user" : "kernel", err); goto err_srq; } is_xrc = (init_attr->srq_type == IB_SRQT_XRC); in->ctx.state_log_sz = ilog2(srq->msrq.max); flgs = ((srq->msrq.wqe_shift - 4) | (is_xrc << 5) | (srq->wq_sig << 7)) << 24; xrcdn = 0; if (is_xrc) { xrcdn = to_mxrcd(init_attr->ext.xrc.xrcd)->xrcdn; in->ctx.pgoff_cqn |= cpu_to_be32(to_mcq(init_attr->ext.xrc.cq)->mcq.cqn); } else if (init_attr->srq_type == IB_SRQT_BASIC) { xrcdn = to_mxrcd(dev->devr.x0)->xrcdn; in->ctx.pgoff_cqn |= cpu_to_be32(to_mcq(dev->devr.c0)->mcq.cqn); } in->ctx.flags_xrcd = cpu_to_be32((flgs & 0xFF000000) | (xrcdn & 0xFFFFFF)); in->ctx.pd = cpu_to_be32(to_mpd(pd)->pdn); in->ctx.db_record = cpu_to_be64(srq->db.dma); err = mlx5_core_create_srq(&dev->mdev, &srq->msrq, in, inlen); mlx5_vfree(in); if (err) { mlx5_ib_dbg(dev, "create SRQ failed, err %d\n", err); goto err_usr_kern_srq; } mlx5_ib_dbg(dev, "create SRQ with srqn 0x%x\n", srq->msrq.srqn); srq->msrq.event = mlx5_ib_srq_event; srq->ibsrq.ext.xrc.srq_num = srq->msrq.srqn; if (pd->uobject) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof(__u32))) { mlx5_ib_dbg(dev, "copy to user failed\n"); err = -EFAULT; goto err_core; } init_attr->attr.max_wr = srq->msrq.max - 1; return &srq->ibsrq; err_core: mlx5_core_destroy_srq(&dev->mdev, &srq->msrq); err_usr_kern_srq: if (pd->uobject) destroy_srq_user(pd, srq); else destroy_srq_kernel(dev, srq); err_srq: kfree(srq); return ERR_PTR(err); }
/* static void mlx4_unmap_uar(struct mlx4_priv *priv) { struct mlx4_priv *priv = mlx4_priv(&priv->dev); int i; for (i = 0; i < mlx4_num_eq_uar(&priv->dev); ++i) if (priv->eq_table.uar_map[i]) { iounmap(priv->eq_table.uar_map[i]); priv->eq_table.uar_map[i] = NULL; } } */ static int mlx4_create_eq(struct mlx4_priv *priv, int nent, u8 intr, struct mlx4_eq *eq) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_eq_context *eq_context; int npages; u64 *dma_list = NULL; genpaddr_t t = 0; u64 mtt_addr; int err = -ENOMEM; int i; eq->priv = priv; eq->nent = roundup_pow_of_two(max(nent, 2)); /* CX3 is capable of extending the CQE\EQE from 32 to 64 bytes*/ npages = PAGE_ALIGN( eq->nent * (MLX4_EQ_ENTRY_SIZE << priv->dev.caps.eqe_factor)) / BASE_PAGE_SIZE; eq->page_list = malloc(npages * sizeof *eq->page_list); if (!eq->page_list) goto err_out; for (i = 0; i < npages; ++i) eq->page_list[i].buf = NULL; dma_list = malloc(npages * sizeof *dma_list); if (!dma_list) goto err_out_free; mailbox = mlx4_alloc_cmd_mailbox(); if (IS_ERR(mailbox)) goto err_out_free; eq_context = mailbox->buf; for (i = 0; i < npages; ++i) { eq->page_list[i].buf = dma_alloc(BASE_PAGE_SIZE, &t); if (!eq->page_list[i].buf) goto err_out_free_pages; dma_list[i] = t; eq->page_list[i].map = t; memset(eq->page_list[i].buf, 0, BASE_PAGE_SIZE); } eq->eqn = mlx4_bitmap_alloc(&priv->eq_table.bitmap); if (eq->eqn == -1) goto err_out_free_pages; eq->doorbell = mlx4_get_eq_uar(priv, eq); if (!eq->doorbell) { err = -ENOMEM; goto err_out_free_eq; } err = mlx4_mtt_init(&priv->dev, npages, PAGE_SHIFT, &eq->mtt); if (err) goto err_out_free_eq; err = mlx4_write_mtt(&priv->dev, &eq->mtt, 0, npages, dma_list); if (err) goto err_out_free_mtt; memset(eq_context, 0, sizeof *eq_context); eq_context->flags = cpu_to_be32(MLX4_EQ_STATUS_OK | MLX4_EQ_STATE_ARMED); eq_context->log_eq_size = ilog2(eq->nent); eq_context->intr = intr; eq_context->log_page_size = PAGE_SHIFT - MLX4_ICM_PAGE_SHIFT; /*printf("mtt_addr: %lx\n", mlx4_mtt_addr(&priv->dev, &eq->mtt)); printf("off: %d\n", eq->mtt.offset); printf("size: %d\n", priv->dev.caps.mtt_entry_sz);*/ mtt_addr = mlx4_mtt_addr(&priv->dev, &eq->mtt); eq_context->mtt_base_addr_h = mtt_addr >> 32; eq_context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff); err = mlx4_SW2HW_EQ(priv, mailbox, eq->eqn); if (err) { MLX4_DEBUG("SW2HW_EQ failed (%d)\n", err); goto err_out_free_mtt; } free(dma_list); mlx4_free_cmd_mailbox(mailbox); eq->cons_index = 0; return err; /*TODO*/ err_out_free_mtt: /*mlx4_mtt_cleanup(&priv->dev, &eq->mtt);*/ err_out_free_eq: /*mlx4_bitmap_free(&priv->eq_table.bitmap, eq->eqn, MLX4_USE_RR);*/ err_out_free_pages: /*for (i = 0; i < npages; ++i) if (eq->page_list[i].buf) dma_free(&priv->dev.pdev->dev, PAGE_SIZE, eq->page_list[i].buf, eq->page_list[i].map);*/ mlx4_free_cmd_mailbox(mailbox); err_out_free: free(eq->page_list); free(dma_list); err_out: return err; }
void* dhd_deferred_work_init(void *dhd_info) { struct dhd_deferred_wq *work = NULL; u8* buf; unsigned long fifo_size = 0; gfp_t flags = CAN_SLEEP()? GFP_KERNEL : GFP_ATOMIC; if (!dhd_info) { DHD_ERROR(("%s: dhd info not initialized\n", __FUNCTION__)); goto return_null; } work = (struct dhd_deferred_wq *)kzalloc(sizeof(struct dhd_deferred_wq), flags); if (!work) { DHD_ERROR(("%s: work queue creation failed \n", __FUNCTION__)); goto return_null; } INIT_WORK((struct work_struct *)work, dhd_deferred_work_handler); /* initialize event fifo */ spin_lock_init(&work->work_lock); /* allocate buffer to hold prio events */ fifo_size = DHD_PRIO_WORK_FIFO_SIZE; fifo_size = is_power_of_2(fifo_size)? fifo_size : roundup_pow_of_two(fifo_size); buf = (u8*)kzalloc(fifo_size, flags); if (!buf) { DHD_ERROR(("%s: prio work fifo allocation failed \n", __FUNCTION__)); goto return_null; } /* Initialize prio event fifo */ work->prio_fifo = dhd_kfifo_init(buf, fifo_size, &work->work_lock); if (!work->prio_fifo) { kfree(buf); goto return_null; } /* allocate buffer to hold work events */ fifo_size = DHD_WORK_FIFO_SIZE; fifo_size = is_power_of_2(fifo_size)? fifo_size : roundup_pow_of_two(fifo_size); buf = (u8*)kzalloc(fifo_size, flags); if (!buf) { DHD_ERROR(("%s: work fifo allocation failed \n", __FUNCTION__)); goto return_null; } /* Initialize event fifo */ work->work_fifo = dhd_kfifo_init(buf, fifo_size, &work->work_lock); if (!work->work_fifo) { kfree(buf); goto return_null; } work->dhd_info = dhd_info; DHD_ERROR(("%s: work queue initialized \n", __FUNCTION__)); return work; return_null: if (work) dhd_deferred_work_deinit(work); return NULL; }
/* Called from syscall */ static struct bpf_map *bloom_map_alloc(union bpf_attr *attr) { printk("* In function %s *\n", __FUNCTION__); return ERR_PTR(-ENOMEM); #if 0 struct bpf_bloom *bloom; int err, i; bloom = kzalloc(sizeof(*bloom), GFP_USER); if (!bloom) return ERR_PTR(-ENOMEM); /* mandatory map attributes */ bloom->map.key_size = attr->key_size; bloom->map.value_size = attr->value_size; bloom->map.max_entries = attr->max_entries; /* check sanity of attributes. * value_size == 0 may be allowed in the future to use map as a set */ err = -EINVAL; if (bloom->map.max_entries == 0 || bloom->map.key_size == 0 || bloom->map.value_size == 0) goto free_bloom; /* hash table size must be power of 2 */ bloom->n_buckets = roundup_pow_of_two(bloom->map.max_entries); err = -E2BIG; if (bloom->map.key_size > MAX_BPF_STACK) /* eBPF programs initialize keys on stack, so they cannot be * larger than max stack size */ goto free_bloom; err = -ENOMEM; /* prevent zero size kmalloc and check for u32 overflow */ if (bloom->n_buckets == 0 || bloom->n_buckets > U32_MAX / sizeof(struct hlist_head)) goto free_bloom; bloom->buckets = kmalloc_array(bloom->n_buckets, sizeof(struct hlist_head), GFP_USER | __GFP_NOWARN); if (!bloom->buckets) { bloom->buckets = vmalloc(bloom->n_buckets * sizeof(struct hlist_head)); if (!bloom->buckets) goto free_bloom; } for (i = 0; i < bloom->n_buckets; i++) INIT_HLIST_HEAD(&bloom->buckets[i]); spin_lock_init(&bloom->lock); bloom->count = 0; bloom->elem_size = sizeof(struct bloom_elem) + round_up(bloom->map.key_size, 8) + bloom->map.value_size; return &bloom->map; free_bloom: kfree(bloom); return ERR_PTR(err); #endif }
int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) { struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_wqe_srq_next_seg *next; struct mlx4_en_rx_ring *ring; int i; int ring_ind; int err; int stride = roundup_pow_of_two(sizeof(struct mlx4_en_rx_desc) + DS_SIZE * priv->num_frags); int max_gs = (stride - sizeof(struct mlx4_wqe_srq_next_seg)) / DS_SIZE; for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) { ring = &priv->rx_ring[ring_ind]; ring->prod = 0; ring->cons = 0; ring->actual_size = 0; ring->cqn = priv->rx_cq[ring_ind].mcq.cqn; ring->stride = stride; ring->log_stride = ffs(ring->stride) - 1; ring->buf_size = ring->size * ring->stride; memset(ring->rx_info, 0, sizeof(*(ring->rx_info))); memset(ring->buf, 0, ring->buf_size); mlx4_en_update_rx_prod_db(ring); /* Initailize all descriptors */ for (i = 0; i < ring->size; i++) mlx4_en_init_rx_desc(priv, ring, i); /* Initialize page allocators */ err = mlx4_en_init_allocator(priv, ring); if (err) { mlx4_err(mdev, "Failed initializing ring allocator\n"); goto err_allocator; } /* Fill Rx buffers */ ring->full = 0; } if (mlx4_en_fill_rx_buffers(priv)) goto err_buffers; for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) { ring = &priv->rx_ring[ring_ind]; mlx4_en_update_rx_prod_db(ring); /* Configure SRQ representing the ring */ ring->srq.max = ring->size; ring->srq.max_gs = max_gs; ring->srq.wqe_shift = ilog2(ring->stride); for (i = 0; i < ring->srq.max; ++i) { next = get_wqe(ring, i); next->next_wqe_index = cpu_to_be16((i + 1) & (ring->srq.max - 1)); } err = mlx4_srq_alloc(mdev->dev, mdev->priv_pdn, &ring->wqres.mtt, ring->wqres.db.dma, &ring->srq); if (err){ mlx4_err(mdev, "Failed to allocate srq\n"); goto err_srq; } ring->srq.event = mlx4_en_srq_event; } return 0; err_srq: while (ring_ind >= 0) { ring = &priv->rx_ring[ring_ind]; mlx4_srq_free(mdev->dev, &ring->srq); ring_ind--; } err_buffers: for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) mlx4_en_free_rx_buf(priv, &priv->rx_ring[ring_ind]); ring_ind = priv->rx_ring_num - 1; err_allocator: while (ring_ind >= 0) { mlx4_en_destroy_allocator(priv, &priv->rx_ring[ring_ind]); ring_ind--; } return err; }
static struct ib_cq *iwch_create_cq(struct ib_device *ibdev, int entries, int vector, struct ib_ucontext *ib_context, struct ib_udata *udata) { struct iwch_dev *rhp; struct iwch_cq *chp; struct iwch_create_cq_resp uresp; struct iwch_create_cq_req ureq; struct iwch_ucontext *ucontext = NULL; static int warned; size_t resplen; PDBG("%s ib_dev %p entries %d\n", __func__, ibdev, entries); rhp = to_iwch_dev(ibdev); chp = kzalloc(sizeof(*chp), GFP_KERNEL); if (!chp) return ERR_PTR(-ENOMEM); if (ib_context) { ucontext = to_iwch_ucontext(ib_context); if (!t3a_device(rhp)) { if (ib_copy_from_udata(&ureq, udata, sizeof (ureq))) { kfree(chp); return ERR_PTR(-EFAULT); } chp->user_rptr_addr = (u32 __user *)(unsigned long)ureq.user_rptr_addr; } } if (t3a_device(rhp)) { /* * T3A: Add some fluff to handle extra CQEs inserted * for various errors. * Additional CQE possibilities: * TERMINATE, * incoming RDMA WRITE Failures * incoming RDMA READ REQUEST FAILUREs * NOTE: We cannot ensure the CQ won't overflow. */ entries += 16; } entries = roundup_pow_of_two(entries); chp->cq.size_log2 = ilog2(entries); if (cxio_create_cq(&rhp->rdev, &chp->cq, !ucontext)) { kfree(chp); return ERR_PTR(-ENOMEM); } chp->rhp = rhp; chp->ibcq.cqe = 1 << chp->cq.size_log2; spin_lock_init(&chp->lock); spin_lock_init(&chp->comp_handler_lock); atomic_set(&chp->refcnt, 1); init_waitqueue_head(&chp->wait); if (insert_handle(rhp, &rhp->cqidr, chp, chp->cq.cqid)) { cxio_destroy_cq(&chp->rhp->rdev, &chp->cq); kfree(chp); return ERR_PTR(-ENOMEM); } if (ucontext) { struct iwch_mm_entry *mm; mm = kmalloc(sizeof *mm, GFP_KERNEL); if (!mm) { iwch_destroy_cq(&chp->ibcq); return ERR_PTR(-ENOMEM); } uresp.cqid = chp->cq.cqid; uresp.size_log2 = chp->cq.size_log2; spin_lock(&ucontext->mmap_lock); uresp.key = ucontext->key; ucontext->key += PAGE_SIZE; spin_unlock(&ucontext->mmap_lock); mm->key = uresp.key; mm->addr = virt_to_phys(chp->cq.queue); if (udata->outlen < sizeof uresp) { if (!warned++) printk(KERN_WARNING MOD "Warning - " "downlevel libcxgb3 (non-fatal).\n"); mm->len = PAGE_ALIGN((1UL << uresp.size_log2) * sizeof(struct t3_cqe)); resplen = sizeof(struct iwch_create_cq_resp_v0); } else { mm->len = PAGE_ALIGN(((1UL << uresp.size_log2) + 1) * sizeof(struct t3_cqe)); uresp.memsize = mm->len; resplen = sizeof uresp; } if (ib_copy_to_udata(udata, &uresp, resplen)) { kfree(mm); iwch_destroy_cq(&chp->ibcq); return ERR_PTR(-EFAULT); } insert_mmap(ucontext, mm); } PDBG("created cqid 0x%0x chp %p size 0x%0x, dma_addr 0x%0llx\n", chp->cq.cqid, chp, (1 << chp->cq.size_log2), (unsigned long long) chp->cq.dma_addr); return &chp->ibcq; }
struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, struct ib_srq_init_attr *init_attr, struct ib_udata *udata) { struct mlx4_ib_dev *dev = to_mdev(pd->device); struct mlx4_ib_srq *srq; struct mlx4_wqe_srq_next_seg *next; struct mlx4_wqe_data_seg *scatter; u32 cqn; u16 xrcdn; int desc_size; int buf_size; int err; int i; /* Sanity check SRQ size before proceeding */ if (init_attr->attr.max_wr >= dev->dev->caps.max_srq_wqes || init_attr->attr.max_sge > dev->dev->caps.max_srq_sge) return ERR_PTR(-EINVAL); srq = kmalloc(sizeof *srq, GFP_KERNEL); if (!srq) return ERR_PTR(-ENOMEM); mutex_init(&srq->mutex); spin_lock_init(&srq->lock); srq->msrq.max = roundup_pow_of_two(init_attr->attr.max_wr + 1); srq->msrq.max_gs = init_attr->attr.max_sge; desc_size = max(32UL, roundup_pow_of_two(sizeof (struct mlx4_wqe_srq_next_seg) + srq->msrq.max_gs * sizeof (struct mlx4_wqe_data_seg))); srq->msrq.wqe_shift = ilog2(desc_size); buf_size = srq->msrq.max * desc_size; if (pd->uobject) { struct mlx4_ib_create_srq ucmd; if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) { err = -EFAULT; goto err_srq; } srq->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr, buf_size, 0, 0); if (IS_ERR(srq->umem)) { err = PTR_ERR(srq->umem); goto err_srq; } err = mlx4_mtt_init(dev->dev, ib_umem_page_count(srq->umem), ilog2(srq->umem->page_size), &srq->mtt); if (err) goto err_buf; err = mlx4_ib_umem_write_mtt(dev, &srq->mtt, srq->umem); if (err) goto err_mtt; err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context), ucmd.db_addr, &srq->db); if (err) goto err_mtt; } else { err = mlx4_db_alloc(dev->dev, &srq->db, 0); if (err) goto err_srq; *srq->db.db = 0; if (mlx4_buf_alloc(dev->dev, buf_size, PAGE_SIZE * 2, &srq->buf)) { err = -ENOMEM; goto err_db; } srq->head = 0; srq->tail = srq->msrq.max - 1; srq->wqe_ctr = 0; for (i = 0; i < srq->msrq.max; ++i) { next = get_wqe(srq, i); next->next_wqe_index = cpu_to_be16((i + 1) & (srq->msrq.max - 1)); for (scatter = (void *) (next + 1); (void *) scatter < (void *) next + desc_size; ++scatter) scatter->lkey = cpu_to_be32(MLX4_INVALID_LKEY); } err = mlx4_mtt_init(dev->dev, srq->buf.npages, srq->buf.page_shift, &srq->mtt); if (err) goto err_buf; err = mlx4_buf_write_mtt(dev->dev, &srq->mtt, &srq->buf); if (err) goto err_mtt; srq->wrid = kmalloc(srq->msrq.max * sizeof (u64), GFP_KERNEL); if (!srq->wrid) { err = -ENOMEM; goto err_mtt; } } cqn = (init_attr->srq_type == IB_SRQT_XRC) ? to_mcq(init_attr->ext.xrc.cq)->mcq.cqn : 0; xrcdn = (init_attr->srq_type == IB_SRQT_XRC) ? to_mxrcd(init_attr->ext.xrc.xrcd)->xrcdn : (u16) dev->dev->caps.reserved_xrcds; err = mlx4_srq_alloc(dev->dev, to_mpd(pd)->pdn, cqn, xrcdn, &srq->mtt, srq->db.dma, &srq->msrq); if (err) goto err_wrid; srq->msrq.event = mlx4_ib_srq_event; srq->ibsrq.ext.xrc.srq_num = srq->msrq.srqn; if (pd->uobject) if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof (__u32))) { err = -EFAULT; goto err_wrid; } init_attr->attr.max_wr = srq->msrq.max - 1; return &srq->ibsrq; err_wrid: if (pd->uobject) mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &srq->db); else kfree(srq->wrid); err_mtt: mlx4_mtt_cleanup(dev->dev, &srq->mtt); err_buf: if (pd->uobject) ib_umem_release(srq->umem); else mlx4_buf_free(dev->dev, buf_size, &srq->buf); err_db: if (!pd->uobject) mlx4_db_free(dev->dev, &srq->db); err_srq: kfree(srq); return ERR_PTR(err); }
static void usdhi6_clk_set(struct usdhi6_host *host, struct mmc_ios *ios) { unsigned long rate = ios->clock; u32 val; unsigned int i; for (i = 1000; i; i--) { if (usdhi6_read(host, USDHI6_SD_INFO2) & USDHI6_SD_INFO2_SCLKDIVEN) break; usleep_range(10, 100); } if (!i) { dev_err(mmc_dev(host->mmc), "SD bus busy, clock set aborted\n"); return; } val = usdhi6_read(host, USDHI6_SD_CLK_CTRL) & ~USDHI6_SD_CLK_CTRL_DIV_MASK; if (rate) { unsigned long new_rate; if (host->imclk <= rate) { if (ios->timing != MMC_TIMING_UHS_DDR50) { /* Cannot have 1-to-1 clock in DDR mode */ new_rate = host->imclk; val |= 0xff; } else { new_rate = host->imclk / 2; } } else { unsigned long div = roundup_pow_of_two(DIV_ROUND_UP(host->imclk, rate)); val |= div >> 2; new_rate = host->imclk / div; } if (host->rate == new_rate) return; host->rate = new_rate; dev_dbg(mmc_dev(host->mmc), "target %lu, div %u, set %lu\n", rate, (val & 0xff) << 2, new_rate); } /* * if old or new rate is equal to input rate, have to switch the clock * off before changing and on after */ if (host->imclk == rate || host->imclk == host->rate || !rate) usdhi6_write(host, USDHI6_SD_CLK_CTRL, val & ~USDHI6_SD_CLK_CTRL_SCLKEN); if (!rate) { host->rate = 0; return; } usdhi6_write(host, USDHI6_SD_CLK_CTRL, val); if (host->imclk == rate || host->imclk == host->rate || !(val & USDHI6_SD_CLK_CTRL_SCLKEN)) usdhi6_write(host, USDHI6_SD_CLK_CTRL, val | USDHI6_SD_CLK_CTRL_SCLKEN); }