Including fixes from bluetooth, wireless and netfilter.

There's one fix for power management with Intel's e1000e here,
 Thorsten tells us there's another problem that started in v6.9.
 We're trying to wrap that up but I don't think it's blocking.
 
 Current release - new code bugs:
 
  - wifi: mac80211: disable softirqs for queued frame handling
 
  - af_unix: fix uninit-value in __unix_walk_scc(), with the new garbage
    collection algo
 
 Previous releases - regressions:
 
  - Bluetooth:
    - qca: fix BT enable failure for QCA6390 after warm reboot
    - add quirk to ignore reserved PHY bits in LE Extended Adv Report,
      abused by some Broadcom controllers found on Apple machines
 
  - wifi: wilc1000: fix ies_len type in connect path
 
 Previous releases - always broken:
 
  - tcp: fix DSACK undo in fast recovery to call tcp_try_to_open(),
    avoid premature timeouts
 
  - net: make sure skb_datagram_iter maps fragments page by page,
    in case we somehow get compound highmem mixed in
 
  - eth: bnx2x: fix multiple UBSAN array-index-out-of-bounds when
    more queues are used
 
 Misc:
 
  - MAINTAINERS: Remembering Larry Finger
 
 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmaGv3sACgkQMUZtbf5S
 IrviRxAAr7yvDg07P1UzFsXI1khOijGCxOYcDDV+AHVZKwJ9fAq0ky5pcaiW62mY
 h3HffvEbNgZ07zd9l4Z9dVoel5ke9k4yofYZrI0D8X/T1e/Xo0LlxUFGwb0IidBj
 IYkTnZfu1lGa73TWCIh369s1HgybupiHQicYSw+KIO1wtfds8gvyZJUyjNhlvUYQ
 NdB/JQrBp/oxm2JlAMDubZfNuVEFCum5J3Ldj5W32j+H82RbGDi/eMn5w+Cs/tEx
 rRFSuJ1L0rBhNcB4HDbcfin9jHjLhDjNXyYprlZAauMXK5AEBwRcOuEzyXWt1Npq
 ZkJ8t/ToVLk9QkXaKA1gR9C6Bo8A+SL5a8ddfj/pHEqOa/GNXKYqEvGOmM7mmbBf
 93sU+dBYZ3nLGrUtuTRVGTnbr+J1AhP/kUqIY1c787m3gCSB1qFkF67DQiYTGB9g
 qf+xTcmJeGpL+4OtXgjpK4gUa152g0VsuAMTzecW/7EU/owD0+zCWuVGK9Gv/bgf
 si40hgZ7Ipnq8k+N+4e2VQp1ufCduT8zGn6sxiivdS5GSNc8e2BnQH3AfjfIM8Z8
 rK15U5WJIVQiCkthYh8cx8pxh2uwtcXevjUh4B682/U4HbLdiYfAQuD4/AOc2i8M
 EJVzl7/5AaxhjoZPxloe9mtRnMvt7XhUiNOW0lR9fgDYOqcmnSo=
 =MZAG
 -----END PGP SIGNATURE-----

Merge tag 'net-6.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from Jakub Kicinski:
 "Including fixes from bluetooth, wireless and netfilter.

  There's one fix for power management with Intel's e1000e here,
  Thorsten tells us there's another problem that started in v6.9. We're
  trying to wrap that up but I don't think it's blocking.

  Current release - new code bugs:

   - wifi: mac80211: disable softirqs for queued frame handling

   - af_unix: fix uninit-value in __unix_walk_scc(), with the new
     garbage collection algo

  Previous releases - regressions:

   - Bluetooth:
      - qca: fix BT enable failure for QCA6390 after warm reboot
      - add quirk to ignore reserved PHY bits in LE Extended Adv Report,
        abused by some Broadcom controllers found on Apple machines

   - wifi: wilc1000: fix ies_len type in connect path

  Previous releases - always broken:

   - tcp: fix DSACK undo in fast recovery to call tcp_try_to_open(),
     avoid premature timeouts

   - net: make sure skb_datagram_iter maps fragments page by page, in
     case we somehow get compound highmem mixed in

   - eth: bnx2x: fix multiple UBSAN array-index-out-of-bounds when more
     queues are used

  Misc:

   - MAINTAINERS: Remembering Larry Finger"

* tag 'net-6.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (62 commits)
  bnxt_en: Fix the resource check condition for RSS contexts
  mlxsw: core_linecards: Fix double memory deallocation in case of invalid INI file
  inet_diag: Initialize pad field in struct inet_diag_req_v2
  tcp: Don't flag tcp_sk(sk)->rx_opt.saw_unknown for TCP AO.
  selftests: make order checking verbose in msg_zerocopy selftest
  selftests: fix OOM in msg_zerocopy selftest
  ice: use proper macro for testing bit
  ice: Reject pin requests with unsupported flags
  ice: Don't process extts if PTP is disabled
  ice: Fix improper extts handling
  selftest: af_unix: Add test case for backtrack after finalising SCC.
  af_unix: Fix uninit-value in __unix_walk_scc()
  bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set()
  net: rswitch: Avoid use-after-free in rswitch_poll()
  netfilter: nf_tables: unconditionally flush pending work before notifier
  wifi: iwlwifi: mvm: check vif for NULL/ERR_PTR before dereference
  wifi: iwlwifi: mvm: avoid link lookup in statistics
  wifi: iwlwifi: mvm: don't wake up rx_sync_waitq upon RFKILL
  wifi: iwlwifi: properly set WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK
  wifi: wilc1000: fix ies_len type in connect path
  ...
This commit is contained in:
Linus Torvalds 2024-07-04 10:11:12 -07:00
commit 033771c085
67 changed files with 629 additions and 377 deletions

View file

@ -1214,6 +1214,10 @@ D: UDF filesystem
S: (ask for current address)
S: USA
N: Larry Finger
E: Larry.Finger@lwfinger.net
D: Maintainer of wireless drivers, too many to list here
N: Jürgen Fischer
E: fischer@norbit.de
D: Author of Adaptec AHA-152x SCSI driver

View file

@ -3601,10 +3601,9 @@ W: https://wireless.wiki.kernel.org/en/users/Drivers/b43
F: drivers/net/wireless/broadcom/b43/
B43LEGACY WIRELESS DRIVER
M: Larry Finger <Larry.Finger@lwfinger.net>
L: linux-wireless@vger.kernel.org
L: b43-dev@lists.infradead.org
S: Maintained
S: Orphan
W: https://wireless.wiki.kernel.org/en/users/Drivers/b43
F: drivers/net/wireless/broadcom/b43legacy/
@ -18374,7 +18373,7 @@ M: Jeff Johnson <jjohnson@kernel.org>
L: ath12k@lists.infradead.org
S: Supported
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath12k
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git
F: drivers/net/wireless/ath/ath12k/
N: ath12k
@ -18384,7 +18383,7 @@ M: Jeff Johnson <jjohnson@kernel.org>
L: ath10k@lists.infradead.org
S: Supported
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git
F: drivers/net/wireless/ath/ath10k/
N: ath10k
@ -18395,7 +18394,7 @@ L: ath11k@lists.infradead.org
S: Supported
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath11k
B: https://wireless.wiki.kernel.org/en/users/Drivers/ath11k/bugreport
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git
F: drivers/net/wireless/ath/ath11k/
N: ath11k
@ -18404,7 +18403,7 @@ M: Toke Høiland-Jørgensen <toke@toke.dk>
L: linux-wireless@vger.kernel.org
S: Maintained
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath9k
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git
F: Documentation/devicetree/bindings/net/wireless/qca,ath9k.yaml
F: drivers/net/wireless/ath/ath9k/
@ -19509,7 +19508,6 @@ F: drivers/net/wireless/realtek/rtl818x/rtl8180/
RTL8187 WIRELESS DRIVER
M: Hin-Tak Leung <hintak.leung@gmail.com>
M: Larry Finger <Larry.Finger@lwfinger.net>
L: linux-wireless@vger.kernel.org
S: Maintained
T: git https://github.com/pkshih/rtw.git
@ -21247,7 +21245,6 @@ W: http://wiki.laptop.org/go/DCON
F: drivers/staging/olpc_dcon/
STAGING - REALTEK RTL8712U DRIVERS
M: Larry Finger <Larry.Finger@lwfinger.net>
M: Florian Schilhabel <florian.c.schilhabel@googlemail.com>.
S: Odd Fixes
F: drivers/staging/rtl8712/

View file

@ -382,7 +382,7 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
/* The first 4 bytes indicates the Intel PCIe specific packet type */
pdata = skb_pull_data(skb, BTINTEL_PCIE_HCI_TYPE_LEN);
if (!data) {
if (!pdata) {
bt_dev_err(hdev, "Corrupted packet received");
ret = -EILSEQ;
goto exit_error;

View file

@ -281,7 +281,7 @@ static u8 crc8_table[CRC8_TABLE_SIZE];
/* Default configurations */
#define DEFAULT_H2C_WAKEUP_MODE WAKEUP_METHOD_BREAK
#define DEFAULT_PS_MODE PS_MODE_DISABLE
#define DEFAULT_PS_MODE PS_MODE_ENABLE
#define FW_INIT_BAUDRATE HCI_NXP_PRI_BAUDRATE
static struct sk_buff *nxp_drv_send_cmd(struct hci_dev *hdev, u16 opcode,

View file

@ -495,6 +495,10 @@ struct bcm4377_data;
* extended scanning
* broken_mws_transport_config: Set to true if the chip erroneously claims to
* support MWS Transport Configuration
* broken_le_ext_adv_report_phy: Set to true if this chip stuffs flags inside
* reserved bits of Primary/Secondary_PHY inside
* LE Extended Advertising Report events which
* have to be ignored
* send_calibration: Optional callback to send calibration data
* send_ptb: Callback to send "PTB" regulatory/calibration data
*/
@ -513,6 +517,7 @@ struct bcm4377_hw {
unsigned long broken_ext_scan : 1;
unsigned long broken_mws_transport_config : 1;
unsigned long broken_le_coded : 1;
unsigned long broken_le_ext_adv_report_phy : 1;
int (*send_calibration)(struct bcm4377_data *bcm4377);
int (*send_ptb)(struct bcm4377_data *bcm4377,
@ -716,7 +721,7 @@ static void bcm4377_handle_ack(struct bcm4377_data *bcm4377,
ring->events[msgid] = NULL;
}
bitmap_release_region(ring->msgids, msgid, ring->n_entries);
bitmap_release_region(ring->msgids, msgid, 0);
unlock:
spin_unlock_irqrestore(&ring->lock, flags);
@ -2373,6 +2378,8 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id)
set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks);
if (bcm4377->hw->broken_le_coded)
set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks);
if (bcm4377->hw->broken_le_ext_adv_report_phy)
set_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY, &hdev->quirks);
pci_set_drvdata(pdev, bcm4377);
hci_set_drvdata(hdev, bcm4377);
@ -2477,6 +2484,7 @@ static const struct bcm4377_hw bcm4377_hw_variants[] = {
.clear_pciecfg_subsystem_ctrl_bit19 = true,
.broken_mws_transport_config = true,
.broken_le_coded = true,
.broken_le_ext_adv_report_phy = true,
.send_calibration = bcm4387_send_calibration,
.send_ptb = bcm4378_send_ptb,
},

View file

@ -2450,15 +2450,27 @@ static void qca_serdev_shutdown(struct device *dev)
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
struct hci_uart *hu = &qcadev->serdev_hu;
struct hci_dev *hdev = hu->hdev;
struct qca_data *qca = hu->priv;
const u8 ibs_wake_cmd[] = { 0xFD };
const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 };
if (qcadev->btsoc_type == QCA_QCA6390) {
if (test_bit(QCA_BT_OFF, &qca->flags) ||
!test_bit(HCI_RUNNING, &hdev->flags))
/* The purpose of sending the VSC is to reset SOC into a initial
* state and the state will ensure next hdev->setup() success.
* if HCI_QUIRK_NON_PERSISTENT_SETUP is set, it means that
* hdev->setup() can do its job regardless of SoC state, so
* don't need to send the VSC.
* if HCI_SETUP is set, it means that hdev->setup() was never
* invoked and the SOC is already in the initial state, so
* don't also need to send the VSC.
*/
if (test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks) ||
hci_dev_test_flag(hdev, HCI_SETUP))
return;
/* The serdev must be in open state when conrol logic arrives
* here, so also fix the use-after-free issue caused by that
* the serdev is flushed or wrote after it is closed.
*/
serdev_device_write_flush(serdev);
ret = serdev_device_write_buf(serdev, ibs_wake_cmd,
sizeof(ibs_wake_cmd));

View file

@ -1214,9 +1214,9 @@ static int bond_option_arp_ip_targets_set(struct bonding *bond,
__be32 target;
if (newval->string) {
if (!in4_pton(newval->string+1, -1, (u8 *)&target, -1, NULL)) {
netdev_err(bond->dev, "invalid ARP target %pI4 specified\n",
&target);
if (strlen(newval->string) < 1 ||
!in4_pton(newval->string + 1, -1, (u8 *)&target, -1, NULL)) {
netdev_err(bond->dev, "invalid ARP target specified\n");
return ret;
}
if (newval->string[0] == '+')

View file

@ -125,6 +125,7 @@ static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_liste
static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = {
.quirks = 0,
.family = KVASER_LEAF,
.ops = &kvaser_usb_leaf_dev_ops,
};

View file

@ -1262,7 +1262,7 @@ enum {
struct bnx2x_fw_stats_req {
struct stats_query_header hdr;
struct stats_query_entry query[FP_SB_MAX_E1x+
struct stats_query_entry query[FP_SB_MAX_E2 +
BNX2X_FIRST_QUEUE_QUERY_IDX];
};

View file

@ -12669,7 +12669,11 @@ bool bnxt_rfs_capable(struct bnxt *bp, bool new_rss_ctx)
if (!BNXT_NEW_RM(bp))
return true;
if (hwr.vnic == bp->hw_resc.resv_vnics &&
/* Do not reduce VNIC and RSS ctx reservations. There is a FW
* issue that will mess up the default VNIC if we reduce the
* reservations.
*/
if (hwr.vnic <= bp->hw_resc.resv_vnics &&
hwr.rss_ctx <= bp->hw_resc.resv_rsscos_ctxs)
return true;

View file

@ -6363,49 +6363,49 @@ static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter)
mac_data |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
ew32(EXTCNF_CTRL, mac_data);
/* Enable the Dynamic Power Gating in the MAC */
mac_data = er32(FEXTNVM7);
mac_data |= BIT(22);
ew32(FEXTNVM7, mac_data);
/* Disable disconnected cable conditioning for Power Gating */
mac_data = er32(DPGFR);
mac_data |= BIT(2);
ew32(DPGFR, mac_data);
/* Don't wake from dynamic Power Gating with clock request */
mac_data = er32(FEXTNVM12);
mac_data |= BIT(12);
ew32(FEXTNVM12, mac_data);
/* Ungate PGCB clock */
mac_data = er32(FEXTNVM9);
mac_data &= ~BIT(28);
ew32(FEXTNVM9, mac_data);
/* Enable K1 off to enable mPHY Power Gating */
mac_data = er32(FEXTNVM6);
mac_data |= BIT(31);
ew32(FEXTNVM6, mac_data);
/* Enable mPHY power gating for any link and speed */
mac_data = er32(FEXTNVM8);
mac_data |= BIT(9);
ew32(FEXTNVM8, mac_data);
/* Enable the Dynamic Clock Gating in the DMA and MAC */
mac_data = er32(CTRL_EXT);
mac_data |= E1000_CTRL_EXT_DMA_DYN_CLK_EN;
ew32(CTRL_EXT, mac_data);
/* No MAC DPG gating SLP_S0 in modern standby
* Switch the logic of the lanphypc to use PMC counter
*/
mac_data = er32(FEXTNVM5);
mac_data |= BIT(7);
ew32(FEXTNVM5, mac_data);
}
/* Enable the Dynamic Power Gating in the MAC */
mac_data = er32(FEXTNVM7);
mac_data |= BIT(22);
ew32(FEXTNVM7, mac_data);
/* Don't wake from dynamic Power Gating with clock request */
mac_data = er32(FEXTNVM12);
mac_data |= BIT(12);
ew32(FEXTNVM12, mac_data);
/* Ungate PGCB clock */
mac_data = er32(FEXTNVM9);
mac_data &= ~BIT(28);
ew32(FEXTNVM9, mac_data);
/* Enable K1 off to enable mPHY Power Gating */
mac_data = er32(FEXTNVM6);
mac_data |= BIT(31);
ew32(FEXTNVM6, mac_data);
/* Enable mPHY power gating for any link and speed */
mac_data = er32(FEXTNVM8);
mac_data |= BIT(9);
ew32(FEXTNVM8, mac_data);
/* No MAC DPG gating SLP_S0 in modern standby
* Switch the logic of the lanphypc to use PMC counter
*/
mac_data = er32(FEXTNVM5);
mac_data |= BIT(7);
ew32(FEXTNVM5, mac_data);
/* Disable the time synchronization clock */
mac_data = er32(FEXTNVM7);
mac_data |= BIT(31);
@ -6498,33 +6498,6 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
} else {
/* Request driver unconfigure the device from S0ix */
/* Disable the Dynamic Power Gating in the MAC */
mac_data = er32(FEXTNVM7);
mac_data &= 0xFFBFFFFF;
ew32(FEXTNVM7, mac_data);
/* Disable mPHY power gating for any link and speed */
mac_data = er32(FEXTNVM8);
mac_data &= ~BIT(9);
ew32(FEXTNVM8, mac_data);
/* Disable K1 off */
mac_data = er32(FEXTNVM6);
mac_data &= ~BIT(31);
ew32(FEXTNVM6, mac_data);
/* Disable Ungate PGCB clock */
mac_data = er32(FEXTNVM9);
mac_data |= BIT(28);
ew32(FEXTNVM9, mac_data);
/* Cancel not waking from dynamic
* Power Gating with clock request
*/
mac_data = er32(FEXTNVM12);
mac_data &= ~BIT(12);
ew32(FEXTNVM12, mac_data);
/* Cancel disable disconnected cable conditioning
* for Power Gating
*/
@ -6537,13 +6510,6 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
mac_data &= 0xFFF7FFFF;
ew32(CTRL_EXT, mac_data);
/* Revert the lanphypc logic to use the internal Gbe counter
* and not the PMC counter
*/
mac_data = er32(FEXTNVM5);
mac_data &= 0xFFFFFF7F;
ew32(FEXTNVM5, mac_data);
/* Enable the periodic inband message,
* Request PCIe clock in K1 page770_17[10:9] =01b
*/
@ -6581,6 +6547,40 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
mac_data &= ~BIT(31);
mac_data |= BIT(0);
ew32(FEXTNVM7, mac_data);
/* Disable the Dynamic Power Gating in the MAC */
mac_data = er32(FEXTNVM7);
mac_data &= 0xFFBFFFFF;
ew32(FEXTNVM7, mac_data);
/* Disable mPHY power gating for any link and speed */
mac_data = er32(FEXTNVM8);
mac_data &= ~BIT(9);
ew32(FEXTNVM8, mac_data);
/* Disable K1 off */
mac_data = er32(FEXTNVM6);
mac_data &= ~BIT(31);
ew32(FEXTNVM6, mac_data);
/* Disable Ungate PGCB clock */
mac_data = er32(FEXTNVM9);
mac_data |= BIT(28);
ew32(FEXTNVM9, mac_data);
/* Cancel not waking from dynamic
* Power Gating with clock request
*/
mac_data = er32(FEXTNVM12);
mac_data &= ~BIT(12);
ew32(FEXTNVM12, mac_data);
/* Revert the lanphypc logic to use the internal Gbe counter
* and not the PMC counter
*/
mac_data = er32(FEXTNVM5);
mac_data &= 0xFFFFFF7F;
ew32(FEXTNVM5, mac_data);
}
static int e1000e_pm_freeze(struct device *dev)

View file

@ -96,7 +96,7 @@ static bool ice_is_internal_reading_supported(struct ice_pf *pf)
unsigned long sensors = pf->hw.dev_caps.supported_sensors;
return _test_bit(ICE_SENSOR_SUPPORT_E810_INT_TEMP_BIT, &sensors);
return test_bit(ICE_SENSOR_SUPPORT_E810_INT_TEMP_BIT, &sensors);
};
void ice_hwmon_init(struct ice_pf *pf)

View file

@ -1559,6 +1559,10 @@ void ice_ptp_extts_event(struct ice_pf *pf)
u8 chan, tmr_idx;
u32 hi, lo;
/* Don't process timestamp events if PTP is not ready */
if (pf->ptp.state != ICE_PTP_READY)
return;
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
/* Event time is captured by one of the two matched registers
* GLTSYN_EVNT_L: 32 LSB of sampled time event
@ -1584,27 +1588,33 @@ void ice_ptp_extts_event(struct ice_pf *pf)
/**
* ice_ptp_cfg_extts - Configure EXTTS pin and channel
* @pf: Board private structure
* @ena: true to enable; false to disable
* @chan: GPIO channel (0-3)
* @gpio_pin: GPIO pin
* @extts_flags: request flags from the ptp_extts_request.flags
* @config: desired EXTTS configuration.
* @store: If set to true, the values will be stored
*
* Configure an external timestamp event on the requested channel.
*
* Return: 0 on success, -EOPNOTUSPP on unsupported flags
*/
static int
ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
unsigned int extts_flags)
static int ice_ptp_cfg_extts(struct ice_pf *pf, unsigned int chan,
struct ice_extts_channel *config, bool store)
{
u32 func, aux_reg, gpio_reg, irq_reg;
struct ice_hw *hw = &pf->hw;
u8 tmr_idx;
if (chan > (unsigned int)pf->ptp.info.n_ext_ts)
return -EINVAL;
/* Reject requests with unsupported flags */
if (config->flags & ~(PTP_ENABLE_FEATURE |
PTP_RISING_EDGE |
PTP_FALLING_EDGE |
PTP_STRICT_FLAGS))
return -EOPNOTSUPP;
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
irq_reg = rd32(hw, PFINT_OICR_ENA);
if (ena) {
if (config->ena) {
/* Enable the interrupt */
irq_reg |= PFINT_OICR_TSYN_EVNT_M;
aux_reg = GLTSYN_AUX_IN_0_INT_ENA_M;
@ -1613,9 +1623,9 @@ ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
#define GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE BIT(1)
/* set event level to requested edge */
if (extts_flags & PTP_FALLING_EDGE)
if (config->flags & PTP_FALLING_EDGE)
aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE;
if (extts_flags & PTP_RISING_EDGE)
if (config->flags & PTP_RISING_EDGE)
aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_RISING_EDGE;
/* Write GPIO CTL reg.
@ -1636,11 +1646,51 @@ ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
wr32(hw, PFINT_OICR_ENA, irq_reg);
wr32(hw, GLTSYN_AUX_IN(chan, tmr_idx), aux_reg);
wr32(hw, GLGEN_GPIO_CTL(gpio_pin), gpio_reg);
wr32(hw, GLGEN_GPIO_CTL(config->gpio_pin), gpio_reg);
if (store)
memcpy(&pf->ptp.extts_channels[chan], config, sizeof(*config));
return 0;
}
/**
* ice_ptp_disable_all_extts - Disable all EXTTS channels
* @pf: Board private structure
*/
static void ice_ptp_disable_all_extts(struct ice_pf *pf)
{
struct ice_extts_channel extts_cfg = {};
int i;
for (i = 0; i < pf->ptp.info.n_ext_ts; i++) {
if (pf->ptp.extts_channels[i].ena) {
extts_cfg.gpio_pin = pf->ptp.extts_channels[i].gpio_pin;
extts_cfg.ena = false;
ice_ptp_cfg_extts(pf, i, &extts_cfg, false);
}
}
synchronize_irq(pf->oicr_irq.virq);
}
/**
* ice_ptp_enable_all_extts - Enable all EXTTS channels
* @pf: Board private structure
*
* Called during reset to restore user configuration.
*/
static void ice_ptp_enable_all_extts(struct ice_pf *pf)
{
int i;
for (i = 0; i < pf->ptp.info.n_ext_ts; i++) {
if (pf->ptp.extts_channels[i].ena)
ice_ptp_cfg_extts(pf, i, &pf->ptp.extts_channels[i],
false);
}
}
/**
* ice_ptp_cfg_clkout - Configure clock to generate periodic wave
* @pf: Board private structure
@ -1659,6 +1709,9 @@ static int ice_ptp_cfg_clkout(struct ice_pf *pf, unsigned int chan,
u32 func, val, gpio_pin;
u8 tmr_idx;
if (config && config->flags & ~PTP_PEROUT_PHASE)
return -EOPNOTSUPP;
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
/* 0. Reset mode & out_en in AUX_OUT */
@ -1795,17 +1848,18 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
struct ptp_clock_request *rq, int on)
{
struct ice_pf *pf = ptp_info_to_pf(info);
struct ice_perout_channel clk_cfg = {0};
bool sma_pres = false;
unsigned int chan;
u32 gpio_pin;
int err;
if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL))
sma_pres = true;
switch (rq->type) {
case PTP_CLK_REQ_PEROUT:
{
struct ice_perout_channel clk_cfg = {};
chan = rq->perout.index;
if (sma_pres) {
if (chan == ice_pin_desc_e810t[SMA1].chan)
@ -1825,15 +1879,19 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
clk_cfg.gpio_pin = chan;
}
clk_cfg.flags = rq->perout.flags;
clk_cfg.period = ((rq->perout.period.sec * NSEC_PER_SEC) +
rq->perout.period.nsec);
clk_cfg.start_time = ((rq->perout.start.sec * NSEC_PER_SEC) +
rq->perout.start.nsec);
clk_cfg.ena = !!on;
err = ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true);
break;
return ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true);
}
case PTP_CLK_REQ_EXTTS:
{
struct ice_extts_channel extts_cfg = {};
chan = rq->extts.index;
if (sma_pres) {
if (chan < ice_pin_desc_e810t[SMA2].chan)
@ -1849,14 +1907,15 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
gpio_pin = chan;
}
err = ice_ptp_cfg_extts(pf, !!on, chan, gpio_pin,
rq->extts.flags);
break;
extts_cfg.flags = rq->extts.flags;
extts_cfg.gpio_pin = gpio_pin;
extts_cfg.ena = !!on;
return ice_ptp_cfg_extts(pf, chan, &extts_cfg, true);
}
default:
return -EOPNOTSUPP;
}
return err;
}
/**
@ -1869,26 +1928,32 @@ static int ice_ptp_gpio_enable_e823(struct ptp_clock_info *info,
struct ptp_clock_request *rq, int on)
{
struct ice_pf *pf = ptp_info_to_pf(info);
struct ice_perout_channel clk_cfg = {0};
int err;
switch (rq->type) {
case PTP_CLK_REQ_PPS:
{
struct ice_perout_channel clk_cfg = {};
clk_cfg.flags = rq->perout.flags;
clk_cfg.gpio_pin = PPS_PIN_INDEX;
clk_cfg.period = NSEC_PER_SEC;
clk_cfg.ena = !!on;
err = ice_ptp_cfg_clkout(pf, PPS_CLK_GEN_CHAN, &clk_cfg, true);
break;
return ice_ptp_cfg_clkout(pf, PPS_CLK_GEN_CHAN, &clk_cfg, true);
}
case PTP_CLK_REQ_EXTTS:
err = ice_ptp_cfg_extts(pf, !!on, rq->extts.index,
TIME_SYNC_PIN_INDEX, rq->extts.flags);
break;
{
struct ice_extts_channel extts_cfg = {};
extts_cfg.flags = rq->extts.flags;
extts_cfg.gpio_pin = TIME_SYNC_PIN_INDEX;
extts_cfg.ena = !!on;
return ice_ptp_cfg_extts(pf, rq->extts.index, &extts_cfg, true);
}
default:
return -EOPNOTSUPP;
}
return err;
}
/**
@ -2720,6 +2785,10 @@ static int ice_ptp_rebuild_owner(struct ice_pf *pf)
ice_ptp_restart_all_phy(pf);
}
/* Re-enable all periodic outputs and external timestamp events */
ice_ptp_enable_all_clkout(pf);
ice_ptp_enable_all_extts(pf);
return 0;
}
@ -3275,6 +3344,8 @@ void ice_ptp_release(struct ice_pf *pf)
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
ice_ptp_disable_all_extts(pf);
kthread_cancel_delayed_work_sync(&pf->ptp.work);
ice_ptp_port_phy_stop(&pf->ptp.port);

View file

@ -29,10 +29,17 @@ enum ice_ptp_pin_e810t {
struct ice_perout_channel {
bool ena;
u32 gpio_pin;
u32 flags;
u64 period;
u64 start_time;
};
struct ice_extts_channel {
bool ena;
u32 gpio_pin;
u32 flags;
};
/* The ice hardware captures Tx hardware timestamps in the PHY. The timestamp
* is stored in a buffer of registers. Depending on the specific hardware,
* this buffer might be shared across multiple PHY ports.
@ -226,6 +233,7 @@ enum ice_ptp_state {
* @ext_ts_irq: the external timestamp IRQ in use
* @kworker: kwork thread for handling periodic work
* @perout_channels: periodic output data
* @extts_channels: channels for external timestamps
* @info: structure defining PTP hardware capabilities
* @clock: pointer to registered PTP clock device
* @tstamp_config: hardware timestamping configuration
@ -249,6 +257,7 @@ struct ice_ptp {
u8 ext_ts_irq;
struct kthread_worker *kworker;
struct ice_perout_channel perout_channels[GLTSYN_TGT_H_IDX_MAX];
struct ice_extts_channel extts_channels[GLTSYN_TGT_H_IDX_MAX];
struct ptp_clock_info info;
struct ptp_clock *clock;
struct hwtstamp_config tstamp_config;

View file

@ -989,7 +989,12 @@ static void mlx5e_xfrm_update_stats(struct xfrm_state *x)
struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
struct mlx5e_ipsec_rule *ipsec_rule = &sa_entry->ipsec_rule;
struct net *net = dev_net(x->xso.dev);
u64 trailer_packets = 0, trailer_bytes = 0;
u64 replay_packets = 0, replay_bytes = 0;
u64 auth_packets = 0, auth_bytes = 0;
u64 success_packets, success_bytes;
u64 packets, bytes, lastuse;
size_t headers;
lockdep_assert(lockdep_is_held(&x->lock) ||
lockdep_is_held(&dev_net(x->xso.real_dev)->xfrm.xfrm_cfg_mutex) ||
@ -999,26 +1004,43 @@ static void mlx5e_xfrm_update_stats(struct xfrm_state *x)
return;
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
mlx5_fc_query_cached(ipsec_rule->auth.fc, &bytes, &packets, &lastuse);
x->stats.integrity_failed += packets;
XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR, packets);
mlx5_fc_query_cached(ipsec_rule->auth.fc, &auth_bytes,
&auth_packets, &lastuse);
x->stats.integrity_failed += auth_packets;
XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR, auth_packets);
mlx5_fc_query_cached(ipsec_rule->trailer.fc, &bytes, &packets, &lastuse);
XFRM_ADD_STATS(net, LINUX_MIB_XFRMINHDRERROR, packets);
mlx5_fc_query_cached(ipsec_rule->trailer.fc, &trailer_bytes,
&trailer_packets, &lastuse);
XFRM_ADD_STATS(net, LINUX_MIB_XFRMINHDRERROR, trailer_packets);
}
if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET)
return;
mlx5_fc_query_cached(ipsec_rule->fc, &bytes, &packets, &lastuse);
x->curlft.packets += packets;
x->curlft.bytes += bytes;
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
mlx5_fc_query_cached(ipsec_rule->replay.fc, &bytes, &packets, &lastuse);
x->stats.replay += packets;
XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR, packets);
mlx5_fc_query_cached(ipsec_rule->replay.fc, &replay_bytes,
&replay_packets, &lastuse);
x->stats.replay += replay_packets;
XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR, replay_packets);
}
mlx5_fc_query_cached(ipsec_rule->fc, &bytes, &packets, &lastuse);
success_packets = packets - auth_packets - trailer_packets - replay_packets;
x->curlft.packets += success_packets;
/* NIC counts all bytes passed through flow steering and doesn't have
* an ability to count payload data size which is needed for SA.
*
* To overcome HW limitestion, let's approximate the payload size
* by removing always available headers.
*/
headers = sizeof(struct ethhdr);
if (sa_entry->attrs.family == AF_INET)
headers += sizeof(struct iphdr);
else
headers += sizeof(struct ipv6hdr);
success_bytes = bytes - auth_bytes - trailer_bytes - replay_bytes;
x->curlft.bytes += success_bytes - headers * success_packets;
}
static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev,

View file

@ -5868,6 +5868,11 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv)
kfree(priv->htb_qos_sq_stats[i]);
kvfree(priv->htb_qos_sq_stats);
if (priv->mqprio_rl) {
mlx5e_mqprio_rl_cleanup(priv->mqprio_rl);
mlx5e_mqprio_rl_free(priv->mqprio_rl);
}
memset(priv, 0, sizeof(*priv));
}

View file

@ -1197,9 +1197,7 @@ static int get_num_eqs(struct mlx5_core_dev *dev)
if (!mlx5_core_is_eth_enabled(dev) && mlx5_eth_supported(dev))
return 1;
max_dev_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ?
MLX5_CAP_GEN(dev, max_num_eqs) :
1 << MLX5_CAP_GEN(dev, log_max_eq);
max_dev_eqs = mlx5_max_eq_cap_get(dev);
num_eqs = min_t(int, mlx5_irq_table_get_num_comp(eq_table->irq_table),
max_dev_eqs - MLX5_MAX_ASYNC_EQS);

View file

@ -6,6 +6,9 @@
#include "helper.h"
#include "ofld.h"
static int
acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport);
static bool
esw_acl_ingress_prio_tag_enabled(struct mlx5_eswitch *esw,
const struct mlx5_vport *vport)
@ -123,18 +126,31 @@ static int esw_acl_ingress_src_port_drop_create(struct mlx5_eswitch *esw,
{
struct mlx5_flow_act flow_act = {};
struct mlx5_flow_handle *flow_rule;
bool created = false;
int err = 0;
if (!vport->ingress.acl) {
err = acl_ingress_ofld_setup(esw, vport);
if (err)
return err;
created = true;
}
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
flow_act.fg = vport->ingress.offloads.drop_grp;
flow_rule = mlx5_add_flow_rules(vport->ingress.acl, NULL, &flow_act, NULL, 0);
if (IS_ERR(flow_rule)) {
err = PTR_ERR(flow_rule);
goto out;
goto err_out;
}
vport->ingress.offloads.drop_rule = flow_rule;
out:
return 0;
err_out:
/* Only destroy ingress acl created in this function. */
if (created)
esw_acl_ingress_ofld_cleanup(esw, vport);
return err;
}
@ -299,16 +315,12 @@ static void esw_acl_ingress_ofld_groups_destroy(struct mlx5_vport *vport)
}
}
int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw,
struct mlx5_vport *vport)
static int
acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
{
int num_ftes = 0;
int err;
if (!mlx5_eswitch_vport_match_metadata_enabled(esw) &&
!esw_acl_ingress_prio_tag_enabled(esw, vport))
return 0;
esw_acl_ingress_allow_rule_destroy(vport);
if (mlx5_eswitch_vport_match_metadata_enabled(esw))
@ -347,6 +359,15 @@ int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw,
return err;
}
int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
{
if (!mlx5_eswitch_vport_match_metadata_enabled(esw) &&
!esw_acl_ingress_prio_tag_enabled(esw, vport))
return 0;
return acl_ingress_ofld_setup(esw, vport);
}
void esw_acl_ingress_ofld_cleanup(struct mlx5_eswitch *esw,
struct mlx5_vport *vport)
{

View file

@ -4600,20 +4600,26 @@ mlx5_devlink_port_fn_max_io_eqs_get(struct devlink_port *port, u32 *max_io_eqs,
return -EOPNOTSUPP;
}
if (!MLX5_CAP_GEN_2(esw->dev, max_num_eqs_24b)) {
NL_SET_ERR_MSG_MOD(extack,
"Device doesn't support getting the max number of EQs");
return -EOPNOTSUPP;
}
query_ctx = kzalloc(query_out_sz, GFP_KERNEL);
if (!query_ctx)
return -ENOMEM;
mutex_lock(&esw->state_lock);
err = mlx5_vport_get_other_func_cap(esw->dev, vport_num, query_ctx,
MLX5_CAP_GENERAL);
MLX5_CAP_GENERAL_2);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Failed getting HCA caps");
goto out;
}
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
max_eqs = MLX5_GET(cmd_hca_cap, hca_caps, max_num_eqs);
max_eqs = MLX5_GET(cmd_hca_cap_2, hca_caps, max_num_eqs_24b);
if (max_eqs < MLX5_ESW_MAX_CTRL_EQS)
*max_io_eqs = 0;
else
@ -4644,6 +4650,12 @@ mlx5_devlink_port_fn_max_io_eqs_set(struct devlink_port *port, u32 max_io_eqs,
return -EOPNOTSUPP;
}
if (!MLX5_CAP_GEN_2(esw->dev, max_num_eqs_24b)) {
NL_SET_ERR_MSG_MOD(extack,
"Device doesn't support changing the max number of EQs");
return -EOPNOTSUPP;
}
if (check_add_overflow(max_io_eqs, MLX5_ESW_MAX_CTRL_EQS, &max_eqs)) {
NL_SET_ERR_MSG_MOD(extack, "Supplied value out of range");
return -EINVAL;
@ -4655,17 +4667,17 @@ mlx5_devlink_port_fn_max_io_eqs_set(struct devlink_port *port, u32 max_io_eqs,
mutex_lock(&esw->state_lock);
err = mlx5_vport_get_other_func_cap(esw->dev, vport_num, query_ctx,
MLX5_CAP_GENERAL);
MLX5_CAP_GENERAL_2);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Failed getting HCA caps");
goto out;
}
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
MLX5_SET(cmd_hca_cap, hca_caps, max_num_eqs, max_eqs);
MLX5_SET(cmd_hca_cap_2, hca_caps, max_num_eqs_24b, max_eqs);
err = mlx5_vport_set_other_func_cap(esw->dev, hca_caps, vport_num,
MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE);
MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE2);
if (err)
NL_SET_ERR_MSG_MOD(extack, "Failed setting HCA caps");

View file

@ -383,4 +383,14 @@ static inline int mlx5_vport_to_func_id(const struct mlx5_core_dev *dev, u16 vpo
: vport;
}
static inline int mlx5_max_eq_cap_get(const struct mlx5_core_dev *dev)
{
if (MLX5_CAP_GEN_2(dev, max_num_eqs_24b))
return MLX5_CAP_GEN_2(dev, max_num_eqs_24b);
if (MLX5_CAP_GEN(dev, max_num_eqs))
return MLX5_CAP_GEN(dev, max_num_eqs);
return 1 << MLX5_CAP_GEN(dev, log_max_eq);
}
#endif /* __MLX5_CORE_H__ */

View file

@ -711,9 +711,7 @@ int mlx5_irq_table_get_num_comp(struct mlx5_irq_table *table)
int mlx5_irq_table_create(struct mlx5_core_dev *dev)
{
int num_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ?
MLX5_CAP_GEN(dev, max_num_eqs) :
1 << MLX5_CAP_GEN(dev, log_max_eq);
int num_eqs = mlx5_max_eq_cap_get(dev);
int total_vec;
int pcif_vec;
int req_vec;

View file

@ -1484,6 +1484,7 @@ static int mlxsw_linecard_types_init(struct mlxsw_core *mlxsw_core,
vfree(types_info->data);
err_data_alloc:
kfree(types_info);
linecards->types_info = NULL;
return err;
}

View file

@ -871,13 +871,13 @@ static void rswitch_tx_free(struct net_device *ndev)
dma_rmb();
skb = gq->skbs[gq->dirty];
if (skb) {
rdev->ndev->stats.tx_packets++;
rdev->ndev->stats.tx_bytes += skb->len;
dma_unmap_single(ndev->dev.parent,
gq->unmap_addrs[gq->dirty],
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(gq->skbs[gq->dirty]);
gq->skbs[gq->dirty] = NULL;
rdev->ndev->stats.tx_packets++;
rdev->ndev->stats.tx_bytes += skb->len;
}
desc->desc.die_dt = DT_EEMPTY;
}

View file

@ -272,7 +272,7 @@ static const struct ethqos_emac_por emac_v4_0_0_por[] = {
static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
.por = emac_v4_0_0_por,
.num_por = ARRAY_SIZE(emac_v3_0_0_por),
.num_por = ARRAY_SIZE(emac_v4_0_0_por),
.rgmii_config_loopback_en = false,
.has_emac_ge_3 = true,
.link_clk_name = "phyaux",

View file

@ -7662,9 +7662,10 @@ int stmmac_dvr_probe(struct device *device,
#ifdef STMMAC_VLAN_TAG_USED
/* Both mac100 and gmac support receive VLAN tag detection */
ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX;
ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
priv->hw->hw_vlan_en = true;
if (priv->plat->has_gmac4) {
ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
priv->hw->hw_vlan_en = true;
}
if (priv->dma_cap.vlhash) {
ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
ndev->features |= NETIF_F_HW_VLAN_STAG_FILTER;

View file

@ -1959,6 +1959,7 @@ int wx_sw_init(struct wx *wx)
}
bitmap_zero(wx->state, WX_STATE_NBITS);
wx->misc_irq_domain = false;
return 0;
}

View file

@ -1686,6 +1686,7 @@ static int wx_set_interrupt_capability(struct wx *wx)
}
pdev->irq = pci_irq_vector(pdev, 0);
wx->num_q_vectors = 1;
return 0;
}
@ -1996,7 +1997,8 @@ void wx_free_irq(struct wx *wx)
int vector;
if (!(pdev->msix_enabled)) {
free_irq(pdev->irq, wx);
if (!wx->misc_irq_domain)
free_irq(pdev->irq, wx);
return;
}
@ -2011,7 +2013,7 @@ void wx_free_irq(struct wx *wx)
free_irq(entry->vector, q_vector);
}
if (wx->mac.type == wx_mac_em)
if (!wx->misc_irq_domain)
free_irq(wx->msix_entry->vector, wx);
}
EXPORT_SYMBOL(wx_free_irq);
@ -2026,6 +2028,9 @@ int wx_setup_isb_resources(struct wx *wx)
{
struct pci_dev *pdev = wx->pdev;
if (wx->isb_mem)
return 0;
wx->isb_mem = dma_alloc_coherent(&pdev->dev,
sizeof(u32) * 4,
&wx->isb_dma,
@ -2385,7 +2390,6 @@ static void wx_free_all_tx_resources(struct wx *wx)
void wx_free_resources(struct wx *wx)
{
wx_free_isb_resources(wx);
wx_free_all_rx_resources(wx);
wx_free_all_tx_resources(wx);
}

View file

@ -1058,6 +1058,7 @@ struct wx {
dma_addr_t isb_dma;
u32 *isb_mem;
u32 isb_tag[WX_ISB_MAX];
bool misc_irq_domain;
#define WX_MAX_RETA_ENTRIES 128
#define WX_RSS_INDIR_TBL_MAX 64

View file

@ -387,6 +387,7 @@ static int ngbe_open(struct net_device *netdev)
err_free_irq:
wx_free_irq(wx);
err_free_resources:
wx_free_isb_resources(wx);
wx_free_resources(wx);
return err;
}
@ -408,6 +409,7 @@ static int ngbe_close(struct net_device *netdev)
ngbe_down(wx);
wx_free_irq(wx);
wx_free_isb_resources(wx);
wx_free_resources(wx);
phylink_disconnect_phy(wx->phylink);
wx_control_hw(wx, false);

View file

@ -27,57 +27,19 @@ void txgbe_irq_enable(struct wx *wx, bool queues)
}
/**
* txgbe_intr - msi/legacy mode Interrupt Handler
* @irq: interrupt number
* @data: pointer to a network interface device structure
**/
static irqreturn_t txgbe_intr(int __always_unused irq, void *data)
{
struct wx_q_vector *q_vector;
struct wx *wx = data;
struct pci_dev *pdev;
u32 eicr;
q_vector = wx->q_vector[0];
pdev = wx->pdev;
eicr = wx_misc_isb(wx, WX_ISB_VEC0);
if (!eicr) {
/* shared interrupt alert!
* the interrupt that we masked before the ICR read.
*/
if (netif_running(wx->netdev))
txgbe_irq_enable(wx, true);
return IRQ_NONE; /* Not our interrupt */
}
wx->isb_mem[WX_ISB_VEC0] = 0;
if (!(pdev->msi_enabled))
wr32(wx, WX_PX_INTA, 1);
wx->isb_mem[WX_ISB_MISC] = 0;
/* would disable interrupts here but it is auto disabled */
napi_schedule_irqoff(&q_vector->napi);
/* re-enable link(maybe) and non-queue interrupts, no flush.
* txgbe_poll will re-enable the queue interrupts
*/
if (netif_running(wx->netdev))
txgbe_irq_enable(wx, false);
return IRQ_HANDLED;
}
/**
* txgbe_request_msix_irqs - Initialize MSI-X interrupts
* txgbe_request_queue_irqs - Initialize MSI-X queue interrupts
* @wx: board private structure
*
* Allocate MSI-X vectors and request interrupts from the kernel.
* Allocate MSI-X queue vectors and request interrupts from the kernel.
**/
static int txgbe_request_msix_irqs(struct wx *wx)
int txgbe_request_queue_irqs(struct wx *wx)
{
struct net_device *netdev = wx->netdev;
int vector, err;
if (!wx->pdev->msix_enabled)
return 0;
for (vector = 0; vector < wx->num_q_vectors; vector++) {
struct wx_q_vector *q_vector = wx->q_vector[vector];
struct msix_entry *entry = &wx->msix_q_entries[vector];
@ -110,34 +72,6 @@ static int txgbe_request_msix_irqs(struct wx *wx)
return err;
}
/**
* txgbe_request_irq - initialize interrupts
* @wx: board private structure
*
* Attempt to configure interrupts using the best available
* capabilities of the hardware and kernel.
**/
int txgbe_request_irq(struct wx *wx)
{
struct net_device *netdev = wx->netdev;
struct pci_dev *pdev = wx->pdev;
int err;
if (pdev->msix_enabled)
err = txgbe_request_msix_irqs(wx);
else if (pdev->msi_enabled)
err = request_irq(wx->pdev->irq, &txgbe_intr, 0,
netdev->name, wx);
else
err = request_irq(wx->pdev->irq, &txgbe_intr, IRQF_SHARED,
netdev->name, wx);
if (err)
wx_err(wx, "request_irq failed, Error %d\n", err);
return err;
}
static int txgbe_request_gpio_irq(struct txgbe *txgbe)
{
txgbe->gpio_irq = irq_find_mapping(txgbe->misc.domain, TXGBE_IRQ_GPIO);
@ -177,6 +111,36 @@ static const struct irq_domain_ops txgbe_misc_irq_domain_ops = {
};
static irqreturn_t txgbe_misc_irq_handle(int irq, void *data)
{
struct wx_q_vector *q_vector;
struct txgbe *txgbe = data;
struct wx *wx = txgbe->wx;
u32 eicr;
if (wx->pdev->msix_enabled)
return IRQ_WAKE_THREAD;
eicr = wx_misc_isb(wx, WX_ISB_VEC0);
if (!eicr) {
/* shared interrupt alert!
* the interrupt that we masked before the ICR read.
*/
if (netif_running(wx->netdev))
txgbe_irq_enable(wx, true);
return IRQ_NONE; /* Not our interrupt */
}
wx->isb_mem[WX_ISB_VEC0] = 0;
if (!(wx->pdev->msi_enabled))
wr32(wx, WX_PX_INTA, 1);
/* would disable interrupts here but it is auto disabled */
q_vector = wx->q_vector[0];
napi_schedule_irqoff(&q_vector->napi);
return IRQ_WAKE_THREAD;
}
static irqreturn_t txgbe_misc_irq_thread_fn(int irq, void *data)
{
struct txgbe *txgbe = data;
struct wx *wx = txgbe->wx;
@ -223,6 +187,7 @@ void txgbe_free_misc_irq(struct txgbe *txgbe)
int txgbe_setup_misc_irq(struct txgbe *txgbe)
{
unsigned long flags = IRQF_ONESHOT;
struct wx *wx = txgbe->wx;
int hwirq, err;
@ -236,14 +201,17 @@ int txgbe_setup_misc_irq(struct txgbe *txgbe)
irq_create_mapping(txgbe->misc.domain, hwirq);
txgbe->misc.chip = txgbe_irq_chip;
if (wx->pdev->msix_enabled)
if (wx->pdev->msix_enabled) {
txgbe->misc.irq = wx->msix_entry->vector;
else
} else {
txgbe->misc.irq = wx->pdev->irq;
if (!wx->pdev->msi_enabled)
flags |= IRQF_SHARED;
}
err = request_threaded_irq(txgbe->misc.irq, NULL,
txgbe_misc_irq_handle,
IRQF_ONESHOT,
err = request_threaded_irq(txgbe->misc.irq, txgbe_misc_irq_handle,
txgbe_misc_irq_thread_fn,
flags,
wx->netdev->name, txgbe);
if (err)
goto del_misc_irq;
@ -256,6 +224,8 @@ int txgbe_setup_misc_irq(struct txgbe *txgbe)
if (err)
goto free_gpio_irq;
wx->misc_irq_domain = true;
return 0;
free_gpio_irq:

View file

@ -2,6 +2,6 @@
/* Copyright (c) 2015 - 2024 Beijing WangXun Technology Co., Ltd. */
void txgbe_irq_enable(struct wx *wx, bool queues);
int txgbe_request_irq(struct wx *wx);
int txgbe_request_queue_irqs(struct wx *wx);
void txgbe_free_misc_irq(struct txgbe *txgbe);
int txgbe_setup_misc_irq(struct txgbe *txgbe);

View file

@ -294,9 +294,9 @@ static int txgbe_open(struct net_device *netdev)
wx_configure(wx);
err = txgbe_request_irq(wx);
err = txgbe_request_queue_irqs(wx);
if (err)
goto err_free_isb;
goto err_free_resources;
/* Notify the stack of the actual queue counts. */
err = netif_set_real_num_tx_queues(netdev, wx->num_tx_queues);
@ -313,8 +313,8 @@ static int txgbe_open(struct net_device *netdev)
err_free_irq:
wx_free_irq(wx);
err_free_isb:
wx_free_isb_resources(wx);
err_free_resources:
wx_free_resources(wx);
err_reset:
txgbe_reset(wx);
@ -729,6 +729,7 @@ static void txgbe_remove(struct pci_dev *pdev)
txgbe_remove_phy(txgbe);
txgbe_free_misc_irq(txgbe);
wx_free_isb_resources(wx);
pci_release_selected_regions(pdev,
pci_select_bars(pdev, IORESOURCE_MEM));

View file

@ -119,7 +119,7 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
skb->protocol = eth_type_trans(skb, ndev);
skb->ip_summed = CHECKSUM_NONE;
if (__netif_rx(skb) == NET_RX_DROP) {
if (netif_rx(skb) == NET_RX_DROP) {
ndev->stats.rx_errors++;
ndev->stats.rx_dropped++;
} else {

View file

@ -6,6 +6,9 @@
* Author: Heiner Kallweit <hkallweit1@gmail.com>
*/
#ifndef AQUANTIA_H
#define AQUANTIA_H
#include <linux/device.h>
#include <linux/phy.h>
@ -120,3 +123,5 @@ static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
#endif
int aqr_firmware_load(struct phy_device *phydev);
#endif /* AQUANTIA_H */

View file

@ -654,7 +654,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
hw->wiphy->features |= NL80211_FEATURE_WFA_TPC_IE_IN_PROBES;
if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_KEK_KCK_MATERIAL,
IWL_FW_CMD_VER_UNKNOWN) == 3)
IWL_FW_CMD_VER_UNKNOWN) >= 3)
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK;
if (fw_has_api(&mvm->fw->ucode_capa,
@ -1656,7 +1656,8 @@ static void iwl_mvm_prevent_esr_done_wk(struct wiphy *wiphy,
struct iwl_mvm_vif *mvmvif =
container_of(wk, struct iwl_mvm_vif, prevent_esr_done_wk.work);
struct iwl_mvm *mvm = mvmvif->mvm;
struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm);
struct ieee80211_vif *vif =
container_of((void *)mvmvif, struct ieee80211_vif, drv_priv);
mutex_lock(&mvm->mutex);
iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_PREVENTION);
@ -1682,7 +1683,8 @@ static void iwl_mvm_unblock_esr_tpt(struct wiphy *wiphy, struct wiphy_work *wk)
struct iwl_mvm_vif *mvmvif =
container_of(wk, struct iwl_mvm_vif, unblock_esr_tpt_wk);
struct iwl_mvm *mvm = mvmvif->mvm;
struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm);
struct ieee80211_vif *vif =
container_of((void *)mvmvif, struct ieee80211_vif, drv_priv);
mutex_lock(&mvm->mutex);
iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_TPT);
@ -6410,11 +6412,9 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
if (sync) {
lockdep_assert_held(&mvm->mutex);
ret = wait_event_timeout(mvm->rx_sync_waitq,
READ_ONCE(mvm->queue_sync_state) == 0 ||
iwl_mvm_is_radio_hw_killed(mvm),
READ_ONCE(mvm->queue_sync_state) == 0,
SYNC_RX_QUEUE_TIMEOUT);
WARN_ONCE(!ret && !iwl_mvm_is_radio_hw_killed(mvm),
"queue sync: failed to sync, state is 0x%lx, cookie %d\n",
WARN_ONCE(!ret, "queue sync: failed to sync, state is 0x%lx, cookie %d\n",
mvm->queue_sync_state,
mvm->queue_sync_cookie);
}

View file

@ -153,7 +153,7 @@ static void iwl_mvm_rx_esr_mode_notif(struct iwl_mvm *mvm,
struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm);
/* FW recommendations is only for entering EMLSR */
if (!vif || iwl_mvm_vif_from_mac80211(vif)->esr_active)
if (IS_ERR_OR_NULL(vif) || iwl_mvm_vif_from_mac80211(vif)->esr_active)
return;
if (le32_to_cpu(notif->action) == ESR_RECOMMEND_ENTER)
@ -1912,12 +1912,10 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
bool rfkill_safe_init_done = READ_ONCE(mvm->rfkill_safe_init_done);
bool unified = iwl_mvm_has_unified_ucode(mvm);
if (state) {
if (state)
set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
wake_up(&mvm->rx_sync_waitq);
} else {
else
clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
}
iwl_mvm_set_rfkill_state(mvm);

View file

@ -557,12 +557,10 @@ struct iwl_mvm_stat_data_all_macs {
};
static void iwl_mvm_update_link_sig(struct ieee80211_vif *vif, int sig,
struct iwl_mvm_vif_link_info *link_info)
struct iwl_mvm_vif_link_info *link_info,
struct ieee80211_bss_conf *bss_conf)
{
struct iwl_mvm *mvm = iwl_mvm_vif_from_mac80211(vif)->mvm;
struct ieee80211_bss_conf *bss_conf =
iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, link_info->fw_link_id,
false);
int thold = bss_conf->cqm_rssi_thold;
int hyst = bss_conf->cqm_rssi_hyst;
int last_event;
@ -670,7 +668,7 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
mvmvif->deflink.beacon_stats.num_beacons;
/* This is used in pre-MLO API so use deflink */
iwl_mvm_update_link_sig(vif, sig, &mvmvif->deflink);
iwl_mvm_update_link_sig(vif, sig, &mvmvif->deflink, &vif->bss_conf);
}
static void iwl_mvm_stat_iterator_all_macs(void *_data, u8 *mac,
@ -705,7 +703,7 @@ static void iwl_mvm_stat_iterator_all_macs(void *_data, u8 *mac,
sig = -le32_to_cpu(mac_stats->beacon_filter_average_energy);
/* This is used in pre-MLO API so use deflink */
iwl_mvm_update_link_sig(vif, sig, &mvmvif->deflink);
iwl_mvm_update_link_sig(vif, sig, &mvmvif->deflink, &vif->bss_conf);
}
static inline void
@ -921,7 +919,8 @@ iwl_mvm_stat_iterator_all_links(struct iwl_mvm *mvm,
mvmvif->link[link_id]->beacon_stats.num_beacons;
sig = -le32_to_cpu(link_stats->beacon_filter_average_energy);
iwl_mvm_update_link_sig(bss_conf->vif, sig, link_info);
iwl_mvm_update_link_sig(bss_conf->vif, sig, link_info,
bss_conf);
if (WARN_ONCE(mvmvif->id >= MAC_INDEX_AUX,
"invalid mvmvif id: %d", mvmvif->id))
@ -967,7 +966,7 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
lockdep_assert_held(&mvm->mutex);
if (!bss_vif)
if (IS_ERR_OR_NULL(bss_vif))
return;
mvmvif = iwl_mvm_vif_from_mac80211(bss_vif);

View file

@ -382,7 +382,8 @@ wilc_parse_join_bss_param(struct cfg80211_bss *bss,
struct ieee80211_p2p_noa_attr noa_attr;
const struct cfg80211_bss_ies *ies;
struct wilc_join_bss_param *param;
u8 rates_len = 0, ies_len;
u8 rates_len = 0;
int ies_len;
int ret;
param = kzalloc(sizeof(*param), GFP_KERNEL);

View file

@ -1566,13 +1566,6 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates,
wlvif->band));
if (!cmd->supported_rates) {
wl1271_debug(DEBUG_CMD,
"peer has no supported rates yet, configuring basic rates: 0x%x",
wlvif->basic_rate_set);
cmd->supported_rates = cpu_to_le32(wlvif->basic_rate_set);
}
wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x",
cmd->supported_rates, sta->uapsd_queues);

View file

@ -5139,19 +5139,23 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
/* Add station (AP mode) */
if (is_ap &&
old_state == IEEE80211_STA_NOTEXIST &&
new_state == IEEE80211_STA_NONE) {
old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_ASSOC) {
ret = wl12xx_sta_add(wl, wlvif, sta);
if (ret)
return ret;
wl_sta->fw_added = true;
wlcore_update_inconn_sta(wl, wlvif, wl_sta, true);
}
/* Remove station (AP mode) */
if (is_ap &&
old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_NOTEXIST) {
old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTH) {
wl_sta->fw_added = false;
/* must not fail */
wl12xx_sta_remove(wl, wlvif, sta);
@ -5165,11 +5169,6 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
if (ret < 0)
return ret;
/* reconfigure rates */
ret = wl12xx_cmd_add_peer(wl, wlvif, sta, wl_sta->hlid);
if (ret < 0)
return ret;
ret = wl1271_acx_set_ht_capabilities(wl, &sta->deflink.ht_cap,
true,
wl_sta->hlid);

View file

@ -140,11 +140,8 @@ EXPORT_SYMBOL(wl12xx_is_dummy_packet);
static u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct sk_buff *skb, struct ieee80211_sta *sta)
{
if (sta) {
struct wl1271_station *wl_sta;
wl_sta = (struct wl1271_station *)sta->drv_priv;
return wl_sta->hlid;
if (sta && wl1271_station(sta)->fw_added) {
return wl1271_station(sta)->hlid;
} else {
struct ieee80211_hdr *hdr;

View file

@ -324,6 +324,7 @@ struct wl12xx_rx_filter {
struct wl1271_station {
u8 hlid;
bool fw_added;
bool in_connection;
/*
@ -335,6 +336,11 @@ struct wl1271_station {
u64 total_freed_pkts;
};
static inline struct wl1271_station *wl1271_station(struct ieee80211_sta *sta)
{
return (struct wl1271_station *)sta->drv_priv;
}
struct wl12xx_vif {
struct wl1271 *wl;
struct list_head list;

View file

@ -2029,7 +2029,11 @@ struct mlx5_ifc_cmd_hca_cap_2_bits {
u8 pcc_ifa2[0x1];
u8 reserved_at_3f1[0xf];
u8 reserved_at_400[0x400];
u8 reserved_at_400[0x40];
u8 reserved_at_440[0x8];
u8 max_num_eqs_24b[0x18];
u8 reserved_at_460[0x3a0];
};
enum mlx5_ifc_flow_destination_type {

View file

@ -1122,7 +1122,7 @@ struct phy_driver {
u8 index, enum led_brightness value);
/**
* @led_blink_set: Set a PHY LED brightness. Index indicates
* @led_blink_set: Set a PHY LED blinking. Index indicates
* which of the PHYs led should be configured to blink. Delays
* are in milliseconds and if both are zero then a sensible
* default should be chosen. The call should adjust the

View file

@ -324,6 +324,17 @@ enum {
* claim to support it.
*/
HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE,
/*
* When this quirk is set, the reserved bits of Primary/Secondary_PHY
* inside the LE Extended Advertising Report events are discarded.
* This is required for some Apple/Broadcom controllers which
* abuse these reserved bits for unrelated flags.
*
* This quirk can be set before hci_register_dev is called or
* during the hdev->setup vendor callback.
*/
HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY,
};
/* HCI device flags */

View file

@ -38,6 +38,8 @@ int __hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
const void *param, u8 event, u32 timeout,
struct sock *sk);
int hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
const void *param, u32 timeout);
void hci_cmd_sync_init(struct hci_dev *hdev);
void hci_cmd_sync_clear(struct hci_dev *hdev);

View file

@ -395,7 +395,7 @@ enum ieee80211_bss_change {
BSS_CHANGED_HE_OBSS_PD = 1<<28,
BSS_CHANGED_HE_BSS_COLOR = 1<<29,
BSS_CHANGED_FILS_DISCOVERY = 1<<30,
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = 1<<31,
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = BIT_ULL(31),
BSS_CHANGED_MLD_VALID_LINKS = BIT_ULL(33),
BSS_CHANGED_MLD_TTLM = BIT_ULL(34),

View file

@ -899,8 +899,8 @@ static int hci_conn_hash_alloc_unset(struct hci_dev *hdev)
U16_MAX, GFP_ATOMIC);
}
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
u8 role, u16 handle)
static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
u8 role, u16 handle)
{
struct hci_conn *conn;
@ -1041,7 +1041,16 @@ struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
if (unlikely(handle < 0))
return ERR_PTR(-ECONNREFUSED);
return hci_conn_add(hdev, type, dst, role, handle);
return __hci_conn_add(hdev, type, dst, role, handle);
}
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
u8 role, u16 handle)
{
if (handle > HCI_CONN_HANDLE_MAX)
return ERR_PTR(-EINVAL);
return __hci_conn_add(hdev, type, dst, role, handle);
}
static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)

View file

@ -63,50 +63,6 @@ DEFINE_MUTEX(hci_cb_list_lock);
/* HCI ID Numbering */
static DEFINE_IDA(hci_index_ida);
static int hci_scan_req(struct hci_request *req, unsigned long opt)
{
__u8 scan = opt;
BT_DBG("%s %x", req->hdev->name, scan);
/* Inquiry and Page scans */
hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
return 0;
}
static int hci_auth_req(struct hci_request *req, unsigned long opt)
{
__u8 auth = opt;
BT_DBG("%s %x", req->hdev->name, auth);
/* Authentication */
hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
return 0;
}
static int hci_encrypt_req(struct hci_request *req, unsigned long opt)
{
__u8 encrypt = opt;
BT_DBG("%s %x", req->hdev->name, encrypt);
/* Encryption */
hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
return 0;
}
static int hci_linkpol_req(struct hci_request *req, unsigned long opt)
{
__le16 policy = cpu_to_le16(opt);
BT_DBG("%s %x", req->hdev->name, policy);
/* Default link policy */
hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
return 0;
}
/* Get HCI device by index.
* Device is held on return. */
struct hci_dev *hci_dev_get(int index)
@ -735,6 +691,7 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
{
struct hci_dev *hdev;
struct hci_dev_req dr;
__le16 policy;
int err = 0;
if (copy_from_user(&dr, arg, sizeof(dr)))
@ -761,8 +718,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
switch (cmd) {
case HCISETAUTH:
err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
HCI_INIT_TIMEOUT, NULL);
err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_AUTH_ENABLE,
1, &dr.dev_opt, HCI_CMD_TIMEOUT);
break;
case HCISETENCRYPT:
@ -773,19 +730,23 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
if (!test_bit(HCI_AUTH, &hdev->flags)) {
/* Auth must be enabled first */
err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
HCI_INIT_TIMEOUT, NULL);
err = __hci_cmd_sync_status(hdev,
HCI_OP_WRITE_AUTH_ENABLE,
1, &dr.dev_opt,
HCI_CMD_TIMEOUT);
if (err)
break;
}
err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
HCI_INIT_TIMEOUT, NULL);
err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_ENCRYPT_MODE,
1, &dr.dev_opt,
HCI_CMD_TIMEOUT);
break;
case HCISETSCAN:
err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
HCI_INIT_TIMEOUT, NULL);
err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_SCAN_ENABLE,
1, &dr.dev_opt,
HCI_CMD_TIMEOUT);
/* Ensure that the connectable and discoverable states
* get correctly modified as this was a non-mgmt change.
@ -795,8 +756,11 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
break;
case HCISETLINKPOL:
err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
HCI_INIT_TIMEOUT, NULL);
policy = cpu_to_le16(dr.dev_opt);
err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
2, &policy,
HCI_CMD_TIMEOUT);
break;
case HCISETLINKMODE:
@ -2751,7 +2715,11 @@ void hci_unregister_dev(struct hci_dev *hdev)
list_del(&hdev->list);
write_unlock(&hci_dev_list_lock);
cancel_work_sync(&hdev->rx_work);
cancel_work_sync(&hdev->cmd_work);
cancel_work_sync(&hdev->tx_work);
cancel_work_sync(&hdev->power_on);
cancel_work_sync(&hdev->error_reset);
hci_cmd_sync_clear(hdev);

View file

@ -6311,6 +6311,13 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK;
legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
if (test_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY,
&hdev->quirks)) {
info->primary_phy &= 0x1f;
info->secondary_phy &= 0x1f;
}
if (legacy_evt_type != LE_ADV_INVALID) {
process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
info->bdaddr_type, NULL, 0,
@ -6660,6 +6667,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
struct bt_iso_qos *qos;
bool pending = false;
u16 handle = __le16_to_cpu(ev->handle);
u32 c_sdu_interval, p_sdu_interval;
bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
@ -6684,12 +6692,25 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
pending = test_and_clear_bit(HCI_CONN_CREATE_CIS, &conn->flags);
/* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */
qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250;
qos->ucast.out.interval = qos->ucast.in.interval;
/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 6, Part G
* page 3075:
* Transport_Latency_C_To_P = CIG_Sync_Delay + (FT_C_To_P) ×
* ISO_Interval + SDU_Interval_C_To_P
* ...
* SDU_Interval = (CIG_Sync_Delay + (FT) x ISO_Interval) -
* Transport_Latency
*/
c_sdu_interval = (get_unaligned_le24(ev->cig_sync_delay) +
(ev->c_ft * le16_to_cpu(ev->interval) * 1250)) -
get_unaligned_le24(ev->c_latency);
p_sdu_interval = (get_unaligned_le24(ev->cig_sync_delay) +
(ev->p_ft * le16_to_cpu(ev->interval) * 1250)) -
get_unaligned_le24(ev->p_latency);
switch (conn->role) {
case HCI_ROLE_SLAVE:
qos->ucast.in.interval = c_sdu_interval;
qos->ucast.out.interval = p_sdu_interval;
/* Convert Transport Latency (us) to Latency (msec) */
qos->ucast.in.latency =
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
@ -6703,6 +6724,8 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
qos->ucast.out.phy = ev->p_phy;
break;
case HCI_ROLE_MASTER:
qos->ucast.in.interval = p_sdu_interval;
qos->ucast.out.interval = c_sdu_interval;
/* Convert Transport Latency (us) to Latency (msec) */
qos->ucast.out.latency =
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
@ -6893,6 +6916,10 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
bis = hci_conn_hash_lookup_handle(hdev, handle);
if (!bis) {
if (handle > HCI_CONN_HANDLE_MAX) {
bt_dev_dbg(hdev, "ignore too large handle %u", handle);
continue;
}
bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY,
HCI_ROLE_SLAVE, handle);
if (IS_ERR(bis))

View file

@ -280,6 +280,19 @@ int __hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
}
EXPORT_SYMBOL(__hci_cmd_sync_status);
int hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
const void *param, u32 timeout)
{
int err;
hci_req_sync_lock(hdev);
err = __hci_cmd_sync_status(hdev, opcode, plen, param, timeout);
hci_req_sync_unlock(hdev);
return err;
}
EXPORT_SYMBOL(hci_cmd_sync_status);
static void hci_cmd_sync_work(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_sync_work);

View file

@ -1356,8 +1356,7 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
lock_sock(sk);
switch (sk->sk_state) {
case BT_CONNECT2:
if (pi->conn->hcon &&
test_bit(HCI_CONN_PA_SYNC, &pi->conn->hcon->flags)) {
if (test_bit(BT_SK_PA_SYNC, &pi->flags)) {
iso_conn_big_sync(sk);
sk->sk_state = BT_LISTEN;
} else {

View file

@ -6761,6 +6761,8 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
BT_DBG("chan %p, len %d", chan, skb->len);
l2cap_chan_lock(chan);
if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
goto drop;
@ -6777,6 +6779,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
}
drop:
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
free_skb:
kfree_skb(skb);

View file

@ -1239,6 +1239,10 @@ static void l2cap_sock_kill(struct sock *sk)
BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));
/* Sock is dead, so set chan data to NULL, avoid other task use invalid
* sock pointer.
*/
l2cap_pi(sk)->chan->data = NULL;
/* Kill poor orphan */
l2cap_chan_put(l2cap_pi(sk)->chan);
@ -1481,12 +1485,16 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
{
struct sock *sk = chan->data;
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sock *sk;
struct l2cap_pinfo *pi;
int err;
lock_sock(sk);
sk = chan->data;
if (!sk)
return -ENXIO;
pi = l2cap_pi(sk);
lock_sock(sk);
if (chan->mode == L2CAP_MODE_ERTM && !list_empty(&pi->rx_busy)) {
err = -ENOMEM;
goto done;

View file

@ -416,15 +416,22 @@ static int __skb_datagram_iter(const struct sk_buff *skb, int offset,
end = start + skb_frag_size(frag);
if ((copy = end - offset) > 0) {
struct page *page = skb_frag_page(frag);
u8 *vaddr = kmap(page);
u32 p_off, p_len, copied;
struct page *p;
u8 *vaddr;
if (copy > len)
copy = len;
n = INDIRECT_CALL_1(cb, simple_copy_to_iter,
vaddr + skb_frag_off(frag) + offset - start,
copy, data, to);
kunmap(page);
skb_frag_foreach_page(frag,
skb_frag_off(frag) + offset - start,
copy, p, p_off, p_len, copied) {
vaddr = kmap_local_page(p);
n = INDIRECT_CALL_1(cb, simple_copy_to_iter,
vaddr + p_off, p_len, data, to);
kunmap_local(vaddr);
}
offset += n;
if (n != copy)
goto short_copy;

View file

@ -1383,6 +1383,7 @@ static int inet_diag_dump_compat(struct sk_buff *skb,
req.sdiag_family = AF_UNSPEC; /* compatibility */
req.sdiag_protocol = inet_diag_type2proto(cb->nlh->nlmsg_type);
req.idiag_ext = rc->idiag_ext;
req.pad = 0;
req.idiag_states = rc->idiag_states;
req.id = rc->id;
@ -1398,6 +1399,7 @@ static int inet_diag_get_exact_compat(struct sk_buff *in_skb,
req.sdiag_family = rc->idiag_family;
req.sdiag_protocol = inet_diag_type2proto(nlh->nlmsg_type);
req.idiag_ext = rc->idiag_ext;
req.pad = 0;
req.idiag_states = rc->idiag_states;
req.id = rc->id;

View file

@ -3077,7 +3077,7 @@ static void tcp_fastretrans_alert(struct sock *sk, const u32 prior_snd_una,
return;
if (tcp_try_undo_dsack(sk))
tcp_try_keep_open(sk);
tcp_try_to_open(sk, flag);
tcp_identify_packet_loss(sk, ack_flag);
if (icsk->icsk_ca_state != TCP_CA_Recovery) {
@ -4223,6 +4223,13 @@ void tcp_parse_options(const struct net *net,
* checked (see tcp_v{4,6}_rcv()).
*/
break;
#endif
#ifdef CONFIG_TCP_AO
case TCPOPT_AO:
/* TCP AO has already been checked
* (see tcp_inbound_ao_hash()).
*/
break;
#endif
case TCPOPT_FASTOPEN:
tcp_parse_fastopen_option(

View file

@ -619,6 +619,7 @@ static const struct nla_policy tcp_metrics_nl_policy[TCP_METRICS_ATTR_MAX + 1] =
[TCP_METRICS_ATTR_ADDR_IPV4] = { .type = NLA_U32, },
[TCP_METRICS_ATTR_ADDR_IPV6] = { .type = NLA_BINARY,
.len = sizeof(struct in6_addr), },
[TCP_METRICS_ATTR_SADDR_IPV4] = { .type = NLA_U32, },
/* Following attributes are not received for GET/DEL,
* we keep them for reference
*/

View file

@ -423,6 +423,7 @@ u64 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
BSS_CHANGED_ERP_SLOT;
}
/* context: requires softirqs disabled */
void ieee80211_handle_queued_frames(struct ieee80211_local *local)
{
struct sk_buff *skb;

View file

@ -1567,7 +1567,9 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
void ieee80211_stop_device(struct ieee80211_local *local)
{
local_bh_disable();
ieee80211_handle_queued_frames(local);
local_bh_enable();
ieee80211_led_radio(local, false);
ieee80211_mod_tpt_led_trig(local, 0, IEEE80211_TPT_LEDTRIG_FL_RADIO);

View file

@ -161,8 +161,10 @@ void ieee802154_configure_durations(struct wpan_phy *phy,
}
phy->symbol_duration = duration;
phy->lifs_period = (IEEE802154_LIFS_PERIOD * phy->symbol_duration) / NSEC_PER_SEC;
phy->sifs_period = (IEEE802154_SIFS_PERIOD * phy->symbol_duration) / NSEC_PER_SEC;
phy->lifs_period =
(IEEE802154_LIFS_PERIOD * phy->symbol_duration) / NSEC_PER_USEC;
phy->sifs_period =
(IEEE802154_SIFS_PERIOD * phy->symbol_duration) / NSEC_PER_USEC;
}
EXPORT_SYMBOL(ieee802154_configure_durations);
@ -184,10 +186,10 @@ static void ieee802154_setup_wpan_phy_pib(struct wpan_phy *wpan_phy)
* Should be done when all drivers sets this value.
*/
wpan_phy->lifs_period =
(IEEE802154_LIFS_PERIOD * wpan_phy->symbol_duration) / 1000;
wpan_phy->sifs_period =
(IEEE802154_SIFS_PERIOD * wpan_phy->symbol_duration) / 1000;
wpan_phy->lifs_period = (IEEE802154_LIFS_PERIOD *
wpan_phy->symbol_duration) / NSEC_PER_USEC;
wpan_phy->sifs_period = (IEEE802154_SIFS_PERIOD *
wpan_phy->symbol_duration) / NSEC_PER_USEC;
}
int ieee802154_register_hw(struct ieee802154_hw *hw)

View file

@ -34,8 +34,8 @@ void ieee802154_xmit_sync_worker(struct work_struct *work)
if (res)
goto err_tx;
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
DEV_STATS_INC(dev, tx_packets);
DEV_STATS_ADD(dev, tx_bytes, skb->len);
ieee802154_xmit_complete(&local->hw, skb, false);
@ -90,8 +90,8 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
if (ret)
goto err_wake_netif_queue;
dev->stats.tx_packets++;
dev->stats.tx_bytes += len;
DEV_STATS_INC(dev, tx_packets);
DEV_STATS_ADD(dev, tx_bytes, len);
} else {
local->tx_skb = skb;
queue_work(local->workqueue, &local->sync_tx_work);

View file

@ -11483,8 +11483,7 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
gc_seq = nft_gc_seq_begin(nft_net);
if (!list_empty(&nf_tables_destroy_list))
nf_tables_trans_destroy_flush_work();
nf_tables_trans_destroy_flush_work();
again:
list_for_each_entry(table, &nft_net->tables, list) {
if (nft_table_has_owner(table) &&

View file

@ -476,6 +476,7 @@ static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_inde
}
if (vertex->index == vertex->scc_index) {
struct unix_vertex *v;
struct list_head scc;
bool scc_dead = true;
@ -486,15 +487,15 @@ static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_inde
*/
__list_cut_position(&scc, &vertex_stack, &vertex->scc_entry);
list_for_each_entry_reverse(vertex, &scc, scc_entry) {
list_for_each_entry_reverse(v, &scc, scc_entry) {
/* Don't restart DFS from this vertex in unix_walk_scc(). */
list_move_tail(&vertex->entry, &unix_visited_vertices);
list_move_tail(&v->entry, &unix_visited_vertices);
/* Mark vertex as off-stack. */
vertex->index = unix_vertex_grouped_index;
v->index = unix_vertex_grouped_index;
if (scc_dead)
scc_dead = unix_vertex_dead(vertex);
scc_dead = unix_vertex_dead(v);
}
if (scc_dead)

View file

@ -468,6 +468,10 @@ static const struct netlink_range_validation nl80211_punct_bitmap_range = {
.max = 0xffff,
};
static const struct netlink_range_validation q_range = {
.max = INT_MAX,
};
static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
@ -754,7 +758,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
[NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
[NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
[NL80211_ATTR_TXQ_QUANTUM] = NLA_POLICY_FULL_RANGE(NLA_U32, &q_range),
[NL80211_ATTR_HE_CAPABILITY] =
NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_he_capa,
NL80211_HE_MAX_CAPABILITY_LEN),

View file

@ -14,12 +14,12 @@
FIXTURE(scm_rights)
{
int fd[16];
int fd[32];
};
FIXTURE_VARIANT(scm_rights)
{
char name[16];
char name[32];
int type;
int flags;
bool test_listener;
@ -172,6 +172,8 @@ static void __create_sockets(struct __test_metadata *_metadata,
const FIXTURE_VARIANT(scm_rights) *variant,
int n)
{
ASSERT_LE(n * 2, sizeof(self->fd) / sizeof(self->fd[0]));
if (variant->test_listener)
create_listeners(_metadata, self, n);
else
@ -283,4 +285,23 @@ TEST_F(scm_rights, cross_edge)
close_sockets(8);
}
TEST_F(scm_rights, backtrack_from_scc)
{
create_sockets(10);
send_fd(0, 1);
send_fd(0, 4);
send_fd(1, 2);
send_fd(2, 3);
send_fd(3, 1);
send_fd(5, 6);
send_fd(5, 9);
send_fd(6, 7);
send_fd(7, 8);
send_fd(8, 6);
close_sockets(10);
}
TEST_HARNESS_MAIN

View file

@ -85,6 +85,7 @@ static bool cfg_rx;
static int cfg_runtime_ms = 4200;
static int cfg_verbose;
static int cfg_waittime_ms = 500;
static int cfg_notification_limit = 32;
static bool cfg_zerocopy;
static socklen_t cfg_alen;
@ -95,6 +96,7 @@ static char payload[IP_MAXPACKET];
static long packets, bytes, completions, expected_completions;
static int zerocopied = -1;
static uint32_t next_completion;
static uint32_t sends_since_notify;
static unsigned long gettimeofday_ms(void)
{
@ -208,6 +210,7 @@ static bool do_sendmsg(int fd, struct msghdr *msg, bool do_zerocopy, int domain)
error(1, errno, "send");
if (cfg_verbose && ret != len)
fprintf(stderr, "send: ret=%u != %u\n", ret, len);
sends_since_notify++;
if (len) {
packets++;
@ -435,7 +438,7 @@ static bool do_recv_completion(int fd, int domain)
/* Detect notification gaps. These should not happen often, if at all.
* Gaps can occur due to drops, reordering and retransmissions.
*/
if (lo != next_completion)
if (cfg_verbose && lo != next_completion)
fprintf(stderr, "gap: %u..%u does not append to %u\n",
lo, hi, next_completion);
next_completion = hi + 1;
@ -460,6 +463,7 @@ static bool do_recv_completion(int fd, int domain)
static void do_recv_completions(int fd, int domain)
{
while (do_recv_completion(fd, domain)) {}
sends_since_notify = 0;
}
/* Wait for all remaining completions on the errqueue */
@ -549,6 +553,9 @@ static void do_tx(int domain, int type, int protocol)
else
do_sendmsg(fd, &msg, cfg_zerocopy, domain);
if (cfg_zerocopy && sends_since_notify >= cfg_notification_limit)
do_recv_completions(fd, domain);
while (!do_poll(fd, POLLOUT)) {
if (cfg_zerocopy)
do_recv_completions(fd, domain);
@ -708,7 +715,7 @@ static void parse_opts(int argc, char **argv)
cfg_payload_len = max_payload_len;
while ((c = getopt(argc, argv, "46c:C:D:i:mp:rs:S:t:vz")) != -1) {
while ((c = getopt(argc, argv, "46c:C:D:i:l:mp:rs:S:t:vz")) != -1) {
switch (c) {
case '4':
if (cfg_family != PF_UNSPEC)
@ -736,6 +743,9 @@ static void parse_opts(int argc, char **argv)
if (cfg_ifindex == 0)
error(1, errno, "invalid iface: %s", optarg);
break;
case 'l':
cfg_notification_limit = strtoul(optarg, NULL, 0);
break;
case 'm':
cfg_cork_mixed = true;
break;