Skip to content

Commit 862cd65

Browse files
vburrudavem330
authored andcommitted
octeon_ep: Add driver framework and device initialization
Add driver framework and device setup and initialization for Octeon PCI Endpoint NIC. Add implementation to load module, initilaize, register network device, cleanup and unload module. Signed-off-by: Veerasenareddy Burru <[email protected]> Signed-off-by: Abhijit Ayarekar <[email protected]> Signed-off-by: Satananda Burla <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9271686 commit 862cd65

File tree

20 files changed

+2904
-0
lines changed

20 files changed

+2904
-0
lines changed

Documentation/networking/device_drivers/ethernet/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Contents:
3939
intel/iavf
4040
intel/ice
4141
marvell/octeontx2
42+
marvell/octeon_ep
4243
mellanox/mlx5
4344
microsoft/netvsc
4445
neterion/s2io
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
.. SPDX-License-Identifier: GPL-2.0+
2+
3+
====================================================================
4+
Linux kernel networking driver for Marvell's Octeon PCI Endpoint NIC
5+
====================================================================
6+
7+
Network driver for Marvell's Octeon PCI EndPoint NIC.
8+
Copyright (c) 2020 Marvell International Ltd.
9+
10+
Contents
11+
========
12+
13+
- `Overview`_
14+
- `Supported Devices`_
15+
- `Interface Control`_
16+
17+
Overview
18+
========
19+
This driver implements networking functionality of Marvell's Octeon PCI
20+
EndPoint NIC.
21+
22+
Supported Devices
23+
=================
24+
Currently, this driver support following devices:
25+
* Network controller: Cavium, Inc. Device b200
26+
27+
Interface Control
28+
=================
29+
Network Interface control like changing mtu, link speed, link down/up are
30+
done by writing command to mailbox command queue, a mailbox interface
31+
implemented through a reserved region in BAR4.
32+
This driver writes the commands into the mailbox and the firmware on the
33+
Octeon device processes them. The firmware also sends unsolicited notifications
34+
to driver for events suchs as link change, through notification queue
35+
implemented as part of mailbox interface.

MAINTAINERS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11828,6 +11828,13 @@ S: Supported
1182811828
F: Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt
1182911829
F: drivers/mmc/host/sdhci-xenon*
1183011830

11831+
MARVELL OCTEON ENDPOINT DRIVER
11832+
M: Veerasenareddy Burru <[email protected]>
11833+
M: Abhijit Ayarekar <[email protected]>
11834+
11835+
S: Supported
11836+
F: drivers/net/ethernet/marvell/octeon_ep
11837+
1183111838
MATROX FRAMEBUFFER DRIVER
1183211839
1183311840
S: Orphan

drivers/net/ethernet/marvell/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ config SKY2_DEBUG
177177

178178

179179
source "drivers/net/ethernet/marvell/octeontx2/Kconfig"
180+
source "drivers/net/ethernet/marvell/octeon_ep/Kconfig"
180181
source "drivers/net/ethernet/marvell/prestera/Kconfig"
181182

182183
endif # NET_VENDOR_MARVELL

drivers/net/ethernet/marvell/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ obj-$(CONFIG_MVPP2) += mvpp2/
1111
obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o
1212
obj-$(CONFIG_SKGE) += skge.o
1313
obj-$(CONFIG_SKY2) += sky2.o
14+
obj-y += octeon_ep/
1415
obj-y += octeontx2/
1516
obj-y += prestera/
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
#
3+
# Marvell's Octeon PCI Endpoint NIC Driver Configuration
4+
#
5+
6+
config OCTEON_EP
7+
tristate "Marvell Octeon PCI Endpoint NIC Driver"
8+
depends on 64BIT
9+
depends on PCI
10+
depends on PTP_1588_CLOCK_OPTIONAL
11+
help
12+
This driver supports networking functionality of Marvell's
13+
Octeon PCI Endpoint NIC.
14+
15+
To know the list of devices supported by this driver, refer
16+
documentation in
17+
<file:Documentation/networking/device_drivers/ethernet/marvell/octeon_ep.rst>.
18+
19+
To compile this drivers as a module, choose M here. Name of the
20+
module is octeon_ep.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
#
3+
# Network driver for Marvell's Octeon PCI Endpoint NIC
4+
#
5+
6+
obj-$(CONFIG_OCTEON_EP) += octeon_ep.o
7+
8+
octeon_ep-y := octep_main.o octep_cn9k_pf.o octep_tx.o octep_rx.o \
9+
octep_ctrl_mbox.o octep_ctrl_net.o
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Marvell Octeon EP (EndPoint) Ethernet Driver
3+
*
4+
* Copyright (C) 2020 Marvell.
5+
*
6+
*/
7+
8+
#include <linux/pci.h>
9+
#include <linux/netdevice.h>
10+
#include <linux/etherdevice.h>
11+
12+
#include "octep_config.h"
13+
#include "octep_main.h"
14+
#include "octep_regs_cn9k_pf.h"
15+
16+
/* Names of Hardware non-queue generic interrupts */
17+
static char *cn93_non_ioq_msix_names[] = {
18+
"epf_ire_rint",
19+
"epf_ore_rint",
20+
"epf_vfire_rint0",
21+
"epf_vfire_rint1",
22+
"epf_vfore_rint0",
23+
"epf_vfore_rint1",
24+
"epf_mbox_rint0",
25+
"epf_mbox_rint1",
26+
"epf_oei_rint",
27+
"epf_dma_rint",
28+
"epf_dma_vf_rint0",
29+
"epf_dma_vf_rint1",
30+
"epf_pp_vf_rint0",
31+
"epf_pp_vf_rint1",
32+
"epf_misc_rint",
33+
"epf_rsvd",
34+
};
35+
36+
/* Reset all hardware Tx/Rx queues */
37+
static void octep_reset_io_queues_cn93_pf(struct octep_device *oct)
38+
{
39+
}
40+
41+
/* Initialize windowed addresses to access some hardware registers */
42+
static void octep_setup_pci_window_regs_cn93_pf(struct octep_device *oct)
43+
{
44+
}
45+
46+
/* Configure Hardware mapping: inform hardware which rings belong to PF. */
47+
static void octep_configure_ring_mapping_cn93_pf(struct octep_device *oct)
48+
{
49+
}
50+
51+
/* Initialize configuration limits and initial active config 93xx PF. */
52+
static void octep_init_config_cn93_pf(struct octep_device *oct)
53+
{
54+
struct octep_config *conf = oct->conf;
55+
struct pci_dev *pdev = oct->pdev;
56+
u64 val;
57+
58+
/* Read ring configuration:
59+
* PF ring count, number of VFs and rings per VF supported
60+
*/
61+
val = octep_read_csr64(oct, CN93_SDP_EPF_RINFO);
62+
conf->sriov_cfg.max_rings_per_vf = CN93_SDP_EPF_RINFO_RPVF(val);
63+
conf->sriov_cfg.active_rings_per_vf = conf->sriov_cfg.max_rings_per_vf;
64+
conf->sriov_cfg.max_vfs = CN93_SDP_EPF_RINFO_NVFS(val);
65+
conf->sriov_cfg.active_vfs = conf->sriov_cfg.max_vfs;
66+
conf->sriov_cfg.vf_srn = CN93_SDP_EPF_RINFO_SRN(val);
67+
68+
val = octep_read_csr64(oct, CN93_SDP_MAC_PF_RING_CTL(oct->pcie_port));
69+
conf->pf_ring_cfg.srn = CN93_SDP_MAC_PF_RING_CTL_SRN(val);
70+
conf->pf_ring_cfg.max_io_rings = CN93_SDP_MAC_PF_RING_CTL_RPPF(val);
71+
conf->pf_ring_cfg.active_io_rings = conf->pf_ring_cfg.max_io_rings;
72+
dev_info(&pdev->dev, "pf_srn=%u rpvf=%u nvfs=%u rppf=%u\n",
73+
conf->pf_ring_cfg.srn, conf->sriov_cfg.active_rings_per_vf,
74+
conf->sriov_cfg.active_vfs, conf->pf_ring_cfg.active_io_rings);
75+
76+
conf->iq.num_descs = OCTEP_IQ_MAX_DESCRIPTORS;
77+
conf->iq.instr_type = OCTEP_64BYTE_INSTR;
78+
conf->iq.pkind = 0;
79+
conf->iq.db_min = OCTEP_DB_MIN;
80+
conf->iq.intr_threshold = OCTEP_IQ_INTR_THRESHOLD;
81+
82+
conf->oq.num_descs = OCTEP_OQ_MAX_DESCRIPTORS;
83+
conf->oq.buf_size = OCTEP_OQ_BUF_SIZE;
84+
conf->oq.refill_threshold = OCTEP_OQ_REFILL_THRESHOLD;
85+
conf->oq.oq_intr_pkt = OCTEP_OQ_INTR_PKT_THRESHOLD;
86+
conf->oq.oq_intr_time = OCTEP_OQ_INTR_TIME_THRESHOLD;
87+
88+
conf->msix_cfg.non_ioq_msix = CN93_NUM_NON_IOQ_INTR;
89+
conf->msix_cfg.ioq_msix = conf->pf_ring_cfg.active_io_rings;
90+
conf->msix_cfg.non_ioq_msix_names = cn93_non_ioq_msix_names;
91+
92+
conf->ctrl_mbox_cfg.barmem_addr = (void __iomem *)oct->mmio[2].hw_addr + (0x400000ull * 7);
93+
}
94+
95+
/* Setup registers for a hardware Tx Queue */
96+
static void octep_setup_iq_regs_cn93_pf(struct octep_device *oct, int iq_no)
97+
{
98+
}
99+
100+
/* Setup registers for a hardware Rx Queue */
101+
static void octep_setup_oq_regs_cn93_pf(struct octep_device *oct, int oq_no)
102+
{
103+
}
104+
105+
/* Setup registers for a PF mailbox */
106+
static void octep_setup_mbox_regs_cn93_pf(struct octep_device *oct, int q_no)
107+
{
108+
}
109+
110+
/* Interrupts handler for all non-queue generic interrupts. */
111+
static irqreturn_t octep_non_ioq_intr_handler_cn93_pf(void *dev)
112+
{
113+
return IRQ_HANDLED;
114+
}
115+
116+
/* Tx/Rx queue interrupt handler */
117+
static irqreturn_t octep_ioq_intr_handler_cn93_pf(void *data)
118+
{
119+
return IRQ_HANDLED;
120+
}
121+
122+
/* soft reset of 93xx */
123+
static int octep_soft_reset_cn93_pf(struct octep_device *oct)
124+
{
125+
dev_info(&oct->pdev->dev, "CN93XX: Doing soft reset\n");
126+
127+
octep_write_csr64(oct, CN93_SDP_WIN_WR_MASK_REG, 0xFF);
128+
129+
/* Set core domain reset bit */
130+
OCTEP_PCI_WIN_WRITE(oct, CN93_RST_CORE_DOMAIN_W1S, 1);
131+
/* Wait for 100ms as Octeon resets. */
132+
mdelay(100);
133+
/* clear core domain reset bit */
134+
OCTEP_PCI_WIN_WRITE(oct, CN93_RST_CORE_DOMAIN_W1C, 1);
135+
136+
return 0;
137+
}
138+
139+
/* Re-initialize Octeon hardware registers */
140+
static void octep_reinit_regs_cn93_pf(struct octep_device *oct)
141+
{
142+
}
143+
144+
/* Enable all interrupts */
145+
static void octep_enable_interrupts_cn93_pf(struct octep_device *oct)
146+
{
147+
}
148+
149+
/* Disable all interrupts */
150+
static void octep_disable_interrupts_cn93_pf(struct octep_device *oct)
151+
{
152+
}
153+
154+
/* Get new Octeon Read Index: index of descriptor that Octeon reads next. */
155+
static u32 octep_update_iq_read_index_cn93_pf(struct octep_iq *iq)
156+
{
157+
return 0;
158+
}
159+
160+
/* Enable a hardware Tx Queue */
161+
static void octep_enable_iq_cn93_pf(struct octep_device *oct, int iq_no)
162+
{
163+
}
164+
165+
/* Enable a hardware Rx Queue */
166+
static void octep_enable_oq_cn93_pf(struct octep_device *oct, int oq_no)
167+
{
168+
}
169+
170+
/* Enable all hardware Tx/Rx Queues assined to PF */
171+
static void octep_enable_io_queues_cn93_pf(struct octep_device *oct)
172+
{
173+
}
174+
175+
/* Disable a hardware Tx Queue assined to PF */
176+
static void octep_disable_iq_cn93_pf(struct octep_device *oct, int iq_no)
177+
{
178+
}
179+
180+
/* Disable a hardware Rx Queue assined to PF */
181+
static void octep_disable_oq_cn93_pf(struct octep_device *oct, int oq_no)
182+
{
183+
}
184+
185+
/* Disable all hardware Tx/Rx Queues assined to PF */
186+
static void octep_disable_io_queues_cn93_pf(struct octep_device *oct)
187+
{
188+
}
189+
190+
/* Dump hardware registers (including Tx/Rx queues) for debugging. */
191+
static void octep_dump_registers_cn93_pf(struct octep_device *oct)
192+
{
193+
}
194+
195+
/**
196+
* octep_device_setup_cn93_pf() - Setup Octeon device.
197+
*
198+
* @oct: Octeon device private data structure.
199+
*
200+
* - initialize hardware operations.
201+
* - get target side pcie port number for the device.
202+
* - setup window access to hardware registers.
203+
* - set initial configuration and max limits.
204+
* - setup hardware mapping of rings to the PF device.
205+
*/
206+
void octep_device_setup_cn93_pf(struct octep_device *oct)
207+
{
208+
oct->hw_ops.setup_iq_regs = octep_setup_iq_regs_cn93_pf;
209+
oct->hw_ops.setup_oq_regs = octep_setup_oq_regs_cn93_pf;
210+
oct->hw_ops.setup_mbox_regs = octep_setup_mbox_regs_cn93_pf;
211+
212+
oct->hw_ops.non_ioq_intr_handler = octep_non_ioq_intr_handler_cn93_pf;
213+
oct->hw_ops.ioq_intr_handler = octep_ioq_intr_handler_cn93_pf;
214+
oct->hw_ops.soft_reset = octep_soft_reset_cn93_pf;
215+
oct->hw_ops.reinit_regs = octep_reinit_regs_cn93_pf;
216+
217+
oct->hw_ops.enable_interrupts = octep_enable_interrupts_cn93_pf;
218+
oct->hw_ops.disable_interrupts = octep_disable_interrupts_cn93_pf;
219+
220+
oct->hw_ops.update_iq_read_idx = octep_update_iq_read_index_cn93_pf;
221+
222+
oct->hw_ops.enable_iq = octep_enable_iq_cn93_pf;
223+
oct->hw_ops.enable_oq = octep_enable_oq_cn93_pf;
224+
oct->hw_ops.enable_io_queues = octep_enable_io_queues_cn93_pf;
225+
226+
oct->hw_ops.disable_iq = octep_disable_iq_cn93_pf;
227+
oct->hw_ops.disable_oq = octep_disable_oq_cn93_pf;
228+
oct->hw_ops.disable_io_queues = octep_disable_io_queues_cn93_pf;
229+
oct->hw_ops.reset_io_queues = octep_reset_io_queues_cn93_pf;
230+
231+
oct->hw_ops.dump_registers = octep_dump_registers_cn93_pf;
232+
233+
octep_setup_pci_window_regs_cn93_pf(oct);
234+
235+
oct->pcie_port = octep_read_csr64(oct, CN93_SDP_MAC_NUMBER) & 0xff;
236+
dev_info(&oct->pdev->dev,
237+
"Octeon device using PCIE Port %d\n", oct->pcie_port);
238+
239+
octep_init_config_cn93_pf(oct);
240+
octep_configure_ring_mapping_cn93_pf(oct);
241+
}

0 commit comments

Comments
 (0)