From owner-svn-src-all@FreeBSD.ORG Sat Mar 26 00:54:01 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 95EE0106564A; Sat, 26 Mar 2011 00:54:01 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 848798FC17; Sat, 26 Mar 2011 00:54:01 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p2Q0s15N098692; Sat, 26 Mar 2011 00:54:01 GMT (envelope-from jeff@svn.freebsd.org) Received: (from jeff@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p2Q0s1X7098684; Sat, 26 Mar 2011 00:54:01 GMT (envelope-from jeff@svn.freebsd.org) Message-Id: <201103260054.p2Q0s1X7098684@svn.freebsd.org> From: Jeff Roberson Date: Sat, 26 Mar 2011 00:54:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r220016 - in head/sys/ofed: drivers/net/mlx4 include/linux/mlx4 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 26 Mar 2011 00:54:01 -0000 Author: jeff Date: Sat Mar 26 00:54:01 2011 New Revision: 220016 URL: http://svn.freebsd.org/changeset/base/220016 Log: - Implement wake-on-lan support in mlxen. Modified: head/sys/ofed/drivers/net/mlx4/en_ethtool.c head/sys/ofed/drivers/net/mlx4/en_netdev.c head/sys/ofed/drivers/net/mlx4/fw.c head/sys/ofed/drivers/net/mlx4/fw.h head/sys/ofed/drivers/net/mlx4/main.c head/sys/ofed/drivers/net/mlx4/mlx4_en.h head/sys/ofed/include/linux/mlx4/device.h Modified: head/sys/ofed/drivers/net/mlx4/en_ethtool.c ============================================================================== --- head/sys/ofed/drivers/net/mlx4/en_ethtool.c Sat Mar 26 00:34:35 2011 (r220015) +++ head/sys/ofed/drivers/net/mlx4/en_ethtool.c Sat Mar 26 00:54:01 2011 (r220016) @@ -494,6 +494,7 @@ const struct ethtool_ops mlx4_en_ethtool .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, Modified: head/sys/ofed/drivers/net/mlx4/en_netdev.c ============================================================================== --- head/sys/ofed/drivers/net/mlx4/en_netdev.c Sat Mar 26 00:34:35 2011 (r220015) +++ head/sys/ofed/drivers/net/mlx4/en_netdev.c Sat Mar 26 00:54:01 2011 (r220016) @@ -532,6 +532,7 @@ int mlx4_en_start_port(struct net_device 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 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 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 *d 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_d 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, Modified: head/sys/ofed/drivers/net/mlx4/fw.c ============================================================================== --- head/sys/ofed/drivers/net/mlx4/fw.c Sat Mar 26 00:34:35 2011 (r220015) +++ head/sys/ofed/drivers/net/mlx4/fw.c Sat Mar 26 00:54:01 2011 (r220016) @@ -289,6 +289,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev * 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[]) { Modified: head/sys/ofed/drivers/net/mlx4/fw.h ============================================================================== --- head/sys/ofed/drivers/net/mlx4/fw.h Sat Mar 26 00:34:35 2011 (r220015) +++ head/sys/ofed/drivers/net/mlx4/fw.h Sat Mar 26 00:54:01 2011 (r220016) @@ -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; Modified: head/sys/ofed/drivers/net/mlx4/main.c ============================================================================== --- head/sys/ofed/drivers/net/mlx4/main.c Sat Mar 26 00:34:35 2011 (r220015) +++ head/sys/ofed/drivers/net/mlx4/main.c Sat Mar 26 00:54:01 2011 (r220016) @@ -331,6 +331,7 @@ static int mlx4_dev_cap(struct mlx4_dev 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; Modified: head/sys/ofed/drivers/net/mlx4/mlx4_en.h ============================================================================== --- head/sys/ofed/drivers/net/mlx4/mlx4_en.h Sat Mar 26 00:34:35 2011 (r220015) +++ head/sys/ofed/drivers/net/mlx4/mlx4_en.h Sat Mar 26 00:54:01 2011 (r220016) @@ -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); Modified: head/sys/ofed/include/linux/mlx4/device.h ============================================================================== --- head/sys/ofed/include/linux/mlx4/device.h Sat Mar 26 00:34:35 2011 (r220015) +++ head/sys/ofed/include/linux/mlx4/device.h Sat Mar 26 00:54:01 2011 (r220016) @@ -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, 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);