Commit d00a50cf authored by David S. Miller's avatar David S. Miller

Merge branch 'atlantic-fixes'

Sudarsana Reddy Kalluru says:

====================
net: atlantic: 11-2021 fixes

The patch series contains fixes for atlantic driver to improve support
of latest AQC113 chipset.

Please consider applying it to 'net' tree.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2191b1df 060a0fb7
......@@ -40,10 +40,12 @@
#define AQ_DEVICE_ID_AQC113DEV 0x00C0
#define AQ_DEVICE_ID_AQC113CS 0x94C0
#define AQ_DEVICE_ID_AQC113CA 0x34C0
#define AQ_DEVICE_ID_AQC114CS 0x93C0
#define AQ_DEVICE_ID_AQC113 0x04C0
#define AQ_DEVICE_ID_AQC113C 0x14C0
#define AQ_DEVICE_ID_AQC115C 0x12C0
#define AQ_DEVICE_ID_AQC116C 0x11C0
#define HW_ATL_NIC_NAME "Marvell (aQuantia) AQtion 10Gbit Network Adapter"
......@@ -53,20 +55,19 @@
#define AQ_NIC_RATE_10G BIT(0)
#define AQ_NIC_RATE_5G BIT(1)
#define AQ_NIC_RATE_5GSR BIT(2)
#define AQ_NIC_RATE_2G5 BIT(3)
#define AQ_NIC_RATE_1G BIT(4)
#define AQ_NIC_RATE_100M BIT(5)
#define AQ_NIC_RATE_10M BIT(6)
#define AQ_NIC_RATE_1G_HALF BIT(7)
#define AQ_NIC_RATE_100M_HALF BIT(8)
#define AQ_NIC_RATE_10M_HALF BIT(9)
#define AQ_NIC_RATE_2G5 BIT(2)
#define AQ_NIC_RATE_1G BIT(3)
#define AQ_NIC_RATE_100M BIT(4)
#define AQ_NIC_RATE_10M BIT(5)
#define AQ_NIC_RATE_1G_HALF BIT(6)
#define AQ_NIC_RATE_100M_HALF BIT(7)
#define AQ_NIC_RATE_10M_HALF BIT(8)
#define AQ_NIC_RATE_EEE_10G BIT(10)
#define AQ_NIC_RATE_EEE_5G BIT(11)
#define AQ_NIC_RATE_EEE_2G5 BIT(12)
#define AQ_NIC_RATE_EEE_1G BIT(13)
#define AQ_NIC_RATE_EEE_100M BIT(14)
#define AQ_NIC_RATE_EEE_10G BIT(9)
#define AQ_NIC_RATE_EEE_5G BIT(10)
#define AQ_NIC_RATE_EEE_2G5 BIT(11)
#define AQ_NIC_RATE_EEE_1G BIT(12)
#define AQ_NIC_RATE_EEE_100M BIT(13)
#define AQ_NIC_RATE_EEE_MSK (AQ_NIC_RATE_EEE_10G |\
AQ_NIC_RATE_EEE_5G |\
AQ_NIC_RATE_EEE_2G5 |\
......
......@@ -80,6 +80,8 @@ struct aq_hw_link_status_s {
};
struct aq_stats_s {
u64 brc;
u64 btc;
u64 uprc;
u64 mprc;
u64 bprc;
......
......@@ -905,7 +905,13 @@ u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
data[++i] = stats->mbtc;
data[++i] = stats->bbrc;
data[++i] = stats->bbtc;
if (stats->brc)
data[++i] = stats->brc;
else
data[++i] = stats->ubrc + stats->mbrc + stats->bbrc;
if (stats->btc)
data[++i] = stats->btc;
else
data[++i] = stats->ubtc + stats->mbtc + stats->bbtc;
data[++i] = stats->dma_pkt_rc;
data[++i] = stats->dma_pkt_tc;
......
......@@ -49,6 +49,8 @@ static const struct pci_device_id aq_pci_tbl[] = {
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113), },
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113C), },
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC115C), },
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113CA), },
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC116C), },
{}
};
......@@ -85,7 +87,10 @@ static const struct aq_board_revision_s hw_atl_boards[] = {
{ AQ_DEVICE_ID_AQC113CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
{ AQ_DEVICE_ID_AQC114CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
{ AQ_DEVICE_ID_AQC113C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
{ AQ_DEVICE_ID_AQC115C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
{ AQ_DEVICE_ID_AQC115C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc115c, },
{ AQ_DEVICE_ID_AQC113CA, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, },
{ AQ_DEVICE_ID_AQC116C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc116c, },
};
MODULE_DEVICE_TABLE(pci, aq_pci_tbl);
......
......@@ -362,9 +362,6 @@ unsigned int aq_vec_get_sw_stats(struct aq_vec_s *self, const unsigned int tc, u
{
unsigned int count;
WARN_ONCE(!aq_vec_is_valid_tc(self, tc),
"Invalid tc %u (#rx=%u, #tx=%u)\n",
tc, self->rx_rings, self->tx_rings);
if (!aq_vec_is_valid_tc(self, tc))
return 0;
......
......@@ -867,12 +867,20 @@ static int hw_atl_fw1x_deinit(struct aq_hw_s *self)
int hw_atl_utils_update_stats(struct aq_hw_s *self)
{
struct aq_stats_s *cs = &self->curr_stats;
struct aq_stats_s curr_stats = *cs;
struct hw_atl_utils_mbox mbox;
bool corrupted_stats = false;
hw_atl_utils_mpi_read_stats(self, &mbox);
#define AQ_SDELTA(_N_) (self->curr_stats._N_ += \
mbox.stats._N_ - self->last_stats._N_)
#define AQ_SDELTA(_N_) \
do { \
if (!corrupted_stats && \
((s64)(mbox.stats._N_ - self->last_stats._N_)) >= 0) \
curr_stats._N_ += mbox.stats._N_ - self->last_stats._N_; \
else \
corrupted_stats = true; \
} while (0)
if (self->aq_link_status.mbps) {
AQ_SDELTA(uprc);
......@@ -892,6 +900,9 @@ int hw_atl_utils_update_stats(struct aq_hw_s *self)
AQ_SDELTA(bbrc);
AQ_SDELTA(bbtc);
AQ_SDELTA(dpc);
if (!corrupted_stats)
*cs = curr_stats;
}
#undef AQ_SDELTA
......
......@@ -132,9 +132,6 @@ static enum hw_atl_fw2x_rate link_speed_mask_2fw2x_ratemask(u32 speed)
if (speed & AQ_NIC_RATE_5G)
rate |= FW2X_RATE_5G;
if (speed & AQ_NIC_RATE_5GSR)
rate |= FW2X_RATE_5G;
if (speed & AQ_NIC_RATE_2G5)
rate |= FW2X_RATE_2G5;
......
......@@ -65,11 +65,25 @@ const struct aq_hw_caps_s hw_atl2_caps_aqc113 = {
AQ_NIC_RATE_5G |
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_1G_HALF |
AQ_NIC_RATE_100M |
AQ_NIC_RATE_100M_HALF |
AQ_NIC_RATE_10M |
AQ_NIC_RATE_10M_HALF,
AQ_NIC_RATE_10M,
};
const struct aq_hw_caps_s hw_atl2_caps_aqc115c = {
DEFAULT_BOARD_BASIC_CAPABILITIES,
.media_type = AQ_HW_MEDIA_TYPE_TP,
.link_speed_msk = AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M |
AQ_NIC_RATE_10M,
};
const struct aq_hw_caps_s hw_atl2_caps_aqc116c = {
DEFAULT_BOARD_BASIC_CAPABILITIES,
.media_type = AQ_HW_MEDIA_TYPE_TP,
.link_speed_msk = AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M |
AQ_NIC_RATE_10M,
};
static u32 hw_atl2_sem_act_rslvr_get(struct aq_hw_s *self)
......
......@@ -9,6 +9,8 @@
#include "aq_common.h"
extern const struct aq_hw_caps_s hw_atl2_caps_aqc113;
extern const struct aq_hw_caps_s hw_atl2_caps_aqc115c;
extern const struct aq_hw_caps_s hw_atl2_caps_aqc116c;
extern const struct aq_hw_ops hw_atl2_ops;
#endif /* HW_ATL2_H */
......@@ -239,7 +239,8 @@ struct version_s {
u8 minor;
u16 build;
} phy;
u32 rsvd;
u32 drv_iface_ver:4;
u32 rsvd:28;
};
struct link_status_s {
......@@ -424,7 +425,7 @@ struct cable_diag_status_s {
u16 rsvd2;
};
struct statistics_s {
struct statistics_a0_s {
struct {
u32 link_up;
u32 link_down;
......@@ -457,6 +458,33 @@ struct statistics_s {
u32 reserve_fw_gap;
};
struct __packed statistics_b0_s {
u64 rx_good_octets;
u64 rx_pause_frames;
u64 rx_good_frames;
u64 rx_errors;
u64 rx_unicast_frames;
u64 rx_multicast_frames;
u64 rx_broadcast_frames;
u64 tx_good_octets;
u64 tx_pause_frames;
u64 tx_good_frames;
u64 tx_errors;
u64 tx_unicast_frames;
u64 tx_multicast_frames;
u64 tx_broadcast_frames;
u32 main_loop_cycles;
};
struct __packed statistics_s {
union __packed {
struct statistics_a0_s a0;
struct statistics_b0_s b0;
};
};
struct filter_caps_s {
u8 l2_filters_base_index:6;
u8 flexible_filter_mask:2;
......@@ -545,7 +573,7 @@ struct management_status_s {
u32 rsvd5;
};
struct fw_interface_out {
struct __packed fw_interface_out {
struct transaction_counter_s transaction_id;
struct version_s version;
struct link_status_s link_status;
......@@ -569,7 +597,6 @@ struct fw_interface_out {
struct core_dump_s core_dump;
u32 rsvd11;
struct statistics_s stats;
u32 rsvd12;
struct filter_caps_s filter_caps;
struct device_caps_s device_caps;
u32 rsvd13;
......@@ -592,6 +619,9 @@ struct fw_interface_out {
#define AQ_HOST_MODE_LOW_POWER 3U
#define AQ_HOST_MODE_SHUTDOWN 4U
#define AQ_A2_FW_INTERFACE_A0 0
#define AQ_A2_FW_INTERFACE_B0 1
int hw_atl2_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops);
int hw_atl2_utils_soft_reset(struct aq_hw_s *self);
......
......@@ -84,7 +84,7 @@ static int hw_atl2_shared_buffer_read_block(struct aq_hw_s *self,
if (cnt > AQ_A2_FW_READ_TRY_MAX)
return -ETIME;
if (tid1.transaction_cnt_a != tid1.transaction_cnt_b)
udelay(1);
mdelay(1);
} while (tid1.transaction_cnt_a != tid1.transaction_cnt_b);
hw_atl2_mif_shared_buf_read(self, offset, (u32 *)data, dwords);
......@@ -154,7 +154,7 @@ static void a2_link_speed_mask2fw(u32 speed,
{
link_options->rate_10G = !!(speed & AQ_NIC_RATE_10G);
link_options->rate_5G = !!(speed & AQ_NIC_RATE_5G);
link_options->rate_N5G = !!(speed & AQ_NIC_RATE_5GSR);
link_options->rate_N5G = link_options->rate_5G;
link_options->rate_2P5G = !!(speed & AQ_NIC_RATE_2G5);
link_options->rate_N2P5G = link_options->rate_2P5G;
link_options->rate_1G = !!(speed & AQ_NIC_RATE_1G);
......@@ -192,8 +192,6 @@ static u32 a2_fw_lkp_to_mask(struct lkp_link_caps_s *lkp_link_caps)
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)
......@@ -335,15 +333,22 @@ static int aq_a2_fw_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
return 0;
}
static int aq_a2_fw_update_stats(struct aq_hw_s *self)
static void aq_a2_fill_a0_stats(struct aq_hw_s *self,
struct statistics_s *stats)
{
struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv;
struct statistics_s stats;
hw_atl2_shared_buffer_read_safe(self, stats, &stats);
#define AQ_SDELTA(_N_, _F_) (self->curr_stats._N_ += \
stats.msm._F_ - priv->last_stats.msm._F_)
struct aq_stats_s *cs = &self->curr_stats;
struct aq_stats_s curr_stats = *cs;
bool corrupted_stats = false;
#define AQ_SDELTA(_N, _F) \
do { \
if (!corrupted_stats && \
((s64)(stats->a0.msm._F - priv->last_stats.a0.msm._F)) >= 0) \
curr_stats._N += stats->a0.msm._F - priv->last_stats.a0.msm._F;\
else \
corrupted_stats = true; \
} while (0)
if (self->aq_link_status.mbps) {
AQ_SDELTA(uprc, rx_unicast_frames);
......@@ -362,17 +367,76 @@ static int aq_a2_fw_update_stats(struct aq_hw_s *self)
AQ_SDELTA(mbtc, tx_multicast_octets);
AQ_SDELTA(bbrc, rx_broadcast_octets);
AQ_SDELTA(bbtc, tx_broadcast_octets);
if (!corrupted_stats)
*cs = curr_stats;
}
#undef AQ_SDELTA
self->curr_stats.dma_pkt_rc =
hw_atl_stats_rx_dma_good_pkt_counter_get(self);
self->curr_stats.dma_pkt_tc =
hw_atl_stats_tx_dma_good_pkt_counter_get(self);
self->curr_stats.dma_oct_rc =
hw_atl_stats_rx_dma_good_octet_counter_get(self);
self->curr_stats.dma_oct_tc =
hw_atl_stats_tx_dma_good_octet_counter_get(self);
self->curr_stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self);
}
static void aq_a2_fill_b0_stats(struct aq_hw_s *self,
struct statistics_s *stats)
{
struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv;
struct aq_stats_s *cs = &self->curr_stats;
struct aq_stats_s curr_stats = *cs;
bool corrupted_stats = false;
#define AQ_SDELTA(_N, _F) \
do { \
if (!corrupted_stats && \
((s64)(stats->b0._F - priv->last_stats.b0._F)) >= 0) \
curr_stats._N += stats->b0._F - priv->last_stats.b0._F; \
else \
corrupted_stats = true; \
} while (0)
if (self->aq_link_status.mbps) {
AQ_SDELTA(uprc, rx_unicast_frames);
AQ_SDELTA(mprc, rx_multicast_frames);
AQ_SDELTA(bprc, rx_broadcast_frames);
AQ_SDELTA(erpr, rx_errors);
AQ_SDELTA(brc, rx_good_octets);
AQ_SDELTA(uptc, tx_unicast_frames);
AQ_SDELTA(mptc, tx_multicast_frames);
AQ_SDELTA(bptc, tx_broadcast_frames);
AQ_SDELTA(erpt, tx_errors);
AQ_SDELTA(btc, tx_good_octets);
if (!corrupted_stats)
*cs = curr_stats;
}
#undef AQ_SDELTA
}
static int aq_a2_fw_update_stats(struct aq_hw_s *self)
{
struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv;
struct aq_stats_s *cs = &self->curr_stats;
struct statistics_s stats;
struct version_s version;
int err;
err = hw_atl2_shared_buffer_read_safe(self, version, &version);
if (err)
return err;
err = hw_atl2_shared_buffer_read_safe(self, stats, &stats);
if (err)
return err;
if (version.drv_iface_ver == AQ_A2_FW_INTERFACE_A0)
aq_a2_fill_a0_stats(self, &stats);
else
aq_a2_fill_b0_stats(self, &stats);
cs->dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counter_get(self);
cs->dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counter_get(self);
cs->dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counter_get(self);
cs->dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counter_get(self);
cs->dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self);
memcpy(&priv->last_stats, &stats, sizeof(stats));
......@@ -499,9 +563,9 @@ u32 hw_atl2_utils_get_fw_version(struct aq_hw_s *self)
hw_atl2_shared_buffer_read_safe(self, version, &version);
/* A2 FW version is stored in reverse order */
return version.mac.major << 24 |
version.mac.minor << 16 |
version.mac.build;
return version.bundle.major << 24 |
version.bundle.minor << 16 |
version.bundle.build;
}
int hw_atl2_utils_get_action_resolve_table_caps(struct aq_hw_s *self,
......
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