#endif
/* These are normally found in linux/if_link.h. */
+#ifndef HAVE_IFLA_NUM_VF
+#define IFLA_NUM_VF 21
+#endif
+#ifndef HAVE_IFLA_EXT_MASK
+#define IFLA_EXT_MASK 29
+#endif
#ifndef HAVE_IFLA_PHYS_SWITCH_ID
#define IFLA_PHYS_SWITCH_ID 36
#endif
/* Add/remove MAC address through Netlink */
struct mlx5_nl_mac_addr {
- struct ether_addr (*mac)[];
+ struct rte_ether_addr (*mac)[];
/**< MAC address handled by the device. */
int mac_n; /**< Number of addresses in the array. */
};
-/** Data structure used by mlx5_nl_ifindex_cb(). */
+/** Data structure used by mlx5_nl_cmdget_cb(). */
struct mlx5_nl_ifindex_data {
const char *name; /**< IB device name (in). */
uint32_t ibindex; /**< IB device index (out). */
uint32_t ifindex; /**< Network interface index (out). */
+ uint32_t portnum; /**< IB device max port number. */
};
/**
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
static int
-mlx5_nl_mac_addr_list(struct rte_eth_dev *dev, struct ether_addr (*mac)[],
+mlx5_nl_mac_addr_list(struct rte_eth_dev *dev, struct rte_ether_addr (*mac)[],
int *mac_n)
{
struct mlx5_priv *priv = dev->data->dev_private;
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
static int
-mlx5_nl_mac_addr_modify(struct rte_eth_dev *dev, struct ether_addr *mac,
+mlx5_nl_mac_addr_modify(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
int add)
{
struct mlx5_priv *priv = dev->data->dev_private;
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
int
-mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
+mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
uint32_t index)
{
struct mlx5_priv *priv = dev->data->dev_private;
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
int
-mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct ether_addr *mac,
+mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
uint32_t index)
{
struct mlx5_priv *priv = dev->data->dev_private;
void
mlx5_nl_mac_addr_sync(struct rte_eth_dev *dev)
{
- struct ether_addr macs[MLX5_MAX_MAC_ADDRESSES];
+ struct rte_ether_addr macs[MLX5_MAX_MAC_ADDRESSES];
int macs_n = 0;
int i;
int ret;
int i;
for (i = MLX5_MAX_MAC_ADDRESSES - 1; i >= 0; --i) {
- struct ether_addr *m = &dev->data->mac_addrs[i];
+ struct rte_ether_addr *m = &dev->data->mac_addrs[i];
if (BITFIELD_ISSET(priv->mac_own, i))
mlx5_nl_mac_addr_remove(dev, m, i);
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
static int
-mlx5_nl_ifindex_cb(struct nlmsghdr *nh, void *arg)
+mlx5_nl_cmdget_cb(struct nlmsghdr *nh, void *arg)
{
struct mlx5_nl_ifindex_data *data = arg;
size_t off = NLMSG_HDRLEN;
uint32_t ibindex = 0;
uint32_t ifindex = 0;
+ uint32_t portnum = 0;
int found = 0;
if (nh->nlmsg_type !=
case RDMA_NLDEV_ATTR_NDEV_INDEX:
ifindex = *(uint32_t *)payload;
break;
+ case RDMA_NLDEV_ATTR_PORT_INDEX:
+ portnum = *(uint32_t *)payload;
+ break;
default:
break;
}
if (found) {
data->ibindex = ibindex;
data->ifindex = ifindex;
+ data->portnum = portnum;
}
return 0;
error:
* Netlink socket of the RDMA kind (NETLINK_RDMA).
* @param[in] name
* IB device name.
- *
+ * @param[in] pindex
+ * IB device port index, starting from 1
* @return
* A valid (nonzero) interface index on success, 0 otherwise and rte_errno
* is set.
*/
unsigned int
-mlx5_nl_ifindex(int nl, const char *name)
+mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex)
{
- static const uint32_t pindex = 1;
uint32_t seq = random();
struct mlx5_nl_ifindex_data data = {
.name = name,
ret = mlx5_nl_send(nl, &req.nh, seq);
if (ret < 0)
return 0;
- ret = mlx5_nl_recv(nl, seq, mlx5_nl_ifindex_cb, &data);
+ ret = mlx5_nl_recv(nl, seq, mlx5_nl_cmdget_cb, &data);
if (ret < 0)
return 0;
if (!data.ibindex)
ret = mlx5_nl_send(nl, &req.nh, seq);
if (ret < 0)
return 0;
- ret = mlx5_nl_recv(nl, seq, mlx5_nl_ifindex_cb, &data);
+ ret = mlx5_nl_recv(nl, seq, mlx5_nl_cmdget_cb, &data);
if (ret < 0)
return 0;
if (!data.ifindex)
return 0;
}
+/**
+ * Get the number of physical ports of given IB device.
+ *
+ * @param nl
+ * Netlink socket of the RDMA kind (NETLINK_RDMA).
+ * @param[in] name
+ * IB device name.
+ *
+ * @return
+ * A valid (nonzero) number of ports on success, 0 otherwise
+ * and rte_errno is set.
+ */
+unsigned int
+mlx5_nl_portnum(int nl, const char *name)
+{
+ uint32_t seq = random();
+ struct mlx5_nl_ifindex_data data = {
+ .name = name,
+ .ibindex = 0,
+ .ifindex = 0,
+ .portnum = 0,
+ };
+ struct nlmsghdr req = {
+ .nlmsg_len = NLMSG_LENGTH(0),
+ .nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV,
+ RDMA_NLDEV_CMD_GET),
+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP,
+ };
+ int ret;
+
+ ret = mlx5_nl_send(nl, &req, seq);
+ if (ret < 0)
+ return 0;
+ ret = mlx5_nl_recv(nl, seq, mlx5_nl_cmdget_cb, &data);
+ if (ret < 0)
+ return 0;
+ if (!data.ibindex) {
+ rte_errno = ENODEV;
+ return 0;
+ }
+ if (!data.portnum)
+ rte_errno = EINVAL;
+ return data.portnum;
+}
+
/**
* Process switch information from Netlink message.
*
struct mlx5_switch_info info = {
.master = 0,
.representor = 0,
- .port_name_new = 0,
+ .name_type = MLX5_PHYS_PORT_NAME_TYPE_NOTSET,
.port_name = 0,
.switch_id = 0,
};
size_t off = NLMSG_LENGTH(sizeof(struct ifinfomsg));
- bool port_name_set = false;
bool switch_id_set = false;
+ bool num_vf_set = false;
if (nh->nlmsg_type != RTM_NEWLINK)
goto error;
if (ra->rta_len > nh->nlmsg_len - off)
goto error;
switch (ra->rta_type) {
+ case IFLA_NUM_VF:
+ num_vf_set = true;
+ break;
case IFLA_PHYS_PORT_NAME:
- port_name_set =
- mlx5_translate_port_name((char *)payload,
- &info);
+ mlx5_translate_port_name((char *)payload, &info);
break;
case IFLA_PHYS_SWITCH_ID:
info.switch_id = 0;
}
off += RTA_ALIGN(ra->rta_len);
}
- info.master = switch_id_set && !port_name_set;
- info.representor = switch_id_set && port_name_set;
+ if (switch_id_set) {
+ /* We have some E-Switch configuration. */
+ mlx5_nl_check_switch_info(num_vf_set, &info);
+ }
+ assert(!(info.master && info.representor));
memcpy(arg, &info, sizeof(info));
return 0;
error:
struct {
struct nlmsghdr nh;
struct ifinfomsg info;
+ struct rtattr rta;
+ uint32_t extmask;
} req = {
.nh = {
- .nlmsg_len = NLMSG_LENGTH(sizeof(req.info)),
+ .nlmsg_len = NLMSG_LENGTH
+ (sizeof(req.info) +
+ RTA_LENGTH(sizeof(uint32_t))),
.nlmsg_type = RTM_GETLINK,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
},
.ifi_family = AF_UNSPEC,
.ifi_index = ifindex,
},
+ .rta = {
+ .rta_type = IFLA_EXT_MASK,
+ .rta_len = RTA_LENGTH(sizeof(int32_t)),
+ },
+ .extmask = RTE_LE32(1),
};
int ret;
ret = mlx5_nl_send(nl, &req.nh, seq);
if (ret >= 0)
ret = mlx5_nl_recv(nl, seq, mlx5_nl_switch_info_cb, info);
+ if (info->master && info->representor) {
+ DRV_LOG(ERR, "ifindex %u device is recognized as master"
+ " and as representor", ifindex);
+ rte_errno = ENODEV;
+ ret = -rte_errno;
+ }
return ret;
}