Skip to content

Commit 61071a8

Browse files
Linu Cheriandavem330
authored andcommitted
octeontx2-af: Forward CGX link notifications to PFs
Upon receiving notification from firmware the CGX event handler in the AF driver gets the current link info such as status, speed, duplex etc from CGX driver and sends it across to PFs who have registered to receive such notifications. To support above - Mbox messaging support for sending msgs from AF to PF has been added. - Added mbox msgs so that PFs can register/unregister for link events. - Link notifications are sent to PF under two scenarioss. 1. When a asynchronous link change notification is received from firmware with notification flag turned on for that PF. 2. Upon notification turn on request, the current link status is send to the PF. Also added a new mailbox msg using which RVU PF/VF can retrieve their mapped CGX LMAC's current link info. Link info includes status, speed, duplex and lmac type. Signed-off-by: Linu Cherian <[email protected]> Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 96be2e0 commit 61071a8

File tree

6 files changed

+368
-12
lines changed

6 files changed

+368
-12
lines changed

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

Lines changed: 89 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,24 @@ 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+
122148
static u64 mac2u64 (u8 *mac_addr)
123149
{
124150
u64 mac = 0;
@@ -160,6 +186,14 @@ u64 cgx_lmac_addr_get(u8 cgx_id, u8 lmac_id)
160186
}
161187
EXPORT_SYMBOL(cgx_lmac_addr_get);
162188

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+
163197
void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable)
164198
{
165199
struct cgx *cgx = cgx_get_pdata(cgx_id);
@@ -306,36 +340,79 @@ static inline int cgx_fwi_cmd_generic(u64 req, u64 *resp,
306340
return err;
307341
}
308342

343+
static inline void cgx_link_usertable_init(void)
344+
{
345+
cgx_speed_mbps[CGX_LINK_NONE] = 0;
346+
cgx_speed_mbps[CGX_LINK_10M] = 10;
347+
cgx_speed_mbps[CGX_LINK_100M] = 100;
348+
cgx_speed_mbps[CGX_LINK_1G] = 1000;
349+
cgx_speed_mbps[CGX_LINK_2HG] = 2500;
350+
cgx_speed_mbps[CGX_LINK_5G] = 5000;
351+
cgx_speed_mbps[CGX_LINK_10G] = 10000;
352+
cgx_speed_mbps[CGX_LINK_20G] = 20000;
353+
cgx_speed_mbps[CGX_LINK_25G] = 25000;
354+
cgx_speed_mbps[CGX_LINK_40G] = 40000;
355+
cgx_speed_mbps[CGX_LINK_50G] = 50000;
356+
cgx_speed_mbps[CGX_LINK_100G] = 100000;
357+
358+
cgx_lmactype_string[LMAC_MODE_SGMII] = "SGMII";
359+
cgx_lmactype_string[LMAC_MODE_XAUI] = "XAUI";
360+
cgx_lmactype_string[LMAC_MODE_RXAUI] = "RXAUI";
361+
cgx_lmactype_string[LMAC_MODE_10G_R] = "10G_R";
362+
cgx_lmactype_string[LMAC_MODE_40G_R] = "40G_R";
363+
cgx_lmactype_string[LMAC_MODE_QSGMII] = "QSGMII";
364+
cgx_lmactype_string[LMAC_MODE_25G_R] = "25G_R";
365+
cgx_lmactype_string[LMAC_MODE_50G_R] = "50G_R";
366+
cgx_lmactype_string[LMAC_MODE_100G_R] = "100G_R";
367+
cgx_lmactype_string[LMAC_MODE_USXGMII] = "USXGMII";
368+
}
369+
370+
static inline void link_status_user_format(u64 lstat,
371+
struct cgx_link_user_info *linfo,
372+
struct cgx *cgx, u8 lmac_id)
373+
{
374+
char *lmac_string;
375+
376+
linfo->link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat);
377+
linfo->full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat);
378+
linfo->speed = cgx_speed_mbps[FIELD_GET(RESP_LINKSTAT_SPEED, lstat)];
379+
linfo->lmac_type_id = cgx_get_lmac_type(cgx, lmac_id);
380+
lmac_string = cgx_lmactype_string[linfo->lmac_type_id];
381+
strncpy(linfo->lmac_type, lmac_string, LMACTYPE_STR_LEN - 1);
382+
}
383+
309384
/* Hardware event handlers */
310385
static inline void cgx_link_change_handler(u64 lstat,
311386
struct lmac *lmac)
312387
{
388+
struct cgx_link_user_info *linfo;
313389
struct cgx *cgx = lmac->cgx;
314390
struct cgx_link_event event;
315391
struct device *dev;
392+
int err_type;
316393

317394
dev = &cgx->pdev->dev;
318395

319-
event.lstat.link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat);
320-
event.lstat.full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat);
321-
event.lstat.speed = FIELD_GET(RESP_LINKSTAT_SPEED, lstat);
322-
event.lstat.err_type = FIELD_GET(RESP_LINKSTAT_ERRTYPE, lstat);
396+
link_status_user_format(lstat, &event.link_uinfo, cgx, lmac->lmac_id);
397+
err_type = FIELD_GET(RESP_LINKSTAT_ERRTYPE, lstat);
323398

324399
event.cgx_id = cgx->cgx_id;
325400
event.lmac_id = lmac->lmac_id;
326401

402+
/* update the local copy of link status */
403+
lmac->link_info = event.link_uinfo;
404+
linfo = &lmac->link_info;
405+
327406
if (!lmac->event_cb.notify_link_chg) {
328407
dev_dbg(dev, "cgx port %d:%d Link change handler null",
329408
cgx->cgx_id, lmac->lmac_id);
330-
if (event.lstat.err_type != CGX_ERR_NONE) {
409+
if (err_type != CGX_ERR_NONE) {
331410
dev_err(dev, "cgx port %d:%d Link error %d\n",
332-
cgx->cgx_id, lmac->lmac_id,
333-
event.lstat.err_type);
411+
cgx->cgx_id, lmac->lmac_id, err_type);
334412
}
335-
dev_info(dev, "cgx port %d:%d Link status %s, speed %x\n",
413+
dev_info(dev, "cgx port %d:%d Link is %s %d Mbps\n",
336414
cgx->cgx_id, lmac->lmac_id,
337-
event.lstat.link_up ? "UP" : "DOWN",
338-
event.lstat.speed);
415+
linfo->link_up ? "UP" : "DOWN", linfo->speed);
339416
return;
340417
}
341418

@@ -563,6 +640,8 @@ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
563640
list_add(&cgx->cgx_list, &cgx_list);
564641
cgx->cgx_id = cgx_get_cgx_cnt() - 1;
565642

643+
cgx_link_usertable_init();
644+
566645
err = cgx_lmac_init(cgx);
567646
if (err)
568647
goto err_release_lmac;

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

Lines changed: 20 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 */
@@ -28,6 +29,8 @@
2829
#define CMR_EN BIT_ULL(55)
2930
#define DATA_PKT_TX_EN BIT_ULL(53)
3031
#define DATA_PKT_RX_EN BIT_ULL(54)
32+
#define CGX_LMAC_TYPE_SHIFT 40
33+
#define CGX_LMAC_TYPE_MASK 0xF
3134
#define CGXX_CMRX_INT 0x040
3235
#define FW_CGX_INT BIT_ULL(1)
3336
#define CGXX_CMRX_INT_ENA_W1S 0x058
@@ -55,8 +58,22 @@
5558
#define CGX_NVEC 37
5659
#define CGX_LMAC_FWI 0
5760

61+
enum LMAC_TYPE {
62+
LMAC_MODE_SGMII = 0,
63+
LMAC_MODE_XAUI = 1,
64+
LMAC_MODE_RXAUI = 2,
65+
LMAC_MODE_10G_R = 3,
66+
LMAC_MODE_40G_R = 4,
67+
LMAC_MODE_QSGMII = 6,
68+
LMAC_MODE_25G_R = 7,
69+
LMAC_MODE_50G_R = 8,
70+
LMAC_MODE_100G_R = 9,
71+
LMAC_MODE_USXGMII = 10,
72+
LMAC_MODE_MAX,
73+
};
74+
5875
struct cgx_link_event {
59-
struct cgx_lnk_sts lstat;
76+
struct cgx_link_user_info link_uinfo;
6077
u8 cgx_id;
6178
u8 lmac_id;
6279
};
@@ -83,4 +100,6 @@ int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable);
83100
int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr);
84101
u64 cgx_lmac_addr_get(u8 cgx_id, u8 lmac_id);
85102
void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable);
103+
int cgx_get_link_info(void *cgxd, int lmac_id,
104+
struct cgx_link_user_info *linfo);
86105
#endif /* CGX_H */

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,24 @@ M(CGX_MAC_ADDR_GET, 0x204, cgx_mac_addr_set_or_get, \
133133
cgx_mac_addr_set_or_get) \
134134
M(CGX_PROMISC_ENABLE, 0x205, msg_req, msg_rsp) \
135135
M(CGX_PROMISC_DISABLE, 0x206, msg_req, msg_rsp) \
136+
M(CGX_START_LINKEVENTS, 0x207, msg_req, msg_rsp) \
137+
M(CGX_STOP_LINKEVENTS, 0x208, msg_req, msg_rsp) \
138+
M(CGX_GET_LINKINFO, 0x209, msg_req, cgx_link_info_msg) \
136139
/* NPA mbox IDs (range 0x400 - 0x5FF) */ \
137140
/* SSO/SSOW mbox IDs (range 0x600 - 0x7FF) */ \
138141
/* TIM mbox IDs (range 0x800 - 0x9FF) */ \
139142
/* CPT mbox IDs (range 0xA00 - 0xBFF) */ \
140143
/* NPC mbox IDs (range 0x6000 - 0x7FFF) */ \
141144
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */ \
142145

146+
/* Messages initiated by AF (range 0xC00 - 0xDFF) */
147+
#define MBOX_UP_CGX_MESSAGES \
148+
M(CGX_LINK_EVENT, 0xC00, cgx_link_info_msg, msg_rsp)
149+
143150
enum {
144151
#define M(_name, _id, _1, _2) MBOX_MSG_ ## _name = _id,
145152
MBOX_MESSAGES
153+
MBOX_UP_CGX_MESSAGES
146154
#undef M
147155
};
148156

@@ -234,4 +242,18 @@ struct cgx_mac_addr_set_or_get {
234242
struct mbox_msghdr hdr;
235243
u8 mac_addr[ETH_ALEN];
236244
};
245+
246+
struct cgx_link_user_info {
247+
uint64_t link_up:1;
248+
uint64_t full_duplex:1;
249+
uint64_t lmac_type_id:4;
250+
uint64_t speed:20; /* speed in Mbps */
251+
#define LMACTYPE_STR_LEN 16
252+
char lmac_type[LMACTYPE_STR_LEN];
253+
};
254+
255+
struct cgx_link_info_msg {
256+
struct mbox_msghdr hdr;
257+
struct cgx_link_user_info link_info;
258+
};
237259
#endif /* MBOX_H */

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

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,63 @@ static void rvu_mbox_handler(struct work_struct *work)
13161316
otx2_mbox_msg_send(mbox, pf);
13171317
}
13181318

1319+
static void rvu_mbox_up_handler(struct work_struct *work)
1320+
{
1321+
struct rvu_work *mwork = container_of(work, struct rvu_work, work);
1322+
struct rvu *rvu = mwork->rvu;
1323+
struct otx2_mbox_dev *mdev;
1324+
struct mbox_hdr *rsp_hdr;
1325+
struct mbox_msghdr *msg;
1326+
struct otx2_mbox *mbox;
1327+
int offset, id;
1328+
u16 pf;
1329+
1330+
mbox = &rvu->mbox_up;
1331+
pf = mwork - rvu->mbox_wrk_up;
1332+
mdev = &mbox->dev[pf];
1333+
1334+
rsp_hdr = mdev->mbase + mbox->rx_start;
1335+
if (rsp_hdr->num_msgs == 0) {
1336+
dev_warn(rvu->dev, "mbox up handler: num_msgs = 0\n");
1337+
return;
1338+
}
1339+
1340+
offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
1341+
1342+
for (id = 0; id < rsp_hdr->num_msgs; id++) {
1343+
msg = mdev->mbase + offset;
1344+
1345+
if (msg->id >= MBOX_MSG_MAX) {
1346+
dev_err(rvu->dev,
1347+
"Mbox msg with unknown ID 0x%x\n", msg->id);
1348+
goto end;
1349+
}
1350+
1351+
if (msg->sig != OTX2_MBOX_RSP_SIG) {
1352+
dev_err(rvu->dev,
1353+
"Mbox msg with wrong signature %x, ID 0x%x\n",
1354+
msg->sig, msg->id);
1355+
goto end;
1356+
}
1357+
1358+
switch (msg->id) {
1359+
case MBOX_MSG_CGX_LINK_EVENT:
1360+
break;
1361+
default:
1362+
if (msg->rc)
1363+
dev_err(rvu->dev,
1364+
"Mbox msg response has err %d, ID 0x%x\n",
1365+
msg->rc, msg->id);
1366+
break;
1367+
}
1368+
end:
1369+
offset = mbox->rx_start + msg->next_msgoff;
1370+
mdev->msgs_acked++;
1371+
}
1372+
1373+
otx2_mbox_reset(mbox, 0);
1374+
}
1375+
13191376
static int rvu_mbox_init(struct rvu *rvu)
13201377
{
13211378
struct rvu_hwinfo *hw = rvu->hw;
@@ -1337,6 +1394,13 @@ static int rvu_mbox_init(struct rvu *rvu)
13371394
goto exit;
13381395
}
13391396

1397+
rvu->mbox_wrk_up = devm_kcalloc(rvu->dev, hw->total_pfs,
1398+
sizeof(struct rvu_work), GFP_KERNEL);
1399+
if (!rvu->mbox_wrk_up) {
1400+
err = -ENOMEM;
1401+
goto exit;
1402+
}
1403+
13401404
/* Map mbox region shared with PFs */
13411405
bar4_addr = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_PF_BAR4_ADDR);
13421406
/* Mailbox is a reserved memory (in RAM) region shared between
@@ -1355,12 +1419,23 @@ static int rvu_mbox_init(struct rvu *rvu)
13551419
if (err)
13561420
goto exit;
13571421

1422+
err = otx2_mbox_init(&rvu->mbox_up, hwbase, rvu->pdev, rvu->afreg_base,
1423+
MBOX_DIR_AFPF_UP, hw->total_pfs);
1424+
if (err)
1425+
goto exit;
1426+
13581427
for (pf = 0; pf < hw->total_pfs; pf++) {
13591428
mwork = &rvu->mbox_wrk[pf];
13601429
mwork->rvu = rvu;
13611430
INIT_WORK(&mwork->work, rvu_mbox_handler);
13621431
}
13631432

1433+
for (pf = 0; pf < hw->total_pfs; pf++) {
1434+
mwork = &rvu->mbox_wrk_up[pf];
1435+
mwork->rvu = rvu;
1436+
INIT_WORK(&mwork->work, rvu_mbox_up_handler);
1437+
}
1438+
13641439
return 0;
13651440
exit:
13661441
if (hwbase)
@@ -1381,6 +1456,7 @@ static void rvu_mbox_destroy(struct rvu *rvu)
13811456
iounmap((void __iomem *)rvu->mbox.hwbase);
13821457

13831458
otx2_mbox_destroy(&rvu->mbox);
1459+
otx2_mbox_destroy(&rvu->mbox_up);
13841460
}
13851461

13861462
static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
@@ -1407,6 +1483,12 @@ static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
14071483
if (hdr->num_msgs)
14081484
queue_work(rvu->mbox_wq,
14091485
&rvu->mbox_wrk[pf].work);
1486+
mbox = &rvu->mbox_up;
1487+
mdev = &mbox->dev[pf];
1488+
hdr = mdev->mbase + mbox->rx_start;
1489+
if (hdr->num_msgs)
1490+
queue_work(rvu->mbox_wq,
1491+
&rvu->mbox_wrk_up[pf].work);
14101492
}
14111493
}
14121494

0 commit comments

Comments
 (0)