aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c8
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_hw.h6
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_main.c10
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_nic.c18
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_nic.h2
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_ring.c35
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c61
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c8
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h3
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h18
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c21
11 files changed, 145 insertions, 45 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index 6a633c70f603..99ef1daaa4d8 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -407,13 +407,13 @@ static void aq_ethtool_get_pauseparam(struct net_device *ndev,
407 struct ethtool_pauseparam *pause) 407 struct ethtool_pauseparam *pause)
408{ 408{
409 struct aq_nic_s *aq_nic = netdev_priv(ndev); 409 struct aq_nic_s *aq_nic = netdev_priv(ndev);
410 u32 fc = aq_nic->aq_nic_cfg.flow_control;
410 411
411 pause->autoneg = 0; 412 pause->autoneg = 0;
412 413
413 if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_RX) 414 pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
414 pause->rx_pause = 1; 415 pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
415 if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_TX) 416
416 pause->tx_pause = 1;
417} 417}
418 418
419static int aq_ethtool_set_pauseparam(struct net_device *ndev, 419static int aq_ethtool_set_pauseparam(struct net_device *ndev,
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index e8689241204e..a1e70da358ca 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -204,6 +204,10 @@ struct aq_hw_ops {
204 204
205 int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version); 205 int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version);
206 206
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);
207}; 211};
208 212
209struct aq_fw_ops { 213struct aq_fw_ops {
@@ -226,6 +230,8 @@ struct aq_fw_ops {
226 230
227 int (*update_stats)(struct aq_hw_s *self); 231 int (*update_stats)(struct aq_hw_s *self);
228 232
233 u32 (*get_flow_control)(struct aq_hw_s *self, u32 *fcmode);
234
229 int (*set_flow_control)(struct aq_hw_s *self); 235 int (*set_flow_control)(struct aq_hw_s *self);
230 236
231 int (*set_power)(struct aq_hw_s *self, unsigned int power_state, 237 int (*set_power)(struct aq_hw_s *self, unsigned int power_state,
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index e3ae29e523f0..7c07eef275eb 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -99,8 +99,11 @@ static int aq_ndev_set_features(struct net_device *ndev,
99 struct aq_nic_s *aq_nic = netdev_priv(ndev); 99 struct aq_nic_s *aq_nic = netdev_priv(ndev);
100 struct aq_nic_cfg_s *aq_cfg = aq_nic_get_cfg(aq_nic); 100 struct aq_nic_cfg_s *aq_cfg = aq_nic_get_cfg(aq_nic);
101 bool is_lro = false; 101 bool is_lro = false;
102 int err = 0;
103
104 aq_cfg->features = features;
102 105
103 if (aq_cfg->hw_features & NETIF_F_LRO) { 106 if (aq_cfg->aq_hw_caps->hw_features & NETIF_F_LRO) {
104 is_lro = features & NETIF_F_LRO; 107 is_lro = features & NETIF_F_LRO;
105 108
106 if (aq_cfg->is_lro != is_lro) { 109 if (aq_cfg->is_lro != is_lro) {
@@ -112,8 +115,11 @@ static int aq_ndev_set_features(struct net_device *ndev,
112 } 115 }
113 } 116 }
114 } 117 }
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);
115 121
116 return 0; 122 return err;
117} 123}
118 124
119static int aq_ndev_set_mac_address(struct net_device *ndev, void *addr) 125static int aq_ndev_set_mac_address(struct net_device *ndev, void *addr)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 5fed24446687..7abdc0952425 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -118,12 +118,13 @@ void aq_nic_cfg_start(struct aq_nic_s *self)
118 } 118 }
119 119
120 cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk; 120 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;
122} 122}
123 123
124static int aq_nic_update_link_status(struct aq_nic_s *self) 124static int aq_nic_update_link_status(struct aq_nic_s *self)
125{ 125{
126 int err = self->aq_fw_ops->update_link_status(self->aq_hw); 126 int err = self->aq_fw_ops->update_link_status(self->aq_hw);
127 u32 fc = 0;
127 128
128 if (err) 129 if (err)
129 return err; 130 return err;
@@ -133,6 +134,15 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)
133 AQ_CFG_DRV_NAME, self->link_status.mbps, 134 AQ_CFG_DRV_NAME, self->link_status.mbps,
134 self->aq_hw->aq_link_status.mbps); 135 self->aq_hw->aq_link_status.mbps);
135 aq_nic_update_interrupt_moderation_settings(self); 136 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);
136 } 146 }
137 147
138 self->link_status = self->aq_hw->aq_link_status; 148 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)
590 } 600 }
591 } 601 }
592 602
593 if (i > 0 && i < AQ_HW_MULTICAST_ADDRESS_MAX) { 603 if (i > 0 && i <= AQ_HW_MULTICAST_ADDRESS_MAX) {
594 packet_filter |= IFF_MULTICAST; 604 packet_filter |= IFF_MULTICAST;
595 self->mc_list.count = i; 605 self->mc_list.count = i;
596 self->aq_hw_ops->hw_multicast_list_set(self->aq_hw, 606 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,
772 ethtool_link_ksettings_add_link_mode(cmd, advertising, 782 ethtool_link_ksettings_add_link_mode(cmd, advertising,
773 Pause); 783 Pause);
774 784
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))
776 ethtool_link_ksettings_add_link_mode(cmd, advertising, 788 ethtool_link_ksettings_add_link_mode(cmd, advertising,
777 Asym_Pause); 789 Asym_Pause);
778 790
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
index c1582f4e8e1b..44ec47a3d60a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
@@ -23,7 +23,7 @@ struct aq_vec_s;
23 23
24struct aq_nic_cfg_s { 24struct aq_nic_cfg_s {
25 const struct aq_hw_caps_s *aq_hw_caps; 25 const struct aq_hw_caps_s *aq_hw_caps;
26 u64 hw_features; 26 u64 features;
27 u32 rxds; /* rx ring size, descriptors # */ 27 u32 rxds; /* rx ring size, descriptors # */
28 u32 txds; /* tx ring size, descriptors # */ 28 u32 txds; /* tx ring size, descriptors # */
29 u32 vecs; /* vecs==allocated irqs */ 29 u32 vecs; /* vecs==allocated irqs */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 3db91446cc67..74550ccc7a20 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -172,6 +172,27 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
172 return !!budget; 172 return !!budget;
173} 173}
174 174
175static 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
175#define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) 196#define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
176int aq_ring_rx_clean(struct aq_ring_s *self, 197int aq_ring_rx_clean(struct aq_ring_s *self,
177 struct napi_struct *napi, 198 struct napi_struct *napi,
@@ -267,18 +288,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
267 } 288 }
268 289
269 skb->protocol = eth_type_trans(skb, ndev); 290 skb->protocol = eth_type_trans(skb, ndev);
270 if (unlikely(buff->is_cso_err)) { 291
271 ++self->stats.rx.errors; 292 aq_rx_checksum(self, buff, skb);
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 }
282 293
283 skb_set_hash(skb, buff->rss_hash, 294 skb_set_hash(skb, buff->rss_hash,
284 buff->is_hash_l4 ? PKT_HASH_TYPE_L4 : 295 buff->is_hash_l4 ? PKT_HASH_TYPE_L4 :
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 76d25d594a0f..f02592f43fe3 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -100,12 +100,17 @@ static int hw_atl_b0_hw_reset(struct aq_hw_s *self)
100 return err; 100 return err;
101} 101}
102 102
103static 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
103static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self) 109static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
104{ 110{
105 u32 tc = 0U; 111 u32 tc = 0U;
106 u32 buff_size = 0U; 112 u32 buff_size = 0U;
107 unsigned int i_priority = 0U; 113 unsigned int i_priority = 0U;
108 bool is_rx_flow_control = false;
109 114
110 /* TPS Descriptor rate init */ 115 /* TPS Descriptor rate init */
111 hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U); 116 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)
138 143
139 /* QoS Rx buf size per TC */ 144 /* QoS Rx buf size per TC */
140 tc = 0; 145 tc = 0;
141 is_rx_flow_control = (AQ_NIC_FC_RX & self->aq_nic_cfg->flow_control);
142 buff_size = HW_ATL_B0_RXBUF_MAX; 146 buff_size = HW_ATL_B0_RXBUF_MAX;
143 147
144 hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc); 148 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)
150 (buff_size * 154 (buff_size *
151 (1024U / 32U) * 50U) / 155 (1024U / 32U) * 50U) /
152 100U, tc); 156 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);
154 159
155 /* QoS 802.1p priority -> TC mapping */ 160 /* QoS 802.1p priority -> TC mapping */
156 for (i_priority = 8U; i_priority--;) 161 for (i_priority = 8U; i_priority--;)
@@ -229,8 +234,10 @@ static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
229 hw_atl_tpo_tcp_udp_crc_offload_en_set(self, 1); 234 hw_atl_tpo_tcp_udp_crc_offload_en_set(self, 1);
230 235
231 /* RX checksums offloads*/ 236 /* RX checksums offloads*/
232 hw_atl_rpo_ipv4header_crc_offload_en_set(self, 1); 237 hw_atl_rpo_ipv4header_crc_offload_en_set(self, !!(aq_nic_cfg->features &
233 hw_atl_rpo_tcp_udp_crc_offload_en_set(self, 1); 238 NETIF_F_RXCSUM));
239 hw_atl_rpo_tcp_udp_crc_offload_en_set(self, !!(aq_nic_cfg->features &
240 NETIF_F_RXCSUM));
234 241
235 /* LSO offloads*/ 242 /* LSO offloads*/
236 hw_atl_tdm_large_send_offload_en_set(self, 0xFFFFFFFFU); 243 hw_atl_tdm_large_send_offload_en_set(self, 0xFFFFFFFFU);
@@ -655,9 +662,9 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
655 struct hw_atl_rxd_wb_s *rxd_wb = (struct hw_atl_rxd_wb_s *) 662 struct hw_atl_rxd_wb_s *rxd_wb = (struct hw_atl_rxd_wb_s *)
656 &ring->dx_ring[ring->hw_head * HW_ATL_B0_RXD_SIZE]; 663 &ring->dx_ring[ring->hw_head * HW_ATL_B0_RXD_SIZE];
657 664
658 unsigned int is_err = 1U;
659 unsigned int is_rx_check_sum_enabled = 0U; 665 unsigned int is_rx_check_sum_enabled = 0U;
660 unsigned int pkt_type = 0U; 666 unsigned int pkt_type = 0U;
667 u8 rx_stat = 0U;
661 668
662 if (!(rxd_wb->status & 0x1U)) { /* RxD is not done */ 669 if (!(rxd_wb->status & 0x1U)) { /* RxD is not done */
663 break; 670 break;
@@ -665,35 +672,35 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
665 672
666 buff = &ring->buff_ring[ring->hw_head]; 673 buff = &ring->buff_ring[ring->hw_head];
667 674
668 is_err = (0x0000003CU & rxd_wb->status); 675 rx_stat = (0x0000003CU & rxd_wb->status) >> 2;
669 676
670 is_rx_check_sum_enabled = (rxd_wb->type) & (0x3U << 19); 677 is_rx_check_sum_enabled = (rxd_wb->type) & (0x3U << 19);
671 is_err &= ~0x20U; /* exclude validity bit */
672 678
673 pkt_type = 0xFFU & (rxd_wb->type >> 4); 679 pkt_type = 0xFFU & (rxd_wb->type >> 4);
674 680
675 if (is_rx_check_sum_enabled) { 681 if (is_rx_check_sum_enabled & BIT(0) &&
676 if (0x0U == (pkt_type & 0x3U)) 682 (0x0U == (pkt_type & 0x3U)))
677 buff->is_ip_cso = (is_err & 0x08U) ? 0U : 1U; 683 buff->is_ip_cso = (rx_stat & BIT(1)) ? 0U : 1U;
678 684
685 if (is_rx_check_sum_enabled & BIT(1)) {
679 if (0x4U == (pkt_type & 0x1CU)) 686 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));
681 else if (0x0U == (pkt_type & 0x1CU)) 689 else if (0x0U == (pkt_type & 0x1CU))
682 buff->is_tcp_cso = buff->is_cso_err ? 0U : 1U; 690 buff->is_tcp_cso = (rx_stat & BIT(2)) ? 0U :
683 691 !!(rx_stat & BIT(3));
684 /* Checksum offload workaround for small packets */ 692 }
685 if (rxd_wb->pkt_len <= 60) { 693 buff->is_cso_err = !!(rx_stat & 0x6);
686 buff->is_ip_cso = 0U; 694 /* Checksum offload workaround for small packets */
687 buff->is_cso_err = 0U; 695 if (unlikely(rxd_wb->pkt_len <= 60)) {
688 } 696 buff->is_ip_cso = 0U;
697 buff->is_cso_err = 0U;
689 } 698 }
690
691 is_err &= ~0x18U;
692 699
693 dma_unmap_page(ndev, buff->pa, buff->len, DMA_FROM_DEVICE); 700 dma_unmap_page(ndev, buff->pa, buff->len, DMA_FROM_DEVICE);
694 701
695 if (is_err || rxd_wb->type & 0x1000U) { 702 if ((rx_stat & BIT(0)) || rxd_wb->type & 0x1000U) {
696 /* status error or DMA error */ 703 /* MAC error or DMA error */
697 buff->is_error = 1U; 704 buff->is_error = 1U;
698 } else { 705 } else {
699 if (self->aq_nic_cfg->is_rss) { 706 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)
915static int hw_atl_b0_hw_stop(struct aq_hw_s *self) 922static int hw_atl_b0_hw_stop(struct aq_hw_s *self)
916{ 923{
917 hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK); 924 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
918 return aq_hw_err_from_flags(self); 931 return aq_hw_err_from_flags(self);
919} 932}
920 933
@@ -963,4 +976,6 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
963 .hw_get_regs = hw_atl_utils_hw_get_regs, 976 .hw_get_regs = hw_atl_utils_hw_get_regs,
964 .hw_get_hw_stats = hw_atl_utils_get_hw_stats, 977 .hw_get_hw_stats = hw_atl_utils_get_hw_stats,
965 .hw_get_fw_version = hw_atl_utils_get_fw_version, 978 .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,
966}; 981};
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
index be0a3a90dfad..5502ec5f0f69 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
@@ -619,6 +619,14 @@ void hw_atl_rpb_rx_flow_ctl_mode_set(struct aq_hw_s *aq_hw, u32 rx_flow_ctl_mode
619 HW_ATL_RPB_RX_FC_MODE_SHIFT, rx_flow_ctl_mode); 619 HW_ATL_RPB_RX_FC_MODE_SHIFT, rx_flow_ctl_mode);
620} 620}
621 621
622void 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
622void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, 630void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw,
623 u32 rx_pkt_buff_size_per_tc, u32 buffer) 631 u32 rx_pkt_buff_size_per_tc, u32 buffer)
624{ 632{
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
index 7056c7342afc..41f239928c15 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
@@ -325,6 +325,9 @@ void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw,
325 u32 rx_pkt_buff_size_per_tc, 325 u32 rx_pkt_buff_size_per_tc,
326 u32 buffer); 326 u32 buffer);
327 327
328/* set rdm rx dma descriptor cache init */
329void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init);
330
328/* set rx xoff enable (per tc) */ 331/* set rx xoff enable (per tc) */
329void hw_atl_rpb_rx_xoff_en_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_xoff_en_per_tc, 332void hw_atl_rpb_rx_xoff_en_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_xoff_en_per_tc,
330 u32 buffer); 333 u32 buffer);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
index 716674a9b729..a715fa317b1c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
@@ -293,6 +293,24 @@
293/* default value of bitfield desc{d}_reset */ 293/* default value of bitfield desc{d}_reset */
294#define HW_ATL_RDM_DESCDRESET_DEFAULT 0x0 294#define HW_ATL_RDM_DESCDRESET_DEFAULT 0x0
295 295
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
296/* rx int_desc_wrb_en bitfield definitions 314/* rx int_desc_wrb_en bitfield definitions
297 * preprocessor definitions for the bitfield "int_desc_wrb_en". 315 * preprocessor definitions for the bitfield "int_desc_wrb_en".
298 * port="pif_rdm_int_desc_wrb_en_i" 316 * port="pif_rdm_int_desc_wrb_en_i"
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index 096ca5730887..7de3220d9cab 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -30,6 +30,8 @@
30#define HW_ATL_FW2X_MPI_STATE_ADDR 0x370 30#define HW_ATL_FW2X_MPI_STATE_ADDR 0x370
31#define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374 31#define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374
32 32
33#define HW_ATL_FW2X_CAP_PAUSE BIT(CAPS_HI_PAUSE)
34#define HW_ATL_FW2X_CAP_ASYM_PAUSE BIT(CAPS_HI_ASYMMETRIC_PAUSE)
33#define HW_ATL_FW2X_CAP_SLEEP_PROXY BIT(CAPS_HI_SLEEP_PROXY) 35#define HW_ATL_FW2X_CAP_SLEEP_PROXY BIT(CAPS_HI_SLEEP_PROXY)
34#define HW_ATL_FW2X_CAP_WOL BIT(CAPS_HI_WOL) 36#define HW_ATL_FW2X_CAP_WOL BIT(CAPS_HI_WOL)
35 37
@@ -451,6 +453,24 @@ static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
451 return 0; 453 return 0;
452} 454}
453 455
456static 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
454const struct aq_fw_ops aq_fw_2x_ops = { 474const struct aq_fw_ops aq_fw_2x_ops = {
455 .init = aq_fw2x_init, 475 .init = aq_fw2x_init,
456 .deinit = aq_fw2x_deinit, 476 .deinit = aq_fw2x_deinit,
@@ -465,4 +485,5 @@ const struct aq_fw_ops aq_fw_2x_ops = {
465 .set_eee_rate = aq_fw2x_set_eee_rate, 485 .set_eee_rate = aq_fw2x_set_eee_rate,
466 .get_eee_rate = aq_fw2x_get_eee_rate, 486 .get_eee_rate = aq_fw2x_get_eee_rate,
467 .set_flow_control = aq_fw2x_set_flow_control, 487 .set_flow_control = aq_fw2x_set_flow_control,
488 .get_flow_control = aq_fw2x_get_flow_control
468}; 489};