Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Intel Corporation
3 : : */
4 : :
5 : : #include "ifcvf.h"
6 : : #include "ifcvf_osdep.h"
7 : :
8 : : STATIC void *
9 : 0 : get_cap_addr(struct ifcvf_hw *hw, struct ifcvf_pci_cap *cap)
10 : : {
11 : 0 : u8 bar = cap->bar;
12 : 0 : u32 length = cap->length;
13 : 0 : u32 offset = cap->offset;
14 : :
15 [ # # ]: 0 : if (bar > IFCVF_PCI_MAX_RESOURCE - 1) {
16 : 0 : DEBUGOUT("invalid bar: %u\n", bar);
17 : 0 : return NULL;
18 : : }
19 : :
20 [ # # ]: 0 : if (offset + length < offset) {
21 : 0 : DEBUGOUT("offset(%u) + length(%u) overflows\n",
22 : : offset, length);
23 : 0 : return NULL;
24 : : }
25 : :
26 [ # # ]: 0 : if (offset + length > hw->mem_resource[cap->bar].len) {
27 : 0 : DEBUGOUT("offset(%u) + length(%u) overflows bar length(%u)",
28 : : offset, length, (u32)hw->mem_resource[cap->bar].len);
29 : 0 : return NULL;
30 : : }
31 : :
32 : 0 : return hw->mem_resource[bar].addr + offset;
33 : : }
34 : :
35 : : int
36 : 0 : ifcvf_init_hw(struct ifcvf_hw *hw, PCI_DEV *dev)
37 : : {
38 : : int ret;
39 : : u8 pos;
40 : : struct ifcvf_pci_cap cap;
41 : :
42 : 0 : ret = PCI_READ_CONFIG_BYTE(dev, &pos, PCI_CAPABILITY_LIST);
43 [ # # ]: 0 : if (ret < 0) {
44 : 0 : DEBUGOUT("failed to read pci capability list\n");
45 : 0 : return -1;
46 : : }
47 : :
48 [ # # ]: 0 : while (pos) {
49 : : ret = PCI_READ_CONFIG_RANGE(dev, (u32 *)&cap,
50 : : sizeof(cap), pos);
51 [ # # ]: 0 : if (ret < 0) {
52 : 0 : DEBUGOUT("failed to read cap at pos: %x", pos);
53 : 0 : break;
54 : : }
55 : :
56 [ # # ]: 0 : if (cap.cap_vndr != PCI_CAP_ID_VNDR)
57 : 0 : goto next;
58 : :
59 : 0 : DEBUGOUT("cfg type: %u, bar: %u, offset: %u, "
60 : : "len: %u\n", cap.cfg_type, cap.bar,
61 : : cap.offset, cap.length);
62 : :
63 [ # # # # : 0 : switch (cap.cfg_type) {
# ]
64 : 0 : case IFCVF_PCI_CAP_COMMON_CFG:
65 : 0 : hw->common_cfg = get_cap_addr(hw, &cap);
66 : 0 : break;
67 : 0 : case IFCVF_PCI_CAP_NOTIFY_CFG:
68 : 0 : ret = PCI_READ_CONFIG_DWORD(dev,
69 : : &hw->notify_off_multiplier,
70 : : pos + sizeof(cap));
71 [ # # ]: 0 : if (ret < 0) {
72 : 0 : DEBUGOUT("failed to read notify_off_multiplier\n");
73 : 0 : return -1;
74 : : }
75 : 0 : hw->notify_base = get_cap_addr(hw, &cap);
76 : 0 : hw->notify_region = cap.bar;
77 : 0 : break;
78 : 0 : case IFCVF_PCI_CAP_ISR_CFG:
79 : 0 : hw->isr = get_cap_addr(hw, &cap);
80 : 0 : break;
81 : 0 : case IFCVF_PCI_CAP_DEVICE_CFG:
82 : 0 : hw->dev_cfg = get_cap_addr(hw, &cap);
83 : 0 : break;
84 : : }
85 : 0 : next:
86 : 0 : pos = cap.cap_next;
87 : : }
88 : :
89 : 0 : hw->lm_cfg = hw->mem_resource[4].addr;
90 [ # # ]: 0 : if (!hw->lm_cfg)
91 : 0 : WARNINGOUT("HW support live migration not support!\n");
92 : :
93 : : /* For some hardware implementation, for example:
94 : : * the BAR 4 of PF is NULL, while BAR 4 of VF is not.
95 : : * This code makes sure hw->mq_cfg is a valid address.
96 : : */
97 [ # # ]: 0 : if (hw->mem_resource[4].addr)
98 : 0 : hw->mq_cfg = hw->mem_resource[4].addr + IFCVF_MQ_OFFSET;
99 : : else
100 : 0 : hw->mq_cfg = NULL;
101 : :
102 [ # # # # ]: 0 : if (hw->common_cfg == NULL || hw->notify_base == NULL ||
103 [ # # # # ]: 0 : hw->isr == NULL || hw->dev_cfg == NULL) {
104 : 0 : DEBUGOUT("capability incomplete\n");
105 : 0 : return -1;
106 : : }
107 : :
108 : 0 : DEBUGOUT("capability mapping:\n"
109 : : "common cfg: %p\n"
110 : : "notify base: %p\n"
111 : : "isr cfg: %p\n"
112 : : "device cfg: %p\n"
113 : : "multiplier: %u\n",
114 : : hw->common_cfg, hw->notify_base, hw->isr, hw->dev_cfg,
115 : : hw->notify_off_multiplier);
116 : :
117 : 0 : return 0;
118 : : }
119 : :
120 : : STATIC u8
121 : : ifcvf_get_status(struct ifcvf_hw *hw)
122 : : {
123 : 0 : return IFCVF_READ_REG8(&hw->common_cfg->device_status);
124 : : }
125 : :
126 : : STATIC void
127 : : ifcvf_set_status(struct ifcvf_hw *hw, u8 status)
128 : : {
129 : 0 : IFCVF_WRITE_REG8(status, &hw->common_cfg->device_status);
130 : 0 : }
131 : :
132 : : STATIC void
133 : : ifcvf_reset(struct ifcvf_hw *hw)
134 : : {
135 : : ifcvf_set_status(hw, 0);
136 : :
137 : : /* flush status write */
138 [ # # # # ]: 0 : while (ifcvf_get_status(hw))
139 : 0 : msec_delay(1);
140 : : }
141 : :
142 : : STATIC void
143 : : ifcvf_add_status(struct ifcvf_hw *hw, u8 status)
144 : : {
145 : : if (status != 0)
146 : 0 : status |= ifcvf_get_status(hw);
147 : :
148 : : ifcvf_set_status(hw, status);
149 : : ifcvf_get_status(hw);
150 : : }
151 : :
152 : : u64
153 : 0 : ifcvf_get_features(struct ifcvf_hw *hw)
154 : : {
155 : : u32 features_lo, features_hi;
156 : 0 : struct ifcvf_pci_common_cfg *cfg = hw->common_cfg;
157 : :
158 : : IFCVF_WRITE_REG32(0, &cfg->device_feature_select);
159 : : features_lo = IFCVF_READ_REG32(&cfg->device_feature);
160 : :
161 : : IFCVF_WRITE_REG32(1, &cfg->device_feature_select);
162 : : features_hi = IFCVF_READ_REG32(&cfg->device_feature);
163 : :
164 : 0 : return ((u64)features_hi << 32) | features_lo;
165 : : }
166 : :
167 : : STATIC void
168 : : ifcvf_set_features(struct ifcvf_hw *hw, u64 features)
169 : : {
170 : 0 : struct ifcvf_pci_common_cfg *cfg = hw->common_cfg;
171 : :
172 : : IFCVF_WRITE_REG32(0, &cfg->guest_feature_select);
173 : 0 : IFCVF_WRITE_REG32(features & ((1ULL << 32) - 1), &cfg->guest_feature);
174 : :
175 : : IFCVF_WRITE_REG32(1, &cfg->guest_feature_select);
176 : 0 : IFCVF_WRITE_REG32(features >> 32, &cfg->guest_feature);
177 : : }
178 : :
179 : : STATIC int
180 : 0 : ifcvf_config_features(struct ifcvf_hw *hw)
181 : : {
182 : : u64 host_features;
183 : :
184 : 0 : host_features = ifcvf_get_features(hw);
185 : 0 : hw->req_features &= host_features;
186 : :
187 : : ifcvf_set_features(hw, hw->req_features);
188 : : ifcvf_add_status(hw, IFCVF_CONFIG_STATUS_FEATURES_OK);
189 : :
190 [ # # ]: 0 : if (!(ifcvf_get_status(hw) & IFCVF_CONFIG_STATUS_FEATURES_OK)) {
191 : 0 : DEBUGOUT("failed to set FEATURES_OK status\n");
192 : 0 : return -1;
193 : : }
194 : :
195 : : return 0;
196 : : }
197 : :
198 : : STATIC void
199 : : io_write64_twopart(u64 val, u32 *lo, u32 *hi)
200 : : {
201 : 0 : IFCVF_WRITE_REG32(val & ((1ULL << 32) - 1), lo);
202 : 0 : IFCVF_WRITE_REG32(val >> 32, hi);
203 : : }
204 : :
205 : : STATIC void
206 : 0 : ifcvf_enable_mq(struct ifcvf_hw *hw)
207 : : {
208 : : u8 *mq_cfg;
209 : : u8 qid;
210 : : int nr_queue = 0;
211 : :
212 [ # # ]: 0 : for (qid = 0; qid < hw->nr_vring; qid++) {
213 [ # # ]: 0 : if (!hw->vring[qid].enable)
214 : 0 : continue;
215 : 0 : nr_queue++;
216 : : }
217 : :
218 [ # # ]: 0 : if (nr_queue == 0) {
219 : 0 : WARNINGOUT("no enabled vring\n");
220 : 0 : return;
221 : : }
222 : :
223 : 0 : mq_cfg = hw->mq_cfg;
224 [ # # ]: 0 : if (mq_cfg) {
225 [ # # ]: 0 : if (hw->device_type == IFCVF_BLK) {
226 : 0 : *(u32 *)mq_cfg = nr_queue;
227 : 0 : RTE_LOG_LINE(INFO, IFCVF_VDPA, "%d queues are enabled", nr_queue);
228 : : } else {
229 : 0 : *(u32 *)mq_cfg = nr_queue / 2;
230 : 0 : RTE_LOG_LINE(INFO, IFCVF_VDPA, "%d queue pairs are enabled",
231 : : nr_queue / 2);
232 : : }
233 : : }
234 : : }
235 : :
236 : : int
237 : 0 : ifcvf_enable_vring_hw(struct ifcvf_hw *hw, int i)
238 : : {
239 : : struct ifcvf_pci_common_cfg *cfg;
240 : : u8 *lm_cfg;
241 : : u16 notify_off;
242 : : int msix_vector;
243 : :
244 [ # # ]: 0 : if (i >= (int)hw->nr_vring)
245 : : return -1;
246 : :
247 : 0 : cfg = hw->common_cfg;
248 [ # # ]: 0 : if (!cfg) {
249 : 0 : RTE_LOG_LINE(ERR, IFCVF_VDPA, "common_cfg in HW is NULL.");
250 : 0 : return -1;
251 : : }
252 : :
253 : 0 : ifcvf_enable_mq(hw);
254 : :
255 : 0 : IFCVF_WRITE_REG16(i, &cfg->queue_select);
256 : 0 : msix_vector = IFCVF_READ_REG16(&cfg->queue_msix_vector);
257 [ # # ]: 0 : if (msix_vector != (i + 1)) {
258 : 0 : IFCVF_WRITE_REG16(i + 1, &cfg->queue_msix_vector);
259 : : msix_vector = IFCVF_READ_REG16(&cfg->queue_msix_vector);
260 [ # # ]: 0 : if (msix_vector == IFCVF_MSI_NO_VECTOR) {
261 : 0 : RTE_LOG_LINE(ERR, IFCVF_VDPA, "queue %d, msix vec alloc failed",
262 : : i);
263 : 0 : return -1;
264 : : }
265 : : }
266 : :
267 : 0 : io_write64_twopart(hw->vring[i].desc, &cfg->queue_desc_lo,
268 : : &cfg->queue_desc_hi);
269 : 0 : io_write64_twopart(hw->vring[i].avail, &cfg->queue_avail_lo,
270 : : &cfg->queue_avail_hi);
271 : 0 : io_write64_twopart(hw->vring[i].used, &cfg->queue_used_lo,
272 : : &cfg->queue_used_hi);
273 : 0 : IFCVF_WRITE_REG16(hw->vring[i].size, &cfg->queue_size);
274 : :
275 : 0 : lm_cfg = hw->lm_cfg;
276 [ # # ]: 0 : if (lm_cfg) {
277 [ # # ]: 0 : if (hw->device_type == IFCVF_BLK)
278 : 0 : *(u32 *)(lm_cfg + IFCVF_LM_RING_STATE_OFFSET +
279 : 0 : i * IFCVF_LM_CFG_SIZE) =
280 : 0 : (u32)hw->vring[i].last_avail_idx |
281 : 0 : ((u32)hw->vring[i].last_used_idx << 16);
282 : : else
283 : : *(u32 *)(lm_cfg + IFCVF_LM_RING_STATE_OFFSET +
284 : 0 : (i / 2) * IFCVF_LM_CFG_SIZE +
285 : 0 : (i % 2) * 4) =
286 : 0 : (u32)hw->vring[i].last_avail_idx |
287 : 0 : ((u32)hw->vring[i].last_used_idx << 16);
288 : : }
289 : :
290 : : notify_off = IFCVF_READ_REG16(&cfg->queue_notify_off);
291 : 0 : hw->notify_addr[i] = (void *)((u8 *)hw->notify_base +
292 : 0 : notify_off * hw->notify_off_multiplier);
293 : : IFCVF_WRITE_REG16(1, &cfg->queue_enable);
294 : :
295 : 0 : return 0;
296 : : }
297 : :
298 : : void
299 : 0 : ifcvf_disable_vring_hw(struct ifcvf_hw *hw, int i)
300 : : {
301 : : struct ifcvf_pci_common_cfg *cfg;
302 : : u32 ring_state;
303 : : u8 *lm_cfg;
304 : :
305 [ # # ]: 0 : if (i >= (int)hw->nr_vring)
306 : : return;
307 : :
308 : 0 : cfg = hw->common_cfg;
309 [ # # ]: 0 : if (!cfg) {
310 : 0 : RTE_LOG_LINE(ERR, IFCVF_VDPA, "common_cfg in HW is NULL.");
311 : 0 : return;
312 : : }
313 : :
314 : 0 : IFCVF_WRITE_REG16(i, &cfg->queue_select);
315 : : IFCVF_WRITE_REG16(0, &cfg->queue_enable);
316 : :
317 : 0 : lm_cfg = hw->lm_cfg;
318 [ # # ]: 0 : if (lm_cfg) {
319 [ # # ]: 0 : if (hw->device_type == IFCVF_BLK) {
320 : 0 : ring_state = *(u32 *)(lm_cfg +
321 : 0 : IFCVF_LM_RING_STATE_OFFSET +
322 : 0 : i * IFCVF_LM_CFG_SIZE);
323 : 0 : hw->vring[i].last_avail_idx =
324 : 0 : (u16)(ring_state & IFCVF_16_BIT_MASK);
325 : : } else {
326 : 0 : ring_state = *(u32 *)(lm_cfg +
327 : : IFCVF_LM_RING_STATE_OFFSET +
328 : 0 : (i / 2) * IFCVF_LM_CFG_SIZE +
329 : 0 : (i % 2) * 4);
330 : 0 : hw->vring[i].last_avail_idx = (u16)(ring_state >> 16);
331 : : }
332 : 0 : hw->vring[i].last_used_idx = (u16)(ring_state >> 16);
333 : : }
334 : : }
335 : :
336 : : STATIC int
337 : 0 : ifcvf_hw_enable(struct ifcvf_hw *hw)
338 : : {
339 : : struct ifcvf_pci_common_cfg *cfg;
340 : : u8 *lm_cfg;
341 : : u32 i;
342 : : u16 notify_off;
343 : :
344 : 0 : cfg = hw->common_cfg;
345 : 0 : lm_cfg = hw->lm_cfg;
346 : :
347 : : IFCVF_WRITE_REG16(0, &cfg->msix_config);
348 [ # # ]: 0 : if (IFCVF_READ_REG16(&cfg->msix_config) == IFCVF_MSI_NO_VECTOR) {
349 : 0 : DEBUGOUT("msix vec alloc failed for device config\n");
350 : 0 : return -1;
351 : : }
352 : :
353 : 0 : ifcvf_enable_mq(hw);
354 [ # # ]: 0 : for (i = 0; i < hw->nr_vring; i++) {
355 [ # # ]: 0 : if (!hw->vring[i].enable)
356 : 0 : continue;
357 : :
358 : 0 : IFCVF_WRITE_REG16(i, &cfg->queue_select);
359 : 0 : io_write64_twopart(hw->vring[i].desc, &cfg->queue_desc_lo,
360 : : &cfg->queue_desc_hi);
361 : 0 : io_write64_twopart(hw->vring[i].avail, &cfg->queue_avail_lo,
362 : : &cfg->queue_avail_hi);
363 : 0 : io_write64_twopart(hw->vring[i].used, &cfg->queue_used_lo,
364 : : &cfg->queue_used_hi);
365 : 0 : IFCVF_WRITE_REG16(hw->vring[i].size, &cfg->queue_size);
366 : :
367 [ # # ]: 0 : if (lm_cfg) {
368 [ # # ]: 0 : if (hw->device_type == IFCVF_BLK)
369 : 0 : *(u32 *)(lm_cfg + IFCVF_LM_RING_STATE_OFFSET +
370 : 0 : i * IFCVF_LM_CFG_SIZE) =
371 : 0 : (u32)hw->vring[i].last_avail_idx |
372 : 0 : ((u32)hw->vring[i].last_used_idx << 16);
373 : : else
374 : : *(u32 *)(lm_cfg + IFCVF_LM_RING_STATE_OFFSET +
375 : 0 : (i / 2) * IFCVF_LM_CFG_SIZE +
376 : 0 : (i % 2) * 4) =
377 : 0 : (u32)hw->vring[i].last_avail_idx |
378 : 0 : ((u32)hw->vring[i].last_used_idx << 16);
379 : : }
380 : :
381 : 0 : IFCVF_WRITE_REG16(i + 1, &cfg->queue_msix_vector);
382 [ # # ]: 0 : if (IFCVF_READ_REG16(&cfg->queue_msix_vector) ==
383 : : IFCVF_MSI_NO_VECTOR) {
384 : 0 : DEBUGOUT("queue %u, msix vec alloc failed\n",
385 : : i);
386 : 0 : return -1;
387 : : }
388 : :
389 : : notify_off = IFCVF_READ_REG16(&cfg->queue_notify_off);
390 : 0 : hw->notify_addr[i] = (void *)((u8 *)hw->notify_base +
391 : 0 : notify_off * hw->notify_off_multiplier);
392 : : IFCVF_WRITE_REG16(1, &cfg->queue_enable);
393 : : }
394 : :
395 : : return 0;
396 : : }
397 : :
398 : : STATIC void
399 : 0 : ifcvf_hw_disable(struct ifcvf_hw *hw)
400 : : {
401 : : u32 i;
402 : : struct ifcvf_pci_common_cfg *cfg;
403 : : u32 ring_state;
404 : : int q_disable_try;
405 : :
406 : 0 : cfg = hw->common_cfg;
407 [ # # ]: 0 : if (!cfg) {
408 : 0 : DEBUGOUT("common_cfg in HW is NULL.\n");
409 : 0 : return;
410 : : }
411 : :
412 : : IFCVF_WRITE_REG16(IFCVF_MSI_NO_VECTOR, &cfg->msix_config);
413 [ # # ]: 0 : for (i = 0; i < hw->nr_vring; i++) {
414 : 0 : IFCVF_WRITE_REG16(i, &cfg->queue_select);
415 : : IFCVF_WRITE_REG16(0, &cfg->queue_enable);
416 : : IFCVF_WRITE_REG16(IFCVF_MSI_NO_VECTOR, &cfg->queue_msix_vector);
417 : :
418 [ # # ]: 0 : if (!hw->lm_cfg) {
419 : 0 : DEBUGOUT("live migration cfg in HW is NULL.\n");
420 : 0 : continue;
421 : : }
422 : :
423 : : /* Some ifc hardware require synchronization between disabling a
424 : : * queue and saving queue-state from LM registers. When queue is
425 : : * disabled from vDPA driver, ifc device stops executing new
426 : : * virtio-cmds and then updates LM registers with used/avail
427 : : * index. Before saving the queue-state, vDPA driver waits until
428 : : * the queue is disabled from backend.
429 : : */
430 : : q_disable_try = 10;
431 [ # # # # ]: 0 : while (q_disable_try-- && IFCVF_READ_REG16(&cfg->queue_enable))
432 : 0 : msec_delay(10);
433 : :
434 [ # # ]: 0 : if (!q_disable_try)
435 : 0 : WARNINGOUT("Failed to disable Q:%u, Saved state could be invalid\n", i);
436 : :
437 [ # # ]: 0 : if (hw->device_type == IFCVF_BLK)
438 : 0 : ring_state = *(u32 *)(hw->lm_cfg +
439 : 0 : IFCVF_LM_RING_STATE_OFFSET +
440 : 0 : i * IFCVF_LM_CFG_SIZE);
441 : : else
442 : 0 : ring_state = *(u32 *)(hw->lm_cfg +
443 : : IFCVF_LM_RING_STATE_OFFSET +
444 : 0 : (i / 2) * IFCVF_LM_CFG_SIZE +
445 : 0 : (i % 2) * 4);
446 : :
447 [ # # ]: 0 : if (hw->device_type == IFCVF_BLK)
448 : 0 : hw->vring[i].last_avail_idx =
449 : 0 : (u16)(ring_state & IFCVF_16_BIT_MASK);
450 : : else
451 : 0 : hw->vring[i].last_avail_idx = (u16)(ring_state >> 16);
452 : 0 : hw->vring[i].last_used_idx = (u16)(ring_state >> 16);
453 : : }
454 : : }
455 : :
456 : : int
457 : 0 : ifcvf_start_hw(struct ifcvf_hw *hw)
458 : : {
459 : : ifcvf_reset(hw);
460 : : ifcvf_add_status(hw, IFCVF_CONFIG_STATUS_ACK);
461 : : ifcvf_add_status(hw, IFCVF_CONFIG_STATUS_DRIVER);
462 : :
463 [ # # ]: 0 : if (ifcvf_config_features(hw) < 0)
464 : : return -1;
465 : :
466 [ # # ]: 0 : if (ifcvf_hw_enable(hw) < 0)
467 : : return -1;
468 : :
469 : : ifcvf_add_status(hw, IFCVF_CONFIG_STATUS_DRIVER_OK);
470 : 0 : return 0;
471 : : }
472 : :
473 : : void
474 : 0 : ifcvf_stop_hw(struct ifcvf_hw *hw)
475 : : {
476 : 0 : ifcvf_hw_disable(hw);
477 : : ifcvf_reset(hw);
478 : 0 : }
479 : :
480 : : void
481 : 0 : ifcvf_enable_logging(struct ifcvf_hw *hw, u64 log_base, u64 log_size)
482 : : {
483 : : u8 *lm_cfg;
484 : :
485 : 0 : lm_cfg = hw->lm_cfg;
486 [ # # ]: 0 : if (!lm_cfg)
487 : : return;
488 : :
489 : 0 : *(u32 *)(lm_cfg + IFCVF_LM_BASE_ADDR_LOW) =
490 : : log_base & IFCVF_32_BIT_MASK;
491 : :
492 : 0 : *(u32 *)(lm_cfg + IFCVF_LM_BASE_ADDR_HIGH) =
493 : 0 : (log_base >> 32) & IFCVF_32_BIT_MASK;
494 : :
495 : 0 : *(u32 *)(lm_cfg + IFCVF_LM_END_ADDR_LOW) =
496 : 0 : (log_base + log_size) & IFCVF_32_BIT_MASK;
497 : :
498 : 0 : *(u32 *)(lm_cfg + IFCVF_LM_END_ADDR_HIGH) =
499 : 0 : ((log_base + log_size) >> 32) & IFCVF_32_BIT_MASK;
500 : :
501 : 0 : *(u32 *)(lm_cfg + IFCVF_LM_LOGGING_CTRL) = IFCVF_LM_ENABLE_VF;
502 : : }
503 : :
504 : : void
505 : 0 : ifcvf_disable_logging(struct ifcvf_hw *hw)
506 : : {
507 : : u8 *lm_cfg;
508 : :
509 : 0 : lm_cfg = hw->lm_cfg;
510 [ # # ]: 0 : if (!lm_cfg)
511 : : return;
512 : :
513 : 0 : *(u32 *)(lm_cfg + IFCVF_LM_LOGGING_CTRL) = IFCVF_LM_DISABLE;
514 : : }
515 : :
516 : : void
517 : 0 : ifcvf_notify_queue(struct ifcvf_hw *hw, u16 qid)
518 : : {
519 : 0 : IFCVF_WRITE_REG16(qid, hw->notify_addr[qid]);
520 : 0 : }
521 : :
522 : : u8
523 : 0 : ifcvf_get_notify_region(struct ifcvf_hw *hw)
524 : : {
525 : 0 : return hw->notify_region;
526 : : }
527 : :
528 : : u64
529 : 0 : ifcvf_get_queue_notify_off(struct ifcvf_hw *hw, int qid)
530 : : {
531 : 0 : return (u8 *)hw->notify_addr[qid] -
532 : 0 : (u8 *)hw->mem_resource[hw->notify_region].addr;
533 : : }
|