Commit 51af33cf authored by Ido Shamay's avatar Ido Shamay Committed by David S. Miller

net/mlx4_en: Add interface identify support

Add support for the interface ethtool identify feature.

Make the physical port LED to blink with green and yellow colors.

The device handles the LED blink by itself (synchrous use of
set_phys_id), by returning 0 to ETHTOOL_ID_ACTIVE command.
Signed-off-by: default avatarEyal Grossman <eyalgr@mellanox.com>
Signed-off-by: default avatarIdo Shamay <idos@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a130b590
...@@ -1939,6 +1939,32 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev, ...@@ -1939,6 +1939,32 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev,
return 0; return 0;
} }
static int mlx4_en_set_phys_id(struct net_device *dev,
enum ethtool_phys_id_state state)
{
int err;
u16 beacon_duration;
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PORT_BEACON))
return -EOPNOTSUPP;
switch (state) {
case ETHTOOL_ID_ACTIVE:
beacon_duration = PORT_BEACON_MAX_LIMIT;
break;
case ETHTOOL_ID_INACTIVE:
beacon_duration = 0;
break;
default:
return -EOPNOTSUPP;
}
err = mlx4_SET_PORT_BEACON(mdev->dev, priv->port, beacon_duration);
return err;
}
const struct ethtool_ops mlx4_en_ethtool_ops = { const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_drvinfo = mlx4_en_get_drvinfo, .get_drvinfo = mlx4_en_get_drvinfo,
.get_settings = mlx4_en_get_settings, .get_settings = mlx4_en_get_settings,
...@@ -1948,6 +1974,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { ...@@ -1948,6 +1974,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_sset_count = mlx4_en_get_sset_count, .get_sset_count = mlx4_en_get_sset_count,
.get_ethtool_stats = mlx4_en_get_ethtool_stats, .get_ethtool_stats = mlx4_en_get_ethtool_stats,
.self_test = mlx4_en_self_test, .self_test = mlx4_en_self_test,
.set_phys_id = mlx4_en_set_phys_id,
.get_wol = mlx4_en_get_wol, .get_wol = mlx4_en_get_wol,
.set_wol = mlx4_en_set_wol, .set_wol = mlx4_en_set_wol,
.get_msglevel = mlx4_en_get_msglevel, .get_msglevel = mlx4_en_get_msglevel,
......
...@@ -150,6 +150,7 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) ...@@ -150,6 +150,7 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
[24] = "Ethernet Flow control statistics support", [24] = "Ethernet Flow control statistics support",
[25] = "Granular QoS per VF support", [25] = "Granular QoS per VF support",
[26] = "Port ETS Scheduler support", [26] = "Port ETS Scheduler support",
[27] = "Port beacon support",
}; };
int i; int i;
...@@ -647,6 +648,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -647,6 +648,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
#define QUERY_DEV_CAP_RSS_OFFSET 0x2e #define QUERY_DEV_CAP_RSS_OFFSET 0x2e
#define QUERY_DEV_CAP_MAX_RDMA_OFFSET 0x2f #define QUERY_DEV_CAP_MAX_RDMA_OFFSET 0x2f
#define QUERY_DEV_CAP_RSZ_SRQ_OFFSET 0x33 #define QUERY_DEV_CAP_RSZ_SRQ_OFFSET 0x33
#define QUERY_DEV_CAP_PORT_BEACON_OFFSET 0x34
#define QUERY_DEV_CAP_ACK_DELAY_OFFSET 0x35 #define QUERY_DEV_CAP_ACK_DELAY_OFFSET 0x35
#define QUERY_DEV_CAP_MTU_WIDTH_OFFSET 0x36 #define QUERY_DEV_CAP_MTU_WIDTH_OFFSET 0x36
#define QUERY_DEV_CAP_VL_PORT_OFFSET 0x37 #define QUERY_DEV_CAP_VL_PORT_OFFSET 0x37
...@@ -786,6 +788,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -786,6 +788,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
if (field & 0x80) if (field & 0x80)
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FS_EN; dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FS_EN;
dev_cap->fs_log_max_ucast_qp_range_size = field & 0x1f; dev_cap->fs_log_max_ucast_qp_range_size = field & 0x1f;
MLX4_GET(field, outbox, QUERY_DEV_CAP_PORT_BEACON_OFFSET);
if (field & 0x80)
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_PORT_BEACON;
MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET);
if (field & 0x80) if (field & 0x80)
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_DMFS_IPOIB; dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_DMFS_IPOIB;
...@@ -1165,6 +1170,11 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, ...@@ -1165,6 +1170,11 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
field &= 0xd7; field &= 0xd7;
MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN); MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN);
/* For guests, disable port BEACON */
MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_PORT_BEACON_OFFSET);
field &= 0x7f;
MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_PORT_BEACON_OFFSET);
/* For guests, report Blueflame disabled */ /* For guests, report Blueflame disabled */
MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_BF_OFFSET); MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_BF_OFFSET);
field &= 0x7f; field &= 0x7f;
......
...@@ -482,6 +482,7 @@ enum { ...@@ -482,6 +482,7 @@ enum {
MLX4_EN_FLAG_RX_CSUM_NON_TCP_UDP = (1 << 5), MLX4_EN_FLAG_RX_CSUM_NON_TCP_UDP = (1 << 5),
}; };
#define PORT_BEACON_MAX_LIMIT (65535)
#define MLX4_EN_MAC_HASH_SIZE (1 << BITS_PER_BYTE) #define MLX4_EN_MAC_HASH_SIZE (1 << BITS_PER_BYTE)
#define MLX4_EN_MAC_HASH_IDX 5 #define MLX4_EN_MAC_HASH_IDX 5
......
...@@ -835,6 +835,12 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, ...@@ -835,6 +835,12 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
MLX4_CMD_NATIVE); MLX4_CMD_NATIVE);
} }
/* Slaves are not allowed to SET_PORT beacon (LED) blink */
if (op_mod == MLX4_SET_PORT_BEACON_OPCODE) {
mlx4_warn(dev, "denying SET_PORT Beacon slave:%d\n", slave);
return -EPERM;
}
/* For IB, we only consider: /* For IB, we only consider:
* - The capability mask, which is set to the aggregate of all * - The capability mask, which is set to the aggregate of all
* slave function capabilities * slave function capabilities
...@@ -1064,6 +1070,26 @@ int mlx4_SET_PORT_VXLAN(struct mlx4_dev *dev, u8 port, u8 steering, int enable) ...@@ -1064,6 +1070,26 @@ int mlx4_SET_PORT_VXLAN(struct mlx4_dev *dev, u8 port, u8 steering, int enable)
} }
EXPORT_SYMBOL(mlx4_SET_PORT_VXLAN); EXPORT_SYMBOL(mlx4_SET_PORT_VXLAN);
int mlx4_SET_PORT_BEACON(struct mlx4_dev *dev, u8 port, u16 time)
{
int err;
struct mlx4_cmd_mailbox *mailbox;
mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
return PTR_ERR(mailbox);
*((__be32 *)mailbox->buf) = cpu_to_be32(time);
err = mlx4_cmd(dev, mailbox->dma, port, MLX4_SET_PORT_BEACON_OPCODE,
MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
MLX4_CMD_NATIVE);
mlx4_free_cmd_mailbox(dev, mailbox);
return err;
}
EXPORT_SYMBOL(mlx4_SET_PORT_BEACON);
int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave, int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_vhcr *vhcr, struct mlx4_vhcr *vhcr,
struct mlx4_cmd_mailbox *inbox, struct mlx4_cmd_mailbox *inbox,
......
...@@ -191,6 +191,7 @@ enum { ...@@ -191,6 +191,7 @@ enum {
/* Set port opcode modifiers */ /* Set port opcode modifiers */
MLX4_SET_PORT_IB_OPCODE = 0x0, MLX4_SET_PORT_IB_OPCODE = 0x0,
MLX4_SET_PORT_ETH_OPCODE = 0x1, MLX4_SET_PORT_ETH_OPCODE = 0x1,
MLX4_SET_PORT_BEACON_OPCODE = 0x4,
}; };
enum { enum {
......
...@@ -208,6 +208,7 @@ enum { ...@@ -208,6 +208,7 @@ enum {
MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN = 1LL << 24, MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN = 1LL << 24,
MLX4_DEV_CAP_FLAG2_QOS_VPP = 1LL << 25, MLX4_DEV_CAP_FLAG2_QOS_VPP = 1LL << 25,
MLX4_DEV_CAP_FLAG2_ETS_CFG = 1LL << 26, MLX4_DEV_CAP_FLAG2_ETS_CFG = 1LL << 26,
MLX4_DEV_CAP_FLAG2_PORT_BEACON = 1LL << 27,
}; };
enum { enum {
...@@ -1311,6 +1312,7 @@ int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu, ...@@ -1311,6 +1312,7 @@ int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx); u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx);
int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
u8 promisc); u8 promisc);
int mlx4_SET_PORT_BEACON(struct mlx4_dev *dev, u8 port, u16 time);
int mlx4_SET_PORT_VXLAN(struct mlx4_dev *dev, u8 port, u8 steering, int enable); int mlx4_SET_PORT_VXLAN(struct mlx4_dev *dev, u8 port, u8 steering, int enable);
int mlx4_find_cached_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *idx); int mlx4_find_cached_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *idx);
int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx); int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment