Index: ofed/drivers/net/mlx4/en_port.c =================================================================== --- ofed/drivers/net/mlx4/en_port.c (revision 233872) +++ ofed/drivers/net/mlx4/en_port.c (working copy) @@ -152,11 +152,21 @@ /* This command is always accessed from Ethtool context * already synchronized, no need in locking */ state->link_state = !!(qport_context->link_up & MLX4_EN_LINK_UP_MASK); - if ((qport_context->link_speed & MLX4_EN_SPEED_MASK) == - MLX4_EN_1G_SPEED) + switch (qport_context->link_speed & MLX4_EN_SPEED_MASK) { + case MLX4_EN_1G_SPEED: state->link_speed = 1000; - else + break; + case MLX4_EN_10G_SPEED_XAUI: + case MLX4_EN_10G_SPEED_XFI: state->link_speed = 10000; + break; + case MLX4_EN_40G_SPEED: + state->link_speed = 40000; + break; + default: + state->link_speed = -1; + break; + } state->transciver = qport_context->transceiver; if (be32_to_cpu(qport_context->transceiver_code_hi) & 0x400) state->transciver = 0x80; Index: ofed/drivers/net/mlx4/en_port.h =================================================================== --- ofed/drivers/net/mlx4/en_port.h (revision 233872) +++ ofed/drivers/net/mlx4/en_port.h (working copy) @@ -85,6 +85,14 @@ MLX4_MCAST_ENABLE = 2, }; +enum { + MLX4_EN_1G_SPEED = 0x02, + MLX4_EN_10G_SPEED_XFI = 0x01, + MLX4_EN_10G_SPEED_XAUI = 0x00, + MLX4_EN_40G_SPEED = 0x40, + MLX4_EN_OTHER_SPEED = 0x0f, +}; + struct mlx4_en_query_port_context { u8 link_up; #define MLX4_EN_LINK_UP_MASK 0x80 @@ -92,8 +100,7 @@ __be16 mtu; u8 reserved2; u8 link_speed; -#define MLX4_EN_SPEED_MASK 0x3 -#define MLX4_EN_1G_SPEED 0x2 +#define MLX4_EN_SPEED_MASK 0x43 u16 reserved3[5]; __be64 mac; u8 transceiver; Index: ofed/drivers/net/mlx4/en_netdev.c =================================================================== --- ofed/drivers/net/mlx4/en_netdev.c (revision 233872) +++ ofed/drivers/net/mlx4/en_netdev.c (working copy) @@ -991,12 +991,20 @@ active |= IFM_FDX; trans_type = priv->port_state.transciver; /* XXX I don't know all of the transceiver values. */ - if (priv->port_state.link_speed == 1000) + switch (priv->port_state.link_speed) { + case 1000: active |= IFM_1000_T; - else if (trans_type > 0 && trans_type <= 0xC) - active |= IFM_10G_SR; - else if (trans_type == 0x80 || trans_type == 0) - active |= IFM_10G_CX4; + break; + case 10000: + if (trans_type > 0 && trans_type <= 0xC) + active |= IFM_10G_SR; + else if (trans_type == 0x80 || trans_type == 0) + active |= IFM_10G_CX4; + break; + case 40000: + active |= IFM_40G; + break; + } if (priv->prof->tx_pause) active |= IFM_ETH_TXPAUSE; if (priv->prof->rx_pause) Index: net/if_media.h =================================================================== --- net/if_media.h (revision 233872) +++ net/if_media.h (working copy) @@ -150,6 +150,7 @@ #define IFM_10G_LRM 24 /* 10GBase-LRM 850nm Multi-mode */ #define IFM_UNKNOWN 25 /* media types not defined yet */ #define IFM_10G_T 26 /* 10GBase-T - RJ45 */ +#define IFM_40G 27 /* 40GBase */ /* note 31 is the max! */ @@ -360,6 +361,7 @@ { IFM_10G_TWINAX_LONG, "10Gbase-Twinax-Long" }, \ { IFM_UNKNOWN, "Unknown" }, \ { IFM_10G_T, "10Gbase-T" }, \ + { IFM_40G, "40Gbase" }, \ { 0, NULL }, \ } @@ -658,6 +660,7 @@ { IFM_ETHER | IFM_10G_TWINAX_LONG, IF_Gbps(10ULL) }, \ { IFM_ETHER | IFM_10G_LRM, IF_Gbps(10ULL) }, \ { IFM_ETHER | IFM_10G_T, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_40G, IF_Gbps(40ULL) }, \ \ { IFM_TOKEN | IFM_TOK_STP4, IF_Mbps(4) }, \ { IFM_TOKEN | IFM_TOK_STP16, IF_Mbps(16) }, \