From nobody Fri Sep 12 05:13:01 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8C07DC61DA4 for ; Tue, 14 Feb 2023 05:15:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231462AbjBNFPY (ORCPT ); Tue, 14 Feb 2023 00:15:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46262 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231536AbjBNFOq (ORCPT ); Tue, 14 Feb 2023 00:14:46 -0500 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE6841BFB; Mon, 13 Feb 2023 21:14:41 -0800 (PST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 31E546P4028965; Mon, 13 Feb 2023 21:14:33 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=oFvC+aNq4d9tFrJmZcY1fqyyXqlhlgsyh2fziXWPoi0=; b=g4F9diQcq2+bBR6tuhQwlkJTniHyE2IZ0nGRh7Fg/Ke3Jli1Fe6Y0HPCtpBmyaNBc6HA RmKi6PruitB9Z3c5GGa5u+sLppiF2nVt+XujLBD6Z7MXAiCI5wHzluGvxIzVK/Hsoa3n UAwuVIxLVdy029XAuPMpMmaY+2xekCAgYkdQAJbEwmzlfq3azm1cNGYaTgf3YD/Lx0ro YHTfgXgAz3NV9yHm4mp7Km8jaf9fN+x0Qy2HwkcvStOdIB6cSY5an7oNKPcmL2XPszUg oPzBgM4wddRHO9/VNm7qs9CasYWVqqfgntvJMQ85cX6n+q8ErEVjCHxtNN8XZpn0SrN/ Aw== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3np98upmpf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Feb 2023 21:14:32 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Mon, 13 Feb 2023 21:14:31 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.42 via Frontend Transport; Mon, 13 Feb 2023 21:14:31 -0800 Received: from sburla-PowerEdge-T630.caveonetworks.com (unknown [10.106.27.217]) by maili.marvell.com (Postfix) with ESMTP id B1D313F706F; Mon, 13 Feb 2023 21:14:30 -0800 (PST) From: Veerasenareddy Burru To: , , , , CC: , Veerasenareddy Burru , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Subject: [PATCH net-next v3 4/7] octeon_ep: enhance control mailbox for VF support Date: Mon, 13 Feb 2023 21:14:19 -0800 Message-ID: <20230214051422.13705-5-vburru@marvell.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20230214051422.13705-1-vburru@marvell.com> References: <20230214051422.13705-1-vburru@marvell.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: aIxU_95OsPJ0xDY9K2HLXH01LQGXWkq6 X-Proofpoint-ORIG-GUID: aIxU_95OsPJ0xDY9K2HLXH01LQGXWkq6 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.930,Hydra:6.0.562,FMLib:17.11.170.22 definitions=2023-02-14_03,2023-02-13_01,2023-02-09_01 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Enhance control mailbox protocol to support following - separate command and response queues * command queue to send control commands to firmware. * response queue to receive responses and notifications from firmware. - variable size messages using scatter/gather - VF support * extend control command structure to include vfid. * update APIs to accept VF ID. Signed-off-by: Abhijit Ayarekar Signed-off-by: Veerasenareddy Burru --- v2 -> v3: * no change v1 -> v2: * modified the patch to work with device status "oct->status" removed. .../marvell/octeon_ep/octep_ctrl_mbox.c | 318 +++++++++------- .../marvell/octeon_ep/octep_ctrl_mbox.h | 102 ++--- .../marvell/octeon_ep/octep_ctrl_net.c | 349 ++++++++++++------ .../marvell/octeon_ep/octep_ctrl_net.h | 176 +++++---- .../marvell/octeon_ep/octep_ethtool.c | 7 +- .../ethernet/marvell/octeon_ep/octep_main.c | 80 ++-- 6 files changed, 619 insertions(+), 413 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.c b/dri= vers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.c index 39322e4dd100..cda252fc8f54 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.c @@ -24,41 +24,49 @@ /* Time in msecs to wait for message response */ #define OCTEP_CTRL_MBOX_MSG_WAIT_MS 10 =20 -#define OCTEP_CTRL_MBOX_INFO_MAGIC_NUM_OFFSET(m) (m) -#define OCTEP_CTRL_MBOX_INFO_BARMEM_SZ_OFFSET(m) ((m) + 8) -#define OCTEP_CTRL_MBOX_INFO_HOST_STATUS_OFFSET(m) ((m) + 24) -#define OCTEP_CTRL_MBOX_INFO_FW_STATUS_OFFSET(m) ((m) + 144) - -#define OCTEP_CTRL_MBOX_H2FQ_INFO_OFFSET(m) ((m) + OCTEP_CTRL_MBOX_INFO_S= Z) -#define OCTEP_CTRL_MBOX_H2FQ_PROD_OFFSET(m) (OCTEP_CTRL_MBOX_H2FQ_INFO_OF= FSET(m)) -#define OCTEP_CTRL_MBOX_H2FQ_CONS_OFFSET(m) ((OCTEP_CTRL_MBOX_H2FQ_INFO_O= FFSET(m)) + 4) -#define OCTEP_CTRL_MBOX_H2FQ_ELEM_SZ_OFFSET(m) ((OCTEP_CTRL_MBOX_H2FQ_INF= O_OFFSET(m)) + 8) -#define OCTEP_CTRL_MBOX_H2FQ_ELEM_CNT_OFFSET(m) ((OCTEP_CTRL_MBOX_H2FQ_IN= FO_OFFSET(m)) + 12) - -#define OCTEP_CTRL_MBOX_F2HQ_INFO_OFFSET(m) ((m) + \ - OCTEP_CTRL_MBOX_INFO_SZ + \ - OCTEP_CTRL_MBOX_H2FQ_INFO_SZ) -#define OCTEP_CTRL_MBOX_F2HQ_PROD_OFFSET(m) (OCTEP_CTRL_MBOX_F2HQ_INFO_OF= FSET(m)) -#define OCTEP_CTRL_MBOX_F2HQ_CONS_OFFSET(m) ((OCTEP_CTRL_MBOX_F2HQ_INFO_O= FFSET(m)) + 4) -#define OCTEP_CTRL_MBOX_F2HQ_ELEM_SZ_OFFSET(m) ((OCTEP_CTRL_MBOX_F2HQ_INF= O_OFFSET(m)) + 8) -#define OCTEP_CTRL_MBOX_F2HQ_ELEM_CNT_OFFSET(m) ((OCTEP_CTRL_MBOX_F2HQ_IN= FO_OFFSET(m)) + 12) - -#define OCTEP_CTRL_MBOX_Q_OFFSET(m, i) ((m) + \ - (sizeof(struct octep_ctrl_mbox_msg) * (i))) - -static u32 octep_ctrl_mbox_circq_inc(u32 index, u32 mask) +/* Size of mbox info in bytes */ +#define OCTEP_CTRL_MBOX_INFO_SZ 256 +/* Size of mbox host to fw queue info in bytes */ +#define OCTEP_CTRL_MBOX_H2FQ_INFO_SZ 16 +/* Size of mbox fw to host queue info in bytes */ +#define OCTEP_CTRL_MBOX_F2HQ_INFO_SZ 16 + +#define OCTEP_CTRL_MBOX_TOTAL_INFO_SZ (OCTEP_CTRL_MBOX_INFO_SZ + \ + OCTEP_CTRL_MBOX_H2FQ_INFO_SZ + \ + OCTEP_CTRL_MBOX_F2HQ_INFO_SZ) + +#define OCTEP_CTRL_MBOX_INFO_MAGIC_NUM(m) (m) +#define OCTEP_CTRL_MBOX_INFO_BARMEM_SZ(m) ((m) + 8) +#define OCTEP_CTRL_MBOX_INFO_HOST_STATUS(m) ((m) + 24) +#define OCTEP_CTRL_MBOX_INFO_FW_STATUS(m) ((m) + 144) + +#define OCTEP_CTRL_MBOX_H2FQ_INFO(m) ((m) + OCTEP_CTRL_MBOX_INFO_SZ) +#define OCTEP_CTRL_MBOX_H2FQ_PROD(m) (OCTEP_CTRL_MBOX_H2FQ_INFO(m)) +#define OCTEP_CTRL_MBOX_H2FQ_CONS(m) ((OCTEP_CTRL_MBOX_H2FQ_INFO(m)) + 4) +#define OCTEP_CTRL_MBOX_H2FQ_SZ(m) ((OCTEP_CTRL_MBOX_H2FQ_INFO(m)) + 8) + +#define OCTEP_CTRL_MBOX_F2HQ_INFO(m) ((m) + \ + OCTEP_CTRL_MBOX_INFO_SZ + \ + OCTEP_CTRL_MBOX_H2FQ_INFO_SZ) +#define OCTEP_CTRL_MBOX_F2HQ_PROD(m) (OCTEP_CTRL_MBOX_F2HQ_INFO(m)) +#define OCTEP_CTRL_MBOX_F2HQ_CONS(m) ((OCTEP_CTRL_MBOX_F2HQ_INFO(m)) + 4) +#define OCTEP_CTRL_MBOX_F2HQ_SZ(m) ((OCTEP_CTRL_MBOX_F2HQ_INFO(m)) + 8) + +static const u32 mbox_hdr_sz =3D sizeof(union octep_ctrl_mbox_msg_hdr); + +static u32 octep_ctrl_mbox_circq_inc(u32 index, u32 inc, u32 sz) { - return (index + 1) & mask; + return (index + inc) % sz; } =20 -static u32 octep_ctrl_mbox_circq_space(u32 pi, u32 ci, u32 mask) +static u32 octep_ctrl_mbox_circq_space(u32 pi, u32 ci, u32 sz) { - return mask - ((pi - ci) & mask); + return sz - (abs(pi - ci) % sz); } =20 -static u32 octep_ctrl_mbox_circq_depth(u32 pi, u32 ci, u32 mask) +static u32 octep_ctrl_mbox_circq_depth(u32 pi, u32 ci, u32 sz) { - return ((pi - ci) & mask); + return (abs(pi - ci) % sz); } =20 int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox) @@ -73,172 +81,228 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox) return -EINVAL; } =20 - magic_num =3D readq(OCTEP_CTRL_MBOX_INFO_MAGIC_NUM_OFFSET(mbox->barmem)); + magic_num =3D readq(OCTEP_CTRL_MBOX_INFO_MAGIC_NUM(mbox->barmem)); if (magic_num !=3D OCTEP_CTRL_MBOX_MAGIC_NUMBER) { - pr_info("octep_ctrl_mbox : Invalid magic number %llx\n", magic_num); + pr_info("octep_ctrl_mbox : Invalid magic number %llx\n", + magic_num); return -EINVAL; } =20 - status =3D readq(OCTEP_CTRL_MBOX_INFO_FW_STATUS_OFFSET(mbox->barmem)); + status =3D readq(OCTEP_CTRL_MBOX_INFO_FW_STATUS(mbox->barmem)); if (status !=3D OCTEP_CTRL_MBOX_STATUS_READY) { pr_info("octep_ctrl_mbox : Firmware is not ready.\n"); return -EINVAL; } =20 - mbox->barmem_sz =3D readl(OCTEP_CTRL_MBOX_INFO_BARMEM_SZ_OFFSET(mbox->bar= mem)); + mbox->barmem_sz =3D readl(OCTEP_CTRL_MBOX_INFO_BARMEM_SZ(mbox->barmem)); =20 - writeq(OCTEP_CTRL_MBOX_STATUS_INIT, OCTEP_CTRL_MBOX_INFO_HOST_STATUS_OFFS= ET(mbox->barmem)); + writeq(OCTEP_CTRL_MBOX_STATUS_INIT, + OCTEP_CTRL_MBOX_INFO_HOST_STATUS(mbox->barmem)); =20 - mbox->h2fq.elem_cnt =3D readl(OCTEP_CTRL_MBOX_H2FQ_ELEM_CNT_OFFSET(mbox->= barmem)); - mbox->h2fq.elem_sz =3D readl(OCTEP_CTRL_MBOX_H2FQ_ELEM_SZ_OFFSET(mbox->ba= rmem)); - mbox->h2fq.mask =3D (mbox->h2fq.elem_cnt - 1); - mutex_init(&mbox->h2fq_lock); + mbox->h2fq.sz =3D readl(OCTEP_CTRL_MBOX_H2FQ_SZ(mbox->barmem)); + mbox->h2fq.hw_prod =3D OCTEP_CTRL_MBOX_H2FQ_PROD(mbox->barmem); + mbox->h2fq.hw_cons =3D OCTEP_CTRL_MBOX_H2FQ_CONS(mbox->barmem); + mbox->h2fq.hw_q =3D mbox->barmem + OCTEP_CTRL_MBOX_TOTAL_INFO_SZ; =20 - mbox->f2hq.elem_cnt =3D readl(OCTEP_CTRL_MBOX_F2HQ_ELEM_CNT_OFFSET(mbox->= barmem)); - mbox->f2hq.elem_sz =3D readl(OCTEP_CTRL_MBOX_F2HQ_ELEM_SZ_OFFSET(mbox->ba= rmem)); - mbox->f2hq.mask =3D (mbox->f2hq.elem_cnt - 1); - mutex_init(&mbox->f2hq_lock); - - mbox->h2fq.hw_prod =3D OCTEP_CTRL_MBOX_H2FQ_PROD_OFFSET(mbox->barmem); - mbox->h2fq.hw_cons =3D OCTEP_CTRL_MBOX_H2FQ_CONS_OFFSET(mbox->barmem); - mbox->h2fq.hw_q =3D mbox->barmem + - OCTEP_CTRL_MBOX_INFO_SZ + - OCTEP_CTRL_MBOX_H2FQ_INFO_SZ + - OCTEP_CTRL_MBOX_F2HQ_INFO_SZ; - - mbox->f2hq.hw_prod =3D OCTEP_CTRL_MBOX_F2HQ_PROD_OFFSET(mbox->barmem); - mbox->f2hq.hw_cons =3D OCTEP_CTRL_MBOX_F2HQ_CONS_OFFSET(mbox->barmem); - mbox->f2hq.hw_q =3D mbox->h2fq.hw_q + - ((mbox->h2fq.elem_sz + sizeof(union octep_ctrl_mbox_msg_hdr)) * - mbox->h2fq.elem_cnt); + mbox->f2hq.sz =3D readl(OCTEP_CTRL_MBOX_F2HQ_SZ(mbox->barmem)); + mbox->f2hq.hw_prod =3D OCTEP_CTRL_MBOX_F2HQ_PROD(mbox->barmem); + mbox->f2hq.hw_cons =3D OCTEP_CTRL_MBOX_F2HQ_CONS(mbox->barmem); + mbox->f2hq.hw_q =3D mbox->barmem + + OCTEP_CTRL_MBOX_TOTAL_INFO_SZ + + mbox->h2fq.sz; =20 /* ensure ready state is seen after everything is initialized */ wmb(); - writeq(OCTEP_CTRL_MBOX_STATUS_READY, OCTEP_CTRL_MBOX_INFO_HOST_STATUS_OFF= SET(mbox->barmem)); + writeq(OCTEP_CTRL_MBOX_STATUS_READY, + OCTEP_CTRL_MBOX_INFO_HOST_STATUS(mbox->barmem)); =20 pr_info("Octep ctrl mbox : Init successful.\n"); =20 return 0; } =20 -int octep_ctrl_mbox_send(struct octep_ctrl_mbox *mbox, struct octep_ctrl_m= box_msg *msg) +static int write_mbox_data(struct octep_ctrl_mbox_q *q, u32 *pi, + u32 ci, void *buf, u32 w_sz) +{ + u32 cp_sz; + u8 __iomem *qbuf; + + /* Assumption: Caller has ensured enough write space */ + qbuf =3D (q->hw_q + *pi); + if (*pi < ci) { + /* copy entire w_sz */ + memcpy_toio(qbuf, buf, w_sz); + *pi =3D octep_ctrl_mbox_circq_inc(*pi, w_sz, q->sz); + } else { + /* copy up to end of queue */ + cp_sz =3D min((q->sz - *pi), w_sz); + memcpy_toio(qbuf, buf, cp_sz); + w_sz -=3D cp_sz; + *pi =3D octep_ctrl_mbox_circq_inc(*pi, cp_sz, q->sz); + if (w_sz) { + /* roll over and copy remaining w_sz */ + buf +=3D cp_sz; + qbuf =3D (q->hw_q + *pi); + memcpy_toio(qbuf, buf, w_sz); + *pi =3D octep_ctrl_mbox_circq_inc(*pi, w_sz, q->sz); + } + } + + return 0; +} + +int octep_ctrl_mbox_send(struct octep_ctrl_mbox *mbox, + struct octep_ctrl_mbox_msg *msgs, + int num) { - unsigned long timeout =3D msecs_to_jiffies(OCTEP_CTRL_MBOX_MSG_TIMEOUT_MS= ); - unsigned long period =3D msecs_to_jiffies(OCTEP_CTRL_MBOX_MSG_WAIT_MS); + struct octep_ctrl_mbox_msg_buf *sg; + struct octep_ctrl_mbox_msg *msg; struct octep_ctrl_mbox_q *q; - unsigned long expire; - u64 *mbuf, *word0; - u8 __iomem *qidx; - u16 pi, ci; - int i; + u32 pi, ci, prev_pi, buf_sz, w_sz; + int m, s; =20 - if (!mbox || !msg) + if (!mbox || !msgs) return -EINVAL; =20 + if (readq(OCTEP_CTRL_MBOX_INFO_FW_STATUS(mbox->barmem)) !=3D + OCTEP_CTRL_MBOX_STATUS_READY) + return -EIO; + + mutex_lock(&mbox->h2fq_lock); q =3D &mbox->h2fq; pi =3D readl(q->hw_prod); ci =3D readl(q->hw_cons); + for (m =3D 0; m < num; m++) { + msg =3D &msgs[m]; + if (!msg) + break; =20 - if (!octep_ctrl_mbox_circq_space(pi, ci, q->mask)) - return -ENOMEM; - - qidx =3D OCTEP_CTRL_MBOX_Q_OFFSET(q->hw_q, pi); - mbuf =3D (u64 *)msg->msg; - word0 =3D &msg->hdr.word0; - - mutex_lock(&mbox->h2fq_lock); - for (i =3D 1; i <=3D msg->hdr.sizew; i++) - writeq(*mbuf++, (qidx + (i * 8))); - - writeq(*word0, qidx); + /* not enough space for next message */ + if (octep_ctrl_mbox_circq_space(pi, ci, q->sz) < + (msg->hdr.s.sz + mbox_hdr_sz)) + break; =20 - pi =3D octep_ctrl_mbox_circq_inc(pi, q->mask); + prev_pi =3D pi; + write_mbox_data(q, &pi, ci, (void *)&msg->hdr, mbox_hdr_sz); + buf_sz =3D msg->hdr.s.sz; + for (s =3D 0; ((s < msg->sg_num) && (buf_sz > 0)); s++) { + sg =3D &msg->sg_list[s]; + w_sz =3D (sg->sz <=3D buf_sz) ? sg->sz : buf_sz; + write_mbox_data(q, &pi, ci, sg->msg, w_sz); + buf_sz -=3D w_sz; + } + if (buf_sz) { + /* we did not write entire message */ + pi =3D prev_pi; + break; + } + } writel(pi, q->hw_prod); mutex_unlock(&mbox->h2fq_lock); =20 - /* don't check for notification response */ - if (msg->hdr.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_NOTIFY) - return 0; + return (m) ? m : -EAGAIN; +} =20 - expire =3D jiffies + timeout; - while (true) { - *word0 =3D readq(qidx); - if (msg->hdr.flags =3D=3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP) - break; - schedule_timeout_interruptible(period); - if (signal_pending(current) || time_after(jiffies, expire)) { - pr_info("octep_ctrl_mbox: Timed out\n"); - return -EBUSY; +static int read_mbox_data(struct octep_ctrl_mbox_q *q, u32 pi, + u32 *ci, void *buf, u32 r_sz) +{ + u32 cp_sz; + u8 __iomem *qbuf; + + /* Assumption: Caller has ensured enough read space */ + qbuf =3D (q->hw_q + *ci); + if (*ci < pi) { + /* copy entire r_sz */ + memcpy_fromio(buf, qbuf, r_sz); + *ci =3D octep_ctrl_mbox_circq_inc(*ci, r_sz, q->sz); + } else { + /* copy up to end of queue */ + cp_sz =3D min((q->sz - *ci), r_sz); + memcpy_fromio(buf, qbuf, cp_sz); + r_sz -=3D cp_sz; + *ci =3D octep_ctrl_mbox_circq_inc(*ci, cp_sz, q->sz); + if (r_sz) { + /* roll over and copy remaining r_sz */ + buf +=3D cp_sz; + qbuf =3D (q->hw_q + *ci); + memcpy_fromio(buf, qbuf, r_sz); + *ci =3D octep_ctrl_mbox_circq_inc(*ci, r_sz, q->sz); } } - mbuf =3D (u64 *)msg->msg; - for (i =3D 1; i <=3D msg->hdr.sizew; i++) - *mbuf++ =3D readq(qidx + (i * 8)); =20 return 0; } =20 -int octep_ctrl_mbox_recv(struct octep_ctrl_mbox *mbox, struct octep_ctrl_m= box_msg *msg) +int octep_ctrl_mbox_recv(struct octep_ctrl_mbox *mbox, + struct octep_ctrl_mbox_msg *msgs, + int num) { + struct octep_ctrl_mbox_msg_buf *sg; + struct octep_ctrl_mbox_msg *msg; struct octep_ctrl_mbox_q *q; - u32 count, pi, ci; - u8 __iomem *qidx; - u64 *mbuf; - int i; + u32 pi, ci, q_depth, r_sz, buf_sz, prev_ci; + int s, m; =20 - if (!mbox || !msg) + if (!mbox || !msgs) return -EINVAL; =20 + if (readq(OCTEP_CTRL_MBOX_INFO_FW_STATUS(mbox->barmem)) !=3D + OCTEP_CTRL_MBOX_STATUS_READY) + return -EIO; + + mutex_lock(&mbox->f2hq_lock); q =3D &mbox->f2hq; pi =3D readl(q->hw_prod); ci =3D readl(q->hw_cons); - count =3D octep_ctrl_mbox_circq_depth(pi, ci, q->mask); - if (!count) - return -EAGAIN; - - qidx =3D OCTEP_CTRL_MBOX_Q_OFFSET(q->hw_q, ci); - mbuf =3D (u64 *)msg->msg; - - mutex_lock(&mbox->f2hq_lock); + for (m =3D 0; m < num; m++) { + q_depth =3D octep_ctrl_mbox_circq_depth(pi, ci, q->sz); + if (q_depth < mbox_hdr_sz) + break; =20 - msg->hdr.word0 =3D readq(qidx); - for (i =3D 1; i <=3D msg->hdr.sizew; i++) - *mbuf++ =3D readq(qidx + (i * 8)); + msg =3D &msgs[m]; + if (!msg) + break; =20 - ci =3D octep_ctrl_mbox_circq_inc(ci, q->mask); + prev_ci =3D ci; + read_mbox_data(q, pi, &ci, (void *)&msg->hdr, mbox_hdr_sz); + buf_sz =3D msg->hdr.s.sz; + if (q_depth < (mbox_hdr_sz + buf_sz)) { + ci =3D prev_ci; + break; + } + for (s =3D 0; ((s < msg->sg_num) && (buf_sz > 0)); s++) { + sg =3D &msg->sg_list[s]; + r_sz =3D (sg->sz <=3D buf_sz) ? sg->sz : buf_sz; + read_mbox_data(q, pi, &ci, sg->msg, r_sz); + buf_sz -=3D r_sz; + } + if (buf_sz) { + /* we did not read entire message */ + ci =3D prev_ci; + break; + } + } writel(ci, q->hw_cons); - mutex_unlock(&mbox->f2hq_lock); =20 - if (msg->hdr.flags !=3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ || !mbox->proces= s_req) - return 0; - - mbox->process_req(mbox->user_ctx, msg); - mbuf =3D (u64 *)msg->msg; - for (i =3D 1; i <=3D msg->hdr.sizew; i++) - writeq(*mbuf++, (qidx + (i * 8))); - - writeq(msg->hdr.word0, qidx); - - return 0; + return (m) ? m : -EAGAIN; } =20 int octep_ctrl_mbox_uninit(struct octep_ctrl_mbox *mbox) { if (!mbox) return -EINVAL; + if (!mbox->barmem) + return -EINVAL; =20 - writeq(OCTEP_CTRL_MBOX_STATUS_UNINIT, - OCTEP_CTRL_MBOX_INFO_HOST_STATUS_OFFSET(mbox->barmem)); + writeq(OCTEP_CTRL_MBOX_STATUS_INVALID, + OCTEP_CTRL_MBOX_INFO_HOST_STATUS(mbox->barmem)); /* ensure uninit state is written before uninitialization */ wmb(); =20 mutex_destroy(&mbox->h2fq_lock); mutex_destroy(&mbox->f2hq_lock); =20 - writeq(OCTEP_CTRL_MBOX_STATUS_INVALID, - OCTEP_CTRL_MBOX_INFO_HOST_STATUS_OFFSET(mbox->barmem)); - pr_info("Octep ctrl mbox : Uninit successful.\n"); =20 return 0; diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.h b/dri= vers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.h index 2dc5753cfec6..6ee0345d4436 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.h +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.h @@ -27,50 +27,39 @@ * |-------------------------------------------| * |producer index (4 bytes) | * |consumer index (4 bytes) | - * |element size (4 bytes) | - * |element count (4 bytes) | + * |max element size (4 bytes) | + * |reserved (4 bytes) | * |=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D| * |Fw to Host Queue info (16 bytes) | * |-------------------------------------------| * |producer index (4 bytes) | * |consumer index (4 bytes) | - * |element size (4 bytes) | - * |element count (4 bytes) | + * |max element size (4 bytes) | + * |reserved (4 bytes) | * |=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D| - * |Host to Fw Queue | + * |Host to Fw Queue ((total size-288/2) bytes)| * |-------------------------------------------| - * |((elem_sz + hdr(8 bytes)) * elem_cnt) bytes| + * | | * |=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D| * |=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D| - * |Fw to Host Queue | + * |Fw to Host Queue ((total size-288/2) bytes)| * |-------------------------------------------| - * |((elem_sz + hdr(8 bytes)) * elem_cnt) bytes| + * | | * |=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D| */ =20 #define OCTEP_CTRL_MBOX_MAGIC_NUMBER 0xdeaddeadbeefbeefull =20 -/* Size of mbox info in bytes */ -#define OCTEP_CTRL_MBOX_INFO_SZ 256 -/* Size of mbox host to target queue info in bytes */ -#define OCTEP_CTRL_MBOX_H2FQ_INFO_SZ 16 -/* Size of mbox target to host queue info in bytes */ -#define OCTEP_CTRL_MBOX_F2HQ_INFO_SZ 16 -/* Size of mbox queue in bytes */ -#define OCTEP_CTRL_MBOX_Q_SZ(sz, cnt) (((sz) + 8) * (cnt)) -/* Size of mbox in bytes */ -#define OCTEP_CTRL_MBOX_SZ(hsz, hcnt, fsz, fcnt) (OCTEP_CTRL_MBOX_INFO_SZ = + \ - OCTEP_CTRL_MBOX_H2FQ_INFO_SZ + \ - OCTEP_CTRL_MBOX_F2HQ_INFO_SZ + \ - OCTEP_CTRL_MBOX_Q_SZ(hsz, hcnt) + \ - OCTEP_CTRL_MBOX_Q_SZ(fsz, fcnt)) - /* Valid request message */ #define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ BIT(0) /* Valid response message */ #define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP BIT(1) /* Valid notification, no response required */ #define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_NOTIFY BIT(2) +/* Valid custom message */ +#define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_CUSTOM BIT(3) + +#define OCTEP_CTRL_MBOX_MSG_DESC_MAX 4 =20 enum octep_ctrl_mbox_status { OCTEP_CTRL_MBOX_STATUS_INVALID =3D 0, @@ -81,31 +70,48 @@ enum octep_ctrl_mbox_status { =20 /* mbox message */ union octep_ctrl_mbox_msg_hdr { - u64 word0; + u64 words[2]; struct { + /* must be 0 */ + u16 reserved1:15; + /* vf_idx is valid if 1 */ + u16 is_vf:1; + /* sender vf index 0-(n-1), 0 if (is_vf=3D=3D0) */ + u16 vf_idx; + /* total size of message excluding header */ + u32 sz; /* OCTEP_CTRL_MBOX_MSG_HDR_FLAG_* */ u32 flags; - /* size of message in words excluding header */ - u32 sizew; - }; + /* identifier to match responses */ + u16 msg_id; + u16 reserved2; + } s; +}; + +/* mbox message buffer */ +struct octep_ctrl_mbox_msg_buf { + u32 reserved1; + u16 reserved2; + /* size of buffer */ + u16 sz; + /* pointer to message buffer */ + void *msg; }; =20 /* mbox message */ struct octep_ctrl_mbox_msg { /* mbox transaction header */ union octep_ctrl_mbox_msg_hdr hdr; - /* pointer to message buffer */ - void *msg; + /* number of sg buffer's */ + int sg_num; + /* message buffer's */ + struct octep_ctrl_mbox_msg_buf sg_list[OCTEP_CTRL_MBOX_MSG_DESC_MAX]; }; =20 /* Mbox queue */ struct octep_ctrl_mbox_q { - /* q element size, should be aligned to unsigned long */ - u16 elem_sz; - /* q element count, should be power of 2 */ - u16 elem_cnt; - /* q mask */ - u16 mask; + /* size of queue buffer */ + u32 sz; /* producer address in bar mem */ u8 __iomem *hw_prod; /* consumer address in bar mem */ @@ -115,16 +121,10 @@ struct octep_ctrl_mbox_q { }; =20 struct octep_ctrl_mbox { - /* host driver version */ - u64 version; /* size of bar memory */ u32 barmem_sz; /* pointer to BAR memory */ u8 __iomem *barmem; - /* user context for callback, can be null */ - void *user_ctx; - /* callback handler for processing request, called from octep_ctrl_mbox_r= ecv */ - int (*process_req)(void *user_ctx, struct octep_ctrl_mbox_msg *msg); /* host-to-fw queue */ struct octep_ctrl_mbox_q h2fq; /* fw-to-host queue */ @@ -146,22 +146,32 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox= ); /* Send mbox message. * * @param mbox: non-null pointer to struct octep_ctrl_mbox. + * @param msgs: Array of non-null pointers to struct octep_ctrl_mbox_msg. + * Caller should fill msg.sz and msg.desc.sz for each message. + * @param num: Size of msg array. * - * return value: 0 on success, -errno on failure. + * return value: number of messages sent on success, -errno on failure. */ -int octep_ctrl_mbox_send(struct octep_ctrl_mbox *mbox, struct octep_ctrl_m= box_msg *msg); +int octep_ctrl_mbox_send(struct octep_ctrl_mbox *mbox, + struct octep_ctrl_mbox_msg *msgs, + int num); =20 /* Retrieve mbox message. * * @param mbox: non-null pointer to struct octep_ctrl_mbox. + * @param msgs: Array of non-null pointers to struct octep_ctrl_mbox_msg. + * Caller should fill msg.sz and msg.desc.sz for each message. + * @param num: Size of msg array. * - * return value: 0 on success, -errno on failure. + * return value: number of messages received on success, -errno on failure. */ -int octep_ctrl_mbox_recv(struct octep_ctrl_mbox *mbox, struct octep_ctrl_m= box_msg *msg); +int octep_ctrl_mbox_recv(struct octep_ctrl_mbox *mbox, + struct octep_ctrl_mbox_msg *msgs, + int num); =20 /* Uninitialize control mbox. * - * @param ep: non-null pointer to struct octep_ctrl_mbox. + * @param mbox: non-null pointer to struct octep_ctrl_mbox. * * return value: 0 on success, -errno on failure. */ diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c b/driv= ers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c index 7c00c896ab98..715af1891d0d 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c @@ -8,134 +8,199 @@ #include #include #include +#include =20 #include "octep_config.h" #include "octep_main.h" #include "octep_ctrl_net.h" =20 -int octep_get_link_status(struct octep_device *oct) +static const u32 req_hdr_sz =3D sizeof(union octep_ctrl_net_req_hdr); +static const u32 mtu_sz =3D sizeof(struct octep_ctrl_net_h2f_req_cmd_mtu); +static const u32 mac_sz =3D sizeof(struct octep_ctrl_net_h2f_req_cmd_mac); +static const u32 state_sz =3D sizeof(struct octep_ctrl_net_h2f_req_cmd_sta= te); +static const u32 link_info_sz =3D sizeof(struct octep_ctrl_net_link_info); +static const u32 get_stats_sz =3D sizeof(struct octep_ctrl_net_h2f_req_cmd= _get_stats); +static atomic_t ctrl_net_msg_id; + +static void init_send_req(struct octep_ctrl_mbox_msg *msg, void *buf, + u16 sz, int vfid) { - struct octep_ctrl_net_h2f_req req =3D {}; - struct octep_ctrl_net_h2f_resp *resp; - struct octep_ctrl_mbox_msg msg =3D {}; - int err; + msg->hdr.s.flags =3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; + msg->hdr.s.msg_id =3D atomic_inc_return(&ctrl_net_msg_id) & + GENMASK(sizeof(msg->hdr.s.msg_id) * BITS_PER_BYTE, 0); + msg->hdr.s.sz =3D req_hdr_sz + sz; + msg->sg_num =3D 1; + msg->sg_list[0].msg =3D buf; + msg->sg_list[0].sz =3D msg->hdr.s.sz; + if (vfid !=3D OCTEP_CTRL_NET_INVALID_VFID) { + msg->hdr.s.is_vf =3D 1; + msg->hdr.s.vf_idx =3D vfid; + } +} =20 - req.hdr.cmd =3D OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS; - req.link.cmd =3D OCTEP_CTRL_NET_CMD_GET; +static int send_mbox_req(struct octep_device *oct, + struct octep_ctrl_net_wait_data *d, + bool wait_for_response) +{ + int err, ret; =20 - msg.hdr.flags =3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; - msg.hdr.sizew =3D OCTEP_CTRL_NET_H2F_STATE_REQ_SZW; - msg.msg =3D &req; - err =3D octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg); - if (err) + err =3D octep_ctrl_mbox_send(&oct->ctrl_mbox, &d->msg, 1); + if (err < 0) return err; =20 - resp =3D (struct octep_ctrl_net_h2f_resp *)&req; - return resp->link.state; + if (!wait_for_response) + return 0; + + d->done =3D 0; + INIT_LIST_HEAD(&d->list); + list_add_tail(&d->list, &oct->ctrl_req_wait_list); + ret =3D wait_event_interruptible_timeout(oct->ctrl_req_wait_q, + (d->done !=3D 0), + jiffies + msecs_to_jiffies(500)); + list_del(&d->list); + if (ret =3D=3D 0 || ret =3D=3D 1) + return -EAGAIN; + + /** + * (ret =3D=3D 0) cond =3D false && timeout, return 0 + * (ret < 0) interrupted by signal, return 0 + * (ret =3D=3D 1) cond =3D true && timeout, return 1 + * (ret >=3D 1) cond =3D true && !timeout, return 1 + */ + + if (d->data.resp.hdr.s.reply !=3D OCTEP_CTRL_NET_REPLY_OK) + return -EAGAIN; + + return 0; } =20 -void octep_set_link_status(struct octep_device *oct, bool up) +int octep_ctrl_net_init(struct octep_device *oct) { - struct octep_ctrl_net_h2f_req req =3D {}; - struct octep_ctrl_mbox_msg msg =3D {}; + struct pci_dev *pdev =3D oct->pdev; + struct octep_ctrl_mbox *ctrl_mbox; + int ret; + + init_waitqueue_head(&oct->ctrl_req_wait_q); + INIT_LIST_HEAD(&oct->ctrl_req_wait_list); + + /* Initialize control mbox */ + ctrl_mbox =3D &oct->ctrl_mbox; + ctrl_mbox->barmem =3D CFG_GET_CTRL_MBOX_MEM_ADDR(oct->conf); + ret =3D octep_ctrl_mbox_init(ctrl_mbox); + if (ret) { + dev_err(&pdev->dev, "Failed to initialize control mbox\n"); + return ret; + } + oct->ctrl_mbox_ifstats_offset =3D ctrl_mbox->barmem_sz; + + return 0; +} =20 - req.hdr.cmd =3D OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS; - req.link.cmd =3D OCTEP_CTRL_NET_CMD_SET; - req.link.state =3D (up) ? OCTEP_CTRL_NET_STATE_UP : OCTEP_CTRL_NET_STATE_= DOWN; +int octep_ctrl_net_get_link_status(struct octep_device *oct, int vfid) +{ + struct octep_ctrl_net_wait_data d =3D {0}; + struct octep_ctrl_net_h2f_req *req =3D &d.data.req; + int err; =20 - msg.hdr.flags =3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; - msg.hdr.sizew =3D OCTEP_CTRL_NET_H2F_STATE_REQ_SZW; - msg.msg =3D &req; - octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg); + init_send_req(&d.msg, (void *)req, state_sz, vfid); + req->hdr.s.cmd =3D OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS; + req->link.cmd =3D OCTEP_CTRL_NET_CMD_GET; + err =3D send_mbox_req(oct, &d, true); + if (err < 0) + return err; + + return d.data.resp.link.state; } =20 -void octep_set_rx_state(struct octep_device *oct, bool up) +int octep_ctrl_net_set_link_status(struct octep_device *oct, int vfid, boo= l up, + bool wait_for_response) { - struct octep_ctrl_net_h2f_req req =3D {}; - struct octep_ctrl_mbox_msg msg =3D {}; + struct octep_ctrl_net_wait_data d =3D {0}; + struct octep_ctrl_net_h2f_req *req =3D &d.data.req; =20 - req.hdr.cmd =3D OCTEP_CTRL_NET_H2F_CMD_RX_STATE; - req.link.cmd =3D OCTEP_CTRL_NET_CMD_SET; - req.link.state =3D (up) ? OCTEP_CTRL_NET_STATE_UP : OCTEP_CTRL_NET_STATE_= DOWN; + init_send_req(&d.msg, req, state_sz, vfid); + req->hdr.s.cmd =3D OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS; + req->link.cmd =3D OCTEP_CTRL_NET_CMD_SET; + req->link.state =3D (up) ? OCTEP_CTRL_NET_STATE_UP : + OCTEP_CTRL_NET_STATE_DOWN; =20 - msg.hdr.flags =3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; - msg.hdr.sizew =3D OCTEP_CTRL_NET_H2F_STATE_REQ_SZW; - msg.msg =3D &req; - octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg); + return send_mbox_req(oct, &d, wait_for_response); } =20 -int octep_get_mac_addr(struct octep_device *oct, u8 *addr) +int octep_ctrl_net_set_rx_state(struct octep_device *oct, int vfid, bool u= p, + bool wait_for_response) { - struct octep_ctrl_net_h2f_req req =3D {}; - struct octep_ctrl_net_h2f_resp *resp; - struct octep_ctrl_mbox_msg msg =3D {}; - int err; + struct octep_ctrl_net_wait_data d =3D {0}; + struct octep_ctrl_net_h2f_req *req =3D &d.data.req; + + init_send_req(&d.msg, req, state_sz, vfid); + req->hdr.s.cmd =3D OCTEP_CTRL_NET_H2F_CMD_RX_STATE; + req->link.cmd =3D OCTEP_CTRL_NET_CMD_SET; + req->link.state =3D (up) ? OCTEP_CTRL_NET_STATE_UP : + OCTEP_CTRL_NET_STATE_DOWN; =20 - req.hdr.cmd =3D OCTEP_CTRL_NET_H2F_CMD_MAC; - req.link.cmd =3D OCTEP_CTRL_NET_CMD_GET; + return send_mbox_req(oct, &d, wait_for_response); +} + +int octep_ctrl_net_get_mac_addr(struct octep_device *oct, int vfid, u8 *ad= dr) +{ + struct octep_ctrl_net_wait_data d =3D {0}; + struct octep_ctrl_net_h2f_req *req =3D &d.data.req; + int err; =20 - msg.hdr.flags =3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; - msg.hdr.sizew =3D OCTEP_CTRL_NET_H2F_MAC_REQ_SZW; - msg.msg =3D &req; - err =3D octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg); - if (err) + init_send_req(&d.msg, req, mac_sz, vfid); + req->hdr.s.cmd =3D OCTEP_CTRL_NET_H2F_CMD_MAC; + req->link.cmd =3D OCTEP_CTRL_NET_CMD_GET; + err =3D send_mbox_req(oct, &d, true); + if (err < 0) return err; =20 - resp =3D (struct octep_ctrl_net_h2f_resp *)&req; - memcpy(addr, resp->mac.addr, ETH_ALEN); + memcpy(addr, d.data.resp.mac.addr, ETH_ALEN); =20 - return err; + return 0; } =20 -int octep_set_mac_addr(struct octep_device *oct, u8 *addr) +int octep_ctrl_net_set_mac_addr(struct octep_device *oct, int vfid, u8 *ad= dr, + bool wait_for_response) { - struct octep_ctrl_net_h2f_req req =3D {}; - struct octep_ctrl_mbox_msg msg =3D {}; + struct octep_ctrl_net_wait_data d =3D {0}; + struct octep_ctrl_net_h2f_req *req =3D &d.data.req; =20 - req.hdr.cmd =3D OCTEP_CTRL_NET_H2F_CMD_MAC; - req.mac.cmd =3D OCTEP_CTRL_NET_CMD_SET; - memcpy(&req.mac.addr, addr, ETH_ALEN); + init_send_req(&d.msg, req, mac_sz, vfid); + req->hdr.s.cmd =3D OCTEP_CTRL_NET_H2F_CMD_MAC; + req->mac.cmd =3D OCTEP_CTRL_NET_CMD_SET; + memcpy(&req->mac.addr, addr, ETH_ALEN); =20 - msg.hdr.flags =3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; - msg.hdr.sizew =3D OCTEP_CTRL_NET_H2F_MAC_REQ_SZW; - msg.msg =3D &req; - - return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg); + return send_mbox_req(oct, &d, wait_for_response); } =20 -int octep_set_mtu(struct octep_device *oct, int mtu) +int octep_ctrl_net_set_mtu(struct octep_device *oct, int vfid, int mtu, + bool wait_for_response) { - struct octep_ctrl_net_h2f_req req =3D {}; - struct octep_ctrl_mbox_msg msg =3D {}; - - req.hdr.cmd =3D OCTEP_CTRL_NET_H2F_CMD_MTU; - req.mtu.cmd =3D OCTEP_CTRL_NET_CMD_SET; - req.mtu.val =3D mtu; + struct octep_ctrl_net_wait_data d =3D {0}; + struct octep_ctrl_net_h2f_req *req =3D &d.data.req; =20 - msg.hdr.flags =3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; - msg.hdr.sizew =3D OCTEP_CTRL_NET_H2F_MTU_REQ_SZW; - msg.msg =3D &req; + init_send_req(&d.msg, req, mtu_sz, vfid); + req->hdr.s.cmd =3D OCTEP_CTRL_NET_H2F_CMD_MTU; + req->mtu.cmd =3D OCTEP_CTRL_NET_CMD_SET; + req->mtu.val =3D mtu; =20 - return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg); + return send_mbox_req(oct, &d, wait_for_response); } =20 -int octep_get_if_stats(struct octep_device *oct) +int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid) { void __iomem *iface_rx_stats; void __iomem *iface_tx_stats; - struct octep_ctrl_net_h2f_req req =3D {}; - struct octep_ctrl_mbox_msg msg =3D {}; + struct octep_ctrl_net_wait_data d =3D {0}; + struct octep_ctrl_net_h2f_req *req =3D &d.data.req; int err; =20 - req.hdr.cmd =3D OCTEP_CTRL_NET_H2F_CMD_GET_IF_STATS; - req.mac.cmd =3D OCTEP_CTRL_NET_CMD_GET; - req.get_stats.offset =3D oct->ctrl_mbox_ifstats_offset; - - msg.hdr.flags =3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; - msg.hdr.sizew =3D OCTEP_CTRL_NET_H2F_GET_STATS_REQ_SZW; - msg.msg =3D &req; - err =3D octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg); - if (err) + init_send_req(&d.msg, req, get_stats_sz, vfid); + req->hdr.s.cmd =3D OCTEP_CTRL_NET_H2F_CMD_GET_IF_STATS; + req->get_stats.offset =3D oct->ctrl_mbox_ifstats_offset; + err =3D send_mbox_req(oct, &d, true); + if (err < 0) return err; =20 iface_rx_stats =3D oct->ctrl_mbox.barmem + oct->ctrl_mbox_ifstats_offset; @@ -144,51 +209,115 @@ int octep_get_if_stats(struct octep_device *oct) memcpy_fromio(&oct->iface_rx_stats, iface_rx_stats, sizeof(struct octep_i= face_rx_stats)); memcpy_fromio(&oct->iface_tx_stats, iface_tx_stats, sizeof(struct octep_i= face_tx_stats)); =20 - return err; + return 0; } =20 -int octep_get_link_info(struct octep_device *oct) +int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid) { - struct octep_ctrl_net_h2f_req req =3D {}; + struct octep_ctrl_net_wait_data d =3D {0}; + struct octep_ctrl_net_h2f_req *req =3D &d.data.req; struct octep_ctrl_net_h2f_resp *resp; - struct octep_ctrl_mbox_msg msg =3D {}; int err; =20 - req.hdr.cmd =3D OCTEP_CTRL_NET_H2F_CMD_LINK_INFO; - req.mac.cmd =3D OCTEP_CTRL_NET_CMD_GET; - - msg.hdr.flags =3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; - msg.hdr.sizew =3D OCTEP_CTRL_NET_H2F_LINK_INFO_REQ_SZW; - msg.msg =3D &req; - err =3D octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg); - if (err) + init_send_req(&d.msg, req, link_info_sz, vfid); + req->hdr.s.cmd =3D OCTEP_CTRL_NET_H2F_CMD_LINK_INFO; + req->link_info.cmd =3D OCTEP_CTRL_NET_CMD_GET; + err =3D send_mbox_req(oct, &d, true); + if (err < 0) return err; =20 - resp =3D (struct octep_ctrl_net_h2f_resp *)&req; + resp =3D &d.data.resp; oct->link_info.supported_modes =3D resp->link_info.supported_modes; oct->link_info.advertised_modes =3D resp->link_info.advertised_modes; oct->link_info.autoneg =3D resp->link_info.autoneg; oct->link_info.pause =3D resp->link_info.pause; oct->link_info.speed =3D resp->link_info.speed; =20 - return err; + return 0; } =20 -int octep_set_link_info(struct octep_device *oct, struct octep_iface_link_= info *link_info) +int octep_ctrl_net_set_link_info(struct octep_device *oct, int vfid, + struct octep_iface_link_info *link_info, + bool wait_for_response) { - struct octep_ctrl_net_h2f_req req =3D {}; - struct octep_ctrl_mbox_msg msg =3D {}; + struct octep_ctrl_net_wait_data d =3D {0}; + struct octep_ctrl_net_h2f_req *req =3D &d.data.req; + + init_send_req(&d.msg, req, link_info_sz, vfid); + req->hdr.s.cmd =3D OCTEP_CTRL_NET_H2F_CMD_LINK_INFO; + req->link_info.cmd =3D OCTEP_CTRL_NET_CMD_SET; + req->link_info.info.advertised_modes =3D link_info->advertised_modes; + req->link_info.info.autoneg =3D link_info->autoneg; + req->link_info.info.pause =3D link_info->pause; + req->link_info.info.speed =3D link_info->speed; + + return send_mbox_req(oct, &d, wait_for_response); +} + +static int process_mbox_req(struct octep_device *oct, + struct octep_ctrl_mbox_msg *msg) +{ + return 0; +} + +static int process_mbox_resp(struct octep_device *oct, + struct octep_ctrl_mbox_msg *msg) +{ + struct octep_ctrl_net_wait_data *pos, *n; + + list_for_each_entry_safe(pos, n, &oct->ctrl_req_wait_list, list) { + if (pos->msg.hdr.s.msg_id =3D=3D msg->hdr.s.msg_id) { + memcpy(&pos->data.resp, + msg->sg_list[0].msg, + msg->hdr.s.sz); + pos->done =3D 1; + wake_up_interruptible_all(&oct->ctrl_req_wait_q); + break; + } + } + + return 0; +} + +int octep_ctrl_net_recv_fw_messages(struct octep_device *oct) +{ + static u16 msg_sz =3D sizeof(union octep_ctrl_net_max_data); + union octep_ctrl_net_max_data data =3D {0}; + struct octep_ctrl_mbox_msg msg =3D {0}; + int ret; + + msg.hdr.s.sz =3D msg_sz; + msg.sg_num =3D 1; + msg.sg_list[0].sz =3D msg_sz; + msg.sg_list[0].msg =3D &data; + while (true) { + /* mbox will overwrite msg.hdr.s.sz so initialize it */ + msg.hdr.s.sz =3D msg_sz; + ret =3D octep_ctrl_mbox_recv(&oct->ctrl_mbox, + (struct octep_ctrl_mbox_msg *)&msg, + 1); + if (ret <=3D 0) + break; + + if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ) + process_mbox_req(oct, &msg); + else if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP) + process_mbox_resp(oct, &msg); + } + + return 0; +} + +int octep_ctrl_net_uninit(struct octep_device *oct) +{ + struct octep_ctrl_net_wait_data *pos, *n; + + list_for_each_entry_safe(pos, n, &oct->ctrl_req_wait_list, list) + pos->done =3D 1; =20 - req.hdr.cmd =3D OCTEP_CTRL_NET_H2F_CMD_LINK_INFO; - req.link_info.cmd =3D OCTEP_CTRL_NET_CMD_SET; - req.link_info.info.advertised_modes =3D link_info->advertised_modes; - req.link_info.info.autoneg =3D link_info->autoneg; - req.link_info.info.pause =3D link_info->pause; - req.link_info.info.speed =3D link_info->speed; + wake_up_interruptible_all(&oct->ctrl_req_wait_q); =20 - msg.hdr.flags =3D OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; - msg.hdr.sizew =3D OCTEP_CTRL_NET_H2F_LINK_INFO_REQ_SZW; - msg.msg =3D &req; + octep_ctrl_mbox_uninit(&oct->ctrl_mbox); =20 - return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg); + return 0; } diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h b/driv= ers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h index f23b58381322..c68cdaa1738b 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h @@ -7,6 +7,8 @@ #ifndef __OCTEP_CTRL_NET_H__ #define __OCTEP_CTRL_NET_H__ =20 +#define OCTEP_CTRL_NET_INVALID_VFID (-1) + /* Supported commands */ enum octep_ctrl_net_cmd { OCTEP_CTRL_NET_CMD_GET =3D 0, @@ -45,15 +47,18 @@ enum octep_ctrl_net_f2h_cmd { OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS, }; =20 -struct octep_ctrl_net_req_hdr { - /* sender id */ - u16 sender; - /* receiver id */ - u16 receiver; - /* octep_ctrl_net_h2t_cmd */ - u16 cmd; - /* reserved */ - u16 rsvd0; +union octep_ctrl_net_req_hdr { + u64 words[1]; + struct { + /* sender id */ + u16 sender; + /* receiver id */ + u16 receiver; + /* octep_ctrl_net_h2t_cmd */ + u16 cmd; + /* reserved */ + u16 rsvd0; + } s; }; =20 /* get/set mtu request */ @@ -110,7 +115,7 @@ struct octep_ctrl_net_h2f_req_cmd_link_info { =20 /* Host to fw request data */ struct octep_ctrl_net_h2f_req { - struct octep_ctrl_net_req_hdr hdr; + union octep_ctrl_net_req_hdr hdr; union { struct octep_ctrl_net_h2f_req_cmd_mtu mtu; struct octep_ctrl_net_h2f_req_cmd_mac mac; @@ -121,15 +126,18 @@ struct octep_ctrl_net_h2f_req { }; } __packed; =20 -struct octep_ctrl_net_resp_hdr { - /* sender id */ - u16 sender; - /* receiver id */ - u16 receiver; - /* octep_ctrl_net_h2t_cmd */ - u16 cmd; - /* octep_ctrl_net_reply */ - u16 reply; +union octep_ctrl_net_resp_hdr { + u64 words[1]; + struct { + /* sender id */ + u16 sender; + /* receiver id */ + u16 receiver; + /* octep_ctrl_net_h2t_cmd */ + u16 cmd; + /* octep_ctrl_net_reply */ + u16 reply; + } s; }; =20 /* get mtu response */ @@ -152,7 +160,7 @@ struct octep_ctrl_net_h2f_resp_cmd_state { =20 /* Host to fw response data */ struct octep_ctrl_net_h2f_resp { - struct octep_ctrl_net_resp_hdr hdr; + union octep_ctrl_net_resp_hdr hdr; union { struct octep_ctrl_net_h2f_resp_cmd_mtu mtu; struct octep_ctrl_net_h2f_resp_cmd_mac mac; @@ -170,7 +178,7 @@ struct octep_ctrl_net_f2h_req_cmd_state { =20 /* Fw to host request data */ struct octep_ctrl_net_f2h_req { - struct octep_ctrl_net_req_hdr hdr; + union octep_ctrl_net_req_hdr hdr; union { struct octep_ctrl_net_f2h_req_cmd_state link; }; @@ -178,122 +186,146 @@ struct octep_ctrl_net_f2h_req { =20 /* Fw to host response data */ struct octep_ctrl_net_f2h_resp { - struct octep_ctrl_net_resp_hdr hdr; + union octep_ctrl_net_resp_hdr hdr; }; =20 -/* Size of host to fw octep_ctrl_mbox queue element */ -union octep_ctrl_net_h2f_data_sz { +/* Max data size to be transferred over mbox */ +union octep_ctrl_net_max_data { struct octep_ctrl_net_h2f_req h2f_req; struct octep_ctrl_net_h2f_resp h2f_resp; -}; - -/* Size of fw to host octep_ctrl_mbox queue element */ -union octep_ctrl_net_f2h_data_sz { struct octep_ctrl_net_f2h_req f2h_req; struct octep_ctrl_net_f2h_resp f2h_resp; }; =20 -/* size of host to fw data in words */ -#define OCTEP_CTRL_NET_H2F_DATA_SZW ((sizeof(union octep_ctrl_net_h2f_dat= a_sz)) / \ - (sizeof(unsigned long))) - -/* size of fw to host data in words */ -#define OCTEP_CTRL_NET_F2H_DATA_SZW ((sizeof(union octep_ctrl_net_f2h_dat= a_sz)) / \ - (sizeof(unsigned long))) - -/* size in words of get/set mtu request */ -#define OCTEP_CTRL_NET_H2F_MTU_REQ_SZW 2 -/* size in words of get/set mac request */ -#define OCTEP_CTRL_NET_H2F_MAC_REQ_SZW 2 -/* size in words of get stats request */ -#define OCTEP_CTRL_NET_H2F_GET_STATS_REQ_SZW 2 -/* size in words of get/set state request */ -#define OCTEP_CTRL_NET_H2F_STATE_REQ_SZW 2 -/* size in words of get/set link info request */ -#define OCTEP_CTRL_NET_H2F_LINK_INFO_REQ_SZW 4 - -/* size in words of get mtu response */ -#define OCTEP_CTRL_NET_H2F_GET_MTU_RESP_SZW 2 -/* size in words of set mtu response */ -#define OCTEP_CTRL_NET_H2F_SET_MTU_RESP_SZW 1 -/* size in words of get mac response */ -#define OCTEP_CTRL_NET_H2F_GET_MAC_RESP_SZW 2 -/* size in words of set mac response */ -#define OCTEP_CTRL_NET_H2F_SET_MAC_RESP_SZW 1 -/* size in words of get state request */ -#define OCTEP_CTRL_NET_H2F_GET_STATE_RESP_SZW 2 -/* size in words of set state request */ -#define OCTEP_CTRL_NET_H2F_SET_STATE_RESP_SZW 1 -/* size in words of get link info request */ -#define OCTEP_CTRL_NET_H2F_GET_LINK_INFO_RESP_SZW 4 -/* size in words of set link info request */ -#define OCTEP_CTRL_NET_H2F_SET_LINK_INFO_RESP_SZW 1 +struct octep_ctrl_net_wait_data { + struct list_head list; + int done; + struct octep_ctrl_mbox_msg msg; + union { + struct octep_ctrl_net_h2f_req req; + struct octep_ctrl_net_h2f_resp resp; + } data; +}; + +/** Initialize data for ctrl net. + * + * @param oct: non-null pointer to struct octep_device. + * + * return value: 0 on success, -errno on error. + */ +int octep_ctrl_net_init(struct octep_device *oct); =20 /** Get link status from firmware. * * @param oct: non-null pointer to struct octep_device. + * @param vfid: Index of virtual function. * * return value: link status 0=3Ddown, 1=3Dup. */ -int octep_get_link_status(struct octep_device *oct); +int octep_ctrl_net_get_link_status(struct octep_device *oct, int vfid); =20 /** Set link status in firmware. * * @param oct: non-null pointer to struct octep_device. + * @param vfid: Index of virtual function. * @param up: boolean status. + * @param wait_for_response: poll for response. + * + * return value: 0 on success, -errno on failure */ -void octep_set_link_status(struct octep_device *oct, bool up); +int octep_ctrl_net_set_link_status(struct octep_device *oct, int vfid, boo= l up, + bool wait_for_response); =20 /** Set rx state in firmware. * * @param oct: non-null pointer to struct octep_device. + * @param vfid: Index of virtual function. * @param up: boolean status. + * @param wait_for_response: poll for response. + * + * return value: 0 on success, -errno on failure. */ -void octep_set_rx_state(struct octep_device *oct, bool up); +int octep_ctrl_net_set_rx_state(struct octep_device *oct, int vfid, bool u= p, + bool wait_for_response); =20 /** Get mac address from firmware. * * @param oct: non-null pointer to struct octep_device. + * @param vfid: Index of virtual function. * @param addr: non-null pointer to mac address. * * return value: 0 on success, -errno on failure. */ -int octep_get_mac_addr(struct octep_device *oct, u8 *addr); +int octep_ctrl_net_get_mac_addr(struct octep_device *oct, int vfid, u8 *ad= dr); =20 /** Set mac address in firmware. * * @param oct: non-null pointer to struct octep_device. + * @param vfid: Index of virtual function. * @param addr: non-null pointer to mac address. + * @param wait_for_response: poll for response. + * + * return value: 0 on success, -errno on failure. */ -int octep_set_mac_addr(struct octep_device *oct, u8 *addr); +int octep_ctrl_net_set_mac_addr(struct octep_device *oct, int vfid, u8 *ad= dr, + bool wait_for_response); =20 /** Set mtu in firmware. * * @param oct: non-null pointer to struct octep_device. + * @param vfid: Index of virtual function. * @param mtu: mtu. + * @param wait_for_response: poll for response. + * + * return value: 0 on success, -errno on failure. */ -int octep_set_mtu(struct octep_device *oct, int mtu); +int octep_ctrl_net_set_mtu(struct octep_device *oct, int vfid, int mtu, + bool wait_for_response); =20 /** Get interface statistics from firmware. * * @param oct: non-null pointer to struct octep_device. + * @param vfid: Index of virtual function. * * return value: 0 on success, -errno on failure. */ -int octep_get_if_stats(struct octep_device *oct); +int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid); =20 /** Get link info from firmware. * * @param oct: non-null pointer to struct octep_device. + * @param vfid: Index of virtual function. * * return value: 0 on success, -errno on failure. */ -int octep_get_link_info(struct octep_device *oct); +int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid); =20 /** Set link info in firmware. * * @param oct: non-null pointer to struct octep_device. + * @param vfid: Index of virtual function. + * @param link_info: non-null pointer to struct octep_iface_link_info. + * @param wait_for_response: poll for response. + * + * return value: 0 on success, -errno on failure. + */ +int octep_ctrl_net_set_link_info(struct octep_device *oct, + int vfid, + struct octep_iface_link_info *link_info, + bool wait_for_response); + +/** Poll for firmware messages and process them. + * + * @param oct: non-null pointer to struct octep_device. + */ +int octep_ctrl_net_recv_fw_messages(struct octep_device *oct); + +/** Uninitialize data for ctrl net. + * + * @param oct: non-null pointer to struct octep_device. + * + * return value: 0 on success, -errno on error. */ -int octep_set_link_info(struct octep_device *oct, struct octep_iface_link_= info *link_info); +int octep_ctrl_net_uninit(struct octep_device *oct); =20 #endif /* __OCTEP_CTRL_NET_H__ */ diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c b/drive= rs/net/ethernet/marvell/octeon_ep/octep_ethtool.c index 87ef129b269a..389042b57787 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c @@ -150,7 +150,7 @@ octep_get_ethtool_stats(struct net_device *netdev, rx_packets =3D 0; rx_bytes =3D 0; =20 - octep_get_if_stats(oct); + octep_ctrl_net_get_if_stats(oct, OCTEP_CTRL_NET_INVALID_VFID); iface_tx_stats =3D &oct->iface_tx_stats; iface_rx_stats =3D &oct->iface_rx_stats; =20 @@ -283,7 +283,7 @@ static int octep_get_link_ksettings(struct net_device *= netdev, ethtool_link_ksettings_zero_link_mode(cmd, supported); ethtool_link_ksettings_zero_link_mode(cmd, advertising); =20 - octep_get_link_info(oct); + octep_ctrl_net_get_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID); =20 advertised_modes =3D oct->link_info.advertised_modes; supported_modes =3D oct->link_info.supported_modes; @@ -439,7 +439,8 @@ static int octep_set_link_ksettings(struct net_device *= netdev, link_info_new.speed =3D cmd->base.speed; link_info_new.autoneg =3D autoneg; =20 - err =3D octep_set_link_info(oct, &link_info_new); + err =3D octep_ctrl_net_set_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID, + &link_info_new, true); if (err) return err; =20 diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/= net/ethernet/marvell/octeon_ep/octep_main.c index 565a383f0c68..e3c7932b85ca 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c @@ -508,11 +508,10 @@ static int octep_open(struct net_device *netdev) octep_napi_enable(oct); =20 oct->link_info.admin_up =3D 1; - octep_set_rx_state(oct, true); - - ret =3D octep_get_link_status(oct); - if (!ret) - octep_set_link_status(oct, true); + octep_ctrl_net_set_rx_state(oct, OCTEP_CTRL_NET_INVALID_VFID, true, + false); + octep_ctrl_net_set_link_status(oct, OCTEP_CTRL_NET_INVALID_VFID, true, + false); oct->poll_non_ioq_intr =3D false; =20 /* Enable the input and output queues for this Octeon device */ @@ -523,7 +522,7 @@ static int octep_open(struct net_device *netdev) =20 octep_oq_dbell_init(oct); =20 - ret =3D octep_get_link_status(oct); + ret =3D octep_ctrl_net_get_link_status(oct, OCTEP_CTRL_NET_INVALID_VFID); if (ret > 0) octep_link_up(netdev); =20 @@ -553,14 +552,16 @@ static int octep_stop(struct net_device *netdev) =20 netdev_info(netdev, "Stopping the device ...\n"); =20 + octep_ctrl_net_set_link_status(oct, OCTEP_CTRL_NET_INVALID_VFID, false, + false); + octep_ctrl_net_set_rx_state(oct, OCTEP_CTRL_NET_INVALID_VFID, false, + false); + /* Stop Tx from stack */ netif_tx_stop_all_queues(netdev); netif_carrier_off(netdev); netif_tx_disable(netdev); =20 - octep_set_link_status(oct, false); - octep_set_rx_state(oct, false); - oct->link_info.admin_up =3D 0; oct->link_info.oper_up =3D 0; =20 @@ -762,7 +763,9 @@ static void octep_get_stats64(struct net_device *netdev, struct octep_device *oct =3D netdev_priv(netdev); int q; =20 - octep_get_if_stats(oct); + if (netif_running(netdev)) + octep_ctrl_net_get_if_stats(oct, OCTEP_CTRL_NET_INVALID_VFID); + tx_packets =3D 0; tx_bytes =3D 0; rx_packets =3D 0; @@ -833,7 +836,8 @@ static int octep_set_mac(struct net_device *netdev, voi= d *p) if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; =20 - err =3D octep_set_mac_addr(oct, addr->sa_data); + err =3D octep_ctrl_net_set_mac_addr(oct, OCTEP_CTRL_NET_INVALID_VFID, + addr->sa_data, true); if (err) return err; =20 @@ -853,7 +857,8 @@ static int octep_change_mtu(struct net_device *netdev, = int new_mtu) if (link_info->mtu =3D=3D new_mtu) return 0; =20 - err =3D octep_set_mtu(oct, new_mtu); + err =3D octep_ctrl_net_set_mtu(oct, OCTEP_CTRL_NET_INVALID_VFID, new_mtu, + true); if (!err) { oct->link_info.mtu =3D new_mtu; netdev->mtu =3D new_mtu; @@ -905,34 +910,8 @@ static void octep_ctrl_mbox_task(struct work_struct *w= ork) { struct octep_device *oct =3D container_of(work, struct octep_device, ctrl_mbox_task); - struct net_device *netdev =3D oct->netdev; - struct octep_ctrl_net_f2h_req req =3D {}; - struct octep_ctrl_mbox_msg msg; - int ret =3D 0; - - msg.msg =3D &req; - while (true) { - ret =3D octep_ctrl_mbox_recv(&oct->ctrl_mbox, &msg); - if (ret) - break; - - switch (req.hdr.cmd) { - case OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS: - if (netif_running(netdev)) { - if (req.link.state) { - dev_info(&oct->pdev->dev, "netif_carrier_on\n"); - netif_carrier_on(netdev); - } else { - dev_info(&oct->pdev->dev, "netif_carrier_off\n"); - netif_carrier_off(netdev); - } - } - break; - default: - pr_info("Unknown mbox req : %u\n", req.hdr.cmd); - break; - } - } + + octep_ctrl_net_recv_fw_messages(oct); } =20 static const char *octep_devid_to_str(struct octep_device *oct) @@ -956,7 +935,6 @@ static const char *octep_devid_to_str(struct octep_devi= ce *oct) */ int octep_device_setup(struct octep_device *oct) { - struct octep_ctrl_mbox *ctrl_mbox; struct pci_dev *pdev =3D oct->pdev; int i, ret; =20 @@ -993,18 +971,9 @@ int octep_device_setup(struct octep_device *oct) =20 oct->pkind =3D CFG_GET_IQ_PKIND(oct->conf); =20 - /* Initialize control mbox */ - ctrl_mbox =3D &oct->ctrl_mbox; - ctrl_mbox->barmem =3D CFG_GET_CTRL_MBOX_MEM_ADDR(oct->conf); - ret =3D octep_ctrl_mbox_init(ctrl_mbox); - if (ret) { - dev_err(&pdev->dev, "Failed to initialize control mbox\n"); - goto unsupported_dev; - } - oct->ctrl_mbox_ifstats_offset =3D OCTEP_CTRL_MBOX_SZ(ctrl_mbox->h2fq.elem= _sz, - ctrl_mbox->h2fq.elem_cnt, - ctrl_mbox->f2hq.elem_sz, - ctrl_mbox->f2hq.elem_cnt); + ret =3D octep_ctrl_net_init(oct); + if (ret) + return ret; =20 return 0; =20 @@ -1034,7 +1003,7 @@ static void octep_device_cleanup(struct octep_device = *oct) oct->mbox[i] =3D NULL; } =20 - octep_ctrl_mbox_uninit(&oct->ctrl_mbox); + octep_ctrl_net_uninit(oct); =20 oct->hw_ops.soft_reset(oct); for (i =3D 0; i < OCTEP_MMIO_REGIONS; i++) { @@ -1145,7 +1114,8 @@ static int octep_probe(struct pci_dev *pdev, const st= ruct pci_device_id *ent) netdev->max_mtu =3D OCTEP_MAX_MTU; netdev->mtu =3D OCTEP_DEFAULT_MTU; =20 - err =3D octep_get_mac_addr(octep_dev, octep_dev->mac_addr); + err =3D octep_ctrl_net_get_mac_addr(octep_dev, OCTEP_CTRL_NET_INVALID_VFI= D, + octep_dev->mac_addr); if (err) { dev_err(&pdev->dev, "Failed to get mac address\n"); goto register_dev_err; --=20 2.36.0