Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,981 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Atlantic Network Driver
*
* Copyright (C) 2014-2019 aQuantia Corporation
* Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File hw_atl_a0.c: Definition of Atlantic hardware specific functions. */
#include "../aq_hw.h"
#include "../aq_hw_utils.h"
#include "../aq_ring.h"
#include "../aq_nic.h"
#include "hw_atl_a0.h"
#include "hw_atl_utils.h"
#include "hw_atl_llh.h"
#include "hw_atl_a0_internal.h"
#define DEFAULT_A0_BOARD_BASIC_CAPABILITIES \
.is_64_dma = true, \
.op64bit = false, \
.msix_irqs = 4U, \
.irq_mask = ~0U, \
.vecs = HW_ATL_A0_RSS_MAX, \
.tcs_max = HW_ATL_A0_TC_MAX, \
.rxd_alignment = 1U, \
.rxd_size = HW_ATL_A0_RXD_SIZE, \
.rxds_max = HW_ATL_A0_MAX_RXD, \
.rxds_min = HW_ATL_A0_MIN_RXD, \
.txd_alignment = 1U, \
.txd_size = HW_ATL_A0_TXD_SIZE, \
.txds_max = HW_ATL_A0_MAX_TXD, \
.txds_min = HW_ATL_A0_MIN_RXD, \
.txhwb_alignment = 4096U, \
.tx_rings = HW_ATL_A0_TX_RINGS, \
.rx_rings = HW_ATL_A0_RX_RINGS, \
.hw_features = NETIF_F_HW_CSUM | \
NETIF_F_RXHASH | \
NETIF_F_RXCSUM | \
NETIF_F_SG | \
NETIF_F_TSO | \
NETIF_F_NTUPLE | \
NETIF_F_HW_VLAN_CTAG_FILTER, \
.hw_priv_flags = IFF_UNICAST_FLT, \
.flow_control = true, \
.mtu = HW_ATL_A0_MTU_JUMBO, \
.mac_regs_count = 88, \
.hw_alive_check_addr = 0x10U
const struct aq_hw_caps_s hw_atl_a0_caps_aqc100 = {
DEFAULT_A0_BOARD_BASIC_CAPABILITIES,
.media_type = AQ_HW_MEDIA_TYPE_FIBRE,
.link_speed_msk = AQ_NIC_RATE_5G |
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
};
const struct aq_hw_caps_s hw_atl_a0_caps_aqc107 = {
DEFAULT_A0_BOARD_BASIC_CAPABILITIES,
.media_type = AQ_HW_MEDIA_TYPE_TP,
.link_speed_msk = AQ_NIC_RATE_10G |
AQ_NIC_RATE_5G |
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
};
const struct aq_hw_caps_s hw_atl_a0_caps_aqc108 = {
DEFAULT_A0_BOARD_BASIC_CAPABILITIES,
.media_type = AQ_HW_MEDIA_TYPE_TP,
.link_speed_msk = AQ_NIC_RATE_5G |
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
};
const struct aq_hw_caps_s hw_atl_a0_caps_aqc109 = {
DEFAULT_A0_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,
};
static int hw_atl_a0_hw_reset(struct aq_hw_s *self)
{
int err = 0;
u32 val;
hw_atl_glb_glb_reg_res_dis_set(self, 1U);
hw_atl_pci_pci_reg_res_dis_set(self, 0U);
hw_atl_rx_rx_reg_res_dis_set(self, 0U);
hw_atl_tx_tx_reg_res_dis_set(self, 0U);
HW_ATL_FLUSH();
hw_atl_glb_soft_res_set(self, 1);
/* check 10 times by 1ms */
err = readx_poll_timeout_atomic(hw_atl_glb_soft_res_get,
self, val, val == 0,
1000U, 10000U);
if (err < 0)
goto err_exit;
hw_atl_itr_irq_reg_res_dis_set(self, 0U);
hw_atl_itr_res_irq_set(self, 1U);
/* check 10 times by 1ms */
err = readx_poll_timeout_atomic(hw_atl_itr_res_irq_get,
self, val, val == 0,
1000U, 10000U);
if (err < 0)
goto err_exit;
self->aq_fw_ops->set_state(self, MPI_RESET);
err = aq_hw_err_from_flags(self);
err_exit:
return err;
}
static int hw_atl_a0_hw_qos_set(struct aq_hw_s *self)
{
bool is_rx_flow_control = false;
unsigned int i_priority = 0U;
u32 buff_size = 0U;
u32 tc = 0U;
/* TPS Descriptor rate init */
hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U);
hw_atl_tps_tx_pkt_shed_desc_rate_lim_set(self, 0xA);
/* TPS VM init */
hw_atl_tps_tx_pkt_shed_desc_vm_arb_mode_set(self, 0U);
/* TPS TC credits init */
hw_atl_tps_tx_pkt_shed_desc_tc_arb_mode_set(self, 0U);
hw_atl_tps_tx_pkt_shed_data_arb_mode_set(self, 0U);
hw_atl_tps_tx_pkt_shed_tc_data_max_credit_set(self, 0U, 0xFFF);
hw_atl_tps_tx_pkt_shed_tc_data_weight_set(self, 0U, 0x64);
hw_atl_tps_tx_pkt_shed_desc_tc_max_credit_set(self, 0U, 0x50);
hw_atl_tps_tx_pkt_shed_desc_tc_weight_set(self, 0U, 0x1E);
/* Tx buf size */
buff_size = HW_ATL_A0_TXBUF_MAX;
hw_atl_tpb_tx_pkt_buff_size_per_tc_set(self, buff_size, tc);
hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(self,
(buff_size *
(1024 / 32U) * 66U) /
100U, tc);
hw_atl_tpb_tx_buff_lo_threshold_per_tc_set(self,
(buff_size *
(1024 / 32U) * 50U) /
100U, tc);
/* QoS Rx buf size per TC */
tc = 0;
is_rx_flow_control = (AQ_NIC_FC_RX & self->aq_nic_cfg->fc.req);
buff_size = HW_ATL_A0_RXBUF_MAX;
hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc);
hw_atl_rpb_rx_buff_hi_threshold_per_tc_set(self,
(buff_size *
(1024U / 32U) * 66U) /
100U, tc);
hw_atl_rpb_rx_buff_lo_threshold_per_tc_set(self,
(buff_size *
(1024U / 32U) * 50U) /
100U, tc);
hw_atl_rpb_rx_xoff_en_per_tc_set(self, is_rx_flow_control ? 1U : 0U, tc);
/* QoS 802.1p priority -> TC mapping */
for (i_priority = 8U; i_priority--;)
hw_atl_rpf_rpb_user_priority_tc_map_set(self, i_priority, 0U);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_rss_hash_set(struct aq_hw_s *self,
struct aq_rss_parameters *rss_params)
{
struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
unsigned int addr = 0U;
unsigned int i = 0U;
int err = 0;
u32 val;
for (i = 10, addr = 0U; i--; ++addr) {
u32 key_data = cfg->is_rss ?
__swab32(rss_params->hash_secret_key[i]) : 0U;
hw_atl_rpf_rss_key_wr_data_set(self, key_data);
hw_atl_rpf_rss_key_addr_set(self, addr);
hw_atl_rpf_rss_key_wr_en_set(self, 1U);
err = readx_poll_timeout_atomic(hw_atl_rpf_rss_key_wr_en_get,
self, val, val == 0,
1000U, 10000U);
if (err < 0)
goto err_exit;
}
err = aq_hw_err_from_flags(self);
err_exit:
return err;
}
static int hw_atl_a0_hw_rss_set(struct aq_hw_s *self,
struct aq_rss_parameters *rss_params)
{
u32 num_rss_queues = max(1U, self->aq_nic_cfg->num_rss_queues);
u8 *indirection_table = rss_params->indirection_table;
u16 bitary[1 + (HW_ATL_A0_RSS_REDIRECTION_MAX *
HW_ATL_A0_RSS_REDIRECTION_BITS / 16U)];
int err = 0;
u32 i = 0U;
u32 val;
memset(bitary, 0, sizeof(bitary));
for (i = HW_ATL_A0_RSS_REDIRECTION_MAX; i--; ) {
(*(u32 *)(bitary + ((i * 3U) / 16U))) |=
((indirection_table[i] % num_rss_queues) <<
((i * 3U) & 0xFU));
}
for (i = ARRAY_SIZE(bitary); i--;) {
hw_atl_rpf_rss_redir_tbl_wr_data_set(self, bitary[i]);
hw_atl_rpf_rss_redir_tbl_addr_set(self, i);
hw_atl_rpf_rss_redir_wr_en_set(self, 1U);
err = readx_poll_timeout_atomic(hw_atl_rpf_rss_redir_wr_en_get,
self, val, val == 0,
1000U, 10000U);
if (err < 0)
goto err_exit;
}
err = aq_hw_err_from_flags(self);
err_exit:
return err;
}
static int hw_atl_a0_hw_offload_set(struct aq_hw_s *self,
struct aq_nic_cfg_s *aq_nic_cfg)
{
/* TX checksums offloads*/
hw_atl_tpo_ipv4header_crc_offload_en_set(self, 1);
hw_atl_tpo_tcp_udp_crc_offload_en_set(self, 1);
/* RX checksums offloads*/
hw_atl_rpo_ipv4header_crc_offload_en_set(self, 1);
hw_atl_rpo_tcp_udp_crc_offload_en_set(self, 1);
/* LSO offloads*/
hw_atl_tdm_large_send_offload_en_set(self, 0xFFFFFFFFU);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_init_tx_path(struct aq_hw_s *self)
{
hw_atl_thm_lso_tcp_flag_of_first_pkt_set(self, 0x0FF6U);
hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(self, 0x0FF6U);
hw_atl_thm_lso_tcp_flag_of_last_pkt_set(self, 0x0F7FU);
/* Tx interrupts */
hw_atl_tdm_tx_desc_wr_wb_irq_en_set(self, 1U);
/* misc */
aq_hw_write_reg(self, 0x00007040U, 0x00000000U);
hw_atl_tdm_tx_dca_en_set(self, 0U);
hw_atl_tdm_tx_dca_mode_set(self, 0U);
hw_atl_tpb_tx_path_scp_ins_en_set(self, 1U);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_init_rx_path(struct aq_hw_s *self)
{
struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
int i;
/* Rx TC/RSS number config */
hw_atl_rpb_rpf_rx_traf_class_mode_set(self, 1U);
/* Rx flow control */
hw_atl_rpb_rx_flow_ctl_mode_set(self, 1U);
/* RSS Ring selection */
hw_atl_reg_rx_flr_rss_control1set(self, cfg->is_rss ?
0xB3333333U : 0x00000000U);
/* Multicast filters */
for (i = HW_ATL_A0_MAC_MAX; i--;) {
hw_atl_rpfl2_uc_flr_en_set(self, (i == 0U) ? 1U : 0U, i);
hw_atl_rpfl2unicast_flr_act_set(self, 1U, i);
}
hw_atl_reg_rx_flr_mcst_flr_msk_set(self, 0x00000000U);
hw_atl_reg_rx_flr_mcst_flr_set(self, 0x00010FFFU, 0U);
/* Vlan filters */
hw_atl_rpf_vlan_outer_etht_set(self, 0x88A8U);
hw_atl_rpf_vlan_inner_etht_set(self, 0x8100U);
hw_atl_rpf_vlan_prom_mode_en_set(self, 1);
/* Rx Interrupts */
hw_atl_rdm_rx_desc_wr_wb_irq_en_set(self, 1U);
/* misc */
hw_atl_rpfl2broadcast_flr_act_set(self, 1U);
hw_atl_rpfl2broadcast_count_threshold_set(self, 0xFFFFU & (~0U / 256U));
hw_atl_rdm_rx_dca_en_set(self, 0U);
hw_atl_rdm_rx_dca_mode_set(self, 0U);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_mac_addr_set(struct aq_hw_s *self, const u8 *mac_addr)
{
unsigned int h = 0U;
unsigned int l = 0U;
int err = 0;
if (!mac_addr) {
err = -EINVAL;
goto err_exit;
}
h = (mac_addr[0] << 8) | (mac_addr[1]);
l = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
(mac_addr[4] << 8) | mac_addr[5];
hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL_A0_MAC);
hw_atl_rpfl2unicast_dest_addresslsw_set(self, l, HW_ATL_A0_MAC);
hw_atl_rpfl2unicast_dest_addressmsw_set(self, h, HW_ATL_A0_MAC);
hw_atl_rpfl2_uc_flr_en_set(self, 1U, HW_ATL_A0_MAC);
err = aq_hw_err_from_flags(self);
err_exit:
return err;
}
static int hw_atl_a0_hw_init(struct aq_hw_s *self, const u8 *mac_addr)
{
static u32 aq_hw_atl_igcr_table_[4][2] = {
[AQ_HW_IRQ_INVALID] = { 0x20000000U, 0x20000000U },
[AQ_HW_IRQ_INTX] = { 0x20000080U, 0x20000080U },
[AQ_HW_IRQ_MSI] = { 0x20000021U, 0x20000025U },
[AQ_HW_IRQ_MSIX] = { 0x20000022U, 0x20000026U },
};
struct aq_nic_cfg_s *aq_nic_cfg = self->aq_nic_cfg;
int err = 0;
hw_atl_a0_hw_init_tx_path(self);
hw_atl_a0_hw_init_rx_path(self);
hw_atl_a0_hw_mac_addr_set(self, mac_addr);
self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk);
self->aq_fw_ops->set_state(self, MPI_INIT);
hw_atl_reg_tx_dma_debug_ctl_set(self, 0x800000b8U);
hw_atl_reg_tx_dma_debug_ctl_set(self, 0x000000b8U);
hw_atl_a0_hw_qos_set(self);
hw_atl_a0_hw_rss_set(self, &aq_nic_cfg->aq_rss);
hw_atl_a0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss);
/* Reset link status and read out initial hardware counters */
self->aq_link_status.mbps = 0;
self->aq_fw_ops->update_stats(self);
err = aq_hw_err_from_flags(self);
if (err < 0)
goto err_exit;
/* Interrupts */
hw_atl_reg_irq_glb_ctl_set(self,
aq_hw_atl_igcr_table_[aq_nic_cfg->irq_type]
[(aq_nic_cfg->vecs > 1U) ? 1 : 0]);
hw_atl_itr_irq_auto_masklsw_set(self, aq_nic_cfg->aq_hw_caps->irq_mask);
/* Interrupts */
hw_atl_reg_gen_irq_map_set(self,
((HW_ATL_A0_ERR_INT << 0x18) | (1U << 0x1F)) |
((HW_ATL_A0_ERR_INT << 0x10) | (1U << 0x17)) |
((HW_ATL_A0_ERR_INT << 8) | (1U << 0xF)) |
((HW_ATL_A0_ERR_INT) | (1U << 0x7)), 0U);
hw_atl_a0_hw_offload_set(self, aq_nic_cfg);
err_exit:
return err;
}
static int hw_atl_a0_hw_ring_tx_start(struct aq_hw_s *self,
struct aq_ring_s *ring)
{
hw_atl_tdm_tx_desc_en_set(self, 1, ring->idx);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_ring_rx_start(struct aq_hw_s *self,
struct aq_ring_s *ring)
{
hw_atl_rdm_rx_desc_en_set(self, 1, ring->idx);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_start(struct aq_hw_s *self)
{
hw_atl_tpb_tx_buff_en_set(self, 1);
hw_atl_rpb_rx_buff_en_set(self, 1);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_tx_ring_tail_update(struct aq_hw_s *self,
struct aq_ring_s *ring)
{
hw_atl_reg_tx_dma_desc_tail_ptr_set(self, ring->sw_tail, ring->idx);
return 0;
}
static int hw_atl_a0_hw_ring_tx_xmit(struct aq_hw_s *self,
struct aq_ring_s *ring,
unsigned int frags)
{
struct aq_ring_buff_s *buff = NULL;
struct hw_atl_txd_s *txd = NULL;
unsigned int buff_pa_len = 0U;
unsigned int frag_count = 0U;
unsigned int pkt_len = 0U;
bool is_gso = false;
buff = &ring->buff_ring[ring->sw_tail];
pkt_len = (buff->is_eop && buff->is_sop) ? buff->len : buff->len_pkt;
for (frag_count = 0; frag_count < frags; frag_count++) {
txd = (struct hw_atl_txd_s *)&ring->dx_ring[ring->sw_tail *
HW_ATL_A0_TXD_SIZE];
txd->ctl = 0;
txd->ctl2 = 0;
txd->buf_addr = 0;
buff = &ring->buff_ring[ring->sw_tail];
if (buff->is_gso_tcp) {
txd->ctl |= (buff->len_l3 << 31) |
(buff->len_l2 << 24) |
HW_ATL_A0_TXD_CTL_CMD_TCP |
HW_ATL_A0_TXD_CTL_DESC_TYPE_TXC;
txd->ctl2 |= (buff->mss << 16) |
(buff->len_l4 << 8) |
(buff->len_l3 >> 1);
pkt_len -= (buff->len_l4 +
buff->len_l3 +
buff->len_l2);
is_gso = true;
if (buff->is_ipv6)
txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_IPV6;
} else {
buff_pa_len = buff->len;
txd->buf_addr = buff->pa;
txd->ctl |= (HW_ATL_A0_TXD_CTL_BLEN &
((u32)buff_pa_len << 4));
txd->ctl |= HW_ATL_A0_TXD_CTL_DESC_TYPE_TXD;
/* PAY_LEN */
txd->ctl2 |= HW_ATL_A0_TXD_CTL2_LEN & (pkt_len << 14);
if (is_gso) {
txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_LSO;
txd->ctl2 |= HW_ATL_A0_TXD_CTL2_CTX_EN;
}
/* Tx checksum offloads */
if (buff->is_ip_cso)
txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_IPCSO;
if (buff->is_udp_cso || buff->is_tcp_cso)
txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_TUCSO;
if (unlikely(buff->is_eop)) {
txd->ctl |= HW_ATL_A0_TXD_CTL_EOP;
txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_WB;
is_gso = false;
}
}
ring->sw_tail = aq_ring_next_dx(ring, ring->sw_tail);
}
hw_atl_a0_hw_tx_ring_tail_update(self, ring);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_ring_rx_init(struct aq_hw_s *self,
struct aq_ring_s *aq_ring,
struct aq_ring_param_s *aq_ring_param)
{
u32 dma_desc_addr_msw = (u32)(((u64)aq_ring->dx_ring_pa) >> 32);
u32 dma_desc_addr_lsw = (u32)aq_ring->dx_ring_pa;
hw_atl_rdm_rx_desc_en_set(self, false, aq_ring->idx);
hw_atl_rdm_rx_desc_head_splitting_set(self, 0U, aq_ring->idx);
hw_atl_reg_rx_dma_desc_base_addresslswset(self, dma_desc_addr_lsw,
aq_ring->idx);
hw_atl_reg_rx_dma_desc_base_addressmswset(self,
dma_desc_addr_msw,
aq_ring->idx);
hw_atl_rdm_rx_desc_len_set(self, aq_ring->size / 8U, aq_ring->idx);
hw_atl_rdm_rx_desc_data_buff_size_set(self,
aq_ring->frame_max / 1024U,
aq_ring->idx);
hw_atl_rdm_rx_desc_head_buff_size_set(self, 0U, aq_ring->idx);
hw_atl_rdm_rx_desc_head_splitting_set(self, 0U, aq_ring->idx);
hw_atl_rpo_rx_desc_vlan_stripping_set(self, 0U, aq_ring->idx);
/* Rx ring set mode */
/* Mapping interrupt vector */
hw_atl_itr_irq_map_rx_set(self, aq_ring_param->vec_idx, aq_ring->idx);
hw_atl_itr_irq_map_en_rx_set(self, true, aq_ring->idx);
hw_atl_rdm_cpu_id_set(self, aq_ring_param->cpu, aq_ring->idx);
hw_atl_rdm_rx_desc_dca_en_set(self, 0U, aq_ring->idx);
hw_atl_rdm_rx_head_dca_en_set(self, 0U, aq_ring->idx);
hw_atl_rdm_rx_pld_dca_en_set(self, 0U, aq_ring->idx);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_ring_tx_init(struct aq_hw_s *self,
struct aq_ring_s *aq_ring,
struct aq_ring_param_s *aq_ring_param)
{
u32 dma_desc_msw_addr = (u32)(((u64)aq_ring->dx_ring_pa) >> 32);
u32 dma_desc_lsw_addr = (u32)aq_ring->dx_ring_pa;
hw_atl_reg_tx_dma_desc_base_addresslswset(self, dma_desc_lsw_addr,
aq_ring->idx);
hw_atl_reg_tx_dma_desc_base_addressmswset(self, dma_desc_msw_addr,
aq_ring->idx);
hw_atl_tdm_tx_desc_len_set(self, aq_ring->size / 8U, aq_ring->idx);
hw_atl_a0_hw_tx_ring_tail_update(self, aq_ring);
/* Set Tx threshold */
hw_atl_tdm_tx_desc_wr_wb_threshold_set(self, 0U, aq_ring->idx);
/* Mapping interrupt vector */
hw_atl_itr_irq_map_tx_set(self, aq_ring_param->vec_idx, aq_ring->idx);
hw_atl_itr_irq_map_en_tx_set(self, true, aq_ring->idx);
hw_atl_tdm_cpu_id_set(self, aq_ring_param->cpu, aq_ring->idx);
hw_atl_tdm_tx_desc_dca_en_set(self, 0U, aq_ring->idx);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_ring_rx_fill(struct aq_hw_s *self,
struct aq_ring_s *ring,
unsigned int sw_tail_old)
{
for (; sw_tail_old != ring->sw_tail;
sw_tail_old = aq_ring_next_dx(ring, sw_tail_old)) {
struct hw_atl_rxd_s *rxd =
(struct hw_atl_rxd_s *)&ring->dx_ring[sw_tail_old *
HW_ATL_A0_RXD_SIZE];
struct aq_ring_buff_s *buff = &ring->buff_ring[sw_tail_old];
rxd->buf_addr = buff->pa;
rxd->hdr_addr = 0U;
}
hw_atl_reg_rx_dma_desc_tail_ptr_set(self, sw_tail_old, ring->idx);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_ring_tx_head_update(struct aq_hw_s *self,
struct aq_ring_s *ring)
{
unsigned int hw_head = hw_atl_tdm_tx_desc_head_ptr_get(self, ring->idx);
int err = 0;
if (aq_utils_obj_test(&self->flags, AQ_HW_FLAG_ERR_UNPLUG)) {
err = -ENXIO;
goto err_exit;
}
ring->hw_head = hw_head;
err = aq_hw_err_from_flags(self);
err_exit:
return err;
}
static int hw_atl_a0_hw_ring_rx_receive(struct aq_hw_s *self,
struct aq_ring_s *ring)
{
for (; ring->hw_head != ring->sw_tail;
ring->hw_head = aq_ring_next_dx(ring, ring->hw_head)) {
struct aq_ring_buff_s *buff = NULL;
struct hw_atl_rxd_wb_s *rxd_wb = (struct hw_atl_rxd_wb_s *)
&ring->dx_ring[ring->hw_head * HW_ATL_A0_RXD_SIZE];
unsigned int is_err = 1U;
unsigned int is_rx_check_sum_enabled = 0U;
unsigned int pkt_type = 0U;
if (!(rxd_wb->status & 0x5U)) { /* RxD is not done */
if ((1U << 4) &
hw_atl_reg_rx_dma_desc_status_get(self, ring->idx)) {
hw_atl_rdm_rx_desc_en_set(self, false, ring->idx);
hw_atl_rdm_rx_desc_res_set(self, true, ring->idx);
hw_atl_rdm_rx_desc_res_set(self, false, ring->idx);
hw_atl_rdm_rx_desc_en_set(self, true, ring->idx);
}
if (ring->hw_head ||
(hw_atl_rdm_rx_desc_head_ptr_get(self,
ring->idx) < 2U)) {
break;
} else if (!(rxd_wb->status & 0x1U)) {
struct hw_atl_rxd_wb_s *rxd_wb1 =
(struct hw_atl_rxd_wb_s *)
(&ring->dx_ring[(1U) *
HW_ATL_A0_RXD_SIZE]);
if ((rxd_wb1->status & 0x1U)) {
rxd_wb->pkt_len = 1514U;
rxd_wb->status = 3U;
} else {
break;
}
}
}
buff = &ring->buff_ring[ring->hw_head];
if (0x3U != (rxd_wb->status & 0x3U))
rxd_wb->status |= 4;
is_err = (0x0000001CU & rxd_wb->status);
is_rx_check_sum_enabled = (rxd_wb->type) & (0x3U << 19);
pkt_type = 0xFFU & (rxd_wb->type >> 4);
if (is_rx_check_sum_enabled) {
if (0x0U == (pkt_type & 0x3U))
buff->is_ip_cso = (is_err & 0x08U) ? 0 : 1;
if (0x4U == (pkt_type & 0x1CU))
buff->is_udp_cso = (is_err & 0x10U) ? 0 : 1;
else if (0x0U == (pkt_type & 0x1CU))
buff->is_tcp_cso = (is_err & 0x10U) ? 0 : 1;
/* Checksum offload workaround for small packets */
if (rxd_wb->pkt_len <= 60) {
buff->is_ip_cso = 0U;
buff->is_cso_err = 0U;
}
}
is_err &= ~0x18U;
is_err &= ~0x04U;
if (is_err || rxd_wb->type & 0x1000U) {
/* status error or DMA error */
buff->is_error = 1U;
} else {
if (self->aq_nic_cfg->is_rss) {
/* last 4 byte */
u16 rss_type = rxd_wb->type & 0xFU;
if (rss_type && rss_type < 0x8U) {
buff->is_hash_l4 = (rss_type == 0x4 ||
rss_type == 0x5);
buff->rss_hash = rxd_wb->rss_hash;
}
}
if (HW_ATL_A0_RXD_WB_STAT2_EOP & rxd_wb->status) {
buff->len = rxd_wb->pkt_len %
ring->frame_max;
buff->len = buff->len ?
buff->len : ring->frame_max;
buff->next = 0U;
buff->is_eop = 1U;
} else {
/* jumbo */
buff->next = aq_ring_next_dx(ring,
ring->hw_head);
++ring->stats.rx.jumbo_packets;
}
}
}
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_irq_enable(struct aq_hw_s *self, u64 mask)
{
hw_atl_itr_irq_msk_setlsw_set(self, LODWORD(mask) |
(1U << HW_ATL_A0_ERR_INT));
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_irq_disable(struct aq_hw_s *self, u64 mask)
{
hw_atl_itr_irq_msk_clearlsw_set(self, LODWORD(mask));
hw_atl_itr_irq_status_clearlsw_set(self, LODWORD(mask));
if ((1U << 16) & hw_atl_reg_gen_irq_status_get(self))
atomic_inc(&self->dpc);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_irq_read(struct aq_hw_s *self, u64 *mask)
{
*mask = hw_atl_itr_irq_statuslsw_get(self);
return aq_hw_err_from_flags(self);
}
#define IS_FILTER_ENABLED(_F_) ((packet_filter & (_F_)) ? 1U : 0U)
static int hw_atl_a0_hw_packet_filter_set(struct aq_hw_s *self,
unsigned int packet_filter)
{
struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
unsigned int i = 0U;
hw_atl_rpfl2promiscuous_mode_en_set(self,
IS_FILTER_ENABLED(IFF_PROMISC));
hw_atl_rpfl2multicast_flr_en_set(self,
IS_FILTER_ENABLED(IFF_MULTICAST), 0);
hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST));
cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST);
for (i = HW_ATL_A0_MAC_MIN; i < HW_ATL_A0_MAC_MAX; ++i)
hw_atl_rpfl2_uc_flr_en_set(self,
(cfg->is_mc_list_enabled &&
(i <= cfg->mc_list_count)) ? 1U : 0U,
i);
return aq_hw_err_from_flags(self);
}
#undef IS_FILTER_ENABLED
static int hw_atl_a0_hw_multicast_list_set(struct aq_hw_s *self,
u8 ar_mac
[AQ_HW_MULTICAST_ADDRESS_MAX]
[ETH_ALEN],
u32 count)
{
struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
int err = 0;
if (count > (HW_ATL_A0_MAC_MAX - HW_ATL_A0_MAC_MIN)) {
err = -EBADRQC;
goto err_exit;
}
for (cfg->mc_list_count = 0U; cfg->mc_list_count < count; ++cfg->mc_list_count) {
u32 i = cfg->mc_list_count;
u32 h = (ar_mac[i][0] << 8) | (ar_mac[i][1]);
u32 l = (ar_mac[i][2] << 24) | (ar_mac[i][3] << 16) |
(ar_mac[i][4] << 8) | ar_mac[i][5];
hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL_A0_MAC_MIN + i);
hw_atl_rpfl2unicast_dest_addresslsw_set(self,
l,
HW_ATL_A0_MAC_MIN + i);
hw_atl_rpfl2unicast_dest_addressmsw_set(self,
h,
HW_ATL_A0_MAC_MIN + i);
hw_atl_rpfl2_uc_flr_en_set(self,
(cfg->is_mc_list_enabled),
HW_ATL_A0_MAC_MIN + i);
}
err = aq_hw_err_from_flags(self);
err_exit:
return err;
}
static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self)
{
unsigned int i = 0U;
u32 itr_rx;
if (self->aq_nic_cfg->itr) {
if (self->aq_nic_cfg->itr != AQ_CFG_INTERRUPT_MODERATION_AUTO) {
u32 itr_ = (self->aq_nic_cfg->itr >> 1);
itr_ = min(AQ_CFG_IRQ_MASK, itr_);
itr_rx = 0x80000000U | (itr_ << 0x10);
} else {
u32 n = 0xFFFFU & aq_hw_read_reg(self, 0x00002A00U);
if (n < self->aq_link_status.mbps) {
itr_rx = 0U;
} else {
static unsigned int hw_timers_tbl_[] = {
0x01CU, /* 10Gbit */
0x039U, /* 5Gbit */
0x039U, /* 5Gbit 5GS */
0x073U, /* 2.5Gbit */
0x120U, /* 1Gbit */
0x1FFU, /* 100Mbit */
};
unsigned int speed_index =
hw_atl_utils_mbps_2_speed_index(
self->aq_link_status.mbps);
itr_rx = 0x80000000U |
(hw_timers_tbl_[speed_index] << 0x10U);
}
aq_hw_write_reg(self, 0x00002A00U, 0x40000000U);
aq_hw_write_reg(self, 0x00002A00U, 0x8D000000U);
}
} else {
itr_rx = 0U;
}
for (i = HW_ATL_A0_RINGS_MAX; i--;)
hw_atl_reg_irq_thr_set(self, itr_rx, i);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_stop(struct aq_hw_s *self)
{
hw_atl_a0_hw_irq_disable(self, HW_ATL_A0_INT_MASK);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_ring_tx_stop(struct aq_hw_s *self,
struct aq_ring_s *ring)
{
hw_atl_tdm_tx_desc_en_set(self, 0U, ring->idx);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_ring_rx_stop(struct aq_hw_s *self,
struct aq_ring_s *ring)
{
hw_atl_rdm_rx_desc_en_set(self, 0U, ring->idx);
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_fl3l4_clear(struct aq_hw_s *self,
struct aq_rx_filter_l3l4 *data)
{
u8 location = data->location;
if (!data->is_ipv6) {
hw_atl_rpfl3l4_cmd_clear(self, location);
hw_atl_rpf_l4_spd_set(self, 0U, location);
hw_atl_rpf_l4_dpd_set(self, 0U, location);
hw_atl_rpfl3l4_ipv4_src_addr_clear(self, location);
hw_atl_rpfl3l4_ipv4_dest_addr_clear(self, location);
} else {
int i;
for (i = 0; i < HW_ATL_RX_CNT_REG_ADDR_IPV6; ++i) {
hw_atl_rpfl3l4_cmd_clear(self, location + i);
hw_atl_rpf_l4_spd_set(self, 0U, location + i);
hw_atl_rpf_l4_dpd_set(self, 0U, location + i);
}
hw_atl_rpfl3l4_ipv6_src_addr_clear(self, location);
hw_atl_rpfl3l4_ipv6_dest_addr_clear(self, location);
}
return aq_hw_err_from_flags(self);
}
static int hw_atl_a0_hw_fl3l4_set(struct aq_hw_s *self,
struct aq_rx_filter_l3l4 *data)
{
u8 location = data->location;
hw_atl_a0_hw_fl3l4_clear(self, data);
if (data->cmd) {
if (!data->is_ipv6) {
hw_atl_rpfl3l4_ipv4_dest_addr_set(self,
location,
data->ip_dst[0]);
hw_atl_rpfl3l4_ipv4_src_addr_set(self,
location,
data->ip_src[0]);
} else {
hw_atl_rpfl3l4_ipv6_dest_addr_set(self,
location,
data->ip_dst);
hw_atl_rpfl3l4_ipv6_src_addr_set(self,
location,
data->ip_src);
}
}
hw_atl_rpf_l4_dpd_set(self, data->p_dst, location);
hw_atl_rpf_l4_spd_set(self, data->p_src, location);
hw_atl_rpfl3l4_cmd_set(self, location, data->cmd);
return aq_hw_err_from_flags(self);
}
const struct aq_hw_ops hw_atl_ops_a0 = {
.hw_soft_reset = hw_atl_utils_soft_reset,
.hw_prepare = hw_atl_utils_initfw,
.hw_set_mac_address = hw_atl_a0_hw_mac_addr_set,
.hw_init = hw_atl_a0_hw_init,
.hw_reset = hw_atl_a0_hw_reset,
.hw_start = hw_atl_a0_hw_start,
.hw_ring_tx_start = hw_atl_a0_hw_ring_tx_start,
.hw_ring_tx_stop = hw_atl_a0_hw_ring_tx_stop,
.hw_ring_rx_start = hw_atl_a0_hw_ring_rx_start,
.hw_ring_rx_stop = hw_atl_a0_hw_ring_rx_stop,
.hw_stop = hw_atl_a0_hw_stop,
.hw_ring_tx_xmit = hw_atl_a0_hw_ring_tx_xmit,
.hw_ring_tx_head_update = hw_atl_a0_hw_ring_tx_head_update,
.hw_ring_rx_receive = hw_atl_a0_hw_ring_rx_receive,
.hw_ring_rx_fill = hw_atl_a0_hw_ring_rx_fill,
.hw_irq_enable = hw_atl_a0_hw_irq_enable,
.hw_irq_disable = hw_atl_a0_hw_irq_disable,
.hw_irq_read = hw_atl_a0_hw_irq_read,
.hw_ring_rx_init = hw_atl_a0_hw_ring_rx_init,
.hw_ring_tx_init = hw_atl_a0_hw_ring_tx_init,
.hw_packet_filter_set = hw_atl_a0_hw_packet_filter_set,
.hw_filter_l3l4_set = hw_atl_a0_hw_fl3l4_set,
.hw_multicast_list_set = hw_atl_a0_hw_multicast_list_set,
.hw_interrupt_moderation_set = hw_atl_a0_hw_interrupt_moderation_set,
.hw_rss_set = hw_atl_a0_hw_rss_set,
.hw_rss_hash_set = hw_atl_a0_hw_rss_hash_set,
.hw_get_regs = hw_atl_utils_hw_get_regs,
.hw_get_hw_stats = hw_atl_utils_get_hw_stats,
.hw_get_fw_version = hw_atl_utils_get_fw_version,
};
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* aQuantia Corporation Network Driver
* Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
*/
/* File hw_atl_a0.h: Declaration of abstract interface for Atlantic hardware
* specific functions.
*/
#ifndef HW_ATL_A0_H
#define HW_ATL_A0_H
#include "../aq_common.h"
extern const struct aq_hw_caps_s hw_atl_a0_caps_aqc100;
extern const struct aq_hw_caps_s hw_atl_a0_caps_aqc107;
extern const struct aq_hw_caps_s hw_atl_a0_caps_aqc108;
extern const struct aq_hw_caps_s hw_atl_a0_caps_aqc109;
extern const struct aq_hw_ops hw_atl_ops_a0;
#endif /* HW_ATL_A0_H */
@@ -0,0 +1,90 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* aQuantia Corporation Network Driver
* Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
*/
/* File hw_atl_a0_internal.h: Definition of Atlantic A0 chip specific
* constants.
*/
#ifndef HW_ATL_A0_INTERNAL_H
#define HW_ATL_A0_INTERNAL_H
#include "../aq_common.h"
#define HW_ATL_A0_MTU_JUMBO 9014U
#define HW_ATL_A0_TX_RINGS 4U
#define HW_ATL_A0_RX_RINGS 4U
#define HW_ATL_A0_RINGS_MAX 32U
#define HW_ATL_A0_TXD_SIZE 16U
#define HW_ATL_A0_RXD_SIZE 16U
#define HW_ATL_A0_MAC 0U
#define HW_ATL_A0_MAC_MIN 1U
#define HW_ATL_A0_MAC_MAX 33U
/* interrupts */
#define HW_ATL_A0_ERR_INT 8U
#define HW_ATL_A0_INT_MASK 0xFFFFFFFFU
#define HW_ATL_A0_TXD_CTL2_LEN 0xFFFFC000U
#define HW_ATL_A0_TXD_CTL2_CTX_EN 0x00002000U
#define HW_ATL_A0_TXD_CTL2_CTX_IDX 0x00001000U
#define HW_ATL_A0_TXD_CTL_DESC_TYPE_TXD 0x00000001U
#define HW_ATL_A0_TXD_CTL_DESC_TYPE_TXC 0x00000002U
#define HW_ATL_A0_TXD_CTL_BLEN 0x000FFFF0U
#define HW_ATL_A0_TXD_CTL_DD 0x00100000U
#define HW_ATL_A0_TXD_CTL_EOP 0x00200000U
#define HW_ATL_A0_TXD_CTL_CMD_X 0x3FC00000U
#define HW_ATL_A0_TXD_CTL_CMD_VLAN BIT(22)
#define HW_ATL_A0_TXD_CTL_CMD_FCS BIT(23)
#define HW_ATL_A0_TXD_CTL_CMD_IPCSO BIT(24)
#define HW_ATL_A0_TXD_CTL_CMD_TUCSO BIT(25)
#define HW_ATL_A0_TXD_CTL_CMD_LSO BIT(26)
#define HW_ATL_A0_TXD_CTL_CMD_WB BIT(27)
#define HW_ATL_A0_TXD_CTL_CMD_VXLAN BIT(28)
#define HW_ATL_A0_TXD_CTL_CMD_IPV6 BIT(21)
#define HW_ATL_A0_TXD_CTL_CMD_TCP BIT(22)
#define HW_ATL_A0_MPI_CONTROL_ADR 0x0368U
#define HW_ATL_A0_MPI_STATE_ADR 0x036CU
#define HW_ATL_A0_MPI_SPEED_MSK 0xFFFFU
#define HW_ATL_A0_MPI_SPEED_SHIFT 16U
#define HW_ATL_A0_TXBUF_MAX 160U
#define HW_ATL_A0_RXBUF_MAX 320U
#define HW_ATL_A0_RSS_REDIRECTION_MAX 64U
#define HW_ATL_A0_RSS_REDIRECTION_BITS 3U
#define HW_ATL_A0_TC_MAX 1U
#define HW_ATL_A0_RSS_MAX 8U
#define HW_ATL_A0_FW_SEMA_RAM 0x2U
#define HW_ATL_A0_RXD_DD 0x1U
#define HW_ATL_A0_RXD_NCEA0 0x1U
#define HW_ATL_A0_RXD_WB_STAT2_EOP 0x0002U
#define HW_ATL_A0_UCP_0X370_REG 0x370U
#define HW_ATL_A0_FW_VER_EXPECTED 0x01050006U
#define HW_ATL_A0_MIN_RXD \
(ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_RXD_MULTIPLE))
#define HW_ATL_A0_MIN_TXD \
(ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_TXD_MULTIPLE))
#define HW_ATL_A0_MAX_RXD 8184U
#define HW_ATL_A0_MAX_TXD 8184U
#endif /* HW_ATL_A0_INTERNAL_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,75 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Atlantic Network Driver
*
* Copyright (C) 2014-2019 aQuantia Corporation
* Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File hw_atl_b0.h: Declaration of abstract interface for Atlantic hardware
* specific functions.
*/
#ifndef HW_ATL_B0_H
#define HW_ATL_B0_H
#include "../aq_common.h"
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc100;
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc107;
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc108;
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc109;
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc111;
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc112;
#define hw_atl_b0_caps_aqc100s hw_atl_b0_caps_aqc100
#define hw_atl_b0_caps_aqc107s hw_atl_b0_caps_aqc107
#define hw_atl_b0_caps_aqc108s hw_atl_b0_caps_aqc108
#define hw_atl_b0_caps_aqc109s hw_atl_b0_caps_aqc109
#define hw_atl_b0_caps_aqc111s hw_atl_b0_caps_aqc111
#define hw_atl_b0_caps_aqc112s hw_atl_b0_caps_aqc112
extern const struct aq_hw_ops hw_atl_ops_b0;
#define hw_atl_ops_b1 hw_atl_ops_b0
int hw_atl_b0_hw_rss_hash_set(struct aq_hw_s *self,
struct aq_rss_parameters *rss_params);
int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
struct aq_nic_cfg_s *aq_nic_cfg);
int hw_atl_b0_hw_ring_tx_start(struct aq_hw_s *self, struct aq_ring_s *ring);
int hw_atl_b0_hw_ring_rx_start(struct aq_hw_s *self, struct aq_ring_s *ring);
int hw_atl_b0_hw_ring_rx_init(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
struct aq_ring_param_s *aq_ring_param);
int hw_atl_b0_hw_ring_rx_fill(struct aq_hw_s *self, struct aq_ring_s *ring,
unsigned int sw_tail_old);
int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, struct aq_ring_s *ring);
int hw_atl_b0_hw_ring_tx_init(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
struct aq_ring_param_s *aq_ring_param);
int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self, struct aq_ring_s *ring,
unsigned int frags);
int hw_atl_b0_hw_ring_tx_head_update(struct aq_hw_s *self,
struct aq_ring_s *ring);
int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring);
int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self, struct aq_ring_s *ring);
void hw_atl_b0_hw_init_rx_rss_ctrl1(struct aq_hw_s *self);
int hw_atl_b0_hw_mac_addr_set(struct aq_hw_s *self, const u8 *mac_addr);
int hw_atl_b0_set_fc(struct aq_hw_s *self, u32 fc, u32 tc);
int hw_atl_b0_set_loopback(struct aq_hw_s *self, u32 mode, bool enable);
int hw_atl_b0_hw_start(struct aq_hw_s *self);
int hw_atl_b0_hw_irq_enable(struct aq_hw_s *self, u64 mask);
int hw_atl_b0_hw_irq_disable(struct aq_hw_s *self, u64 mask);
int hw_atl_b0_hw_irq_read(struct aq_hw_s *self, u64 *mask);
int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,
unsigned int packet_filter);
#endif /* HW_ATL_B0_H */
@@ -0,0 +1,160 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* aQuantia Corporation Network Driver
* Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
*/
/* File hw_atl_b0_internal.h: Definition of Atlantic B0 chip specific
* constants.
*/
#ifndef HW_ATL_B0_INTERNAL_H
#define HW_ATL_B0_INTERNAL_H
#include "../aq_common.h"
#define HW_ATL_B0_MTU_JUMBO 16352U
#define HW_ATL_B0_MTU 1514U
#define HW_ATL_B0_TX_RINGS 4U
#define HW_ATL_B0_RX_RINGS 4U
#define HW_ATL_B0_RINGS_MAX 32U
#define HW_ATL_B0_TXD_SIZE (16U)
#define HW_ATL_B0_RXD_SIZE (16U)
#define HW_ATL_B0_MAC 0U
#define HW_ATL_B0_MAC_MIN 1U
#define HW_ATL_B0_MAC_MAX 33U
/* UCAST/MCAST filters */
#define HW_ATL_B0_UCAST_FILTERS_MAX 38
#define HW_ATL_B0_MCAST_FILTERS_MAX 8
/* interrupts */
#define HW_ATL_B0_ERR_INT 8U
#define HW_ATL_B0_INT_MASK (0xFFFFFFFFU)
#define HW_ATL_B0_TXD_CTL2_LEN (0xFFFFC000)
#define HW_ATL_B0_TXD_CTL2_CTX_EN (0x00002000)
#define HW_ATL_B0_TXD_CTL2_CTX_IDX (0x00001000)
#define HW_ATL_B0_TXD_CTL_DESC_TYPE_TXD (0x00000001)
#define HW_ATL_B0_TXD_CTL_DESC_TYPE_TXC (0x00000002)
#define HW_ATL_B0_TXD_CTL_BLEN (0x000FFFF0)
#define HW_ATL_B0_TXD_CTL_DD (0x00100000)
#define HW_ATL_B0_TXD_CTL_EOP (0x00200000)
#define HW_ATL_B0_TXD_CTL_CMD_X (0x3FC00000)
#define HW_ATL_B0_TXD_CTL_CMD_VLAN BIT(22)
#define HW_ATL_B0_TXD_CTL_CMD_FCS BIT(23)
#define HW_ATL_B0_TXD_CTL_CMD_IPCSO BIT(24)
#define HW_ATL_B0_TXD_CTL_CMD_TUCSO BIT(25)
#define HW_ATL_B0_TXD_CTL_CMD_LSO BIT(26)
#define HW_ATL_B0_TXD_CTL_CMD_WB BIT(27)
#define HW_ATL_B0_TXD_CTL_CMD_VXLAN BIT(28)
#define HW_ATL_B0_TXD_CTL_CMD_IPV6 BIT(21)
#define HW_ATL_B0_TXD_CTL_CMD_TCP BIT(22)
#define HW_ATL_B0_MPI_CONTROL_ADR 0x0368U
#define HW_ATL_B0_MPI_STATE_ADR 0x036CU
#define HW_ATL_B0_MPI_SPEED_MSK 0xFFFFU
#define HW_ATL_B0_MPI_SPEED_SHIFT 16U
#define HW_ATL_B0_TXBUF_MAX 160U
#define HW_ATL_B0_PTP_TXBUF_SIZE 8U
#define HW_ATL_B0_RXBUF_MAX 320U
#define HW_ATL_B0_PTP_RXBUF_SIZE 16U
#define HW_ATL_B0_RSS_REDIRECTION_MAX 64U
#define HW_ATL_B0_RSS_REDIRECTION_BITS 3U
#define HW_ATL_B0_RSS_HASHKEY_BITS 320U
#define HW_ATL_B0_TCRSS_4_8 1
#define HW_ATL_B0_TC_MAX 8U
#define HW_ATL_B0_RSS_MAX 8U
#define HW_ATL_B0_LRO_RXD_MAX 16U
#define HW_ATL_B0_RS_SLIP_ENABLED 0U
/* (256k -1(max pay_len) - 54(header)) */
#define HAL_ATL_B0_LSO_MAX_SEGMENT_SIZE 262089U
/* (256k -1(max pay_len) - 74(header)) */
#define HAL_ATL_B0_LSO_IPV6_MAX_SEGMENT_SIZE 262069U
#define HW_ATL_B0_CHIP_REVISION_B0 0xA0U
#define HW_ATL_B0_CHIP_REVISION_UNKNOWN 0xFFU
#define HW_ATL_B0_FW_SEMA_RAM 0x2U
#define HW_ATL_B0_TXC_LEN_TUNLEN (0x0000FF00)
#define HW_ATL_B0_TXC_LEN_OUTLEN (0xFFFF0000)
#define HW_ATL_B0_TXC_CTL_DESC_TYPE (0x00000007)
#define HW_ATL_B0_TXC_CTL_CTX_ID (0x00000008)
#define HW_ATL_B0_TXC_CTL_VLAN (0x000FFFF0)
#define HW_ATL_B0_TXC_CTL_CMD (0x00F00000)
#define HW_ATL_B0_TXC_CTL_L2LEN (0x7F000000)
#define HW_ATL_B0_TXC_CTL_L3LEN (0x80000000) /* L3LEN lsb */
#define HW_ATL_B0_TXC_LEN2_L3LEN (0x000000FF) /* L3LE upper bits */
#define HW_ATL_B0_TXC_LEN2_L4LEN (0x0000FF00)
#define HW_ATL_B0_TXC_LEN2_MSSLEN (0xFFFF0000)
#define HW_ATL_B0_RXD_DD (0x1)
#define HW_ATL_B0_RXD_NCEA0 (0x1)
#define HW_ATL_B0_RXD_WB_STAT_RSSTYPE (0x0000000F)
#define HW_ATL_B0_RXD_WB_STAT_RSSTYPE_SHIFT (0x0)
#define HW_ATL_B0_RXD_WB_STAT_PKTTYPE (0x00000FF0)
#define HW_ATL_B0_RXD_WB_STAT_PKTTYPE_SHIFT (0x4)
#define HW_ATL_B0_RXD_WB_STAT_RXCTRL (0x00180000)
#define HW_ATL_B0_RXD_WB_STAT_RXCTRL_SHIFT (0x13)
#define HW_ATL_B0_RXD_WB_STAT_SPLHDR (0x00200000)
#define HW_ATL_B0_RXD_WB_STAT_HDRLEN (0xFFC00000)
#define HW_ATL_B0_RXD_WB_STAT_HDRLEN_SHIFT (0x16)
#define HW_ATL_B0_RXD_WB_PKTTYPE_VLAN BIT(5)
#define HW_ATL_B0_RXD_WB_PKTTYPE_VLAN_DOUBLE BIT(6)
#define HW_ATL_B0_RXD_WB_STAT2_DD (0x0001)
#define HW_ATL_B0_RXD_WB_STAT2_EOP (0x0002)
#define HW_ATL_B0_RXD_WB_STAT2_RXSTAT (0x003C)
#define HW_ATL_B0_RXD_WB_STAT2_MACERR (0x0004)
#define HW_ATL_B0_RXD_WB_STAT2_IP4ERR (0x0008)
#define HW_ATL_B0_RXD_WB_STAT2_TCPUPDERR (0x0010)
#define HW_ATL_B0_RXD_WB_STAT2_RXESTAT (0x0FC0)
#define HW_ATL_B0_RXD_WB_STAT2_RSCCNT (0xF000)
#define L2_FILTER_ACTION_DISCARD (0x0)
#define L2_FILTER_ACTION_HOST (0x1)
#define HW_ATL_B0_UCP_0X370_REG (0x370)
#define HW_ATL_B0_FLUSH() AQ_HW_READ_REG(self, 0x10)
#define HW_ATL_B0_FW_VER_EXPECTED 0x01050006U
#define HW_ATL_INTR_MODER_MAX 0x1FF
#define HW_ATL_INTR_MODER_MIN 0xFF
#define HW_ATL_B0_MIN_RXD \
(ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_RXD_MULTIPLE))
#define HW_ATL_B0_MIN_TXD \
(ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_TXD_MULTIPLE))
#define HW_ATL_B0_MAX_RXD 8184U
#define HW_ATL_B0_MAX_TXD 8184U
#define HW_ATL_RSS_DISABLED 0x00000000U
#define HW_ATL_RSS_ENABLED_8TCS_2INDEX_BITS 0xA2222222U
#define HW_ATL_RSS_ENABLED_4TCS_3INDEX_BITS 0x80003333U
/* HW layer capabilities */
#endif /* HW_ATL_B0_INTERNAL_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,893 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Atlantic Network Driver
*
* Copyright (C) 2014-2019 aQuantia Corporation
* Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File hw_atl_llh.h: Declarations of bitfield and register access functions for
* Atlantic registers.
*/
#ifndef HW_ATL_LLH_H
#define HW_ATL_LLH_H
#include <linux/types.h>
struct aq_hw_s;
/* set temperature sense reset */
void hw_atl_ts_reset_set(struct aq_hw_s *aq_hw, u32 val);
/* set temperature sense power down */
void hw_atl_ts_power_down_set(struct aq_hw_s *aq_hw, u32 val);
/* get temperature sense power down */
u32 hw_atl_ts_power_down_get(struct aq_hw_s *aq_hw);
/* get temperature sense ready */
u32 hw_atl_ts_ready_get(struct aq_hw_s *aq_hw);
/* get temperature sense ready latch high */
u32 hw_atl_ts_ready_latch_high_get(struct aq_hw_s *aq_hw);
/* get temperature sense data */
u32 hw_atl_ts_data_get(struct aq_hw_s *aq_hw);
/* SMBUS0 bus busy */
u32 hw_atl_smb0_bus_busy_get(struct aq_hw_s *aq_hw);
/* SMBUS0 byte transfer complete */
u32 hw_atl_smb0_byte_transfer_complete_get(struct aq_hw_s *aq_hw);
/* SMBUS0 receive acknowledged */
u32 hw_atl_smb0_receive_acknowledged_get(struct aq_hw_s *aq_hw);
/* SMBUS0 set transmitted data (only leftmost byte of data valid) */
void hw_atl_smb0_tx_data_set(struct aq_hw_s *aq_hw, u32 data);
/* SMBUS0 provisioning2 command register */
void hw_atl_smb0_provisioning2_set(struct aq_hw_s *aq_hw, u32 data);
/* SMBUS0 repeated start detect */
u32 hw_atl_smb0_repeated_start_detect_get(struct aq_hw_s *aq_hw);
/* SMBUS0 received data register */
u32 hw_atl_smb0_rx_data_get(struct aq_hw_s *aq_hw);
/* global */
/* set global microprocessor semaphore */
void hw_atl_reg_glb_cpu_sem_set(struct aq_hw_s *aq_hw, u32 glb_cpu_sem,
u32 semaphore);
/* get global microprocessor semaphore */
u32 hw_atl_reg_glb_cpu_sem_get(struct aq_hw_s *aq_hw, u32 semaphore);
/* set global register reset disable */
void hw_atl_glb_glb_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 glb_reg_res_dis);
/* set soft reset */
void hw_atl_glb_soft_res_set(struct aq_hw_s *aq_hw, u32 soft_res);
/* get soft reset */
u32 hw_atl_glb_soft_res_get(struct aq_hw_s *aq_hw);
/* stats */
u32 hw_atl_rpb_rx_dma_drop_pkt_cnt_get(struct aq_hw_s *aq_hw);
/* get rx dma good octet counter */
u64 hw_atl_stats_rx_dma_good_octet_counter_get(struct aq_hw_s *aq_hw);
/* get rx dma good packet counter */
u64 hw_atl_stats_rx_dma_good_pkt_counter_get(struct aq_hw_s *aq_hw);
/* get tx dma good octet counter */
u64 hw_atl_stats_tx_dma_good_octet_counter_get(struct aq_hw_s *aq_hw);
/* get tx dma good packet counter */
u64 hw_atl_stats_tx_dma_good_pkt_counter_get(struct aq_hw_s *aq_hw);
/* get msm rx errors counter register */
u32 hw_atl_reg_mac_msm_rx_errs_cnt_get(struct aq_hw_s *aq_hw);
/* get msm rx unicast frames counter register */
u32 hw_atl_reg_mac_msm_rx_ucst_frm_cnt_get(struct aq_hw_s *aq_hw);
/* get msm rx multicast frames counter register */
u32 hw_atl_reg_mac_msm_rx_mcst_frm_cnt_get(struct aq_hw_s *aq_hw);
/* get msm rx broadcast frames counter register */
u32 hw_atl_reg_mac_msm_rx_bcst_frm_cnt_get(struct aq_hw_s *aq_hw);
/* get msm rx broadcast octets counter register 1 */
u32 hw_atl_reg_mac_msm_rx_bcst_octets_counter1get(struct aq_hw_s *aq_hw);
/* get msm rx unicast octets counter register 0 */
u32 hw_atl_reg_mac_msm_rx_ucst_octets_counter0get(struct aq_hw_s *aq_hw);
/* get msm tx errors counter register */
u32 hw_atl_reg_mac_msm_tx_errs_cnt_get(struct aq_hw_s *aq_hw);
/* get msm tx unicast frames counter register */
u32 hw_atl_reg_mac_msm_tx_ucst_frm_cnt_get(struct aq_hw_s *aq_hw);
/* get msm tx multicast frames counter register */
u32 hw_atl_reg_mac_msm_tx_mcst_frm_cnt_get(struct aq_hw_s *aq_hw);
/* get msm tx broadcast frames counter register */
u32 hw_atl_reg_mac_msm_tx_bcst_frm_cnt_get(struct aq_hw_s *aq_hw);
/* get msm tx multicast octets counter register 1 */
u32 hw_atl_reg_mac_msm_tx_mcst_octets_counter1get(struct aq_hw_s *aq_hw);
/* get msm tx broadcast octets counter register 1 */
u32 hw_atl_reg_mac_msm_tx_bcst_octets_counter1get(struct aq_hw_s *aq_hw);
/* get msm tx unicast octets counter register 0 */
u32 hw_atl_reg_mac_msm_tx_ucst_octets_counter0get(struct aq_hw_s *aq_hw);
/* get global mif identification */
u32 hw_atl_reg_glb_mif_id_get(struct aq_hw_s *aq_hw);
/* interrupt */
/* set interrupt auto mask lsw */
void hw_atl_itr_irq_auto_masklsw_set(struct aq_hw_s *aq_hw,
u32 irq_auto_masklsw);
/* set interrupt mapping enable rx */
void hw_atl_itr_irq_map_en_rx_set(struct aq_hw_s *aq_hw, u32 irq_map_en_rx,
u32 rx);
/* set interrupt mapping enable tx */
void hw_atl_itr_irq_map_en_tx_set(struct aq_hw_s *aq_hw, u32 irq_map_en_tx,
u32 tx);
/* set interrupt mapping rx */
void hw_atl_itr_irq_map_rx_set(struct aq_hw_s *aq_hw, u32 irq_map_rx, u32 rx);
/* set interrupt mapping tx */
void hw_atl_itr_irq_map_tx_set(struct aq_hw_s *aq_hw, u32 irq_map_tx, u32 tx);
/* set interrupt mask clear lsw */
void hw_atl_itr_irq_msk_clearlsw_set(struct aq_hw_s *aq_hw,
u32 irq_msk_clearlsw);
/* set interrupt mask set lsw */
void hw_atl_itr_irq_msk_setlsw_set(struct aq_hw_s *aq_hw, u32 irq_msk_setlsw);
/* set interrupt register reset disable */
void hw_atl_itr_irq_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 irq_reg_res_dis);
/* set interrupt status clear lsw */
void hw_atl_itr_irq_status_clearlsw_set(struct aq_hw_s *aq_hw,
u32 irq_status_clearlsw);
/* get interrupt status lsw */
u32 hw_atl_itr_irq_statuslsw_get(struct aq_hw_s *aq_hw);
/* get reset interrupt */
u32 hw_atl_itr_res_irq_get(struct aq_hw_s *aq_hw);
/* set reset interrupt */
void hw_atl_itr_res_irq_set(struct aq_hw_s *aq_hw, u32 res_irq);
/* set RSC interrupt */
void hw_atl_itr_rsc_en_set(struct aq_hw_s *aq_hw, u32 enable);
/* set RSC delay */
void hw_atl_itr_rsc_delay_set(struct aq_hw_s *aq_hw, u32 delay);
/* rdm */
/* set cpu id */
void hw_atl_rdm_cpu_id_set(struct aq_hw_s *aq_hw, u32 cpuid, u32 dca);
/* set rx dca enable */
void hw_atl_rdm_rx_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_dca_en);
/* set rx dca mode */
void hw_atl_rdm_rx_dca_mode_set(struct aq_hw_s *aq_hw, u32 rx_dca_mode);
/* set rx descriptor data buffer size */
void hw_atl_rdm_rx_desc_data_buff_size_set(struct aq_hw_s *aq_hw,
u32 rx_desc_data_buff_size,
u32 descriptor);
/* set rx descriptor dca enable */
void hw_atl_rdm_rx_desc_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_desc_dca_en,
u32 dca);
/* set rx descriptor enable */
void hw_atl_rdm_rx_desc_en_set(struct aq_hw_s *aq_hw, u32 rx_desc_en,
u32 descriptor);
/* set rx descriptor header splitting */
void hw_atl_rdm_rx_desc_head_splitting_set(struct aq_hw_s *aq_hw,
u32 rx_desc_head_splitting,
u32 descriptor);
/* get rx descriptor head pointer */
u32 hw_atl_rdm_rx_desc_head_ptr_get(struct aq_hw_s *aq_hw, u32 descriptor);
/* set rx descriptor length */
void hw_atl_rdm_rx_desc_len_set(struct aq_hw_s *aq_hw, u32 rx_desc_len,
u32 descriptor);
/* set rx descriptor write-back interrupt enable */
void hw_atl_rdm_rx_desc_wr_wb_irq_en_set(struct aq_hw_s *aq_hw,
u32 rx_desc_wr_wb_irq_en);
/* set rx header dca enable */
void hw_atl_rdm_rx_head_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_head_dca_en,
u32 dca);
/* set rx payload dca enable */
void hw_atl_rdm_rx_pld_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_pld_dca_en,
u32 dca);
/* set rx descriptor header buffer size */
void hw_atl_rdm_rx_desc_head_buff_size_set(struct aq_hw_s *aq_hw,
u32 rx_desc_head_buff_size,
u32 descriptor);
/* set rx descriptor reset */
void hw_atl_rdm_rx_desc_res_set(struct aq_hw_s *aq_hw, u32 rx_desc_res,
u32 descriptor);
/* Set RDM Interrupt Moderation Enable */
void hw_atl_rdm_rdm_intr_moder_en_set(struct aq_hw_s *aq_hw,
u32 rdm_intr_moder_en);
/* reg */
/* set general interrupt mapping register */
void hw_atl_reg_gen_irq_map_set(struct aq_hw_s *aq_hw, u32 gen_intr_map,
u32 regidx);
/* get general interrupt status register */
u32 hw_atl_reg_gen_irq_status_get(struct aq_hw_s *aq_hw);
/* set interrupt global control register */
void hw_atl_reg_irq_glb_ctl_set(struct aq_hw_s *aq_hw, u32 intr_glb_ctl);
/* set interrupt throttle register */
void hw_atl_reg_irq_thr_set(struct aq_hw_s *aq_hw, u32 intr_thr, u32 throttle);
/* set rx dma descriptor base address lsw */
void hw_atl_reg_rx_dma_desc_base_addresslswset(struct aq_hw_s *aq_hw,
u32 rx_dma_desc_base_addrlsw,
u32 descriptor);
/* set rx dma descriptor base address msw */
void hw_atl_reg_rx_dma_desc_base_addressmswset(struct aq_hw_s *aq_hw,
u32 rx_dma_desc_base_addrmsw,
u32 descriptor);
/* get rx dma descriptor status register */
u32 hw_atl_reg_rx_dma_desc_status_get(struct aq_hw_s *aq_hw, u32 descriptor);
/* set rx dma descriptor tail pointer register */
void hw_atl_reg_rx_dma_desc_tail_ptr_set(struct aq_hw_s *aq_hw,
u32 rx_dma_desc_tail_ptr,
u32 descriptor);
/* set rx filter multicast filter mask register */
void hw_atl_reg_rx_flr_mcst_flr_msk_set(struct aq_hw_s *aq_hw,
u32 rx_flr_mcst_flr_msk);
/* set rx filter multicast filter register */
void hw_atl_reg_rx_flr_mcst_flr_set(struct aq_hw_s *aq_hw, u32 rx_flr_mcst_flr,
u32 filter);
/* set rx filter rss control register 1 */
void hw_atl_reg_rx_flr_rss_control1set(struct aq_hw_s *aq_hw,
u32 rx_flr_rss_control1);
/* Set RX Filter Control Register 2 */
void hw_atl_reg_rx_flr_control2_set(struct aq_hw_s *aq_hw, u32 rx_flr_control2);
/* Set RX Interrupt Moderation Control Register */
void hw_atl_reg_rx_intr_moder_ctrl_set(struct aq_hw_s *aq_hw,
u32 rx_intr_moderation_ctl,
u32 queue);
/* set tx dma debug control */
void hw_atl_reg_tx_dma_debug_ctl_set(struct aq_hw_s *aq_hw,
u32 tx_dma_debug_ctl);
/* set tx dma descriptor base address lsw */
void hw_atl_reg_tx_dma_desc_base_addresslswset(struct aq_hw_s *aq_hw,
u32 tx_dma_desc_base_addrlsw,
u32 descriptor);
/* set tx dma descriptor base address msw */
void hw_atl_reg_tx_dma_desc_base_addressmswset(struct aq_hw_s *aq_hw,
u32 tx_dma_desc_base_addrmsw,
u32 descriptor);
/* set tx dma descriptor tail pointer register */
void hw_atl_reg_tx_dma_desc_tail_ptr_set(struct aq_hw_s *aq_hw,
u32 tx_dma_desc_tail_ptr,
u32 descriptor);
/* Set TX Interrupt Moderation Control Register */
void hw_atl_reg_tx_intr_moder_ctrl_set(struct aq_hw_s *aq_hw,
u32 tx_intr_moderation_ctl,
u32 queue);
/* set global microprocessor scratch pad */
void hw_atl_reg_glb_cpu_scratch_scp_set(struct aq_hw_s *aq_hw,
u32 glb_cpu_scratch_scp,
u32 scratch_scp);
/* rpb */
/* set dma system loopback */
void hw_atl_rpb_dma_sys_lbk_set(struct aq_hw_s *aq_hw, u32 dma_sys_lbk);
/* set dma network loopback */
void hw_atl_rpb_dma_net_lbk_set(struct aq_hw_s *aq_hw, u32 dma_net_lbk);
/* set rx traffic class mode */
void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw,
u32 rx_traf_class_mode);
/* get rx traffic class mode */
u32 hw_atl_rpb_rpf_rx_traf_class_mode_get(struct aq_hw_s *aq_hw);
/* set rx buffer enable */
void hw_atl_rpb_rx_buff_en_set(struct aq_hw_s *aq_hw, u32 rx_buff_en);
/* set rx buffer high threshold (per tc) */
void hw_atl_rpb_rx_buff_hi_threshold_per_tc_set(struct aq_hw_s *aq_hw,
u32 rx_buff_hi_threshold_per_tc,
u32 buffer);
/* set rx buffer low threshold (per tc) */
void hw_atl_rpb_rx_buff_lo_threshold_per_tc_set(struct aq_hw_s *aq_hw,
u32 rx_buff_lo_threshold_per_tc,
u32 buffer);
/* set rx flow control mode */
void hw_atl_rpb_rx_flow_ctl_mode_set(struct aq_hw_s *aq_hw,
u32 rx_flow_ctl_mode);
/* set rx packet buffer size (per tc) */
void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw,
u32 rx_pkt_buff_size_per_tc,
u32 buffer);
/* toggle rdm rx dma descriptor cache init */
void hw_atl_rdm_rx_dma_desc_cache_init_tgl(struct aq_hw_s *aq_hw);
/* get rdm rx dma descriptor cache init done */
u32 hw_atl_rdm_rx_dma_desc_cache_init_done_get(struct aq_hw_s *aq_hw);
/* set rx xoff enable (per tc) */
void hw_atl_rpb_rx_xoff_en_per_tc_set(struct aq_hw_s *aq_hw,
u32 rx_xoff_en_per_tc,
u32 buffer);
/* rpf */
/* set l2 broadcast count threshold */
void hw_atl_rpfl2broadcast_count_threshold_set(struct aq_hw_s *aq_hw,
u32 l2broadcast_count_threshold);
/* set l2 broadcast enable */
void hw_atl_rpfl2broadcast_en_set(struct aq_hw_s *aq_hw, u32 l2broadcast_en);
/* set l2 broadcast filter action */
void hw_atl_rpfl2broadcast_flr_act_set(struct aq_hw_s *aq_hw,
u32 l2broadcast_flr_act);
/* set l2 multicast filter enable */
void hw_atl_rpfl2multicast_flr_en_set(struct aq_hw_s *aq_hw,
u32 l2multicast_flr_en,
u32 filter);
/* get l2 promiscuous mode enable */
u32 hw_atl_rpfl2promiscuous_mode_en_get(struct aq_hw_s *aq_hw);
/* set l2 promiscuous mode enable */
void hw_atl_rpfl2promiscuous_mode_en_set(struct aq_hw_s *aq_hw,
u32 l2promiscuous_mode_en);
/* set l2 unicast filter action */
void hw_atl_rpfl2unicast_flr_act_set(struct aq_hw_s *aq_hw,
u32 l2unicast_flr_act,
u32 filter);
/* set l2 unicast filter enable */
void hw_atl_rpfl2_uc_flr_en_set(struct aq_hw_s *aq_hw, u32 l2unicast_flr_en,
u32 filter);
/* set l2 unicast destination address lsw */
void hw_atl_rpfl2unicast_dest_addresslsw_set(struct aq_hw_s *aq_hw,
u32 l2unicast_dest_addresslsw,
u32 filter);
/* set l2 unicast destination address msw */
void hw_atl_rpfl2unicast_dest_addressmsw_set(struct aq_hw_s *aq_hw,
u32 l2unicast_dest_addressmsw,
u32 filter);
/* Set L2 Accept all Multicast packets */
void hw_atl_rpfl2_accept_all_mc_packets_set(struct aq_hw_s *aq_hw,
u32 l2_accept_all_mc_packets);
/* set user-priority tc mapping */
void hw_atl_rpf_rpb_user_priority_tc_map_set(struct aq_hw_s *aq_hw,
u32 user_priority_tc_map, u32 tc);
/* set rss key address */
void hw_atl_rpf_rss_key_addr_set(struct aq_hw_s *aq_hw, u32 rss_key_addr);
/* set rss key write data */
void hw_atl_rpf_rss_key_wr_data_set(struct aq_hw_s *aq_hw, u32 rss_key_wr_data);
/* get rss key write enable */
u32 hw_atl_rpf_rss_key_wr_en_get(struct aq_hw_s *aq_hw);
/* set rss key write enable */
void hw_atl_rpf_rss_key_wr_en_set(struct aq_hw_s *aq_hw, u32 rss_key_wr_en);
/* set rss redirection table address */
void hw_atl_rpf_rss_redir_tbl_addr_set(struct aq_hw_s *aq_hw,
u32 rss_redir_tbl_addr);
/* set rss redirection table write data */
void hw_atl_rpf_rss_redir_tbl_wr_data_set(struct aq_hw_s *aq_hw,
u32 rss_redir_tbl_wr_data);
/* get rss redirection write enable */
u32 hw_atl_rpf_rss_redir_wr_en_get(struct aq_hw_s *aq_hw);
/* set rss redirection write enable */
void hw_atl_rpf_rss_redir_wr_en_set(struct aq_hw_s *aq_hw, u32 rss_redir_wr_en);
/* set tpo to rpf system loopback */
void hw_atl_rpf_tpo_to_rpf_sys_lbk_set(struct aq_hw_s *aq_hw,
u32 tpo_to_rpf_sys_lbk);
/* set vlan inner ethertype */
void hw_atl_rpf_vlan_inner_etht_set(struct aq_hw_s *aq_hw, u32 vlan_inner_etht);
/* set vlan outer ethertype */
void hw_atl_rpf_vlan_outer_etht_set(struct aq_hw_s *aq_hw, u32 vlan_outer_etht);
/* set vlan promiscuous mode enable */
void hw_atl_rpf_vlan_prom_mode_en_set(struct aq_hw_s *aq_hw,
u32 vlan_prom_mode_en);
/* Get VLAN promiscuous mode enable */
u32 hw_atl_rpf_vlan_prom_mode_en_get(struct aq_hw_s *aq_hw);
/* Set VLAN untagged action */
void hw_atl_rpf_vlan_untagged_act_set(struct aq_hw_s *aq_hw,
u32 vlan_untagged_act);
/* Set VLAN accept untagged packets */
void hw_atl_rpf_vlan_accept_untagged_packets_set(struct aq_hw_s *aq_hw,
u32 vlan_acc_untagged_packets);
/* Set VLAN filter enable */
void hw_atl_rpf_vlan_flr_en_set(struct aq_hw_s *aq_hw, u32 vlan_flr_en,
u32 filter);
/* Set VLAN Filter Action */
void hw_atl_rpf_vlan_flr_act_set(struct aq_hw_s *aq_hw, u32 vlan_filter_act,
u32 filter);
/* Set VLAN ID Filter */
void hw_atl_rpf_vlan_id_flr_set(struct aq_hw_s *aq_hw, u32 vlan_id_flr,
u32 filter);
/* Set VLAN RX queue assignment enable */
void hw_atl_rpf_vlan_rxq_en_flr_set(struct aq_hw_s *aq_hw, u32 vlan_rxq_en,
u32 filter);
/* Set VLAN RX queue */
void hw_atl_rpf_vlan_rxq_flr_set(struct aq_hw_s *aq_hw, u32 vlan_rxq,
u32 filter);
/* set ethertype filter enable */
void hw_atl_rpf_etht_flr_en_set(struct aq_hw_s *aq_hw, u32 etht_flr_en,
u32 filter);
/* set ethertype user-priority enable */
void hw_atl_rpf_etht_user_priority_en_set(struct aq_hw_s *aq_hw,
u32 etht_user_priority_en,
u32 filter);
/* set ethertype rx queue enable */
void hw_atl_rpf_etht_rx_queue_en_set(struct aq_hw_s *aq_hw,
u32 etht_rx_queue_en,
u32 filter);
/* set ethertype rx queue */
void hw_atl_rpf_etht_rx_queue_set(struct aq_hw_s *aq_hw, u32 etht_rx_queue,
u32 filter);
/* set ethertype user-priority */
void hw_atl_rpf_etht_user_priority_set(struct aq_hw_s *aq_hw,
u32 etht_user_priority,
u32 filter);
/* set ethertype management queue */
void hw_atl_rpf_etht_mgt_queue_set(struct aq_hw_s *aq_hw, u32 etht_mgt_queue,
u32 filter);
/* set ethertype filter action */
void hw_atl_rpf_etht_flr_act_set(struct aq_hw_s *aq_hw, u32 etht_flr_act,
u32 filter);
/* set ethertype filter */
void hw_atl_rpf_etht_flr_set(struct aq_hw_s *aq_hw, u32 etht_flr, u32 filter);
/* set L4 source port */
void hw_atl_rpf_l4_spd_set(struct aq_hw_s *aq_hw, u32 val, u32 filter);
/* set L4 destination port */
void hw_atl_rpf_l4_dpd_set(struct aq_hw_s *aq_hw, u32 val, u32 filter);
/* rpo */
/* set ipv4 header checksum offload enable */
void hw_atl_rpo_ipv4header_crc_offload_en_set(struct aq_hw_s *aq_hw,
u32 ipv4header_crc_offload_en);
/* set rx descriptor vlan stripping */
void hw_atl_rpo_rx_desc_vlan_stripping_set(struct aq_hw_s *aq_hw,
u32 rx_desc_vlan_stripping,
u32 descriptor);
void hw_atl_rpo_outer_vlan_tag_mode_set(void *context,
u32 outervlantagmode);
u32 hw_atl_rpo_outer_vlan_tag_mode_get(void *context);
/* set tcp/udp checksum offload enable */
void hw_atl_rpo_tcp_udp_crc_offload_en_set(struct aq_hw_s *aq_hw,
u32 tcp_udp_crc_offload_en);
/* Set LRO Patch Optimization Enable. */
void hw_atl_rpo_lro_patch_optimization_en_set(struct aq_hw_s *aq_hw,
u32 lro_patch_optimization_en);
/* Set Large Receive Offload Enable */
void hw_atl_rpo_lro_en_set(struct aq_hw_s *aq_hw, u32 lro_en);
/* Set LRO Q Sessions Limit */
void hw_atl_rpo_lro_qsessions_lim_set(struct aq_hw_s *aq_hw,
u32 lro_qsessions_lim);
/* Set LRO Total Descriptor Limit */
void hw_atl_rpo_lro_total_desc_lim_set(struct aq_hw_s *aq_hw,
u32 lro_total_desc_lim);
/* Set LRO Min Payload of First Packet */
void hw_atl_rpo_lro_min_pay_of_first_pkt_set(struct aq_hw_s *aq_hw,
u32 lro_min_pld_of_first_pkt);
/* Set LRO Packet Limit */
void hw_atl_rpo_lro_pkt_lim_set(struct aq_hw_s *aq_hw, u32 lro_packet_lim);
/* Set LRO Max Number of Descriptors */
void hw_atl_rpo_lro_max_num_of_descriptors_set(struct aq_hw_s *aq_hw,
u32 lro_max_desc_num, u32 lro);
/* Set LRO Time Base Divider */
void hw_atl_rpo_lro_time_base_divider_set(struct aq_hw_s *aq_hw,
u32 lro_time_base_divider);
/*Set LRO Inactive Interval */
void hw_atl_rpo_lro_inactive_interval_set(struct aq_hw_s *aq_hw,
u32 lro_inactive_interval);
/*Set LRO Max Coalescing Interval */
void hw_atl_rpo_lro_max_coalescing_interval_set(struct aq_hw_s *aq_hw,
u32 lro_max_coal_interval);
/* rx */
/* set rx register reset disable */
void hw_atl_rx_rx_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 rx_reg_res_dis);
/* tdm */
/* set cpu id */
void hw_atl_tdm_cpu_id_set(struct aq_hw_s *aq_hw, u32 cpuid, u32 dca);
/* set large send offload enable */
void hw_atl_tdm_large_send_offload_en_set(struct aq_hw_s *aq_hw,
u32 large_send_offload_en);
/* set tx descriptor enable */
void hw_atl_tdm_tx_desc_en_set(struct aq_hw_s *aq_hw, u32 tx_desc_en,
u32 descriptor);
/* set tx dca enable */
void hw_atl_tdm_tx_dca_en_set(struct aq_hw_s *aq_hw, u32 tx_dca_en);
/* set tx dca mode */
void hw_atl_tdm_tx_dca_mode_set(struct aq_hw_s *aq_hw, u32 tx_dca_mode);
/* set tx descriptor dca enable */
void hw_atl_tdm_tx_desc_dca_en_set(struct aq_hw_s *aq_hw, u32 tx_desc_dca_en,
u32 dca);
/* get tx descriptor head pointer */
u32 hw_atl_tdm_tx_desc_head_ptr_get(struct aq_hw_s *aq_hw, u32 descriptor);
/* set tx descriptor length */
void hw_atl_tdm_tx_desc_len_set(struct aq_hw_s *aq_hw, u32 tx_desc_len,
u32 descriptor);
/* set tx descriptor write-back interrupt enable */
void hw_atl_tdm_tx_desc_wr_wb_irq_en_set(struct aq_hw_s *aq_hw,
u32 tx_desc_wr_wb_irq_en);
/* set tx descriptor write-back threshold */
void hw_atl_tdm_tx_desc_wr_wb_threshold_set(struct aq_hw_s *aq_hw,
u32 tx_desc_wr_wb_threshold,
u32 descriptor);
/* Set TDM Interrupt Moderation Enable */
void hw_atl_tdm_tdm_intr_moder_en_set(struct aq_hw_s *aq_hw,
u32 tdm_irq_moderation_en);
/* thm */
/* set lso tcp flag of first packet */
void hw_atl_thm_lso_tcp_flag_of_first_pkt_set(struct aq_hw_s *aq_hw,
u32 lso_tcp_flag_of_first_pkt);
/* set lso tcp flag of last packet */
void hw_atl_thm_lso_tcp_flag_of_last_pkt_set(struct aq_hw_s *aq_hw,
u32 lso_tcp_flag_of_last_pkt);
/* set lso tcp flag of middle packet */
void hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(struct aq_hw_s *aq_hw,
u32 lso_tcp_flag_of_middle_pkt);
/* tpb */
/* set TX Traffic Class Mode */
void hw_atl_tpb_tps_tx_tc_mode_set(struct aq_hw_s *aq_hw,
u32 tx_traf_class_mode);
/* get TX Traffic Class Mode */
u32 hw_atl_tpb_tps_tx_tc_mode_get(struct aq_hw_s *aq_hw);
/* set tx buffer enable */
void hw_atl_tpb_tx_buff_en_set(struct aq_hw_s *aq_hw, u32 tx_buff_en);
/* set tx buffer high threshold (per tc) */
void hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(struct aq_hw_s *aq_hw,
u32 tx_buff_hi_threshold_per_tc,
u32 buffer);
/* set tx buffer low threshold (per tc) */
void hw_atl_tpb_tx_buff_lo_threshold_per_tc_set(struct aq_hw_s *aq_hw,
u32 tx_buff_lo_threshold_per_tc,
u32 buffer);
/* set tx dma system loopback enable */
void hw_atl_tpb_tx_dma_sys_lbk_en_set(struct aq_hw_s *aq_hw, u32 tx_dma_sys_lbk_en);
/* set tx dma network loopback enable */
void hw_atl_tpb_tx_dma_net_lbk_en_set(struct aq_hw_s *aq_hw,
u32 tx_dma_net_lbk_en);
/* set tx clock gating enable */
void hw_atl_tpb_tx_tx_clk_gate_en_set(struct aq_hw_s *aq_hw,
u32 tx_clk_gate_en);
/* set tx packet buffer size (per tc) */
void hw_atl_tpb_tx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw,
u32 tx_pkt_buff_size_per_tc,
u32 buffer);
/* set tx path pad insert enable */
void hw_atl_tpb_tx_path_scp_ins_en_set(struct aq_hw_s *aq_hw, u32 tx_path_scp_ins_en);
/* tpo */
/* set ipv4 header checksum offload enable */
void hw_atl_tpo_ipv4header_crc_offload_en_set(struct aq_hw_s *aq_hw,
u32 ipv4header_crc_offload_en);
/* set tcp/udp checksum offload enable */
void hw_atl_tpo_tcp_udp_crc_offload_en_set(struct aq_hw_s *aq_hw,
u32 tcp_udp_crc_offload_en);
/* set tx pkt system loopback enable */
void hw_atl_tpo_tx_pkt_sys_lbk_en_set(struct aq_hw_s *aq_hw,
u32 tx_pkt_sys_lbk_en);
/* tps */
/* set tx packet scheduler data arbitration mode */
void hw_atl_tps_tx_pkt_shed_data_arb_mode_set(struct aq_hw_s *aq_hw,
u32 tx_pkt_shed_data_arb_mode);
/* set tx packet scheduler descriptor rate current time reset */
void hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(struct aq_hw_s *aq_hw,
u32 curr_time_res);
/* set tx packet scheduler descriptor rate limit */
void hw_atl_tps_tx_pkt_shed_desc_rate_lim_set(struct aq_hw_s *aq_hw,
u32 tx_pkt_shed_desc_rate_lim);
/* set tx packet scheduler descriptor tc arbitration mode */
void hw_atl_tps_tx_pkt_shed_desc_tc_arb_mode_set(struct aq_hw_s *aq_hw,
u32 arb_mode);
/* set tx packet scheduler descriptor tc max credit */
void hw_atl_tps_tx_pkt_shed_desc_tc_max_credit_set(struct aq_hw_s *aq_hw,
const u32 tc,
const u32 max_credit);
/* set tx packet scheduler descriptor tc weight */
void hw_atl_tps_tx_pkt_shed_desc_tc_weight_set(struct aq_hw_s *aq_hw,
const u32 tc,
const u32 weight);
/* set tx packet scheduler descriptor vm arbitration mode */
void hw_atl_tps_tx_pkt_shed_desc_vm_arb_mode_set(struct aq_hw_s *aq_hw,
u32 arb_mode);
/* set tx packet scheduler tc data max credit */
void hw_atl_tps_tx_pkt_shed_tc_data_max_credit_set(struct aq_hw_s *aq_hw,
const u32 tc,
const u32 max_credit);
/* set tx packet scheduler tc data weight */
void hw_atl_tps_tx_pkt_shed_tc_data_weight_set(struct aq_hw_s *aq_hw,
const u32 tc,
const u32 weight);
/* set tx descriptor rate mode */
void hw_atl_tps_tx_desc_rate_mode_set(struct aq_hw_s *aq_hw,
const u32 rate_mode);
/* set tx packet scheduler descriptor rate enable */
void hw_atl_tps_tx_desc_rate_en_set(struct aq_hw_s *aq_hw, const u32 desc,
const u32 enable);
/* set tx packet scheduler descriptor rate integral value */
void hw_atl_tps_tx_desc_rate_x_set(struct aq_hw_s *aq_hw, const u32 desc,
const u32 rate_int);
/* set tx packet scheduler descriptor rate fractional value */
void hw_atl_tps_tx_desc_rate_y_set(struct aq_hw_s *aq_hw, const u32 desc,
const u32 rate_frac);
/* tx */
/* set tx register reset disable */
void hw_atl_tx_tx_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 tx_reg_res_dis);
/* msm */
/* get register access status */
u32 hw_atl_msm_reg_access_status_get(struct aq_hw_s *aq_hw);
/* set register address for indirect address */
void hw_atl_msm_reg_addr_for_indirect_addr_set(struct aq_hw_s *aq_hw,
u32 reg_addr_for_indirect_addr);
/* set register read strobe */
void hw_atl_msm_reg_rd_strobe_set(struct aq_hw_s *aq_hw, u32 reg_rd_strobe);
/* get register read data */
u32 hw_atl_msm_reg_rd_data_get(struct aq_hw_s *aq_hw);
/* set register write data */
void hw_atl_msm_reg_wr_data_set(struct aq_hw_s *aq_hw, u32 reg_wr_data);
/* set register write strobe */
void hw_atl_msm_reg_wr_strobe_set(struct aq_hw_s *aq_hw, u32 reg_wr_strobe);
/* pci */
/* set pci register reset disable */
void hw_atl_pci_pci_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 pci_reg_res_dis);
/* pcs */
void hw_atl_pcs_ptp_clock_read_enable(struct aq_hw_s *aq_hw,
u32 ptp_clock_read_enable);
u32 hw_atl_pcs_ptp_clock_get(struct aq_hw_s *aq_hw, u32 index);
/* set uP Force Interrupt */
void hw_atl_mcp_up_force_intr_set(struct aq_hw_s *aq_hw, u32 up_force_intr);
/* clear ipv4 filter destination address */
void hw_atl_rpfl3l4_ipv4_dest_addr_clear(struct aq_hw_s *aq_hw, u8 location);
/* clear ipv4 filter source address */
void hw_atl_rpfl3l4_ipv4_src_addr_clear(struct aq_hw_s *aq_hw, u8 location);
/* clear command for filter l3-l4 */
void hw_atl_rpfl3l4_cmd_clear(struct aq_hw_s *aq_hw, u8 location);
/* clear ipv6 filter destination address */
void hw_atl_rpfl3l4_ipv6_dest_addr_clear(struct aq_hw_s *aq_hw, u8 location);
/* clear ipv6 filter source address */
void hw_atl_rpfl3l4_ipv6_src_addr_clear(struct aq_hw_s *aq_hw, u8 location);
/* set ipv4 filter destination address */
void hw_atl_rpfl3l4_ipv4_dest_addr_set(struct aq_hw_s *aq_hw, u8 location,
u32 ipv4_dest);
/* set ipv4 filter source address */
void hw_atl_rpfl3l4_ipv4_src_addr_set(struct aq_hw_s *aq_hw, u8 location,
u32 ipv4_src);
/* set command for filter l3-l4 */
void hw_atl_rpfl3l4_cmd_set(struct aq_hw_s *aq_hw, u8 location, u32 cmd);
/* set ipv6 filter source address */
void hw_atl_rpfl3l4_ipv6_src_addr_set(struct aq_hw_s *aq_hw, u8 location,
u32 *ipv6_src);
/* set ipv6 filter destination address */
void hw_atl_rpfl3l4_ipv6_dest_addr_set(struct aq_hw_s *aq_hw, u8 location,
u32 *ipv6_dest);
/* set Global MDIO Interface 1 */
void hw_atl_glb_mdio_iface1_set(struct aq_hw_s *hw, u32 value);
/* get Global MDIO Interface 1 */
u32 hw_atl_glb_mdio_iface1_get(struct aq_hw_s *hw);
/* set Global MDIO Interface 2 */
void hw_atl_glb_mdio_iface2_set(struct aq_hw_s *hw, u32 value);
/* get Global MDIO Interface 2 */
u32 hw_atl_glb_mdio_iface2_get(struct aq_hw_s *hw);
/* set Global MDIO Interface 3 */
void hw_atl_glb_mdio_iface3_set(struct aq_hw_s *hw, u32 value);
/* get Global MDIO Interface 3 */
u32 hw_atl_glb_mdio_iface3_get(struct aq_hw_s *hw);
/* set Global MDIO Interface 4 */
void hw_atl_glb_mdio_iface4_set(struct aq_hw_s *hw, u32 value);
/* get Global MDIO Interface 4 */
u32 hw_atl_glb_mdio_iface4_get(struct aq_hw_s *hw);
/* set Global MDIO Interface 5 */
void hw_atl_glb_mdio_iface5_set(struct aq_hw_s *hw, u32 value);
/* get Global MDIO Interface 5 */
u32 hw_atl_glb_mdio_iface5_get(struct aq_hw_s *hw);
u32 hw_atl_mdio_busy_get(struct aq_hw_s *aq_hw);
/* get global microprocessor ram semaphore */
u32 hw_atl_sem_ram_get(struct aq_hw_s *self);
/* get global microprocessor mdio semaphore */
u32 hw_atl_sem_mdio_get(struct aq_hw_s *self);
u32 hw_atl_sem_reset1_get(struct aq_hw_s *self);
u32 hw_atl_sem_reset2_get(struct aq_hw_s *self);
/* get global microprocessor scratch pad register */
u32 hw_atl_scrpad_get(struct aq_hw_s *aq_hw, u32 scratch_scp);
/* get global microprocessor scratch pad 12 register */
u32 hw_atl_scrpad12_get(struct aq_hw_s *self);
/* get global microprocessor scratch pad 25 register */
u32 hw_atl_scrpad25_get(struct aq_hw_s *self);
#endif /* HW_ATL_LLH_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,649 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Atlantic Network Driver
*
* Copyright (C) 2014-2019 aQuantia Corporation
* Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File hw_atl_utils.h: Declaration of common functions for Atlantic hardware
* abstraction layer.
*/
#ifndef HW_ATL_UTILS_H
#define HW_ATL_UTILS_H
#define HW_ATL_FLUSH() { (void)aq_hw_read_reg(self, 0x10); }
/* Hardware tx descriptor */
struct __packed hw_atl_txd_s {
u64 buf_addr;
u32 ctl;
u32 ctl2; /* 63..46 - payload length, 45 - ctx enable, 44 - ctx index */
};
/* Hardware tx context descriptor */
struct __packed hw_atl_txc_s {
u32 rsvd;
u32 len;
u32 ctl;
u32 len2;
};
/* Hardware rx descriptor */
struct __packed hw_atl_rxd_s {
u64 buf_addr;
u64 hdr_addr;
};
/* Hardware rx descriptor writeback */
struct __packed hw_atl_rxd_wb_s {
u32 type;
u32 rss_hash;
u16 status;
u16 pkt_len;
u16 next_desc_ptr;
__le16 vlan;
};
/* Hardware rx HW TIMESTAMP writeback */
struct __packed hw_atl_rxd_hwts_wb_s {
u32 sec_hw;
u32 ns;
u32 sec_lw0;
u32 sec_lw1;
};
struct __packed hw_atl_stats_s {
u32 uprc;
u32 mprc;
u32 bprc;
u32 erpt;
u32 uptc;
u32 mptc;
u32 bptc;
u32 erpr;
u32 mbtc;
u32 bbtc;
u32 mbrc;
u32 bbrc;
u32 ubrc;
u32 ubtc;
u32 dpc;
};
struct __packed drv_msg_enable_wakeup {
union {
u32 pattern_mask;
struct {
u32 reason_arp_v4_pkt : 1;
u32 reason_ipv4_ping_pkt : 1;
u32 reason_ipv6_ns_pkt : 1;
u32 reason_ipv6_ping_pkt : 1;
u32 reason_link_up : 1;
u32 reason_link_down : 1;
u32 reason_maximum : 1;
};
};
union {
u32 offload_mask;
};
};
struct __packed magic_packet_pattern_s {
u8 mac_addr[ETH_ALEN];
};
struct __packed drv_msg_wol_add {
u32 priority;
u32 packet_type;
u32 pattern_id;
u32 next_pattern_offset;
struct magic_packet_pattern_s magic_packet_pattern;
};
struct __packed drv_msg_wol_remove {
u32 id;
};
struct __packed hw_atl_utils_mbox_header {
u32 version;
u32 transaction_id;
u32 error;
};
struct __packed hw_atl_ptp_offset {
u16 ingress_100;
u16 egress_100;
u16 ingress_1000;
u16 egress_1000;
u16 ingress_2500;
u16 egress_2500;
u16 ingress_5000;
u16 egress_5000;
u16 ingress_10000;
u16 egress_10000;
};
struct __packed hw_atl_cable_diag {
u8 fault;
u8 distance;
u8 far_distance;
u8 reserved;
};
enum gpio_pin_function {
GPIO_PIN_FUNCTION_NC,
GPIO_PIN_FUNCTION_VAUX_ENABLE,
GPIO_PIN_FUNCTION_EFUSE_BURN_ENABLE,
GPIO_PIN_FUNCTION_SFP_PLUS_DETECT,
GPIO_PIN_FUNCTION_TX_DISABLE,
GPIO_PIN_FUNCTION_RATE_SEL_0,
GPIO_PIN_FUNCTION_RATE_SEL_1,
GPIO_PIN_FUNCTION_TX_FAULT,
GPIO_PIN_FUNCTION_PTP0,
GPIO_PIN_FUNCTION_PTP1,
GPIO_PIN_FUNCTION_PTP2,
GPIO_PIN_FUNCTION_SIZE
};
struct __packed hw_atl_info {
u8 reserved[6];
u16 phy_fault_code;
u16 phy_temperature;
u8 cable_len;
u8 reserved1;
struct hw_atl_cable_diag cable_diag_data[4];
struct hw_atl_ptp_offset ptp_offset;
u8 reserved2[12];
u32 caps_lo;
u32 caps_hi;
u32 reserved_datapath;
u32 reserved3[7];
u32 reserved_simpleresp[3];
u32 reserved_linkstat[7];
u32 reserved_wakes_count;
u32 reserved_eee_stat[12];
u32 tx_stuck_cnt;
u32 setting_address;
u32 setting_length;
u32 caps_ex;
enum gpio_pin_function gpio_pin[3];
u32 pcie_aer_dump[18];
u16 snr_margin[4];
};
struct __packed hw_atl_utils_mbox {
struct hw_atl_utils_mbox_header header;
struct hw_atl_stats_s stats;
struct hw_atl_info info;
};
struct __packed offload_ip_info {
u8 v4_local_addr_count;
u8 v4_addr_count;
u8 v6_local_addr_count;
u8 v6_addr_count;
u32 v4_addr;
u32 v4_prefix;
u32 v6_addr;
u32 v6_prefix;
};
struct __packed offload_port_info {
u16 udp_port_count;
u16 tcp_port_count;
u32 udp_port;
u32 tcp_port;
};
struct __packed offload_ka_info {
u16 v4_ka_count;
u16 v6_ka_count;
u32 retry_count;
u32 retry_interval;
u32 v4_ka;
u32 v6_ka;
};
struct __packed offload_rr_info {
u32 rr_count;
u32 rr_buf_len;
u32 rr_id_x;
u32 rr_buf;
};
struct __packed offload_info {
u32 version;
u32 len;
u8 mac_addr[ETH_ALEN];
u8 reserved[2];
struct offload_ip_info ips;
struct offload_port_info ports;
struct offload_ka_info kas;
struct offload_rr_info rrs;
};
struct __packed hw_atl_utils_fw_rpc {
u32 msg_id;
union {
/* fw1x structures */
struct drv_msg_wol_add msg_wol_add;
struct drv_msg_wol_remove msg_wol_remove;
struct drv_msg_enable_wakeup msg_enable_wakeup;
/* fw2x structures */
struct offload_info fw2x_offloads;
};
};
/* Mailbox FW Request interface */
struct __packed hw_fw_request_ptp_gpio_ctrl {
u32 index;
u32 period;
u64 start;
};
struct __packed hw_fw_request_ptp_adj_freq {
u32 ns_mac;
u32 fns_mac;
u32 ns_phy;
u32 fns_phy;
u32 mac_ns_adj;
u32 mac_fns_adj;
};
struct __packed hw_fw_request_ptp_adj_clock {
u32 ns;
u32 sec;
int sign;
};
#define HW_AQ_FW_REQUEST_PTP_GPIO_CTRL 0x11
#define HW_AQ_FW_REQUEST_PTP_ADJ_FREQ 0x12
#define HW_AQ_FW_REQUEST_PTP_ADJ_CLOCK 0x13
struct __packed hw_fw_request_iface {
u32 msg_id;
union {
/* PTP FW Request */
struct hw_fw_request_ptp_gpio_ctrl ptp_gpio_ctrl;
struct hw_fw_request_ptp_adj_freq ptp_adj_freq;
struct hw_fw_request_ptp_adj_clock ptp_adj_clock;
};
};
struct __packed hw_atl_utils_settings {
u32 mtu;
u32 downshift_retry_count;
u32 link_pause_frame_quanta_100m;
u32 link_pause_frame_threshold_100m;
u32 link_pause_frame_quanta_1g;
u32 link_pause_frame_threshold_1g;
u32 link_pause_frame_quanta_2p5g;
u32 link_pause_frame_threshold_2p5g;
u32 link_pause_frame_quanta_5g;
u32 link_pause_frame_threshold_5g;
u32 link_pause_frame_quanta_10g;
u32 link_pause_frame_threshold_10g;
u32 pfc_quanta_class_0;
u32 pfc_threshold_class_0;
u32 pfc_quanta_class_1;
u32 pfc_threshold_class_1;
u32 pfc_quanta_class_2;
u32 pfc_threshold_class_2;
u32 pfc_quanta_class_3;
u32 pfc_threshold_class_3;
u32 pfc_quanta_class_4;
u32 pfc_threshold_class_4;
u32 pfc_quanta_class_5;
u32 pfc_threshold_class_5;
u32 pfc_quanta_class_6;
u32 pfc_threshold_class_6;
u32 pfc_quanta_class_7;
u32 pfc_threshold_class_7;
u32 eee_link_down_timeout;
u32 eee_link_up_timeout;
u32 eee_max_link_drops;
u32 eee_rates_mask;
u32 wake_timer;
u32 thermal_shutdown_off_temp;
u32 thermal_shutdown_warning_temp;
u32 thermal_shutdown_cold_temp;
u32 msm_options;
u32 dac_cable_serdes_modes;
u32 media_detect;
};
struct __packed smbus_request {
u32 msg_id;
u32 device_id;
u32 address;
u32 length;
};
enum macsec_msg_type {
macsec_cfg_msg = 0,
macsec_add_rx_sc_msg,
macsec_add_tx_sc_msg,
macsec_add_rx_sa_msg,
macsec_add_tx_sa_msg,
macsec_get_stats_msg,
};
struct __packed macsec_cfg_request {
u32 enabled;
u32 egress_threshold;
u32 ingress_threshold;
u32 interrupts_enabled;
};
struct __packed macsec_msg_fw_request {
u32 msg_id; /* not used */
u32 msg_type;
struct macsec_cfg_request cfg;
};
struct __packed macsec_msg_fw_response {
u32 result;
};
enum hw_atl_rx_action_with_traffic {
HW_ATL_RX_DISCARD,
HW_ATL_RX_HOST,
HW_ATL_RX_MNGMNT,
HW_ATL_RX_HOST_AND_MNGMNT,
HW_ATL_RX_WOL
};
struct aq_rx_filter_vlan {
u8 enable;
u8 location;
u16 vlan_id;
u8 queue;
};
#define HW_ATL_VLAN_MAX_FILTERS 16U
struct aq_rx_filter_l2 {
s8 queue;
u8 location;
u8 user_priority_en;
u8 user_priority;
u16 ethertype;
};
struct aq_rx_filter_l3l4 {
u32 cmd;
u8 location;
u32 ip_dst[4];
u32 ip_src[4];
u16 p_dst;
u16 p_src;
u8 is_ipv6;
};
enum hw_atl_rx_protocol_value_l3l4 {
HW_ATL_RX_TCP,
HW_ATL_RX_UDP,
HW_ATL_RX_SCTP,
HW_ATL_RX_ICMP
};
enum hw_atl_rx_ctrl_registers_l3l4 {
HW_ATL_RX_ENABLE_MNGMNT_QUEUE_L3L4 = BIT(22),
HW_ATL_RX_ENABLE_QUEUE_L3L4 = BIT(23),
HW_ATL_RX_ENABLE_ARP_FLTR_L3 = BIT(24),
HW_ATL_RX_ENABLE_CMP_PROT_L4 = BIT(25),
HW_ATL_RX_ENABLE_CMP_DEST_PORT_L4 = BIT(26),
HW_ATL_RX_ENABLE_CMP_SRC_PORT_L4 = BIT(27),
HW_ATL_RX_ENABLE_CMP_DEST_ADDR_L3 = BIT(28),
HW_ATL_RX_ENABLE_CMP_SRC_ADDR_L3 = BIT(29),
HW_ATL_RX_ENABLE_L3_IPV6 = BIT(30),
HW_ATL_RX_ENABLE_FLTR_L3L4 = BIT(31)
};
#define HW_ATL_RX_QUEUE_FL3L4_SHIFT 8U
#define HW_ATL_RX_ACTION_FL3F4_SHIFT 16U
#define HW_ATL_RX_CNT_REG_ADDR_IPV6 4U
#define HW_ATL_GET_REG_LOCATION_FL3L4(location) \
((location) - AQ_RX_FIRST_LOC_FL3L4)
enum hal_atl_utils_fw_state_e {
MPI_DEINIT = 0,
MPI_RESET = 1,
MPI_INIT = 2,
MPI_POWER = 4,
};
#define HAL_ATLANTIC_RATE_10G BIT(0)
#define HAL_ATLANTIC_RATE_5G BIT(1)
#define HAL_ATLANTIC_RATE_5GSR BIT(2)
#define HAL_ATLANTIC_RATE_2G5 BIT(3)
#define HAL_ATLANTIC_RATE_1G BIT(4)
#define HAL_ATLANTIC_RATE_100M BIT(5)
#define HAL_ATLANTIC_RATE_INVALID BIT(6)
#define HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD 0x4U
#define HAL_ATLANTIC_UTILS_FW_MSG_WOL_PRIOR 0x10000000U
#define HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN 0x1U
#define HAL_ATLANTIC_UTILS_FW_MSG_WOL_MAG_PKT 0x2U
#define HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL 0x5U
#define HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP 0x6U
enum hw_atl_fw2x_rate {
FW2X_RATE_100M = 0x20,
FW2X_RATE_1G = 0x100,
FW2X_RATE_2G5 = 0x200,
FW2X_RATE_5G = 0x400,
FW2X_RATE_10G = 0x800,
};
/* 0x370
* Link capabilities resolution register
*/
enum hw_atl_fw2x_caps_lo {
CAPS_LO_10BASET_HD = 0,
CAPS_LO_10BASET_FD,
CAPS_LO_100BASETX_HD,
CAPS_LO_100BASET4_HD,
CAPS_LO_100BASET2_HD,
CAPS_LO_100BASETX_FD = 5,
CAPS_LO_100BASET2_FD,
CAPS_LO_1000BASET_HD,
CAPS_LO_1000BASET_FD,
CAPS_LO_2P5GBASET_FD,
CAPS_LO_5GBASET_FD = 10,
CAPS_LO_10GBASET_FD,
CAPS_LO_AUTONEG,
CAPS_LO_SMBUS_READ,
CAPS_LO_SMBUS_WRITE,
CAPS_LO_MACSEC = 15,
CAPS_LO_RESERVED1,
CAPS_LO_WAKE_ON_LINK_FORCED,
CAPS_LO_HIGH_TEMP_WARNING = 29,
CAPS_LO_DRIVER_SCRATCHPAD = 30,
CAPS_LO_GLOBAL_FAULT = 31
};
/* 0x374
* Status register
*/
enum hw_atl_fw2x_caps_hi {
CAPS_HI_TPO2EN = 0,
CAPS_HI_10BASET_EEE,
CAPS_HI_RESERVED2,
CAPS_HI_PAUSE,
CAPS_HI_ASYMMETRIC_PAUSE,
CAPS_HI_100BASETX_EEE = 5,
CAPS_HI_PHY_BUF_SEND,
CAPS_HI_PHY_BUF_RECV,
CAPS_HI_1000BASET_FD_EEE,
CAPS_HI_2P5GBASET_FD_EEE,
CAPS_HI_5GBASET_FD_EEE = 10,
CAPS_HI_10GBASET_FD_EEE,
CAPS_HI_FW_REQUEST,
CAPS_HI_PHY_LOG,
CAPS_HI_EEE_AUTO_DISABLE_SETTINGS,
CAPS_HI_PFC = 15,
CAPS_HI_WAKE_ON_LINK,
CAPS_HI_CABLE_DIAG,
CAPS_HI_TEMPERATURE,
CAPS_HI_DOWNSHIFT,
CAPS_HI_PTP_AVB_EN_FW2X = 20,
CAPS_HI_THERMAL_SHUTDOWN,
CAPS_HI_LINK_DROP,
CAPS_HI_SLEEP_PROXY,
CAPS_HI_WOL,
CAPS_HI_MAC_STOP = 25,
CAPS_HI_EXT_LOOPBACK,
CAPS_HI_INT_LOOPBACK,
CAPS_HI_EFUSE_AGENT,
CAPS_HI_WOL_TIMER,
CAPS_HI_STATISTICS = 30,
CAPS_HI_TRANSACTION_ID,
};
/* 0x36C
* Control register
*/
enum hw_atl_fw2x_ctrl {
CTRL_RESERVED1 = 0,
CTRL_RESERVED2,
CTRL_RESERVED3,
CTRL_PAUSE,
CTRL_ASYMMETRIC_PAUSE,
CTRL_RESERVED4 = 5,
CTRL_RESERVED5,
CTRL_RESERVED6,
CTRL_1GBASET_FD_EEE,
CTRL_2P5GBASET_FD_EEE,
CTRL_5GBASET_FD_EEE = 10,
CTRL_10GBASET_FD_EEE,
CTRL_THERMAL_SHUTDOWN,
CTRL_PHY_LOGS,
CTRL_EEE_AUTO_DISABLE,
CTRL_PFC = 15,
CTRL_WAKE_ON_LINK,
CTRL_CABLE_DIAG,
CTRL_TEMPERATURE,
CTRL_DOWNSHIFT,
CTRL_PTP_AVB = 20,
CTRL_RESERVED7,
CTRL_LINK_DROP,
CTRL_SLEEP_PROXY,
CTRL_WOL,
CTRL_MAC_STOP = 25,
CTRL_EXT_LOOPBACK,
CTRL_INT_LOOPBACK,
CTRL_RESERVED8,
CTRL_WOL_TIMER,
CTRL_STATISTICS = 30,
CTRL_FORCE_RECONNECT,
};
enum hw_atl_caps_ex {
CAPS_EX_LED_CONTROL = 0,
CAPS_EX_LED0_MODE_LO,
CAPS_EX_LED0_MODE_HI,
CAPS_EX_LED1_MODE_LO,
CAPS_EX_LED1_MODE_HI,
CAPS_EX_LED2_MODE_LO = 5,
CAPS_EX_LED2_MODE_HI,
CAPS_EX_RESERVED07,
CAPS_EX_RESERVED08,
CAPS_EX_RESERVED09,
CAPS_EX_RESERVED10 = 10,
CAPS_EX_RESERVED11,
CAPS_EX_RESERVED12,
CAPS_EX_RESERVED13,
CAPS_EX_RESERVED14,
CAPS_EX_RESERVED15 = 15,
CAPS_EX_PHY_PTP_EN,
CAPS_EX_MAC_PTP_EN,
CAPS_EX_EXT_CLK_EN,
CAPS_EX_SCHED_DMA_EN,
CAPS_EX_PTP_GPIO_EN = 20,
CAPS_EX_UPDATE_SETTINGS,
CAPS_EX_PHY_CTRL_TS_PIN,
CAPS_EX_SNR_OPERATING_MARGIN,
CAPS_EX_RESERVED24,
CAPS_EX_RESERVED25 = 25,
CAPS_EX_RESERVED26,
CAPS_EX_RESERVED27,
CAPS_EX_RESERVED28,
CAPS_EX_RESERVED29,
CAPS_EX_RESERVED30 = 30,
CAPS_EX_RESERVED31
};
struct aq_hw_s;
struct aq_fw_ops;
struct aq_hw_caps_s;
struct aq_hw_link_status_s;
int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops);
int hw_atl_utils_soft_reset(struct aq_hw_s *self);
void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p);
int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
struct hw_atl_utils_mbox_header *pmbox);
void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
struct hw_atl_utils_mbox *pmbox);
void hw_atl_utils_mpi_set(struct aq_hw_s *self,
enum hal_atl_utils_fw_state_e state,
u32 speed);
int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self);
int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
u8 *mac);
unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps);
int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
const struct aq_hw_caps_s *aq_hw_caps,
u32 *regs_buff);
int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
unsigned int power_state);
int hw_atl_utils_hw_deinit(struct aq_hw_s *self);
u32 hw_atl_utils_get_fw_version(struct aq_hw_s *self);
int hw_atl_utils_update_stats(struct aq_hw_s *self);
struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self);
int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
u32 *p, u32 cnt);
int hw_atl_write_fwcfg_dwords(struct aq_hw_s *self, u32 *p, u32 cnt);
int hw_atl_write_fwsettings_dwords(struct aq_hw_s *self, u32 offset, u32 *p,
u32 cnt);
int hw_atl_utils_fw_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac);
int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size);
int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
struct hw_atl_utils_fw_rpc **rpc);
bool hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
extern const struct aq_fw_ops aq_fw_1x_ops;
extern const struct aq_fw_ops aq_fw_2x_ops;
#endif /* HW_ATL_UTILS_H */
@@ -0,0 +1,812 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Atlantic Network Driver
*
* Copyright (C) 2014-2019 aQuantia Corporation
* Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File hw_atl_utils_fw2x.c: Definition of firmware 2.x functions for
* Atlantic hardware abstraction layer.
*/
#include "../aq_hw.h"
#include "../aq_hw_utils.h"
#include "../aq_pci_func.h"
#include "../aq_ring.h"
#include "../aq_vec.h"
#include "../aq_nic.h"
#include "hw_atl_utils.h"
#include "hw_atl_llh.h"
#define HW_ATL_FW2X_MPI_LED_ADDR 0x31c
#define HW_ATL_FW2X_MPI_RPC_ADDR 0x334
#define HW_ATL_FW2X_MPI_MBOX_ADDR 0x360
#define HW_ATL_FW2X_MPI_EFUSE_ADDR 0x364
#define HW_ATL_FW2X_MPI_CONTROL_ADDR 0x368
#define HW_ATL_FW2X_MPI_CONTROL2_ADDR 0x36C
#define HW_ATL_FW2X_MPI_STATE_ADDR 0x370
#define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374
#define HW_ATL_FW3X_EXT_CONTROL_ADDR 0x378
#define HW_ATL_FW3X_EXT_STATE_ADDR 0x37c
#define HW_ATL_FW3X_PTP_ADJ_LSW_ADDR 0x50a0
#define HW_ATL_FW3X_PTP_ADJ_MSW_ADDR 0x50a4
#define HW_ATL_FW2X_CAP_PAUSE BIT(CAPS_HI_PAUSE)
#define HW_ATL_FW2X_CAP_ASYM_PAUSE BIT(CAPS_HI_ASYMMETRIC_PAUSE)
#define HW_ATL_FW2X_CAP_SLEEP_PROXY BIT(CAPS_HI_SLEEP_PROXY)
#define HW_ATL_FW2X_CAP_WOL BIT(CAPS_HI_WOL)
#define HW_ATL_FW2X_CTRL_WAKE_ON_LINK BIT(CTRL_WAKE_ON_LINK)
#define HW_ATL_FW2X_CTRL_SLEEP_PROXY BIT(CTRL_SLEEP_PROXY)
#define HW_ATL_FW2X_CTRL_WOL BIT(CTRL_WOL)
#define HW_ATL_FW2X_CTRL_LINK_DROP BIT(CTRL_LINK_DROP)
#define HW_ATL_FW2X_CTRL_PAUSE BIT(CTRL_PAUSE)
#define HW_ATL_FW2X_CTRL_TEMPERATURE BIT(CTRL_TEMPERATURE)
#define HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE BIT(CTRL_ASYMMETRIC_PAUSE)
#define HW_ATL_FW2X_CTRL_INT_LOOPBACK BIT(CTRL_INT_LOOPBACK)
#define HW_ATL_FW2X_CTRL_EXT_LOOPBACK BIT(CTRL_EXT_LOOPBACK)
#define HW_ATL_FW2X_CTRL_DOWNSHIFT BIT(CTRL_DOWNSHIFT)
#define HW_ATL_FW2X_CTRL_FORCE_RECONNECT BIT(CTRL_FORCE_RECONNECT)
#define HW_ATL_FW2X_CAP_EEE_1G_MASK BIT(CAPS_HI_1000BASET_FD_EEE)
#define HW_ATL_FW2X_CAP_EEE_2G5_MASK BIT(CAPS_HI_2P5GBASET_FD_EEE)
#define HW_ATL_FW2X_CAP_EEE_5G_MASK BIT(CAPS_HI_5GBASET_FD_EEE)
#define HW_ATL_FW2X_CAP_EEE_10G_MASK BIT(CAPS_HI_10GBASET_FD_EEE)
#define HW_ATL_FW2X_CAP_MACSEC BIT(CAPS_LO_MACSEC)
#define HAL_ATLANTIC_WOL_FILTERS_COUNT 8
#define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL 0x0E
#define HW_ATL_FW_VER_LED 0x03010026U
#define HW_ATL_FW_VER_MEDIA_CONTROL 0x0301005aU
struct __packed fw2x_msg_wol_pattern {
u8 mask[16];
u32 crc;
};
struct __packed fw2x_msg_wol {
u32 msg_id;
u8 hw_addr[ETH_ALEN];
u8 magic_packet_enabled;
u8 filter_count;
struct fw2x_msg_wol_pattern filter[HAL_ATLANTIC_WOL_FILTERS_COUNT];
u8 link_up_enabled;
u8 link_down_enabled;
u16 reserved;
u32 link_up_timeout;
u32 link_down_timeout;
};
static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed);
static int aq_fw2x_set_state(struct aq_hw_s *self,
enum hal_atl_utils_fw_state_e state);
static u32 aq_fw2x_mbox_get(struct aq_hw_s *self);
static u32 aq_fw2x_rpc_get(struct aq_hw_s *self);
static int aq_fw2x_settings_get(struct aq_hw_s *self, u32 *addr);
static u32 aq_fw2x_state_get(struct aq_hw_s *self);
static u32 aq_fw2x_state2_get(struct aq_hw_s *self);
static int aq_fw2x_init(struct aq_hw_s *self)
{
int err = 0;
/* check 10 times by 1ms */
err = readx_poll_timeout_atomic(aq_fw2x_mbox_get,
self, self->mbox_addr,
self->mbox_addr != 0U,
1000U, 10000U);
err = readx_poll_timeout_atomic(aq_fw2x_rpc_get,
self, self->rpc_addr,
self->rpc_addr != 0U,
1000U, 100000U);
err = aq_fw2x_settings_get(self, &self->settings_addr);
return err;
}
static int aq_fw2x_deinit(struct aq_hw_s *self)
{
int err = aq_fw2x_set_link_speed(self, 0);
if (!err)
err = aq_fw2x_set_state(self, MPI_DEINIT);
return err;
}
static enum hw_atl_fw2x_rate link_speed_mask_2fw2x_ratemask(u32 speed)
{
enum hw_atl_fw2x_rate rate = 0;
if (speed & AQ_NIC_RATE_10G)
rate |= FW2X_RATE_10G;
if (speed & AQ_NIC_RATE_5G)
rate |= FW2X_RATE_5G;
if (speed & AQ_NIC_RATE_2G5)
rate |= FW2X_RATE_2G5;
if (speed & AQ_NIC_RATE_1G)
rate |= FW2X_RATE_1G;
if (speed & AQ_NIC_RATE_100M)
rate |= FW2X_RATE_100M;
return rate;
}
static u32 fw2x_to_eee_mask(u32 speed)
{
u32 rate = 0;
if (speed & HW_ATL_FW2X_CAP_EEE_10G_MASK)
rate |= AQ_NIC_RATE_EEE_10G;
if (speed & HW_ATL_FW2X_CAP_EEE_5G_MASK)
rate |= AQ_NIC_RATE_EEE_5G;
if (speed & HW_ATL_FW2X_CAP_EEE_2G5_MASK)
rate |= AQ_NIC_RATE_EEE_2G5;
if (speed & HW_ATL_FW2X_CAP_EEE_1G_MASK)
rate |= AQ_NIC_RATE_EEE_1G;
return rate;
}
static u32 eee_mask_to_fw2x(u32 speed)
{
u32 rate = 0;
if (speed & AQ_NIC_RATE_EEE_10G)
rate |= HW_ATL_FW2X_CAP_EEE_10G_MASK;
if (speed & AQ_NIC_RATE_EEE_5G)
rate |= HW_ATL_FW2X_CAP_EEE_5G_MASK;
if (speed & AQ_NIC_RATE_EEE_2G5)
rate |= HW_ATL_FW2X_CAP_EEE_2G5_MASK;
if (speed & AQ_NIC_RATE_EEE_1G)
rate |= HW_ATL_FW2X_CAP_EEE_1G_MASK;
return rate;
}
static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed)
{
u32 val = link_speed_mask_2fw2x_ratemask(speed);
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, val);
return 0;
}
static void aq_fw2x_upd_flow_control_bits(struct aq_hw_s *self,
u32 *mpi_state, u32 fc)
{
*mpi_state &= ~(HW_ATL_FW2X_CTRL_PAUSE |
HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE);
switch (fc) {
/* There is not explicit mode of RX only pause frames,
* thus, we join this mode with FC full.
* FC full is either Rx, either Tx, or both.
*/
case AQ_NIC_FC_FULL:
case AQ_NIC_FC_RX:
*mpi_state |= HW_ATL_FW2X_CTRL_PAUSE |
HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE;
break;
case AQ_NIC_FC_TX:
*mpi_state |= HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE;
break;
}
}
static void aq_fw2x_upd_eee_rate_bits(struct aq_hw_s *self, u32 *mpi_opts,
u32 eee_speeds)
{
*mpi_opts &= ~(HW_ATL_FW2X_CAP_EEE_1G_MASK |
HW_ATL_FW2X_CAP_EEE_2G5_MASK |
HW_ATL_FW2X_CAP_EEE_5G_MASK |
HW_ATL_FW2X_CAP_EEE_10G_MASK);
*mpi_opts |= eee_mask_to_fw2x(eee_speeds);
}
static int aq_fw2x_set_state(struct aq_hw_s *self,
enum hal_atl_utils_fw_state_e state)
{
u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
switch (state) {
case MPI_INIT:
mpi_state &= ~BIT(CAPS_HI_LINK_DROP);
aq_fw2x_upd_eee_rate_bits(self, &mpi_state, cfg->eee_speeds);
aq_fw2x_upd_flow_control_bits(self, &mpi_state,
self->aq_nic_cfg->fc.req);
break;
case MPI_DEINIT:
mpi_state |= BIT(CAPS_HI_LINK_DROP);
break;
case MPI_RESET:
case MPI_POWER:
/* No actions */
break;
}
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state);
return 0;
}
static int aq_fw2x_update_link_status(struct aq_hw_s *self)
{
struct aq_hw_link_status_s *link_status = &self->aq_link_status;
u32 mpi_state;
u32 speed;
mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR);
speed = mpi_state & (FW2X_RATE_100M | FW2X_RATE_1G |
FW2X_RATE_2G5 | FW2X_RATE_5G |
FW2X_RATE_10G);
if (speed) {
if (speed & FW2X_RATE_10G)
link_status->mbps = 10000;
else if (speed & FW2X_RATE_5G)
link_status->mbps = 5000;
else if (speed & FW2X_RATE_2G5)
link_status->mbps = 2500;
else if (speed & FW2X_RATE_1G)
link_status->mbps = 1000;
else if (speed & FW2X_RATE_100M)
link_status->mbps = 100;
else
link_status->mbps = 10000;
} else {
link_status->mbps = 0;
}
link_status->full_duplex = true;
return 0;
}
static int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
{
u32 efuse_addr = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_EFUSE_ADDR);
u32 mac_addr[2] = { 0 };
int err = 0;
if (efuse_addr != 0) {
err = hw_atl_utils_fw_downld_dwords(self,
efuse_addr + (40U * 4U),
mac_addr,
ARRAY_SIZE(mac_addr));
if (err)
return err;
mac_addr[0] = __swab32(mac_addr[0]);
mac_addr[1] = __swab32(mac_addr[1]);
}
ether_addr_copy(mac, (u8 *)mac_addr);
return err;
}
static int aq_fw2x_update_stats(struct aq_hw_s *self)
{
u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
u32 orig_stats_val = mpi_opts & BIT(CAPS_HI_STATISTICS);
u32 stats_val;
int err = 0;
/* Toggle statistics bit for FW to update */
mpi_opts = mpi_opts ^ BIT(CAPS_HI_STATISTICS);
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
/* Wait FW to report back */
err = readx_poll_timeout_atomic(aq_fw2x_state2_get,
self, stats_val,
orig_stats_val != (stats_val &
BIT(CAPS_HI_STATISTICS)),
1U, 10000U);
if (err)
return err;
return hw_atl_utils_update_stats(self);
}
static int aq_fw2x_get_phy_temp(struct aq_hw_s *self, int *temp)
{
u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
u32 temp_val = mpi_opts & HW_ATL_FW2X_CTRL_TEMPERATURE;
u32 phy_temp_offset;
u32 temp_res;
int err = 0;
u32 val;
phy_temp_offset = self->mbox_addr + offsetof(struct hw_atl_utils_mbox,
info.phy_temperature);
/* Toggle statistics bit for FW to 0x36C.18 (CTRL_TEMPERATURE) */
mpi_opts = mpi_opts ^ HW_ATL_FW2X_CTRL_TEMPERATURE;
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
/* Wait FW to report back */
err = readx_poll_timeout_atomic(aq_fw2x_state2_get, self, val,
temp_val !=
(val & HW_ATL_FW2X_CTRL_TEMPERATURE),
1U, 10000U);
err = hw_atl_utils_fw_downld_dwords(self, phy_temp_offset,
&temp_res, 1);
if (err)
return err;
/* Convert PHY temperature from 1/256 degree Celsius
* to 1/1000 degree Celsius.
*/
*temp = (int16_t)(temp_res & 0xFFFF) * 1000 / 256;
return 0;
}
static int aq_fw2x_set_wol(struct aq_hw_s *self, const u8 *mac)
{
struct hw_atl_utils_fw_rpc *rpc = NULL;
struct offload_info *info = NULL;
u32 wol_bits = 0;
u32 rpc_size;
int err = 0;
u32 val;
if (self->aq_nic_cfg->wol & WAKE_PHY) {
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR,
HW_ATL_FW2X_CTRL_LINK_DROP);
readx_poll_timeout_atomic(aq_fw2x_state2_get, self, val,
(val &
HW_ATL_FW2X_CTRL_LINK_DROP) != 0,
1000, 100000);
wol_bits |= HW_ATL_FW2X_CTRL_WAKE_ON_LINK;
}
if (self->aq_nic_cfg->wol & WAKE_MAGIC) {
wol_bits |= HW_ATL_FW2X_CTRL_SLEEP_PROXY |
HW_ATL_FW2X_CTRL_WOL;
err = hw_atl_utils_fw_rpc_wait(self, &rpc);
if (err < 0)
goto err_exit;
rpc_size = sizeof(*info) +
offsetof(struct hw_atl_utils_fw_rpc, fw2x_offloads);
memset(rpc, 0, rpc_size);
info = &rpc->fw2x_offloads;
memcpy(info->mac_addr, mac, ETH_ALEN);
info->len = sizeof(*info);
err = hw_atl_utils_fw_rpc_call(self, rpc_size);
if (err < 0)
goto err_exit;
}
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, wol_bits);
err_exit:
return err;
}
static int aq_fw2x_set_power(struct aq_hw_s *self, unsigned int power_state,
const u8 *mac)
{
int err = 0;
if (self->aq_nic_cfg->wol)
err = aq_fw2x_set_wol(self, mac);
return err;
}
static int aq_fw2x_send_fw_request(struct aq_hw_s *self,
const struct hw_fw_request_iface *fw_req,
size_t size)
{
u32 ctrl2, orig_ctrl2;
u32 dword_cnt;
int err = 0;
u32 val;
/* Write data to drvIface Mailbox */
dword_cnt = size / sizeof(u32);
if (size % sizeof(u32))
dword_cnt++;
err = hw_atl_write_fwcfg_dwords(self, (void *)fw_req, dword_cnt);
if (err < 0)
goto err_exit;
/* Toggle statistics bit for FW to update */
ctrl2 = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
orig_ctrl2 = ctrl2 & BIT(CAPS_HI_FW_REQUEST);
ctrl2 = ctrl2 ^ BIT(CAPS_HI_FW_REQUEST);
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, ctrl2);
/* Wait FW to report back */
err = readx_poll_timeout_atomic(aq_fw2x_state2_get, self, val,
orig_ctrl2 != (val &
BIT(CAPS_HI_FW_REQUEST)),
1U, 10000U);
err_exit:
return err;
}
static void aq_fw3x_enable_ptp(struct aq_hw_s *self, int enable)
{
u32 ptp_opts = aq_hw_read_reg(self, HW_ATL_FW3X_EXT_STATE_ADDR);
u32 all_ptp_features = BIT(CAPS_EX_PHY_PTP_EN) |
BIT(CAPS_EX_PTP_GPIO_EN);
if (enable)
ptp_opts |= all_ptp_features;
else
ptp_opts &= ~all_ptp_features;
aq_hw_write_reg(self, HW_ATL_FW3X_EXT_CONTROL_ADDR, ptp_opts);
}
static void aq_fw3x_adjust_ptp(struct aq_hw_s *self, uint64_t adj)
{
aq_hw_write_reg(self, HW_ATL_FW3X_PTP_ADJ_LSW_ADDR,
(adj >> 0) & 0xffffffff);
aq_hw_write_reg(self, HW_ATL_FW3X_PTP_ADJ_MSW_ADDR,
(adj >> 32) & 0xffffffff);
}
static int aq_fw2x_led_control(struct aq_hw_s *self, u32 mode)
{
if (self->fw_ver_actual < HW_ATL_FW_VER_LED)
return -EOPNOTSUPP;
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_LED_ADDR, mode);
return 0;
}
static int aq_fw2x_set_eee_rate(struct aq_hw_s *self, u32 speed)
{
u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
aq_fw2x_upd_eee_rate_bits(self, &mpi_opts, speed);
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
return 0;
}
static int aq_fw2x_get_eee_rate(struct aq_hw_s *self, u32 *rate,
u32 *supported_rates)
{
u32 mpi_state;
u32 caps_hi;
int err = 0;
u32 offset;
offset = self->mbox_addr + offsetof(struct hw_atl_utils_mbox,
info.caps_hi);
err = hw_atl_utils_fw_downld_dwords(self, offset, &caps_hi, 1);
if (err)
return err;
*supported_rates = fw2x_to_eee_mask(caps_hi);
mpi_state = aq_fw2x_state2_get(self);
*rate = fw2x_to_eee_mask(mpi_state);
return err;
}
static int aq_fw2x_renegotiate(struct aq_hw_s *self)
{
u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
mpi_opts |= BIT(CTRL_FORCE_RECONNECT);
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
return 0;
}
static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
{
u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
aq_fw2x_upd_flow_control_bits(self, &mpi_state,
self->aq_nic_cfg->fc.req);
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state);
return 0;
}
static u32 aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fcmode)
{
u32 mpi_state = aq_fw2x_state2_get(self);
*fcmode = 0;
if (mpi_state & HW_ATL_FW2X_CAP_PAUSE)
*fcmode |= AQ_NIC_FC_RX;
if (mpi_state & HW_ATL_FW2X_CAP_ASYM_PAUSE)
*fcmode |= AQ_NIC_FC_TX;
return 0;
}
static int aq_fw2x_set_phyloopback(struct aq_hw_s *self, u32 mode, bool enable)
{
u32 mpi_opts;
switch (mode) {
case AQ_HW_LOOPBACK_PHYINT_SYS:
mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
if (enable)
mpi_opts |= HW_ATL_FW2X_CTRL_INT_LOOPBACK;
else
mpi_opts &= ~HW_ATL_FW2X_CTRL_INT_LOOPBACK;
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
break;
case AQ_HW_LOOPBACK_PHYEXT_SYS:
mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
if (enable)
mpi_opts |= HW_ATL_FW2X_CTRL_EXT_LOOPBACK;
else
mpi_opts &= ~HW_ATL_FW2X_CTRL_EXT_LOOPBACK;
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
break;
default:
return -EINVAL;
}
return 0;
}
static u32 aq_fw2x_mbox_get(struct aq_hw_s *self)
{
return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR);
}
static u32 aq_fw2x_rpc_get(struct aq_hw_s *self)
{
return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR);
}
static int aq_fw2x_settings_get(struct aq_hw_s *self, u32 *addr)
{
int err = 0;
u32 offset;
offset = self->mbox_addr + offsetof(struct hw_atl_utils_mbox,
info.setting_address);
err = hw_atl_utils_fw_downld_dwords(self, offset, addr, 1);
return err;
}
static u32 aq_fw2x_state_get(struct aq_hw_s *self)
{
return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR);
}
static u32 aq_fw2x_state2_get(struct aq_hw_s *self)
{
return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);
}
static int aq_fw2x_set_downshift(struct aq_hw_s *self, u32 counter)
{
int err = 0;
u32 mpi_opts;
u32 offset;
offset = offsetof(struct hw_atl_utils_settings, downshift_retry_count);
err = hw_atl_write_fwsettings_dwords(self, offset, &counter, 1);
if (err)
return err;
mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
if (counter)
mpi_opts |= HW_ATL_FW2X_CTRL_DOWNSHIFT;
else
mpi_opts &= ~HW_ATL_FW2X_CTRL_DOWNSHIFT;
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
return err;
}
static int aq_fw2x_set_media_detect(struct aq_hw_s *self, bool on)
{
u32 enable;
u32 offset;
if (self->fw_ver_actual < HW_ATL_FW_VER_MEDIA_CONTROL)
return -EOPNOTSUPP;
offset = offsetof(struct hw_atl_utils_settings, media_detect);
enable = on;
return hw_atl_write_fwsettings_dwords(self, offset, &enable, 1);
}
static u32 aq_fw2x_get_link_capabilities(struct aq_hw_s *self)
{
int err = 0;
u32 offset;
u32 val;
offset = self->mbox_addr +
offsetof(struct hw_atl_utils_mbox, info.caps_lo);
err = hw_atl_utils_fw_downld_dwords(self, offset, &val, 1);
if (err)
return 0;
return val;
}
static int aq_fw2x_send_macsec_req(struct aq_hw_s *hw,
struct macsec_msg_fw_request *req,
struct macsec_msg_fw_response *response)
{
u32 low_status, low_req = 0;
u32 dword_cnt;
u32 caps_lo;
u32 offset;
int err;
if (!req || !response)
return -EINVAL;
caps_lo = aq_fw2x_get_link_capabilities(hw);
if (!(caps_lo & BIT(CAPS_LO_MACSEC)))
return -EOPNOTSUPP;
/* Write macsec request to cfg memory */
dword_cnt = (sizeof(*req) + sizeof(u32) - 1) / sizeof(u32);
err = hw_atl_write_fwcfg_dwords(hw, (void *)req, dword_cnt);
if (err < 0)
return err;
/* Toggle 0x368.CAPS_LO_MACSEC bit */
low_req = aq_hw_read_reg(hw, HW_ATL_FW2X_MPI_CONTROL_ADDR);
low_req ^= HW_ATL_FW2X_CAP_MACSEC;
aq_hw_write_reg(hw, HW_ATL_FW2X_MPI_CONTROL_ADDR, low_req);
/* Wait FW to report back */
err = readx_poll_timeout_atomic(aq_fw2x_state_get, hw, low_status,
low_req != (low_status & BIT(CAPS_LO_MACSEC)), 1U, 10000U);
if (err)
return -EIO;
/* Read status of write operation */
offset = hw->rpc_addr + sizeof(u32);
err = hw_atl_utils_fw_downld_dwords(hw, offset, (u32 *)(void *)response,
sizeof(*response) / sizeof(u32));
return err;
}
static int aq_fw2x_read_module_eeprom(struct aq_hw_s *self, u8 dev_addr,
u8 reg_start_addr, int len, u8 *data)
{
u32 low_status, orig_low_status, low_req = 0;
u32 res_bytes_remain_cnt = len % sizeof(u32);
u32 res_dword_cnt = len / sizeof(u32);
struct smbus_request request = { 0 };
u32 req_dword_cnt;
u32 result = 0;
u32 caps_lo;
u32 offset;
int err;
caps_lo = aq_fw2x_get_link_capabilities(self);
if (!(caps_lo & BIT(CAPS_LO_SMBUS_READ)))
return -EOPNOTSUPP;
request.msg_id = 0;
request.device_id = dev_addr;
request.address = reg_start_addr;
request.length = len;
/* Write SMBUS request to cfg memory */
req_dword_cnt = DIV_ROUND_UP(sizeof(request), sizeof(u32));
err = hw_atl_write_fwcfg_dwords(self, (void *)&request, req_dword_cnt);
if (err < 0)
return err;
/* Toggle 0x368.CAPS_LO_SMBUS_READ bit */
low_req = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);
orig_low_status = low_req & BIT(CAPS_LO_SMBUS_READ);
low_req ^= BIT(CAPS_LO_SMBUS_READ);
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, low_req);
/* Wait FW to report back */
err = readx_poll_timeout_atomic(aq_fw2x_state_get, self, low_status,
orig_low_status != (low_status &
BIT(CAPS_LO_SMBUS_READ)),
10U, 100000U);
if (err)
return err;
/* Read status of read operation */
offset = self->rpc_addr + sizeof(u32);
err = hw_atl_utils_fw_downld_dwords(self, offset, &result,
sizeof(result) / sizeof(u32));
if (err < 0)
return err;
if (result)
return -EIO;
/* Read response full DWORD data */
if (res_dword_cnt) {
offset = self->rpc_addr + sizeof(u32) * 2;
err = hw_atl_utils_fw_downld_dwords(self, offset, (u32 *)data,
res_dword_cnt);
if (err < 0)
return err;
}
/* Read response trailing bytes data */
if (res_bytes_remain_cnt) {
u32 bytes_remain_val = 0;
offset = self->rpc_addr +
(sizeof(u32) * 2) +
(res_dword_cnt * sizeof(u32));
err = hw_atl_utils_fw_downld_dwords(self, offset,
&bytes_remain_val, 1);
if (err < 0)
return err;
memcpy(data + len - res_bytes_remain_cnt,
&bytes_remain_val, res_bytes_remain_cnt);
}
return 0;
}
const struct aq_fw_ops aq_fw_2x_ops = {
.init = aq_fw2x_init,
.deinit = aq_fw2x_deinit,
.reset = NULL,
.renegotiate = aq_fw2x_renegotiate,
.get_mac_permanent = aq_fw2x_get_mac_permanent,
.set_link_speed = aq_fw2x_set_link_speed,
.set_state = aq_fw2x_set_state,
.update_link_status = aq_fw2x_update_link_status,
.update_stats = aq_fw2x_update_stats,
.get_mac_temp = NULL,
.get_phy_temp = aq_fw2x_get_phy_temp,
.set_power = aq_fw2x_set_power,
.set_eee_rate = aq_fw2x_set_eee_rate,
.get_eee_rate = aq_fw2x_get_eee_rate,
.set_flow_control = aq_fw2x_set_flow_control,
.get_flow_control = aq_fw2x_get_flow_control,
.send_fw_request = aq_fw2x_send_fw_request,
.enable_ptp = aq_fw3x_enable_ptp,
.led_control = aq_fw2x_led_control,
.set_phyloopback = aq_fw2x_set_phyloopback,
.set_downshift = aq_fw2x_set_downshift,
.set_media_detect = aq_fw2x_set_media_detect,
.adjust_ptp = aq_fw3x_adjust_ptp,
.get_link_capabilities = aq_fw2x_get_link_capabilities,
.send_macsec_req = aq_fw2x_send_macsec_req,
.read_module_eeprom = aq_fw2x_read_module_eeprom,
};