Skip to content

Commit fbfb803

Browse files
emuslndavem330
authored andcommitted
ionic: Add hardware init and device commands
The ionic device has a small set of PCI registers, including a device control and data space, and a large set of message commands. Also adds new DEVLINK_INFO_VERSION_GENERIC tags for ASIC_ID, ASIC_REV, and FW. Signed-off-by: Shannon Nelson <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent df69ba4 commit fbfb803

File tree

13 files changed

+3481
-2
lines changed

13 files changed

+3481
-2
lines changed

drivers/net/ethernet/pensando/ionic/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33

44
obj-$(CONFIG_IONIC) := ionic.o
55

6-
ionic-y := ionic_main.o ionic_bus_pci.o ionic_devlink.o
6+
ionic-y := ionic_main.o ionic_bus_pci.o ionic_devlink.o ionic_dev.o \
7+
ionic_debugfs.o

drivers/net/ethernet/pensando/ionic/ionic.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#ifndef _IONIC_H_
55
#define _IONIC_H_
66

7+
#include "ionic_if.h"
8+
#include "ionic_dev.h"
79
#include "ionic_devlink.h"
810

911
#define IONIC_DRV_NAME "ionic"
@@ -19,9 +21,25 @@
1921
#define IONIC_SUBDEV_ID_NAPLES_100_4 0x4001
2022
#define IONIC_SUBDEV_ID_NAPLES_100_8 0x4002
2123

24+
#define DEVCMD_TIMEOUT 10
25+
2226
struct ionic {
2327
struct pci_dev *pdev;
2428
struct device *dev;
29+
struct ionic_dev idev;
30+
struct mutex dev_cmd_lock; /* lock for dev_cmd operations */
31+
struct dentry *dentry;
32+
struct ionic_dev_bar bars[IONIC_BARS_MAX];
33+
unsigned int num_bars;
34+
struct ionic_identity ident;
2535
};
2636

37+
int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_wait);
38+
int ionic_set_dma_mask(struct ionic *ionic);
39+
int ionic_setup(struct ionic *ionic);
40+
41+
int ionic_identify(struct ionic *ionic);
42+
int ionic_init(struct ionic *ionic);
43+
int ionic_reset(struct ionic *ionic);
44+
2745
#endif /* _IONIC_H_ */

drivers/net/ethernet/pensando/ionic/ionic_bus.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#ifndef _IONIC_BUS_H_
55
#define _IONIC_BUS_H_
66

7+
const char *ionic_bus_info(struct ionic *ionic);
78
int ionic_bus_register_driver(void);
89
void ionic_bus_unregister_driver(void);
910

drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "ionic.h"
1010
#include "ionic_bus.h"
11+
#include "ionic_debugfs.h"
1112

1213
/* Supported devices */
1314
static const struct pci_device_id ionic_id_table[] = {
@@ -17,10 +18,68 @@ static const struct pci_device_id ionic_id_table[] = {
1718
};
1819
MODULE_DEVICE_TABLE(pci, ionic_id_table);
1920

21+
const char *ionic_bus_info(struct ionic *ionic)
22+
{
23+
return pci_name(ionic->pdev);
24+
}
25+
26+
static int ionic_map_bars(struct ionic *ionic)
27+
{
28+
struct pci_dev *pdev = ionic->pdev;
29+
struct device *dev = ionic->dev;
30+
struct ionic_dev_bar *bars;
31+
unsigned int i, j;
32+
33+
bars = ionic->bars;
34+
ionic->num_bars = 0;
35+
36+
for (i = 0, j = 0; i < IONIC_BARS_MAX; i++) {
37+
if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
38+
continue;
39+
bars[j].len = pci_resource_len(pdev, i);
40+
41+
/* only map the whole bar 0 */
42+
if (j > 0) {
43+
bars[j].vaddr = NULL;
44+
} else {
45+
bars[j].vaddr = pci_iomap(pdev, i, bars[j].len);
46+
if (!bars[j].vaddr) {
47+
dev_err(dev,
48+
"Cannot memory-map BAR %d, aborting\n",
49+
i);
50+
return -ENODEV;
51+
}
52+
}
53+
54+
bars[j].bus_addr = pci_resource_start(pdev, i);
55+
bars[j].res_index = i;
56+
ionic->num_bars++;
57+
j++;
58+
}
59+
60+
return 0;
61+
}
62+
63+
static void ionic_unmap_bars(struct ionic *ionic)
64+
{
65+
struct ionic_dev_bar *bars = ionic->bars;
66+
unsigned int i;
67+
68+
for (i = 0; i < IONIC_BARS_MAX; i++) {
69+
if (bars[i].vaddr) {
70+
iounmap(bars[i].vaddr);
71+
bars[i].bus_addr = 0;
72+
bars[i].vaddr = NULL;
73+
bars[i].len = 0;
74+
}
75+
}
76+
}
77+
2078
static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2179
{
2280
struct device *dev = &pdev->dev;
2381
struct ionic *ionic;
82+
int err;
2483

2584
ionic = ionic_devlink_alloc(dev);
2685
if (!ionic)
@@ -29,14 +88,96 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2988
ionic->pdev = pdev;
3089
ionic->dev = dev;
3190
pci_set_drvdata(pdev, ionic);
91+
mutex_init(&ionic->dev_cmd_lock);
92+
93+
/* Query system for DMA addressing limitation for the device. */
94+
err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(IONIC_ADDR_LEN));
95+
if (err) {
96+
dev_err(dev, "Unable to obtain 64-bit DMA for consistent allocations, aborting. err=%d\n",
97+
err);
98+
goto err_out_clear_drvdata;
99+
}
100+
101+
ionic_debugfs_add_dev(ionic);
102+
103+
/* Setup PCI device */
104+
err = pci_enable_device_mem(pdev);
105+
if (err) {
106+
dev_err(dev, "Cannot enable PCI device: %d, aborting\n", err);
107+
goto err_out_debugfs_del_dev;
108+
}
109+
110+
err = pci_request_regions(pdev, IONIC_DRV_NAME);
111+
if (err) {
112+
dev_err(dev, "Cannot request PCI regions: %d, aborting\n", err);
113+
goto err_out_pci_disable_device;
114+
}
115+
116+
pci_set_master(pdev);
117+
118+
err = ionic_map_bars(ionic);
119+
if (err)
120+
goto err_out_pci_clear_master;
121+
122+
/* Configure the device */
123+
err = ionic_setup(ionic);
124+
if (err) {
125+
dev_err(dev, "Cannot setup device: %d, aborting\n", err);
126+
goto err_out_unmap_bars;
127+
}
128+
129+
err = ionic_identify(ionic);
130+
if (err) {
131+
dev_err(dev, "Cannot identify device: %d, aborting\n", err);
132+
goto err_out_teardown;
133+
}
134+
135+
err = ionic_init(ionic);
136+
if (err) {
137+
dev_err(dev, "Cannot init device: %d, aborting\n", err);
138+
goto err_out_teardown;
139+
}
140+
141+
err = ionic_devlink_register(ionic);
142+
if (err)
143+
dev_err(dev, "Cannot register devlink: %d\n", err);
32144

33145
return 0;
146+
147+
err_out_teardown:
148+
ionic_dev_teardown(ionic);
149+
err_out_unmap_bars:
150+
ionic_unmap_bars(ionic);
151+
pci_release_regions(pdev);
152+
err_out_pci_clear_master:
153+
pci_clear_master(pdev);
154+
err_out_pci_disable_device:
155+
pci_disable_device(pdev);
156+
err_out_debugfs_del_dev:
157+
ionic_debugfs_del_dev(ionic);
158+
err_out_clear_drvdata:
159+
mutex_destroy(&ionic->dev_cmd_lock);
160+
ionic_devlink_free(ionic);
161+
162+
return err;
34163
}
35164

36165
static void ionic_remove(struct pci_dev *pdev)
37166
{
38167
struct ionic *ionic = pci_get_drvdata(pdev);
39168

169+
if (!ionic)
170+
return;
171+
172+
ionic_devlink_unregister(ionic);
173+
ionic_reset(ionic);
174+
ionic_dev_teardown(ionic);
175+
ionic_unmap_bars(ionic);
176+
pci_release_regions(pdev);
177+
pci_clear_master(pdev);
178+
pci_disable_device(pdev);
179+
ionic_debugfs_del_dev(ionic);
180+
mutex_destroy(&ionic->dev_cmd_lock);
40181
ionic_devlink_free(ionic);
41182
}
42183

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */
3+
4+
#include <linux/netdevice.h>
5+
6+
#include "ionic.h"
7+
#include "ionic_bus.h"
8+
#include "ionic_debugfs.h"
9+
10+
#ifdef CONFIG_DEBUG_FS
11+
12+
static struct dentry *ionic_dir;
13+
14+
void ionic_debugfs_create(void)
15+
{
16+
ionic_dir = debugfs_create_dir(IONIC_DRV_NAME, NULL);
17+
}
18+
19+
void ionic_debugfs_destroy(void)
20+
{
21+
debugfs_remove_recursive(ionic_dir);
22+
}
23+
24+
void ionic_debugfs_add_dev(struct ionic *ionic)
25+
{
26+
ionic->dentry = debugfs_create_dir(ionic_bus_info(ionic), ionic_dir);
27+
}
28+
29+
void ionic_debugfs_del_dev(struct ionic *ionic)
30+
{
31+
debugfs_remove_recursive(ionic->dentry);
32+
ionic->dentry = NULL;
33+
}
34+
35+
static int identity_show(struct seq_file *seq, void *v)
36+
{
37+
struct ionic *ionic = seq->private;
38+
struct ionic_identity *ident;
39+
40+
ident = &ionic->ident;
41+
42+
seq_printf(seq, "nlifs: %d\n", ident->dev.nlifs);
43+
seq_printf(seq, "nintrs: %d\n", ident->dev.nintrs);
44+
seq_printf(seq, "ndbpgs_per_lif: %d\n", ident->dev.ndbpgs_per_lif);
45+
seq_printf(seq, "intr_coal_mult: %d\n", ident->dev.intr_coal_mult);
46+
seq_printf(seq, "intr_coal_div: %d\n", ident->dev.intr_coal_div);
47+
48+
seq_printf(seq, "max_ucast_filters: %d\n", ident->lif.eth.max_ucast_filters);
49+
seq_printf(seq, "max_mcast_filters: %d\n", ident->lif.eth.max_mcast_filters);
50+
51+
return 0;
52+
}
53+
DEFINE_SHOW_ATTRIBUTE(identity);
54+
55+
void ionic_debugfs_add_ident(struct ionic *ionic)
56+
{
57+
debugfs_create_file("identity", 0400, ionic->dentry,
58+
ionic, &identity_fops) ? 0 : -EOPNOTSUPP;
59+
}
60+
61+
#endif
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */
3+
4+
#ifndef _IONIC_DEBUGFS_H_
5+
#define _IONIC_DEBUGFS_H_
6+
7+
#include <linux/debugfs.h>
8+
9+
#ifdef CONFIG_DEBUG_FS
10+
11+
void ionic_debugfs_create(void);
12+
void ionic_debugfs_destroy(void);
13+
void ionic_debugfs_add_dev(struct ionic *ionic);
14+
void ionic_debugfs_del_dev(struct ionic *ionic);
15+
void ionic_debugfs_add_ident(struct ionic *ionic);
16+
#else
17+
static inline void ionic_debugfs_create(void) { }
18+
static inline void ionic_debugfs_destroy(void) { }
19+
static inline void ionic_debugfs_add_dev(struct ionic *ionic) { }
20+
static inline void ionic_debugfs_del_dev(struct ionic *ionic) { }
21+
static inline void ionic_debugfs_add_ident(struct ionic *ionic) { }
22+
#endif
23+
24+
#endif /* _IONIC_DEBUGFS_H_ */

0 commit comments

Comments
 (0)