Commit ebd297a2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull networking fixes from Jakub Kicinski:
 "Happy May Day.

  Things have calmed down on our end (knock on wood), no outstanding
  investigations. Including fixes from Bluetooth and WiFi.

  Current release - fix to a fix:

   - igc: fix lock order in igc_ptp_reset

  Current release - new code bugs:

   - Revert "wifi: iwlwifi: make no_160 more generic", fixes regression
     to Killer line of devices reported by a number of people

   - Revert "wifi: iwlwifi: add support for BE213", initial FW is too
     buggy

   - number of fixes for mld, the new Intel WiFi subdriver

  Previous releases - regressions:

   - wifi: mac80211: restore monitor for outgoing frames

   - drv: vmxnet3: fix malformed packet sizing in vmxnet3_process_xdp

   - eth: bnxt_en: fix timestamping FIFO getting out of sync on reset,
     delivering stale timestamps

   - use sock_gen_put() in the TCP fraglist GRO heuristic, don't assume
     every socket is a full socket

  Previous releases - always broken:

   - sched: adapt qdiscs for reentrant enqueue cases, fix list
     corruptions

   - xsk: fix race condition in AF_XDP generic RX path, shared UMEM
     can't be protected by a per-socket lock

   - eth: mtk-star-emac: fix spinlock recursion issues on rx/tx poll

   - btusb: avoid NULL pointer dereference in skb_dequeue()

   - dsa: felix: fix broken taprio gate states after clock jump"

* tag 'net-6.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (83 commits)
  net: vertexcom: mse102x: Fix RX error handling
  net: vertexcom: mse102x: Add range check for CMD_RTS
  net: vertexcom: mse102x: Fix LEN_MASK
  net: vertexcom: mse102x: Fix possible stuck of SPI interrupt
  net: hns3: defer calling ptp_clock_register()
  net: hns3: fixed debugfs tm_qset size
  net: hns3: fix an interrupt residual problem
  net: hns3: store rx VLAN tag offload state for VF
  octeon_ep: Fix host hang issue during device reboot
  net: fec: ERR007885 Workaround for conventional TX
  net: lan743x: Fix memleak issue when GSO enabled
  ptp: ocp: Fix NULL dereference in Adva board SMA sysfs operations
  net: use sock_gen_put() when sk_state is TCP_TIME_WAIT
  bnxt_en: fix module unload sequence
  bnxt_en: Fix ethtool -d byte order for 32-bit values
  bnxt_en: Fix out-of-bound memcpy() during ethtool -w
  bnxt_en: Fix coredump logic to free allocated buffer
  bnxt_en: delay pci_alloc_irq_vectors() in the AER path
  bnxt_en: call pci_alloc_irq_vectors() after bnxt_reserve_rings()
  bnxt_en: Add missing skb_mark_for_recycle() in bnxt_rx_vlan()
  ...
parents 4f79eaa2 1daa05fd
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -89,8 +89,10 @@ definitions:
          doc: Group of short_detected states
  -
    name: phy-upstream-type
    enum-name:
    enum-name: phy-upstream
    header: linux/ethtool.h
    type: enum
    name-prefix: phy-upstream
    entries: [ mac, phy ]
  -
    name: tcp-data-split
+31 −26
Original line number Diff line number Diff line
@@ -957,9 +957,11 @@ static int btintel_pcie_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
		/* This is a debug event that comes from IML and OP image when it
		 * starts execution. There is no need pass this event to stack.
		 */
		if (skb->data[2] == 0x97)
		if (skb->data[2] == 0x97) {
			hci_recv_diag(hdev, skb);
			return 0;
		}
	}

	return hci_recv_frame(hdev, skb);
}
@@ -974,7 +976,6 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
	u8 pkt_type;
	u16 plen;
	u32 pcie_pkt_type;
	struct sk_buff *new_skb;
	void *pdata;
	struct hci_dev *hdev = data->hdev;

@@ -1051,24 +1052,20 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,

	bt_dev_dbg(hdev, "pkt_type: 0x%2.2x len: %u", pkt_type, plen);

	new_skb = bt_skb_alloc(plen, GFP_ATOMIC);
	if (!new_skb) {
		bt_dev_err(hdev, "Failed to allocate memory for skb of len: %u",
			   skb->len);
		ret = -ENOMEM;
		goto exit_error;
	}

	hci_skb_pkt_type(new_skb) = pkt_type;
	skb_put_data(new_skb, skb->data, plen);
	hci_skb_pkt_type(skb) = pkt_type;
	hdev->stat.byte_rx += plen;
	skb_trim(skb, plen);

	if (pcie_pkt_type == BTINTEL_PCIE_HCI_EVT_PKT)
		ret = btintel_pcie_recv_event(hdev, new_skb);
		ret = btintel_pcie_recv_event(hdev, skb);
	else
		ret = hci_recv_frame(hdev, new_skb);
		ret = hci_recv_frame(hdev, skb);
	skb = NULL; /* skb is freed in the callee  */

exit_error:
	if (skb)
		kfree_skb(skb);

	if (ret)
		hdev->stat.err_rx++;

@@ -1202,8 +1199,6 @@ static void btintel_pcie_rx_work(struct work_struct *work)
	struct btintel_pcie_data *data = container_of(work,
					struct btintel_pcie_data, rx_work);
	struct sk_buff *skb;
	int err;
	struct hci_dev *hdev = data->hdev;

	if (test_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags)) {
		/* Unlike usb products, controller will not send hardware
@@ -1224,11 +1219,7 @@ static void btintel_pcie_rx_work(struct work_struct *work)

	/* Process the sk_buf in queue and send to the HCI layer */
	while ((skb = skb_dequeue(&data->rx_skb_q))) {
		err = btintel_pcie_recv_frame(data, skb);
		if (err)
			bt_dev_err(hdev, "Failed to send received frame: %d",
				   err);
		kfree_skb(skb);
		btintel_pcie_recv_frame(data, skb);
	}
}

@@ -1281,10 +1272,8 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
	bt_dev_dbg(hdev, "RXQ: cr_hia: %u  cr_tia: %u", cr_hia, cr_tia);

	/* Check CR_TIA and CR_HIA for change */
	if (cr_tia == cr_hia) {
		bt_dev_warn(hdev, "RXQ: no new CD found");
	if (cr_tia == cr_hia)
		return;
	}

	rxq = &data->rxq;

@@ -1320,6 +1309,16 @@ static irqreturn_t btintel_pcie_msix_isr(int irq, void *data)
	return IRQ_WAKE_THREAD;
}

static inline bool btintel_pcie_is_rxq_empty(struct btintel_pcie_data *data)
{
	return data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM] == data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM];
}

static inline bool btintel_pcie_is_txackq_empty(struct btintel_pcie_data *data)
{
	return data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM] == data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM];
}

static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
{
	struct msix_entry *entry = dev_id;
@@ -1351,12 +1350,18 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
		btintel_pcie_msix_gp0_handler(data);

	/* For TX */
	if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0)
	if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) {
		btintel_pcie_msix_tx_handle(data);
		if (!btintel_pcie_is_rxq_empty(data))
			btintel_pcie_msix_rx_handle(data);
	}

	/* For RX */
	if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1)
	if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1) {
		btintel_pcie_msix_rx_handle(data);
		if (!btintel_pcie_is_txackq_empty(data))
			btintel_pcie_msix_tx_handle(data);
	}

	/*
	 * Before sending the interrupt the HW disables it to prevent a nested
+10 −2
Original line number Diff line number Diff line
@@ -723,6 +723,10 @@ static int btmtksdio_close(struct hci_dev *hdev)
{
	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);

	/* Skip btmtksdio_close if BTMTKSDIO_FUNC_ENABLED isn't set */
	if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
		return 0;

	sdio_claim_host(bdev->func);

	/* Disable interrupt */
@@ -1443,11 +1447,15 @@ static void btmtksdio_remove(struct sdio_func *func)
	if (!bdev)
		return;

	hdev = bdev->hdev;

	/* Make sure to call btmtksdio_close before removing sdio card */
	if (test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
		btmtksdio_close(hdev);

	/* Be consistent the state in btmtksdio_probe */
	pm_runtime_get_noresume(bdev->dev);

	hdev = bdev->hdev;

	sdio_set_drvdata(func, NULL);
	hci_unregister_dev(hdev);
	hci_free_dev(hdev);
+73 −28
Original line number Diff line number Diff line
@@ -3010,22 +3010,16 @@ static void btusb_coredump_qca(struct hci_dev *hdev)
		bt_dev_err(hdev, "%s: triggle crash failed (%d)", __func__, err);
}

/*
 * ==0: not a dump pkt.
 * < 0: fails to handle a dump pkt
 * > 0: otherwise.
 */
/* Return: 0 on success, negative errno on failure. */
static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
{
	int ret = 1;
	int ret = 0;
	u8 pkt_type;
	u8 *sk_ptr;
	unsigned int sk_len;
	u16 seqno;
	u32 dump_size;

	struct hci_event_hdr *event_hdr;
	struct hci_acl_hdr *acl_hdr;
	struct qca_dump_hdr *dump_hdr;
	struct btusb_data *btdata = hci_get_drvdata(hdev);
	struct usb_device *udev = btdata->udev;
@@ -3035,30 +3029,14 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
	sk_len = skb->len;

	if (pkt_type == HCI_ACLDATA_PKT) {
		acl_hdr = hci_acl_hdr(skb);
		if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE)
			return 0;
		sk_ptr += HCI_ACL_HDR_SIZE;
		sk_len -= HCI_ACL_HDR_SIZE;
		event_hdr = (struct hci_event_hdr *)sk_ptr;
	} else {
		event_hdr = hci_event_hdr(skb);
	}

	if ((event_hdr->evt != HCI_VENDOR_PKT)
		|| (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
		return 0;

	sk_ptr += HCI_EVENT_HDR_SIZE;
	sk_len -= HCI_EVENT_HDR_SIZE;

	dump_hdr = (struct qca_dump_hdr *)sk_ptr;
	if ((sk_len < offsetof(struct qca_dump_hdr, data))
		|| (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS)
	    || (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
		return 0;

	/*it is dump pkt now*/
	seqno = le16_to_cpu(dump_hdr->seqno);
	if (seqno == 0) {
		set_bit(BTUSB_HW_SSR_ACTIVE, &btdata->flags);
@@ -3132,17 +3110,84 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
	return ret;
}

/* Return: true if the ACL packet is a dump packet, false otherwise. */
static bool acl_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb)
{
	u8 *sk_ptr;
	unsigned int sk_len;

	struct hci_event_hdr *event_hdr;
	struct hci_acl_hdr *acl_hdr;
	struct qca_dump_hdr *dump_hdr;

	sk_ptr = skb->data;
	sk_len = skb->len;

	acl_hdr = hci_acl_hdr(skb);
	if (le16_to_cpu(acl_hdr->handle) != QCA_MEMDUMP_ACL_HANDLE)
		return false;

	sk_ptr += HCI_ACL_HDR_SIZE;
	sk_len -= HCI_ACL_HDR_SIZE;
	event_hdr = (struct hci_event_hdr *)sk_ptr;

	if ((event_hdr->evt != HCI_VENDOR_PKT) ||
	    (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
		return false;

	sk_ptr += HCI_EVENT_HDR_SIZE;
	sk_len -= HCI_EVENT_HDR_SIZE;

	dump_hdr = (struct qca_dump_hdr *)sk_ptr;
	if ((sk_len < offsetof(struct qca_dump_hdr, data)) ||
	    (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) ||
	    (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
		return false;

	return true;
}

/* Return: true if the event packet is a dump packet, false otherwise. */
static bool evt_pkt_is_dump_qca(struct hci_dev *hdev, struct sk_buff *skb)
{
	u8 *sk_ptr;
	unsigned int sk_len;

	struct hci_event_hdr *event_hdr;
	struct qca_dump_hdr *dump_hdr;

	sk_ptr = skb->data;
	sk_len = skb->len;

	event_hdr = hci_event_hdr(skb);

	if ((event_hdr->evt != HCI_VENDOR_PKT)
	    || (event_hdr->plen != (sk_len - HCI_EVENT_HDR_SIZE)))
		return false;

	sk_ptr += HCI_EVENT_HDR_SIZE;
	sk_len -= HCI_EVENT_HDR_SIZE;

	dump_hdr = (struct qca_dump_hdr *)sk_ptr;
	if ((sk_len < offsetof(struct qca_dump_hdr, data)) ||
	    (dump_hdr->vse_class != QCA_MEMDUMP_VSE_CLASS) ||
	    (dump_hdr->msg_type != QCA_MEMDUMP_MSG_TYPE))
		return false;

	return true;
}

static int btusb_recv_acl_qca(struct hci_dev *hdev, struct sk_buff *skb)
{
	if (handle_dump_pkt_qca(hdev, skb))
		return 0;
	if (acl_pkt_is_dump_qca(hdev, skb))
		return handle_dump_pkt_qca(hdev, skb);
	return hci_recv_frame(hdev, skb);
}

static int btusb_recv_evt_qca(struct hci_dev *hdev, struct sk_buff *skb)
{
	if (handle_dump_pkt_qca(hdev, skb))
		return 0;
	if (evt_pkt_is_dump_qca(hdev, skb))
		return handle_dump_pkt_qca(hdev, skb);
	return hci_recv_frame(hdev, skb);
}

+4 −1
Original line number Diff line number Diff line
@@ -1543,7 +1543,7 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot)
	struct tc_taprio_qopt_offload *taprio;
	struct ocelot_port *ocelot_port;
	struct timespec64 base_ts;
	int port;
	int i, port;
	u32 val;

	mutex_lock(&ocelot->fwd_domain_lock);
@@ -1575,6 +1575,9 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot)
			   QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB_M,
			   QSYS_PARAM_CFG_REG_3);

		for (i = 0; i < taprio->num_entries; i++)
			vsc9959_tas_gcl_set(ocelot, i, &taprio->entries[i]);

		ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
			   QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
			   QSYS_TAS_PARAM_CFG_CTRL);
Loading