Skip to content

Commit b8fea84

Browse files
Geetha sowjanyadavem330
authored andcommitted
octeontx2-pf: Add support to sync link state between representor and VFs
Implements the below requirement mentioned in the representors documentation. " The representee's link state is controlled through the representor. Setting the representor administratively UP or DOWN should cause carrier ON or OFF at the representee. " This patch enables - Reflecting the link state of representor based on the VF state and link state of VF based on representor. - On VF interface up/down a notification is sent via mbox to representor to update the link state. eg: ip link set eth0 up/down will disable carrier on/off of the corresponding representor(r0p1) interface. - On representor interface up/down will cause the link state update of VF. eg: ip link set r0p1 up/down will disable carrier on/off of the corresponding representee(eth0) interface. Signed-off-by: Harman Kalra <[email protected]> Signed-off-by: Geetha sowjanya <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 940754a commit b8fea84

File tree

8 files changed

+287
-3
lines changed

8 files changed

+287
-3
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ M(SET_VF_PERM, 0x00b, set_vf_perm, set_vf_perm, msg_rsp) \
146146
M(PTP_GET_CAP, 0x00c, ptp_get_cap, msg_req, ptp_get_cap_rsp) \
147147
M(GET_REP_CNT, 0x00d, get_rep_cnt, msg_req, get_rep_cnt_rsp) \
148148
M(ESW_CFG, 0x00e, esw_cfg, esw_cfg_req, msg_rsp) \
149+
M(REP_EVENT_NOTIFY, 0x00f, rep_event_notify, rep_event, msg_rsp) \
149150
/* CGX mbox IDs (range 0x200 - 0x3FF) */ \
150151
M(CGX_START_RXTX, 0x200, cgx_start_rxtx, msg_req, msg_rsp) \
151152
M(CGX_STOP_RXTX, 0x201, cgx_stop_rxtx, msg_req, msg_rsp) \
@@ -383,12 +384,16 @@ M(CPT_INST_LMTST, 0xD00, cpt_inst_lmtst, cpt_inst_lmtst_req, msg_rsp)
383384
#define MBOX_UP_MCS_MESSAGES \
384385
M(MCS_INTR_NOTIFY, 0xE00, mcs_intr_notify, mcs_intr_info, msg_rsp)
385386

387+
#define MBOX_UP_REP_MESSAGES \
388+
M(REP_EVENT_UP_NOTIFY, 0xEF0, rep_event_up_notify, rep_event, msg_rsp) \
389+
386390
enum {
387391
#define M(_name, _id, _1, _2, _3) MBOX_MSG_ ## _name = _id,
388392
MBOX_MESSAGES
389393
MBOX_UP_CGX_MESSAGES
390394
MBOX_UP_CPT_MESSAGES
391395
MBOX_UP_MCS_MESSAGES
396+
MBOX_UP_REP_MESSAGES
392397
#undef M
393398
};
394399

@@ -1572,6 +1577,26 @@ struct esw_cfg_req {
15721577
u64 rsvd;
15731578
};
15741579

1580+
struct rep_evt_data {
1581+
u8 port_state;
1582+
u8 vf_state;
1583+
u16 rx_mode;
1584+
u16 rx_flags;
1585+
u16 mtu;
1586+
u64 rsvd[5];
1587+
};
1588+
1589+
struct rep_event {
1590+
struct mbox_msghdr hdr;
1591+
u16 pcifunc;
1592+
#define RVU_EVENT_PORT_STATE BIT_ULL(0)
1593+
#define RVU_EVENT_PFVF_STATE BIT_ULL(1)
1594+
#define RVU_EVENT_MTU_CHANGE BIT_ULL(2)
1595+
#define RVU_EVENT_RX_MODE_CHANGE BIT_ULL(3)
1596+
u16 event;
1597+
struct rep_evt_data evt_data;
1598+
};
1599+
15751600
struct flow_msg {
15761601
unsigned char dmac[6];
15771602
unsigned char smac[6];

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,11 @@ struct rvu_switch {
513513
u16 start_entry;
514514
};
515515

516+
struct rep_evtq_ent {
517+
struct list_head node;
518+
struct rep_event event;
519+
};
520+
516521
struct rvu {
517522
void __iomem *afreg_base;
518523
void __iomem *pfreg_base;
@@ -599,6 +604,11 @@ struct rvu {
599604
int rep_cnt;
600605
u16 *rep2pfvf_map;
601606
u8 rep_mode;
607+
struct work_struct rep_evt_work;
608+
struct workqueue_struct *rep_evt_wq;
609+
struct list_head rep_evtq_head;
610+
/* Representor event lock */
611+
spinlock_t rep_evtq_lock;
602612
};
603613

604614
static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
@@ -1081,4 +1091,5 @@ void rvu_mcs_exit(struct rvu *rvu);
10811091
int rvu_rep_pf_init(struct rvu *rvu);
10821092
int rvu_rep_install_mcam_rules(struct rvu *rvu);
10831093
void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
1094+
int rvu_rep_notify_pfvf_state(struct rvu *rvu, u16 pcifunc, bool enable);
10841095
#endif /* RVU_H */

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,6 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf,
363363

364364
cgx_set_pkind(rvu_cgx_pdata(cgx_id, rvu), lmac_id, pkind);
365365
rvu_npc_set_pkind(rvu, pkind, pfvf);
366-
367366
break;
368367
case NIX_INTF_TYPE_LBK:
369368
vf = (pcifunc & RVU_PFVF_FUNC_MASK) - 1;
@@ -5180,7 +5179,7 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
51805179
{
51815180
u16 pcifunc = req->hdr.pcifunc;
51825181
struct rvu_pfvf *pfvf;
5183-
int nixlf, err;
5182+
int nixlf, err, pf;
51845183

51855184
err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
51865185
if (err)
@@ -5198,6 +5197,10 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
51985197

51995198
rvu_switch_update_rules(rvu, pcifunc, true);
52005199

5200+
pf = rvu_get_pf(pcifunc);
5201+
if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode)
5202+
rvu_rep_notify_pfvf_state(rvu, pcifunc, true);
5203+
52015204
return rvu_cgx_start_stop_io(rvu, pcifunc, true);
52025205
}
52035206

@@ -5206,7 +5209,7 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
52065209
{
52075210
u16 pcifunc = req->hdr.pcifunc;
52085211
struct rvu_pfvf *pfvf;
5209-
int nixlf, err;
5212+
int nixlf, err, pf;
52105213

52115214
err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
52125215
if (err)
@@ -5227,6 +5230,9 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
52275230
rvu_switch_update_rules(rvu, pcifunc, false);
52285231
rvu_cgx_tx_enable(rvu, pcifunc, true);
52295232

5233+
pf = rvu_get_pf(pcifunc);
5234+
if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode)
5235+
rvu_rep_notify_pfvf_state(rvu, pcifunc, false);
52305236
return 0;
52315237
}
52325238

@@ -5254,6 +5260,9 @@ void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
52545260

52555261
clear_bit(NIXLF_INITIALIZED, &pfvf->flags);
52565262

5263+
if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode)
5264+
rvu_rep_notify_pfvf_state(rvu, pcifunc, false);
5265+
52575266
rvu_cgx_start_stop_io(rvu, pcifunc, false);
52585267

52595268
if (pfvf->sq_ctx) {

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

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,124 @@
1414
#include "rvu.h"
1515
#include "rvu_reg.h"
1616

17+
#define M(_name, _id, _fn_name, _req_type, _rsp_type) \
18+
static struct _req_type __maybe_unused \
19+
*otx2_mbox_alloc_msg_ ## _fn_name(struct rvu *rvu, int devid) \
20+
{ \
21+
struct _req_type *req; \
22+
\
23+
req = (struct _req_type *)otx2_mbox_alloc_msg_rsp( \
24+
&rvu->afpf_wq_info.mbox_up, devid, sizeof(struct _req_type), \
25+
sizeof(struct _rsp_type)); \
26+
if (!req) \
27+
return NULL; \
28+
req->hdr.sig = OTX2_MBOX_REQ_SIG; \
29+
req->hdr.id = _id; \
30+
return req; \
31+
}
32+
33+
MBOX_UP_REP_MESSAGES
34+
#undef M
35+
36+
static int rvu_rep_up_notify(struct rvu *rvu, struct rep_event *event)
37+
{
38+
struct rep_event *msg;
39+
int pf;
40+
41+
pf = rvu_get_pf(event->pcifunc);
42+
43+
mutex_lock(&rvu->mbox_lock);
44+
msg = otx2_mbox_alloc_msg_rep_event_up_notify(rvu, pf);
45+
if (!msg) {
46+
mutex_unlock(&rvu->mbox_lock);
47+
return -ENOMEM;
48+
}
49+
50+
msg->hdr.pcifunc = event->pcifunc;
51+
msg->event = event->event;
52+
53+
memcpy(&msg->evt_data, &event->evt_data, sizeof(struct rep_evt_data));
54+
55+
otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf);
56+
57+
otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf);
58+
59+
mutex_unlock(&rvu->mbox_lock);
60+
return 0;
61+
}
62+
63+
static void rvu_rep_wq_handler(struct work_struct *work)
64+
{
65+
struct rvu *rvu = container_of(work, struct rvu, rep_evt_work);
66+
struct rep_evtq_ent *qentry;
67+
struct rep_event *event;
68+
unsigned long flags;
69+
70+
do {
71+
spin_lock_irqsave(&rvu->rep_evtq_lock, flags);
72+
qentry = list_first_entry_or_null(&rvu->rep_evtq_head,
73+
struct rep_evtq_ent,
74+
node);
75+
if (qentry)
76+
list_del(&qentry->node);
77+
78+
spin_unlock_irqrestore(&rvu->rep_evtq_lock, flags);
79+
if (!qentry)
80+
break; /* nothing more to process */
81+
82+
event = &qentry->event;
83+
84+
rvu_rep_up_notify(rvu, event);
85+
kfree(qentry);
86+
} while (1);
87+
}
88+
89+
int rvu_mbox_handler_rep_event_notify(struct rvu *rvu, struct rep_event *req,
90+
struct msg_rsp *rsp)
91+
{
92+
struct rep_evtq_ent *qentry;
93+
94+
qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC);
95+
if (!qentry)
96+
return -ENOMEM;
97+
98+
qentry->event = *req;
99+
spin_lock(&rvu->rep_evtq_lock);
100+
list_add_tail(&qentry->node, &rvu->rep_evtq_head);
101+
spin_unlock(&rvu->rep_evtq_lock);
102+
queue_work(rvu->rep_evt_wq, &rvu->rep_evt_work);
103+
return 0;
104+
}
105+
106+
int rvu_rep_notify_pfvf_state(struct rvu *rvu, u16 pcifunc, bool enable)
107+
{
108+
struct rep_event *req;
109+
int pf;
110+
111+
if (!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
112+
return 0;
113+
114+
pf = rvu_get_pf(rvu->rep_pcifunc);
115+
116+
mutex_lock(&rvu->mbox_lock);
117+
req = otx2_mbox_alloc_msg_rep_event_up_notify(rvu, pf);
118+
if (!req) {
119+
mutex_unlock(&rvu->mbox_lock);
120+
return -ENOMEM;
121+
}
122+
123+
req->hdr.pcifunc = rvu->rep_pcifunc;
124+
req->event |= RVU_EVENT_PFVF_STATE;
125+
req->pcifunc = pcifunc;
126+
req->evt_data.vf_state = enable;
127+
128+
otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf);
129+
otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf);
130+
131+
mutex_unlock(&rvu->mbox_lock);
132+
return 0;
133+
}
134+
17135
#define RVU_LF_RX_STATS(reg) \
18136
rvu_read64(rvu, blkaddr, NIX_AF_LFX_RX_STATX(nixlf, reg))
19137

@@ -248,6 +366,16 @@ int rvu_rep_install_mcam_rules(struct rvu *rvu)
248366
}
249367
}
250368
}
369+
370+
/* Initialize the wq for handling REP events */
371+
spin_lock_init(&rvu->rep_evtq_lock);
372+
INIT_LIST_HEAD(&rvu->rep_evtq_head);
373+
INIT_WORK(&rvu->rep_evt_work, rvu_rep_wq_handler);
374+
rvu->rep_evt_wq = alloc_workqueue("rep_evt_wq", 0, 0);
375+
if (!rvu->rep_evt_wq) {
376+
dev_err(rvu->dev, "REP workqueue allocation failed\n");
377+
return -ENOMEM;
378+
}
251379
return 0;
252380
}
253381

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ struct otx2_nic {
441441
#define OTX2_FLAG_ADPTV_INT_COAL_ENABLED BIT_ULL(16)
442442
#define OTX2_FLAG_TC_MARK_ENABLED BIT_ULL(17)
443443
#define OTX2_FLAG_REP_MODE_ENABLED BIT_ULL(18)
444+
#define OTX2_FLAG_PORT_UP BIT_ULL(19)
444445
u64 flags;
445446
u64 *cq_op_addr;
446447

@@ -1125,4 +1126,5 @@ u16 otx2_select_queue(struct net_device *netdev, struct sk_buff *skb,
11251126
int otx2_get_txq_by_classid(struct otx2_nic *pfvf, u16 classid);
11261127
void otx2_qos_config_txschq(struct otx2_nic *pfvf);
11271128
void otx2_clean_qos_queues(struct otx2_nic *pfvf);
1129+
int rvu_event_up_notify(struct otx2_nic *pf, struct rep_event *info);
11281130
#endif /* OTX2_COMMON_H */

drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ static void otx2_pfvf_mbox_up_handler(struct work_struct *work)
519519

520520
switch (msg->id) {
521521
case MBOX_MSG_CGX_LINK_EVENT:
522+
case MBOX_MSG_REP_EVENT_UP_NOTIFY:
522523
break;
523524
default:
524525
if (msg->rc)
@@ -832,6 +833,9 @@ static void otx2_handle_link_event(struct otx2_nic *pf)
832833
struct cgx_link_user_info *linfo = &pf->linfo;
833834
struct net_device *netdev = pf->netdev;
834835

836+
if (pf->flags & OTX2_FLAG_PORT_UP)
837+
return;
838+
835839
pr_info("%s NIC Link is %s %d Mbps %s duplex\n", netdev->name,
836840
linfo->link_up ? "UP" : "DOWN", linfo->speed,
837841
linfo->full_duplex ? "Full" : "Half");
@@ -844,6 +848,30 @@ static void otx2_handle_link_event(struct otx2_nic *pf)
844848
}
845849
}
846850

851+
static int otx2_mbox_up_handler_rep_event_up_notify(struct otx2_nic *pf,
852+
struct rep_event *info,
853+
struct msg_rsp *rsp)
854+
{
855+
struct net_device *netdev = pf->netdev;
856+
857+
if (info->event == RVU_EVENT_PORT_STATE) {
858+
if (info->evt_data.port_state) {
859+
pf->flags |= OTX2_FLAG_PORT_UP;
860+
netif_carrier_on(netdev);
861+
netif_tx_start_all_queues(netdev);
862+
} else {
863+
pf->flags &= ~OTX2_FLAG_PORT_UP;
864+
netif_tx_stop_all_queues(netdev);
865+
netif_carrier_off(netdev);
866+
}
867+
return 0;
868+
}
869+
#ifdef CONFIG_RVU_ESWITCH
870+
rvu_event_up_notify(pf, info);
871+
#endif
872+
return 0;
873+
}
874+
847875
int otx2_mbox_up_handler_mcs_intr_notify(struct otx2_nic *pf,
848876
struct mcs_intr_info *event,
849877
struct msg_rsp *rsp)
@@ -913,6 +941,7 @@ static int otx2_process_mbox_msg_up(struct otx2_nic *pf,
913941
}
914942
MBOX_UP_CGX_MESSAGES
915943
MBOX_UP_MCS_MESSAGES
944+
MBOX_UP_REP_MESSAGES
916945
#undef M
917946
break;
918947
default:
@@ -1974,6 +2003,7 @@ int otx2_open(struct net_device *netdev)
19742003
}
19752004

19762005
pf->flags &= ~OTX2_FLAG_INTF_DOWN;
2006+
pf->flags &= ~OTX2_FLAG_PORT_UP;
19772007
/* 'intf_down' may be checked on any cpu */
19782008
smp_wmb();
19792009

0 commit comments

Comments
 (0)