hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
....@@ -1,16 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Huawei HiNIC PCI Express Linux driver
34 * Copyright(c) 2017 Huawei Technologies Co., Ltd
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope it will be useful, but WITHOUT
10
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
- * for more details.
13
- *
145 */
156
167 #include <linux/pci.h>
....@@ -19,6 +10,7 @@
1910 #include <linux/io.h>
2011 #include <linux/types.h>
2112 #include <linux/bitops.h>
13
+#include <linux/delay.h>
2214
2315 #include "hinic_hw_csr.h"
2416 #include "hinic_hw_if.h"
....@@ -26,6 +18,10 @@
2618 #define PCIE_ATTR_ENTRY 0
2719
2820 #define VALID_MSIX_IDX(attr, msix_index) ((msix_index) < (attr)->num_irqs)
21
+
22
+#define WAIT_HWIF_READY_TIMEOUT 10000
23
+
24
+#define HINIC_SELFTEST_RESULT 0x883C
2925
3026 /**
3127 * hinic_msix_attr_set - set message attribute for msix entry
....@@ -124,8 +120,12 @@
124120 **/
125121 void hinic_set_pf_action(struct hinic_hwif *hwif, enum hinic_pf_action action)
126122 {
127
- u32 attr5 = hinic_hwif_read_reg(hwif, HINIC_CSR_FUNC_ATTR5_ADDR);
123
+ u32 attr5;
128124
125
+ if (HINIC_IS_VF(hwif))
126
+ return;
127
+
128
+ attr5 = hinic_hwif_read_reg(hwif, HINIC_CSR_FUNC_ATTR5_ADDR);
129129 attr5 = HINIC_FA5_CLEAR(attr5, PF_ACTION);
130130 attr5 |= HINIC_FA5_SET(action, PF_ACTION);
131131
....@@ -168,6 +168,22 @@
168168 hinic_hwif_write_reg(hwif, HINIC_CSR_FUNC_ATTR4_ADDR, attr4);
169169 }
170170
171
+void hinic_set_msix_state(struct hinic_hwif *hwif, u16 msix_idx,
172
+ enum hinic_msix_state flag)
173
+{
174
+ u32 offset = msix_idx * HINIC_PCI_MSIX_ENTRY_SIZE +
175
+ HINIC_PCI_MSIX_ENTRY_VECTOR_CTRL;
176
+ u32 mask_bits;
177
+
178
+ mask_bits = readl(hwif->intr_regs_base + offset);
179
+ mask_bits &= ~HINIC_PCI_MSIX_ENTRY_CTRL_MASKBIT;
180
+
181
+ if (flag)
182
+ mask_bits |= HINIC_PCI_MSIX_ENTRY_CTRL_MASKBIT;
183
+
184
+ writel(mask_bits, hwif->intr_regs_base + offset);
185
+}
186
+
171187 /**
172188 * hwif_ready - test if the HW is ready for use
173189 * @hwif: the HW interface of a pci function device
....@@ -176,18 +192,37 @@
176192 **/
177193 static int hwif_ready(struct hinic_hwif *hwif)
178194 {
179
- struct pci_dev *pdev = hwif->pdev;
180195 u32 addr, attr1;
181196
182197 addr = HINIC_CSR_FUNC_ATTR1_ADDR;
183198 attr1 = hinic_hwif_read_reg(hwif, addr);
184199
185
- if (!HINIC_FA1_GET(attr1, INIT_STATUS)) {
186
- dev_err(&pdev->dev, "hwif status is not ready\n");
187
- return -EFAULT;
200
+ if (!HINIC_FA1_GET(attr1, MGMT_INIT_STATUS))
201
+ return -EBUSY;
202
+
203
+ if (HINIC_IS_VF(hwif)) {
204
+ if (!HINIC_FA1_GET(attr1, PF_INIT_STATUS))
205
+ return -EBUSY;
188206 }
189207
190208 return 0;
209
+}
210
+
211
+static int wait_hwif_ready(struct hinic_hwif *hwif)
212
+{
213
+ unsigned long timeout = 0;
214
+
215
+ do {
216
+ if (!hwif_ready(hwif))
217
+ return 0;
218
+
219
+ usleep_range(999, 1000);
220
+ timeout++;
221
+ } while (timeout <= WAIT_HWIF_READY_TIMEOUT);
222
+
223
+ dev_err(&hwif->pdev->dev, "Wait for hwif timeout\n");
224
+
225
+ return -EBUSY;
191226 }
192227
193228 /**
....@@ -195,8 +230,10 @@
195230 * @hwif: the HW interface of a pci function device
196231 * @attr0: the first attribute that was read from the hw
197232 * @attr1: the second attribute that was read from the hw
233
+ * @attr2: the third attribute that was read from the hw
198234 **/
199
-static void set_hwif_attr(struct hinic_hwif *hwif, u32 attr0, u32 attr1)
235
+static void set_hwif_attr(struct hinic_hwif *hwif, u32 attr0, u32 attr1,
236
+ u32 attr2)
200237 {
201238 hwif->attr.func_idx = HINIC_FA0_GET(attr0, FUNC_IDX);
202239 hwif->attr.pf_idx = HINIC_FA0_GET(attr0, PF_IDX);
....@@ -207,6 +244,8 @@
207244 hwif->attr.num_ceqs = BIT(HINIC_FA1_GET(attr1, CEQS_PER_FUNC));
208245 hwif->attr.num_irqs = BIT(HINIC_FA1_GET(attr1, IRQS_PER_FUNC));
209246 hwif->attr.num_dma_attr = BIT(HINIC_FA1_GET(attr1, DMA_ATTR_PER_FUNC));
247
+ hwif->attr.global_vf_id_of_pf = HINIC_FA2_GET(attr2,
248
+ GLOBAL_VF_ID_OF_PF);
210249 }
211250
212251 /**
....@@ -215,7 +254,7 @@
215254 **/
216255 static void read_hwif_attr(struct hinic_hwif *hwif)
217256 {
218
- u32 addr, attr0, attr1;
257
+ u32 addr, attr0, attr1, attr2;
219258
220259 addr = HINIC_CSR_FUNC_ATTR0_ADDR;
221260 attr0 = hinic_hwif_read_reg(hwif, addr);
....@@ -223,7 +262,10 @@
223262 addr = HINIC_CSR_FUNC_ATTR1_ADDR;
224263 attr1 = hinic_hwif_read_reg(hwif, addr);
225264
226
- set_hwif_attr(hwif, attr0, attr1);
265
+ addr = HINIC_CSR_FUNC_ATTR2_ADDR;
266
+ attr2 = hinic_hwif_read_reg(hwif, addr);
267
+
268
+ set_hwif_attr(hwif, attr0, attr1, attr2);
227269 }
228270
229271 /**
....@@ -302,6 +344,54 @@
302344 HINIC_PCIE_SNOOP, HINIC_PCIE_TPH_DISABLE);
303345 }
304346
347
+u16 hinic_glb_pf_vf_offset(struct hinic_hwif *hwif)
348
+{
349
+ if (!hwif)
350
+ return 0;
351
+
352
+ return hwif->attr.global_vf_id_of_pf;
353
+}
354
+
355
+u16 hinic_global_func_id_hw(struct hinic_hwif *hwif)
356
+{
357
+ u32 addr, attr0;
358
+
359
+ addr = HINIC_CSR_FUNC_ATTR0_ADDR;
360
+ attr0 = hinic_hwif_read_reg(hwif, addr);
361
+
362
+ return HINIC_FA0_GET(attr0, FUNC_IDX);
363
+}
364
+
365
+u16 hinic_pf_id_of_vf_hw(struct hinic_hwif *hwif)
366
+{
367
+ u32 addr, attr0;
368
+
369
+ addr = HINIC_CSR_FUNC_ATTR0_ADDR;
370
+ attr0 = hinic_hwif_read_reg(hwif, addr);
371
+
372
+ return HINIC_FA0_GET(attr0, PF_IDX);
373
+}
374
+
375
+static void __print_selftest_reg(struct hinic_hwif *hwif)
376
+{
377
+ u32 addr, attr0, attr1;
378
+
379
+ addr = HINIC_CSR_FUNC_ATTR1_ADDR;
380
+ attr1 = hinic_hwif_read_reg(hwif, addr);
381
+
382
+ if (attr1 == HINIC_PCIE_LINK_DOWN) {
383
+ dev_err(&hwif->pdev->dev, "PCIE is link down\n");
384
+ return;
385
+ }
386
+
387
+ addr = HINIC_CSR_FUNC_ATTR0_ADDR;
388
+ attr0 = hinic_hwif_read_reg(hwif, addr);
389
+ if (HINIC_FA0_GET(attr0, FUNC_TYPE) != HINIC_VF &&
390
+ !HINIC_FA0_GET(attr0, PCI_INTF_IDX))
391
+ dev_err(&hwif->pdev->dev, "Selftest reg: 0x%08x\n",
392
+ hinic_hwif_read_reg(hwif, HINIC_SELFTEST_RESULT));
393
+}
394
+
305395 /**
306396 * hinic_init_hwif - initialize the hw interface
307397 * @hwif: the HW interface of a pci function device
....@@ -321,9 +411,17 @@
321411 return -ENOMEM;
322412 }
323413
324
- err = hwif_ready(hwif);
414
+ hwif->intr_regs_base = pci_ioremap_bar(pdev, HINIC_PCI_INTR_REGS_BAR);
415
+ if (!hwif->intr_regs_base) {
416
+ dev_err(&pdev->dev, "Failed to map configuration regs\n");
417
+ err = -ENOMEM;
418
+ goto err_map_intr_bar;
419
+ }
420
+
421
+ err = wait_hwif_ready(hwif);
325422 if (err) {
326423 dev_err(&pdev->dev, "HW interface is not ready\n");
424
+ __print_selftest_reg(hwif);
327425 goto err_hwif_ready;
328426 }
329427
....@@ -337,7 +435,11 @@
337435 return 0;
338436
339437 err_hwif_ready:
438
+ iounmap(hwif->intr_regs_base);
439
+
440
+err_map_intr_bar:
340441 iounmap(hwif->cfg_regs_bar);
442
+
341443 return err;
342444 }
343445
....@@ -347,5 +449,6 @@
347449 **/
348450 void hinic_free_hwif(struct hinic_hwif *hwif)
349451 {
452
+ iounmap(hwif->intr_regs_base);
350453 iounmap(hwif->cfg_regs_bar);
351454 }