mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-19 15:33:56 +00:00
- Implement wake-on-lan support in mlxen.
This commit is contained in:
parent
83baf4bacc
commit
cafd78fc6e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=220016
@ -494,6 +494,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
|
||||
.get_ethtool_stats = mlx4_en_get_ethtool_stats,
|
||||
.self_test = mlx4_en_self_test,
|
||||
.get_wol = mlx4_en_get_wol,
|
||||
.set_wol = mlx4_en_set_wol,
|
||||
.get_msglevel = mlx4_en_get_msglevel,
|
||||
.set_msglevel = mlx4_en_set_msglevel,
|
||||
.get_coalesce = mlx4_en_get_coalesce,
|
||||
|
@ -532,6 +532,7 @@ int mlx4_en_start_port(struct net_device *dev)
|
||||
struct mlx4_en_dev *mdev = priv->mdev;
|
||||
struct mlx4_en_cq *cq;
|
||||
struct mlx4_en_tx_ring *tx_ring;
|
||||
u64 config;
|
||||
int rx_index = 0;
|
||||
int tx_index = 0;
|
||||
int err = 0;
|
||||
@ -662,6 +663,25 @@ int mlx4_en_start_port(struct net_device *dev)
|
||||
else
|
||||
priv->rx_csum = 0;
|
||||
|
||||
err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);
|
||||
if (err) {
|
||||
en_err(priv, "Failed to get WoL info, unable to modify\n");
|
||||
goto wol_err;
|
||||
}
|
||||
if (dev->if_capenable & IFCAP_WOL_MAGIC) {
|
||||
config |= MLX4_EN_WOL_DO_MODIFY | MLX4_EN_WOL_ENABLED |
|
||||
MLX4_EN_WOL_MAGIC;
|
||||
} else {
|
||||
config &= ~(MLX4_EN_WOL_ENABLED | MLX4_EN_WOL_MAGIC);
|
||||
config |= MLX4_EN_WOL_DO_MODIFY;
|
||||
}
|
||||
|
||||
err = mlx4_wol_write(priv->mdev->dev, config, priv->port);
|
||||
if (err) {
|
||||
en_err(priv, "Failed to set WoL information\n");
|
||||
goto wol_err;
|
||||
}
|
||||
|
||||
priv->port_up = true;
|
||||
|
||||
/* Populate multicast list */
|
||||
@ -676,6 +696,10 @@ int mlx4_en_start_port(struct net_device *dev)
|
||||
|
||||
return 0;
|
||||
|
||||
wol_err:
|
||||
/* close port*/
|
||||
mlx4_CLOSE_PORT(mdev->dev, priv->port);
|
||||
|
||||
mac_err:
|
||||
mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
|
||||
tx_err:
|
||||
@ -1095,6 +1119,8 @@ static int mlx4_en_ioctl(struct ifnet *dev, u_long command, caddr_t data)
|
||||
dev->if_capenable ^= IFCAP_VLAN_HWTAGGING;
|
||||
if (mask & IFCAP_VLAN_HWFILTER)
|
||||
dev->if_capenable ^= IFCAP_VLAN_HWFILTER;
|
||||
if (mask & IFCAP_WOL_MAGIC)
|
||||
dev->if_capenable ^= IFCAP_WOL_MAGIC;
|
||||
if (dev->if_drv_flags & IFF_DRV_RUNNING)
|
||||
mlx4_en_init(priv);
|
||||
VLAN_CAPABILITIES(dev);
|
||||
@ -1534,14 +1560,23 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
|
||||
dev->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING;
|
||||
dev->if_capabilities |= IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWFILTER;
|
||||
dev->if_capabilities |= IFCAP_LINKSTATE | IFCAP_JUMBO_MTU;
|
||||
#if 0 /* Not yet */
|
||||
dev->if_capabilities |= IFCAP_WOL;
|
||||
#endif
|
||||
if (mdev->LSO_support)
|
||||
dev->if_capabilities |= IFCAP_TSO | IFCAP_VLAN_HWTSO;
|
||||
if (mdev->profile.num_lro)
|
||||
dev->if_capabilities |= IFCAP_LRO;
|
||||
dev->if_capenable = dev->if_capabilities;
|
||||
/*
|
||||
* Setup wake-on-lan.
|
||||
*/
|
||||
if (priv->mdev->dev->caps.wol) {
|
||||
u64 config;
|
||||
if (mlx4_wol_read(priv->mdev->dev, &config, priv->port) == 0) {
|
||||
if (config & MLX4_EN_WOL_MAGIC)
|
||||
dev->if_capabilities |= IFCAP_WOL_MAGIC;
|
||||
if (config & MLX4_EN_WOL_ENABLED)
|
||||
dev->if_capenable |= IFCAP_WOL_MAGIC;
|
||||
}
|
||||
}
|
||||
|
||||
/* Register for VLAN events */
|
||||
priv->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
|
||||
|
@ -289,6 +289,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
||||
dev_cap->udp_rss = field & 0x1;
|
||||
MLX4_GET(field, outbox, QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET);
|
||||
dev_cap->loopback_support = field & 0x1;
|
||||
dev_cap->wol = field & 0x40;
|
||||
MLX4_GET(tmp1, outbox, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
|
||||
MLX4_GET(tmp2, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
|
||||
dev_cap->flags = tmp2 | (u64)tmp1 << 32;
|
||||
@ -969,6 +970,25 @@ int mlx4_NOP(struct mlx4_dev *dev)
|
||||
return mlx4_cmd(dev, 0, 0x1f, 0, MLX4_CMD_NOP, 100);
|
||||
}
|
||||
|
||||
#define MLX4_WOL_SETUP_MODE (5 << 28)
|
||||
int mlx4_wol_read(struct mlx4_dev *dev, u64 *config, int port)
|
||||
{
|
||||
u32 in_mod = MLX4_WOL_SETUP_MODE | port << 8;
|
||||
|
||||
return mlx4_cmd_imm(dev, 0, config, in_mod, 0x3,
|
||||
MLX4_CMD_MOD_STAT_CFG, MLX4_CMD_TIME_CLASS_A);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx4_wol_read);
|
||||
|
||||
int mlx4_wol_write(struct mlx4_dev *dev, u64 config, int port)
|
||||
{
|
||||
u32 in_mod = MLX4_WOL_SETUP_MODE | port << 8;
|
||||
|
||||
return mlx4_cmd(dev, config, in_mod, 0x1, MLX4_CMD_MOD_STAT_CFG,
|
||||
MLX4_CMD_TIME_CLASS_A);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx4_wol_write);
|
||||
|
||||
int mlx4_query_diag_counters(struct mlx4_dev *dev, int array_length,
|
||||
u8 op_modifier, u32 in_offset[], u32 counter_out[])
|
||||
{
|
||||
|
@ -80,6 +80,7 @@ struct mlx4_dev_cap {
|
||||
u16 stat_rate_support;
|
||||
int udp_rss;
|
||||
int loopback_support;
|
||||
int wol;
|
||||
u64 flags;
|
||||
int reserved_uars;
|
||||
int uar_size;
|
||||
|
@ -331,6 +331,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
||||
dev->caps.stat_rate_support = dev_cap->stat_rate_support;
|
||||
dev->caps.udp_rss = dev_cap->udp_rss;
|
||||
dev->caps.loopback_support = dev_cap->loopback_support;
|
||||
dev->caps.wol = dev_cap->wol;
|
||||
dev->caps.max_gso_sz = dev_cap->max_gso_sz;
|
||||
dev->caps.reserved_xrcds = (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) ?
|
||||
dev_cap->reserved_xrcds : 0;
|
||||
|
@ -164,7 +164,7 @@ enum {
|
||||
#define MLX4_EN_DEF_TX_RING_SIZE 512
|
||||
#define MLX4_EN_DEF_TX_QUEUE_SIZE 4096
|
||||
#define MLX4_EN_DEF_RX_RING_SIZE 1024
|
||||
#define MLX4_EN_MAX_RX_POLL 16
|
||||
#define MLX4_EN_MAX_RX_POLL 1024
|
||||
|
||||
/* Target number of bytes to coalesce with interrupt moderation */
|
||||
#define MLX4_EN_RX_COAL_TARGET 0x20000
|
||||
@ -537,6 +537,7 @@ struct mlx4_en_priv {
|
||||
u16 num_frags;
|
||||
u16 log_rx_info;
|
||||
int ip_reasm;
|
||||
bool wol;
|
||||
|
||||
struct mlx4_en_tx_ring tx_ring[MAX_TX_RINGS];
|
||||
struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS];
|
||||
@ -561,6 +562,11 @@ struct mlx4_en_priv {
|
||||
struct sysctl_ctx_list stat_ctx;
|
||||
};
|
||||
|
||||
enum mlx4_en_wol {
|
||||
MLX4_EN_WOL_MAGIC = (1ULL << 61),
|
||||
MLX4_EN_WOL_ENABLED = (1ULL << 62),
|
||||
MLX4_EN_WOL_DO_MODIFY = (1ULL << 63),
|
||||
};
|
||||
|
||||
int mlx4_en_transmit(struct net_device *dev, struct mbuf *mb);
|
||||
void mlx4_en_qflush(struct net_device *dev);
|
||||
|
@ -251,6 +251,7 @@ struct mlx4_caps {
|
||||
u16 stat_rate_support;
|
||||
int udp_rss;
|
||||
int loopback_support;
|
||||
int wol;
|
||||
u8 port_width_cap[MLX4_MAX_PORTS + 1];
|
||||
int max_gso_sz;
|
||||
int reserved_qps_cnt[MLX4_NUM_QP_REGION];
|
||||
@ -535,6 +536,9 @@ int mlx4_mtt_init(struct mlx4_dev *dev, int npages, int page_shift,
|
||||
struct mlx4_mtt *mtt);
|
||||
void mlx4_mtt_cleanup(struct mlx4_dev *dev, struct mlx4_mtt *mtt);
|
||||
u64 mlx4_mtt_addr(struct mlx4_dev *dev, struct mlx4_mtt *mtt);
|
||||
int mlx4_wol_read(struct mlx4_dev *dev, u64 *config, int port);
|
||||
int mlx4_wol_write(struct mlx4_dev *dev, u64 config, int port);
|
||||
|
||||
|
||||
int mlx4_mr_reserve_range(struct mlx4_dev *dev, int cnt, int align, u32 *base_mridx);
|
||||
void mlx4_mr_release_range(struct mlx4_dev *dev, u32 base_mridx, int cnt);
|
||||
|
Loading…
Reference in New Issue
Block a user