Skip to content

Commit 2c758ce

Browse files
committed
Merge tag 'platform-drivers-x86-v6.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86
Pull x86 platform driver fixes from Hans de Goede: - various platform/mellanox fixes - one new DMI quirk for asus-wmi * tag 'platform-drivers-x86-v6.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: platform/x86: asus-wmi: Support 2023 ROG X16 tablet mode platform/mellanox: NVSW_SN2201 should depend on ACPI platform/mellanox: mlxbf-bootctl: add NET dependency into Kconfig platform/mellanox: mlxbf-pmc: Fix reading of unprogrammed events platform/mellanox: mlxbf-pmc: Fix potential buffer overflows platform/mellanox: mlxbf-tmfifo: Drop jumbo frames platform/mellanox: mlxbf-tmfifo: Drop the Rx packet if no more descriptors
2 parents a747acc + 4106a70 commit 2c758ce

File tree

4 files changed

+92
-53
lines changed

4 files changed

+92
-53
lines changed

drivers/platform/mellanox/Kconfig

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ config MLXBF_BOOTCTL
6060
tristate "Mellanox BlueField Firmware Boot Control driver"
6161
depends on ARM64
6262
depends on ACPI
63+
depends on NET
6364
help
6465
The Mellanox BlueField firmware implements functionality to
6566
request swapping the primary and alternate eMMC boot partition,
@@ -80,8 +81,8 @@ config MLXBF_PMC
8081

8182
config NVSW_SN2201
8283
tristate "Nvidia SN2201 platform driver support"
83-
depends on HWMON
84-
depends on I2C
84+
depends on HWMON && I2C
85+
depends on ACPI || COMPILE_TEST
8586
select REGMAP_I2C
8687
help
8788
This driver provides support for the Nvidia SN2201 platform.

drivers/platform/mellanox/mlxbf-pmc.c

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_smgen_events[] = {
191191
};
192192

193193
static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_1[] = {
194+
{ 0x0, "DISABLE" },
194195
{ 0xa0, "TPIO_DATA_BEAT" },
195196
{ 0xa1, "TDMA_DATA_BEAT" },
196197
{ 0xa2, "MAP_DATA_BEAT" },
@@ -214,6 +215,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_1[] = {
214215
};
215216

216217
static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_2[] = {
218+
{ 0x0, "DISABLE" },
217219
{ 0xa0, "TPIO_DATA_BEAT" },
218220
{ 0xa1, "TDMA_DATA_BEAT" },
219221
{ 0xa2, "MAP_DATA_BEAT" },
@@ -246,6 +248,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_2[] = {
246248
};
247249

248250
static const struct mlxbf_pmc_events mlxbf_pmc_ecc_events[] = {
251+
{ 0x0, "DISABLE" },
249252
{ 0x100, "ECC_SINGLE_ERROR_CNT" },
250253
{ 0x104, "ECC_DOUBLE_ERROR_CNT" },
251254
{ 0x114, "SERR_INJ" },
@@ -258,13 +261,15 @@ static const struct mlxbf_pmc_events mlxbf_pmc_ecc_events[] = {
258261
};
259262

260263
static const struct mlxbf_pmc_events mlxbf_pmc_mss_events[] = {
264+
{ 0x0, "DISABLE" },
261265
{ 0xc0, "RXREQ_MSS" },
262266
{ 0xc1, "RXDAT_MSS" },
263267
{ 0xc2, "TXRSP_MSS" },
264268
{ 0xc3, "TXDAT_MSS" },
265269
};
266270

267271
static const struct mlxbf_pmc_events mlxbf_pmc_hnf_events[] = {
272+
{ 0x0, "DISABLE" },
268273
{ 0x45, "HNF_REQUESTS" },
269274
{ 0x46, "HNF_REJECTS" },
270275
{ 0x47, "ALL_BUSY" },
@@ -323,6 +328,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_hnf_events[] = {
323328
};
324329

325330
static const struct mlxbf_pmc_events mlxbf_pmc_hnfnet_events[] = {
331+
{ 0x0, "DISABLE" },
326332
{ 0x12, "CDN_REQ" },
327333
{ 0x13, "DDN_REQ" },
328334
{ 0x14, "NDN_REQ" },
@@ -892,7 +898,7 @@ static int mlxbf_pmc_read_event(int blk_num, uint32_t cnt_num, bool is_l3,
892898
uint64_t *result)
893899
{
894900
uint32_t perfcfg_offset, perfval_offset;
895-
uint64_t perfmon_cfg, perfevt, perfctl;
901+
uint64_t perfmon_cfg, perfevt;
896902

897903
if (cnt_num >= pmc->block[blk_num].counters)
898904
return -EINVAL;
@@ -904,25 +910,6 @@ static int mlxbf_pmc_read_event(int blk_num, uint32_t cnt_num, bool is_l3,
904910
perfval_offset = perfcfg_offset +
905911
pmc->block[blk_num].counters * MLXBF_PMC_REG_SIZE;
906912

907-
/* Set counter in "read" mode */
908-
perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR,
909-
MLXBF_PMC_PERFCTL);
910-
perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_STROBE, 1);
911-
perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_WR_R_B, 0);
912-
913-
if (mlxbf_pmc_write(pmc->block[blk_num].mmio_base + perfcfg_offset,
914-
MLXBF_PMC_WRITE_REG_64, perfmon_cfg))
915-
return -EFAULT;
916-
917-
/* Check if the counter is enabled */
918-
919-
if (mlxbf_pmc_read(pmc->block[blk_num].mmio_base + perfval_offset,
920-
MLXBF_PMC_READ_REG_64, &perfctl))
921-
return -EFAULT;
922-
923-
if (!FIELD_GET(MLXBF_PMC_PERFCTL_EN0, perfctl))
924-
return -EINVAL;
925-
926913
/* Set counter in "read" mode */
927914
perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR,
928915
MLXBF_PMC_PERFEVT);
@@ -1008,7 +995,7 @@ static ssize_t mlxbf_pmc_counter_show(struct device *dev,
1008995
} else
1009996
return -EINVAL;
1010997

1011-
return sprintf(buf, "0x%llx\n", value);
998+
return sysfs_emit(buf, "0x%llx\n", value);
1012999
}
10131000

10141001
/* Store function for "counter" sysfs files */
@@ -1078,13 +1065,13 @@ static ssize_t mlxbf_pmc_event_show(struct device *dev,
10781065

10791066
err = mlxbf_pmc_read_event(blk_num, cnt_num, is_l3, &evt_num);
10801067
if (err)
1081-
return sprintf(buf, "No event being monitored\n");
1068+
return sysfs_emit(buf, "No event being monitored\n");
10821069

10831070
evt_name = mlxbf_pmc_get_event_name(pmc->block_name[blk_num], evt_num);
10841071
if (!evt_name)
10851072
return -EINVAL;
10861073

1087-
return sprintf(buf, "0x%llx: %s\n", evt_num, evt_name);
1074+
return sysfs_emit(buf, "0x%llx: %s\n", evt_num, evt_name);
10881075
}
10891076

10901077
/* Store function for "event" sysfs files */
@@ -1139,9 +1126,9 @@ static ssize_t mlxbf_pmc_event_list_show(struct device *dev,
11391126
return -EINVAL;
11401127

11411128
for (i = 0, buf[0] = '\0'; i < size; ++i) {
1142-
len += sprintf(e_info, "0x%x: %s\n", events[i].evt_num,
1143-
events[i].evt_name);
1144-
if (len > PAGE_SIZE)
1129+
len += snprintf(e_info, sizeof(e_info), "0x%x: %s\n",
1130+
events[i].evt_num, events[i].evt_name);
1131+
if (len >= PAGE_SIZE)
11451132
break;
11461133
strcat(buf, e_info);
11471134
ret = len;
@@ -1168,7 +1155,7 @@ static ssize_t mlxbf_pmc_enable_show(struct device *dev,
11681155

11691156
value = FIELD_GET(MLXBF_PMC_L3C_PERF_CNT_CFG_EN, perfcnt_cfg);
11701157

1171-
return sprintf(buf, "%d\n", value);
1158+
return sysfs_emit(buf, "%d\n", value);
11721159
}
11731160

11741161
/* Store function for "enable" sysfs files - only for l3cache */

drivers/platform/mellanox/mlxbf-tmfifo.c

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct mlxbf_tmfifo;
5959
* @vq: pointer to the virtio virtqueue
6060
* @desc: current descriptor of the pending packet
6161
* @desc_head: head descriptor of the pending packet
62+
* @drop_desc: dummy desc for packet dropping
6263
* @cur_len: processed length of the current descriptor
6364
* @rem_len: remaining length of the pending packet
6465
* @pkt_len: total length of the pending packet
@@ -75,6 +76,7 @@ struct mlxbf_tmfifo_vring {
7576
struct virtqueue *vq;
7677
struct vring_desc *desc;
7778
struct vring_desc *desc_head;
79+
struct vring_desc drop_desc;
7880
int cur_len;
7981
int rem_len;
8082
u32 pkt_len;
@@ -86,6 +88,14 @@ struct mlxbf_tmfifo_vring {
8688
struct mlxbf_tmfifo *fifo;
8789
};
8890

91+
/* Check whether vring is in drop mode. */
92+
#define IS_VRING_DROP(_r) ({ \
93+
typeof(_r) (r) = (_r); \
94+
(r->desc_head == &r->drop_desc ? true : false); })
95+
96+
/* A stub length to drop maximum length packet. */
97+
#define VRING_DROP_DESC_MAX_LEN GENMASK(15, 0)
98+
8999
/* Interrupt types. */
90100
enum {
91101
MLXBF_TM_RX_LWM_IRQ,
@@ -214,7 +224,7 @@ static u8 mlxbf_tmfifo_net_default_mac[ETH_ALEN] = {
214224
static efi_char16_t mlxbf_tmfifo_efi_name[] = L"RshimMacAddr";
215225

216226
/* Maximum L2 header length. */
217-
#define MLXBF_TMFIFO_NET_L2_OVERHEAD 36
227+
#define MLXBF_TMFIFO_NET_L2_OVERHEAD (ETH_HLEN + VLAN_HLEN)
218228

219229
/* Supported virtio-net features. */
220230
#define MLXBF_TMFIFO_NET_FEATURES \
@@ -262,6 +272,7 @@ static int mlxbf_tmfifo_alloc_vrings(struct mlxbf_tmfifo *fifo,
262272
vring->align = SMP_CACHE_BYTES;
263273
vring->index = i;
264274
vring->vdev_id = tm_vdev->vdev.id.device;
275+
vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN;
265276
dev = &tm_vdev->vdev.dev;
266277

267278
size = vring_size(vring->num, vring->align);
@@ -367,7 +378,7 @@ static u32 mlxbf_tmfifo_get_pkt_len(struct mlxbf_tmfifo_vring *vring,
367378
return len;
368379
}
369380

370-
static void mlxbf_tmfifo_release_pending_pkt(struct mlxbf_tmfifo_vring *vring)
381+
static void mlxbf_tmfifo_release_pkt(struct mlxbf_tmfifo_vring *vring)
371382
{
372383
struct vring_desc *desc_head;
373384
u32 len = 0;
@@ -596,19 +607,25 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring,
596607

597608
if (vring->cur_len + sizeof(u64) <= len) {
598609
/* The whole word. */
599-
if (is_rx)
600-
memcpy(addr + vring->cur_len, &data, sizeof(u64));
601-
else
602-
memcpy(&data, addr + vring->cur_len, sizeof(u64));
610+
if (!IS_VRING_DROP(vring)) {
611+
if (is_rx)
612+
memcpy(addr + vring->cur_len, &data,
613+
sizeof(u64));
614+
else
615+
memcpy(&data, addr + vring->cur_len,
616+
sizeof(u64));
617+
}
603618
vring->cur_len += sizeof(u64);
604619
} else {
605620
/* Leftover bytes. */
606-
if (is_rx)
607-
memcpy(addr + vring->cur_len, &data,
608-
len - vring->cur_len);
609-
else
610-
memcpy(&data, addr + vring->cur_len,
611-
len - vring->cur_len);
621+
if (!IS_VRING_DROP(vring)) {
622+
if (is_rx)
623+
memcpy(addr + vring->cur_len, &data,
624+
len - vring->cur_len);
625+
else
626+
memcpy(&data, addr + vring->cur_len,
627+
len - vring->cur_len);
628+
}
612629
vring->cur_len = len;
613630
}
614631

@@ -625,13 +642,14 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring,
625642
* flag is set.
626643
*/
627644
static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
628-
struct vring_desc *desc,
645+
struct vring_desc **desc,
629646
bool is_rx, bool *vring_change)
630647
{
631648
struct mlxbf_tmfifo *fifo = vring->fifo;
632649
struct virtio_net_config *config;
633650
struct mlxbf_tmfifo_msg_hdr hdr;
634651
int vdev_id, hdr_len;
652+
bool drop_rx = false;
635653

636654
/* Read/Write packet header. */
637655
if (is_rx) {
@@ -651,8 +669,8 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
651669
if (ntohs(hdr.len) >
652670
__virtio16_to_cpu(virtio_legacy_is_little_endian(),
653671
config->mtu) +
654-
MLXBF_TMFIFO_NET_L2_OVERHEAD)
655-
return;
672+
MLXBF_TMFIFO_NET_L2_OVERHEAD)
673+
drop_rx = true;
656674
} else {
657675
vdev_id = VIRTIO_ID_CONSOLE;
658676
hdr_len = 0;
@@ -667,16 +685,25 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
667685

668686
if (!tm_dev2)
669687
return;
670-
vring->desc = desc;
688+
vring->desc = *desc;
671689
vring = &tm_dev2->vrings[MLXBF_TMFIFO_VRING_RX];
672690
*vring_change = true;
673691
}
692+
693+
if (drop_rx && !IS_VRING_DROP(vring)) {
694+
if (vring->desc_head)
695+
mlxbf_tmfifo_release_pkt(vring);
696+
*desc = &vring->drop_desc;
697+
vring->desc_head = *desc;
698+
vring->desc = *desc;
699+
}
700+
674701
vring->pkt_len = ntohs(hdr.len) + hdr_len;
675702
} else {
676703
/* Network virtio has an extra header. */
677704
hdr_len = (vring->vdev_id == VIRTIO_ID_NET) ?
678705
sizeof(struct virtio_net_hdr) : 0;
679-
vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, desc);
706+
vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, *desc);
680707
hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ?
681708
VIRTIO_ID_NET : VIRTIO_ID_CONSOLE;
682709
hdr.len = htons(vring->pkt_len - hdr_len);
@@ -709,15 +736,23 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
709736
/* Get the descriptor of the next packet. */
710737
if (!vring->desc) {
711738
desc = mlxbf_tmfifo_get_next_pkt(vring, is_rx);
712-
if (!desc)
713-
return false;
739+
if (!desc) {
740+
/* Drop next Rx packet to avoid stuck. */
741+
if (is_rx) {
742+
desc = &vring->drop_desc;
743+
vring->desc_head = desc;
744+
vring->desc = desc;
745+
} else {
746+
return false;
747+
}
748+
}
714749
} else {
715750
desc = vring->desc;
716751
}
717752

718753
/* Beginning of a packet. Start to Rx/Tx packet header. */
719754
if (vring->pkt_len == 0) {
720-
mlxbf_tmfifo_rxtx_header(vring, desc, is_rx, &vring_change);
755+
mlxbf_tmfifo_rxtx_header(vring, &desc, is_rx, &vring_change);
721756
(*avail)--;
722757

723758
/* Return if new packet is for another ring. */
@@ -743,17 +778,24 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
743778
vring->rem_len -= len;
744779

745780
/* Get the next desc on the chain. */
746-
if (vring->rem_len > 0 &&
781+
if (!IS_VRING_DROP(vring) && vring->rem_len > 0 &&
747782
(virtio16_to_cpu(vdev, desc->flags) & VRING_DESC_F_NEXT)) {
748783
idx = virtio16_to_cpu(vdev, desc->next);
749784
desc = &vr->desc[idx];
750785
goto mlxbf_tmfifo_desc_done;
751786
}
752787

753-
/* Done and release the pending packet. */
754-
mlxbf_tmfifo_release_pending_pkt(vring);
788+
/* Done and release the packet. */
755789
desc = NULL;
756790
fifo->vring[is_rx] = NULL;
791+
if (!IS_VRING_DROP(vring)) {
792+
mlxbf_tmfifo_release_pkt(vring);
793+
} else {
794+
vring->pkt_len = 0;
795+
vring->desc_head = NULL;
796+
vring->desc = NULL;
797+
return false;
798+
}
757799

758800
/*
759801
* Make sure the load/store are in order before
@@ -933,7 +975,7 @@ static void mlxbf_tmfifo_virtio_del_vqs(struct virtio_device *vdev)
933975

934976
/* Release the pending packet. */
935977
if (vring->desc)
936-
mlxbf_tmfifo_release_pending_pkt(vring);
978+
mlxbf_tmfifo_release_pkt(vring);
937979
vq = vring->vq;
938980
if (vq) {
939981
vring->vq = NULL;

drivers/platform/x86/asus-nb-wmi.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,15 @@ static const struct dmi_system_id asus_quirks[] = {
478478
},
479479
.driver_data = &quirk_asus_tablet_mode,
480480
},
481+
{
482+
.callback = dmi_matched,
483+
.ident = "ASUS ROG FLOW X16",
484+
.matches = {
485+
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
486+
DMI_MATCH(DMI_PRODUCT_NAME, "GV601V"),
487+
},
488+
.driver_data = &quirk_asus_tablet_mode,
489+
},
481490
{
482491
.callback = dmi_matched,
483492
.ident = "ASUS VivoBook E410MA",

0 commit comments

Comments
 (0)