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) ...@@ -722,6 +722,11 @@ static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
if (flags & ~AQ_PRIV_FLAGS_MASK) if (flags & ~AQ_PRIV_FLAGS_MASK)
return -EOPNOTSUPP; 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; cfg->priv_flags = flags;
if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) { if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
......
...@@ -163,7 +163,7 @@ aq_check_approve_fvlan(struct aq_nic_s *aq_nic, ...@@ -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) && 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))) { aq_nic->active_vlans))) {
netdev_err(aq_nic->ndev, netdev_err(aq_nic->ndev,
"ethtool: unknown vlan-id specified"); "ethtool: unknown vlan-id specified");
......
...@@ -337,6 +337,8 @@ struct aq_fw_ops { ...@@ -337,6 +337,8 @@ struct aq_fw_ops {
void (*enable_ptp)(struct aq_hw_s *self, int enable); 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 (*set_eee_rate)(struct aq_hw_s *self, u32 speed);
int (*get_eee_rate)(struct aq_hw_s *self, u32 *rate, 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, ...@@ -533,8 +533,10 @@ unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb,
dx_buff->len, dx_buff->len,
DMA_TO_DEVICE); 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; goto exit;
}
first = dx_buff; first = dx_buff;
dx_buff->len_pkt = skb->len; dx_buff->len_pkt = skb->len;
...@@ -655,10 +657,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) ...@@ -655,10 +657,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
if (likely(frags)) { if (likely(frags)) {
err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw, err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw,
ring, frags); ring, frags);
if (err >= 0) {
++ring->stats.tx.packets;
ring->stats.tx.bytes += skb->len;
}
} else { } else {
err = NETDEV_TX_BUSY; err = NETDEV_TX_BUSY;
} }
......
...@@ -359,7 +359,8 @@ static int aq_suspend_common(struct device *dev, bool deep) ...@@ -359,7 +359,8 @@ static int aq_suspend_common(struct device *dev, bool deep)
netif_device_detach(nic->ndev); netif_device_detach(nic->ndev);
netif_tx_stop_all_queues(nic->ndev); netif_tx_stop_all_queues(nic->ndev);
aq_nic_stop(nic); if (netif_running(nic->ndev))
aq_nic_stop(nic);
if (deep) { if (deep) {
aq_nic_deinit(nic, !nic->aq_hw->aq_nic_cfg->wol); aq_nic_deinit(nic, !nic->aq_hw->aq_nic_cfg->wol);
...@@ -375,7 +376,7 @@ static int atl_resume_common(struct device *dev, bool deep) ...@@ -375,7 +376,7 @@ static int atl_resume_common(struct device *dev, bool deep)
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
struct aq_nic_s *nic; struct aq_nic_s *nic;
int ret; int ret = 0;
nic = pci_get_drvdata(pdev); nic = pci_get_drvdata(pdev);
...@@ -390,9 +391,11 @@ static int atl_resume_common(struct device *dev, bool deep) ...@@ -390,9 +391,11 @@ static int atl_resume_common(struct device *dev, bool deep)
goto err_exit; goto err_exit;
} }
ret = aq_nic_start(nic); if (netif_running(nic->ndev)) {
if (ret) ret = aq_nic_start(nic);
goto err_exit; if (ret)
goto err_exit;
}
netif_device_attach(nic->ndev); netif_device_attach(nic->ndev);
netif_tx_start_all_queues(nic->ndev); netif_tx_start_all_queues(nic->ndev);
......
...@@ -272,9 +272,12 @@ bool aq_ring_tx_clean(struct aq_ring_s *self) ...@@ -272,9 +272,12 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
} }
} }
if (unlikely(buff->is_eop)) if (unlikely(buff->is_eop)) {
dev_kfree_skb_any(buff->skb); ++self->stats.rx.packets;
self->stats.tx.bytes += buff->skb->len;
dev_kfree_skb_any(buff->skb);
}
buff->pa = 0U; buff->pa = 0U;
buff->eop_index = 0xffffU; buff->eop_index = 0xffffU;
self->sw_head = aq_ring_next_dx(self, self->sw_head); 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, ...@@ -351,7 +354,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
err = 0; err = 0;
goto err_exit; goto err_exit;
} }
if (buff->is_error || buff->is_cso_err) { if (buff->is_error ||
(buff->is_lro && buff->is_cso_err)) {
buff_ = buff; buff_ = buff;
do { do {
next_ = buff_->next, next_ = buff_->next,
......
...@@ -78,7 +78,8 @@ struct __packed aq_ring_buff_s { ...@@ -78,7 +78,8 @@ struct __packed aq_ring_buff_s {
u32 is_cleaned:1; u32 is_cleaned:1;
u32 is_error:1; u32 is_error:1;
u32 is_vlan:1; u32 is_vlan:1;
u32 rsvd3:4; u32 is_lro:1;
u32 rsvd3:3;
u16 eop_index; u16 eop_index;
u16 rsvd4; u16 rsvd4;
}; };
......
...@@ -823,6 +823,8 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, ...@@ -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) { if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) {
buff->len = rxd_wb->pkt_len % buff->len = rxd_wb->pkt_len %
AQ_CFG_RX_FRAME_MAX; AQ_CFG_RX_FRAME_MAX;
...@@ -835,8 +837,7 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, ...@@ -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 ? rxd_wb->pkt_len > AQ_CFG_RX_FRAME_MAX ?
AQ_CFG_RX_FRAME_MAX : rxd_wb->pkt_len; AQ_CFG_RX_FRAME_MAX : rxd_wb->pkt_len;
if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT & if (buff->is_lro) {
rxd_wb->status) {
/* LRO */ /* LRO */
buff->next = rxd_wb->next_desc_ptr; buff->next = rxd_wb->next_desc_ptr;
++ring->stats.rx.lro_packets; ++ring->stats.rx.lro_packets;
...@@ -884,13 +885,16 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self, ...@@ -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; struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
unsigned int i = 0U; unsigned int i = 0U;
u32 vlan_promisc;
u32 l2_promisc;
hw_atl_rpfl2promiscuous_mode_en_set(self, l2_promisc = IS_FILTER_ENABLED(IFF_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, hw_atl_rpfl2promiscuous_mode_en_set(self, l2_promisc);
IS_FILTER_ENABLED(IFF_PROMISC) ||
cfg->is_vlan_force_promisc); hw_atl_rpf_vlan_prom_mode_en_set(self, vlan_promisc);
hw_atl_rpfl2multicast_flr_en_set(self, hw_atl_rpfl2multicast_flr_en_set(self,
IS_FILTER_ENABLED(IFF_ALLMULTI) && IS_FILTER_ENABLED(IFF_ALLMULTI) &&
...@@ -1161,6 +1165,8 @@ static int hw_atl_b0_adj_sys_clock(struct aq_hw_s *self, s64 delta) ...@@ -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->ptp_clk_offset += delta;
self->aq_fw_ops->adjust_ptp(self, self->ptp_clk_offset);
return 0; return 0;
} }
...@@ -1211,7 +1217,7 @@ static int hw_atl_b0_gpio_pulse(struct aq_hw_s *self, u32 index, ...@@ -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.index = index;
fwreq.ptp_gpio_ctrl.period = period; fwreq.ptp_gpio_ctrl.period = period;
/* Apply time offset */ /* 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); size = sizeof(fwreq.msg_id) + sizeof(fwreq.ptp_gpio_ctrl);
return self->aq_fw_ops->send_fw_request(self, &fwreq, size); return self->aq_fw_ops->send_fw_request(self, &fwreq, size);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define HW_ATL_MIF_ADDR 0x0208U #define HW_ATL_MIF_ADDR 0x0208U
#define HW_ATL_MIF_VAL 0x020CU #define HW_ATL_MIF_VAL 0x020CU
#define HW_ATL_MPI_RPC_ADDR 0x0334U
#define HW_ATL_RPC_CONTROL_ADR 0x0338U #define HW_ATL_RPC_CONTROL_ADR 0x0338U
#define HW_ATL_RPC_STATE_ADR 0x033CU #define HW_ATL_RPC_STATE_ADR 0x033CU
...@@ -53,15 +54,14 @@ enum mcp_area { ...@@ -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_ver_match(u32 ver_expected, u32 ver_actual);
static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self, static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
enum hal_atl_utils_fw_state_e state); 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_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_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_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_mif_addr_get(struct aq_hw_s *self);
static u32 hw_atl_utils_rpc_state_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) 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, ...@@ -476,6 +476,10 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
self, self->mbox_addr, self, self->mbox_addr,
self->mbox_addr != 0U, self->mbox_addr != 0U,
1000U, 10000U); 1000U, 10000U);
err = readx_poll_timeout_atomic(aq_fw1x_rpc_get, self,
self->rpc_addr,
self->rpc_addr != 0U,
1000U, 100000U);
return err; return err;
} }
...@@ -531,6 +535,12 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self, ...@@ -531,6 +535,12 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
self, fw.val, self, fw.val,
sw.tid == fw.tid, sw.tid == fw.tid,
1000U, 100000U); 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) { if (fw.len == 0xFFFFU) {
err = hw_atl_utils_fw_rpc_call(self, sw.len); 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) ...@@ -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); 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 = { const struct aq_fw_ops aq_fw_1x_ops = {
.init = hw_atl_utils_mpi_create, .init = hw_atl_utils_mpi_create,
.deinit = hw_atl_fw1x_deinit, .deinit = hw_atl_fw1x_deinit,
......
...@@ -30,6 +30,9 @@ ...@@ -30,6 +30,9 @@
#define HW_ATL_FW3X_EXT_CONTROL_ADDR 0x378 #define HW_ATL_FW3X_EXT_CONTROL_ADDR 0x378
#define HW_ATL_FW3X_EXT_STATE_ADDR 0x37c #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_PAUSE BIT(CAPS_HI_PAUSE)
#define HW_ATL_FW2X_CAP_ASYM_PAUSE BIT(CAPS_HI_ASYMMETRIC_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_SLEEP_PROXY BIT(CAPS_HI_SLEEP_PROXY)
...@@ -475,6 +478,14 @@ static void aq_fw3x_enable_ptp(struct aq_hw_s *self, int enable) ...@@ -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); 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) static int aq_fw2x_led_control(struct aq_hw_s *self, u32 mode)
{ {
if (self->fw_ver_actual < HW_ATL_FW_VER_LED) if (self->fw_ver_actual < HW_ATL_FW_VER_LED)
...@@ -633,4 +644,5 @@ const struct aq_fw_ops aq_fw_2x_ops = { ...@@ -633,4 +644,5 @@ const struct aq_fw_ops aq_fw_2x_ops = {
.enable_ptp = aq_fw3x_enable_ptp, .enable_ptp = aq_fw3x_enable_ptp,
.led_control = aq_fw2x_led_control, .led_control = aq_fw2x_led_control,
.set_phyloopback = aq_fw2x_set_phyloopback, .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