Skip to content

Commit e943d94

Browse files
committed
Merge branch 'octeontx2-af-NPA-and-NIX-blocks-initialization'
Sunil Goutham says: ==================== octeontx2-af: NPA and NIX blocks initialization This patchset is a continuation to earlier submitted patch series to add a new driver for Marvell's OcteonTX2 SOC's Resource virtualization unit (RVU) admin function driver. octeontx2-af: Add RVU Admin Function driver https://www.spinics.net/lists/netdev/msg528272.html This patch series adds logic for the following. - Modified register polling loop to use time_before(jiffies, timeout), as suggested by Arnd Bergmann. - Support to forward interface link status notifications sent by firmware to registered PFs mapped to a CGX::LMAC. - Support to set CGX LMAC in loopback mode, retrieve stats, configure DMAC filters at CGX level etc. - Network pool allocator (NPA) functional block initialization, admin queue support, NPALF aura/pool contexts memory allocation, init and deinit. - Network interface controller (NIX) functional block basic init, admin queue support, NIXLF RQ/CQ/SQ HW contexts memory allocation, init and deinit. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 53e50a6 + 557dd48 commit e943d94

File tree

11 files changed

+3407
-17
lines changed

11 files changed

+3407
-17
lines changed

drivers/net/ethernet/marvell/octeontx2/af/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ obj-$(CONFIG_OCTEONTX2_MBOX) += octeontx2_mbox.o
77
obj-$(CONFIG_OCTEONTX2_AF) += octeontx2_af.o
88

99
octeontx2_mbox-y := mbox.o
10-
octeontx2_af-y := cgx.o rvu.o rvu_cgx.o
10+
octeontx2_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o

drivers/net/ethernet/marvell/octeontx2/af/cgx.c

Lines changed: 234 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
* @wq_cmd_cmplt: waitq to keep the process blocked until cmd completion
3030
* @cmd_lock: Lock to serialize the command interface
3131
* @resp: command response
32+
* @link_info: link related information
3233
* @event_cb: callback for linkchange events
3334
* @cmd_pend: flag set before new command is started
3435
* flag cleared after command response is received
@@ -40,6 +41,7 @@ struct lmac {
4041
wait_queue_head_t wq_cmd_cmplt;
4142
struct mutex cmd_lock;
4243
u64 resp;
44+
struct cgx_link_user_info link_info;
4345
struct cgx_event_cb event_cb;
4446
bool cmd_pend;
4547
struct cgx *cgx;
@@ -58,6 +60,12 @@ struct cgx {
5860

5961
static LIST_HEAD(cgx_list);
6062

63+
/* Convert firmware speed encoding to user format(Mbps) */
64+
static u32 cgx_speed_mbps[CGX_LINK_SPEED_MAX];
65+
66+
/* Convert firmware lmac type encoding to string */
67+
static char *cgx_lmactype_string[LMAC_MODE_MAX];
68+
6169
/* Supported devices */
6270
static const struct pci_device_id cgx_id_table[] = {
6371
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_CGX) },
@@ -119,6 +127,177 @@ void *cgx_get_pdata(int cgx_id)
119127
}
120128
EXPORT_SYMBOL(cgx_get_pdata);
121129

130+
/* Ensure the required lock for event queue(where asynchronous events are
131+
* posted) is acquired before calling this API. Else an asynchronous event(with
132+
* latest link status) can reach the destination before this function returns
133+
* and could make the link status appear wrong.
134+
*/
135+
int cgx_get_link_info(void *cgxd, int lmac_id,
136+
struct cgx_link_user_info *linfo)
137+
{
138+
struct lmac *lmac = lmac_pdata(lmac_id, cgxd);
139+
140+
if (!lmac)
141+
return -ENODEV;
142+
143+
*linfo = lmac->link_info;
144+
return 0;
145+
}
146+
EXPORT_SYMBOL(cgx_get_link_info);
147+
148+
static u64 mac2u64 (u8 *mac_addr)
149+
{
150+
u64 mac = 0;
151+
int index;
152+
153+
for (index = ETH_ALEN - 1; index >= 0; index--)
154+
mac |= ((u64)*mac_addr++) << (8 * index);
155+
return mac;
156+
}
157+
158+
int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr)
159+
{
160+
struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
161+
u64 cfg;
162+
163+
/* copy 6bytes from macaddr */
164+
/* memcpy(&cfg, mac_addr, 6); */
165+
166+
cfg = mac2u64 (mac_addr);
167+
168+
cgx_write(cgx_dev, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (lmac_id * 0x8)),
169+
cfg | CGX_DMAC_CAM_ADDR_ENABLE | ((u64)lmac_id << 49));
170+
171+
cfg = cgx_read(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
172+
cfg |= CGX_DMAC_CTL0_CAM_ENABLE;
173+
cgx_write(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
174+
175+
return 0;
176+
}
177+
EXPORT_SYMBOL(cgx_lmac_addr_set);
178+
179+
u64 cgx_lmac_addr_get(u8 cgx_id, u8 lmac_id)
180+
{
181+
struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
182+
u64 cfg;
183+
184+
cfg = cgx_read(cgx_dev, 0, CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8);
185+
return cfg & CGX_RX_DMAC_ADR_MASK;
186+
}
187+
EXPORT_SYMBOL(cgx_lmac_addr_get);
188+
189+
static inline u8 cgx_get_lmac_type(struct cgx *cgx, int lmac_id)
190+
{
191+
u64 cfg;
192+
193+
cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_CFG);
194+
return (cfg >> CGX_LMAC_TYPE_SHIFT) & CGX_LMAC_TYPE_MASK;
195+
}
196+
197+
/* Configure CGX LMAC in internal loopback mode */
198+
int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable)
199+
{
200+
struct cgx *cgx = cgxd;
201+
u8 lmac_type;
202+
u64 cfg;
203+
204+
if (!cgx || lmac_id >= cgx->lmac_count)
205+
return -ENODEV;
206+
207+
lmac_type = cgx_get_lmac_type(cgx, lmac_id);
208+
if (lmac_type == LMAC_MODE_SGMII || lmac_type == LMAC_MODE_QSGMII) {
209+
cfg = cgx_read(cgx, lmac_id, CGXX_GMP_PCS_MRX_CTL);
210+
if (enable)
211+
cfg |= CGXX_GMP_PCS_MRX_CTL_LBK;
212+
else
213+
cfg &= ~CGXX_GMP_PCS_MRX_CTL_LBK;
214+
cgx_write(cgx, lmac_id, CGXX_GMP_PCS_MRX_CTL, cfg);
215+
} else {
216+
cfg = cgx_read(cgx, lmac_id, CGXX_SPUX_CONTROL1);
217+
if (enable)
218+
cfg |= CGXX_SPUX_CONTROL1_LBK;
219+
else
220+
cfg &= ~CGXX_SPUX_CONTROL1_LBK;
221+
cgx_write(cgx, lmac_id, CGXX_SPUX_CONTROL1, cfg);
222+
}
223+
return 0;
224+
}
225+
EXPORT_SYMBOL(cgx_lmac_internal_loopback);
226+
227+
void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable)
228+
{
229+
struct cgx *cgx = cgx_get_pdata(cgx_id);
230+
u64 cfg = 0;
231+
232+
if (!cgx)
233+
return;
234+
235+
if (enable) {
236+
/* Enable promiscuous mode on LMAC */
237+
cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
238+
cfg &= ~(CGX_DMAC_CAM_ACCEPT | CGX_DMAC_MCAST_MODE);
239+
cfg |= CGX_DMAC_BCAST_MODE;
240+
cgx_write(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
241+
242+
cfg = cgx_read(cgx, 0,
243+
(CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8));
244+
cfg &= ~CGX_DMAC_CAM_ADDR_ENABLE;
245+
cgx_write(cgx, 0,
246+
(CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8), cfg);
247+
} else {
248+
/* Disable promiscuous mode */
249+
cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
250+
cfg |= CGX_DMAC_CAM_ACCEPT | CGX_DMAC_MCAST_MODE;
251+
cgx_write(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
252+
cfg = cgx_read(cgx, 0,
253+
(CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8));
254+
cfg |= CGX_DMAC_CAM_ADDR_ENABLE;
255+
cgx_write(cgx, 0,
256+
(CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8), cfg);
257+
}
258+
}
259+
EXPORT_SYMBOL(cgx_lmac_promisc_config);
260+
261+
int cgx_get_rx_stats(void *cgxd, int lmac_id, int idx, u64 *rx_stat)
262+
{
263+
struct cgx *cgx = cgxd;
264+
265+
if (!cgx || lmac_id >= cgx->lmac_count)
266+
return -ENODEV;
267+
*rx_stat = cgx_read(cgx, lmac_id, CGXX_CMRX_RX_STAT0 + (idx * 8));
268+
return 0;
269+
}
270+
EXPORT_SYMBOL(cgx_get_rx_stats);
271+
272+
int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat)
273+
{
274+
struct cgx *cgx = cgxd;
275+
276+
if (!cgx || lmac_id >= cgx->lmac_count)
277+
return -ENODEV;
278+
*tx_stat = cgx_read(cgx, lmac_id, CGXX_CMRX_TX_STAT0 + (idx * 8));
279+
return 0;
280+
}
281+
EXPORT_SYMBOL(cgx_get_tx_stats);
282+
283+
int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable)
284+
{
285+
struct cgx *cgx = cgxd;
286+
u64 cfg;
287+
288+
if (!cgx || lmac_id >= cgx->lmac_count)
289+
return -ENODEV;
290+
291+
cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_CFG);
292+
if (enable)
293+
cfg |= CMR_EN | DATA_PKT_RX_EN | DATA_PKT_TX_EN;
294+
else
295+
cfg &= ~(CMR_EN | DATA_PKT_RX_EN | DATA_PKT_TX_EN);
296+
cgx_write(cgx, lmac_id, CGXX_CMRX_CFG, cfg);
297+
return 0;
298+
}
299+
EXPORT_SYMBOL(cgx_lmac_rx_tx_enable);
300+
122301
/* CGX Firmware interface low level support */
123302
static int cgx_fwi_cmd_send(u64 req, u64 *resp, struct lmac *lmac)
124303
{
@@ -191,36 +370,79 @@ static inline int cgx_fwi_cmd_generic(u64 req, u64 *resp,
191370
return err;
192371
}
193372

373+
static inline void cgx_link_usertable_init(void)
374+
{
375+
cgx_speed_mbps[CGX_LINK_NONE] = 0;
376+
cgx_speed_mbps[CGX_LINK_10M] = 10;
377+
cgx_speed_mbps[CGX_LINK_100M] = 100;
378+
cgx_speed_mbps[CGX_LINK_1G] = 1000;
379+
cgx_speed_mbps[CGX_LINK_2HG] = 2500;
380+
cgx_speed_mbps[CGX_LINK_5G] = 5000;
381+
cgx_speed_mbps[CGX_LINK_10G] = 10000;
382+
cgx_speed_mbps[CGX_LINK_20G] = 20000;
383+
cgx_speed_mbps[CGX_LINK_25G] = 25000;
384+
cgx_speed_mbps[CGX_LINK_40G] = 40000;
385+
cgx_speed_mbps[CGX_LINK_50G] = 50000;
386+
cgx_speed_mbps[CGX_LINK_100G] = 100000;
387+
388+
cgx_lmactype_string[LMAC_MODE_SGMII] = "SGMII";
389+
cgx_lmactype_string[LMAC_MODE_XAUI] = "XAUI";
390+
cgx_lmactype_string[LMAC_MODE_RXAUI] = "RXAUI";
391+
cgx_lmactype_string[LMAC_MODE_10G_R] = "10G_R";
392+
cgx_lmactype_string[LMAC_MODE_40G_R] = "40G_R";
393+
cgx_lmactype_string[LMAC_MODE_QSGMII] = "QSGMII";
394+
cgx_lmactype_string[LMAC_MODE_25G_R] = "25G_R";
395+
cgx_lmactype_string[LMAC_MODE_50G_R] = "50G_R";
396+
cgx_lmactype_string[LMAC_MODE_100G_R] = "100G_R";
397+
cgx_lmactype_string[LMAC_MODE_USXGMII] = "USXGMII";
398+
}
399+
400+
static inline void link_status_user_format(u64 lstat,
401+
struct cgx_link_user_info *linfo,
402+
struct cgx *cgx, u8 lmac_id)
403+
{
404+
char *lmac_string;
405+
406+
linfo->link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat);
407+
linfo->full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat);
408+
linfo->speed = cgx_speed_mbps[FIELD_GET(RESP_LINKSTAT_SPEED, lstat)];
409+
linfo->lmac_type_id = cgx_get_lmac_type(cgx, lmac_id);
410+
lmac_string = cgx_lmactype_string[linfo->lmac_type_id];
411+
strncpy(linfo->lmac_type, lmac_string, LMACTYPE_STR_LEN - 1);
412+
}
413+
194414
/* Hardware event handlers */
195415
static inline void cgx_link_change_handler(u64 lstat,
196416
struct lmac *lmac)
197417
{
418+
struct cgx_link_user_info *linfo;
198419
struct cgx *cgx = lmac->cgx;
199420
struct cgx_link_event event;
200421
struct device *dev;
422+
int err_type;
201423

202424
dev = &cgx->pdev->dev;
203425

204-
event.lstat.link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat);
205-
event.lstat.full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat);
206-
event.lstat.speed = FIELD_GET(RESP_LINKSTAT_SPEED, lstat);
207-
event.lstat.err_type = FIELD_GET(RESP_LINKSTAT_ERRTYPE, lstat);
426+
link_status_user_format(lstat, &event.link_uinfo, cgx, lmac->lmac_id);
427+
err_type = FIELD_GET(RESP_LINKSTAT_ERRTYPE, lstat);
208428

209429
event.cgx_id = cgx->cgx_id;
210430
event.lmac_id = lmac->lmac_id;
211431

432+
/* update the local copy of link status */
433+
lmac->link_info = event.link_uinfo;
434+
linfo = &lmac->link_info;
435+
212436
if (!lmac->event_cb.notify_link_chg) {
213437
dev_dbg(dev, "cgx port %d:%d Link change handler null",
214438
cgx->cgx_id, lmac->lmac_id);
215-
if (event.lstat.err_type != CGX_ERR_NONE) {
439+
if (err_type != CGX_ERR_NONE) {
216440
dev_err(dev, "cgx port %d:%d Link error %d\n",
217-
cgx->cgx_id, lmac->lmac_id,
218-
event.lstat.err_type);
441+
cgx->cgx_id, lmac->lmac_id, err_type);
219442
}
220-
dev_info(dev, "cgx port %d:%d Link status %s, speed %x\n",
443+
dev_info(dev, "cgx port %d:%d Link is %s %d Mbps\n",
221444
cgx->cgx_id, lmac->lmac_id,
222-
event.lstat.link_up ? "UP" : "DOWN",
223-
event.lstat.speed);
445+
linfo->link_up ? "UP" : "DOWN", linfo->speed);
224446
return;
225447
}
226448

@@ -448,6 +670,8 @@ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
448670
list_add(&cgx->cgx_list, &cgx_list);
449671
cgx->cgx_id = cgx_get_cgx_cnt() - 1;
450672

673+
cgx_link_usertable_init();
674+
451675
err = cgx_lmac_init(cgx);
452676
if (err)
453677
goto err_release_lmac;

drivers/net/ethernet/marvell/octeontx2/af/cgx.h

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#ifndef CGX_H
1212
#define CGX_H
1313

14+
#include "mbox.h"
1415
#include "cgx_fw_if.h"
1516

1617
/* PCI device IDs */
@@ -24,14 +25,35 @@
2425
#define CGX_OFFSET(x) ((x) * MAX_LMAC_PER_CGX)
2526

2627
/* Registers */
28+
#define CGXX_CMRX_CFG 0x00
29+
#define CMR_EN BIT_ULL(55)
30+
#define DATA_PKT_TX_EN BIT_ULL(53)
31+
#define DATA_PKT_RX_EN BIT_ULL(54)
32+
#define CGX_LMAC_TYPE_SHIFT 40
33+
#define CGX_LMAC_TYPE_MASK 0xF
2734
#define CGXX_CMRX_INT 0x040
2835
#define FW_CGX_INT BIT_ULL(1)
2936
#define CGXX_CMRX_INT_ENA_W1S 0x058
3037
#define CGXX_CMRX_RX_ID_MAP 0x060
38+
#define CGXX_CMRX_RX_STAT0 0x070
3139
#define CGXX_CMRX_RX_LMACS 0x128
40+
#define CGXX_CMRX_RX_DMAC_CTL0 0x1F8
41+
#define CGX_DMAC_CTL0_CAM_ENABLE BIT_ULL(3)
42+
#define CGX_DMAC_CAM_ACCEPT BIT_ULL(3)
43+
#define CGX_DMAC_MCAST_MODE BIT_ULL(1)
44+
#define CGX_DMAC_BCAST_MODE BIT_ULL(0)
45+
#define CGXX_CMRX_RX_DMAC_CAM0 0x200
46+
#define CGX_DMAC_CAM_ADDR_ENABLE BIT_ULL(48)
47+
#define CGXX_CMRX_RX_DMAC_CAM1 0x400
48+
#define CGX_RX_DMAC_ADR_MASK GENMASK_ULL(47, 0)
49+
#define CGXX_CMRX_TX_STAT0 0x700
3250
#define CGXX_SCRATCH0_REG 0x1050
3351
#define CGXX_SCRATCH1_REG 0x1058
3452
#define CGX_CONST 0x2000
53+
#define CGXX_SPUX_CONTROL1 0x10000
54+
#define CGXX_SPUX_CONTROL1_LBK BIT_ULL(14)
55+
#define CGXX_GMP_PCS_MRX_CTL 0x30000
56+
#define CGXX_GMP_PCS_MRX_CTL_LBK BIT_ULL(14)
3557

3658
#define CGX_COMMAND_REG CGXX_SCRATCH1_REG
3759
#define CGX_EVENT_REG CGXX_SCRATCH0_REG
@@ -40,8 +62,22 @@
4062
#define CGX_NVEC 37
4163
#define CGX_LMAC_FWI 0
4264

65+
enum LMAC_TYPE {
66+
LMAC_MODE_SGMII = 0,
67+
LMAC_MODE_XAUI = 1,
68+
LMAC_MODE_RXAUI = 2,
69+
LMAC_MODE_10G_R = 3,
70+
LMAC_MODE_40G_R = 4,
71+
LMAC_MODE_QSGMII = 6,
72+
LMAC_MODE_25G_R = 7,
73+
LMAC_MODE_50G_R = 8,
74+
LMAC_MODE_100G_R = 9,
75+
LMAC_MODE_USXGMII = 10,
76+
LMAC_MODE_MAX,
77+
};
78+
4379
struct cgx_link_event {
44-
struct cgx_lnk_sts lstat;
80+
struct cgx_link_user_info link_uinfo;
4581
u8 cgx_id;
4682
u8 lmac_id;
4783
};
@@ -62,4 +98,13 @@ int cgx_get_cgx_cnt(void);
6298
int cgx_get_lmac_cnt(void *cgxd);
6399
void *cgx_get_pdata(int cgx_id);
64100
int cgx_lmac_evh_register(struct cgx_event_cb *cb, void *cgxd, int lmac_id);
101+
int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat);
102+
int cgx_get_rx_stats(void *cgxd, int lmac_id, int idx, u64 *rx_stat);
103+
int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable);
104+
int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr);
105+
u64 cgx_lmac_addr_get(u8 cgx_id, u8 lmac_id);
106+
void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable);
107+
int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable);
108+
int cgx_get_link_info(void *cgxd, int lmac_id,
109+
struct cgx_link_user_info *linfo);
65110
#endif /* CGX_H */

0 commit comments

Comments
 (0)