Commit 0b634c0e authored by David S. Miller's avatar David S. Miller

Merge branch 'atlantic-fixes'

Igor Russkikh says:

====================
Marvell atlantic 2020/02 updates

Hi David, here is another set of bugfixes on AQC family found on
last integration phase.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4e867c9a 5a292c89
......@@ -722,6 +722,11 @@ static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
if (flags & ~AQ_PRIV_FLAGS_MASK)
return -EOPNOTSUPP;
if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) {
netdev_info(ndev, "Can't enable more than one loopback simultaneously\n");
return -EINVAL;
}
cfg->priv_flags = flags;
if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
......
......@@ -163,7 +163,7 @@ aq_check_approve_fvlan(struct aq_nic_s *aq_nic,
}
if ((aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
(!test_bit(be16_to_cpu(fsp->h_ext.vlan_tci),
(!test_bit(be16_to_cpu(fsp->h_ext.vlan_tci) & VLAN_VID_MASK,
aq_nic->active_vlans))) {
netdev_err(aq_nic->ndev,
"ethtool: unknown vlan-id specified");
......
......@@ -337,6 +337,8 @@ struct aq_fw_ops {
void (*enable_ptp)(struct aq_hw_s *self, int enable);
void (*adjust_ptp)(struct aq_hw_s *self, uint64_t adj);
int (*set_eee_rate)(struct aq_hw_s *self, u32 speed);
int (*get_eee_rate)(struct aq_hw_s *self, u32 *rate,
......
......@@ -533,8 +533,10 @@ unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb,
dx_buff->len,
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa)))
if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) {
ret = 0;
goto exit;
}
first = dx_buff;
dx_buff->len_pkt = skb->len;
......@@ -655,10 +657,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
if (likely(frags)) {
err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw,
ring, frags);
if (err >= 0) {
++ring->stats.tx.packets;
ring->stats.tx.bytes += skb->len;
}
} else {
err = NETDEV_TX_BUSY;
}
......
......@@ -359,6 +359,7 @@ static int aq_suspend_common(struct device *dev, bool deep)
netif_device_detach(nic->ndev);
netif_tx_stop_all_queues(nic->ndev);
if (netif_running(nic->ndev))
aq_nic_stop(nic);
if (deep) {
......@@ -375,7 +376,7 @@ static int atl_resume_common(struct device *dev, bool deep)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct aq_nic_s *nic;
int ret;
int ret = 0;
nic = pci_get_drvdata(pdev);
......@@ -390,9 +391,11 @@ static int atl_resume_common(struct device *dev, bool deep)
goto err_exit;
}
if (netif_running(nic->ndev)) {
ret = aq_nic_start(nic);
if (ret)
goto err_exit;
}
netif_device_attach(nic->ndev);
netif_tx_start_all_queues(nic->ndev);
......
......@@ -272,9 +272,12 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
}
}
if (unlikely(buff->is_eop))
dev_kfree_skb_any(buff->skb);
if (unlikely(buff->is_eop)) {
++self->stats.rx.packets;
self->stats.tx.bytes += buff->skb->len;
dev_kfree_skb_any(buff->skb);
}
buff->pa = 0U;
buff->eop_index = 0xffffU;
self->sw_head = aq_ring_next_dx(self, self->sw_head);
......@@ -351,7 +354,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
err = 0;
goto err_exit;
}
if (buff->is_error || buff->is_cso_err) {
if (buff->is_error ||
(buff->is_lro && buff->is_cso_err)) {
buff_ = buff;
do {
next_ = buff_->next,
......
......@@ -78,7 +78,8 @@ struct __packed aq_ring_buff_s {
u32 is_cleaned:1;
u32 is_error:1;
u32 is_vlan:1;
u32 rsvd3:4;
u32 is_lro:1;
u32 rsvd3:3;
u16 eop_index;
u16 rsvd4;
};
......
......@@ -823,6 +823,8 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
}
}
buff->is_lro = !!(HW_ATL_B0_RXD_WB_STAT2_RSCCNT &
rxd_wb->status);
if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) {
buff->len = rxd_wb->pkt_len %
AQ_CFG_RX_FRAME_MAX;
......@@ -835,8 +837,7 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
rxd_wb->pkt_len > AQ_CFG_RX_FRAME_MAX ?
AQ_CFG_RX_FRAME_MAX : rxd_wb->pkt_len;
if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT &
rxd_wb->status) {
if (buff->is_lro) {
/* LRO */
buff->next = rxd_wb->next_desc_ptr;
++ring->stats.rx.lro_packets;
......@@ -884,13 +885,16 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,
{
struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
unsigned int i = 0U;
u32 vlan_promisc;
u32 l2_promisc;
hw_atl_rpfl2promiscuous_mode_en_set(self,
IS_FILTER_ENABLED(IFF_PROMISC));
l2_promisc = IS_FILTER_ENABLED(IFF_PROMISC) ||
!!(cfg->priv_flags & BIT(AQ_HW_LOOPBACK_DMA_NET));
vlan_promisc = l2_promisc || cfg->is_vlan_force_promisc;
hw_atl_rpf_vlan_prom_mode_en_set(self,
IS_FILTER_ENABLED(IFF_PROMISC) ||
cfg->is_vlan_force_promisc);
hw_atl_rpfl2promiscuous_mode_en_set(self, l2_promisc);
hw_atl_rpf_vlan_prom_mode_en_set(self, vlan_promisc);
hw_atl_rpfl2multicast_flr_en_set(self,
IS_FILTER_ENABLED(IFF_ALLMULTI) &&
......@@ -1161,6 +1165,8 @@ static int hw_atl_b0_adj_sys_clock(struct aq_hw_s *self, s64 delta)
{
self->ptp_clk_offset += delta;
self->aq_fw_ops->adjust_ptp(self, self->ptp_clk_offset);
return 0;
}
......@@ -1211,7 +1217,7 @@ static int hw_atl_b0_gpio_pulse(struct aq_hw_s *self, u32 index,
fwreq.ptp_gpio_ctrl.index = index;
fwreq.ptp_gpio_ctrl.period = period;
/* Apply time offset */
fwreq.ptp_gpio_ctrl.start = start - self->ptp_clk_offset;
fwreq.ptp_gpio_ctrl.start = start;
size = sizeof(fwreq.msg_id) + sizeof(fwreq.ptp_gpio_ctrl);
return self->aq_fw_ops->send_fw_request(self, &fwreq, size);
......
......@@ -22,6 +22,7 @@
#define HW_ATL_MIF_ADDR 0x0208U
#define HW_ATL_MIF_VAL 0x020CU
#define HW_ATL_MPI_RPC_ADDR 0x0334U
#define HW_ATL_RPC_CONTROL_ADR 0x0338U
#define HW_ATL_RPC_STATE_ADR 0x033CU
......@@ -53,15 +54,14 @@ enum mcp_area {
};
static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
enum hal_atl_utils_fw_state_e state);
static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self);
static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self);
static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self);
static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self);
static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self);
static u32 aq_fw1x_rpc_get(struct aq_hw_s *self);
int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
{
......@@ -476,6 +476,10 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
self, self->mbox_addr,
self->mbox_addr != 0U,
1000U, 10000U);
err = readx_poll_timeout_atomic(aq_fw1x_rpc_get, self,
self->rpc_addr,
self->rpc_addr != 0U,
1000U, 100000U);
return err;
}
......@@ -531,6 +535,12 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
self, fw.val,
sw.tid == fw.tid,
1000U, 100000U);
if (err < 0)
goto err_exit;
err = aq_hw_err_from_flags(self);
if (err < 0)
goto err_exit;
if (fw.len == 0xFFFFU) {
err = hw_atl_utils_fw_rpc_call(self, sw.len);
......@@ -1025,6 +1035,11 @@ static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self)
return aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR);
}
static u32 aq_fw1x_rpc_get(struct aq_hw_s *self)
{
return aq_hw_read_reg(self, HW_ATL_MPI_RPC_ADDR);
}
const struct aq_fw_ops aq_fw_1x_ops = {
.init = hw_atl_utils_mpi_create,
.deinit = hw_atl_fw1x_deinit,
......
......@@ -30,6 +30,9 @@
#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)
......@@ -475,6 +478,14 @@ static void aq_fw3x_enable_ptp(struct aq_hw_s *self, int enable)
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)
......@@ -633,4 +644,5 @@ const struct aq_fw_ops aq_fw_2x_ops = {
.enable_ptp = aq_fw3x_enable_ptp,
.led_control = aq_fw2x_led_control,
.set_phyloopback = aq_fw2x_set_phyloopback,
.adjust_ptp = aq_fw3x_adjust_ptp,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment