diff --git a/drivers/ub/ubase/ubase_ubus.c b/drivers/ub/ubase/ubase_ubus.c index a589915cd68663ee0be874f4ee4fb198041e583d..a0351b283890992d4808329f4bce3177abb37f6c 100644 --- a/drivers/ub/ubase/ubase_ubus.c +++ b/drivers/ub/ubase/ubase_ubus.c @@ -114,26 +114,22 @@ static void ubase_ubus_uninit(struct ub_entity *ue) ub_entity_enable(ue, 0); } -static void ubase_port_reset_prepare(struct ub_entity *ue, u16 port_id) +static void ubase_port_event_notify(struct ub_entity *ue, u16 port_id, int event) { struct ubase_dev *udev = dev_get_drvdata(&ue->dev); - ubase_info(udev, "port %u reset prepare.\n", port_id); - ubase_port_down(udev); -} - -static void ubase_port_reset_done(struct ub_entity *ue, u16 port_id) -{ - struct ubase_dev *udev = dev_get_drvdata(&ue->dev); - - ubase_port_up(udev); - ubase_info(udev, "port %u reset done.\n", port_id); - udev->reset_stat.port_reset_cnt++; + if (event == UB_PORT_EVENT_RESET_PREPARE) { + ubase_info(udev, "port %u reset prepare.\n", port_id); + ubase_port_down(udev); + } else if (event == UB_PORT_EVENT_RESET_DONE) { + ubase_port_up(udev); + ubase_info(udev, "port %u reset done.\n", port_id); + udev->reset_stat.port_reset_cnt++; + } } static struct ub_share_port_ops ubase_share_port_ops = { - .reset_prepare = ubase_port_reset_prepare, - .reset_done = ubase_port_reset_done + .event_notify = ubase_port_event_notify }; static int ubase_ubus_reg_share_port(struct ubase_dev *udev) diff --git a/drivers/ub/ubfi/irq.c b/drivers/ub/ubfi/irq.c index eb716af1308846242058d57d1d0003d039063af0..5835bc8421b367cb34c6ed58f6e636277267e581 100644 --- a/drivers/ub/ubfi/irq.c +++ b/drivers/ub/ubfi/irq.c @@ -62,8 +62,10 @@ int ubrt_register_gsi(u32 hwirq, int trigger, int polarity, const char *name, res->start = irq; res->end = irq; res->flags = IORESOURCE_IRQ; -#endif return 0; +#else + return -EINVAL; +#endif } EXPORT_SYMBOL_GPL(ubrt_register_gsi); diff --git a/drivers/ub/ubus/Makefile b/drivers/ub/ubus/Makefile index 59505977dd2f3e15e2ce3f7f7ab94a5651c67cb2..96efd80d502fb6ec9352c28430b90bb02c1e95a1 100644 --- a/drivers/ub/ubus/Makefile +++ b/drivers/ub/ubus/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_UB_UBUS) += ub-driver.o controller.o config.o entity.o ras.o obj-$(CONFIG_UB_UBUS) += msi/ ubus-y := ubus_driver.o sysfs.o ubus_controller.o msg.o ubus_config.o port.o cc.o eid.o cna.o route.o -ubus-y += enum.o resource.o ubus_entity.o reset.o cap.o interrupt.o decoder.o omm.o ioctl.o eu.o link.o +ubus-y += enum.o resource.o ubus_entity.o reset.o cap.o interrupt.o decoder.o ioctl.o eu.o link.o ubus-y += instance.o pool.o memory.o ubus-y += services/ras.o services/service.o services/gucd.o diff --git a/drivers/ub/ubus/decoder.c b/drivers/ub/ubus/decoder.c index f5a8e69fd1cf8bebe0503a75ec00e6c5a96d2d2f..288e33a960381c96543237aa7a80e3c7eee3810c 100644 --- a/drivers/ub/ubus/decoder.c +++ b/drivers/ub/ubus/decoder.c @@ -13,7 +13,6 @@ #include "ubus.h" #include "ubus_controller.h" -#include "omm.h" #include "decoder.h" #define MMIO_SIZE_MASK GENMASK_ULL(18, 16) @@ -33,8 +32,6 @@ #define EVTQ_ENABLE 0x1 #define EVT_ENTRY_SIZE 16 -#define DECODER_PAGE_TABLE_ENTRY_SIZE 8 - #define DECODER_QUEUE_TIMEOUT_US 1000000 /* 1s */ static void ub_decoder_uninit_queue(struct ub_decoder *decoder) @@ -170,68 +167,24 @@ static u32 ub_decoder_device_set(struct ub_decoder *decoder) return ret; } -static int ub_decoder_create_page_table(struct ub_decoder *decoder) +static int ub_decoder_create_page_table(struct ub_bus_controller *ubc, + struct ub_decoder *decoder) { - struct page_table_desc *invalid_desc = &decoder->invalid_desc; - struct ub_entity *uent = decoder->uent; - struct page_table *pgtlb; - void *pgtlb_base; - size_t size; - - size = DECODER_PAGE_TABLE_ENTRY_SIZE * DECODER_PAGE_TABLE_SIZE; - pgtlb = &decoder->pgtlb; - pgtlb_base = dmam_alloc_coherent(decoder->dev, size, - &pgtlb->pgtlb_dma, GFP_KERNEL); - if (!pgtlb_base) { - ub_err(uent, "allocate ub decoder page table fail\n"); - return -ENOMEM; - } - pgtlb->pgtlb_base = pgtlb_base; - - size = sizeof(*pgtlb->desc_base) * DECODER_PAGE_TABLE_SIZE; - pgtlb->desc_base = kzalloc(size, GFP_KERNEL); - if (!pgtlb->desc_base) { - ub_err(uent, "allocate ub decoder page table desc fail\n"); - goto release_pgtlb; - } - - invalid_desc->page_base = dmam_alloc_coherent(decoder->dev, - RANGE_TABLE_PAGE_SIZE, - &invalid_desc->page_dma, - GFP_KERNEL); - if (!invalid_desc->page_base) { - ub_err(uent, "decoder alloc free page fail\n"); - goto release_desc; - } - decoder->invalid_page_dma = (invalid_desc->page_dma & - DECODER_PGTBL_PGPRT_MASK) >> - DECODER_DMA_PAGE_ADDR_OFFSET; - - ub_decoder_init_page_table(decoder, pgtlb_base); + if (ubc->ops->create_decoder_table) + return ubc->ops->create_decoder_table(decoder); - return 0; - -release_desc: - kfree(pgtlb->desc_base); - pgtlb->desc_base = NULL; -release_pgtlb: - size = DECODER_PAGE_TABLE_ENTRY_SIZE * DECODER_PAGE_TABLE_SIZE; - dmam_free_coherent(decoder->dev, size, pgtlb_base, pgtlb->pgtlb_dma); - return -ENOMEM; + ub_err(decoder->uent, "ub bus controller can't create decoder table\n"); + return -EPERM; } -static void ub_decoder_free_page_table(struct ub_decoder *decoder) +static void ub_decoder_free_page_table(struct ub_bus_controller *ubc, + struct ub_decoder *decoder) { - struct page_table_desc *invalid_desc = &decoder->invalid_desc; - size_t size; - - dmam_free_coherent(decoder->dev, RANGE_TABLE_PAGE_SIZE, - invalid_desc->page_base, invalid_desc->page_dma); - kfree(decoder->pgtlb.desc_base); - - size = DECODER_PAGE_TABLE_ENTRY_SIZE * DECODER_PAGE_TABLE_SIZE; - dmam_free_coherent(decoder->dev, size, decoder->pgtlb.pgtlb_base, - decoder->pgtlb.pgtlb_dma); + if (ubc->ops->free_decoder_table) + ubc->ops->free_decoder_table(decoder); + else + ub_err(decoder->uent, + "ub bus controller can't free decoder table\n"); } static void ub_get_decoder_mmio_base(struct ub_bus_controller *ubc, @@ -302,7 +255,7 @@ static int ub_create_decoder(struct ub_bus_controller *ubc) if (ret) goto release_decoder; - ret = ub_decoder_create_page_table(decoder); + ret = ub_decoder_create_page_table(ubc, decoder); if (ret) { ub_err(uent, "decoder create page table failed\n"); goto release_queue; @@ -321,7 +274,7 @@ static int ub_create_decoder(struct ub_bus_controller *ubc) return ret; release_page_table: - ub_decoder_free_page_table(decoder); + ub_decoder_free_page_table(ubc, decoder); release_queue: ub_decoder_uninit_queue(decoder); release_decoder: @@ -397,7 +350,7 @@ static void ub_remove_decoder(struct ub_bus_controller *ubc) ub_decoder_device_unset(decoder); - ub_decoder_free_page_table(decoder); + ub_decoder_free_page_table(ubc, decoder); ub_decoder_uninit_queue(decoder); @@ -635,6 +588,7 @@ int ub_decoder_cmd_request(struct ub_decoder *decoder, phys_addr_t addr, ret = wait_for_cmdq_notify(decoder); return ret; } +EXPORT_SYMBOL_GPL(ub_decoder_cmd_request); static bool queue_empty(struct ub_decoder_queue *q) { @@ -839,3 +793,38 @@ void ub_decoder_uninit(struct ub_entity *uent) ub_remove_decoder(uent->ubc); } + +int ub_decoder_unmap(struct ub_decoder *decoder, phys_addr_t addr, u64 size) +{ + struct ub_bus_controller *ubc; + + if (!decoder) { + pr_err("unmap mmio decoder ptr is null\n"); + return -EINVAL; + } + + ubc = decoder->uent->ubc; + if (!ubc->ops->decoder_unmap) { + pr_err("decoder_unmap ops not exist\n"); + return -EINVAL; + } + return ubc->ops->decoder_unmap(ubc->decoder, addr, size); +} + +int ub_decoder_map(struct ub_decoder *decoder, struct decoder_map_info *info) +{ + struct ub_bus_controller *ubc; + + if (!decoder || !info) { + pr_err("decoder or map info is null\n"); + return -EINVAL; + } + + ubc = decoder->uent->ubc; + if (!ubc->ops->decoder_map) { + pr_err("decoder_map ops not exist\n"); + return -EINVAL; + } + + return ubc->ops->decoder_map(ubc->decoder, info); +} diff --git a/drivers/ub/ubus/decoder.h b/drivers/ub/ubus/decoder.h index 47710ead71db6414f26f26b8492eb0c0c8b2048b..37d628dc45e278865e364931619e42548edf7480 100644 --- a/drivers/ub/ubus/decoder.h +++ b/drivers/ub/ubus/decoder.h @@ -87,33 +87,20 @@ struct ub_decoder { struct mutex table_lock; }; -#define DECODER_PGTBL_PGPRT_MASK GENMASK_ULL(47, 12) -#define DECODER_DMA_PAGE_ADDR_OFFSET 12 - -#define PGTLB_CACHE_IR_NC 0b00 -#define PGTLB_CACHE_IR_WBRA 0b01 -#define PGTLB_CACHE_IR_WT 0b10 -#define PGTLB_CACHE_IR_WB 0b11 -#define PGTLB_CACHE_OR_NC 0b0000 -#define PGTLB_CACHE_OR_WBRA 0b0100 -#define PGTLB_CACHE_OR_WT 0b1000 -#define PGTLB_CACHE_OR_WB 0b1100 -#define PGTLB_CACHE_SH_NSH 0b000000 -#define PGTLB_CACHE_SH_OSH 0b100000 -#define PGTLB_CACHE_SH_ISH 0b110000 - -#define PGTLB_ATTR_DEFAULT (PGTLB_CACHE_IR_WBRA | \ - PGTLB_CACHE_OR_WBRA | \ - PGTLB_CACHE_SH_ISH) - -#define RGTLB_TO_PGTLB 8 -#define DECODER_PAGE_ENTRY_SIZE 64 -#define DECODER_PAGE_SIZE (1 << 12) -#define DECODER_PAGE_TABLE_SIZE (1 << 12) -#define PAGE_TABLE_PAGE_SIZE (DECODER_PAGE_ENTRY_SIZE * DECODER_PAGE_SIZE) -#define RANGE_TABLE_PAGE_SIZE (DECODER_PAGE_ENTRY_SIZE * \ - DECODER_PAGE_SIZE * \ - RGTLB_TO_PGTLB) +struct decoder_map_info { + phys_addr_t pa; + phys_addr_t uba; + u64 size; + u32 tpg_num; + u8 order_id; + u8 order_type; + u64 eid_low; + u64 eid_high; + u32 token_id; + u32 token_value; + u32 upi; + u32 src_eid; +}; void ub_decoder_init(struct ub_entity *uent); void ub_decoder_uninit(struct ub_entity *uent); @@ -121,4 +108,6 @@ void ub_init_decoder_usi(struct ub_entity *uent); void ub_uninit_decoder_usi(struct ub_entity *uent); int ub_decoder_cmd_request(struct ub_decoder *decoder, phys_addr_t addr, u64 size, enum ub_cmd_op_type op); +int ub_decoder_map(struct ub_decoder *decoder, struct decoder_map_info *info); +int ub_decoder_unmap(struct ub_decoder *decoder, phys_addr_t addr, u64 size); #endif /* __DECODER_H__ */ diff --git a/drivers/ub/ubus/link.c b/drivers/ub/ubus/link.c index 266d8e828143d5591d78c051f9bfa0ccc90cb8da..001139f3ad63078a1a6d9f0dead7477903245358 100644 --- a/drivers/ub/ubus/link.c +++ b/drivers/ub/ubus/link.c @@ -285,13 +285,13 @@ static void port_link_state_change(struct ub_port *port, struct ub_port *r_port) void ublc_link_up_handle(struct ub_port *port) { struct ub_entity *uent = port->uent; - struct ub_port *r_port; struct ub_entity *r_uent; + struct ub_port *r_port; int ret; if (port->r_uent) { - ub_err(uent, "port%u is already up\n", port->index); - return; + ub_warn(uent, "port%u is already up\n", port->index); + goto link_up_notify; } device_lock(&uent->dev); @@ -324,6 +324,8 @@ void ublc_link_up_handle(struct ub_port *port) ub_info(uent, "port%u link up\n", port->index); out: device_unlock(&uent->dev); +link_up_notify: + ub_notify_share_port(port, UB_PORT_EVENT_LINK_UP); } void ublc_link_down_handle(struct ub_port *port) @@ -332,8 +334,8 @@ void ublc_link_down_handle(struct ub_port *port) struct ub_port *r_port; if (!port->r_uent) { - ub_err(uent, "port%u is already down\n", port->index); - return; + ub_warn(uent, "port%u is already down\n", port->index); + goto link_down_notify; } device_lock(&uent->dev); @@ -355,6 +357,8 @@ void ublc_link_down_handle(struct ub_port *port) device_unlock(&uent->dev); ub_info(uent, "port%u link down\n", port->index); +link_down_notify: + ub_notify_share_port(port, UB_PORT_EVENT_LINK_DOWN); } void ub_link_change_handler(struct work_struct *work) diff --git a/drivers/ub/ubus/msg.c b/drivers/ub/ubus/msg.c index 1d1893a8f54de23334eb8b7a28e0daf5e9119a5d..54f77128ad2f95c8da4f636b605d6f37a9df06f7 100644 --- a/drivers/ub/ubus/msg.c +++ b/drivers/ub/ubus/msg.c @@ -162,7 +162,7 @@ struct workqueue_struct *get_rx_msg_wq(u8 msg_code) return rx_msg_wq[msg_code]; } -static bool msg_rx_flag; +static atomic_t msg_rx_flag; int message_rx_init(void) { @@ -186,18 +186,20 @@ int message_rx_init(void) rx_msg_wq[i] = q; } - msg_rx_flag = true; + wmb(); /* Ensure the register is written correctly. */ + atomic_set(&msg_rx_flag, 1); return 0; } void message_rx_uninit(void) { -#define MSG_RX_WAIT_US 1000 +#define MSG_RX_WAIT_US 15000 struct workqueue_struct *q; int i; - msg_rx_flag = false; + atomic_set(&msg_rx_flag, 0); + wmb(); /* Ensure the register is written correctly. */ /* For cpus still handle rx msg in interrupt context */ udelay(MSG_RX_WAIT_US); @@ -297,7 +299,7 @@ int message_rx_handler(struct ub_bus_controller *ubc, void *pkt, u16 len) struct msg_extended_header *msgetah = &header->msgetah; struct ub_rx_msg_task *task; - if (!msg_rx_flag) + if (!atomic_read(&msg_rx_flag)) return -EBUSY; if (len < MSG_PKT_HEADER_SIZE) { diff --git a/drivers/ub/ubus/omm.h b/drivers/ub/ubus/omm.h deleted file mode 100644 index e90ce9cb1f7f2d83fcbac386c95e8c2134ded6dc..0000000000000000000000000000000000000000 --- a/drivers/ub/ubus/omm.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) HiSilicon Technologies Co., Ltd. 2025. All rights reserved. - */ - -#ifndef __OMM_H__ -#define __OMM_H__ - -#include - -extern u8 ubc_feature; - -struct decoder_map_info { - phys_addr_t pa; - phys_addr_t uba; - u64 size; - u32 tpg_num; - u8 order_id; - u8 order_type; - u64 eid_low; - u64 eid_high; - u32 token_id; - u32 token_value; - u32 upi; - u32 src_eid; -}; - -void ub_decoder_init_page_table(struct ub_decoder *decoder, void *pgtlb_base); -int ub_decoder_unmap(struct ub_decoder *decoder, phys_addr_t addr, u64 size); -int ub_decoder_map(struct ub_decoder *decoder, struct decoder_map_info *info); - -#endif /* __OMM_H__ */ diff --git a/drivers/ub/ubus/pool.c b/drivers/ub/ubus/pool.c index e86b19b58f630ef9e4b309f8b26431976a3d54ff..414e9dba0c20522d4c8c83c773b45c5b40a99807 100644 --- a/drivers/ub/ubus/pool.c +++ b/drivers/ub/ubus/pool.c @@ -613,9 +613,9 @@ static void ub_port_reset_notify_handler(struct ub_bus_controller *ubc, void *ms port = ubc->uent->ports + pld->port_index; if (port->shareable && port->domain_boundary) { if (pld->type == RESET_PREPARE) - ub_notify_share_port(port, RESET_PREPARE); + ub_notify_share_port(port, UB_PORT_EVENT_RESET_PREPARE); else if (pld->type == RESET_DONE) - ub_notify_share_port(port, RESET_DONE); + ub_notify_share_port(port, UB_PORT_EVENT_RESET_DONE); } rsp: diff --git a/drivers/ub/ubus/port.c b/drivers/ub/ubus/port.c index 36950c24e3443ee5c67b305c065eee582ec5932b..a8a238df8cc4fdb098323858b184d4582d57575a 100644 --- a/drivers/ub/ubus/port.c +++ b/drivers/ub/ubus/port.c @@ -577,49 +577,46 @@ static DECLARE_RWSEM(ub_share_port_notify_list_rwsem); struct ub_share_port_notify_node { struct ub_entity *parent; - struct ub_entity *idev; + struct ub_entity *entity; u16 port_id; struct ub_share_port_ops *ops; struct list_head node; }; -int ub_register_share_port(struct ub_entity *idev, u16 port_id, +int ub_register_share_port(struct ub_entity *entity, u16 port_id, struct ub_share_port_ops *ops) { struct ub_share_port_notify_node *notify_node; struct ub_entity *parent; struct ub_port *port; - if (unlikely(!idev || !ops)) + if (unlikely(!entity || !ops)) return -EINVAL; - if (!is_idev(idev)) { - ub_err(idev, "don't support non-idev device with type %u register share port\n", - uent_type(idev)); + if (!is_idev(entity) && !is_ibus_controller(entity)) { + ub_err(entity, + "don't support device with type %u register share port\n", + uent_type(entity)); return -EINVAL; } /* get primary entity first */ - parent = idev; - while (!is_primary(parent)) - parent = parent->pue; - - /* check parent is controller */ - parent = to_ub_entity(parent->dev.parent); - if (!is_ibus_controller(parent)) { - ub_err(idev, "don't support register share port at non-controller device with type %u\n", - uent_type(parent)); - return -EINVAL; - } - - if (port_id >= parent->port_nums) { - ub_err(parent, "port id %u exceeds port num %u\n", port_id, - parent->port_nums); - return -EINVAL; + parent = entity; + if (is_idev(parent)) { + while (!is_primary(parent)) + parent = parent->pue; + + /* check parent is controller */ + parent = to_ub_entity(parent->dev.parent); + if (!is_ibus_controller(parent)) { + ub_err(entity, "don't support register share port at non-controller device with type %u\n", + uent_type(parent)); + return -EINVAL; + } } port = parent->ports + port_id; - if (!port->shareable) { + if (is_idev(entity) && !port->shareable) { ub_err(parent, "port%u isn't shareable\n", port_id); return -EINVAL; } @@ -629,7 +626,7 @@ int ub_register_share_port(struct ub_entity *idev, u16 port_id, return -ENOMEM; notify_node->parent = parent; - notify_node->idev = idev; + notify_node->entity = entity; notify_node->port_id = port_id; notify_node->ops = ops; INIT_LIST_HEAD(¬ify_node->node); @@ -638,33 +635,33 @@ int ub_register_share_port(struct ub_entity *idev, u16 port_id, list_add_tail(¬ify_node->node, &ub_share_port_notify_list); up_write(&ub_share_port_notify_list_rwsem); - ub_info(idev, "register share port at %u success\n", port_id); + ub_info(entity, "register share port at %u success\n", port_id); return 0; } EXPORT_SYMBOL_GPL(ub_register_share_port); -void ub_unregister_share_port(struct ub_entity *idev, u16 port_id, +void ub_unregister_share_port(struct ub_entity *entity, u16 port_id, struct ub_share_port_ops *ops) { struct ub_share_port_notify_node *notify_node; - if (unlikely(!idev)) + if (unlikely(!entity)) return; down_write(&ub_share_port_notify_list_rwsem); list_for_each_entry(notify_node, &ub_share_port_notify_list, node) { - if (notify_node->idev != idev || + if (notify_node->entity != entity || notify_node->port_id != port_id || notify_node->ops != ops) continue; list_del(¬ify_node->node); kfree(notify_node); - ub_info(idev, "unregister share port at %u success\n", port_id); + ub_info(entity, "unregister share port at %u success\n", port_id); goto unlock; } - ub_err(idev, "share port %u isn't registered, unregister failed\n", + ub_err(entity, "share port %u isn't registered, unregister failed\n", port_id); unlock: up_write(&ub_share_port_notify_list_rwsem); @@ -672,13 +669,13 @@ void ub_unregister_share_port(struct ub_entity *idev, u16 port_id, EXPORT_SYMBOL_GPL(ub_unregister_share_port); void ub_notify_share_port(struct ub_port *port, - enum ub_share_port_notify_type type) + enum ub_port_event type) { struct ub_share_port_notify_node *notify_node; struct ub_share_port_ops *ops; struct ub_entity *uent; - if (!port || type >= NOTIFY_TYPE_MAX) + if (!port || type > UB_PORT_EVENT_RESET_DONE) return; uent = port->uent; @@ -689,23 +686,13 @@ void ub_notify_share_port(struct ub_port *port, continue; ops = notify_node->ops; - switch (type) { - case RESET_PREPARE: - if (ops->reset_prepare) - ops->reset_prepare(notify_node->idev, - notify_node->port_id); - break; - case RESET_DONE: - if (ops->reset_done) - ops->reset_done(notify_node->idev, - notify_node->port_id); - break; - default: - break; - } + if (ops->event_notify) + ops->event_notify(notify_node->entity, + notify_node->port_id, type); } up_read(&ub_share_port_notify_list_rwsem); } +EXPORT_SYMBOL_GPL(ub_notify_share_port); bool ub_port_check_link_up(struct ub_port *port) { diff --git a/drivers/ub/ubus/port.h b/drivers/ub/ubus/port.h index 0350908c531abb606f93cbfc11250f7c45f198f6..21a2c7d33299b96799617e27c76da5e5c768f339 100644 --- a/drivers/ub/ubus/port.h +++ b/drivers/ub/ubus/port.h @@ -8,10 +8,9 @@ #define for_each_uent_port(p, d) \ for ((p) = (d)->ports; ((p) - (d)->ports) < (d)->port_nums; (p)++) -enum ub_share_port_notify_type { +enum ub_port_reset_notify_type { RESET_PREPARE, - RESET_DONE, - NOTIFY_TYPE_MAX + RESET_DONE }; struct ub_port; @@ -24,7 +23,7 @@ void ub_ports_del(struct ub_entity *uent); int ub_ports_setup(struct ub_entity *uent); void ub_ports_unset(struct ub_entity *uent); void ub_notify_share_port(struct ub_port *port, - enum ub_share_port_notify_type type); + enum ub_port_event type); int ub_port_write_dword(struct ub_port *port, u32 pos, u32 val); bool ub_port_check_link_up(struct ub_port *port); diff --git a/drivers/ub/ubus/reset.c b/drivers/ub/ubus/reset.c index 596d848c2c1184b98d5eeddd950b267110a47f73..51d984d25b8fe2f1c64433fa303ec1732e7031e3 100644 --- a/drivers/ub/ubus/reset.c +++ b/drivers/ub/ubus/reset.c @@ -293,8 +293,7 @@ int ub_port_reset(struct ub_entity *dev, int port_id) return -EINVAL; } - if (port->shareable) - ub_notify_share_port(port, RESET_PREPARE); + ub_notify_share_port(port, UB_PORT_EVENT_RESET_PREPARE); /* enable port reset */ ret = ub_port_write_dword(port, UB_PORT_RST, 0x01); @@ -310,8 +309,7 @@ int ub_port_reset(struct ub_entity *dev, int port_id) device_unlock(&dev->dev); if (ub_wait_port_complete(port)) { - if (port->shareable) - ub_notify_share_port(port, RESET_DONE); + ub_notify_share_port(port, UB_PORT_EVENT_RESET_DONE); port->link_state = LINK_STATE_NORMAL; ub_info(dev, "port(%d) reset success!\n", port_id); return ret; diff --git a/drivers/ub/ubus/resource.c b/drivers/ub/ubus/resource.c index d4516d672bb5c92a5f53bb73a1b1718560cc73ff..6e8ceeb9fa93fe172409a258602f158ed4d4fab7 100644 --- a/drivers/ub/ubus/resource.c +++ b/drivers/ub/ubus/resource.c @@ -12,7 +12,6 @@ #include "ubus.h" #include "msg.h" #include "decoder.h" -#include "omm.h" #include "resource.h" struct query_token_msg_pld_req { diff --git a/drivers/ub/ubus/route.c b/drivers/ub/ubus/route.c index 364bf78d93c33f3f7425ceebc4bf4bcc801badca..ef3d462a90eec2738950a52bd73fb2f32707ed71 100644 --- a/drivers/ub/ubus/route.c +++ b/drivers/ub/ubus/route.c @@ -505,6 +505,10 @@ static void ub_set_route_table_entry(struct ub_entity *uent, u32 dst_cna, if (uent->port_nums == 1) return; + /* In a cluster scenario, do not configure the UBC routing table. */ + if (is_ibus_controller(uent) && uent->ubc->cluster) + return; + pr_info("cna %#x uent set dstcna %#x route\n", uent->cna, dst_cna); for (i = 0; i < EBW(uent->port_nums); i++) { diff --git a/drivers/ub/ubus/ubus_controller.h b/drivers/ub/ubus/ubus_controller.h index 4b3c7a74a41407bcd5cbbb5827acb45a4fda4f87..04eb4a3d76480619d66af0f44e2af07ab91e01a5 100644 --- a/drivers/ub/ubus/ubus_controller.h +++ b/drivers/ub/ubus/ubus_controller.h @@ -6,6 +6,9 @@ #ifndef __UBUS_CONTROLLER_H__ #define __UBUS_CONTROLLER_H__ +#include +#include "decoder.h" + struct ub_bus_controller; struct ub_bus_controller_ops { int (*eu_table_init)(struct ub_bus_controller *ubc); @@ -18,6 +21,12 @@ struct ub_bus_controller_ops { void (*register_decoder_base_addr)(struct ub_bus_controller *ubc, u64 *cmd_queue, u64 *event_queue); int (*entity_enable)(struct ub_entity *uent, u8 enable); + int (*create_decoder_table)(struct ub_decoder *decoder); + void (*free_decoder_table)(struct ub_decoder *decoder); + int (*decoder_map)(struct ub_decoder *decoder, + struct decoder_map_info *info); + int (*decoder_unmap)(struct ub_decoder *decoder, phys_addr_t addr, + u64 size); KABI_RESERVE(1) KABI_RESERVE(2) diff --git a/drivers/ub/ubus/vendor/hisilicon/Makefile b/drivers/ub/ubus/vendor/hisilicon/Makefile index 998c0e09aeef1019f8ad67987bc616dacb1a7005..fec1dbe157969f5b1c643383ce4998a5bdef6bb2 100644 --- a/drivers/ub/ubus/vendor/hisilicon/Makefile +++ b/drivers/ub/ubus/vendor/hisilicon/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ hisi_ubus-objs := hisi-ubus.o controller.o vdm.o local-ras.o msg.o msg-core.o -hisi_ubus-objs += msg-debugfs.o eu-table.o memory.o +hisi_ubus-objs += msg-debugfs.o eu-table.o memory.o hisi-decoder.o obj-$(CONFIG_UB_HISI_UBUS) += hisi_ubus.o diff --git a/drivers/ub/ubus/vendor/hisilicon/controller.c b/drivers/ub/ubus/vendor/hisilicon/controller.c index d7ea5c118d32bbf04e81ccf1dce37666b0890cf4..6c9c8e32047999d91bde3635bb3b6d9447dbd86a 100644 --- a/drivers/ub/ubus/vendor/hisilicon/controller.c +++ b/drivers/ub/ubus/vendor/hisilicon/controller.c @@ -10,6 +10,7 @@ #include #include "../../ubus_controller.h" +#include "hisi-decoder.h" #include "hisi-ubus.h" #include "hisi-msg.h" @@ -23,17 +24,12 @@ static struct ub_bus_controller_ops hi_ubc_ops = { .unregister_ubmem_irq = hi_unregister_ubmem_irq, .register_decoder_base_addr = hi_register_decoder_base_addr, .entity_enable = hi_send_entity_enable_msg, + .create_decoder_table = hi_create_decoder_table, + .free_decoder_table = hi_free_decoder_table, + .decoder_map = hi_decoder_map, + .decoder_unmap = hi_decoder_unmap, }; -void hi_register_decoder_base_addr(struct ub_bus_controller *ubc, u64 *cmd_queue, - u64 *event_queue) -{ - struct hi_ubc_private_data *data = (struct hi_ubc_private_data *)ubc->data; - - *cmd_queue = data->io_decoder_cmdq; - *event_queue = data->io_decoder_evtq; -} - static void ub_bus_controller_debugfs_init(struct ub_bus_controller *ubc) { if (!debugfs_initialized()) diff --git a/drivers/ub/ubus/omm.c b/drivers/ub/ubus/vendor/hisilicon/hisi-decoder.c similarity index 86% rename from drivers/ub/ubus/omm.c rename to drivers/ub/ubus/vendor/hisilicon/hisi-decoder.c index b8b59a9da4f16f2fe7f1baab7ea0b23ab3f903fe..ac1fa0498ffc57783c454a789824c3001fcf9c95 100644 --- a/drivers/ub/ubus/omm.c +++ b/drivers/ub/ubus/vendor/hisilicon/hisi-decoder.c @@ -3,11 +3,13 @@ * Copyright (c) HiSilicon Technologies Co., Ltd. 2025. All rights reserved. */ -#define pr_fmt(fmt) "ubus omm: " fmt +#define pr_fmt(fmt) "ubus hisi decoder: " fmt #include -#include "decoder.h" -#include "omm.h" +#include +#include "../../ubus.h" +#include "hisi-ubus.h" +#include "hisi-decoder.h" enum entry_type { INVALID_ENTRY = 0x0, @@ -95,6 +97,7 @@ struct range_table_entry { u64 reserve11 : 12; }; +#define DECODER_PAGE_TABLE_ENTRY_SIZE 8 #define UBA_ADDR_OFFSET 12 #define DECODER_PAGE_INDEX_LOC 20 @@ -107,6 +110,11 @@ struct range_table_entry { #define DECODER_RGTLB_ADDRESS_MASK GENMASK_ULL(34, 20) #define DECODER_RGTLB_ADDRESS_OFFSET 20 #define TOKEN_VALID_MASK GENMASK(0, 0) +#define MEM_LMT_MAX 0x7FFF +#define RANGE_UBA_LOW_MASK GENMASK_ULL(34, 20) +#define RANGE_UBA_HIGH_MASK GENMASK_ULL(63, 35) +#define UBA_CARRY 0x800000000 +#define UBA_NOCARRY 0x0 #define get_pgtlb_idx(decoder, pa) ((((pa) - (decoder)->mmio_base_addr) & \ DECODER_PAGE_TABLE_MASK) >> \ @@ -485,12 +493,6 @@ static int handle_page_table(struct ub_decoder *decoder, u64 *offset, return ret; } -#define MEM_LMT_MAX 0x7FFF -#define RANGE_UBA_LOW_MASK GENMASK_ULL(34, 20) -#define RANGE_UBA_HIGH_MASK GENMASK_ULL(63, 35) -#define UBA_CARRY 0x800000000 -#define UBA_NOCARRY 0x0 - static void fill_range_table(struct ub_decoder *decoder, struct range_table_entry *rg_entry, struct decoder_map_info *info, u64 *offset) @@ -593,7 +595,7 @@ static int handle_table(struct ub_decoder *decoder, ret); /* if it is map operation, revert it. unmap operation can't revert */ if (is_map) - (void)ub_decoder_unmap(decoder, info->pa, + (void)hi_decoder_unmap(decoder, info->pa, rollback_size); break; } @@ -601,7 +603,88 @@ static int handle_table(struct ub_decoder *decoder, return ret; } -int ub_decoder_unmap(struct ub_decoder *decoder, phys_addr_t addr, u64 size) +static void ub_decoder_init_page_table(struct ub_decoder *decoder, void *pgtlb_base) +{ + struct page_table_entry *pgtlb_entry; + int i; + + for (i = 0; i < DECODER_PAGE_TABLE_SIZE; i++) { + pgtlb_entry = (struct page_table_entry *)pgtlb_base + i; + pgtlb_entry->entry_type = PAGE_TABLE; + pgtlb_entry->next_lv_addr = decoder->invalid_page_dma; + pgtlb_entry->pgtlb_attr = PGTLB_ATTR_DEFAULT; + } +} + +void hi_register_decoder_base_addr(struct ub_bus_controller *ubc, + u64 *cmd_queue, u64 *event_queue) +{ + struct hi_ubc_private_data *data = (struct hi_ubc_private_data *)ubc->data; + + *cmd_queue = data->io_decoder_cmdq; + *event_queue = data->io_decoder_evtq; +} + +int hi_create_decoder_table(struct ub_decoder *decoder) +{ + struct page_table_desc *invalid_desc = &decoder->invalid_desc; + struct page_table *pgtlb; + void *pgtlb_base; + size_t size; + + size = DECODER_PAGE_TABLE_ENTRY_SIZE * DECODER_PAGE_TABLE_SIZE; + pgtlb = &decoder->pgtlb; + pgtlb_base = dmam_alloc_coherent(decoder->dev, size, + &pgtlb->pgtlb_dma, GFP_KERNEL); + if (!pgtlb_base) + return -ENOMEM; + + pgtlb->pgtlb_base = pgtlb_base; + + size = sizeof(*pgtlb->desc_base) * DECODER_PAGE_TABLE_SIZE; + pgtlb->desc_base = kzalloc(size, GFP_KERNEL); + if (!pgtlb->desc_base) + goto release_pgtlb; + + invalid_desc->page_base = dmam_alloc_coherent(decoder->dev, + RANGE_TABLE_PAGE_SIZE, + &invalid_desc->page_dma, + GFP_KERNEL); + if (!invalid_desc->page_base) + goto release_desc; + + decoder->invalid_page_dma = (invalid_desc->page_dma & + DECODER_PGTBL_PGPRT_MASK) >> + DECODER_DMA_PAGE_ADDR_OFFSET; + + ub_decoder_init_page_table(decoder, pgtlb_base); + + return 0; + +release_desc: + kfree(pgtlb->desc_base); + pgtlb->desc_base = NULL; +release_pgtlb: + size = DECODER_PAGE_TABLE_ENTRY_SIZE * DECODER_PAGE_TABLE_SIZE; + dmam_free_coherent(decoder->dev, size, pgtlb_base, pgtlb->pgtlb_dma); + return -ENOMEM; +} + +void hi_free_decoder_table(struct ub_decoder *decoder) +{ + struct page_table_desc *invalid_desc = &decoder->invalid_desc; + size_t size; + + dmam_free_coherent(decoder->dev, RANGE_TABLE_PAGE_SIZE, + invalid_desc->page_base, invalid_desc->page_dma); + kfree(decoder->pgtlb.desc_base); + + size = DECODER_PAGE_TABLE_ENTRY_SIZE * DECODER_PAGE_TABLE_SIZE; + dmam_free_coherent(decoder->dev, size, decoder->pgtlb.pgtlb_base, + decoder->pgtlb.pgtlb_dma); +} + +int hi_decoder_unmap(struct ub_decoder *decoder, phys_addr_t addr, u64 size) { int ret; struct decoder_map_info info = { @@ -609,10 +692,6 @@ int ub_decoder_unmap(struct ub_decoder *decoder, phys_addr_t addr, u64 size) .size = size, }; - if (!decoder) { - pr_err("unmap mmio decoder ptr is null\n"); - return -EINVAL; - } if (size < SZ_1M) size = SZ_1M; ret = handle_table(decoder, &info, false); @@ -621,12 +700,8 @@ int ub_decoder_unmap(struct ub_decoder *decoder, phys_addr_t addr, u64 size) return ub_decoder_cmd_request(decoder, addr, size, TLBI_PARTIAL); } -int ub_decoder_map(struct ub_decoder *decoder, struct decoder_map_info *info) +int hi_decoder_map(struct ub_decoder *decoder, struct decoder_map_info *info) { - if (!decoder || !info) { - pr_err("decoder or map info is null\n"); - return -EINVAL; - } if (info->size < SZ_1M) info->size = SZ_1M; ub_info(decoder->uent, @@ -637,16 +712,3 @@ int ub_decoder_map(struct ub_decoder *decoder, struct decoder_map_info *info) return handle_table(decoder, info, true); } - -void ub_decoder_init_page_table(struct ub_decoder *decoder, void *pgtlb_base) -{ - struct page_table_entry *pgtlb_entry; - int i; - - for (i = 0; i < DECODER_PAGE_TABLE_SIZE; i++) { - pgtlb_entry = (struct page_table_entry *)pgtlb_base + i; - pgtlb_entry->entry_type = PAGE_TABLE; - pgtlb_entry->next_lv_addr = decoder->invalid_page_dma; - pgtlb_entry->pgtlb_attr = PGTLB_ATTR_DEFAULT; - } -} diff --git a/drivers/ub/ubus/vendor/hisilicon/hisi-decoder.h b/drivers/ub/ubus/vendor/hisilicon/hisi-decoder.h new file mode 100644 index 0000000000000000000000000000000000000000..50658ef7b9cbd5bf3598b43c1d8b7853c0e53d1c --- /dev/null +++ b/drivers/ub/ubus/vendor/hisilicon/hisi-decoder.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) HiSilicon Technologies Co., Ltd. 2025. All rights reserved. + */ + +#ifndef __HISI_DECODER_H__ +#define __HISI_DECODER_H__ + +#include +#include +#include "../../decoder.h" + +#define DECODER_PGTBL_PGPRT_MASK GENMASK_ULL(47, 12) +#define DECODER_DMA_PAGE_ADDR_OFFSET 12 + +#define PGTLB_CACHE_IR_NC 0b00 +#define PGTLB_CACHE_IR_WBRA 0b01 +#define PGTLB_CACHE_IR_WT 0b10 +#define PGTLB_CACHE_IR_WB 0b11 +#define PGTLB_CACHE_OR_NC 0b0000 +#define PGTLB_CACHE_OR_WBRA 0b0100 +#define PGTLB_CACHE_OR_WT 0b1000 +#define PGTLB_CACHE_OR_WB 0b1100 +#define PGTLB_CACHE_SH_NSH 0b000000 +#define PGTLB_CACHE_SH_OSH 0b100000 +#define PGTLB_CACHE_SH_ISH 0b110000 + +#define PGTLB_ATTR_DEFAULT (PGTLB_CACHE_IR_WBRA | \ + PGTLB_CACHE_OR_WBRA | \ + PGTLB_CACHE_SH_ISH) + +#define RGTLB_TO_PGTLB 8 +#define DECODER_PAGE_ENTRY_SIZE 64 +#define DECODER_PAGE_SIZE (1 << 12) +#define DECODER_PAGE_TABLE_SIZE (1 << 12) +#define PAGE_TABLE_PAGE_SIZE (DECODER_PAGE_ENTRY_SIZE * DECODER_PAGE_SIZE) +#define RANGE_TABLE_PAGE_SIZE (DECODER_PAGE_ENTRY_SIZE * \ + DECODER_PAGE_SIZE * \ + RGTLB_TO_PGTLB) + +void hi_register_decoder_base_addr(struct ub_bus_controller *ubc, + u64 *cmd_queue, u64 *event_queue); + +int hi_create_decoder_table(struct ub_decoder *decoder); +void hi_free_decoder_table(struct ub_decoder *decoder); + +int hi_decoder_map(struct ub_decoder *decoder, struct decoder_map_info *info); +int hi_decoder_unmap(struct ub_decoder *decoder, phys_addr_t addr, u64 size); + +#endif /* __HISI_DECODER_H__ */ diff --git a/drivers/ub/ubus/vendor/hisilicon/hisi-ubus.h b/drivers/ub/ubus/vendor/hisilicon/hisi-ubus.h index 092695e9d43c349054e4827bb188fe23f96843f6..44e5fc8165babe9c5431738272c239e3fc7aaf51 100644 --- a/drivers/ub/ubus/vendor/hisilicon/hisi-ubus.h +++ b/drivers/ub/ubus/vendor/hisilicon/hisi-ubus.h @@ -43,10 +43,8 @@ int hi_mem_decoder_create(struct ub_bus_controller *ubc); void hi_mem_decoder_remove(struct ub_bus_controller *ubc); void hi_register_ubmem_irq(struct ub_bus_controller *ubc); void hi_unregister_ubmem_irq(struct ub_bus_controller *ubc); -void hi_register_decoder_base_addr(struct ub_bus_controller *ubc, u64 *cmd_queue, - u64 *event_queue); int hi_send_entity_enable_msg(struct ub_entity *uent, u8 enable); - +int hi_send_port_reset_msg(struct ub_entity *uent, u16 port_idx); int ub_bus_controller_probe(struct ub_bus_controller *ubc); void ub_bus_controller_remove(struct ub_bus_controller *ubc); diff --git a/drivers/ub/ubus/vendor/hisilicon/local-ras.c b/drivers/ub/ubus/vendor/hisilicon/local-ras.c index 9dc016555732bec8d473eb405d526e83a5705def..cf65f06da93f4c0dc6454dfb206f1271243f0cbb 100644 --- a/drivers/ub/ubus/vendor/hisilicon/local-ras.c +++ b/drivers/ub/ubus/vendor/hisilicon/local-ras.c @@ -9,7 +9,9 @@ #include "../../ubus.h" #include "../../ubus_driver.h" #include "../../reset.h" +#include "../../port.h" #include "local-ras.h" +#include "hisi-ubus.h" struct sub_module_info { u32 sub_module_id; @@ -197,7 +199,31 @@ static int ubus_port_recover(struct ub_entity *uent, u16 port_id) return 0; } -static int nl_ssu_link_credi_overtime_recover(struct ub_entity *uent, u8 nl_id) +static int ubus_port_recover_cluster(struct ub_entity *uent, u16 port_id) +{ + struct ub_port *port; + int ret; + + if (port_id >= uent->port_nums || uent->ports[port_id].type != PHYSICAL) { + pr_err("port id is over port nums or port type is not physical\n"); + return -EINVAL; + } + + port = uent->ports + port_id; + ub_notify_share_port(port, UB_PORT_EVENT_RESET_PREPARE); + + ret = hi_send_port_reset_msg(uent, port_id); + if (ret) { + pr_err("ub vdm port reset failed, ret:%d\n", ret); + return ret; + } + + ub_notify_share_port(port, UB_PORT_EVENT_RESET_DONE); + + return 0; +} + +static int nl_ssu_link_credi_overtime_recover(struct ub_entity *uent, u8 nl_id, bool cluster) { #define NL_PORTS 2 /* @@ -210,7 +236,10 @@ static int nl_ssu_link_credi_overtime_recover(struct ub_entity *uent, u8 nl_id) for (i = 0; i < NL_PORTS; i++) { port_id += i; - ret = ubus_port_recover(uent, port_id); + if (!cluster) + ret = ubus_port_recover(uent, port_id); + else + ret = ubus_port_recover_cluster(uent, port_id); if (ret) { ub_err(uent, "port[%u] recover failed, ret=%d.\n", port_id, ret); return ret; @@ -230,11 +259,14 @@ static int ubus_recover(struct ub_entity *uent, if (is_nl_local_ras(edata->sub_module_id) && is_nl_ssu_link_credi_overtime_err(edata)) { nl_id = edata->core_id; - return nl_ssu_link_credi_overtime_recover(uent, nl_id); + return nl_ssu_link_credi_overtime_recover(uent, nl_id, uent->ubc->cluster); } port_id = (int)edata->port_id; - return ubus_port_recover(uent, port_id); + if (uent->ubc->cluster) + return ubus_port_recover_cluster(uent, port_id); + else + return ubus_port_recover(uent, port_id); } static void hisi_ubus_handle_error(struct ub_entity *uent, diff --git a/drivers/ub/ubus/vendor/hisilicon/vdm.c b/drivers/ub/ubus/vendor/hisilicon/vdm.c index 2d0444a585c9e6438c0ce69e33ded1f5880f5f76..f95da0843e266b304e3d0ec29d8e6b9c399d2795 100644 --- a/drivers/ub/ubus/vendor/hisilicon/vdm.c +++ b/drivers/ub/ubus/vendor/hisilicon/vdm.c @@ -537,3 +537,48 @@ int hi_send_entity_enable_msg(struct ub_entity *uent, u8 enable) return 0; } + +int hi_send_port_reset_msg(struct ub_entity *uent, u16 port_idx) +{ + struct port_reset_pld *rst_pld; + struct vdm_msg_pkt pkt = {}; + struct msg_info info = {}; + struct msg_pkt_dw0 *pld_dw0; + u8 status; + int ret; + + if (!uent->ubc->cluster) + return 0; + + ub_msg_pkt_header_init(&pkt.header, uent, VDM_PORT_RESET_PLD_SIZE, + code_gen(UB_MSG_CODE_VDM, UB_VENDOR_MSG, + MSG_REQ), true); + + pkt.guid_high = *(u64 *)(&uent->ubc->uent->guid.dw[SZ_2]); + pld_dw0 = &pkt.pld_dw0; + pld_dw0->opcode = VDM_OPCODE_UB2FM_COMM_MSG; + pld_dw0->sub_opcode = VDM_SUB_OPCODE_PORT_RESET; + rst_pld = &pkt.reset_pld; + rst_pld->port_idx = port_idx; + + message_info_init(&info, uent->ubc->uent, &pkt, &pkt, + (VDM_PORT_RESET_SIZE << MSG_REQ_SIZE_OFFSET) | + VDM_PORT_RESET_SIZE); + + ub_info(uent, "Sync request port reset msg\n"); + + ret = hi_message_sync_request(uent->message->mdev, &info, + pkt.header.msgetah.code); + if (ret) { + ub_err(uent, "msg sync request ret=%d\n", ret); + return ret; + } + + status = pkt.header.msgetah.rsp_status; + if (status != UB_MSG_RSP_SUCCESS) { + ub_err(uent, "msg rsp status=%#02x\n", status); + return -EINVAL; + } + + return 0; +} diff --git a/drivers/ub/ubus/vendor/hisilicon/vdm.h b/drivers/ub/ubus/vendor/hisilicon/vdm.h index 183449aa082ef68d0354ec565a01469b51700f3a..725288d6abac846e90a92f8d0ba99fd33e703e75 100644 --- a/drivers/ub/ubus/vendor/hisilicon/vdm.h +++ b/drivers/ub/ubus/vendor/hisilicon/vdm.h @@ -24,6 +24,7 @@ enum vdm_fm2ub_sub_opcode { enum vdm_ub2fm_sub_opcode { VDM_SUB_OPCODE_ENTITY_ENABLE = 0x1, + VDM_SUB_OPCODE_PORT_RESET = 0x2, }; struct msg_pkt_dw0 { @@ -103,6 +104,13 @@ struct idev_ue_rls_pld { }; #define IDEV_UE_RLS_PLD_TOTAL_SIZE 36 +struct port_reset_pld { + /* DW1 */ + u16 rsvd; + u16 port_idx; +}; +#define VDM_PORT_RESET_PLD_SIZE 16 + #define MSG_IDEV_MUE_REG_SIZE \ (MSG_PKT_HEADER_SIZE + IDEV_MUE_REG_PLD_TOTAL_SIZE) #define MSG_IDEV_MUE_RLS_SIZE \ @@ -111,6 +119,8 @@ struct idev_ue_rls_pld { (MSG_PKT_HEADER_SIZE + IDEV_UE_REG_PLD_TOTAL_SIZE) #define MSG_IDEV_UE_RLS_SIZE \ (MSG_PKT_HEADER_SIZE + IDEV_UE_RLS_PLD_TOTAL_SIZE) +#define VDM_PORT_RESET_SIZE \ + (MSG_PKT_HEADER_SIZE + VDM_PORT_RESET_PLD_SIZE) #define VENDOR_GUID_PLD_SIZE 8 @@ -119,6 +129,7 @@ struct vdm_msg_pkt { u64 guid_high; struct msg_pkt_dw0 pld_dw0; union { + struct port_reset_pld reset_pld; struct entity_enable_pld enable_pld; struct idev_pue_reg_pld pd_reg_pld; struct idev_pue_rls_pld pd_rls_pld; diff --git a/drivers/vfio/ubus/vfio_ub_config.c b/drivers/vfio/ubus/vfio_ub_config.c index aaf398281d9e034d8726316ea141a2eb98a34746..0addb2526c16e4626bb564c40afd6e5a7edb31bb 100644 --- a/drivers/vfio/ubus/vfio_ub_config.c +++ b/drivers/vfio/ubus/vfio_ub_config.c @@ -588,6 +588,9 @@ static int vfio_ub_cfg1_basic_write(struct vfio_ub_core_device *vdev, u64 pos, if (count < 0) return count; + if (pos == UB_ENTITY_RS_ACCESS_EN) + ub_entity_enable(vdev->uent, val & 0x1); + buf = vfio_ub_find_cfg_buf(vdev, UB_CFG1_BASIC_CAP); if (!buf) return -EFAULT;