Skip to content

Commit dd63c3e

Browse files
committed
Merge branch 'aquantia-fixes'
Igor Russkikh says: ==================== net: aquantia: 2018-11 bugfixes The patchset fixes a number of bugs found in various areas after driver validation. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 85b18b0 + bbb67a4 commit dd63c3e

File tree

11 files changed

+145
-45
lines changed

11 files changed

+145
-45
lines changed

drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -407,13 +407,13 @@ static void aq_ethtool_get_pauseparam(struct net_device *ndev,
407407
struct ethtool_pauseparam *pause)
408408
{
409409
struct aq_nic_s *aq_nic = netdev_priv(ndev);
410+
u32 fc = aq_nic->aq_nic_cfg.flow_control;
410411

411412
pause->autoneg = 0;
412413

413-
if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)
414-
pause->rx_pause = 1;
415-
if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_TX)
416-
pause->tx_pause = 1;
414+
pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
415+
pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
416+
417417
}
418418

419419
static int aq_ethtool_set_pauseparam(struct net_device *ndev,

drivers/net/ethernet/aquantia/atlantic/aq_hw.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ struct aq_hw_ops {
204204

205205
int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version);
206206

207+
int (*hw_set_offload)(struct aq_hw_s *self,
208+
struct aq_nic_cfg_s *aq_nic_cfg);
209+
210+
int (*hw_set_fc)(struct aq_hw_s *self, u32 fc, u32 tc);
207211
};
208212

209213
struct aq_fw_ops {
@@ -226,6 +230,8 @@ struct aq_fw_ops {
226230

227231
int (*update_stats)(struct aq_hw_s *self);
228232

233+
u32 (*get_flow_control)(struct aq_hw_s *self, u32 *fcmode);
234+
229235
int (*set_flow_control)(struct aq_hw_s *self);
230236

231237
int (*set_power)(struct aq_hw_s *self, unsigned int power_state,

drivers/net/ethernet/aquantia/atlantic/aq_main.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,11 @@ static int aq_ndev_set_features(struct net_device *ndev,
9999
struct aq_nic_s *aq_nic = netdev_priv(ndev);
100100
struct aq_nic_cfg_s *aq_cfg = aq_nic_get_cfg(aq_nic);
101101
bool is_lro = false;
102+
int err = 0;
103+
104+
aq_cfg->features = features;
102105

103-
if (aq_cfg->hw_features & NETIF_F_LRO) {
106+
if (aq_cfg->aq_hw_caps->hw_features & NETIF_F_LRO) {
104107
is_lro = features & NETIF_F_LRO;
105108

106109
if (aq_cfg->is_lro != is_lro) {
@@ -112,8 +115,11 @@ static int aq_ndev_set_features(struct net_device *ndev,
112115
}
113116
}
114117
}
118+
if ((aq_nic->ndev->features ^ features) & NETIF_F_RXCSUM)
119+
err = aq_nic->aq_hw_ops->hw_set_offload(aq_nic->aq_hw,
120+
aq_cfg);
115121

116-
return 0;
122+
return err;
117123
}
118124

119125
static int aq_ndev_set_mac_address(struct net_device *ndev, void *addr)

drivers/net/ethernet/aquantia/atlantic/aq_nic.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,13 @@ void aq_nic_cfg_start(struct aq_nic_s *self)
118118
}
119119

120120
cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk;
121-
cfg->hw_features = cfg->aq_hw_caps->hw_features;
121+
cfg->features = cfg->aq_hw_caps->hw_features;
122122
}
123123

124124
static int aq_nic_update_link_status(struct aq_nic_s *self)
125125
{
126126
int err = self->aq_fw_ops->update_link_status(self->aq_hw);
127+
u32 fc = 0;
127128

128129
if (err)
129130
return err;
@@ -133,6 +134,15 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)
133134
AQ_CFG_DRV_NAME, self->link_status.mbps,
134135
self->aq_hw->aq_link_status.mbps);
135136
aq_nic_update_interrupt_moderation_settings(self);
137+
138+
/* Driver has to update flow control settings on RX block
139+
* on any link event.
140+
* We should query FW whether it negotiated FC.
141+
*/
142+
if (self->aq_fw_ops->get_flow_control)
143+
self->aq_fw_ops->get_flow_control(self->aq_hw, &fc);
144+
if (self->aq_hw_ops->hw_set_fc)
145+
self->aq_hw_ops->hw_set_fc(self->aq_hw, fc, 0);
136146
}
137147

138148
self->link_status = self->aq_hw->aq_link_status;
@@ -590,7 +600,7 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev)
590600
}
591601
}
592602

593-
if (i > 0 && i < AQ_HW_MULTICAST_ADDRESS_MAX) {
603+
if (i > 0 && i <= AQ_HW_MULTICAST_ADDRESS_MAX) {
594604
packet_filter |= IFF_MULTICAST;
595605
self->mc_list.count = i;
596606
self->aq_hw_ops->hw_multicast_list_set(self->aq_hw,
@@ -772,7 +782,9 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
772782
ethtool_link_ksettings_add_link_mode(cmd, advertising,
773783
Pause);
774784

775-
if (self->aq_nic_cfg.flow_control & AQ_NIC_FC_TX)
785+
/* Asym is when either RX or TX, but not both */
786+
if (!!(self->aq_nic_cfg.flow_control & AQ_NIC_FC_TX) ^
787+
!!(self->aq_nic_cfg.flow_control & AQ_NIC_FC_RX))
776788
ethtool_link_ksettings_add_link_mode(cmd, advertising,
777789
Asym_Pause);
778790

drivers/net/ethernet/aquantia/atlantic/aq_nic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct aq_vec_s;
2323

2424
struct aq_nic_cfg_s {
2525
const struct aq_hw_caps_s *aq_hw_caps;
26-
u64 hw_features;
26+
u64 features;
2727
u32 rxds; /* rx ring size, descriptors # */
2828
u32 txds; /* tx ring size, descriptors # */
2929
u32 vecs; /* vecs==allocated irqs */

drivers/net/ethernet/aquantia/atlantic/aq_ring.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,27 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
172172
return !!budget;
173173
}
174174

175+
static void aq_rx_checksum(struct aq_ring_s *self,
176+
struct aq_ring_buff_s *buff,
177+
struct sk_buff *skb)
178+
{
179+
if (!(self->aq_nic->ndev->features & NETIF_F_RXCSUM))
180+
return;
181+
182+
if (unlikely(buff->is_cso_err)) {
183+
++self->stats.rx.errors;
184+
skb->ip_summed = CHECKSUM_NONE;
185+
return;
186+
}
187+
if (buff->is_ip_cso) {
188+
__skb_incr_checksum_unnecessary(skb);
189+
if (buff->is_udp_cso || buff->is_tcp_cso)
190+
__skb_incr_checksum_unnecessary(skb);
191+
} else {
192+
skb->ip_summed = CHECKSUM_NONE;
193+
}
194+
}
195+
175196
#define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
176197
int aq_ring_rx_clean(struct aq_ring_s *self,
177198
struct napi_struct *napi,
@@ -267,18 +288,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
267288
}
268289

269290
skb->protocol = eth_type_trans(skb, ndev);
270-
if (unlikely(buff->is_cso_err)) {
271-
++self->stats.rx.errors;
272-
skb->ip_summed = CHECKSUM_NONE;
273-
} else {
274-
if (buff->is_ip_cso) {
275-
__skb_incr_checksum_unnecessary(skb);
276-
if (buff->is_udp_cso || buff->is_tcp_cso)
277-
__skb_incr_checksum_unnecessary(skb);
278-
} else {
279-
skb->ip_summed = CHECKSUM_NONE;
280-
}
281-
}
291+
292+
aq_rx_checksum(self, buff, skb);
282293

283294
skb_set_hash(skb, buff->rss_hash,
284295
buff->is_hash_l4 ? PKT_HASH_TYPE_L4 :

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,17 @@ static int hw_atl_b0_hw_reset(struct aq_hw_s *self)
100100
return err;
101101
}
102102

103+
static int hw_atl_b0_set_fc(struct aq_hw_s *self, u32 fc, u32 tc)
104+
{
105+
hw_atl_rpb_rx_xoff_en_per_tc_set(self, !!(fc & AQ_NIC_FC_RX), tc);
106+
return 0;
107+
}
108+
103109
static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
104110
{
105111
u32 tc = 0U;
106112
u32 buff_size = 0U;
107113
unsigned int i_priority = 0U;
108-
bool is_rx_flow_control = false;
109114

110115
/* TPS Descriptor rate init */
111116
hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U);
@@ -138,7 +143,6 @@ static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
138143

139144
/* QoS Rx buf size per TC */
140145
tc = 0;
141-
is_rx_flow_control = (AQ_NIC_FC_RX & self->aq_nic_cfg->flow_control);
142146
buff_size = HW_ATL_B0_RXBUF_MAX;
143147

144148
hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc);
@@ -150,7 +154,8 @@ static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
150154
(buff_size *
151155
(1024U / 32U) * 50U) /
152156
100U, tc);
153-
hw_atl_rpb_rx_xoff_en_per_tc_set(self, is_rx_flow_control ? 1U : 0U, tc);
157+
158+
hw_atl_b0_set_fc(self, self->aq_nic_cfg->flow_control, tc);
154159

155160
/* QoS 802.1p priority -> TC mapping */
156161
for (i_priority = 8U; i_priority--;)
@@ -229,8 +234,10 @@ static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
229234
hw_atl_tpo_tcp_udp_crc_offload_en_set(self, 1);
230235

231236
/* RX checksums offloads*/
232-
hw_atl_rpo_ipv4header_crc_offload_en_set(self, 1);
233-
hw_atl_rpo_tcp_udp_crc_offload_en_set(self, 1);
237+
hw_atl_rpo_ipv4header_crc_offload_en_set(self, !!(aq_nic_cfg->features &
238+
NETIF_F_RXCSUM));
239+
hw_atl_rpo_tcp_udp_crc_offload_en_set(self, !!(aq_nic_cfg->features &
240+
NETIF_F_RXCSUM));
234241

235242
/* LSO offloads*/
236243
hw_atl_tdm_large_send_offload_en_set(self, 0xFFFFFFFFU);
@@ -655,45 +662,45 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
655662
struct hw_atl_rxd_wb_s *rxd_wb = (struct hw_atl_rxd_wb_s *)
656663
&ring->dx_ring[ring->hw_head * HW_ATL_B0_RXD_SIZE];
657664

658-
unsigned int is_err = 1U;
659665
unsigned int is_rx_check_sum_enabled = 0U;
660666
unsigned int pkt_type = 0U;
667+
u8 rx_stat = 0U;
661668

662669
if (!(rxd_wb->status & 0x1U)) { /* RxD is not done */
663670
break;
664671
}
665672

666673
buff = &ring->buff_ring[ring->hw_head];
667674

668-
is_err = (0x0000003CU & rxd_wb->status);
675+
rx_stat = (0x0000003CU & rxd_wb->status) >> 2;
669676

670677
is_rx_check_sum_enabled = (rxd_wb->type) & (0x3U << 19);
671-
is_err &= ~0x20U; /* exclude validity bit */
672678

673679
pkt_type = 0xFFU & (rxd_wb->type >> 4);
674680

675-
if (is_rx_check_sum_enabled) {
676-
if (0x0U == (pkt_type & 0x3U))
677-
buff->is_ip_cso = (is_err & 0x08U) ? 0U : 1U;
681+
if (is_rx_check_sum_enabled & BIT(0) &&
682+
(0x0U == (pkt_type & 0x3U)))
683+
buff->is_ip_cso = (rx_stat & BIT(1)) ? 0U : 1U;
678684

685+
if (is_rx_check_sum_enabled & BIT(1)) {
679686
if (0x4U == (pkt_type & 0x1CU))
680-
buff->is_udp_cso = buff->is_cso_err ? 0U : 1U;
687+
buff->is_udp_cso = (rx_stat & BIT(2)) ? 0U :
688+
!!(rx_stat & BIT(3));
681689
else if (0x0U == (pkt_type & 0x1CU))
682-
buff->is_tcp_cso = buff->is_cso_err ? 0U : 1U;
683-
684-
/* Checksum offload workaround for small packets */
685-
if (rxd_wb->pkt_len <= 60) {
686-
buff->is_ip_cso = 0U;
687-
buff->is_cso_err = 0U;
688-
}
690+
buff->is_tcp_cso = (rx_stat & BIT(2)) ? 0U :
691+
!!(rx_stat & BIT(3));
692+
}
693+
buff->is_cso_err = !!(rx_stat & 0x6);
694+
/* Checksum offload workaround for small packets */
695+
if (unlikely(rxd_wb->pkt_len <= 60)) {
696+
buff->is_ip_cso = 0U;
697+
buff->is_cso_err = 0U;
689698
}
690-
691-
is_err &= ~0x18U;
692699

693700
dma_unmap_page(ndev, buff->pa, buff->len, DMA_FROM_DEVICE);
694701

695-
if (is_err || rxd_wb->type & 0x1000U) {
696-
/* status error or DMA error */
702+
if ((rx_stat & BIT(0)) || rxd_wb->type & 0x1000U) {
703+
/* MAC error or DMA error */
697704
buff->is_error = 1U;
698705
} else {
699706
if (self->aq_nic_cfg->is_rss) {
@@ -915,6 +922,12 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)
915922
static int hw_atl_b0_hw_stop(struct aq_hw_s *self)
916923
{
917924
hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK);
925+
926+
/* Invalidate Descriptor Cache to prevent writing to the cached
927+
* descriptors and to the data pointer of those descriptors
928+
*/
929+
hw_atl_rdm_rx_dma_desc_cache_init_set(self, 1);
930+
918931
return aq_hw_err_from_flags(self);
919932
}
920933

@@ -963,4 +976,6 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
963976
.hw_get_regs = hw_atl_utils_hw_get_regs,
964977
.hw_get_hw_stats = hw_atl_utils_get_hw_stats,
965978
.hw_get_fw_version = hw_atl_utils_get_fw_version,
979+
.hw_set_offload = hw_atl_b0_hw_offload_set,
980+
.hw_set_fc = hw_atl_b0_set_fc,
966981
};

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,14 @@ void hw_atl_rpb_rx_flow_ctl_mode_set(struct aq_hw_s *aq_hw, u32 rx_flow_ctl_mode
619619
HW_ATL_RPB_RX_FC_MODE_SHIFT, rx_flow_ctl_mode);
620620
}
621621

622+
void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init)
623+
{
624+
aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR,
625+
HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK,
626+
HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT,
627+
init);
628+
}
629+
622630
void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw,
623631
u32 rx_pkt_buff_size_per_tc, u32 buffer)
624632
{

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw,
325325
u32 rx_pkt_buff_size_per_tc,
326326
u32 buffer);
327327

328+
/* set rdm rx dma descriptor cache init */
329+
void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init);
330+
328331
/* set rx xoff enable (per tc) */
329332
void hw_atl_rpb_rx_xoff_en_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_xoff_en_per_tc,
330333
u32 buffer);

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,24 @@
293293
/* default value of bitfield desc{d}_reset */
294294
#define HW_ATL_RDM_DESCDRESET_DEFAULT 0x0
295295

296+
/* rdm_desc_init_i bitfield definitions
297+
* preprocessor definitions for the bitfield rdm_desc_init_i.
298+
* port="pif_rdm_desc_init_i"
299+
*/
300+
301+
/* register address for bitfield rdm_desc_init_i */
302+
#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR 0x00005a00
303+
/* bitmask for bitfield rdm_desc_init_i */
304+
#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK 0xffffffff
305+
/* inverted bitmask for bitfield rdm_desc_init_i */
306+
#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSKN 0x00000000
307+
/* lower bit position of bitfield rdm_desc_init_i */
308+
#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT 0
309+
/* width of bitfield rdm_desc_init_i */
310+
#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_WIDTH 32
311+
/* default value of bitfield rdm_desc_init_i */
312+
#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_DEFAULT 0x0
313+
296314
/* rx int_desc_wrb_en bitfield definitions
297315
* preprocessor definitions for the bitfield "int_desc_wrb_en".
298316
* port="pif_rdm_int_desc_wrb_en_i"

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#define HW_ATL_FW2X_MPI_STATE_ADDR 0x370
3131
#define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374
3232

33+
#define HW_ATL_FW2X_CAP_PAUSE BIT(CAPS_HI_PAUSE)
34+
#define HW_ATL_FW2X_CAP_ASYM_PAUSE BIT(CAPS_HI_ASYMMETRIC_PAUSE)
3335
#define HW_ATL_FW2X_CAP_SLEEP_PROXY BIT(CAPS_HI_SLEEP_PROXY)
3436
#define HW_ATL_FW2X_CAP_WOL BIT(CAPS_HI_WOL)
3537

@@ -451,6 +453,24 @@ static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
451453
return 0;
452454
}
453455

456+
static u32 aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fcmode)
457+
{
458+
u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);
459+
460+
if (mpi_state & HW_ATL_FW2X_CAP_PAUSE)
461+
if (mpi_state & HW_ATL_FW2X_CAP_ASYM_PAUSE)
462+
*fcmode = AQ_NIC_FC_RX;
463+
else
464+
*fcmode = AQ_NIC_FC_RX | AQ_NIC_FC_TX;
465+
else
466+
if (mpi_state & HW_ATL_FW2X_CAP_ASYM_PAUSE)
467+
*fcmode = AQ_NIC_FC_TX;
468+
else
469+
*fcmode = 0;
470+
471+
return 0;
472+
}
473+
454474
const struct aq_fw_ops aq_fw_2x_ops = {
455475
.init = aq_fw2x_init,
456476
.deinit = aq_fw2x_deinit,
@@ -465,4 +485,5 @@ const struct aq_fw_ops aq_fw_2x_ops = {
465485
.set_eee_rate = aq_fw2x_set_eee_rate,
466486
.get_eee_rate = aq_fw2x_get_eee_rate,
467487
.set_flow_control = aq_fw2x_set_flow_control,
488+
.get_flow_control = aq_fw2x_get_flow_control
468489
};

0 commit comments

Comments
 (0)