mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-27 23:20:26 +09:00
firmware: ti_sci: Add support for firewall management
TI-SCI message protocol provides support for controlling the firewall configurations available in SoC. Introduce support for the set of TI-SCI message protocol APIs that provide us with this capability of controlling firewalls. Signed-off-by: Andrew F. Davis <afd@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com> Reviewed-by: Andreas Dannenberg <dannenberg@ti.com>
This commit is contained in:
parent
407a219261
commit
32ca8ffd5b
@ -2428,6 +2428,178 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_cmd_set_fwl_region() - Request for configuring a firewall region
|
||||
* @handle: pointer to TI SCI handle
|
||||
* @region: region configuration parameters
|
||||
*
|
||||
* Return: 0 if all went well, else returns appropriate error value.
|
||||
*/
|
||||
static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle,
|
||||
const struct ti_sci_msg_fwl_region *region)
|
||||
{
|
||||
struct ti_sci_msg_fwl_set_firewall_region_req req;
|
||||
struct ti_sci_msg_hdr *resp;
|
||||
struct ti_sci_info *info;
|
||||
struct ti_sci_xfer *xfer;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR(handle))
|
||||
return PTR_ERR(handle);
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
info = handle_to_ti_sci_info(handle);
|
||||
|
||||
xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_SET,
|
||||
TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
|
||||
(u32 *)&req, sizeof(req), sizeof(*resp));
|
||||
if (IS_ERR(xfer)) {
|
||||
ret = PTR_ERR(xfer);
|
||||
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
req.fwl_id = region->fwl_id;
|
||||
req.region = region->region;
|
||||
req.n_permission_regs = region->n_permission_regs;
|
||||
req.control = region->control;
|
||||
req.permissions[0] = region->permissions[0];
|
||||
req.permissions[1] = region->permissions[1];
|
||||
req.permissions[2] = region->permissions[2];
|
||||
req.start_address = region->start_address;
|
||||
req.end_address = region->end_address;
|
||||
|
||||
ret = ti_sci_do_xfer(info, xfer);
|
||||
if (ret) {
|
||||
dev_err(info->dev, "Mbox send fail %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
|
||||
|
||||
if (!ti_sci_is_response_ack(resp))
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_cmd_get_fwl_region() - Request for getting a firewall region
|
||||
* @handle: pointer to TI SCI handle
|
||||
* @region: region configuration parameters
|
||||
*
|
||||
* Return: 0 if all went well, else returns appropriate error value.
|
||||
*/
|
||||
static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle,
|
||||
struct ti_sci_msg_fwl_region *region)
|
||||
{
|
||||
struct ti_sci_msg_fwl_get_firewall_region_req req;
|
||||
struct ti_sci_msg_fwl_get_firewall_region_resp *resp;
|
||||
struct ti_sci_info *info;
|
||||
struct ti_sci_xfer *xfer;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR(handle))
|
||||
return PTR_ERR(handle);
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
info = handle_to_ti_sci_info(handle);
|
||||
|
||||
xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_GET,
|
||||
TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
|
||||
(u32 *)&req, sizeof(req), sizeof(*resp));
|
||||
if (IS_ERR(xfer)) {
|
||||
ret = PTR_ERR(xfer);
|
||||
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
req.fwl_id = region->fwl_id;
|
||||
req.region = region->region;
|
||||
req.n_permission_regs = region->n_permission_regs;
|
||||
|
||||
ret = ti_sci_do_xfer(info, xfer);
|
||||
if (ret) {
|
||||
dev_err(info->dev, "Mbox send fail %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
resp = (struct ti_sci_msg_fwl_get_firewall_region_resp *)xfer->tx_message.buf;
|
||||
|
||||
if (!ti_sci_is_response_ack(resp))
|
||||
return -ENODEV;
|
||||
|
||||
region->fwl_id = resp->fwl_id;
|
||||
region->region = resp->region;
|
||||
region->n_permission_regs = resp->n_permission_regs;
|
||||
region->control = resp->control;
|
||||
region->permissions[0] = resp->permissions[0];
|
||||
region->permissions[1] = resp->permissions[1];
|
||||
region->permissions[2] = resp->permissions[2];
|
||||
region->start_address = resp->start_address;
|
||||
region->end_address = resp->end_address;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_cmd_change_fwl_owner() - Request for changing a firewall owner
|
||||
* @handle: pointer to TI SCI handle
|
||||
* @region: region configuration parameters
|
||||
*
|
||||
* Return: 0 if all went well, else returns appropriate error value.
|
||||
*/
|
||||
static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle,
|
||||
struct ti_sci_msg_fwl_owner *owner)
|
||||
{
|
||||
struct ti_sci_msg_fwl_change_owner_info_req req;
|
||||
struct ti_sci_msg_fwl_change_owner_info_resp *resp;
|
||||
struct ti_sci_info *info;
|
||||
struct ti_sci_xfer *xfer;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR(handle))
|
||||
return PTR_ERR(handle);
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
info = handle_to_ti_sci_info(handle);
|
||||
|
||||
xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_GET,
|
||||
TISCI_MSG_FWL_CHANGE_OWNER,
|
||||
(u32 *)&req, sizeof(req), sizeof(*resp));
|
||||
if (IS_ERR(xfer)) {
|
||||
ret = PTR_ERR(xfer);
|
||||
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
req.fwl_id = owner->fwl_id;
|
||||
req.region = owner->region;
|
||||
req.owner_index = owner->owner_index;
|
||||
|
||||
ret = ti_sci_do_xfer(info, xfer);
|
||||
if (ret) {
|
||||
dev_err(info->dev, "Mbox send fail %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
resp = (struct ti_sci_msg_fwl_change_owner_info_resp *)xfer->tx_message.buf;
|
||||
|
||||
if (!ti_sci_is_response_ack(resp))
|
||||
return -ENODEV;
|
||||
|
||||
owner->fwl_id = resp->fwl_id;
|
||||
owner->region = resp->region;
|
||||
owner->owner_index = resp->owner_index;
|
||||
owner->owner_privid = resp->owner_privid;
|
||||
owner->owner_permission_bits = resp->owner_permission_bits;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* ti_sci_setup_ops() - Setup the operations structures
|
||||
* @info: pointer to TISCI pointer
|
||||
@ -2444,6 +2616,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
|
||||
struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops;
|
||||
struct ti_sci_rm_psil_ops *psilops = &ops->rm_psil_ops;
|
||||
struct ti_sci_rm_udmap_ops *udmap_ops = &ops->rm_udmap_ops;
|
||||
struct ti_sci_fwl_ops *fwl_ops = &ops->fwl_ops;
|
||||
|
||||
bops->board_config = ti_sci_cmd_set_board_config;
|
||||
bops->board_config_rm = ti_sci_cmd_set_board_config_rm;
|
||||
@ -2501,6 +2674,10 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
|
||||
udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg;
|
||||
udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg;
|
||||
udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg;
|
||||
|
||||
fwl_ops->set_fwl_region = ti_sci_cmd_set_fwl_region;
|
||||
fwl_ops->get_fwl_region = ti_sci_cmd_get_fwl_region;
|
||||
fwl_ops->change_fwl_owner = ti_sci_cmd_change_fwl_owner;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,6 +79,10 @@
|
||||
#define TISCI_MSG_RM_UDMAP_FLOW_GET_CFG 0x1232
|
||||
#define TISCI_MSG_RM_UDMAP_FLOW_SIZE_THRESH_GET_CFG 0x1233
|
||||
|
||||
#define TISCI_MSG_FWL_SET 0x9000
|
||||
#define TISCI_MSG_FWL_GET 0x9001
|
||||
#define TISCI_MSG_FWL_CHANGE_OWNER 0x9002
|
||||
|
||||
/**
|
||||
* struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
|
||||
* @type: Type of messages: One of TI_SCI_MSG* values
|
||||
@ -1338,4 +1342,121 @@ struct ti_sci_msg_rm_udmap_flow_cfg_resp {
|
||||
struct ti_sci_msg_hdr hdr;
|
||||
} __packed;
|
||||
|
||||
#define FWL_MAX_PRIVID_SLOTS 3U
|
||||
|
||||
/**
|
||||
* struct ti_sci_msg_fwl_set_firewall_region_req - Request for configuring the firewall permissions.
|
||||
*
|
||||
* @hdr: Generic Header
|
||||
*
|
||||
* @fwl_id: Firewall ID in question
|
||||
* @region: Region or channel number to set config info
|
||||
* This field is unused in case of a simple firewall and must be initialized
|
||||
* to zero. In case of a region based firewall, this field indicates the
|
||||
* region in question. (index starting from 0) In case of a channel based
|
||||
* firewall, this field indicates the channel in question (index starting
|
||||
* from 0)
|
||||
* @n_permission_regs: Number of permission registers to set
|
||||
* @control: Contents of the firewall CONTROL register to set
|
||||
* @permissions: Contents of the firewall PERMISSION register to set
|
||||
* @start_address: Contents of the firewall START_ADDRESS register to set
|
||||
* @end_address: Contents of the firewall END_ADDRESS register to set
|
||||
*/
|
||||
|
||||
struct ti_sci_msg_fwl_set_firewall_region_req {
|
||||
struct ti_sci_msg_hdr hdr;
|
||||
u16 fwl_id;
|
||||
u16 region;
|
||||
u32 n_permission_regs;
|
||||
u32 control;
|
||||
u32 permissions[FWL_MAX_PRIVID_SLOTS];
|
||||
u64 start_address;
|
||||
u64 end_address;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ti_sci_msg_fwl_get_firewall_region_req - Request for retrieving the firewall permissions
|
||||
*
|
||||
* @hdr: Generic Header
|
||||
*
|
||||
* @fwl_id: Firewall ID in question
|
||||
* @region: Region or channel number to get config info
|
||||
* This field is unused in case of a simple firewall and must be initialized
|
||||
* to zero. In case of a region based firewall, this field indicates the
|
||||
* region in question (index starting from 0). In case of a channel based
|
||||
* firewall, this field indicates the channel in question (index starting
|
||||
* from 0).
|
||||
* @n_permission_regs: Number of permission registers to retrieve
|
||||
*/
|
||||
struct ti_sci_msg_fwl_get_firewall_region_req {
|
||||
struct ti_sci_msg_hdr hdr;
|
||||
u16 fwl_id;
|
||||
u16 region;
|
||||
u32 n_permission_regs;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ti_sci_msg_fwl_get_firewall_region_resp - Response for retrieving the firewall permissions
|
||||
*
|
||||
* @hdr: Generic Header
|
||||
*
|
||||
* @fwl_id: Firewall ID in question
|
||||
* @region: Region or channel number to set config info This field is
|
||||
* unused in case of a simple firewall and must be initialized to zero. In
|
||||
* case of a region based firewall, this field indicates the region in
|
||||
* question. (index starting from 0) In case of a channel based firewall, this
|
||||
* field indicates the channel in question (index starting from 0)
|
||||
* @n_permission_regs: Number of permission registers retrieved
|
||||
* @control: Contents of the firewall CONTROL register
|
||||
* @permissions: Contents of the firewall PERMISSION registers
|
||||
* @start_address: Contents of the firewall START_ADDRESS register This is not applicable for channelized firewalls.
|
||||
* @end_address: Contents of the firewall END_ADDRESS register This is not applicable for channelized firewalls.
|
||||
*/
|
||||
struct ti_sci_msg_fwl_get_firewall_region_resp {
|
||||
struct ti_sci_msg_hdr hdr;
|
||||
u16 fwl_id;
|
||||
u16 region;
|
||||
u32 n_permission_regs;
|
||||
u32 control;
|
||||
u32 permissions[FWL_MAX_PRIVID_SLOTS];
|
||||
u64 start_address;
|
||||
u64 end_address;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ti_sci_msg_fwl_change_owner_info_req - Request for a firewall owner change
|
||||
*
|
||||
* @hdr: Generic Header
|
||||
*
|
||||
* @fwl_id: Firewall ID in question
|
||||
* @region: Region or channel number if applicable
|
||||
* @owner_index: New owner index to transfer ownership to
|
||||
*/
|
||||
struct ti_sci_msg_fwl_change_owner_info_req {
|
||||
struct ti_sci_msg_hdr hdr;
|
||||
u16 fwl_id;
|
||||
u16 region;
|
||||
u8 owner_index;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ti_sci_msg_fwl_change_owner_info_resp - Response for a firewall owner change
|
||||
*
|
||||
* @hdr: Generic Header
|
||||
*
|
||||
* @fwl_id: Firewall ID specified in request
|
||||
* @region: Region or channel number specified in request
|
||||
* @owner_index: Owner index specified in request
|
||||
* @owner_privid: New owner priv-ID returned by DMSC.
|
||||
* @owner_permission_bits: New owner permission bits returned by DMSC.
|
||||
*/
|
||||
struct ti_sci_msg_fwl_change_owner_info_resp {
|
||||
struct ti_sci_msg_hdr hdr;
|
||||
u16 fwl_id;
|
||||
u16 region;
|
||||
u8 owner_index;
|
||||
u8 owner_privid;
|
||||
u16 owner_permission_bits;
|
||||
} __packed;
|
||||
|
||||
#endif /* __TI_SCI_H */
|
||||
|
@ -510,6 +510,68 @@ struct ti_sci_rm_udmap_ops {
|
||||
const struct ti_sci_msg_rm_udmap_flow_cfg *params);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ti_sci_msg_fwl_region_cfg - Request and Response for firewalls settings
|
||||
*
|
||||
* @fwl_id: Firewall ID in question
|
||||
* @region: Region or channel number to set config info
|
||||
* This field is unused in case of a simple firewall and must be initialized
|
||||
* to zero. In case of a region based firewall, this field indicates the
|
||||
* region in question. (index starting from 0) In case of a channel based
|
||||
* firewall, this field indicates the channel in question (index starting
|
||||
* from 0)
|
||||
* @n_permission_regs: Number of permission registers to set
|
||||
* @control: Contents of the firewall CONTROL register to set
|
||||
* @permissions: Contents of the firewall PERMISSION register to set
|
||||
* @start_address: Contents of the firewall START_ADDRESS register to set
|
||||
* @end_address: Contents of the firewall END_ADDRESS register to set
|
||||
*/
|
||||
struct ti_sci_msg_fwl_region {
|
||||
u16 fwl_id;
|
||||
u16 region;
|
||||
u32 n_permission_regs;
|
||||
u32 control;
|
||||
u32 permissions[3];
|
||||
u64 start_address;
|
||||
u64 end_address;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* \brief Request and Response for firewall owner change
|
||||
*
|
||||
* @fwl_id: Firewall ID in question
|
||||
* @region: Region or channel number to set config info
|
||||
* This field is unused in case of a simple firewall and must be initialized
|
||||
* to zero. In case of a region based firewall, this field indicates the
|
||||
* region in question. (index starting from 0) In case of a channel based
|
||||
* firewall, this field indicates the channel in question (index starting
|
||||
* from 0)
|
||||
* @n_permission_regs: Number of permission registers <= 3
|
||||
* @control: Control register value for this region
|
||||
* @owner_index: New owner index to change to. Owner indexes are setup in DMSC firmware boot configuration data
|
||||
* @owner_privid: New owner priv-id, used to lookup owner_index is not known, must be set to zero otherwise
|
||||
* @owner_permission_bits: New owner permission bits
|
||||
*/
|
||||
struct ti_sci_msg_fwl_owner {
|
||||
u16 fwl_id;
|
||||
u16 region;
|
||||
u8 owner_index;
|
||||
u8 owner_privid;
|
||||
u16 owner_permission_bits;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ti_sci_fwl_ops - Firewall specific operations
|
||||
* @set_fwl_region: Request for configuring the firewall permissions.
|
||||
* @get_fwl_region: Request for retrieving the firewall permissions.
|
||||
* @change_fwl_owner: Request for a change of firewall owner.
|
||||
*/
|
||||
struct ti_sci_fwl_ops {
|
||||
int (*set_fwl_region)(const struct ti_sci_handle *handle, const struct ti_sci_msg_fwl_region *region);
|
||||
int (*get_fwl_region)(const struct ti_sci_handle *handle, struct ti_sci_msg_fwl_region *region);
|
||||
int (*change_fwl_owner)(const struct ti_sci_handle *handle, struct ti_sci_msg_fwl_owner *owner);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ti_sci_ops - Function support for TI SCI
|
||||
* @board_ops: Miscellaneous operations
|
||||
@ -518,6 +580,7 @@ struct ti_sci_rm_udmap_ops {
|
||||
* @core_ops: Core specific operations
|
||||
* @proc_ops: Processor specific operations
|
||||
* @ring_ops: Ring Accelerator Management operations
|
||||
* @fw_ops: Firewall specific operations
|
||||
*/
|
||||
struct ti_sci_ops {
|
||||
struct ti_sci_board_ops board_ops;
|
||||
@ -529,6 +592,7 @@ struct ti_sci_ops {
|
||||
struct ti_sci_rm_ringacc_ops rm_ring_ops;
|
||||
struct ti_sci_rm_psil_ops rm_psil_ops;
|
||||
struct ti_sci_rm_udmap_ops rm_udmap_ops;
|
||||
struct ti_sci_fwl_ops fwl_ops;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user