Skip to content

Commit

Permalink
net: atlantic: A2: report link partner capabilities
Browse files Browse the repository at this point in the history
This patch adds link partner capabilities reporting support on A2.
In particular, the following capabilities are available for reporting:
* link rate;
* EEE;
* flow control.

Signed-off-by: Dmitry Bogdanov <dbogdanov@marvell.com>
Signed-off-by: Mark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Dmitry Bogdanov authored and David S. Miller committed Jun 23, 2020
1 parent 3e168de commit 2b53b04
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/aquantia/atlantic/aq_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ struct aq_hw_caps_s {
struct aq_hw_link_status_s {
unsigned int mbps;
bool full_duplex;
u32 lp_link_speed_msk;
u32 lp_flow_control;
};

struct aq_stats_s {
Expand Down
49 changes: 49 additions & 0 deletions drivers/net/ethernet/aquantia/atlantic/aq_nic.c
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,8 @@ static void aq_nic_update_ndev_stats(struct aq_nic_s *self)
void aq_nic_get_link_ksettings(struct aq_nic_s *self,
struct ethtool_link_ksettings *cmd)
{
u32 lp_link_speed_msk;

if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE)
cmd->base.port = PORT_FIBRE;
else
Expand Down Expand Up @@ -1053,6 +1055,53 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
else
ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);

ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising);
lp_link_speed_msk = self->aq_hw->aq_link_status.lp_link_speed_msk;

if (lp_link_speed_msk & AQ_NIC_RATE_10G)
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
10000baseT_Full);

if (lp_link_speed_msk & AQ_NIC_RATE_5G)
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
5000baseT_Full);

if (lp_link_speed_msk & AQ_NIC_RATE_2G5)
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
2500baseT_Full);

if (lp_link_speed_msk & AQ_NIC_RATE_1G)
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
1000baseT_Full);

if (lp_link_speed_msk & AQ_NIC_RATE_1G_HALF)
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
1000baseT_Half);

if (lp_link_speed_msk & AQ_NIC_RATE_100M)
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
100baseT_Full);

if (lp_link_speed_msk & AQ_NIC_RATE_100M_HALF)
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
100baseT_Half);

if (lp_link_speed_msk & AQ_NIC_RATE_10M)
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
10baseT_Full);

if (lp_link_speed_msk & AQ_NIC_RATE_10M_HALF)
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
10baseT_Half);

if (self->aq_hw->aq_link_status.lp_flow_control & AQ_NIC_FC_RX)
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
Pause);
if (!!(self->aq_hw->aq_link_status.lp_flow_control & AQ_NIC_FC_TX) ^
!!(self->aq_hw->aq_link_status.lp_flow_control & AQ_NIC_FC_RX))
ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
Asym_Pause);
}

int aq_nic_set_link_ksettings(struct aq_nic_s *self,
Expand Down
30 changes: 30 additions & 0 deletions drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,27 @@ static u32 a2_fw_lkp_to_mask(struct lkp_link_caps_s *lkp_link_caps)
{
u32 rate = 0;

if (lkp_link_caps->rate_10G)
rate |= AQ_NIC_RATE_10G;
if (lkp_link_caps->rate_5G)
rate |= AQ_NIC_RATE_5G;
if (lkp_link_caps->rate_N5G)
rate |= AQ_NIC_RATE_5GSR;
if (lkp_link_caps->rate_2P5G)
rate |= AQ_NIC_RATE_2G5;
if (lkp_link_caps->rate_1G)
rate |= AQ_NIC_RATE_1G;
if (lkp_link_caps->rate_1G_hd)
rate |= AQ_NIC_RATE_1G_HALF;
if (lkp_link_caps->rate_100M)
rate |= AQ_NIC_RATE_100M;
if (lkp_link_caps->rate_100M_hd)
rate |= AQ_NIC_RATE_100M_HALF;
if (lkp_link_caps->rate_10M)
rate |= AQ_NIC_RATE_10M;
if (lkp_link_caps->rate_10M_hd)
rate |= AQ_NIC_RATE_10M_HALF;

if (lkp_link_caps->eee_10G)
rate |= AQ_NIC_RATE_EEE_10G;
if (lkp_link_caps->eee_5G)
Expand Down Expand Up @@ -240,6 +261,7 @@ static int aq_a2_fw_set_state(struct aq_hw_s *self,

static int aq_a2_fw_update_link_status(struct aq_hw_s *self)
{
struct lkp_link_caps_s lkp_link_caps;
struct link_status_s link_status;

hw_atl2_shared_buffer_read(self, link_status, link_status);
Expand Down Expand Up @@ -268,6 +290,14 @@ static int aq_a2_fw_update_link_status(struct aq_hw_s *self)
}
self->aq_link_status.full_duplex = link_status.duplex;

hw_atl2_shared_buffer_read(self, lkp_link_caps, lkp_link_caps);

self->aq_link_status.lp_link_speed_msk =
a2_fw_lkp_to_mask(&lkp_link_caps);
self->aq_link_status.lp_flow_control =
((lkp_link_caps.pause_rx) ? AQ_NIC_FC_RX : 0) |
((lkp_link_caps.pause_tx) ? AQ_NIC_FC_TX : 0);

return 0;
}

Expand Down

0 comments on commit 2b53b04

Please sign in to comment.