staging: dpaa2-switch: setup dpio

Setup interrupts on the control interface queues. We do not force an
exact affinity between the interrupts received from a specific queue and
a cpu.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ioana Ciornei 2021-03-10 14:14:43 +02:00 коммит произвёл David S. Miller
Родитель 2877e4f7e1
Коммит 04abc97d3e
5 изменённых файлов: 137 добавлений и 0 удалений

Просмотреть файл

@ -76,6 +76,7 @@
#define DPSW_CMDID_CTRL_IF_GET_ATTR DPSW_CMD_ID(0x0A0)
#define DPSW_CMDID_CTRL_IF_SET_POOLS DPSW_CMD_ID(0x0A1)
#define DPSW_CMDID_CTRL_IF_SET_QUEUE DPSW_CMD_ID(0x0A6)
/* Macros for accessing command fields smaller than 1byte */
#define DPSW_MASK(field) \
@ -368,6 +369,20 @@ struct dpsw_cmd_ctrl_if_set_pools {
__le16 buffer_size[DPSW_MAX_DPBP];
};
#define DPSW_DEST_TYPE_SHIFT 0
#define DPSW_DEST_TYPE_SIZE 4
struct dpsw_cmd_ctrl_if_set_queue {
__le32 dest_id;
u8 dest_priority;
u8 pad;
/* from LSB: dest_type:4 */
u8 dest_type;
u8 qtype;
__le64 user_ctx;
__le32 options;
};
struct dpsw_rsp_get_api_version {
__le16 version_major;
__le16 version_minor;

Просмотреть файл

@ -1151,6 +1151,39 @@ int dpsw_ctrl_if_set_pools(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_ctrl_if_set_queue() - Set Rx queue configuration
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of dpsw object
* @qtype: dpsw_queue_type of the targeted queue
* @cfg: Rx queue configuration
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsw_ctrl_if_set_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
enum dpsw_queue_type qtype,
const struct dpsw_ctrl_if_queue_cfg *cfg)
{
struct dpsw_cmd_ctrl_if_set_queue *cmd_params;
struct fsl_mc_command cmd = { 0 };
cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_SET_QUEUE,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_ctrl_if_set_queue *)cmd.params;
cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
cmd_params->dest_priority = cfg->dest_cfg.priority;
cmd_params->qtype = qtype;
cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
cmd_params->options = cpu_to_le32(cfg->options);
dpsw_set_field(cmd_params->dest_type,
DEST_TYPE,
cfg->dest_cfg.dest_type);
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_get_api_version() - Get Data Path Switch API version
* @mc_io: Pointer to MC portal's I/O object

Просмотреть файл

@ -222,6 +222,29 @@ struct dpsw_ctrl_if_pools_cfg {
int dpsw_ctrl_if_set_pools(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
const struct dpsw_ctrl_if_pools_cfg *cfg);
#define DPSW_CTRL_IF_QUEUE_OPT_USER_CTX 0x00000001
#define DPSW_CTRL_IF_QUEUE_OPT_DEST 0x00000002
enum dpsw_ctrl_if_dest {
DPSW_CTRL_IF_DEST_NONE = 0,
DPSW_CTRL_IF_DEST_DPIO = 1,
};
struct dpsw_ctrl_if_dest_cfg {
enum dpsw_ctrl_if_dest dest_type;
int dest_id;
u8 priority;
};
struct dpsw_ctrl_if_queue_cfg {
u32 options;
u64 user_ctx;
struct dpsw_ctrl_if_dest_cfg dest_cfg;
};
int dpsw_ctrl_if_set_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
enum dpsw_queue_type qtype,
const struct dpsw_ctrl_if_queue_cfg *cfg);
/**
* enum dpsw_action - Action selection for special/control frames
* @DPSW_ACTION_DROP: Drop frame

Просмотреть файл

@ -1463,6 +1463,64 @@ static void dpaa2_switch_destroy_rings(struct ethsw_core *ethsw)
dpaa2_io_store_destroy(ethsw->fq[i].store);
}
static int dpaa2_switch_setup_dpio(struct ethsw_core *ethsw)
{
struct dpsw_ctrl_if_queue_cfg queue_cfg;
struct dpaa2_io_notification_ctx *nctx;
int err, i, j;
for (i = 0; i < DPAA2_SWITCH_RX_NUM_FQS; i++) {
nctx = &ethsw->fq[i].nctx;
/* Register a new software context for the FQID.
* By using NULL as the first parameter, we specify that we do
* not care on which cpu are interrupts received for this queue
*/
nctx->is_cdan = 0;
nctx->id = ethsw->fq[i].fqid;
nctx->desired_cpu = DPAA2_IO_ANY_CPU;
err = dpaa2_io_service_register(NULL, nctx, ethsw->dev);
if (err) {
err = -EPROBE_DEFER;
goto err_register;
}
queue_cfg.options = DPSW_CTRL_IF_QUEUE_OPT_DEST |
DPSW_CTRL_IF_QUEUE_OPT_USER_CTX;
queue_cfg.dest_cfg.dest_type = DPSW_CTRL_IF_DEST_DPIO;
queue_cfg.dest_cfg.dest_id = nctx->dpio_id;
queue_cfg.dest_cfg.priority = 0;
queue_cfg.user_ctx = nctx->qman64;
err = dpsw_ctrl_if_set_queue(ethsw->mc_io, 0,
ethsw->dpsw_handle,
ethsw->fq[i].type,
&queue_cfg);
if (err)
goto err_set_queue;
}
return 0;
err_set_queue:
dpaa2_io_service_deregister(NULL, nctx, ethsw->dev);
err_register:
for (j = 0; j < i; j++)
dpaa2_io_service_deregister(NULL, &ethsw->fq[j].nctx,
ethsw->dev);
return err;
}
static void dpaa2_switch_free_dpio(struct ethsw_core *ethsw)
{
int i;
for (i = 0; i < DPAA2_SWITCH_RX_NUM_FQS; i++)
dpaa2_io_service_deregister(NULL, &ethsw->fq[i].nctx,
ethsw->dev);
}
static int dpaa2_switch_ctrl_if_setup(struct ethsw_core *ethsw)
{
int err;
@ -1481,8 +1539,14 @@ static int dpaa2_switch_ctrl_if_setup(struct ethsw_core *ethsw)
if (err)
goto err_free_dpbp;
err = dpaa2_switch_setup_dpio(ethsw);
if (err)
goto err_destroy_rings;
return 0;
err_destroy_rings:
dpaa2_switch_destroy_rings(ethsw);
err_free_dpbp:
dpaa2_switch_free_dpbp(ethsw);
@ -1683,6 +1747,7 @@ static void dpaa2_switch_takedown(struct fsl_mc_device *sw_dev)
static void dpaa2_switch_ctrl_if_teardown(struct ethsw_core *ethsw)
{
dpaa2_switch_free_dpio(ethsw);
dpaa2_switch_destroy_rings(ethsw);
dpaa2_switch_free_dpbp(ethsw);
}

Просмотреть файл

@ -61,6 +61,7 @@ struct dpaa2_switch_fq {
struct ethsw_core *ethsw;
enum dpsw_queue_type type;
struct dpaa2_io_store *store;
struct dpaa2_io_notification_ctx nctx;
u32 fqid;
};