forked from Minki/linux
Networking fixes for 5.17-rc3, including fixes from bpf, netfilter,
and ieee802154. Current release - regressions: - Partially revert "net/smc: Add netlink net namespace support", fix uABI breakage - netfilter: - nft_ct: fix use after free when attaching zone template - nft_byteorder: track register operations Previous releases - regressions: - ipheth: fix EOVERFLOW in ipheth_rcvbulk_callback - phy: qca8081: fix speeds lower than 2.5Gb/s - sched: fix use-after-free in tc_new_tfilter() Previous releases - always broken: - tcp: fix mem under-charging with zerocopy sendmsg() - tcp: add missing tcp_skb_can_collapse() test in tcp_shift_skb_data() - neigh: do not trigger immediate probes on NUD_FAILED from neigh_managed_work, avoid a deadlock - bpf: use VM_MAP instead of VM_ALLOC for ringbuf, avoid KASAN false-positives - netfilter: nft_reject_bridge: fix for missing reply from prerouting - smc: forward wakeup to smc socket waitqueue after fallback - ieee802154: - return meaningful error codes from the netlink helpers - mcr20a: fix lifs/sifs periods - at86rf230, ca8210: stop leaking skbs on error paths - macsec: add missing un-offload call for NETDEV_UNREGISTER of parent - ax25: add refcount in ax25_dev to avoid UAF bugs - eth: mlx5e: - fix SFP module EEPROM query - fix broken SKB allocation in HW-GRO - IPsec offload: fix tunnel mode crypto for non-TCP/UDP flows - eth: amd-xgbe: - fix skb data length underflow - ensure reset of the tx_timer_active flag, avoid Tx timeouts - eth: stmmac: fix runtime pm use in stmmac_dvr_remove() - eth: e1000e: handshake with CSME starts from Alder Lake platforms Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmH8X9UACgkQMUZtbf5S IrsxuhAAlAvFHGL6y5Y2gAmhKvVUvCYjiIJBcvk7R66CwYVRxofvlhmxi6GM/Czs 9SrVSaN4RXu3p3d7UtAl1gAQwHqzLIHH3m2g5dSKVvHZWQgkm/+n74x0aZQ9Fll7 mWs9uu5fWsQr/qZBnnjoQTvUxRUNVd4trBy7nXGzkNqJL5j0+2TT4BhH4qalhE28 iPc9YFCyKPdjoWFksteZqD3hAQbXxK/xRRr6xuvFHENlZdEHM6ARftHnJthTG/fY 32rdn9YUkQ9lNtOBJNMN9yP2z1B7TcxASBqjjk55I7XtT1QAI9/PskszavHC0hOk BCSMX779bLNW4+G0wiSKVB4tq4tvswtawq8Hxa6zdU4TKIzfQ84ZL/Nf66GtH+4W C0mbZohmyJV9hQFkNT0ZLeihljd7i4BkDttlbK3uz2IL9tHeX3uSo5V7AgS/Xaf6 frXgbGgjQTaR6IL9AUhfN3GTCx60mzpH/aRpFho8A5xAl3EtHWCJcRhbY/CEhQBR zyCndcLcG5mUzbhx/TxlKrrpRCLxqCUG/Tsb2wCh5jMxO1zonW9Hhv4P1ie6EFuI h+XiJT2WWObS/KTze9S86WOR0zcqrtRqaOGJlNB+/+K8ClZU8UsDTFXLQ0dqpVZF Mvp7VchBzyFFJrrvO8WkkJgLTKdaPJmM9wuWUZb4J6d2MWlmDkE= =qKvf -----END PGP SIGNATURE----- Merge tag 'net-5.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from bpf, netfilter, and ieee802154. Current release - regressions: - Partially revert "net/smc: Add netlink net namespace support", fix uABI breakage - netfilter: - nft_ct: fix use after free when attaching zone template - nft_byteorder: track register operations Previous releases - regressions: - ipheth: fix EOVERFLOW in ipheth_rcvbulk_callback - phy: qca8081: fix speeds lower than 2.5Gb/s - sched: fix use-after-free in tc_new_tfilter() Previous releases - always broken: - tcp: fix mem under-charging with zerocopy sendmsg() - tcp: add missing tcp_skb_can_collapse() test in tcp_shift_skb_data() - neigh: do not trigger immediate probes on NUD_FAILED from neigh_managed_work, avoid a deadlock - bpf: use VM_MAP instead of VM_ALLOC for ringbuf, avoid KASAN false-positives - netfilter: nft_reject_bridge: fix for missing reply from prerouting - smc: forward wakeup to smc socket waitqueue after fallback - ieee802154: - return meaningful error codes from the netlink helpers - mcr20a: fix lifs/sifs periods - at86rf230, ca8210: stop leaking skbs on error paths - macsec: add missing un-offload call for NETDEV_UNREGISTER of parent - ax25: add refcount in ax25_dev to avoid UAF bugs - eth: mlx5e: - fix SFP module EEPROM query - fix broken SKB allocation in HW-GRO - IPsec offload: fix tunnel mode crypto for non-TCP/UDP flows - eth: amd-xgbe: - fix skb data length underflow - ensure reset of the tx_timer_active flag, avoid Tx timeouts - eth: stmmac: fix runtime pm use in stmmac_dvr_remove() - eth: e1000e: handshake with CSME starts from Alder Lake platforms" * tag 'net-5.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (69 commits) ax25: fix reference count leaks of ax25_dev net: stmmac: ensure PTP time register reads are consistent net: ipa: request IPA register values be retained dt-bindings: net: qcom,ipa: add optional qcom,qmp property tools/resolve_btfids: Do not print any commands when building silently bpf: Use VM_MAP instead of VM_ALLOC for ringbuf net, neigh: Do not trigger immediate probes on NUD_FAILED from neigh_managed_work tcp: add missing tcp_skb_can_collapse() test in tcp_shift_skb_data() net: sparx5: do not refer to skb after passing it on Partially revert "net/smc: Add netlink net namespace support" net/mlx5e: Avoid field-overflowing memcpy() net/mlx5e: Use struct_group() for memcpy() region net/mlx5e: Avoid implicit modify hdr for decap drop rule net/mlx5e: IPsec: Fix tunnel mode crypto offload for non TCP/UDP traffic net/mlx5e: IPsec: Fix crypto offload for non TCP/UDP encapsulated traffic net/mlx5e: Don't treat small ceil values as unlimited in HTB offload net/mlx5: E-Switch, Fix uninitialized variable modact net/mlx5e: Fix handling of wrong devices during bond netevent net/mlx5e: Fix broken SKB allocation in HW-GRO net/mlx5e: Fix wrong calculation of header index in HW_GRO ...
This commit is contained in:
commit
eb2eb5161c
@ -107,6 +107,10 @@ properties:
|
||||
- const: imem
|
||||
- const: config
|
||||
|
||||
qcom,qmp:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: phandle to the AOSS side-channel message RAM
|
||||
|
||||
qcom,smem-states:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: State bits used in by the AP to signal the modem.
|
||||
@ -222,6 +226,8 @@ examples:
|
||||
"imem",
|
||||
"config";
|
||||
|
||||
qcom,qmp = <&aoss_qmp>;
|
||||
|
||||
qcom,smem-states = <&ipa_smp2p_out 0>,
|
||||
<&ipa_smp2p_out 1>;
|
||||
qcom,smem-state-names = "ipa-clock-enabled-valid",
|
||||
|
@ -4157,9 +4157,8 @@ N: csky
|
||||
K: csky
|
||||
|
||||
CA8210 IEEE-802.15.4 RADIO DRIVER
|
||||
M: Harry Morris <h.morris@cascoda.com>
|
||||
L: linux-wpan@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
W: https://github.com/Cascoda/ca8210-linux.git
|
||||
F: Documentation/devicetree/bindings/net/ieee802154/ca8210.txt
|
||||
F: drivers/net/ieee802154/ca8210.c
|
||||
|
@ -36,6 +36,7 @@ config NET_DSA_LANTIQ_GSWIP
|
||||
config NET_DSA_MT7530
|
||||
tristate "MediaTek MT753x and MT7621 Ethernet switch support"
|
||||
select NET_DSA_TAG_MTK
|
||||
select MEDIATEK_GE_PHY
|
||||
help
|
||||
This enables support for the MediaTek MT7530, MT7531, and MT7621
|
||||
Ethernet switch chips.
|
||||
|
@ -721,7 +721,9 @@ static void xgbe_stop_timers(struct xgbe_prv_data *pdata)
|
||||
if (!channel->tx_ring)
|
||||
break;
|
||||
|
||||
/* Deactivate the Tx timer */
|
||||
del_timer_sync(&channel->tx_timer);
|
||||
channel->tx_timer_active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2550,6 +2552,14 @@ read_again:
|
||||
buf2_len = xgbe_rx_buf2_len(rdata, packet, len);
|
||||
len += buf2_len;
|
||||
|
||||
if (buf2_len > rdata->rx.buf.dma_len) {
|
||||
/* Hardware inconsistency within the descriptors
|
||||
* that has resulted in a length underflow.
|
||||
*/
|
||||
error = 1;
|
||||
goto skip_data;
|
||||
}
|
||||
|
||||
if (!skb) {
|
||||
skb = xgbe_create_skb(pdata, napi, rdata,
|
||||
buf1_len);
|
||||
@ -2579,8 +2589,10 @@ skip_data:
|
||||
if (!last || context_next)
|
||||
goto read_again;
|
||||
|
||||
if (!skb)
|
||||
if (!skb || error) {
|
||||
dev_kfree_skb(skb);
|
||||
goto next_packet;
|
||||
}
|
||||
|
||||
/* Be sure we don't exceed the configured MTU */
|
||||
max_len = netdev->mtu + ETH_HLEN;
|
||||
|
@ -301,7 +301,7 @@ static int gve_adminq_parse_err(struct gve_priv *priv, u32 status)
|
||||
*/
|
||||
static int gve_adminq_kick_and_wait(struct gve_priv *priv)
|
||||
{
|
||||
u32 tail, head;
|
||||
int tail, head;
|
||||
int i;
|
||||
|
||||
tail = ioread32be(&priv->reg_bar0->adminq_event_counter);
|
||||
|
@ -115,7 +115,8 @@ enum e1000_boards {
|
||||
board_pch_lpt,
|
||||
board_pch_spt,
|
||||
board_pch_cnp,
|
||||
board_pch_tgp
|
||||
board_pch_tgp,
|
||||
board_pch_adp
|
||||
};
|
||||
|
||||
struct e1000_ps_page {
|
||||
@ -502,6 +503,7 @@ extern const struct e1000_info e1000_pch_lpt_info;
|
||||
extern const struct e1000_info e1000_pch_spt_info;
|
||||
extern const struct e1000_info e1000_pch_cnp_info;
|
||||
extern const struct e1000_info e1000_pch_tgp_info;
|
||||
extern const struct e1000_info e1000_pch_adp_info;
|
||||
extern const struct e1000_info e1000_es2_info;
|
||||
|
||||
void e1000e_ptp_init(struct e1000_adapter *adapter);
|
||||
|
@ -6021,3 +6021,23 @@ const struct e1000_info e1000_pch_tgp_info = {
|
||||
.phy_ops = &ich8_phy_ops,
|
||||
.nvm_ops = &spt_nvm_ops,
|
||||
};
|
||||
|
||||
const struct e1000_info e1000_pch_adp_info = {
|
||||
.mac = e1000_pch_adp,
|
||||
.flags = FLAG_IS_ICH
|
||||
| FLAG_HAS_WOL
|
||||
| FLAG_HAS_HW_TIMESTAMP
|
||||
| FLAG_HAS_CTRLEXT_ON_LOAD
|
||||
| FLAG_HAS_AMT
|
||||
| FLAG_HAS_FLASH
|
||||
| FLAG_HAS_JUMBO_FRAMES
|
||||
| FLAG_APME_IN_WUC,
|
||||
.flags2 = FLAG2_HAS_PHY_STATS
|
||||
| FLAG2_HAS_EEE,
|
||||
.pba = 26,
|
||||
.max_hw_frame_size = 9022,
|
||||
.get_variants = e1000_get_variants_ich8lan,
|
||||
.mac_ops = &ich8_mac_ops,
|
||||
.phy_ops = &ich8_phy_ops,
|
||||
.nvm_ops = &spt_nvm_ops,
|
||||
};
|
||||
|
@ -52,6 +52,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
|
||||
[board_pch_spt] = &e1000_pch_spt_info,
|
||||
[board_pch_cnp] = &e1000_pch_cnp_info,
|
||||
[board_pch_tgp] = &e1000_pch_tgp_info,
|
||||
[board_pch_adp] = &e1000_pch_adp_info,
|
||||
};
|
||||
|
||||
struct e1000_reg_info {
|
||||
@ -6341,7 +6342,8 @@ static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter)
|
||||
u32 mac_data;
|
||||
u16 phy_data;
|
||||
|
||||
if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) {
|
||||
if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
|
||||
hw->mac.type >= e1000_pch_adp) {
|
||||
/* Request ME configure the device for S0ix */
|
||||
mac_data = er32(H2ME);
|
||||
mac_data |= E1000_H2ME_START_DPG;
|
||||
@ -6490,7 +6492,8 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
|
||||
u16 phy_data;
|
||||
u32 i = 0;
|
||||
|
||||
if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) {
|
||||
if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
|
||||
hw->mac.type >= e1000_pch_adp) {
|
||||
/* Request ME unconfigure the device from S0ix */
|
||||
mac_data = er32(H2ME);
|
||||
mac_data &= ~E1000_H2ME_START_DPG;
|
||||
@ -7898,22 +7901,22 @@ static const struct pci_device_id e1000_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_TGP_I219_V14), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_TGP_I219_LM15), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_TGP_I219_V15), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM23), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V23), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_LM16), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V16), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_LM17), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V22), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM19), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V19), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V21), board_pch_tgp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM23), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V23), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_LM16), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V16), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_LM17), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V22), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM19), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V19), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_adp },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V21), board_pch_adp },
|
||||
|
||||
{ 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
|
||||
};
|
||||
|
@ -144,6 +144,7 @@ enum i40e_state_t {
|
||||
__I40E_VIRTCHNL_OP_PENDING,
|
||||
__I40E_RECOVERY_MODE,
|
||||
__I40E_VF_RESETS_DISABLED, /* disable resets during i40e_remove */
|
||||
__I40E_IN_REMOVE,
|
||||
__I40E_VFS_RELEASING,
|
||||
/* This must be last as it determines the size of the BITMAP */
|
||||
__I40E_STATE_SIZE__,
|
||||
|
@ -5372,7 +5372,15 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
|
||||
/* There is no need to reset BW when mqprio mode is on. */
|
||||
if (pf->flags & I40E_FLAG_TC_MQPRIO)
|
||||
return 0;
|
||||
if (!vsi->mqprio_qopt.qopt.hw && !(pf->flags & I40E_FLAG_DCB_ENABLED)) {
|
||||
|
||||
if (!vsi->mqprio_qopt.qopt.hw) {
|
||||
if (pf->flags & I40E_FLAG_DCB_ENABLED)
|
||||
goto skip_reset;
|
||||
|
||||
if (IS_ENABLED(CONFIG_I40E_DCB) &&
|
||||
i40e_dcb_hw_get_num_tc(&pf->hw) == 1)
|
||||
goto skip_reset;
|
||||
|
||||
ret = i40e_set_bw_limit(vsi, vsi->seid, 0);
|
||||
if (ret)
|
||||
dev_info(&pf->pdev->dev,
|
||||
@ -5380,6 +5388,8 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
|
||||
vsi->seid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
skip_reset:
|
||||
memset(&bw_data, 0, sizeof(bw_data));
|
||||
bw_data.tc_valid_bits = enabled_tc;
|
||||
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
|
||||
@ -10853,6 +10863,9 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit,
|
||||
bool lock_acquired)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (test_bit(__I40E_IN_REMOVE, pf->state))
|
||||
return;
|
||||
/* Now we wait for GRST to settle out.
|
||||
* We don't have to delete the VEBs or VSIs from the hw switch
|
||||
* because the reset will make them disappear.
|
||||
@ -12212,6 +12225,8 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
|
||||
|
||||
vsi->req_queue_pairs = queue_count;
|
||||
i40e_prep_for_reset(pf);
|
||||
if (test_bit(__I40E_IN_REMOVE, pf->state))
|
||||
return pf->alloc_rss_size;
|
||||
|
||||
pf->alloc_rss_size = new_rss_size;
|
||||
|
||||
@ -13038,6 +13053,10 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
|
||||
if (need_reset)
|
||||
i40e_prep_for_reset(pf);
|
||||
|
||||
/* VSI shall be deleted in a moment, just return EINVAL */
|
||||
if (test_bit(__I40E_IN_REMOVE, pf->state))
|
||||
return -EINVAL;
|
||||
|
||||
old_prog = xchg(&vsi->xdp_prog, prog);
|
||||
|
||||
if (need_reset) {
|
||||
@ -15928,8 +15947,13 @@ static void i40e_remove(struct pci_dev *pdev)
|
||||
i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
|
||||
i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
|
||||
|
||||
while (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
|
||||
/* Grab __I40E_RESET_RECOVERY_PENDING and set __I40E_IN_REMOVE
|
||||
* flags, once they are set, i40e_rebuild should not be called as
|
||||
* i40e_prep_for_reset always returns early.
|
||||
*/
|
||||
while (test_and_set_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
|
||||
usleep_range(1000, 2000);
|
||||
set_bit(__I40E_IN_REMOVE, pf->state);
|
||||
|
||||
if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
|
||||
set_bit(__I40E_VF_RESETS_DISABLED, pf->state);
|
||||
@ -16128,6 +16152,9 @@ static void i40e_pci_error_reset_done(struct pci_dev *pdev)
|
||||
{
|
||||
struct i40e_pf *pf = pci_get_drvdata(pdev);
|
||||
|
||||
if (test_bit(__I40E_IN_REMOVE, pf->state))
|
||||
return;
|
||||
|
||||
i40e_reset_and_rebuild(pf, false, false);
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,7 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
|
||||
struct mlx5e_tx_wqe {
|
||||
struct mlx5_wqe_ctrl_seg ctrl;
|
||||
struct mlx5_wqe_eth_seg eth;
|
||||
struct mlx5_wqe_data_seg data[0];
|
||||
struct mlx5_wqe_data_seg data[];
|
||||
};
|
||||
|
||||
struct mlx5e_rx_wqe_ll {
|
||||
@ -241,8 +241,8 @@ struct mlx5e_umr_wqe {
|
||||
struct mlx5_wqe_umr_ctrl_seg uctrl;
|
||||
struct mlx5_mkey_seg mkc;
|
||||
union {
|
||||
struct mlx5_mtt inline_mtts[0];
|
||||
struct mlx5_klm inline_klms[0];
|
||||
DECLARE_FLEX_ARRAY(struct mlx5_mtt, inline_mtts);
|
||||
DECLARE_FLEX_ARRAY(struct mlx5_klm, inline_klms);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -570,7 +570,8 @@ static int mlx5e_htb_convert_rate(struct mlx5e_priv *priv, u64 rate,
|
||||
|
||||
static void mlx5e_htb_convert_ceil(struct mlx5e_priv *priv, u64 ceil, u32 *max_average_bw)
|
||||
{
|
||||
*max_average_bw = div_u64(ceil, BYTES_IN_MBIT);
|
||||
/* Hardware treats 0 as "unlimited", set at least 1. */
|
||||
*max_average_bw = max_t(u32, div_u64(ceil, BYTES_IN_MBIT), 1);
|
||||
|
||||
qos_dbg(priv->mdev, "Convert: ceil %llu -> max_average_bw %u\n",
|
||||
ceil, *max_average_bw);
|
||||
|
@ -183,18 +183,7 @@ void mlx5e_rep_bond_unslave(struct mlx5_eswitch *esw,
|
||||
|
||||
static bool mlx5e_rep_is_lag_netdev(struct net_device *netdev)
|
||||
{
|
||||
struct mlx5e_rep_priv *rpriv;
|
||||
struct mlx5e_priv *priv;
|
||||
|
||||
/* A given netdev is not a representor or not a slave of LAG configuration */
|
||||
if (!mlx5e_eswitch_rep(netdev) || !netif_is_lag_port(netdev))
|
||||
return false;
|
||||
|
||||
priv = netdev_priv(netdev);
|
||||
rpriv = priv->ppriv;
|
||||
|
||||
/* Egress acl forward to vport is supported only non-uplink representor */
|
||||
return rpriv->rep->vport != MLX5_VPORT_UPLINK;
|
||||
return netif_is_lag_port(netdev) && mlx5e_eswitch_vf_rep(netdev);
|
||||
}
|
||||
|
||||
static void mlx5e_rep_changelowerstate_event(struct net_device *netdev, void *ptr)
|
||||
@ -210,9 +199,6 @@ static void mlx5e_rep_changelowerstate_event(struct net_device *netdev, void *pt
|
||||
u16 fwd_vport_num;
|
||||
int err;
|
||||
|
||||
if (!mlx5e_rep_is_lag_netdev(netdev))
|
||||
return;
|
||||
|
||||
info = ptr;
|
||||
lag_info = info->lower_state_info;
|
||||
/* This is not an event of a representor becoming active slave */
|
||||
@ -266,9 +252,6 @@ static void mlx5e_rep_changeupper_event(struct net_device *netdev, void *ptr)
|
||||
struct net_device *lag_dev;
|
||||
struct mlx5e_priv *priv;
|
||||
|
||||
if (!mlx5e_rep_is_lag_netdev(netdev))
|
||||
return;
|
||||
|
||||
priv = netdev_priv(netdev);
|
||||
rpriv = priv->ppriv;
|
||||
lag_dev = info->upper_dev;
|
||||
@ -293,6 +276,19 @@ static int mlx5e_rep_esw_bond_netevent(struct notifier_block *nb,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
|
||||
struct mlx5e_rep_priv *rpriv;
|
||||
struct mlx5e_rep_bond *bond;
|
||||
struct mlx5e_priv *priv;
|
||||
|
||||
if (!mlx5e_rep_is_lag_netdev(netdev))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
bond = container_of(nb, struct mlx5e_rep_bond, nb);
|
||||
priv = netdev_priv(netdev);
|
||||
rpriv = mlx5_eswitch_get_uplink_priv(priv->mdev->priv.eswitch, REP_ETH);
|
||||
/* Verify VF representor is on the same device of the bond handling the netevent. */
|
||||
if (rpriv->uplink_priv.bond != bond)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_CHANGELOWERSTATE:
|
||||
|
@ -491,7 +491,7 @@ void mlx5e_rep_bridge_init(struct mlx5e_priv *priv)
|
||||
}
|
||||
|
||||
br_offloads->netdev_nb.notifier_call = mlx5_esw_bridge_switchdev_port_event;
|
||||
err = register_netdevice_notifier(&br_offloads->netdev_nb);
|
||||
err = register_netdevice_notifier_net(&init_net, &br_offloads->netdev_nb);
|
||||
if (err) {
|
||||
esw_warn(mdev, "Failed to register bridge offloads netdevice notifier (err=%d)\n",
|
||||
err);
|
||||
@ -509,7 +509,9 @@ err_register_swdev_blk:
|
||||
err_register_swdev:
|
||||
destroy_workqueue(br_offloads->wq);
|
||||
err_alloc_wq:
|
||||
rtnl_lock();
|
||||
mlx5_esw_bridge_cleanup(esw);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
void mlx5e_rep_bridge_cleanup(struct mlx5e_priv *priv)
|
||||
@ -524,7 +526,7 @@ void mlx5e_rep_bridge_cleanup(struct mlx5e_priv *priv)
|
||||
return;
|
||||
|
||||
cancel_delayed_work_sync(&br_offloads->update_work);
|
||||
unregister_netdevice_notifier(&br_offloads->netdev_nb);
|
||||
unregister_netdevice_notifier_net(&init_net, &br_offloads->netdev_nb);
|
||||
unregister_switchdev_blocking_notifier(&br_offloads->nb_blk);
|
||||
unregister_switchdev_notifier(&br_offloads->nb);
|
||||
destroy_workqueue(br_offloads->wq);
|
||||
|
@ -167,6 +167,11 @@ static inline u16 mlx5e_txqsq_get_next_pi(struct mlx5e_txqsq *sq, u16 size)
|
||||
return pi;
|
||||
}
|
||||
|
||||
static inline u16 mlx5e_shampo_get_cqe_header_index(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
|
||||
{
|
||||
return be16_to_cpu(cqe->shampo.header_entry_index) & (rq->mpwqe.shampo->hd_per_wq - 1);
|
||||
}
|
||||
|
||||
struct mlx5e_shampo_umr {
|
||||
u16 len;
|
||||
};
|
||||
|
@ -341,8 +341,10 @@ mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptxd,
|
||||
|
||||
/* copy the inline part if required */
|
||||
if (sq->min_inline_mode != MLX5_INLINE_MODE_NONE) {
|
||||
memcpy(eseg->inline_hdr.start, xdptxd->data, MLX5E_XDP_MIN_INLINE);
|
||||
memcpy(eseg->inline_hdr.start, xdptxd->data, sizeof(eseg->inline_hdr.start));
|
||||
eseg->inline_hdr.sz = cpu_to_be16(MLX5E_XDP_MIN_INLINE);
|
||||
memcpy(dseg, xdptxd->data + sizeof(eseg->inline_hdr.start),
|
||||
MLX5E_XDP_MIN_INLINE - sizeof(eseg->inline_hdr.start));
|
||||
dma_len -= MLX5E_XDP_MIN_INLINE;
|
||||
dma_addr += MLX5E_XDP_MIN_INLINE;
|
||||
dseg++;
|
||||
|
@ -157,11 +157,20 @@ static void mlx5e_ipsec_set_swp(struct sk_buff *skb,
|
||||
/* Tunnel mode */
|
||||
if (mode == XFRM_MODE_TUNNEL) {
|
||||
eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2;
|
||||
eseg->swp_inner_l4_offset = skb_inner_transport_offset(skb) / 2;
|
||||
if (xo->proto == IPPROTO_IPV6)
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
|
||||
if (inner_ip_hdr(skb)->protocol == IPPROTO_UDP)
|
||||
|
||||
switch (xo->inner_ipproto) {
|
||||
case IPPROTO_UDP:
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L4_UDP;
|
||||
fallthrough;
|
||||
case IPPROTO_TCP:
|
||||
/* IP | ESP | IP | [TCP | UDP] */
|
||||
eseg->swp_inner_l4_offset = skb_inner_transport_offset(skb) / 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -131,14 +131,17 @@ static inline bool
|
||||
mlx5e_ipsec_txwqe_build_eseg_csum(struct mlx5e_txqsq *sq, struct sk_buff *skb,
|
||||
struct mlx5_wqe_eth_seg *eseg)
|
||||
{
|
||||
struct xfrm_offload *xo = xfrm_offload(skb);
|
||||
u8 inner_ipproto;
|
||||
|
||||
if (!mlx5e_ipsec_eseg_meta(eseg))
|
||||
return false;
|
||||
|
||||
eseg->cs_flags = MLX5_ETH_WQE_L3_CSUM;
|
||||
if (xo->inner_ipproto) {
|
||||
eseg->cs_flags |= MLX5_ETH_WQE_L4_INNER_CSUM | MLX5_ETH_WQE_L3_INNER_CSUM;
|
||||
inner_ipproto = xfrm_offload(skb)->inner_ipproto;
|
||||
if (inner_ipproto) {
|
||||
eseg->cs_flags |= MLX5_ETH_WQE_L3_INNER_CSUM;
|
||||
if (inner_ipproto == IPPROTO_TCP || inner_ipproto == IPPROTO_UDP)
|
||||
eseg->cs_flags |= MLX5_ETH_WQE_L4_INNER_CSUM;
|
||||
} else if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
|
||||
eseg->cs_flags |= MLX5_ETH_WQE_L4_CSUM;
|
||||
sq->stats->csum_partial_inner++;
|
||||
|
@ -1117,7 +1117,7 @@ static void mlx5e_shampo_update_ipv6_udp_hdr(struct mlx5e_rq *rq, struct ipv6hdr
|
||||
static void mlx5e_shampo_update_fin_psh_flags(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
|
||||
struct tcphdr *skb_tcp_hd)
|
||||
{
|
||||
u16 header_index = be16_to_cpu(cqe->shampo.header_entry_index);
|
||||
u16 header_index = mlx5e_shampo_get_cqe_header_index(rq, cqe);
|
||||
struct tcphdr *last_tcp_hd;
|
||||
void *last_hd_addr;
|
||||
|
||||
@ -1871,7 +1871,7 @@ mlx5e_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
|
||||
return skb;
|
||||
}
|
||||
|
||||
static void
|
||||
static struct sk_buff *
|
||||
mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
|
||||
struct mlx5_cqe64 *cqe, u16 header_index)
|
||||
{
|
||||
@ -1895,7 +1895,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
|
||||
skb = mlx5e_build_linear_skb(rq, hdr, frag_size, rx_headroom, head_size);
|
||||
|
||||
if (unlikely(!skb))
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* queue up for recycling/reuse */
|
||||
page_ref_inc(head->page);
|
||||
@ -1907,7 +1907,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
|
||||
ALIGN(head_size, sizeof(long)));
|
||||
if (unlikely(!skb)) {
|
||||
rq->stats->buff_alloc_err++;
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prefetchw(skb->data);
|
||||
@ -1918,9 +1918,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
|
||||
skb->tail += head_size;
|
||||
skb->len += head_size;
|
||||
}
|
||||
rq->hw_gro_data->skb = skb;
|
||||
NAPI_GRO_CB(skb)->count = 1;
|
||||
skb_shinfo(skb)->gso_size = mpwrq_get_cqe_byte_cnt(cqe) - head_size;
|
||||
return skb;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1973,13 +1971,14 @@ mlx5e_free_rx_shampo_hd_entry(struct mlx5e_rq *rq, u16 header_index)
|
||||
static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
|
||||
{
|
||||
u16 data_bcnt = mpwrq_get_cqe_byte_cnt(cqe) - cqe->shampo.header_size;
|
||||
u16 header_index = be16_to_cpu(cqe->shampo.header_entry_index);
|
||||
u16 header_index = mlx5e_shampo_get_cqe_header_index(rq, cqe);
|
||||
u32 wqe_offset = be32_to_cpu(cqe->shampo.data_offset);
|
||||
u16 cstrides = mpwrq_get_cqe_consumed_strides(cqe);
|
||||
u32 data_offset = wqe_offset & (PAGE_SIZE - 1);
|
||||
u32 cqe_bcnt = mpwrq_get_cqe_byte_cnt(cqe);
|
||||
u16 wqe_id = be16_to_cpu(cqe->wqe_id);
|
||||
u32 page_idx = wqe_offset >> PAGE_SHIFT;
|
||||
u16 head_size = cqe->shampo.header_size;
|
||||
struct sk_buff **skb = &rq->hw_gro_data->skb;
|
||||
bool flush = cqe->shampo.flush;
|
||||
bool match = cqe->shampo.match;
|
||||
@ -2011,9 +2010,16 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
|
||||
}
|
||||
|
||||
if (!*skb) {
|
||||
mlx5e_skb_from_cqe_shampo(rq, wi, cqe, header_index);
|
||||
if (likely(head_size))
|
||||
*skb = mlx5e_skb_from_cqe_shampo(rq, wi, cqe, header_index);
|
||||
else
|
||||
*skb = mlx5e_skb_from_cqe_mpwrq_nonlinear(rq, wi, cqe_bcnt, data_offset,
|
||||
page_idx);
|
||||
if (unlikely(!*skb))
|
||||
goto free_hd_entry;
|
||||
|
||||
NAPI_GRO_CB(*skb)->count = 1;
|
||||
skb_shinfo(*skb)->gso_size = cqe_bcnt - head_size;
|
||||
} else {
|
||||
NAPI_GRO_CB(*skb)->count++;
|
||||
if (NAPI_GRO_CB(*skb)->count == 2 &&
|
||||
@ -2027,8 +2033,10 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
|
||||
}
|
||||
}
|
||||
|
||||
di = &wi->umr.dma_info[page_idx];
|
||||
mlx5e_fill_skb_data(*skb, rq, di, data_bcnt, data_offset);
|
||||
if (likely(head_size)) {
|
||||
di = &wi->umr.dma_info[page_idx];
|
||||
mlx5e_fill_skb_data(*skb, rq, di, data_bcnt, data_offset);
|
||||
}
|
||||
|
||||
mlx5e_shampo_complete_rx_cqe(rq, cqe, cqe_bcnt, *skb);
|
||||
if (flush)
|
||||
|
@ -1414,7 +1414,8 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
if (!attr->chain && esw_attr->int_port) {
|
||||
if (!attr->chain && esw_attr->int_port &&
|
||||
attr->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
|
||||
/* If decap route device is internal port, change the
|
||||
* source vport value in reg_c0 back to uplink just in
|
||||
* case the rule performs goto chain > 0. If we have a miss
|
||||
@ -3191,6 +3192,18 @@ actions_match_supported(struct mlx5e_priv *priv,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(~actions &
|
||||
(MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP))) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Rule cannot support forward+drop action");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR &&
|
||||
actions & MLX5_FLOW_CONTEXT_ACTION_DROP) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Drop with modify header action is not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR &&
|
||||
!modify_header_match_supported(priv, &parse_attr->spec, flow_action,
|
||||
actions, ct_flow, ct_clear, extack))
|
||||
|
@ -208,7 +208,7 @@ static inline void mlx5e_insert_vlan(void *start, struct sk_buff *skb, u16 ihs)
|
||||
int cpy1_sz = 2 * ETH_ALEN;
|
||||
int cpy2_sz = ihs - cpy1_sz;
|
||||
|
||||
memcpy(vhdr, skb->data, cpy1_sz);
|
||||
memcpy(&vhdr->addrs, skb->data, cpy1_sz);
|
||||
vhdr->h_vlan_proto = skb->vlan_proto;
|
||||
vhdr->h_vlan_TCI = cpu_to_be16(skb_vlan_tag_get(skb));
|
||||
memcpy(&vhdr->h_vlan_encapsulated_proto, skb->data + cpy1_sz, cpy2_sz);
|
||||
|
@ -1574,6 +1574,8 @@ struct mlx5_esw_bridge_offloads *mlx5_esw_bridge_init(struct mlx5_eswitch *esw)
|
||||
{
|
||||
struct mlx5_esw_bridge_offloads *br_offloads;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
br_offloads = kvzalloc(sizeof(*br_offloads), GFP_KERNEL);
|
||||
if (!br_offloads)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
@ -1590,6 +1592,8 @@ void mlx5_esw_bridge_cleanup(struct mlx5_eswitch *esw)
|
||||
{
|
||||
struct mlx5_esw_bridge_offloads *br_offloads = esw->br_offloads;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (!br_offloads)
|
||||
return;
|
||||
|
||||
|
@ -21,7 +21,7 @@ DECLARE_EVENT_CLASS(mlx5_esw_bridge_fdb_template,
|
||||
__field(unsigned int, used)
|
||||
),
|
||||
TP_fast_assign(
|
||||
strncpy(__entry->dev_name,
|
||||
strscpy(__entry->dev_name,
|
||||
netdev_name(fdb->dev),
|
||||
IFNAMSIZ);
|
||||
memcpy(__entry->addr, fdb->key.addr, ETH_ALEN);
|
||||
|
@ -132,7 +132,7 @@ static void mlx5_stop_sync_reset_poll(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
|
||||
|
||||
del_timer(&fw_reset->timer);
|
||||
del_timer_sync(&fw_reset->timer);
|
||||
}
|
||||
|
||||
static void mlx5_sync_reset_clear_reset_requested(struct mlx5_core_dev *dev, bool poll_health)
|
||||
|
@ -121,12 +121,13 @@ u32 mlx5_chains_get_nf_ft_chain(struct mlx5_fs_chains *chains)
|
||||
|
||||
u32 mlx5_chains_get_prio_range(struct mlx5_fs_chains *chains)
|
||||
{
|
||||
if (!mlx5_chains_prios_supported(chains))
|
||||
return 1;
|
||||
|
||||
if (mlx5_chains_ignore_flow_level_supported(chains))
|
||||
return UINT_MAX;
|
||||
|
||||
if (!chains->dev->priv.eswitch ||
|
||||
chains->dev->priv.eswitch->mode != MLX5_ESWITCH_OFFLOADS)
|
||||
return 1;
|
||||
|
||||
/* We should get here only for eswitch case */
|
||||
return FDB_TC_MAX_PRIO;
|
||||
}
|
||||
@ -211,7 +212,7 @@ static int
|
||||
create_chain_restore(struct fs_chain *chain)
|
||||
{
|
||||
struct mlx5_eswitch *esw = chain->chains->dev->priv.eswitch;
|
||||
char modact[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)];
|
||||
u8 modact[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
|
||||
struct mlx5_fs_chains *chains = chain->chains;
|
||||
enum mlx5e_tc_attr_to_reg chain_to_reg;
|
||||
struct mlx5_modify_hdr *mod_hdr;
|
||||
|
@ -406,23 +406,24 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
|
||||
|
||||
switch (module_id) {
|
||||
case MLX5_MODULE_ID_SFP:
|
||||
mlx5_sfp_eeprom_params_set(&query.i2c_address, &query.page, &query.offset);
|
||||
mlx5_sfp_eeprom_params_set(&query.i2c_address, &query.page, &offset);
|
||||
break;
|
||||
case MLX5_MODULE_ID_QSFP:
|
||||
case MLX5_MODULE_ID_QSFP_PLUS:
|
||||
case MLX5_MODULE_ID_QSFP28:
|
||||
mlx5_qsfp_eeprom_params_set(&query.i2c_address, &query.page, &query.offset);
|
||||
mlx5_qsfp_eeprom_params_set(&query.i2c_address, &query.page, &offset);
|
||||
break;
|
||||
default:
|
||||
mlx5_core_err(dev, "Module ID not recognized: 0x%x\n", module_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (query.offset + size > MLX5_EEPROM_PAGE_LENGTH)
|
||||
if (offset + size > MLX5_EEPROM_PAGE_LENGTH)
|
||||
/* Cross pages read, read until offset 256 in low page */
|
||||
size -= offset + size - MLX5_EEPROM_PAGE_LENGTH;
|
||||
size = MLX5_EEPROM_PAGE_LENGTH - offset;
|
||||
|
||||
query.size = size;
|
||||
query.offset = offset;
|
||||
|
||||
return mlx5_query_mcia(dev, &query, data);
|
||||
}
|
||||
|
@ -145,9 +145,9 @@ static void sparx5_xtr_grp(struct sparx5 *sparx5, u8 grp, bool byte_swap)
|
||||
skb_put(skb, byte_cnt - ETH_FCS_LEN);
|
||||
eth_skb_pad(skb);
|
||||
skb->protocol = eth_type_trans(skb, netdev);
|
||||
netif_rx(skb);
|
||||
netdev->stats.rx_bytes += skb->len;
|
||||
netdev->stats.rx_packets++;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
static int sparx5_inject(struct sparx5 *sparx5,
|
||||
|
@ -1648,7 +1648,7 @@ static int smc911x_ethtool_geteeprom(struct net_device *dev,
|
||||
return ret;
|
||||
if ((ret=smc911x_ethtool_read_eeprom_byte(dev, &eebuf[i]))!=0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
memcpy(data, eebuf+eeprom->offset, eeprom->len);
|
||||
return 0;
|
||||
}
|
||||
@ -1667,11 +1667,11 @@ static int smc911x_ethtool_seteeprom(struct net_device *dev,
|
||||
return ret;
|
||||
/* write byte */
|
||||
if ((ret=smc911x_ethtool_write_eeprom_byte(dev, *data))!=0)
|
||||
return ret;
|
||||
return ret;
|
||||
if ((ret=smc911x_ethtool_write_eeprom_cmd(dev, E2P_CMD_EPC_CMD_WRITE_, i ))!=0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smc911x_ethtool_geteeprom_len(struct net_device *dev)
|
||||
|
@ -49,13 +49,15 @@ struct visconti_eth {
|
||||
void __iomem *reg;
|
||||
u32 phy_intf_sel;
|
||||
struct clk *phy_ref_clk;
|
||||
struct device *dev;
|
||||
spinlock_t lock; /* lock to protect register update */
|
||||
};
|
||||
|
||||
static void visconti_eth_fix_mac_speed(void *priv, unsigned int speed)
|
||||
{
|
||||
struct visconti_eth *dwmac = priv;
|
||||
unsigned int val, clk_sel_val;
|
||||
struct net_device *netdev = dev_get_drvdata(dwmac->dev);
|
||||
unsigned int val, clk_sel_val = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dwmac->lock, flags);
|
||||
@ -85,7 +87,9 @@ static void visconti_eth_fix_mac_speed(void *priv, unsigned int speed)
|
||||
break;
|
||||
default:
|
||||
/* No bit control */
|
||||
break;
|
||||
netdev_err(netdev, "Unsupported speed request (%d)", speed);
|
||||
spin_unlock_irqrestore(&dwmac->lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
writel(val, dwmac->reg + MAC_CTRL_REG);
|
||||
@ -229,6 +233,7 @@ static int visconti_eth_dwmac_probe(struct platform_device *pdev)
|
||||
|
||||
spin_lock_init(&dwmac->lock);
|
||||
dwmac->reg = stmmac_res.addr;
|
||||
dwmac->dev = &pdev->dev;
|
||||
plat_dat->bsp_priv = dwmac;
|
||||
plat_dat->fix_mac_speed = visconti_eth_fix_mac_speed;
|
||||
|
||||
|
@ -150,6 +150,7 @@
|
||||
|
||||
#define NUM_DWMAC100_DMA_REGS 9
|
||||
#define NUM_DWMAC1000_DMA_REGS 23
|
||||
#define NUM_DWMAC4_DMA_REGS 27
|
||||
|
||||
void dwmac_enable_dma_transmission(void __iomem *ioaddr);
|
||||
void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx);
|
||||
|
@ -21,10 +21,18 @@
|
||||
#include "dwxgmac2.h"
|
||||
|
||||
#define REG_SPACE_SIZE 0x1060
|
||||
#define GMAC4_REG_SPACE_SIZE 0x116C
|
||||
#define MAC100_ETHTOOL_NAME "st_mac100"
|
||||
#define GMAC_ETHTOOL_NAME "st_gmac"
|
||||
#define XGMAC_ETHTOOL_NAME "st_xgmac"
|
||||
|
||||
/* Same as DMA_CHAN_BASE_ADDR defined in dwmac4_dma.h
|
||||
*
|
||||
* It is here because dwmac_dma.h and dwmac4_dam.h can not be included at the
|
||||
* same time due to the conflicting macro names.
|
||||
*/
|
||||
#define GMAC4_DMA_CHAN_BASE_ADDR 0x00001100
|
||||
|
||||
#define ETHTOOL_DMA_OFFSET 55
|
||||
|
||||
struct stmmac_stats {
|
||||
@ -434,6 +442,8 @@ static int stmmac_ethtool_get_regs_len(struct net_device *dev)
|
||||
|
||||
if (priv->plat->has_xgmac)
|
||||
return XGMAC_REGSIZE * 4;
|
||||
else if (priv->plat->has_gmac4)
|
||||
return GMAC4_REG_SPACE_SIZE;
|
||||
return REG_SPACE_SIZE;
|
||||
}
|
||||
|
||||
@ -446,8 +456,13 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
|
||||
stmmac_dump_mac_regs(priv, priv->hw, reg_space);
|
||||
stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space);
|
||||
|
||||
if (!priv->plat->has_xgmac) {
|
||||
/* Copy DMA registers to where ethtool expects them */
|
||||
/* Copy DMA registers to where ethtool expects them */
|
||||
if (priv->plat->has_gmac4) {
|
||||
/* GMAC4 dumps its DMA registers at its DMA_CHAN_BASE_ADDR */
|
||||
memcpy(®_space[ETHTOOL_DMA_OFFSET],
|
||||
®_space[GMAC4_DMA_CHAN_BASE_ADDR / 4],
|
||||
NUM_DWMAC4_DMA_REGS * 4);
|
||||
} else if (!priv->plat->has_xgmac) {
|
||||
memcpy(®_space[ETHTOOL_DMA_OFFSET],
|
||||
®_space[DMA_BUS_MODE / 4],
|
||||
NUM_DWMAC1000_DMA_REGS * 4);
|
||||
|
@ -145,15 +145,20 @@ static int adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec,
|
||||
|
||||
static void get_systime(void __iomem *ioaddr, u64 *systime)
|
||||
{
|
||||
u64 ns;
|
||||
u64 ns, sec0, sec1;
|
||||
|
||||
/* Get the TSSS value */
|
||||
ns = readl(ioaddr + PTP_STNSR);
|
||||
/* Get the TSS and convert sec time value to nanosecond */
|
||||
ns += readl(ioaddr + PTP_STSR) * 1000000000ULL;
|
||||
/* Get the TSS value */
|
||||
sec1 = readl_relaxed(ioaddr + PTP_STSR);
|
||||
do {
|
||||
sec0 = sec1;
|
||||
/* Get the TSSS value */
|
||||
ns = readl_relaxed(ioaddr + PTP_STNSR);
|
||||
/* Get the TSS value */
|
||||
sec1 = readl_relaxed(ioaddr + PTP_STSR);
|
||||
} while (sec0 != sec1);
|
||||
|
||||
if (systime)
|
||||
*systime = ns;
|
||||
*systime = ns + (sec1 * 1000000000ULL);
|
||||
}
|
||||
|
||||
static void get_ptptime(void __iomem *ptpaddr, u64 *ptp_time)
|
||||
|
@ -7252,6 +7252,10 @@ int stmmac_dvr_remove(struct device *dev)
|
||||
|
||||
netdev_info(priv->dev, "%s: removing driver", __func__);
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_put_noidle(dev);
|
||||
|
||||
stmmac_stop_all_dma(priv);
|
||||
stmmac_mac_set(priv, priv->ioaddr, false);
|
||||
netif_carrier_off(ndev);
|
||||
@ -7270,8 +7274,6 @@ int stmmac_dvr_remove(struct device *dev)
|
||||
if (priv->plat->stmmac_rst)
|
||||
reset_control_assert(priv->plat->stmmac_rst);
|
||||
reset_control_assert(priv->plat->stmmac_ahb_rst);
|
||||
pm_runtime_put(dev);
|
||||
pm_runtime_disable(dev);
|
||||
if (priv->hw->pcs != STMMAC_PCS_TBI &&
|
||||
priv->hw->pcs != STMMAC_PCS_RTBI)
|
||||
stmmac_mdio_unregister(ndev);
|
||||
|
@ -100,6 +100,7 @@ struct at86rf230_local {
|
||||
unsigned long cal_timeout;
|
||||
bool is_tx;
|
||||
bool is_tx_from_off;
|
||||
bool was_tx;
|
||||
u8 tx_retry;
|
||||
struct sk_buff *tx_skb;
|
||||
struct at86rf230_state_change tx;
|
||||
@ -343,7 +344,11 @@ at86rf230_async_error_recover_complete(void *context)
|
||||
if (ctx->free)
|
||||
kfree(ctx);
|
||||
|
||||
ieee802154_wake_queue(lp->hw);
|
||||
if (lp->was_tx) {
|
||||
lp->was_tx = 0;
|
||||
dev_kfree_skb_any(lp->tx_skb);
|
||||
ieee802154_wake_queue(lp->hw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -352,7 +357,11 @@ at86rf230_async_error_recover(void *context)
|
||||
struct at86rf230_state_change *ctx = context;
|
||||
struct at86rf230_local *lp = ctx->lp;
|
||||
|
||||
lp->is_tx = 0;
|
||||
if (lp->is_tx) {
|
||||
lp->was_tx = 1;
|
||||
lp->is_tx = 0;
|
||||
}
|
||||
|
||||
at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON,
|
||||
at86rf230_async_error_recover_complete);
|
||||
}
|
||||
|
@ -1771,6 +1771,7 @@ static int ca8210_async_xmit_complete(
|
||||
status
|
||||
);
|
||||
if (status != MAC_TRANSACTION_OVERFLOW) {
|
||||
dev_kfree_skb_any(priv->tx_skb);
|
||||
ieee802154_wake_queue(priv->hw);
|
||||
return 0;
|
||||
}
|
||||
|
@ -786,6 +786,7 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev,
|
||||
goto err_pib;
|
||||
}
|
||||
|
||||
pib->channel = 13;
|
||||
rcu_assign_pointer(phy->pib, pib);
|
||||
phy->idx = idx;
|
||||
INIT_LIST_HEAD(&phy->edges);
|
||||
|
@ -976,8 +976,8 @@ static void mcr20a_hw_setup(struct mcr20a_local *lp)
|
||||
dev_dbg(printdev(lp), "%s\n", __func__);
|
||||
|
||||
phy->symbol_duration = 16;
|
||||
phy->lifs_period = 40;
|
||||
phy->sifs_period = 12;
|
||||
phy->lifs_period = 40 * phy->symbol_duration;
|
||||
phy->sifs_period = 12 * phy->symbol_duration;
|
||||
|
||||
hw->flags = IEEE802154_HW_TX_OMIT_CKSUM |
|
||||
IEEE802154_HW_AFILT |
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include "linux/soc/qcom/qcom_aoss.h"
|
||||
|
||||
#include "ipa.h"
|
||||
#include "ipa_power.h"
|
||||
#include "ipa_endpoint.h"
|
||||
@ -64,6 +66,7 @@ enum ipa_power_flag {
|
||||
* struct ipa_power - IPA power management information
|
||||
* @dev: IPA device pointer
|
||||
* @core: IPA core clock
|
||||
* @qmp: QMP handle for AOSS communication
|
||||
* @spinlock: Protects modem TX queue enable/disable
|
||||
* @flags: Boolean state flags
|
||||
* @interconnect_count: Number of elements in interconnect[]
|
||||
@ -72,6 +75,7 @@ enum ipa_power_flag {
|
||||
struct ipa_power {
|
||||
struct device *dev;
|
||||
struct clk *core;
|
||||
struct qmp *qmp;
|
||||
spinlock_t spinlock; /* used with STOPPED/STARTED power flags */
|
||||
DECLARE_BITMAP(flags, IPA_POWER_FLAG_COUNT);
|
||||
u32 interconnect_count;
|
||||
@ -382,6 +386,47 @@ void ipa_power_modem_queue_active(struct ipa *ipa)
|
||||
clear_bit(IPA_POWER_FLAG_STARTED, ipa->power->flags);
|
||||
}
|
||||
|
||||
static int ipa_power_retention_init(struct ipa_power *power)
|
||||
{
|
||||
struct qmp *qmp = qmp_get(power->dev);
|
||||
|
||||
if (IS_ERR(qmp)) {
|
||||
if (PTR_ERR(qmp) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
/* We assume any other error means it's not defined/needed */
|
||||
qmp = NULL;
|
||||
}
|
||||
power->qmp = qmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ipa_power_retention_exit(struct ipa_power *power)
|
||||
{
|
||||
qmp_put(power->qmp);
|
||||
power->qmp = NULL;
|
||||
}
|
||||
|
||||
/* Control register retention on power collapse */
|
||||
void ipa_power_retention(struct ipa *ipa, bool enable)
|
||||
{
|
||||
static const char fmt[] = "{ class: bcm, res: ipa_pc, val: %c }";
|
||||
struct ipa_power *power = ipa->power;
|
||||
char buf[36]; /* Exactly enough for fmt[]; size a multiple of 4 */
|
||||
int ret;
|
||||
|
||||
if (!power->qmp)
|
||||
return; /* Not needed on this platform */
|
||||
|
||||
(void)snprintf(buf, sizeof(buf), fmt, enable ? '1' : '0');
|
||||
|
||||
ret = qmp_send(power->qmp, buf, sizeof(buf));
|
||||
if (ret)
|
||||
dev_err(power->dev, "error %d sending QMP %sable request\n",
|
||||
ret, enable ? "en" : "dis");
|
||||
}
|
||||
|
||||
int ipa_power_setup(struct ipa *ipa)
|
||||
{
|
||||
int ret;
|
||||
@ -438,12 +483,18 @@ ipa_power_init(struct device *dev, const struct ipa_power_data *data)
|
||||
if (ret)
|
||||
goto err_kfree;
|
||||
|
||||
ret = ipa_power_retention_init(power);
|
||||
if (ret)
|
||||
goto err_interconnect_exit;
|
||||
|
||||
pm_runtime_set_autosuspend_delay(dev, IPA_AUTOSUSPEND_DELAY);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return power;
|
||||
|
||||
err_interconnect_exit:
|
||||
ipa_interconnect_exit(power);
|
||||
err_kfree:
|
||||
kfree(power);
|
||||
err_clk_put:
|
||||
@ -460,6 +511,7 @@ void ipa_power_exit(struct ipa_power *power)
|
||||
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_dont_use_autosuspend(dev);
|
||||
ipa_power_retention_exit(power);
|
||||
ipa_interconnect_exit(power);
|
||||
kfree(power);
|
||||
clk_put(clk);
|
||||
|
@ -40,6 +40,13 @@ void ipa_power_modem_queue_wake(struct ipa *ipa);
|
||||
*/
|
||||
void ipa_power_modem_queue_active(struct ipa *ipa);
|
||||
|
||||
/**
|
||||
* ipa_power_retention() - Control register retention on power collapse
|
||||
* @ipa: IPA pointer
|
||||
* @enable: Whether retention should be enabled or disabled
|
||||
*/
|
||||
void ipa_power_retention(struct ipa *ipa, bool enable);
|
||||
|
||||
/**
|
||||
* ipa_power_setup() - Set up IPA power management
|
||||
* @ipa: IPA pointer
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "ipa.h"
|
||||
#include "ipa_uc.h"
|
||||
#include "ipa_power.h"
|
||||
|
||||
/**
|
||||
* DOC: The IPA embedded microcontroller
|
||||
@ -154,6 +155,7 @@ static void ipa_uc_response_hdlr(struct ipa *ipa, enum ipa_irq_id irq_id)
|
||||
case IPA_UC_RESPONSE_INIT_COMPLETED:
|
||||
if (ipa->uc_powered) {
|
||||
ipa->uc_loaded = true;
|
||||
ipa_power_retention(ipa, true);
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
(void)pm_runtime_put_autosuspend(dev);
|
||||
ipa->uc_powered = false;
|
||||
@ -184,6 +186,9 @@ void ipa_uc_deconfig(struct ipa *ipa)
|
||||
|
||||
ipa_interrupt_remove(ipa->interrupt, IPA_IRQ_UC_1);
|
||||
ipa_interrupt_remove(ipa->interrupt, IPA_IRQ_UC_0);
|
||||
if (ipa->uc_loaded)
|
||||
ipa_power_retention(ipa, false);
|
||||
|
||||
if (!ipa->uc_powered)
|
||||
return;
|
||||
|
||||
|
@ -3870,6 +3870,18 @@ static void macsec_common_dellink(struct net_device *dev, struct list_head *head
|
||||
struct macsec_dev *macsec = macsec_priv(dev);
|
||||
struct net_device *real_dev = macsec->real_dev;
|
||||
|
||||
/* If h/w offloading is available, propagate to the device */
|
||||
if (macsec_is_offloaded(macsec)) {
|
||||
const struct macsec_ops *ops;
|
||||
struct macsec_context ctx;
|
||||
|
||||
ops = macsec_get_ops(netdev_priv(dev), &ctx);
|
||||
if (ops) {
|
||||
ctx.secy = &macsec->secy;
|
||||
macsec_offload(ops->mdo_del_secy, &ctx);
|
||||
}
|
||||
}
|
||||
|
||||
unregister_netdevice_queue(dev, head);
|
||||
list_del_rcu(&macsec->secys);
|
||||
macsec_del_dev(macsec);
|
||||
@ -3884,18 +3896,6 @@ static void macsec_dellink(struct net_device *dev, struct list_head *head)
|
||||
struct net_device *real_dev = macsec->real_dev;
|
||||
struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev);
|
||||
|
||||
/* If h/w offloading is available, propagate to the device */
|
||||
if (macsec_is_offloaded(macsec)) {
|
||||
const struct macsec_ops *ops;
|
||||
struct macsec_context ctx;
|
||||
|
||||
ops = macsec_get_ops(netdev_priv(dev), &ctx);
|
||||
if (ops) {
|
||||
ctx.secy = &macsec->secy;
|
||||
macsec_offload(ops->mdo_del_secy, &ctx);
|
||||
}
|
||||
}
|
||||
|
||||
macsec_common_dellink(dev, head);
|
||||
|
||||
if (list_empty(&rxd->secys)) {
|
||||
@ -4018,6 +4018,15 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
|
||||
!macsec_check_offload(macsec->offload, macsec))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* send_sci must be set to true when transmit sci explicitly is set */
|
||||
if ((data && data[IFLA_MACSEC_SCI]) &&
|
||||
(data && data[IFLA_MACSEC_INC_SCI])) {
|
||||
u8 send_sci = !!nla_get_u8(data[IFLA_MACSEC_INC_SCI]);
|
||||
|
||||
if (!send_sci)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data && data[IFLA_MACSEC_ICV_LEN])
|
||||
icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]);
|
||||
mtu = real_dev->mtu - icv_len - macsec_extra_len(true);
|
||||
|
@ -1688,19 +1688,19 @@ static int qca808x_read_status(struct phy_device *phydev)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (phydev->link && phydev->speed == SPEED_2500)
|
||||
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||
else
|
||||
phydev->interface = PHY_INTERFACE_MODE_SMII;
|
||||
|
||||
/* generate seed as a lower random value to make PHY linked as SLAVE easily,
|
||||
* except for master/slave configuration fault detected.
|
||||
* the reason for not putting this code into the function link_change_notify is
|
||||
* the corner case where the link partner is also the qca8081 PHY and the seed
|
||||
* value is configured as the same value, the link can't be up and no link change
|
||||
* occurs.
|
||||
*/
|
||||
if (!phydev->link) {
|
||||
if (phydev->link) {
|
||||
if (phydev->speed == SPEED_2500)
|
||||
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||
else
|
||||
phydev->interface = PHY_INTERFACE_MODE_SGMII;
|
||||
} else {
|
||||
/* generate seed as a lower random value to make PHY linked as SLAVE easily,
|
||||
* except for master/slave configuration fault detected.
|
||||
* the reason for not putting this code into the function link_change_notify is
|
||||
* the corner case where the link partner is also the qca8081 PHY and the seed
|
||||
* value is configured as the same value, the link can't be up and no link change
|
||||
* occurs.
|
||||
*/
|
||||
if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) {
|
||||
qca808x_phy_ms_seed_enable(phydev, false);
|
||||
} else {
|
||||
|
@ -121,7 +121,7 @@ static int ipheth_alloc_urbs(struct ipheth_device *iphone)
|
||||
if (tx_buf == NULL)
|
||||
goto free_rx_urb;
|
||||
|
||||
rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE,
|
||||
rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN,
|
||||
GFP_KERNEL, &rx_urb->transfer_dma);
|
||||
if (rx_buf == NULL)
|
||||
goto free_tx_buf;
|
||||
@ -146,7 +146,7 @@ error_nomem:
|
||||
|
||||
static void ipheth_free_urbs(struct ipheth_device *iphone)
|
||||
{
|
||||
usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf,
|
||||
usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, iphone->rx_buf,
|
||||
iphone->rx_urb->transfer_dma);
|
||||
usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
|
||||
iphone->tx_urb->transfer_dma);
|
||||
@ -317,7 +317,7 @@ static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)
|
||||
|
||||
usb_fill_bulk_urb(dev->rx_urb, udev,
|
||||
usb_rcvbulkpipe(udev, dev->bulk_in),
|
||||
dev->rx_buf, IPHETH_BUF_SIZE,
|
||||
dev->rx_buf, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN,
|
||||
ipheth_rcvbulk_callback,
|
||||
dev);
|
||||
dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
|
@ -46,8 +46,10 @@ struct vlan_hdr {
|
||||
* @h_vlan_encapsulated_proto: packet type ID or len
|
||||
*/
|
||||
struct vlan_ethhdr {
|
||||
unsigned char h_dest[ETH_ALEN];
|
||||
unsigned char h_source[ETH_ALEN];
|
||||
struct_group(addrs,
|
||||
unsigned char h_dest[ETH_ALEN];
|
||||
unsigned char h_source[ETH_ALEN];
|
||||
);
|
||||
__be16 h_vlan_proto;
|
||||
__be16 h_vlan_TCI;
|
||||
__be16 h_vlan_encapsulated_proto;
|
||||
|
@ -239,6 +239,7 @@ typedef struct ax25_dev {
|
||||
#if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
|
||||
ax25_dama_info dama;
|
||||
#endif
|
||||
refcount_t refcount;
|
||||
} ax25_dev;
|
||||
|
||||
typedef struct ax25_cb {
|
||||
@ -293,6 +294,17 @@ static __inline__ void ax25_cb_put(ax25_cb *ax25)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ax25_dev_hold(ax25_dev *ax25_dev)
|
||||
{
|
||||
refcount_inc(&ax25_dev->refcount);
|
||||
}
|
||||
|
||||
static inline void ax25_dev_put(ax25_dev *ax25_dev)
|
||||
{
|
||||
if (refcount_dec_and_test(&ax25_dev->refcount)) {
|
||||
kfree(ax25_dev);
|
||||
}
|
||||
}
|
||||
static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
skb->dev = dev;
|
||||
|
@ -350,7 +350,8 @@ static inline struct neighbour *neigh_create(struct neigh_table *tbl,
|
||||
return __neigh_create(tbl, pkey, dev, true);
|
||||
}
|
||||
void neigh_destroy(struct neighbour *neigh);
|
||||
int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb);
|
||||
int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb,
|
||||
const bool immediate_ok);
|
||||
int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags,
|
||||
u32 nlmsg_pid);
|
||||
void __neigh_set_probe_once(struct neighbour *neigh);
|
||||
@ -460,17 +461,24 @@ static inline struct neighbour * neigh_clone(struct neighbour *neigh)
|
||||
|
||||
#define neigh_hold(n) refcount_inc(&(n)->refcnt)
|
||||
|
||||
static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
|
||||
static __always_inline int neigh_event_send_probe(struct neighbour *neigh,
|
||||
struct sk_buff *skb,
|
||||
const bool immediate_ok)
|
||||
{
|
||||
unsigned long now = jiffies;
|
||||
|
||||
|
||||
if (READ_ONCE(neigh->used) != now)
|
||||
WRITE_ONCE(neigh->used, now);
|
||||
if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
|
||||
return __neigh_event_send(neigh, skb);
|
||||
if (!(neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE)))
|
||||
return __neigh_event_send(neigh, skb, immediate_ok);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
|
||||
{
|
||||
return neigh_event_send_probe(neigh, skb, true);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
|
||||
static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
|
||||
{
|
||||
|
@ -84,12 +84,11 @@ struct smc_diag_conninfo {
|
||||
/* SMC_DIAG_LINKINFO */
|
||||
|
||||
struct smc_diag_linkinfo {
|
||||
__u8 link_id; /* link identifier */
|
||||
__u8 ibname[IB_DEVICE_NAME_MAX]; /* name of the RDMA device */
|
||||
__u8 ibport; /* RDMA device port number */
|
||||
__u8 gid[40]; /* local GID */
|
||||
__u8 peer_gid[40]; /* peer GID */
|
||||
__aligned_u64 net_cookie; /* RDMA device net namespace */
|
||||
__u8 link_id; /* link identifier */
|
||||
__u8 ibname[IB_DEVICE_NAME_MAX]; /* name of the RDMA device */
|
||||
__u8 ibport; /* RDMA device port number */
|
||||
__u8 gid[40]; /* local GID */
|
||||
__u8 peer_gid[40]; /* peer GID */
|
||||
};
|
||||
|
||||
struct smc_diag_lgrinfo {
|
||||
|
@ -207,7 +207,7 @@ BTF_ID(func, bpf_lsm_socket_socketpair)
|
||||
|
||||
BTF_ID(func, bpf_lsm_syslog)
|
||||
BTF_ID(func, bpf_lsm_task_alloc)
|
||||
BTF_ID(func, bpf_lsm_task_getsecid_subj)
|
||||
BTF_ID(func, bpf_lsm_current_getsecid_subj)
|
||||
BTF_ID(func, bpf_lsm_task_getsecid_obj)
|
||||
BTF_ID(func, bpf_lsm_task_prctl)
|
||||
BTF_ID(func, bpf_lsm_task_setscheduler)
|
||||
|
@ -104,7 +104,7 @@ static struct bpf_ringbuf *bpf_ringbuf_area_alloc(size_t data_sz, int numa_node)
|
||||
}
|
||||
|
||||
rb = vmap(pages, nr_meta_pages + 2 * nr_data_pages,
|
||||
VM_ALLOC | VM_USERMAP, PAGE_KERNEL);
|
||||
VM_MAP | VM_USERMAP, PAGE_KERNEL);
|
||||
if (rb) {
|
||||
kmemleak_not_leak(pages);
|
||||
rb->pages = pages;
|
||||
|
@ -550,11 +550,12 @@ static __always_inline u64 notrace bpf_prog_start_time(void)
|
||||
static void notrace inc_misses_counter(struct bpf_prog *prog)
|
||||
{
|
||||
struct bpf_prog_stats *stats;
|
||||
unsigned int flags;
|
||||
|
||||
stats = this_cpu_ptr(prog->stats);
|
||||
u64_stats_update_begin(&stats->syncp);
|
||||
flags = u64_stats_update_begin_irqsave(&stats->syncp);
|
||||
u64_stats_inc(&stats->misses);
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
u64_stats_update_end_irqrestore(&stats->syncp, flags);
|
||||
}
|
||||
|
||||
/* The logic is similar to bpf_prog_run(), but with an explicit
|
||||
|
@ -77,6 +77,7 @@ static void ax25_kill_by_device(struct net_device *dev)
|
||||
{
|
||||
ax25_dev *ax25_dev;
|
||||
ax25_cb *s;
|
||||
struct sock *sk;
|
||||
|
||||
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
|
||||
return;
|
||||
@ -85,13 +86,16 @@ static void ax25_kill_by_device(struct net_device *dev)
|
||||
again:
|
||||
ax25_for_each(s, &ax25_list) {
|
||||
if (s->ax25_dev == ax25_dev) {
|
||||
sk = s->sk;
|
||||
sock_hold(sk);
|
||||
spin_unlock_bh(&ax25_list_lock);
|
||||
lock_sock(s->sk);
|
||||
lock_sock(sk);
|
||||
s->ax25_dev = NULL;
|
||||
release_sock(s->sk);
|
||||
ax25_dev_put(ax25_dev);
|
||||
release_sock(sk);
|
||||
ax25_disconnect(s, ENETUNREACH);
|
||||
spin_lock_bh(&ax25_list_lock);
|
||||
|
||||
sock_put(sk);
|
||||
/* The entry could have been deleted from the
|
||||
* list meanwhile and thus the next pointer is
|
||||
* no longer valid. Play it safe and restart
|
||||
@ -355,21 +359,25 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
|
||||
if (copy_from_user(&ax25_ctl, arg, sizeof(ax25_ctl)))
|
||||
return -EFAULT;
|
||||
|
||||
if ((ax25_dev = ax25_addr_ax25dev(&ax25_ctl.port_addr)) == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
if (ax25_ctl.digi_count > AX25_MAX_DIGIS)
|
||||
return -EINVAL;
|
||||
|
||||
if (ax25_ctl.arg > ULONG_MAX / HZ && ax25_ctl.cmd != AX25_KILL)
|
||||
return -EINVAL;
|
||||
|
||||
ax25_dev = ax25_addr_ax25dev(&ax25_ctl.port_addr);
|
||||
if (!ax25_dev)
|
||||
return -ENODEV;
|
||||
|
||||
digi.ndigi = ax25_ctl.digi_count;
|
||||
for (k = 0; k < digi.ndigi; k++)
|
||||
digi.calls[k] = ax25_ctl.digi_addr[k];
|
||||
|
||||
if ((ax25 = ax25_find_cb(&ax25_ctl.source_addr, &ax25_ctl.dest_addr, &digi, ax25_dev->dev)) == NULL)
|
||||
ax25 = ax25_find_cb(&ax25_ctl.source_addr, &ax25_ctl.dest_addr, &digi, ax25_dev->dev);
|
||||
if (!ax25) {
|
||||
ax25_dev_put(ax25_dev);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
switch (ax25_ctl.cmd) {
|
||||
case AX25_KILL:
|
||||
@ -436,6 +444,7 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
|
||||
}
|
||||
|
||||
out_put:
|
||||
ax25_dev_put(ax25_dev);
|
||||
ax25_cb_put(ax25);
|
||||
return ret;
|
||||
|
||||
|
@ -37,6 +37,7 @@ ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
|
||||
for (ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
|
||||
if (ax25cmp(addr, (const ax25_address *)ax25_dev->dev->dev_addr) == 0) {
|
||||
res = ax25_dev;
|
||||
ax25_dev_hold(ax25_dev);
|
||||
}
|
||||
spin_unlock_bh(&ax25_dev_lock);
|
||||
|
||||
@ -56,6 +57,7 @@ void ax25_dev_device_up(struct net_device *dev)
|
||||
return;
|
||||
}
|
||||
|
||||
refcount_set(&ax25_dev->refcount, 1);
|
||||
dev->ax25_ptr = ax25_dev;
|
||||
ax25_dev->dev = dev;
|
||||
dev_hold_track(dev, &ax25_dev->dev_tracker, GFP_ATOMIC);
|
||||
@ -84,6 +86,7 @@ void ax25_dev_device_up(struct net_device *dev)
|
||||
ax25_dev->next = ax25_dev_list;
|
||||
ax25_dev_list = ax25_dev;
|
||||
spin_unlock_bh(&ax25_dev_lock);
|
||||
ax25_dev_hold(ax25_dev);
|
||||
|
||||
ax25_register_dev_sysctl(ax25_dev);
|
||||
}
|
||||
@ -113,9 +116,10 @@ void ax25_dev_device_down(struct net_device *dev)
|
||||
if ((s = ax25_dev_list) == ax25_dev) {
|
||||
ax25_dev_list = s->next;
|
||||
spin_unlock_bh(&ax25_dev_lock);
|
||||
ax25_dev_put(ax25_dev);
|
||||
dev->ax25_ptr = NULL;
|
||||
dev_put_track(dev, &ax25_dev->dev_tracker);
|
||||
kfree(ax25_dev);
|
||||
ax25_dev_put(ax25_dev);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -123,9 +127,10 @@ void ax25_dev_device_down(struct net_device *dev)
|
||||
if (s->next == ax25_dev) {
|
||||
s->next = ax25_dev->next;
|
||||
spin_unlock_bh(&ax25_dev_lock);
|
||||
ax25_dev_put(ax25_dev);
|
||||
dev->ax25_ptr = NULL;
|
||||
dev_put_track(dev, &ax25_dev->dev_tracker);
|
||||
kfree(ax25_dev);
|
||||
ax25_dev_put(ax25_dev);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -133,6 +138,7 @@ void ax25_dev_device_down(struct net_device *dev)
|
||||
}
|
||||
spin_unlock_bh(&ax25_dev_lock);
|
||||
dev->ax25_ptr = NULL;
|
||||
ax25_dev_put(ax25_dev);
|
||||
}
|
||||
|
||||
int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
|
||||
@ -144,20 +150,32 @@ int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCAX25ADDFWD:
|
||||
if ((fwd_dev = ax25_addr_ax25dev(&fwd->port_to)) == NULL)
|
||||
fwd_dev = ax25_addr_ax25dev(&fwd->port_to);
|
||||
if (!fwd_dev) {
|
||||
ax25_dev_put(ax25_dev);
|
||||
return -EINVAL;
|
||||
if (ax25_dev->forward != NULL)
|
||||
}
|
||||
if (ax25_dev->forward) {
|
||||
ax25_dev_put(fwd_dev);
|
||||
ax25_dev_put(ax25_dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
ax25_dev->forward = fwd_dev->dev;
|
||||
ax25_dev_put(fwd_dev);
|
||||
ax25_dev_put(ax25_dev);
|
||||
break;
|
||||
|
||||
case SIOCAX25DELFWD:
|
||||
if (ax25_dev->forward == NULL)
|
||||
if (!ax25_dev->forward) {
|
||||
ax25_dev_put(ax25_dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
ax25_dev->forward = NULL;
|
||||
ax25_dev_put(ax25_dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
ax25_dev_put(ax25_dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -75,11 +75,13 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
|
||||
ax25_dev *ax25_dev;
|
||||
int i;
|
||||
|
||||
if ((ax25_dev = ax25_addr_ax25dev(&route->port_addr)) == NULL)
|
||||
return -EINVAL;
|
||||
if (route->digi_count > AX25_MAX_DIGIS)
|
||||
return -EINVAL;
|
||||
|
||||
ax25_dev = ax25_addr_ax25dev(&route->port_addr);
|
||||
if (!ax25_dev)
|
||||
return -EINVAL;
|
||||
|
||||
write_lock_bh(&ax25_route_lock);
|
||||
|
||||
ax25_rt = ax25_route_list;
|
||||
@ -91,6 +93,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
|
||||
if (route->digi_count != 0) {
|
||||
if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
|
||||
write_unlock_bh(&ax25_route_lock);
|
||||
ax25_dev_put(ax25_dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
ax25_rt->digipeat->lastrepeat = -1;
|
||||
@ -101,6 +104,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
|
||||
}
|
||||
}
|
||||
write_unlock_bh(&ax25_route_lock);
|
||||
ax25_dev_put(ax25_dev);
|
||||
return 0;
|
||||
}
|
||||
ax25_rt = ax25_rt->next;
|
||||
@ -108,6 +112,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
|
||||
|
||||
if ((ax25_rt = kmalloc(sizeof(ax25_route), GFP_ATOMIC)) == NULL) {
|
||||
write_unlock_bh(&ax25_route_lock);
|
||||
ax25_dev_put(ax25_dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -120,6 +125,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
|
||||
if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
|
||||
write_unlock_bh(&ax25_route_lock);
|
||||
kfree(ax25_rt);
|
||||
ax25_dev_put(ax25_dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
ax25_rt->digipeat->lastrepeat = -1;
|
||||
@ -132,6 +138,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
|
||||
ax25_rt->next = ax25_route_list;
|
||||
ax25_route_list = ax25_rt;
|
||||
write_unlock_bh(&ax25_route_lock);
|
||||
ax25_dev_put(ax25_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -173,6 +180,7 @@ static int ax25_rt_del(struct ax25_routes_struct *route)
|
||||
}
|
||||
}
|
||||
write_unlock_bh(&ax25_route_lock);
|
||||
ax25_dev_put(ax25_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -215,6 +223,7 @@ static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option)
|
||||
|
||||
out:
|
||||
write_unlock_bh(&ax25_route_lock);
|
||||
ax25_dev_put(ax25_dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ static void nft_reject_br_send_v4_tcp_reset(struct net *net,
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
|
||||
nskb = nf_reject_skb_v4_tcp_reset(net, oldskb, dev, hook);
|
||||
nskb = nf_reject_skb_v4_tcp_reset(net, oldskb, NULL, hook);
|
||||
if (!nskb)
|
||||
return;
|
||||
|
||||
@ -65,7 +65,7 @@ static void nft_reject_br_send_v4_unreach(struct net *net,
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
|
||||
nskb = nf_reject_skb_v4_unreach(net, oldskb, dev, hook, code);
|
||||
nskb = nf_reject_skb_v4_unreach(net, oldskb, NULL, hook, code);
|
||||
if (!nskb)
|
||||
return;
|
||||
|
||||
@ -81,7 +81,7 @@ static void nft_reject_br_send_v6_tcp_reset(struct net *net,
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
|
||||
nskb = nf_reject_skb_v6_tcp_reset(net, oldskb, dev, hook);
|
||||
nskb = nf_reject_skb_v6_tcp_reset(net, oldskb, NULL, hook);
|
||||
if (!nskb)
|
||||
return;
|
||||
|
||||
@ -98,7 +98,7 @@ static void nft_reject_br_send_v6_unreach(struct net *net,
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
|
||||
nskb = nf_reject_skb_v6_unreach(net, oldskb, dev, hook, code);
|
||||
nskb = nf_reject_skb_v6_unreach(net, oldskb, NULL, hook, code);
|
||||
if (!nskb)
|
||||
return;
|
||||
|
||||
|
@ -1133,7 +1133,8 @@ out:
|
||||
neigh_release(neigh);
|
||||
}
|
||||
|
||||
int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
|
||||
int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb,
|
||||
const bool immediate_ok)
|
||||
{
|
||||
int rc;
|
||||
bool immediate_probe = false;
|
||||
@ -1154,12 +1155,17 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
|
||||
atomic_set(&neigh->probes,
|
||||
NEIGH_VAR(neigh->parms, UCAST_PROBES));
|
||||
neigh_del_timer(neigh);
|
||||
neigh->nud_state = NUD_INCOMPLETE;
|
||||
neigh->nud_state = NUD_INCOMPLETE;
|
||||
neigh->updated = now;
|
||||
next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME),
|
||||
HZ/100);
|
||||
if (!immediate_ok) {
|
||||
next = now + 1;
|
||||
} else {
|
||||
immediate_probe = true;
|
||||
next = now + max(NEIGH_VAR(neigh->parms,
|
||||
RETRANS_TIME),
|
||||
HZ / 100);
|
||||
}
|
||||
neigh_add_timer(neigh, next);
|
||||
immediate_probe = true;
|
||||
} else {
|
||||
neigh->nud_state = NUD_FAILED;
|
||||
neigh->updated = jiffies;
|
||||
@ -1571,7 +1577,7 @@ static void neigh_managed_work(struct work_struct *work)
|
||||
|
||||
write_lock_bh(&tbl->lock);
|
||||
list_for_each_entry(neigh, &tbl->managed_list, managed_list)
|
||||
neigh_event_send(neigh, NULL);
|
||||
neigh_event_send_probe(neigh, NULL, false);
|
||||
queue_delayed_work(system_power_efficient_wq, &tbl->managed_work,
|
||||
NEIGH_VAR(&tbl->parms, DELAY_PROBE_TIME));
|
||||
write_unlock_bh(&tbl->lock);
|
||||
|
@ -3275,8 +3275,8 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct nlattr *slave_attr[RTNL_SLAVE_MAX_TYPE + 1];
|
||||
unsigned char name_assign_type = NET_NAME_USER;
|
||||
struct nlattr *linkinfo[IFLA_INFO_MAX + 1];
|
||||
const struct rtnl_link_ops *m_ops = NULL;
|
||||
struct net_device *master_dev = NULL;
|
||||
const struct rtnl_link_ops *m_ops;
|
||||
struct net_device *master_dev;
|
||||
struct net *net = sock_net(skb->sk);
|
||||
const struct rtnl_link_ops *ops;
|
||||
struct nlattr *tb[IFLA_MAX + 1];
|
||||
@ -3314,6 +3314,8 @@ replay:
|
||||
else
|
||||
dev = NULL;
|
||||
|
||||
master_dev = NULL;
|
||||
m_ops = NULL;
|
||||
if (dev) {
|
||||
master_dev = netdev_master_upper_dev_get(dev);
|
||||
if (master_dev)
|
||||
|
@ -1441,7 +1441,7 @@ static int nl802154_send_key(struct sk_buff *msg, u32 cmd, u32 portid,
|
||||
|
||||
hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
|
||||
if (!hdr)
|
||||
return -1;
|
||||
return -ENOBUFS;
|
||||
|
||||
if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
|
||||
goto nla_put_failure;
|
||||
@ -1634,7 +1634,7 @@ static int nl802154_send_device(struct sk_buff *msg, u32 cmd, u32 portid,
|
||||
|
||||
hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
|
||||
if (!hdr)
|
||||
return -1;
|
||||
return -ENOBUFS;
|
||||
|
||||
if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
|
||||
goto nla_put_failure;
|
||||
@ -1812,7 +1812,7 @@ static int nl802154_send_devkey(struct sk_buff *msg, u32 cmd, u32 portid,
|
||||
|
||||
hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
|
||||
if (!hdr)
|
||||
return -1;
|
||||
return -ENOBUFS;
|
||||
|
||||
if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
|
||||
goto nla_put_failure;
|
||||
@ -1988,7 +1988,7 @@ static int nl802154_send_seclevel(struct sk_buff *msg, u32 cmd, u32 portid,
|
||||
|
||||
hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
|
||||
if (!hdr)
|
||||
return -1;
|
||||
return -ENOBUFS;
|
||||
|
||||
if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
|
||||
goto nla_put_failure;
|
||||
|
@ -58,10 +58,6 @@ config NF_TABLES_ARP
|
||||
|
||||
endif # NF_TABLES
|
||||
|
||||
config NF_FLOW_TABLE_IPV4
|
||||
tristate
|
||||
select NF_FLOW_TABLE_INET
|
||||
|
||||
config NF_DUP_IPV4
|
||||
tristate "Netfilter IPv4 packet duplication to alternate destination"
|
||||
depends on !NF_CONNTRACK || NF_CONNTRACK
|
||||
|
@ -1322,10 +1322,13 @@ new_segment:
|
||||
|
||||
/* skb changing from pure zc to mixed, must charge zc */
|
||||
if (unlikely(skb_zcopy_pure(skb))) {
|
||||
if (!sk_wmem_schedule(sk, skb->data_len))
|
||||
u32 extra = skb->truesize -
|
||||
SKB_TRUESIZE(skb_end_offset(skb));
|
||||
|
||||
if (!sk_wmem_schedule(sk, extra))
|
||||
goto wait_for_space;
|
||||
|
||||
sk_mem_charge(sk, skb->data_len);
|
||||
sk_mem_charge(sk, extra);
|
||||
skb_shinfo(skb)->flags &= ~SKBFL_PURE_ZEROCOPY;
|
||||
}
|
||||
|
||||
|
@ -1660,6 +1660,8 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb,
|
||||
(mss != tcp_skb_seglen(skb)))
|
||||
goto out;
|
||||
|
||||
if (!tcp_skb_can_collapse(prev, skb))
|
||||
goto out;
|
||||
len = skb->len;
|
||||
pcount = tcp_skb_pcount(skb);
|
||||
if (tcp_skb_shift(prev, skb, pcount, len))
|
||||
|
@ -47,10 +47,6 @@ config NFT_FIB_IPV6
|
||||
endif # NF_TABLES_IPV6
|
||||
endif # NF_TABLES
|
||||
|
||||
config NF_FLOW_TABLE_IPV6
|
||||
tristate
|
||||
select NF_FLOW_TABLE_INET
|
||||
|
||||
config NF_DUP_IPV6
|
||||
tristate "Netfilter IPv6 packet duplication to alternate destination"
|
||||
depends on !NF_CONNTRACK || NF_CONNTRACK
|
||||
|
@ -28,9 +28,6 @@ obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o
|
||||
obj-$(CONFIG_NFT_DUP_IPV6) += nft_dup_ipv6.o
|
||||
obj-$(CONFIG_NFT_FIB_IPV6) += nft_fib_ipv6.o
|
||||
|
||||
# flow table support
|
||||
obj-$(CONFIG_NF_FLOW_TABLE_IPV6) += nf_flow_table_ipv6.o
|
||||
|
||||
# matches
|
||||
obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
|
||||
|
@ -2011,7 +2011,6 @@ static void nft_last_rule(struct nft_rule_blob *blob, const void *ptr)
|
||||
|
||||
prule = (struct nft_rule_dp *)ptr;
|
||||
prule->is_last = 1;
|
||||
ptr += offsetof(struct nft_rule_dp, data);
|
||||
/* blob size does not include the trailer rule */
|
||||
}
|
||||
|
||||
|
@ -167,12 +167,24 @@ nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool nft_byteorder_reduce(struct nft_regs_track *track,
|
||||
const struct nft_expr *expr)
|
||||
{
|
||||
struct nft_byteorder *priv = nft_expr_priv(expr);
|
||||
|
||||
track->regs[priv->dreg].selector = NULL;
|
||||
track->regs[priv->dreg].bitwise = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct nft_expr_ops nft_byteorder_ops = {
|
||||
.type = &nft_byteorder_type,
|
||||
.size = NFT_EXPR_SIZE(sizeof(struct nft_byteorder)),
|
||||
.eval = nft_byteorder_eval,
|
||||
.init = nft_byteorder_init,
|
||||
.dump = nft_byteorder_dump,
|
||||
.reduce = nft_byteorder_reduce,
|
||||
};
|
||||
|
||||
struct nft_expr_type nft_byteorder_type __read_mostly = {
|
||||
|
@ -260,9 +260,12 @@ static void nft_ct_set_zone_eval(const struct nft_expr *expr,
|
||||
ct = this_cpu_read(nft_ct_pcpu_template);
|
||||
|
||||
if (likely(refcount_read(&ct->ct_general.use) == 1)) {
|
||||
refcount_inc(&ct->ct_general.use);
|
||||
nf_ct_zone_add(ct, &zone);
|
||||
} else {
|
||||
/* previous skb got queued to userspace */
|
||||
/* previous skb got queued to userspace, allocate temporary
|
||||
* one until percpu template can be reused.
|
||||
*/
|
||||
ct = nf_ct_tmpl_alloc(nft_net(pkt), &zone, GFP_ATOMIC);
|
||||
if (!ct) {
|
||||
regs->verdict.code = NF_DROP;
|
||||
|
@ -1789,7 +1789,10 @@ static int fanout_add(struct sock *sk, struct fanout_args *args)
|
||||
err = -ENOSPC;
|
||||
if (refcount_read(&match->sk_ref) < match->max_num_members) {
|
||||
__dev_remove_pack(&po->prot_hook);
|
||||
po->fanout = match;
|
||||
|
||||
/* Paired with packet_setsockopt(PACKET_FANOUT_DATA) */
|
||||
WRITE_ONCE(po->fanout, match);
|
||||
|
||||
po->rollover = rollover;
|
||||
rollover = NULL;
|
||||
refcount_set(&match->sk_ref, refcount_read(&match->sk_ref) + 1);
|
||||
@ -3934,7 +3937,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
|
||||
}
|
||||
case PACKET_FANOUT_DATA:
|
||||
{
|
||||
if (!po->fanout)
|
||||
/* Paired with the WRITE_ONCE() in fanout_add() */
|
||||
if (!READ_ONCE(po->fanout))
|
||||
return -EINVAL;
|
||||
|
||||
return fanout_set_data(po, optval, optlen);
|
||||
|
@ -1945,9 +1945,9 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
|
||||
bool prio_allocate;
|
||||
u32 parent;
|
||||
u32 chain_index;
|
||||
struct Qdisc *q = NULL;
|
||||
struct Qdisc *q;
|
||||
struct tcf_chain_info chain_info;
|
||||
struct tcf_chain *chain = NULL;
|
||||
struct tcf_chain *chain;
|
||||
struct tcf_block *block;
|
||||
struct tcf_proto *tp;
|
||||
unsigned long cl;
|
||||
@ -1976,6 +1976,8 @@ replay:
|
||||
tp = NULL;
|
||||
cl = 0;
|
||||
block = NULL;
|
||||
q = NULL;
|
||||
chain = NULL;
|
||||
flags = 0;
|
||||
|
||||
if (prio == 0) {
|
||||
@ -2798,8 +2800,8 @@ static int tc_ctl_chain(struct sk_buff *skb, struct nlmsghdr *n,
|
||||
struct tcmsg *t;
|
||||
u32 parent;
|
||||
u32 chain_index;
|
||||
struct Qdisc *q = NULL;
|
||||
struct tcf_chain *chain = NULL;
|
||||
struct Qdisc *q;
|
||||
struct tcf_chain *chain;
|
||||
struct tcf_block *block;
|
||||
unsigned long cl;
|
||||
int err;
|
||||
@ -2809,6 +2811,7 @@ static int tc_ctl_chain(struct sk_buff *skb, struct nlmsghdr *n,
|
||||
return -EPERM;
|
||||
|
||||
replay:
|
||||
q = NULL;
|
||||
err = nlmsg_parse_deprecated(n, sizeof(*t), tca, TCA_MAX,
|
||||
rtm_tca_policy, extack);
|
||||
if (err < 0)
|
||||
|
133
net/smc/af_smc.c
133
net/smc/af_smc.c
@ -566,17 +566,115 @@ static void smc_stat_fallback(struct smc_sock *smc)
|
||||
mutex_unlock(&net->smc.mutex_fback_rsn);
|
||||
}
|
||||
|
||||
/* must be called under rcu read lock */
|
||||
static void smc_fback_wakeup_waitqueue(struct smc_sock *smc, void *key)
|
||||
{
|
||||
struct socket_wq *wq;
|
||||
__poll_t flags;
|
||||
|
||||
wq = rcu_dereference(smc->sk.sk_wq);
|
||||
if (!skwq_has_sleeper(wq))
|
||||
return;
|
||||
|
||||
/* wake up smc sk->sk_wq */
|
||||
if (!key) {
|
||||
/* sk_state_change */
|
||||
wake_up_interruptible_all(&wq->wait);
|
||||
} else {
|
||||
flags = key_to_poll(key);
|
||||
if (flags & (EPOLLIN | EPOLLOUT))
|
||||
/* sk_data_ready or sk_write_space */
|
||||
wake_up_interruptible_sync_poll(&wq->wait, flags);
|
||||
else if (flags & EPOLLERR)
|
||||
/* sk_error_report */
|
||||
wake_up_interruptible_poll(&wq->wait, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static int smc_fback_mark_woken(wait_queue_entry_t *wait,
|
||||
unsigned int mode, int sync, void *key)
|
||||
{
|
||||
struct smc_mark_woken *mark =
|
||||
container_of(wait, struct smc_mark_woken, wait_entry);
|
||||
|
||||
mark->woken = true;
|
||||
mark->key = key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void smc_fback_forward_wakeup(struct smc_sock *smc, struct sock *clcsk,
|
||||
void (*clcsock_callback)(struct sock *sk))
|
||||
{
|
||||
struct smc_mark_woken mark = { .woken = false };
|
||||
struct socket_wq *wq;
|
||||
|
||||
init_waitqueue_func_entry(&mark.wait_entry,
|
||||
smc_fback_mark_woken);
|
||||
rcu_read_lock();
|
||||
wq = rcu_dereference(clcsk->sk_wq);
|
||||
if (!wq)
|
||||
goto out;
|
||||
add_wait_queue(sk_sleep(clcsk), &mark.wait_entry);
|
||||
clcsock_callback(clcsk);
|
||||
remove_wait_queue(sk_sleep(clcsk), &mark.wait_entry);
|
||||
|
||||
if (mark.woken)
|
||||
smc_fback_wakeup_waitqueue(smc, mark.key);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void smc_fback_state_change(struct sock *clcsk)
|
||||
{
|
||||
struct smc_sock *smc =
|
||||
smc_clcsock_user_data(clcsk);
|
||||
|
||||
if (!smc)
|
||||
return;
|
||||
smc_fback_forward_wakeup(smc, clcsk, smc->clcsk_state_change);
|
||||
}
|
||||
|
||||
static void smc_fback_data_ready(struct sock *clcsk)
|
||||
{
|
||||
struct smc_sock *smc =
|
||||
smc_clcsock_user_data(clcsk);
|
||||
|
||||
if (!smc)
|
||||
return;
|
||||
smc_fback_forward_wakeup(smc, clcsk, smc->clcsk_data_ready);
|
||||
}
|
||||
|
||||
static void smc_fback_write_space(struct sock *clcsk)
|
||||
{
|
||||
struct smc_sock *smc =
|
||||
smc_clcsock_user_data(clcsk);
|
||||
|
||||
if (!smc)
|
||||
return;
|
||||
smc_fback_forward_wakeup(smc, clcsk, smc->clcsk_write_space);
|
||||
}
|
||||
|
||||
static void smc_fback_error_report(struct sock *clcsk)
|
||||
{
|
||||
struct smc_sock *smc =
|
||||
smc_clcsock_user_data(clcsk);
|
||||
|
||||
if (!smc)
|
||||
return;
|
||||
smc_fback_forward_wakeup(smc, clcsk, smc->clcsk_error_report);
|
||||
}
|
||||
|
||||
static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
|
||||
{
|
||||
wait_queue_head_t *smc_wait = sk_sleep(&smc->sk);
|
||||
wait_queue_head_t *clc_wait;
|
||||
unsigned long flags;
|
||||
struct sock *clcsk;
|
||||
|
||||
mutex_lock(&smc->clcsock_release_lock);
|
||||
if (!smc->clcsock) {
|
||||
mutex_unlock(&smc->clcsock_release_lock);
|
||||
return -EBADF;
|
||||
}
|
||||
clcsk = smc->clcsock->sk;
|
||||
|
||||
smc->use_fallback = true;
|
||||
smc->fallback_rsn = reason_code;
|
||||
smc_stat_fallback(smc);
|
||||
@ -587,16 +685,22 @@ static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
|
||||
smc->clcsock->wq.fasync_list =
|
||||
smc->sk.sk_socket->wq.fasync_list;
|
||||
|
||||
/* There may be some entries remaining in
|
||||
* smc socket->wq, which should be removed
|
||||
* to clcsocket->wq during the fallback.
|
||||
/* There might be some wait entries remaining
|
||||
* in smc sk->sk_wq and they should be woken up
|
||||
* as clcsock's wait queue is woken up.
|
||||
*/
|
||||
clc_wait = sk_sleep(smc->clcsock->sk);
|
||||
spin_lock_irqsave(&smc_wait->lock, flags);
|
||||
spin_lock_nested(&clc_wait->lock, SINGLE_DEPTH_NESTING);
|
||||
list_splice_init(&smc_wait->head, &clc_wait->head);
|
||||
spin_unlock(&clc_wait->lock);
|
||||
spin_unlock_irqrestore(&smc_wait->lock, flags);
|
||||
smc->clcsk_state_change = clcsk->sk_state_change;
|
||||
smc->clcsk_data_ready = clcsk->sk_data_ready;
|
||||
smc->clcsk_write_space = clcsk->sk_write_space;
|
||||
smc->clcsk_error_report = clcsk->sk_error_report;
|
||||
|
||||
clcsk->sk_state_change = smc_fback_state_change;
|
||||
clcsk->sk_data_ready = smc_fback_data_ready;
|
||||
clcsk->sk_write_space = smc_fback_write_space;
|
||||
clcsk->sk_error_report = smc_fback_error_report;
|
||||
|
||||
smc->clcsock->sk->sk_user_data =
|
||||
(void *)((uintptr_t)smc | SK_USER_DATA_NOCOPY);
|
||||
}
|
||||
mutex_unlock(&smc->clcsock_release_lock);
|
||||
return 0;
|
||||
@ -2115,10 +2219,9 @@ out:
|
||||
|
||||
static void smc_clcsock_data_ready(struct sock *listen_clcsock)
|
||||
{
|
||||
struct smc_sock *lsmc;
|
||||
struct smc_sock *lsmc =
|
||||
smc_clcsock_user_data(listen_clcsock);
|
||||
|
||||
lsmc = (struct smc_sock *)
|
||||
((uintptr_t)listen_clcsock->sk_user_data & ~SK_USER_DATA_NOCOPY);
|
||||
if (!lsmc)
|
||||
return;
|
||||
lsmc->clcsk_data_ready(listen_clcsock);
|
||||
|
@ -139,6 +139,12 @@ enum smc_urg_state {
|
||||
SMC_URG_READ = 3, /* data was already read */
|
||||
};
|
||||
|
||||
struct smc_mark_woken {
|
||||
bool woken;
|
||||
void *key;
|
||||
wait_queue_entry_t wait_entry;
|
||||
};
|
||||
|
||||
struct smc_connection {
|
||||
struct rb_node alert_node;
|
||||
struct smc_link_group *lgr; /* link group of connection */
|
||||
@ -228,8 +234,14 @@ struct smc_connection {
|
||||
struct smc_sock { /* smc sock container */
|
||||
struct sock sk;
|
||||
struct socket *clcsock; /* internal tcp socket */
|
||||
void (*clcsk_state_change)(struct sock *sk);
|
||||
/* original stat_change fct. */
|
||||
void (*clcsk_data_ready)(struct sock *sk);
|
||||
/* original data_ready fct. **/
|
||||
/* original data_ready fct. */
|
||||
void (*clcsk_write_space)(struct sock *sk);
|
||||
/* original write_space fct. */
|
||||
void (*clcsk_error_report)(struct sock *sk);
|
||||
/* original error_report fct. */
|
||||
struct smc_connection conn; /* smc connection */
|
||||
struct smc_sock *listen_smc; /* listen parent */
|
||||
struct work_struct connect_work; /* handle non-blocking connect*/
|
||||
@ -264,6 +276,12 @@ static inline struct smc_sock *smc_sk(const struct sock *sk)
|
||||
return (struct smc_sock *)sk;
|
||||
}
|
||||
|
||||
static inline struct smc_sock *smc_clcsock_user_data(struct sock *clcsk)
|
||||
{
|
||||
return (struct smc_sock *)
|
||||
((uintptr_t)clcsk->sk_user_data & ~SK_USER_DATA_NOCOPY);
|
||||
}
|
||||
|
||||
extern struct workqueue_struct *smc_hs_wq; /* wq for handshake work */
|
||||
extern struct workqueue_struct *smc_close_wq; /* wq for close work */
|
||||
|
||||
|
@ -146,13 +146,11 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,
|
||||
(req->diag_ext & (1 << (SMC_DIAG_LGRINFO - 1))) &&
|
||||
!list_empty(&smc->conn.lgr->list)) {
|
||||
struct smc_link *link = smc->conn.lnk;
|
||||
struct net *net = read_pnet(&link->smcibdev->ibdev->coredev.rdma_net);
|
||||
|
||||
struct smc_diag_lgrinfo linfo = {
|
||||
.role = smc->conn.lgr->role,
|
||||
.lnk[0].ibport = link->ibport,
|
||||
.lnk[0].link_id = link->link_id,
|
||||
.lnk[0].net_cookie = net->net_cookie,
|
||||
};
|
||||
|
||||
memcpy(linfo.lnk[0].ibname,
|
||||
|
@ -9,7 +9,11 @@ ifeq ($(V),1)
|
||||
msg =
|
||||
else
|
||||
Q = @
|
||||
msg = @printf ' %-8s %s%s\n' "$(1)" "$(notdir $(2))" "$(if $(3), $(3))";
|
||||
ifeq ($(silent),1)
|
||||
msg =
|
||||
else
|
||||
msg = @printf ' %-8s %s%s\n' "$(1)" "$(notdir $(2))" "$(if $(3), $(3))";
|
||||
endif
|
||||
MAKEFLAGS=--no-print-directory
|
||||
endif
|
||||
|
||||
|
@ -1,229 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* lirc.h - linux infrared remote control header file
|
||||
* last modified 2010/07/13 by Jarod Wilson
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_LIRC_H
|
||||
#define _LINUX_LIRC_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#define PULSE_BIT 0x01000000
|
||||
#define PULSE_MASK 0x00FFFFFF
|
||||
|
||||
#define LIRC_MODE2_SPACE 0x00000000
|
||||
#define LIRC_MODE2_PULSE 0x01000000
|
||||
#define LIRC_MODE2_FREQUENCY 0x02000000
|
||||
#define LIRC_MODE2_TIMEOUT 0x03000000
|
||||
|
||||
#define LIRC_VALUE_MASK 0x00FFFFFF
|
||||
#define LIRC_MODE2_MASK 0xFF000000
|
||||
|
||||
#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE)
|
||||
#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE)
|
||||
#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY)
|
||||
#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT)
|
||||
|
||||
#define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK)
|
||||
#define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK)
|
||||
|
||||
#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE)
|
||||
#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE)
|
||||
#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY)
|
||||
#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT)
|
||||
|
||||
/* used heavily by lirc userspace */
|
||||
#define lirc_t int
|
||||
|
||||
/*** lirc compatible hardware features ***/
|
||||
|
||||
#define LIRC_MODE2SEND(x) (x)
|
||||
#define LIRC_SEND2MODE(x) (x)
|
||||
#define LIRC_MODE2REC(x) ((x) << 16)
|
||||
#define LIRC_REC2MODE(x) ((x) >> 16)
|
||||
|
||||
#define LIRC_MODE_RAW 0x00000001
|
||||
#define LIRC_MODE_PULSE 0x00000002
|
||||
#define LIRC_MODE_MODE2 0x00000004
|
||||
#define LIRC_MODE_SCANCODE 0x00000008
|
||||
#define LIRC_MODE_LIRCCODE 0x00000010
|
||||
|
||||
|
||||
#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW)
|
||||
#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE)
|
||||
#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2)
|
||||
#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE)
|
||||
|
||||
#define LIRC_CAN_SEND_MASK 0x0000003f
|
||||
|
||||
#define LIRC_CAN_SET_SEND_CARRIER 0x00000100
|
||||
#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200
|
||||
#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400
|
||||
|
||||
#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW)
|
||||
#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE)
|
||||
#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2)
|
||||
#define LIRC_CAN_REC_SCANCODE LIRC_MODE2REC(LIRC_MODE_SCANCODE)
|
||||
#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE)
|
||||
|
||||
#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK)
|
||||
|
||||
#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16)
|
||||
#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16)
|
||||
|
||||
#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000
|
||||
#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000
|
||||
#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000
|
||||
#define LIRC_CAN_SET_REC_TIMEOUT 0x10000000
|
||||
#define LIRC_CAN_SET_REC_FILTER 0x08000000
|
||||
|
||||
#define LIRC_CAN_MEASURE_CARRIER 0x02000000
|
||||
#define LIRC_CAN_USE_WIDEBAND_RECEIVER 0x04000000
|
||||
|
||||
#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK)
|
||||
#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK)
|
||||
|
||||
#define LIRC_CAN_NOTIFY_DECODE 0x01000000
|
||||
|
||||
/*** IOCTL commands for lirc driver ***/
|
||||
|
||||
#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32)
|
||||
|
||||
#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32)
|
||||
#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32)
|
||||
#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32)
|
||||
|
||||
#define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, __u32)
|
||||
#define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, __u32)
|
||||
|
||||
/* code length in bits, currently only for LIRC_MODE_LIRCCODE */
|
||||
#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32)
|
||||
|
||||
#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, __u32)
|
||||
#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, __u32)
|
||||
/* Note: these can reset the according pulse_width */
|
||||
#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32)
|
||||
#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32)
|
||||
#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32)
|
||||
#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32)
|
||||
|
||||
/*
|
||||
* when a timeout != 0 is set the driver will send a
|
||||
* LIRC_MODE2_TIMEOUT data packet, otherwise LIRC_MODE2_TIMEOUT is
|
||||
* never sent, timeout is disabled by default
|
||||
*/
|
||||
#define LIRC_SET_REC_TIMEOUT _IOW('i', 0x00000018, __u32)
|
||||
|
||||
/* 1 enables, 0 disables timeout reports in MODE2 */
|
||||
#define LIRC_SET_REC_TIMEOUT_REPORTS _IOW('i', 0x00000019, __u32)
|
||||
|
||||
/*
|
||||
* if enabled from the next key press on the driver will send
|
||||
* LIRC_MODE2_FREQUENCY packets
|
||||
*/
|
||||
#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32)
|
||||
|
||||
/*
|
||||
* to set a range use LIRC_SET_REC_CARRIER_RANGE with the
|
||||
* lower bound first and later LIRC_SET_REC_CARRIER with the upper bound
|
||||
*/
|
||||
#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32)
|
||||
|
||||
#define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32)
|
||||
|
||||
/*
|
||||
* Return the recording timeout, which is either set by
|
||||
* the ioctl LIRC_SET_REC_TIMEOUT or by the kernel after setting the protocols.
|
||||
*/
|
||||
#define LIRC_GET_REC_TIMEOUT _IOR('i', 0x00000024, __u32)
|
||||
|
||||
/*
|
||||
* struct lirc_scancode - decoded scancode with protocol for use with
|
||||
* LIRC_MODE_SCANCODE
|
||||
*
|
||||
* @timestamp: Timestamp in nanoseconds using CLOCK_MONOTONIC when IR
|
||||
* was decoded.
|
||||
* @flags: should be 0 for transmit. When receiving scancodes,
|
||||
* LIRC_SCANCODE_FLAG_TOGGLE or LIRC_SCANCODE_FLAG_REPEAT can be set
|
||||
* depending on the protocol
|
||||
* @rc_proto: see enum rc_proto
|
||||
* @keycode: the translated keycode. Set to 0 for transmit.
|
||||
* @scancode: the scancode received or to be sent
|
||||
*/
|
||||
struct lirc_scancode {
|
||||
__u64 timestamp;
|
||||
__u16 flags;
|
||||
__u16 rc_proto;
|
||||
__u32 keycode;
|
||||
__u64 scancode;
|
||||
};
|
||||
|
||||
/* Set if the toggle bit of rc-5 or rc-6 is enabled */
|
||||
#define LIRC_SCANCODE_FLAG_TOGGLE 1
|
||||
/* Set if this is a nec or sanyo repeat */
|
||||
#define LIRC_SCANCODE_FLAG_REPEAT 2
|
||||
|
||||
/**
|
||||
* enum rc_proto - the Remote Controller protocol
|
||||
*
|
||||
* @RC_PROTO_UNKNOWN: Protocol not known
|
||||
* @RC_PROTO_OTHER: Protocol known but proprietary
|
||||
* @RC_PROTO_RC5: Philips RC5 protocol
|
||||
* @RC_PROTO_RC5X_20: Philips RC5x 20 bit protocol
|
||||
* @RC_PROTO_RC5_SZ: StreamZap variant of RC5
|
||||
* @RC_PROTO_JVC: JVC protocol
|
||||
* @RC_PROTO_SONY12: Sony 12 bit protocol
|
||||
* @RC_PROTO_SONY15: Sony 15 bit protocol
|
||||
* @RC_PROTO_SONY20: Sony 20 bit protocol
|
||||
* @RC_PROTO_NEC: NEC protocol
|
||||
* @RC_PROTO_NECX: Extended NEC protocol
|
||||
* @RC_PROTO_NEC32: NEC 32 bit protocol
|
||||
* @RC_PROTO_SANYO: Sanyo protocol
|
||||
* @RC_PROTO_MCIR2_KBD: RC6-ish MCE keyboard
|
||||
* @RC_PROTO_MCIR2_MSE: RC6-ish MCE mouse
|
||||
* @RC_PROTO_RC6_0: Philips RC6-0-16 protocol
|
||||
* @RC_PROTO_RC6_6A_20: Philips RC6-6A-20 protocol
|
||||
* @RC_PROTO_RC6_6A_24: Philips RC6-6A-24 protocol
|
||||
* @RC_PROTO_RC6_6A_32: Philips RC6-6A-32 protocol
|
||||
* @RC_PROTO_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol
|
||||
* @RC_PROTO_SHARP: Sharp protocol
|
||||
* @RC_PROTO_XMP: XMP protocol
|
||||
* @RC_PROTO_CEC: CEC protocol
|
||||
* @RC_PROTO_IMON: iMon Pad protocol
|
||||
* @RC_PROTO_RCMM12: RC-MM protocol 12 bits
|
||||
* @RC_PROTO_RCMM24: RC-MM protocol 24 bits
|
||||
* @RC_PROTO_RCMM32: RC-MM protocol 32 bits
|
||||
*/
|
||||
enum rc_proto {
|
||||
RC_PROTO_UNKNOWN = 0,
|
||||
RC_PROTO_OTHER = 1,
|
||||
RC_PROTO_RC5 = 2,
|
||||
RC_PROTO_RC5X_20 = 3,
|
||||
RC_PROTO_RC5_SZ = 4,
|
||||
RC_PROTO_JVC = 5,
|
||||
RC_PROTO_SONY12 = 6,
|
||||
RC_PROTO_SONY15 = 7,
|
||||
RC_PROTO_SONY20 = 8,
|
||||
RC_PROTO_NEC = 9,
|
||||
RC_PROTO_NECX = 10,
|
||||
RC_PROTO_NEC32 = 11,
|
||||
RC_PROTO_SANYO = 12,
|
||||
RC_PROTO_MCIR2_KBD = 13,
|
||||
RC_PROTO_MCIR2_MSE = 14,
|
||||
RC_PROTO_RC6_0 = 15,
|
||||
RC_PROTO_RC6_6A_20 = 16,
|
||||
RC_PROTO_RC6_6A_24 = 17,
|
||||
RC_PROTO_RC6_6A_32 = 18,
|
||||
RC_PROTO_RC6_MCE = 19,
|
||||
RC_PROTO_SHARP = 20,
|
||||
RC_PROTO_XMP = 21,
|
||||
RC_PROTO_CEC = 22,
|
||||
RC_PROTO_IMON = 23,
|
||||
RC_PROTO_RCMM12 = 24,
|
||||
RC_PROTO_RCMM24 = 25,
|
||||
RC_PROTO_RCMM32 = 26,
|
||||
};
|
||||
|
||||
#endif
|
@ -90,7 +90,7 @@ EXTRA_WARNINGS += -Wstrict-aliasing=3
|
||||
|
||||
else ifneq ($(CROSS_COMPILE),)
|
||||
CLANG_CROSS_FLAGS := --target=$(notdir $(CROSS_COMPILE:%-=%))
|
||||
GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)gcc))
|
||||
GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)gcc 2>/dev/null))
|
||||
ifneq ($(GCC_TOOLCHAIN_DIR),)
|
||||
CLANG_CROSS_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))
|
||||
CLANG_CROSS_FLAGS += --sysroot=$(shell $(CROSS_COMPILE)gcc -print-sysroot)
|
||||
|
@ -28,7 +28,6 @@
|
||||
// 5. We can read keycode from same /dev/lirc device
|
||||
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/lirc.h>
|
||||
#include <linux/input.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
@ -27,7 +27,7 @@ TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto
|
||||
net6_port_net6_port net_port_mac_proto_net"
|
||||
|
||||
# Reported bugs, also described by TYPE_ variables below
|
||||
BUGS="flush_remove_add"
|
||||
BUGS="flush_remove_add reload"
|
||||
|
||||
# List of possible paths to pktgen script from kernel tree for performance tests
|
||||
PKTGEN_SCRIPT_PATHS="
|
||||
@ -354,6 +354,23 @@ TYPE_flush_remove_add="
|
||||
display Add two elements, flush, re-add
|
||||
"
|
||||
|
||||
TYPE_reload="
|
||||
display net,mac with reload
|
||||
type_spec ipv4_addr . ether_addr
|
||||
chain_spec ip daddr . ether saddr
|
||||
dst addr4
|
||||
src mac
|
||||
start 1
|
||||
count 1
|
||||
src_delta 2000
|
||||
tools sendip nc bash
|
||||
proto udp
|
||||
|
||||
race_repeat 0
|
||||
|
||||
perf_duration 0
|
||||
"
|
||||
|
||||
# Set template for all tests, types and rules are filled in depending on test
|
||||
set_template='
|
||||
flush ruleset
|
||||
@ -1473,6 +1490,59 @@ test_bug_flush_remove_add() {
|
||||
nft flush ruleset
|
||||
}
|
||||
|
||||
# - add ranged element, check that packets match it
|
||||
# - reload the set, check packets still match
|
||||
test_bug_reload() {
|
||||
setup veth send_"${proto}" set || return ${KSELFTEST_SKIP}
|
||||
rstart=${start}
|
||||
|
||||
range_size=1
|
||||
for i in $(seq "${start}" $((start + count))); do
|
||||
end=$((start + range_size))
|
||||
|
||||
# Avoid negative or zero-sized port ranges
|
||||
if [ $((end / 65534)) -gt $((start / 65534)) ]; then
|
||||
start=${end}
|
||||
end=$((end + 1))
|
||||
fi
|
||||
srcstart=$((start + src_delta))
|
||||
srcend=$((end + src_delta))
|
||||
|
||||
add "$(format)" || return 1
|
||||
range_size=$((range_size + 1))
|
||||
start=$((end + range_size))
|
||||
done
|
||||
|
||||
# check kernel does allocate pcpu sctrach map
|
||||
# for reload with no elemet add/delete
|
||||
( echo flush set inet filter test ;
|
||||
nft list set inet filter test ) | nft -f -
|
||||
|
||||
start=${rstart}
|
||||
range_size=1
|
||||
|
||||
for i in $(seq "${start}" $((start + count))); do
|
||||
end=$((start + range_size))
|
||||
|
||||
# Avoid negative or zero-sized port ranges
|
||||
if [ $((end / 65534)) -gt $((start / 65534)) ]; then
|
||||
start=${end}
|
||||
end=$((end + 1))
|
||||
fi
|
||||
srcstart=$((start + src_delta))
|
||||
srcend=$((end + src_delta))
|
||||
|
||||
for j in $(seq ${start} $((range_size / 2 + 1)) ${end}); do
|
||||
send_match "${j}" $((j + src_delta)) || return 1
|
||||
done
|
||||
|
||||
range_size=$((range_size + 1))
|
||||
start=$((end + range_size))
|
||||
done
|
||||
|
||||
nft flush ruleset
|
||||
}
|
||||
|
||||
test_reported_issues() {
|
||||
eval test_bug_"${subtest}"
|
||||
}
|
||||
|
@ -899,6 +899,144 @@ EOF
|
||||
ip netns exec "$ns0" nft delete table $family nat
|
||||
}
|
||||
|
||||
test_stateless_nat_ip()
|
||||
{
|
||||
local lret=0
|
||||
|
||||
ip netns exec "$ns0" sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
|
||||
ip netns exec "$ns0" sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
|
||||
|
||||
ip netns exec "$ns2" ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "ERROR: cannot ping $ns1 from $ns2 before loading stateless rules"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ip netns exec "$ns0" nft -f /dev/stdin <<EOF
|
||||
table ip stateless {
|
||||
map xlate_in {
|
||||
typeof meta iifname . ip saddr . ip daddr : ip daddr
|
||||
elements = {
|
||||
"veth1" . 10.0.2.99 . 10.0.1.99 : 10.0.2.2,
|
||||
}
|
||||
}
|
||||
map xlate_out {
|
||||
typeof meta iifname . ip saddr . ip daddr : ip daddr
|
||||
elements = {
|
||||
"veth0" . 10.0.1.99 . 10.0.2.2 : 10.0.2.99
|
||||
}
|
||||
}
|
||||
|
||||
chain prerouting {
|
||||
type filter hook prerouting priority -400; policy accept;
|
||||
ip saddr set meta iifname . ip saddr . ip daddr map @xlate_in
|
||||
ip daddr set meta iifname . ip saddr . ip daddr map @xlate_out
|
||||
}
|
||||
}
|
||||
EOF
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "SKIP: Could not add ip statless rules"
|
||||
return $ksft_skip
|
||||
fi
|
||||
|
||||
reset_counters
|
||||
|
||||
ip netns exec "$ns2" ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "ERROR: cannot ping $ns1 from $ns2 with stateless rules"
|
||||
lret=1
|
||||
fi
|
||||
|
||||
# ns1 should have seen packets from .2.2, due to stateless rewrite.
|
||||
expect="packets 1 bytes 84"
|
||||
cnt=$(ip netns exec "$ns1" nft list counter inet filter ns0insl | grep -q "$expect")
|
||||
if [ $? -ne 0 ]; then
|
||||
bad_counter "$ns1" ns0insl "$expect" "test_stateless 1"
|
||||
lret=1
|
||||
fi
|
||||
|
||||
for dir in "in" "out" ; do
|
||||
cnt=$(ip netns exec "$ns2" nft list counter inet filter ns1${dir} | grep -q "$expect")
|
||||
if [ $? -ne 0 ]; then
|
||||
bad_counter "$ns2" ns1$dir "$expect" "test_stateless 2"
|
||||
lret=1
|
||||
fi
|
||||
done
|
||||
|
||||
# ns1 should not have seen packets from ns2, due to masquerade
|
||||
expect="packets 0 bytes 0"
|
||||
for dir in "in" "out" ; do
|
||||
cnt=$(ip netns exec "$ns1" nft list counter inet filter ns2${dir} | grep -q "$expect")
|
||||
if [ $? -ne 0 ]; then
|
||||
bad_counter "$ns1" ns0$dir "$expect" "test_stateless 3"
|
||||
lret=1
|
||||
fi
|
||||
|
||||
cnt=$(ip netns exec "$ns0" nft list counter inet filter ns1${dir} | grep -q "$expect")
|
||||
if [ $? -ne 0 ]; then
|
||||
bad_counter "$ns0" ns1$dir "$expect" "test_stateless 4"
|
||||
lret=1
|
||||
fi
|
||||
done
|
||||
|
||||
reset_counters
|
||||
|
||||
socat -h > /dev/null 2>&1
|
||||
if [ $? -ne 0 ];then
|
||||
echo "SKIP: Could not run stateless nat frag test without socat tool"
|
||||
if [ $lret -eq 0 ]; then
|
||||
return $ksft_skip
|
||||
fi
|
||||
|
||||
ip netns exec "$ns0" nft delete table ip stateless
|
||||
return $lret
|
||||
fi
|
||||
|
||||
local tmpfile=$(mktemp)
|
||||
dd if=/dev/urandom of=$tmpfile bs=4096 count=1 2>/dev/null
|
||||
|
||||
local outfile=$(mktemp)
|
||||
ip netns exec "$ns1" timeout 3 socat -u UDP4-RECV:4233 OPEN:$outfile < /dev/null &
|
||||
sc_r=$!
|
||||
|
||||
sleep 1
|
||||
# re-do with large ping -> ip fragmentation
|
||||
ip netns exec "$ns2" timeout 3 socat - UDP4-SENDTO:"10.0.1.99:4233" < "$tmpfile" > /dev/null
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "ERROR: failed to test udp $ns1 to $ns2 with stateless ip nat" 1>&2
|
||||
lret=1
|
||||
fi
|
||||
|
||||
wait
|
||||
|
||||
cmp "$tmpfile" "$outfile"
|
||||
if [ $? -ne 0 ]; then
|
||||
ls -l "$tmpfile" "$outfile"
|
||||
echo "ERROR: in and output file mismatch when checking udp with stateless nat" 1>&2
|
||||
lret=1
|
||||
fi
|
||||
|
||||
rm -f "$tmpfile" "$outfile"
|
||||
|
||||
# ns1 should have seen packets from 2.2, due to stateless rewrite.
|
||||
expect="packets 3 bytes 4164"
|
||||
cnt=$(ip netns exec "$ns1" nft list counter inet filter ns0insl | grep -q "$expect")
|
||||
if [ $? -ne 0 ]; then
|
||||
bad_counter "$ns1" ns0insl "$expect" "test_stateless 5"
|
||||
lret=1
|
||||
fi
|
||||
|
||||
ip netns exec "$ns0" nft delete table ip stateless
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Could not delete table ip stateless" 1>&2
|
||||
lret=1
|
||||
fi
|
||||
|
||||
test $lret -eq 0 && echo "PASS: IP statless for $ns2"
|
||||
|
||||
return $lret
|
||||
}
|
||||
|
||||
# ip netns exec "$ns0" ping -c 1 -q 10.0.$i.99
|
||||
for i in 0 1 2; do
|
||||
ip netns exec ns$i-$sfx nft -f /dev/stdin <<EOF
|
||||
@ -965,6 +1103,19 @@ table inet filter {
|
||||
EOF
|
||||
done
|
||||
|
||||
# special case for stateless nat check, counter needs to
|
||||
# be done before (input) ip defragmentation
|
||||
ip netns exec ns1-$sfx nft -f /dev/stdin <<EOF
|
||||
table inet filter {
|
||||
counter ns0insl {}
|
||||
|
||||
chain pre {
|
||||
type filter hook prerouting priority -400; policy accept;
|
||||
ip saddr 10.0.2.2 counter name "ns0insl"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
sleep 3
|
||||
# test basic connectivity
|
||||
for i in 1 2; do
|
||||
@ -1019,6 +1170,7 @@ $test_inet_nat && test_redirect inet
|
||||
$test_inet_nat && test_redirect6 inet
|
||||
|
||||
test_port_shadowing
|
||||
test_stateless_nat_ip
|
||||
|
||||
if [ $ret -ne 0 ];then
|
||||
echo -n "FAIL: "
|
||||
|
@ -9,7 +9,7 @@ ns="ns-$sfx"
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
ksft_skip=4
|
||||
|
||||
zones=20000
|
||||
zones=2000
|
||||
have_ct_tool=0
|
||||
ret=0
|
||||
|
||||
@ -75,10 +75,10 @@ EOF
|
||||
|
||||
while [ $i -lt $max_zones ]; do
|
||||
local start=$(date +%s%3N)
|
||||
i=$((i + 10000))
|
||||
i=$((i + 1000))
|
||||
j=$((j + 1))
|
||||
# nft rule in output places each packet in a different zone.
|
||||
dd if=/dev/zero of=/dev/stdout bs=8k count=10000 2>/dev/null | ip netns exec "$ns" socat STDIN UDP:127.0.0.1:12345,sourceport=12345
|
||||
dd if=/dev/zero of=/dev/stdout bs=8k count=1000 2>/dev/null | ip netns exec "$ns" socat STDIN UDP:127.0.0.1:12345,sourceport=12345
|
||||
if [ $? -ne 0 ] ;then
|
||||
ret=1
|
||||
break
|
||||
@ -86,7 +86,7 @@ EOF
|
||||
|
||||
stop=$(date +%s%3N)
|
||||
local duration=$((stop-start))
|
||||
echo "PASS: added 10000 entries in $duration ms (now $i total, loop $j)"
|
||||
echo "PASS: added 1000 entries in $duration ms (now $i total, loop $j)"
|
||||
done
|
||||
|
||||
if [ $have_ct_tool -eq 1 ]; then
|
||||
@ -128,11 +128,11 @@ test_conntrack_tool() {
|
||||
break
|
||||
fi
|
||||
|
||||
if [ $((i%10000)) -eq 0 ];then
|
||||
if [ $((i%1000)) -eq 0 ];then
|
||||
stop=$(date +%s%3N)
|
||||
|
||||
local duration=$((stop-start))
|
||||
echo "PASS: added 10000 entries in $duration ms (now $i total)"
|
||||
echo "PASS: added 1000 entries in $duration ms (now $i total)"
|
||||
start=$stop
|
||||
fi
|
||||
done
|
||||
|
Loading…
Reference in New Issue
Block a user