* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ * @file
+ * Flow API operations for mlx4 driver.
+ */
+
+#include <arpa/inet.h>
#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/queue.h>
+
+/* Verbs headers do not support -pedantic. */
+#ifdef PEDANTIC
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+#include <infiniband/verbs.h>
+#ifdef PEDANTIC
+#pragma GCC diagnostic error "-Wpedantic"
+#endif
+#include <rte_errno.h>
+#include <rte_eth_ctrl.h>
+#include <rte_ethdev.h>
#include <rte_flow.h>
#include <rte_flow_driver.h>
#include <rte_malloc.h>
/* PMD headers. */
#include "mlx4.h"
#include "mlx4_flow.h"
+#include "mlx4_rxtx.h"
#include "mlx4_utils.h"
/** Static initializer for items. */
};
/**
- * Validate a flow supported by the NIC.
+ * Make sure a flow rule is supported and initialize associated structure.
*
* @param priv
* Pointer to private structure.
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
static int
-priv_flow_validate(struct priv *priv,
- const struct rte_flow_attr *attr,
- const struct rte_flow_item items[],
- const struct rte_flow_action actions[],
- struct rte_flow_error *error,
- struct mlx4_flow *flow)
+mlx4_flow_prepare(struct priv *priv,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item items[],
+ const struct rte_flow_action actions[],
+ struct rte_flow_error *error,
+ struct mlx4_flow *flow)
{
const struct mlx4_flow_items *cur_item = mlx4_flow_items;
struct mlx4_flow_action action = {
(const struct rte_flow_action_queue *)
actions->conf;
- if (!queue || (queue->index > (priv->rxqs_n - 1)))
+ if (!queue || (queue->index >
+ (priv->dev->data->nb_rx_queues - 1)))
goto exit_action_not_supported;
action.queue = 1;
} else {
* @see rte_flow_validate()
* @see rte_flow_ops
*/
-int
+static int
mlx4_flow_validate(struct rte_eth_dev *dev,
const struct rte_flow_attr *attr,
const struct rte_flow_item items[],
struct priv *priv = dev->data->dev_private;
struct mlx4_flow flow = { .offset = sizeof(struct ibv_flow_attr) };
- return priv_flow_validate(priv, attr, items, actions, error, &flow);
+ return mlx4_flow_prepare(priv, attr, items, actions, error, &flow);
}
/**
* A flow if the rule could be created.
*/
static struct rte_flow *
-priv_flow_create_action_queue(struct priv *priv,
+mlx4_flow_create_action_queue(struct priv *priv,
struct ibv_flow_attr *ibv_attr,
struct mlx4_flow_action *action,
struct rte_flow_error *error)
if (action->drop) {
qp = priv->flow_drop_queue ? priv->flow_drop_queue->qp : NULL;
} else {
- struct rxq *rxq = (*priv->rxqs)[action->queue_id];
+ struct rxq *rxq = priv->dev->data->rx_queues[action->queue_id];
qp = rxq->qp;
rte_flow->qp = qp;
* @see rte_flow_create()
* @see rte_flow_ops
*/
-struct rte_flow *
+static struct rte_flow *
mlx4_flow_create(struct rte_eth_dev *dev,
const struct rte_flow_attr *attr,
const struct rte_flow_item items[],
struct mlx4_flow flow = { .offset = sizeof(struct ibv_flow_attr), };
int err;
- err = priv_flow_validate(priv, attr, items, actions, error, &flow);
+ err = mlx4_flow_prepare(priv, attr, items, actions, error, &flow);
if (err)
return NULL;
flow.ibv_attr = rte_malloc(__func__, flow.offset, 0);
.port = priv->port,
.flags = 0,
};
- claim_zero(priv_flow_validate(priv, attr, items, actions,
- error, &flow));
+ claim_zero(mlx4_flow_prepare(priv, attr, items, actions,
+ error, &flow));
action = (struct mlx4_flow_action){
.queue = 0,
.drop = 0,
goto exit;
}
}
- rte_flow = priv_flow_create_action_queue(priv, flow.ibv_attr,
+ rte_flow = mlx4_flow_create_action_queue(priv, flow.ibv_attr,
&action, error);
if (rte_flow) {
LIST_INSERT_HEAD(&priv->flows, rte_flow, next);
}
/**
- * @see rte_flow_isolate()
- *
- * Must be done before calling dev_configure().
- *
- * @param dev
- * Pointer to the ethernet device structure.
- * @param enable
- * Nonzero to enter isolated mode, attempt to leave it otherwise.
- * @param[out] error
- * Perform verbose error reporting if not NULL. PMDs initialize this
- * structure in case of error only.
+ * Configure isolated mode.
*
- * @return
- * 0 on success, a negative value on error.
+ * @see rte_flow_isolate()
+ * @see rte_flow_ops
*/
-int
+static int
mlx4_flow_isolate(struct rte_eth_dev *dev,
int enable,
struct rte_flow_error *error)
{
struct priv *priv = dev->data->dev_private;
- if (priv->rxqs) {
- rte_flow_error_set(error, ENOTSUP,
- RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
- NULL, "isolated mode must be set"
- " before configuring the device");
- return -rte_errno;
- }
+ if (!!enable == !!priv->isolated)
+ return 0;
priv->isolated = !!enable;
+ if (enable) {
+ mlx4_mac_addr_del(priv);
+ } else if (mlx4_mac_addr_add(priv) < 0) {
+ priv->isolated = 1;
+ return rte_flow_error_set(error, rte_errno,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, "cannot leave isolated mode");
+ }
return 0;
}
* @see rte_flow_destroy()
* @see rte_flow_ops
*/
-int
+static int
mlx4_flow_destroy(struct rte_eth_dev *dev,
struct rte_flow *flow,
struct rte_flow_error *error)
* @see rte_flow_flush()
* @see rte_flow_ops
*/
-int
+static int
mlx4_flow_flush(struct rte_eth_dev *dev,
struct rte_flow_error *error)
{
* Pointer to private structure.
*/
void
-mlx4_priv_flow_stop(struct priv *priv)
+mlx4_flow_stop(struct priv *priv)
{
struct rte_flow *flow;
* 0 on success, a errno value otherwise and rte_errno is set.
*/
int
-mlx4_priv_flow_start(struct priv *priv)
+mlx4_flow_start(struct priv *priv)
{
int ret;
struct ibv_qp *qp;
}
return 0;
}
+
+static const struct rte_flow_ops mlx4_flow_ops = {
+ .validate = mlx4_flow_validate,
+ .create = mlx4_flow_create,
+ .destroy = mlx4_flow_destroy,
+ .flush = mlx4_flow_flush,
+ .isolate = mlx4_flow_isolate,
+};
+
+/**
+ * Manage filter operations.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param filter_type
+ * Filter type.
+ * @param filter_op
+ * Operation to perform.
+ * @param arg
+ * Pointer to operation-specific structure.
+ *
+ * @return
+ * 0 on success, negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx4_filter_ctrl(struct rte_eth_dev *dev,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op,
+ void *arg)
+{
+ switch (filter_type) {
+ case RTE_ETH_FILTER_GENERIC:
+ if (filter_op != RTE_ETH_FILTER_GET)
+ break;
+ *(const void **)arg = &mlx4_flow_ops;
+ return 0;
+ default:
+ ERROR("%p: filter type (%d) not supported",
+ (void *)dev, filter_type);
+ break;
+ }
+ rte_errno = ENOTSUP;
+ return -rte_errno;
+}