Skip to content

Commit 29264a3

Browse files
Mengyuan Loukuba-moo
authored andcommitted
net: libwx: Add mailbox api for wangxun pf drivers
Implements the mailbox interfaces for wangxun pf drivers ngbe and txgbe. Signed-off-by: Mengyuan Lou <mengyuanlou@net-swift.com> Link: https://patch.msgid.link/70017BD4D67614A4+20250408091556.9640-2-mengyuanlou@net-swift.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 6a07e3a commit 29264a3

File tree

4 files changed

+217
-1
lines changed

4 files changed

+217
-1
lines changed

drivers/net/ethernet/wangxun/libwx/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
obj-$(CONFIG_LIBWX) += libwx.o
66

7-
libwx-objs := wx_hw.o wx_lib.o wx_ethtool.o wx_ptp.o
7+
libwx-objs := wx_hw.o wx_lib.o wx_ethtool.o wx_ptp.o wx_mbx.o
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */
3+
4+
#include <linux/pci.h>
5+
#include "wx_type.h"
6+
#include "wx_mbx.h"
7+
8+
/**
9+
* wx_obtain_mbx_lock_pf - obtain mailbox lock
10+
* @wx: pointer to the HW structure
11+
* @vf: the VF index
12+
*
13+
* Return: return 0 on success and -EBUSY on failure
14+
**/
15+
static int wx_obtain_mbx_lock_pf(struct wx *wx, u16 vf)
16+
{
17+
int count = 5;
18+
u32 mailbox;
19+
20+
while (count--) {
21+
/* Take ownership of the buffer */
22+
wr32(wx, WX_PXMAILBOX(vf), WX_PXMAILBOX_PFU);
23+
24+
/* reserve mailbox for vf use */
25+
mailbox = rd32(wx, WX_PXMAILBOX(vf));
26+
if (mailbox & WX_PXMAILBOX_PFU)
27+
return 0;
28+
else if (count)
29+
udelay(10);
30+
}
31+
wx_err(wx, "Failed to obtain mailbox lock for PF%d", vf);
32+
33+
return -EBUSY;
34+
}
35+
36+
static int wx_check_for_bit_pf(struct wx *wx, u32 mask, int index)
37+
{
38+
u32 mbvficr = rd32(wx, WX_MBVFICR(index));
39+
40+
if (!(mbvficr & mask))
41+
return -EBUSY;
42+
wr32(wx, WX_MBVFICR(index), mask);
43+
44+
return 0;
45+
}
46+
47+
/**
48+
* wx_check_for_ack_pf - checks to see if the VF has acked
49+
* @wx: pointer to the HW structure
50+
* @vf: the VF index
51+
*
52+
* Return: return 0 if the VF has set the status bit or else -EBUSY
53+
**/
54+
int wx_check_for_ack_pf(struct wx *wx, u16 vf)
55+
{
56+
u32 index = vf / 16, vf_bit = vf % 16;
57+
58+
return wx_check_for_bit_pf(wx,
59+
FIELD_PREP(WX_MBVFICR_VFACK_MASK,
60+
BIT(vf_bit)),
61+
index);
62+
}
63+
64+
/**
65+
* wx_check_for_msg_pf - checks to see if the VF has sent mail
66+
* @wx: pointer to the HW structure
67+
* @vf: the VF index
68+
*
69+
* Return: return 0 if the VF has got req bit or else -EBUSY
70+
**/
71+
int wx_check_for_msg_pf(struct wx *wx, u16 vf)
72+
{
73+
u32 index = vf / 16, vf_bit = vf % 16;
74+
75+
return wx_check_for_bit_pf(wx,
76+
FIELD_PREP(WX_MBVFICR_VFREQ_MASK,
77+
BIT(vf_bit)),
78+
index);
79+
}
80+
81+
/**
82+
* wx_write_mbx_pf - Places a message in the mailbox
83+
* @wx: pointer to the HW structure
84+
* @msg: The message buffer
85+
* @size: Length of buffer
86+
* @vf: the VF index
87+
*
88+
* Return: return 0 on success and -EINVAL/-EBUSY on failure
89+
**/
90+
int wx_write_mbx_pf(struct wx *wx, u32 *msg, u16 size, u16 vf)
91+
{
92+
struct wx_mbx_info *mbx = &wx->mbx;
93+
int ret, i;
94+
95+
/* mbx->size is up to 15 */
96+
if (size > mbx->size) {
97+
wx_err(wx, "Invalid mailbox message size %d", size);
98+
return -EINVAL;
99+
}
100+
101+
/* lock the mailbox to prevent pf/vf race condition */
102+
ret = wx_obtain_mbx_lock_pf(wx, vf);
103+
if (ret)
104+
return ret;
105+
106+
/* flush msg and acks as we are overwriting the message buffer */
107+
wx_check_for_msg_pf(wx, vf);
108+
wx_check_for_ack_pf(wx, vf);
109+
110+
/* copy the caller specified message to the mailbox memory buffer */
111+
for (i = 0; i < size; i++)
112+
wr32a(wx, WX_PXMBMEM(vf), i, msg[i]);
113+
114+
/* Interrupt VF to tell it a message has been sent and release buffer */
115+
/* set mirrored mailbox flags */
116+
wr32a(wx, WX_PXMBMEM(vf), WX_VXMAILBOX_SIZE, WX_PXMAILBOX_STS);
117+
wr32(wx, WX_PXMAILBOX(vf), WX_PXMAILBOX_STS);
118+
119+
return 0;
120+
}
121+
122+
/**
123+
* wx_read_mbx_pf - Read a message from the mailbox
124+
* @wx: pointer to the HW structure
125+
* @msg: The message buffer
126+
* @size: Length of buffer
127+
* @vf: the VF index
128+
*
129+
* Return: return 0 on success and -EBUSY on failure
130+
**/
131+
int wx_read_mbx_pf(struct wx *wx, u32 *msg, u16 size, u16 vf)
132+
{
133+
struct wx_mbx_info *mbx = &wx->mbx;
134+
int ret;
135+
u16 i;
136+
137+
/* limit read to size of mailbox and mbx->size is up to 15 */
138+
if (size > mbx->size)
139+
size = mbx->size;
140+
141+
/* lock the mailbox to prevent pf/vf race condition */
142+
ret = wx_obtain_mbx_lock_pf(wx, vf);
143+
if (ret)
144+
return ret;
145+
146+
for (i = 0; i < size; i++)
147+
msg[i] = rd32a(wx, WX_PXMBMEM(vf), i);
148+
149+
/* Acknowledge the message and release buffer */
150+
/* set mirrored mailbox flags */
151+
wr32a(wx, WX_PXMBMEM(vf), WX_VXMAILBOX_SIZE, WX_PXMAILBOX_ACK);
152+
wr32(wx, WX_PXMAILBOX(vf), WX_PXMAILBOX_ACK);
153+
154+
return 0;
155+
}
156+
157+
/**
158+
* wx_check_for_rst_pf - checks to see if the VF has reset
159+
* @wx: pointer to the HW structure
160+
* @vf: the VF index
161+
*
162+
* Return: return 0 on success and -EBUSY on failure
163+
**/
164+
int wx_check_for_rst_pf(struct wx *wx, u16 vf)
165+
{
166+
u32 reg_offset = WX_VF_REG_OFFSET(vf);
167+
u32 vf_shift = WX_VF_IND_SHIFT(vf);
168+
u32 vflre = 0;
169+
170+
vflre = rd32(wx, WX_VFLRE(reg_offset));
171+
if (!(vflre & BIT(vf_shift)))
172+
return -EBUSY;
173+
wr32(wx, WX_VFLREC(reg_offset), BIT(vf_shift));
174+
175+
return 0;
176+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */
3+
#ifndef _WX_MBX_H_
4+
#define _WX_MBX_H_
5+
6+
#define WX_VXMAILBOX_SIZE 15
7+
8+
/* PF Registers */
9+
#define WX_PXMAILBOX(i) (0x600 + (4 * (i))) /* i=[0,63] */
10+
#define WX_PXMAILBOX_STS BIT(0) /* Initiate message send to VF */
11+
#define WX_PXMAILBOX_ACK BIT(1) /* Ack message recv'd from VF */
12+
#define WX_PXMAILBOX_PFU BIT(3) /* PF owns the mailbox buffer */
13+
14+
#define WX_PXMBMEM(i) (0x5000 + (64 * (i))) /* i=[0,63] */
15+
16+
#define WX_VFLRE(i) (0x4A0 + (4 * (i))) /* i=[0,1] */
17+
#define WX_VFLREC(i) (0x4A8 + (4 * (i))) /* i=[0,1] */
18+
19+
/* SR-IOV specific macros */
20+
#define WX_MBVFICR(i) (0x480 + (4 * (i))) /* i=[0,3] */
21+
#define WX_MBVFICR_VFREQ_MASK GENMASK(15, 0)
22+
#define WX_MBVFICR_VFACK_MASK GENMASK(31, 16)
23+
24+
#define WX_VT_MSGINFO_MASK GENMASK(23, 16)
25+
26+
int wx_write_mbx_pf(struct wx *wx, u32 *msg, u16 size, u16 vf);
27+
int wx_read_mbx_pf(struct wx *wx, u32 *msg, u16 size, u16 vf);
28+
int wx_check_for_rst_pf(struct wx *wx, u16 mbx_id);
29+
int wx_check_for_msg_pf(struct wx *wx, u16 mbx_id);
30+
int wx_check_for_ack_pf(struct wx *wx, u16 mbx_id);
31+
32+
#endif /* _WX_MBX_H_ */

drivers/net/ethernet/wangxun/libwx/wx_type.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#define WX_PCI_LINK_STATUS 0xB2
2323

2424
/**************** Global Registers ****************************/
25+
#define WX_VF_REG_OFFSET(_v) FIELD_GET(GENMASK(15, 5), (_v))
26+
#define WX_VF_IND_SHIFT(_v) FIELD_GET(GENMASK(4, 0), (_v))
27+
2528
/* chip control Registers */
2629
#define WX_MIS_PWR 0x10000
2730
#define WX_MIS_RST 0x1000C
@@ -779,6 +782,10 @@ struct wx_bus_info {
779782
u16 device;
780783
};
781784

785+
struct wx_mbx_info {
786+
u16 size;
787+
};
788+
782789
struct wx_thermal_sensor_data {
783790
s16 temp;
784791
s16 alarm_thresh;
@@ -1129,6 +1136,7 @@ struct wx {
11291136
struct pci_dev *pdev;
11301137
struct net_device *netdev;
11311138
struct wx_bus_info bus;
1139+
struct wx_mbx_info mbx;
11321140
struct wx_mac_info mac;
11331141
enum em_mac_type mac_type;
11341142
enum sp_media_type media_type;

0 commit comments

Comments
 (0)