mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'net-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski:
"Including fixes from CAN, netfilter, wireguard and IPsec.
I'd like to highlight [ lowlight? - Linus ] Florian W stepping down as
a netfilter maintainer due to constant stream of bug reports. Not sure
what we can do but IIUC this is not the first such case.
Current release - regressions:
- rxrpc: fix use of page_frag_alloc_align(), it changed semantics and
we added a new caller in a different subtree
- xfrm: allow UDP encapsulation only in offload modes
Current release - new code bugs:
- tcp: fix refcnt handling in __inet_hash_connect()
- Revert "net: Re-use and set mono_delivery_time bit for userspace
tstamp packets", conflicted with some expectations in BPF uAPI
Previous releases - regressions:
- ipv4: raw: fix sending packets from raw sockets via IPsec tunnels
- devlink: fix devlink's parallel command processing
- veth: do not manipulate GRO when using XDP
- esp: fix bad handling of pages from page_pool
Previous releases - always broken:
- report RCU QS for busy network kthreads (with Paul McK's blessing)
- tcp/rds: fix use-after-free on netns with kernel TCP reqsk
- virt: vmxnet3: fix missing reserved tailroom with XDP
Misc:
- couple of build fixes for Documentation"
* tag 'net-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (59 commits)
selftests: forwarding: Fix ping failure due to short timeout
MAINTAINERS: step down as netfilter maintainer
netfilter: nf_tables: Fix a memory leak in nf_tables_updchain
net: dsa: mt7530: fix handling of all link-local frames
net: dsa: mt7530: fix link-local frames that ingress vlan filtering ports
bpf: report RCU QS in cpumap kthread
net: report RCU QS on threaded NAPI repolling
rcu: add a helper to report consolidated flavor QS
ionic: update documentation for XDP support
lib/bitmap: Fix bitmap_scatter() and bitmap_gather() kernel doc
netfilter: nf_tables: do not compare internal table flags on updates
netfilter: nft_set_pipapo: release elements in clone only from destroy path
octeontx2-af: Use separate handlers for interrupts
octeontx2-pf: Send UP messages to VF only when VF is up.
octeontx2-pf: Use default max_active works instead of one
octeontx2-pf: Wait till detach_resources msg is complete
octeontx2: Detect the mbox up or down message via register
devlink: fix port new reply cmd type
tcp: Clear req->syncookie in reqsk_alloc().
net/bnx2x: Prevent access to a freed page in page_pool
...
This commit is contained in:
@@ -99,6 +99,12 @@ Minimal SR-IOV support is currently offered and can be enabled by setting
|
||||
the sysfs 'sriov_numvfs' value, if supported by your particular firmware
|
||||
configuration.
|
||||
|
||||
XDP
|
||||
---
|
||||
|
||||
Support for XDP includes the basics, plus Jumbo frames, Redirect and
|
||||
ndo_xmit. There is no current support for zero-copy sockets or HW offload.
|
||||
|
||||
Statistics
|
||||
==========
|
||||
|
||||
@@ -138,6 +144,12 @@ Driver port specific::
|
||||
rx_csum_none: 0
|
||||
rx_csum_complete: 3
|
||||
rx_csum_error: 0
|
||||
xdp_drop: 0
|
||||
xdp_aborted: 0
|
||||
xdp_pass: 0
|
||||
xdp_tx: 0
|
||||
xdp_redirect: 0
|
||||
xdp_frames: 0
|
||||
|
||||
Driver queue specific::
|
||||
|
||||
@@ -149,9 +161,12 @@ Driver queue specific::
|
||||
tx_0_frags: 0
|
||||
tx_0_tso: 0
|
||||
tx_0_tso_bytes: 0
|
||||
tx_0_hwstamp_valid: 0
|
||||
tx_0_hwstamp_invalid: 0
|
||||
tx_0_csum_none: 3
|
||||
tx_0_csum: 0
|
||||
tx_0_vlan_inserted: 0
|
||||
tx_0_xdp_frames: 0
|
||||
rx_0_pkts: 2
|
||||
rx_0_bytes: 120
|
||||
rx_0_dma_map_err: 0
|
||||
@@ -159,8 +174,15 @@ Driver queue specific::
|
||||
rx_0_csum_none: 0
|
||||
rx_0_csum_complete: 0
|
||||
rx_0_csum_error: 0
|
||||
rx_0_hwstamp_valid: 0
|
||||
rx_0_hwstamp_invalid: 0
|
||||
rx_0_dropped: 0
|
||||
rx_0_vlan_stripped: 0
|
||||
rx_0_xdp_drop: 0
|
||||
rx_0_xdp_aborted: 0
|
||||
rx_0_xdp_pass: 0
|
||||
rx_0_xdp_tx: 0
|
||||
rx_0_xdp_redirect: 0
|
||||
|
||||
Firmware port specific::
|
||||
|
||||
|
||||
@@ -87,35 +87,35 @@ all using the same instance under "priv->mdev".
|
||||
|
||||
Observability
|
||||
=============
|
||||
The relation between PF, irq, napi, and queue can be observed via netlink spec:
|
||||
The relation between PF, irq, napi, and queue can be observed via netlink spec::
|
||||
|
||||
$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump queue-get --json='{"ifindex": 13}'
|
||||
[{'id': 0, 'ifindex': 13, 'napi-id': 539, 'type': 'rx'},
|
||||
{'id': 1, 'ifindex': 13, 'napi-id': 540, 'type': 'rx'},
|
||||
{'id': 2, 'ifindex': 13, 'napi-id': 541, 'type': 'rx'},
|
||||
{'id': 3, 'ifindex': 13, 'napi-id': 542, 'type': 'rx'},
|
||||
{'id': 4, 'ifindex': 13, 'napi-id': 543, 'type': 'rx'},
|
||||
{'id': 0, 'ifindex': 13, 'napi-id': 539, 'type': 'tx'},
|
||||
{'id': 1, 'ifindex': 13, 'napi-id': 540, 'type': 'tx'},
|
||||
{'id': 2, 'ifindex': 13, 'napi-id': 541, 'type': 'tx'},
|
||||
{'id': 3, 'ifindex': 13, 'napi-id': 542, 'type': 'tx'},
|
||||
{'id': 4, 'ifindex': 13, 'napi-id': 543, 'type': 'tx'}]
|
||||
$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump queue-get --json='{"ifindex": 13}'
|
||||
[{'id': 0, 'ifindex': 13, 'napi-id': 539, 'type': 'rx'},
|
||||
{'id': 1, 'ifindex': 13, 'napi-id': 540, 'type': 'rx'},
|
||||
{'id': 2, 'ifindex': 13, 'napi-id': 541, 'type': 'rx'},
|
||||
{'id': 3, 'ifindex': 13, 'napi-id': 542, 'type': 'rx'},
|
||||
{'id': 4, 'ifindex': 13, 'napi-id': 543, 'type': 'rx'},
|
||||
{'id': 0, 'ifindex': 13, 'napi-id': 539, 'type': 'tx'},
|
||||
{'id': 1, 'ifindex': 13, 'napi-id': 540, 'type': 'tx'},
|
||||
{'id': 2, 'ifindex': 13, 'napi-id': 541, 'type': 'tx'},
|
||||
{'id': 3, 'ifindex': 13, 'napi-id': 542, 'type': 'tx'},
|
||||
{'id': 4, 'ifindex': 13, 'napi-id': 543, 'type': 'tx'}]
|
||||
|
||||
$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump napi-get --json='{"ifindex": 13}'
|
||||
[{'id': 543, 'ifindex': 13, 'irq': 42},
|
||||
{'id': 542, 'ifindex': 13, 'irq': 41},
|
||||
{'id': 541, 'ifindex': 13, 'irq': 40},
|
||||
{'id': 540, 'ifindex': 13, 'irq': 39},
|
||||
{'id': 539, 'ifindex': 13, 'irq': 36}]
|
||||
$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump napi-get --json='{"ifindex": 13}'
|
||||
[{'id': 543, 'ifindex': 13, 'irq': 42},
|
||||
{'id': 542, 'ifindex': 13, 'irq': 41},
|
||||
{'id': 541, 'ifindex': 13, 'irq': 40},
|
||||
{'id': 540, 'ifindex': 13, 'irq': 39},
|
||||
{'id': 539, 'ifindex': 13, 'irq': 36}]
|
||||
|
||||
Here you can clearly observe our channels distribution policy:
|
||||
Here you can clearly observe our channels distribution policy::
|
||||
|
||||
$ ls /proc/irq/{36,39,40,41,42}/mlx5* -d -1
|
||||
/proc/irq/36/mlx5_comp1@pci:0000:08:00.0
|
||||
/proc/irq/39/mlx5_comp1@pci:0000:09:00.0
|
||||
/proc/irq/40/mlx5_comp2@pci:0000:08:00.0
|
||||
/proc/irq/41/mlx5_comp2@pci:0000:09:00.0
|
||||
/proc/irq/42/mlx5_comp3@pci:0000:08:00.0
|
||||
$ ls /proc/irq/{36,39,40,41,42}/mlx5* -d -1
|
||||
/proc/irq/36/mlx5_comp1@pci:0000:08:00.0
|
||||
/proc/irq/39/mlx5_comp1@pci:0000:09:00.0
|
||||
/proc/irq/40/mlx5_comp2@pci:0000:08:00.0
|
||||
/proc/irq/41/mlx5_comp2@pci:0000:09:00.0
|
||||
/proc/irq/42/mlx5_comp3@pci:0000:08:00.0
|
||||
|
||||
Steering
|
||||
========
|
||||
|
||||
@@ -13,7 +13,7 @@ struct_dev_ifalias* ifalias
|
||||
unsigned_long mem_end
|
||||
unsigned_long mem_start
|
||||
unsigned_long base_addr
|
||||
unsigned_long state
|
||||
unsigned_long state read_mostly read_mostly netif_running(dev)
|
||||
struct_list_head dev_list
|
||||
struct_list_head napi_list
|
||||
struct_list_head unreg_list
|
||||
|
||||
@@ -15237,7 +15237,6 @@ F: drivers/net/ethernet/neterion/
|
||||
NETFILTER
|
||||
M: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
M: Jozsef Kadlecsik <kadlec@netfilter.org>
|
||||
M: Florian Westphal <fw@strlen.de>
|
||||
L: netfilter-devel@vger.kernel.org
|
||||
L: coreteam@netfilter.org
|
||||
S: Maintained
|
||||
|
||||
@@ -370,8 +370,8 @@ static const struct kvaser_pciefd_irq_mask kvaser_pciefd_sf2_irq_mask = {
|
||||
|
||||
static const struct kvaser_pciefd_irq_mask kvaser_pciefd_xilinx_irq_mask = {
|
||||
.kcan_rx0 = BIT(4),
|
||||
.kcan_tx = { BIT(16), BIT(17), BIT(18), BIT(19) },
|
||||
.all = GENMASK(19, 16) | BIT(4),
|
||||
.kcan_tx = { BIT(16), BIT(17), BIT(18), BIT(19), BIT(20), BIT(21), BIT(22), BIT(23) },
|
||||
.all = GENMASK(23, 16) | BIT(4),
|
||||
};
|
||||
|
||||
static const struct kvaser_pciefd_dev_ops kvaser_pciefd_altera_dev_ops = {
|
||||
|
||||
@@ -950,20 +950,56 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
}
|
||||
|
||||
/* On page 205, section "8.6.3 Frame filtering" of the active standard, IEEE Std
|
||||
* 802.1Q™-2022, it is stated that frames with 01:80:C2:00:00:00-0F as MAC DA
|
||||
* must only be propagated to C-VLAN and MAC Bridge components. That means
|
||||
* VLAN-aware and VLAN-unaware bridges. On the switch designs with CPU ports,
|
||||
* these frames are supposed to be processed by the CPU (software). So we make
|
||||
* the switch only forward them to the CPU port. And if received from a CPU
|
||||
* port, forward to a single port. The software is responsible of making the
|
||||
* switch conform to the latter by setting a single port as destination port on
|
||||
* the special tag.
|
||||
*
|
||||
* This switch intellectual property cannot conform to this part of the standard
|
||||
* fully. Whilst the REV_UN frame tag covers the remaining :04-0D and :0F MAC
|
||||
* DAs, it also includes :22-FF which the scope of propagation is not supposed
|
||||
* to be restricted for these MAC DAs.
|
||||
*/
|
||||
static void
|
||||
mt753x_trap_frames(struct mt7530_priv *priv)
|
||||
{
|
||||
/* Trap BPDUs to the CPU port(s) */
|
||||
mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
|
||||
/* Trap 802.1X PAE frames and BPDUs to the CPU port(s) and egress them
|
||||
* VLAN-untagged.
|
||||
*/
|
||||
mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_EG_TAG_MASK |
|
||||
MT753X_PAE_PORT_FW_MASK | MT753X_BPDU_EG_TAG_MASK |
|
||||
MT753X_BPDU_PORT_FW_MASK,
|
||||
MT753X_PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY) |
|
||||
MT753X_BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
MT753X_BPDU_CPU_ONLY);
|
||||
|
||||
/* Trap 802.1X PAE frames to the CPU port(s) */
|
||||
mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_PORT_FW_MASK,
|
||||
MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY));
|
||||
/* Trap frames with :01 and :02 MAC DAs to the CPU port(s) and egress
|
||||
* them VLAN-untagged.
|
||||
*/
|
||||
mt7530_rmw(priv, MT753X_RGAC1, MT753X_R02_EG_TAG_MASK |
|
||||
MT753X_R02_PORT_FW_MASK | MT753X_R01_EG_TAG_MASK |
|
||||
MT753X_R01_PORT_FW_MASK,
|
||||
MT753X_R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
MT753X_R02_PORT_FW(MT753X_BPDU_CPU_ONLY) |
|
||||
MT753X_R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
MT753X_BPDU_CPU_ONLY);
|
||||
|
||||
/* Trap LLDP frames with :0E MAC DA to the CPU port(s) */
|
||||
mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_PORT_FW_MASK,
|
||||
MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY));
|
||||
/* Trap frames with :03 and :0E MAC DAs to the CPU port(s) and egress
|
||||
* them VLAN-untagged.
|
||||
*/
|
||||
mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_EG_TAG_MASK |
|
||||
MT753X_R0E_PORT_FW_MASK | MT753X_R03_EG_TAG_MASK |
|
||||
MT753X_R03_PORT_FW_MASK,
|
||||
MT753X_R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY) |
|
||||
MT753X_R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
|
||||
MT753X_BPDU_CPU_ONLY);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2192,22 +2228,16 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable LEDs before reset to prevent the MT7530 sampling a
|
||||
* potentially incorrect HT_XTAL_FSEL value.
|
||||
*/
|
||||
mt7530_write(priv, MT7530_LED_EN, 0);
|
||||
usleep_range(1000, 1100);
|
||||
|
||||
/* Reset whole chip through gpio pin or memory-mapped registers for
|
||||
* different type of hardware
|
||||
*/
|
||||
if (priv->mcm) {
|
||||
reset_control_assert(priv->rstc);
|
||||
usleep_range(1000, 1100);
|
||||
usleep_range(5000, 5100);
|
||||
reset_control_deassert(priv->rstc);
|
||||
} else {
|
||||
gpiod_set_value_cansleep(priv->reset, 0);
|
||||
usleep_range(1000, 1100);
|
||||
usleep_range(5000, 5100);
|
||||
gpiod_set_value_cansleep(priv->reset, 1);
|
||||
}
|
||||
|
||||
@@ -2420,11 +2450,11 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
*/
|
||||
if (priv->mcm) {
|
||||
reset_control_assert(priv->rstc);
|
||||
usleep_range(1000, 1100);
|
||||
usleep_range(5000, 5100);
|
||||
reset_control_deassert(priv->rstc);
|
||||
} else {
|
||||
gpiod_set_value_cansleep(priv->reset, 0);
|
||||
usleep_range(1000, 1100);
|
||||
usleep_range(5000, 5100);
|
||||
gpiod_set_value_cansleep(priv->reset, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,14 +65,33 @@ enum mt753x_id {
|
||||
|
||||
/* Registers for BPDU and PAE frame control*/
|
||||
#define MT753X_BPC 0x24
|
||||
#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0)
|
||||
#define MT753X_PAE_EG_TAG_MASK GENMASK(24, 22)
|
||||
#define MT753X_PAE_EG_TAG(x) FIELD_PREP(MT753X_PAE_EG_TAG_MASK, x)
|
||||
#define MT753X_PAE_PORT_FW_MASK GENMASK(18, 16)
|
||||
#define MT753X_PAE_PORT_FW(x) FIELD_PREP(MT753X_PAE_PORT_FW_MASK, x)
|
||||
#define MT753X_BPDU_EG_TAG_MASK GENMASK(8, 6)
|
||||
#define MT753X_BPDU_EG_TAG(x) FIELD_PREP(MT753X_BPDU_EG_TAG_MASK, x)
|
||||
#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0)
|
||||
|
||||
/* Register for :01 and :02 MAC DA frame control */
|
||||
#define MT753X_RGAC1 0x28
|
||||
#define MT753X_R02_EG_TAG_MASK GENMASK(24, 22)
|
||||
#define MT753X_R02_EG_TAG(x) FIELD_PREP(MT753X_R02_EG_TAG_MASK, x)
|
||||
#define MT753X_R02_PORT_FW_MASK GENMASK(18, 16)
|
||||
#define MT753X_R02_PORT_FW(x) FIELD_PREP(MT753X_R02_PORT_FW_MASK, x)
|
||||
#define MT753X_R01_EG_TAG_MASK GENMASK(8, 6)
|
||||
#define MT753X_R01_EG_TAG(x) FIELD_PREP(MT753X_R01_EG_TAG_MASK, x)
|
||||
#define MT753X_R01_PORT_FW_MASK GENMASK(2, 0)
|
||||
|
||||
/* Register for :03 and :0E MAC DA frame control */
|
||||
#define MT753X_RGAC2 0x2c
|
||||
#define MT753X_R0E_EG_TAG_MASK GENMASK(24, 22)
|
||||
#define MT753X_R0E_EG_TAG(x) FIELD_PREP(MT753X_R0E_EG_TAG_MASK, x)
|
||||
#define MT753X_R0E_PORT_FW_MASK GENMASK(18, 16)
|
||||
#define MT753X_R0E_PORT_FW(x) FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x)
|
||||
#define MT753X_R03_EG_TAG_MASK GENMASK(8, 6)
|
||||
#define MT753X_R03_EG_TAG(x) FIELD_PREP(MT753X_R03_EG_TAG_MASK, x)
|
||||
#define MT753X_R03_PORT_FW_MASK GENMASK(2, 0)
|
||||
|
||||
enum mt753x_bpdu_port_fw {
|
||||
MT753X_BPDU_FOLLOW_MFC,
|
||||
@@ -253,6 +272,7 @@ enum mt7530_port_mode {
|
||||
enum mt7530_vlan_port_eg_tag {
|
||||
MT7530_VLAN_EG_DISABLED = 0,
|
||||
MT7530_VLAN_EG_CONSISTENT = 1,
|
||||
MT7530_VLAN_EG_UNTAGGED = 4,
|
||||
};
|
||||
|
||||
enum mt7530_vlan_port_attr {
|
||||
|
||||
@@ -1002,9 +1002,6 @@ static inline void bnx2x_set_fw_mac_addr(__le16 *fw_hi, __le16 *fw_mid,
|
||||
static inline void bnx2x_free_rx_mem_pool(struct bnx2x *bp,
|
||||
struct bnx2x_alloc_pool *pool)
|
||||
{
|
||||
if (!pool->page)
|
||||
return;
|
||||
|
||||
put_page(pool->page);
|
||||
|
||||
pool->page = NULL;
|
||||
@@ -1015,6 +1012,9 @@ static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp,
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!fp->page_pool.page)
|
||||
return;
|
||||
|
||||
if (fp->mode == TPA_MODE_DISABLED)
|
||||
return;
|
||||
|
||||
|
||||
@@ -1338,7 +1338,7 @@ static irqreturn_t cgx_fwi_event_handler(int irq, void *data)
|
||||
|
||||
/* Release thread waiting for completion */
|
||||
lmac->cmd_pend = false;
|
||||
wake_up_interruptible(&lmac->wq_cmd_cmplt);
|
||||
wake_up(&lmac->wq_cmd_cmplt);
|
||||
break;
|
||||
case CGX_EVT_ASYNC:
|
||||
if (cgx_event_is_linkevent(event))
|
||||
|
||||
@@ -214,11 +214,12 @@ int otx2_mbox_busy_poll_for_rsp(struct otx2_mbox *mbox, int devid)
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_mbox_busy_poll_for_rsp);
|
||||
|
||||
void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid)
|
||||
static void otx2_mbox_msg_send_data(struct otx2_mbox *mbox, int devid, u64 data)
|
||||
{
|
||||
struct otx2_mbox_dev *mdev = &mbox->dev[devid];
|
||||
struct mbox_hdr *tx_hdr, *rx_hdr;
|
||||
void *hw_mbase = mdev->hwbase;
|
||||
u64 intr_val;
|
||||
|
||||
tx_hdr = hw_mbase + mbox->tx_start;
|
||||
rx_hdr = hw_mbase + mbox->rx_start;
|
||||
@@ -254,14 +255,52 @@ void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid)
|
||||
|
||||
spin_unlock(&mdev->mbox_lock);
|
||||
|
||||
/* Check if interrupt pending */
|
||||
intr_val = readq((void __iomem *)mbox->reg_base +
|
||||
(mbox->trigger | (devid << mbox->tr_shift)));
|
||||
|
||||
intr_val |= data;
|
||||
/* The interrupt should be fired after num_msgs is written
|
||||
* to the shared memory
|
||||
*/
|
||||
writeq(1, (void __iomem *)mbox->reg_base +
|
||||
writeq(intr_val, (void __iomem *)mbox->reg_base +
|
||||
(mbox->trigger | (devid << mbox->tr_shift)));
|
||||
}
|
||||
|
||||
void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid)
|
||||
{
|
||||
otx2_mbox_msg_send_data(mbox, devid, MBOX_DOWN_MSG);
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_mbox_msg_send);
|
||||
|
||||
void otx2_mbox_msg_send_up(struct otx2_mbox *mbox, int devid)
|
||||
{
|
||||
otx2_mbox_msg_send_data(mbox, devid, MBOX_UP_MSG);
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_mbox_msg_send_up);
|
||||
|
||||
bool otx2_mbox_wait_for_zero(struct otx2_mbox *mbox, int devid)
|
||||
{
|
||||
u64 data;
|
||||
|
||||
data = readq((void __iomem *)mbox->reg_base +
|
||||
(mbox->trigger | (devid << mbox->tr_shift)));
|
||||
|
||||
/* If data is non-zero wait for ~1ms and return to caller
|
||||
* whether data has changed to zero or not after the wait.
|
||||
*/
|
||||
if (!data)
|
||||
return true;
|
||||
|
||||
usleep_range(950, 1000);
|
||||
|
||||
data = readq((void __iomem *)mbox->reg_base +
|
||||
(mbox->trigger | (devid << mbox->tr_shift)));
|
||||
|
||||
return data == 0;
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_mbox_wait_for_zero);
|
||||
|
||||
struct mbox_msghdr *otx2_mbox_alloc_msg_rsp(struct otx2_mbox *mbox, int devid,
|
||||
int size, int size_rsp)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
#define MBOX_SIZE SZ_64K
|
||||
|
||||
#define MBOX_DOWN_MSG 1
|
||||
#define MBOX_UP_MSG 2
|
||||
|
||||
/* AF/PF: PF initiated, PF/VF VF initiated */
|
||||
#define MBOX_DOWN_RX_START 0
|
||||
#define MBOX_DOWN_RX_SIZE (46 * SZ_1K)
|
||||
@@ -101,6 +104,7 @@ int otx2_mbox_regions_init(struct otx2_mbox *mbox, void __force **hwbase,
|
||||
struct pci_dev *pdev, void __force *reg_base,
|
||||
int direction, int ndevs, unsigned long *bmap);
|
||||
void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid);
|
||||
void otx2_mbox_msg_send_up(struct otx2_mbox *mbox, int devid);
|
||||
int otx2_mbox_wait_for_rsp(struct otx2_mbox *mbox, int devid);
|
||||
int otx2_mbox_busy_poll_for_rsp(struct otx2_mbox *mbox, int devid);
|
||||
struct mbox_msghdr *otx2_mbox_alloc_msg_rsp(struct otx2_mbox *mbox, int devid,
|
||||
@@ -118,6 +122,8 @@ static inline struct mbox_msghdr *otx2_mbox_alloc_msg(struct otx2_mbox *mbox,
|
||||
return otx2_mbox_alloc_msg_rsp(mbox, devid, size, 0);
|
||||
}
|
||||
|
||||
bool otx2_mbox_wait_for_zero(struct otx2_mbox *mbox, int devid);
|
||||
|
||||
/* Mailbox message types */
|
||||
#define MBOX_MSG_MASK 0xFFFF
|
||||
#define MBOX_MSG_INVALID 0xFFFE
|
||||
|
||||
@@ -121,13 +121,17 @@ int mcs_add_intr_wq_entry(struct mcs *mcs, struct mcs_intr_event *event)
|
||||
static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu)
|
||||
{
|
||||
struct mcs_intr_info *req;
|
||||
int err, pf;
|
||||
int pf;
|
||||
|
||||
pf = rvu_get_pf(event->pcifunc);
|
||||
|
||||
mutex_lock(&rvu->mbox_lock);
|
||||
|
||||
req = otx2_mbox_alloc_msg_mcs_intr_notify(rvu, pf);
|
||||
if (!req)
|
||||
if (!req) {
|
||||
mutex_unlock(&rvu->mbox_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
req->mcs_id = event->mcs_id;
|
||||
req->intr_mask = event->intr_mask;
|
||||
@@ -135,10 +139,11 @@ static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu)
|
||||
req->hdr.pcifunc = event->pcifunc;
|
||||
req->lmac_id = event->lmac_id;
|
||||
|
||||
otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, pf);
|
||||
err = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pf);
|
||||
if (err)
|
||||
dev_warn(rvu->dev, "MCS notification to pf %d failed\n", pf);
|
||||
otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf);
|
||||
|
||||
otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf);
|
||||
|
||||
mutex_unlock(&rvu->mbox_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2119,7 +2119,7 @@ bad_message:
|
||||
}
|
||||
}
|
||||
|
||||
static void __rvu_mbox_handler(struct rvu_work *mwork, int type)
|
||||
static void __rvu_mbox_handler(struct rvu_work *mwork, int type, bool poll)
|
||||
{
|
||||
struct rvu *rvu = mwork->rvu;
|
||||
int offset, err, id, devid;
|
||||
@@ -2186,6 +2186,9 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type)
|
||||
}
|
||||
mw->mbox_wrk[devid].num_msgs = 0;
|
||||
|
||||
if (poll)
|
||||
otx2_mbox_wait_for_zero(mbox, devid);
|
||||
|
||||
/* Send mbox responses to VF/PF */
|
||||
otx2_mbox_msg_send(mbox, devid);
|
||||
}
|
||||
@@ -2193,15 +2196,18 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type)
|
||||
static inline void rvu_afpf_mbox_handler(struct work_struct *work)
|
||||
{
|
||||
struct rvu_work *mwork = container_of(work, struct rvu_work, work);
|
||||
struct rvu *rvu = mwork->rvu;
|
||||
|
||||
__rvu_mbox_handler(mwork, TYPE_AFPF);
|
||||
mutex_lock(&rvu->mbox_lock);
|
||||
__rvu_mbox_handler(mwork, TYPE_AFPF, true);
|
||||
mutex_unlock(&rvu->mbox_lock);
|
||||
}
|
||||
|
||||
static inline void rvu_afvf_mbox_handler(struct work_struct *work)
|
||||
{
|
||||
struct rvu_work *mwork = container_of(work, struct rvu_work, work);
|
||||
|
||||
__rvu_mbox_handler(mwork, TYPE_AFVF);
|
||||
__rvu_mbox_handler(mwork, TYPE_AFVF, false);
|
||||
}
|
||||
|
||||
static void __rvu_mbox_up_handler(struct rvu_work *mwork, int type)
|
||||
@@ -2376,6 +2382,8 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
|
||||
}
|
||||
}
|
||||
|
||||
mutex_init(&rvu->mbox_lock);
|
||||
|
||||
mbox_regions = kcalloc(num, sizeof(void *), GFP_KERNEL);
|
||||
if (!mbox_regions) {
|
||||
err = -ENOMEM;
|
||||
@@ -2525,10 +2533,9 @@ static void rvu_queue_work(struct mbox_wq_info *mw, int first,
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
|
||||
static irqreturn_t rvu_mbox_pf_intr_handler(int irq, void *rvu_irq)
|
||||
{
|
||||
struct rvu *rvu = (struct rvu *)rvu_irq;
|
||||
int vfs = rvu->vfs;
|
||||
u64 intr;
|
||||
|
||||
intr = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_PFAF_MBOX_INT);
|
||||
@@ -2542,6 +2549,18 @@ static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
|
||||
|
||||
rvu_queue_work(&rvu->afpf_wq_info, 0, rvu->hw->total_pfs, intr);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
|
||||
{
|
||||
struct rvu *rvu = (struct rvu *)rvu_irq;
|
||||
int vfs = rvu->vfs;
|
||||
u64 intr;
|
||||
|
||||
/* Sync with mbox memory region */
|
||||
rmb();
|
||||
|
||||
/* Handle VF interrupts */
|
||||
if (vfs > 64) {
|
||||
intr = rvupf_read64(rvu, RVU_PF_VFPF_MBOX_INTX(1));
|
||||
@@ -2886,7 +2905,7 @@ static int rvu_register_interrupts(struct rvu *rvu)
|
||||
/* Register mailbox interrupt handler */
|
||||
sprintf(&rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], "RVUAF Mbox");
|
||||
ret = request_irq(pci_irq_vector(rvu->pdev, RVU_AF_INT_VEC_MBOX),
|
||||
rvu_mbox_intr_handler, 0,
|
||||
rvu_mbox_pf_intr_handler, 0,
|
||||
&rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], rvu);
|
||||
if (ret) {
|
||||
dev_err(rvu->dev,
|
||||
|
||||
@@ -591,6 +591,8 @@ struct rvu {
|
||||
spinlock_t mcs_intrq_lock;
|
||||
/* CPT interrupt lock */
|
||||
spinlock_t cpt_intr_lock;
|
||||
|
||||
struct mutex mbox_lock; /* Serialize mbox up and down msgs */
|
||||
};
|
||||
|
||||
static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
|
||||
|
||||
@@ -232,7 +232,7 @@ static void cgx_notify_pfs(struct cgx_link_event *event, struct rvu *rvu)
|
||||
struct cgx_link_user_info *linfo;
|
||||
struct cgx_link_info_msg *msg;
|
||||
unsigned long pfmap;
|
||||
int err, pfid;
|
||||
int pfid;
|
||||
|
||||
linfo = &event->link_uinfo;
|
||||
pfmap = cgxlmac_to_pfmap(rvu, event->cgx_id, event->lmac_id);
|
||||
@@ -255,16 +255,22 @@ static void cgx_notify_pfs(struct cgx_link_event *event, struct rvu *rvu)
|
||||
continue;
|
||||
}
|
||||
|
||||
mutex_lock(&rvu->mbox_lock);
|
||||
|
||||
/* Send mbox message to PF */
|
||||
msg = otx2_mbox_alloc_msg_cgx_link_event(rvu, pfid);
|
||||
if (!msg)
|
||||
if (!msg) {
|
||||
mutex_unlock(&rvu->mbox_lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
msg->link_info = *linfo;
|
||||
otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, pfid);
|
||||
err = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pfid);
|
||||
if (err)
|
||||
dev_warn(rvu->dev, "notification to pf %d failed\n",
|
||||
pfid);
|
||||
|
||||
otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pfid);
|
||||
|
||||
otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pfid);
|
||||
|
||||
mutex_unlock(&rvu->mbox_lock);
|
||||
} while (pfmap);
|
||||
}
|
||||
|
||||
|
||||
@@ -1592,7 +1592,7 @@ int otx2_detach_resources(struct mbox *mbox)
|
||||
detach->partial = false;
|
||||
|
||||
/* Send detach request to AF */
|
||||
otx2_mbox_msg_send(&mbox->mbox, 0);
|
||||
otx2_sync_mbox_msg(mbox);
|
||||
mutex_unlock(&mbox->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -815,7 +815,7 @@ static inline int otx2_sync_mbox_up_msg(struct mbox *mbox, int devid)
|
||||
|
||||
if (!otx2_mbox_nonempty(&mbox->mbox_up, devid))
|
||||
return 0;
|
||||
otx2_mbox_msg_send(&mbox->mbox_up, devid);
|
||||
otx2_mbox_msg_send_up(&mbox->mbox_up, devid);
|
||||
err = otx2_mbox_wait_for_rsp(&mbox->mbox_up, devid);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -292,8 +292,8 @@ static int otx2_pf_flr_init(struct otx2_nic *pf, int num_vfs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void otx2_queue_work(struct mbox *mw, struct workqueue_struct *mbox_wq,
|
||||
int first, int mdevs, u64 intr, int type)
|
||||
static void otx2_queue_vf_work(struct mbox *mw, struct workqueue_struct *mbox_wq,
|
||||
int first, int mdevs, u64 intr)
|
||||
{
|
||||
struct otx2_mbox_dev *mdev;
|
||||
struct otx2_mbox *mbox;
|
||||
@@ -307,40 +307,26 @@ static void otx2_queue_work(struct mbox *mw, struct workqueue_struct *mbox_wq,
|
||||
|
||||
mbox = &mw->mbox;
|
||||
mdev = &mbox->dev[i];
|
||||
if (type == TYPE_PFAF)
|
||||
otx2_sync_mbox_bbuf(mbox, i);
|
||||
hdr = mdev->mbase + mbox->rx_start;
|
||||
/* The hdr->num_msgs is set to zero immediately in the interrupt
|
||||
* handler to ensure that it holds a correct value next time
|
||||
* when the interrupt handler is called.
|
||||
* pf->mbox.num_msgs holds the data for use in pfaf_mbox_handler
|
||||
* pf>mbox.up_num_msgs holds the data for use in
|
||||
* pfaf_mbox_up_handler.
|
||||
* handler to ensure that it holds a correct value next time
|
||||
* when the interrupt handler is called. pf->mw[i].num_msgs
|
||||
* holds the data for use in otx2_pfvf_mbox_handler and
|
||||
* pf->mw[i].up_num_msgs holds the data for use in
|
||||
* otx2_pfvf_mbox_up_handler.
|
||||
*/
|
||||
if (hdr->num_msgs) {
|
||||
mw[i].num_msgs = hdr->num_msgs;
|
||||
hdr->num_msgs = 0;
|
||||
if (type == TYPE_PFAF)
|
||||
memset(mbox->hwbase + mbox->rx_start, 0,
|
||||
ALIGN(sizeof(struct mbox_hdr),
|
||||
sizeof(u64)));
|
||||
|
||||
queue_work(mbox_wq, &mw[i].mbox_wrk);
|
||||
}
|
||||
|
||||
mbox = &mw->mbox_up;
|
||||
mdev = &mbox->dev[i];
|
||||
if (type == TYPE_PFAF)
|
||||
otx2_sync_mbox_bbuf(mbox, i);
|
||||
hdr = mdev->mbase + mbox->rx_start;
|
||||
if (hdr->num_msgs) {
|
||||
mw[i].up_num_msgs = hdr->num_msgs;
|
||||
hdr->num_msgs = 0;
|
||||
if (type == TYPE_PFAF)
|
||||
memset(mbox->hwbase + mbox->rx_start, 0,
|
||||
ALIGN(sizeof(struct mbox_hdr),
|
||||
sizeof(u64)));
|
||||
|
||||
queue_work(mbox_wq, &mw[i].mbox_up_wrk);
|
||||
}
|
||||
}
|
||||
@@ -356,8 +342,10 @@ static void otx2_forward_msg_pfvf(struct otx2_mbox_dev *mdev,
|
||||
/* Msgs are already copied, trigger VF's mbox irq */
|
||||
smp_wmb();
|
||||
|
||||
otx2_mbox_wait_for_zero(pfvf_mbox, devid);
|
||||
|
||||
offset = pfvf_mbox->trigger | (devid << pfvf_mbox->tr_shift);
|
||||
writeq(1, (void __iomem *)pfvf_mbox->reg_base + offset);
|
||||
writeq(MBOX_DOWN_MSG, (void __iomem *)pfvf_mbox->reg_base + offset);
|
||||
|
||||
/* Restore VF's mbox bounce buffer region address */
|
||||
src_mdev->mbase = bbuf_base;
|
||||
@@ -547,7 +535,7 @@ static void otx2_pfvf_mbox_up_handler(struct work_struct *work)
|
||||
end:
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
if (mdev->msgs_acked == (vf_mbox->up_num_msgs - 1))
|
||||
__otx2_mbox_reset(mbox, 0);
|
||||
__otx2_mbox_reset(mbox, vf_idx);
|
||||
mdev->msgs_acked++;
|
||||
}
|
||||
}
|
||||
@@ -564,8 +552,7 @@ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq)
|
||||
if (vfs > 64) {
|
||||
intr = otx2_read64(pf, RVU_PF_VFPF_MBOX_INTX(1));
|
||||
otx2_write64(pf, RVU_PF_VFPF_MBOX_INTX(1), intr);
|
||||
otx2_queue_work(mbox, pf->mbox_pfvf_wq, 64, vfs, intr,
|
||||
TYPE_PFVF);
|
||||
otx2_queue_vf_work(mbox, pf->mbox_pfvf_wq, 64, vfs, intr);
|
||||
if (intr)
|
||||
trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr);
|
||||
vfs = 64;
|
||||
@@ -574,7 +561,7 @@ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq)
|
||||
intr = otx2_read64(pf, RVU_PF_VFPF_MBOX_INTX(0));
|
||||
otx2_write64(pf, RVU_PF_VFPF_MBOX_INTX(0), intr);
|
||||
|
||||
otx2_queue_work(mbox, pf->mbox_pfvf_wq, 0, vfs, intr, TYPE_PFVF);
|
||||
otx2_queue_vf_work(mbox, pf->mbox_pfvf_wq, 0, vfs, intr);
|
||||
|
||||
if (intr)
|
||||
trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr);
|
||||
@@ -597,8 +584,9 @@ static int otx2_pfvf_mbox_init(struct otx2_nic *pf, int numvfs)
|
||||
if (!pf->mbox_pfvf)
|
||||
return -ENOMEM;
|
||||
|
||||
pf->mbox_pfvf_wq = alloc_ordered_workqueue("otx2_pfvf_mailbox",
|
||||
WQ_HIGHPRI | WQ_MEM_RECLAIM);
|
||||
pf->mbox_pfvf_wq = alloc_workqueue("otx2_pfvf_mailbox",
|
||||
WQ_UNBOUND | WQ_HIGHPRI |
|
||||
WQ_MEM_RECLAIM, 0);
|
||||
if (!pf->mbox_pfvf_wq)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -821,20 +809,22 @@ static void otx2_pfaf_mbox_handler(struct work_struct *work)
|
||||
struct mbox *af_mbox;
|
||||
struct otx2_nic *pf;
|
||||
int offset, id;
|
||||
u16 num_msgs;
|
||||
|
||||
af_mbox = container_of(work, struct mbox, mbox_wrk);
|
||||
mbox = &af_mbox->mbox;
|
||||
mdev = &mbox->dev[0];
|
||||
rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
num_msgs = rsp_hdr->num_msgs;
|
||||
|
||||
offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
|
||||
pf = af_mbox->pfvf;
|
||||
|
||||
for (id = 0; id < af_mbox->num_msgs; id++) {
|
||||
for (id = 0; id < num_msgs; id++) {
|
||||
msg = (struct mbox_msghdr *)(mdev->mbase + offset);
|
||||
otx2_process_pfaf_mbox_msg(pf, msg);
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
if (mdev->msgs_acked == (af_mbox->num_msgs - 1))
|
||||
if (mdev->msgs_acked == (num_msgs - 1))
|
||||
__otx2_mbox_reset(mbox, 0);
|
||||
mdev->msgs_acked++;
|
||||
}
|
||||
@@ -945,12 +935,14 @@ static void otx2_pfaf_mbox_up_handler(struct work_struct *work)
|
||||
int offset, id, devid = 0;
|
||||
struct mbox_hdr *rsp_hdr;
|
||||
struct mbox_msghdr *msg;
|
||||
u16 num_msgs;
|
||||
|
||||
rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
num_msgs = rsp_hdr->num_msgs;
|
||||
|
||||
offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
|
||||
|
||||
for (id = 0; id < af_mbox->up_num_msgs; id++) {
|
||||
for (id = 0; id < num_msgs; id++) {
|
||||
msg = (struct mbox_msghdr *)(mdev->mbase + offset);
|
||||
|
||||
devid = msg->pcifunc & RVU_PFVF_FUNC_MASK;
|
||||
@@ -959,10 +951,11 @@ static void otx2_pfaf_mbox_up_handler(struct work_struct *work)
|
||||
otx2_process_mbox_msg_up(pf, msg);
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
}
|
||||
if (devid) {
|
||||
/* Forward to VF iff VFs are really present */
|
||||
if (devid && pci_num_vf(pf->pdev)) {
|
||||
otx2_forward_vf_mbox_msgs(pf, &pf->mbox.mbox_up,
|
||||
MBOX_DIR_PFVF_UP, devid - 1,
|
||||
af_mbox->up_num_msgs);
|
||||
num_msgs);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -972,16 +965,49 @@ static void otx2_pfaf_mbox_up_handler(struct work_struct *work)
|
||||
static irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq)
|
||||
{
|
||||
struct otx2_nic *pf = (struct otx2_nic *)pf_irq;
|
||||
struct mbox *mbox;
|
||||
struct mbox *mw = &pf->mbox;
|
||||
struct otx2_mbox_dev *mdev;
|
||||
struct otx2_mbox *mbox;
|
||||
struct mbox_hdr *hdr;
|
||||
u64 mbox_data;
|
||||
|
||||
/* Clear the IRQ */
|
||||
otx2_write64(pf, RVU_PF_INT, BIT_ULL(0));
|
||||
|
||||
mbox = &pf->mbox;
|
||||
|
||||
trace_otx2_msg_interrupt(mbox->mbox.pdev, "AF to PF", BIT_ULL(0));
|
||||
mbox_data = otx2_read64(pf, RVU_PF_PFAF_MBOX0);
|
||||
|
||||
otx2_queue_work(mbox, pf->mbox_wq, 0, 1, 1, TYPE_PFAF);
|
||||
if (mbox_data & MBOX_UP_MSG) {
|
||||
mbox_data &= ~MBOX_UP_MSG;
|
||||
otx2_write64(pf, RVU_PF_PFAF_MBOX0, mbox_data);
|
||||
|
||||
mbox = &mw->mbox_up;
|
||||
mdev = &mbox->dev[0];
|
||||
otx2_sync_mbox_bbuf(mbox, 0);
|
||||
|
||||
hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
if (hdr->num_msgs)
|
||||
queue_work(pf->mbox_wq, &mw->mbox_up_wrk);
|
||||
|
||||
trace_otx2_msg_interrupt(pf->pdev, "UP message from AF to PF",
|
||||
BIT_ULL(0));
|
||||
}
|
||||
|
||||
if (mbox_data & MBOX_DOWN_MSG) {
|
||||
mbox_data &= ~MBOX_DOWN_MSG;
|
||||
otx2_write64(pf, RVU_PF_PFAF_MBOX0, mbox_data);
|
||||
|
||||
mbox = &mw->mbox;
|
||||
mdev = &mbox->dev[0];
|
||||
otx2_sync_mbox_bbuf(mbox, 0);
|
||||
|
||||
hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
if (hdr->num_msgs)
|
||||
queue_work(pf->mbox_wq, &mw->mbox_wrk);
|
||||
|
||||
trace_otx2_msg_interrupt(pf->pdev, "DOWN reply from AF to PF",
|
||||
BIT_ULL(0));
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -3087,6 +3113,7 @@ static void otx2_vf_link_event_task(struct work_struct *work)
|
||||
struct otx2_vf_config *config;
|
||||
struct cgx_link_info_msg *req;
|
||||
struct mbox_msghdr *msghdr;
|
||||
struct delayed_work *dwork;
|
||||
struct otx2_nic *pf;
|
||||
int vf_idx;
|
||||
|
||||
@@ -3095,10 +3122,24 @@ static void otx2_vf_link_event_task(struct work_struct *work)
|
||||
vf_idx = config - config->pf->vf_configs;
|
||||
pf = config->pf;
|
||||
|
||||
if (config->intf_down)
|
||||
return;
|
||||
|
||||
mutex_lock(&pf->mbox.lock);
|
||||
|
||||
dwork = &config->link_event_work;
|
||||
|
||||
if (!otx2_mbox_wait_for_zero(&pf->mbox_pfvf[0].mbox_up, vf_idx)) {
|
||||
schedule_delayed_work(dwork, msecs_to_jiffies(100));
|
||||
mutex_unlock(&pf->mbox.lock);
|
||||
return;
|
||||
}
|
||||
|
||||
msghdr = otx2_mbox_alloc_msg_rsp(&pf->mbox_pfvf[0].mbox_up, vf_idx,
|
||||
sizeof(*req), sizeof(struct msg_rsp));
|
||||
if (!msghdr) {
|
||||
dev_err(pf->dev, "Failed to create VF%d link event\n", vf_idx);
|
||||
mutex_unlock(&pf->mbox.lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3107,7 +3148,11 @@ static void otx2_vf_link_event_task(struct work_struct *work)
|
||||
req->hdr.sig = OTX2_MBOX_REQ_SIG;
|
||||
memcpy(&req->link_info, &pf->linfo, sizeof(req->link_info));
|
||||
|
||||
otx2_mbox_wait_for_zero(&pf->mbox_pfvf[0].mbox_up, vf_idx);
|
||||
|
||||
otx2_sync_mbox_up_msg(&pf->mbox_pfvf[0], vf_idx);
|
||||
|
||||
mutex_unlock(&pf->mbox.lock);
|
||||
}
|
||||
|
||||
static int otx2_sriov_enable(struct pci_dev *pdev, int numvfs)
|
||||
|
||||
@@ -89,16 +89,20 @@ static void otx2vf_vfaf_mbox_handler(struct work_struct *work)
|
||||
struct otx2_mbox *mbox;
|
||||
struct mbox *af_mbox;
|
||||
int offset, id;
|
||||
u16 num_msgs;
|
||||
|
||||
af_mbox = container_of(work, struct mbox, mbox_wrk);
|
||||
mbox = &af_mbox->mbox;
|
||||
mdev = &mbox->dev[0];
|
||||
rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
if (af_mbox->num_msgs == 0)
|
||||
num_msgs = rsp_hdr->num_msgs;
|
||||
|
||||
if (num_msgs == 0)
|
||||
return;
|
||||
|
||||
offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
|
||||
|
||||
for (id = 0; id < af_mbox->num_msgs; id++) {
|
||||
for (id = 0; id < num_msgs; id++) {
|
||||
msg = (struct mbox_msghdr *)(mdev->mbase + offset);
|
||||
otx2vf_process_vfaf_mbox_msg(af_mbox->pfvf, msg);
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
@@ -151,6 +155,7 @@ static void otx2vf_vfaf_mbox_up_handler(struct work_struct *work)
|
||||
struct mbox *vf_mbox;
|
||||
struct otx2_nic *vf;
|
||||
int offset, id;
|
||||
u16 num_msgs;
|
||||
|
||||
vf_mbox = container_of(work, struct mbox, mbox_up_wrk);
|
||||
vf = vf_mbox->pfvf;
|
||||
@@ -158,12 +163,14 @@ static void otx2vf_vfaf_mbox_up_handler(struct work_struct *work)
|
||||
mdev = &mbox->dev[0];
|
||||
|
||||
rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
if (vf_mbox->up_num_msgs == 0)
|
||||
num_msgs = rsp_hdr->num_msgs;
|
||||
|
||||
if (num_msgs == 0)
|
||||
return;
|
||||
|
||||
offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
|
||||
|
||||
for (id = 0; id < vf_mbox->up_num_msgs; id++) {
|
||||
for (id = 0; id < num_msgs; id++) {
|
||||
msg = (struct mbox_msghdr *)(mdev->mbase + offset);
|
||||
otx2vf_process_mbox_msg_up(vf, msg);
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
@@ -178,40 +185,48 @@ static irqreturn_t otx2vf_vfaf_mbox_intr_handler(int irq, void *vf_irq)
|
||||
struct otx2_mbox_dev *mdev;
|
||||
struct otx2_mbox *mbox;
|
||||
struct mbox_hdr *hdr;
|
||||
u64 mbox_data;
|
||||
|
||||
/* Clear the IRQ */
|
||||
otx2_write64(vf, RVU_VF_INT, BIT_ULL(0));
|
||||
|
||||
mbox_data = otx2_read64(vf, RVU_VF_VFPF_MBOX0);
|
||||
|
||||
/* Read latest mbox data */
|
||||
smp_rmb();
|
||||
|
||||
/* Check for PF => VF response messages */
|
||||
mbox = &vf->mbox.mbox;
|
||||
mdev = &mbox->dev[0];
|
||||
otx2_sync_mbox_bbuf(mbox, 0);
|
||||
if (mbox_data & MBOX_DOWN_MSG) {
|
||||
mbox_data &= ~MBOX_DOWN_MSG;
|
||||
otx2_write64(vf, RVU_VF_VFPF_MBOX0, mbox_data);
|
||||
|
||||
trace_otx2_msg_interrupt(mbox->pdev, "PF to VF", BIT_ULL(0));
|
||||
/* Check for PF => VF response messages */
|
||||
mbox = &vf->mbox.mbox;
|
||||
mdev = &mbox->dev[0];
|
||||
otx2_sync_mbox_bbuf(mbox, 0);
|
||||
|
||||
hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
if (hdr->num_msgs) {
|
||||
vf->mbox.num_msgs = hdr->num_msgs;
|
||||
hdr->num_msgs = 0;
|
||||
memset(mbox->hwbase + mbox->rx_start, 0,
|
||||
ALIGN(sizeof(struct mbox_hdr), sizeof(u64)));
|
||||
queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk);
|
||||
hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
if (hdr->num_msgs)
|
||||
queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk);
|
||||
|
||||
trace_otx2_msg_interrupt(mbox->pdev, "DOWN reply from PF to VF",
|
||||
BIT_ULL(0));
|
||||
}
|
||||
/* Check for PF => VF notification messages */
|
||||
mbox = &vf->mbox.mbox_up;
|
||||
mdev = &mbox->dev[0];
|
||||
otx2_sync_mbox_bbuf(mbox, 0);
|
||||
|
||||
hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
if (hdr->num_msgs) {
|
||||
vf->mbox.up_num_msgs = hdr->num_msgs;
|
||||
hdr->num_msgs = 0;
|
||||
memset(mbox->hwbase + mbox->rx_start, 0,
|
||||
ALIGN(sizeof(struct mbox_hdr), sizeof(u64)));
|
||||
queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk);
|
||||
if (mbox_data & MBOX_UP_MSG) {
|
||||
mbox_data &= ~MBOX_UP_MSG;
|
||||
otx2_write64(vf, RVU_VF_VFPF_MBOX0, mbox_data);
|
||||
|
||||
/* Check for PF => VF notification messages */
|
||||
mbox = &vf->mbox.mbox_up;
|
||||
mdev = &mbox->dev[0];
|
||||
otx2_sync_mbox_bbuf(mbox, 0);
|
||||
|
||||
hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
|
||||
if (hdr->num_msgs)
|
||||
queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk);
|
||||
|
||||
trace_otx2_msg_interrupt(mbox->pdev, "UP message from PF to VF",
|
||||
BIT_ULL(0));
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -760,8 +775,8 @@ static void otx2vf_remove(struct pci_dev *pdev)
|
||||
otx2_mcam_flow_del(vf);
|
||||
otx2_shutdown_tc(vf);
|
||||
otx2_shutdown_qos(vf);
|
||||
otx2vf_disable_mbox_intr(vf);
|
||||
otx2_detach_resources(&vf->mbox);
|
||||
otx2vf_disable_mbox_intr(vf);
|
||||
free_percpu(vf->hw.lmt_info);
|
||||
if (test_bit(CN10K_LMTST, &vf->hw.cap_flag))
|
||||
qmem_free(vf->dev, vf->dync_lmt);
|
||||
|
||||
@@ -677,8 +677,7 @@ static int mtk_mac_finish(struct phylink_config *config, unsigned int mode,
|
||||
mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
|
||||
mcr_new = mcr_cur;
|
||||
mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
|
||||
MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK |
|
||||
MAC_MCR_RX_FIFO_CLR_DIS;
|
||||
MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_RX_FIFO_CLR_DIS;
|
||||
|
||||
/* Only update control register when needed! */
|
||||
if (mcr_new != mcr_cur)
|
||||
@@ -694,7 +693,7 @@ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
|
||||
phylink_config);
|
||||
u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
|
||||
|
||||
mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
|
||||
mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK);
|
||||
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
|
||||
}
|
||||
|
||||
@@ -803,7 +802,7 @@ static void mtk_mac_link_up(struct phylink_config *config,
|
||||
if (rx_pause)
|
||||
mcr |= MAC_MCR_FORCE_RX_FC;
|
||||
|
||||
mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN;
|
||||
mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK;
|
||||
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user