1 /* 2 * Copyright (c) 2016 Hisilicon Limited. 3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the 9 * OpenIB.org BSD license below: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * - Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 */ 33 34 #include <linux/platform_device.h> 35 #include "hns_roce_device.h" 36 37 int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj) 38 { 39 int ret = 0; 40 41 spin_lock(&bitmap->lock); 42 *obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last); 43 if (*obj >= bitmap->max) { 44 bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) 45 & bitmap->mask; 46 *obj = find_first_zero_bit(bitmap->table, bitmap->max); 47 } 48 49 if (*obj < bitmap->max) { 50 set_bit(*obj, bitmap->table); 51 bitmap->last = (*obj + 1); 52 if (bitmap->last == bitmap->max) 53 bitmap->last = 0; 54 *obj |= bitmap->top; 55 } else { 56 ret = -1; 57 } 58 59 spin_unlock(&bitmap->lock); 60 61 return ret; 62 } 63 64 void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj, 65 int rr) 66 { 67 hns_roce_bitmap_free_range(bitmap, obj, 1, rr); 68 } 69 70 int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap *bitmap, int cnt, 71 int align, unsigned long *obj) 72 { 73 int ret = 0; 74 int i; 75 76 if (likely(cnt == 1 && align == 1)) 77 return hns_roce_bitmap_alloc(bitmap, obj); 78 79 spin_lock(&bitmap->lock); 80 81 *obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max, 82 bitmap->last, cnt, align - 1); 83 if (*obj >= bitmap->max) { 84 bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) 85 & bitmap->mask; 86 *obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max, 0, 87 cnt, align - 1); 88 } 89 90 if (*obj < bitmap->max) { 91 for (i = 0; i < cnt; i++) 92 set_bit(*obj + i, bitmap->table); 93 94 if (*obj == bitmap->last) { 95 bitmap->last = (*obj + cnt); 96 if (bitmap->last >= bitmap->max) 97 bitmap->last = 0; 98 } 99 *obj |= bitmap->top; 100 } else { 101 ret = -1; 102 } 103 104 spin_unlock(&bitmap->lock); 105 106 return ret; 107 } 108 109 void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap, 110 unsigned long obj, int cnt, 111 int rr) 112 { 113 int i; 114 115 obj &= bitmap->max + bitmap->reserved_top - 1; 116 117 spin_lock(&bitmap->lock); 118 for (i = 0; i < cnt; i++) 119 clear_bit(obj + i, bitmap->table); 120 121 if (!rr) 122 bitmap->last = min(bitmap->last, obj); 123 bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) 124 & bitmap->mask; 125 spin_unlock(&bitmap->lock); 126 } 127 128 int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask, 129 u32 reserved_bot, u32 reserved_top) 130 { 131 u32 i; 132 133 if (num != roundup_pow_of_two(num)) 134 return -EINVAL; 135 136 bitmap->last = 0; 137 bitmap->top = 0; 138 bitmap->max = num - reserved_top; 139 bitmap->mask = mask; 140 bitmap->reserved_top = reserved_top; 141 spin_lock_init(&bitmap->lock); 142 bitmap->table = kcalloc(BITS_TO_LONGS(bitmap->max), sizeof(long), 143 GFP_KERNEL); 144 if (!bitmap->table) 145 return -ENOMEM; 146 147 for (i = 0; i < reserved_bot; ++i) 148 set_bit(i, bitmap->table); 149 150 return 0; 151 } 152 153 void hns_roce_bitmap_cleanup(struct hns_roce_bitmap *bitmap) 154 { 155 kfree(bitmap->table); 156 } 157 158 void hns_roce_buf_free(struct hns_roce_dev *hr_dev, u32 size, 159 struct hns_roce_buf *buf) 160 { 161 int i; 162 struct device *dev = &hr_dev->pdev->dev; 163 u32 bits_per_long = BITS_PER_LONG; 164 165 if (buf->nbufs == 1) { 166 dma_free_coherent(dev, size, buf->direct.buf, buf->direct.map); 167 } else { 168 if (bits_per_long == 64) 169 vunmap(buf->direct.buf); 170 171 for (i = 0; i < buf->nbufs; ++i) 172 if (buf->page_list[i].buf) 173 dma_free_coherent(&hr_dev->pdev->dev, PAGE_SIZE, 174 buf->page_list[i].buf, 175 buf->page_list[i].map); 176 kfree(buf->page_list); 177 } 178 } 179 180 int hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, u32 max_direct, 181 struct hns_roce_buf *buf) 182 { 183 int i = 0; 184 dma_addr_t t; 185 struct page **pages; 186 struct device *dev = &hr_dev->pdev->dev; 187 u32 bits_per_long = BITS_PER_LONG; 188 189 /* SQ/RQ buf lease than one page, SQ + RQ = 8K */ 190 if (size <= max_direct) { 191 buf->nbufs = 1; 192 /* Npages calculated by page_size */ 193 buf->npages = 1 << get_order(size); 194 buf->page_shift = PAGE_SHIFT; 195 /* MTT PA must be recorded in 4k alignment, t is 4k aligned */ 196 buf->direct.buf = dma_alloc_coherent(dev, size, &t, GFP_KERNEL); 197 if (!buf->direct.buf) 198 return -ENOMEM; 199 200 buf->direct.map = t; 201 202 while (t & ((1 << buf->page_shift) - 1)) { 203 --buf->page_shift; 204 buf->npages *= 2; 205 } 206 207 memset(buf->direct.buf, 0, size); 208 } else { 209 buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE; 210 buf->npages = buf->nbufs; 211 buf->page_shift = PAGE_SHIFT; 212 buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list), 213 GFP_KERNEL); 214 215 if (!buf->page_list) 216 return -ENOMEM; 217 218 for (i = 0; i < buf->nbufs; ++i) { 219 buf->page_list[i].buf = dma_alloc_coherent(dev, 220 PAGE_SIZE, &t, 221 GFP_KERNEL); 222 223 if (!buf->page_list[i].buf) 224 goto err_free; 225 226 buf->page_list[i].map = t; 227 memset(buf->page_list[i].buf, 0, PAGE_SIZE); 228 } 229 if (bits_per_long == 64) { 230 pages = kmalloc_array(buf->nbufs, sizeof(*pages), 231 GFP_KERNEL); 232 if (!pages) 233 goto err_free; 234 235 for (i = 0; i < buf->nbufs; ++i) 236 pages[i] = virt_to_page(buf->page_list[i].buf); 237 238 buf->direct.buf = vmap(pages, buf->nbufs, VM_MAP, 239 PAGE_KERNEL); 240 kfree(pages); 241 if (!buf->direct.buf) 242 goto err_free; 243 } 244 } 245 246 return 0; 247 248 err_free: 249 hns_roce_buf_free(hr_dev, size, buf); 250 return -ENOMEM; 251 } 252 253 void hns_roce_cleanup_bitmap(struct hns_roce_dev *hr_dev) 254 { 255 hns_roce_cleanup_qp_table(hr_dev); 256 hns_roce_cleanup_cq_table(hr_dev); 257 hns_roce_cleanup_mr_table(hr_dev); 258 hns_roce_cleanup_pd_table(hr_dev); 259 hns_roce_cleanup_uar_table(hr_dev); 260 } 261