net: aquantia: 2018-11 bugfixes
Subsystems (3)
cover net: aquantia: 2018-11 bugfixes
The patchset fixes a number of bugs found in various areas after driver validation.
Dmitry Bogdanov (3):
net: aquantia: fix potential IOMMU fault after driver unbind
net: aquantia: invalid checksumm offload implementation
net: aquantia: allow rx checksum offload configuration
Igor Russkikh (2):
net: aquantia: synchronized flow control between mac/phy
net: aquantia: fixed enable unicast on 32 macvlan
.../net/ethernet/aquantia/atlantic/aq_ethtool.c | 8 +-- drivers/net/ethernet/aquantia/atlantic/aq_hw.h | 6 +++ drivers/net/ethernet/aquantia/atlantic/aq_main.c | 10 +++- drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 18 +++++-- drivers/net/ethernet/aquantia/atlantic/aq_nic.h | 2 +- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 35 ++++++++----- .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 61 ++++++++++++++-------- .../ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c | 8 +++ .../ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h | 3 ++ .../aquantia/atlantic/hw_atl/hw_atl_llh_internal.h | 18 +++++++ .../aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c | 21 ++++++++ 11 files changed, 145 insertions(+), 45 deletions(-)
Signature · 1 line
2.7.4
PATCH 1/5 net: aquantia: synchronized flow control between mac/phy
Flow control statuses were not synchronized between blocks, that caused packets/link drop on some corner cases, when MAC sent PFC although Phy was not expecting these to come.
Driver should readout the negotiated FC from phy and configure RX block accordigly.
This is done on each link change event with information from FW.
--- drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c | 8 ++++---- drivers/net/ethernet/aquantia/atlantic/aq_hw.h | 3 +++ drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 14 +++++++++++++- .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 12 +++++++++--- .../aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c | 21 +++++++++++++++++++++ 5 files changed, 50 insertions(+), 8 deletions(-)
drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c +4 -4
@@ -407,13 +407,13 @@ static void aq_ethtool_get_pauseparam(struct net_device *ndev, struct ethtool_pauseparam *pause) {struct aq_nic_s *aq_nic =netdev_priv (ndev); +u32 fc = aq_nic->aq_nic_cfg.flow_control; pause->autoneg =0 ; -if (aq_nic->aq_hw->aq_nic_cfg->flow_control &AQ_NIC_FC_RX ) - pause->rx_pause =1 ; -if (aq_nic->aq_hw->aq_nic_cfg->flow_control &AQ_NIC_FC_TX ) - pause->tx_pause =1 ; + pause->rx_pause = !!(fc &AQ_NIC_FC_RX ); + pause->tx_pause = !!(fc &AQ_NIC_FC_TX ); + } static int aq_ethtool_set_pauseparam(struct net_device *ndev,
drivers/net/ethernet/aquantia/atlantic/aq_hw.h +3 -0
@@ -204,6 +204,7 @@ struct aq_hw_ops {int (*hw_get_fw_version)(struct aq_hw_s *self,u32 *fw_version); +int (*hw_set_fc)(struct aq_hw_s *self,u32 fc,u32 tc); };struct aq_fw_ops {
@@ -226,6 +227,8 @@ struct aq_fw_ops {int (*update_stats)(struct aq_hw_s *self); +u32 (*get_flow_control)(struct aq_hw_s *self,u32 *fcmode); +int (*set_flow_control)(struct aq_hw_s *self); int (*set_power)(struct aq_hw_s *self, unsigned int power_state,
drivers/net/ethernet/aquantia/atlantic/aq_nic.c +13 -1
@@ -124,6 +124,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self)static int aq_nic_update_link_status (struct aq_nic_s *self) {int err = self->aq_fw_ops->update_link_status (self->aq_hw); +u32 fc =0 ;if (err)return err;
@@ -133,6 +134,15 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)AQ_CFG_DRV_NAME , self->link_status.mbps, self->aq_hw->aq_link_status.mbps);aq_nic_update_interrupt_moderation_settings (self); + +/* Driver has to update flow control settings on RX block +* on any link event. +* We should query FW whether it negotiated FC. +*/ +if (self->aq_fw_ops->get_flow_control) + self->aq_fw_ops->get_flow_control (self->aq_hw, &fc); +if (self->aq_hw_ops->hw_set_fc) + self->aq_hw_ops->hw_set_fc (self->aq_hw, fc,0 ); } self->link_status = self->aq_hw->aq_link_status;
@@ -772,7 +782,9 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,ethtool_link_ksettings_add_link_mode (cmd, advertising, Pause); -if (self->aq_nic_cfg.flow_control &AQ_NIC_FC_TX ) +/* Asym is when either RX or TX, but not both */ +if (!!(self->aq_nic_cfg.flow_control &AQ_NIC_FC_TX ) ^ + !!(self->aq_nic_cfg.flow_control &AQ_NIC_FC_RX ))ethtool_link_ksettings_add_link_mode (cmd, advertising, Asym_Pause);
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +9 -3
@@ -100,12 +100,17 @@ static int hw_atl_b0_hw_reset(struct aq_hw_s *self)return err; } +static int hw_atl_b0_set_fc (struct aq_hw_s *self,u32 fc,u32 tc) +{ +hw_atl_rpb_rx_xoff_en_per_tc_set (self, !!(fc &AQ_NIC_FC_RX ), tc); +return 0 ; +} +static int hw_atl_b0_hw_qos_set (struct aq_hw_s *self) {u32 tc =0U ;u32 buff_size =0U ;unsigned int i_priority =0U ; -bool is_rx_flow_control = false;/* TPS Descriptor rate init */ 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)/* QoS Rx buf size per TC */ tc =0 ; - is_rx_flow_control = (AQ_NIC_FC_RX & self->aq_nic_cfg->flow_control); buff_size =HW_ATL_B0_RXBUF_MAX ;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) (buff_size * (1024U /32U ) *50U ) / 100U, tc); -hw_atl_rpb_rx_xoff_en_per_tc_set (self, is_rx_flow_control ?1U :0U , tc); + +hw_atl_b0_set_fc (self, self->aq_nic_cfg->flow_control, tc);/* QoS 802.1p priority -> TC mapping */ for (i_priority =8U ; i_priority--;)
@@ -963,4 +968,5 @@ const struct aq_hw_ops hw_atl_ops_b0 = { .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, + .hw_set_fc = hw_atl_b0_set_fc, };
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c +21 -0
@@ -30,6 +30,8 @@#define HW_ATL_FW2X_MPI_STATE_ADDR 0x370#define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374 +#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)
@@ -451,6 +453,24 @@ static int aq_fw2x_set_flow_control(struct aq_hw_s *self)return 0 ; } +static u32 aq_fw2x_get_flow_control (struct aq_hw_s *self,u32 *fcmode) +{ +u32 mpi_state =aq_hw_read_reg (self,HW_ATL_FW2X_MPI_STATE2_ADDR ); + +if (mpi_state &HW_ATL_FW2X_CAP_PAUSE ) +if (mpi_state &HW_ATL_FW2X_CAP_ASYM_PAUSE ) + *fcmode =AQ_NIC_FC_RX ; +else + *fcmode =AQ_NIC_FC_RX |AQ_NIC_FC_TX ; +else +if (mpi_state &HW_ATL_FW2X_CAP_ASYM_PAUSE ) + *fcmode =AQ_NIC_FC_TX ; +else + *fcmode =0 ; + +return 0 ; +} +const struct aq_fw_ops aq_fw_2x_ops = { .init = aq_fw2x_init, .deinit = aq_fw2x_deinit,
@@ -465,4 +485,5 @@ const struct aq_fw_ops aq_fw_2x_ops = { .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 };
Signature · 1 line
2.7.4
PATCH 2/5 net: aquantia: fix potential IOMMU fault after driver unbind
In reply to Igor RusskikhFrom: Dmitry Bogdanov <[email protected]>
IOMMU fault may occurr on unbind/bind or if_down/if_up sequence.
Although driver disables the rings on down, this is not enough. Due to internal HW design, during subsequent initialization NIC sometimes may reuse RX descriptors cache and write to the host memory from the descriptor cache.
That's get catched by IOMMU on host.
This patch invalidates the descriptor cache in NIC on interface down to prevent writing to the cached descriptors and to the memory pointed in those descriptors.
--- .../net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 6 ++++++ .../net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c | 8 ++++++++ .../net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h | 3 +++ .../aquantia/atlantic/hw_atl/hw_atl_llh_internal.h | 18 ++++++++++++++++++ 4 files changed, 35 insertions(+)
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +6 -0
@@ -920,6 +920,12 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)static int hw_atl_b0_hw_stop (struct aq_hw_s *self) {hw_atl_b0_hw_irq_disable (self,HW_ATL_B0_INT_MASK ); + +/* Invalidate Descriptor Cache to prevent writing to the cached +* descriptors and to the data pointer of those descriptors +*/ +hw_atl_rdm_rx_dma_desc_cache_init_set (self,1 ); +return aq_hw_err_from_flags (self); }
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c +8 -0
@@ -619,6 +619,14 @@ void hw_atl_rpb_rx_flow_ctl_mode_set(struct aq_hw_s *aq_hw, u32 rx_flow_ctl_mode HW_ATL_RPB_RX_FC_MODE_SHIFT, rx_flow_ctl_mode); } +void hw_atl_rdm_rx_dma_desc_cache_init_set (struct aq_hw_s *aq_hw,u32 init) +{ +aq_hw_write_reg_bit (aq_hw,HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR , +HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK , +HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT , + init); +} +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) {
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h +3 -0
@@ -325,6 +325,9 @@ 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); +/* set rdm rx dma descriptor cache init */ +void hw_atl_rdm_rx_dma_desc_cache_init_set (struct aq_hw_s *aq_hw,u32 init); +/* 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);
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h +18 -0
@@ -293,6 +293,24 @@/* default value of bitfield desc{d}_reset */ #define HW_ATL_RDM_DESCDRESET_DEFAULT 0x0 +/* rdm_desc_init_i bitfield definitions +* preprocessor definitions for the bitfield rdm_desc_init_i. +* port="pif_rdm_desc_init_i" +*/ + +/* register address for bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR 0x00005a00 +/* bitmask for bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK 0xffffffff +/* inverted bitmask for bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSKN 0x00000000 +/* lower bit position of bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT 0 +/* width of bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_WIDTH 32 +/* default value of bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_DEFAULT 0x0 +/* rx int_desc_wrb_en bitfield definitions * preprocessor definitions for the bitfield "int_desc_wrb_en". * port="pif_rdm_int_desc_wrb_en_i"
Signature · 1 line
2.7.4
PATCH 3/5 net: aquantia: fixed enable unicast on 32 macvlan
In reply to Igor RusskikhFixed a condition mistake due to which macvlans unicast item number 32 was not added in the unicast filter.
The consequence is that when exactly 32 macvlans are created on NIC, the last created macvlan receives no traffic because its MAC was not registered in HW.
--- drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/aquantia/atlantic/aq_nic.c +1 -1
@@ -600,7 +600,7 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev) } } -if (i >0 && i <AQ_HW_MULTICAST_ADDRESS_MAX ) { +if (i >0 && i <=AQ_HW_MULTICAST_ADDRESS_MAX ) { packet_filter |=IFF_MULTICAST ; self->mc_list.count = i; self->aq_hw_ops->hw_multicast_list_set(self->aq_hw,
Signature · 1 line
2.7.4
PATCH 4/5 net: aquantia: invalid checksumm offload implementation
In reply to Igor RusskikhFrom: Dmitry Bogdanov <[email protected]>
Packets with marked invalid IP/UDP/TCP checksums were considered as good by the driver. The error was in a logic, processing offload bits in RX descriptor.
--- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 35 +++++++++++++-------- .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 36 +++++++++++----------- 2 files changed, 41 insertions(+), 30 deletions(-)
drivers/net/ethernet/aquantia/atlantic/aq_ring.c +23 -12
@@ -172,6 +172,27 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)return !!budget; } +static void aq_rx_checksum (struct aq_ring_s *self, +struct aq_ring_buff_s *buff, +struct sk_buff *skb) +{ +if (!(self->aq_nic->ndev->features &NETIF_F_RXCSUM )) +return ; + +if (unlikely (buff->is_cso_err)) { + ++self->stats.rx.errors; + skb->ip_summed =CHECKSUM_NONE ; +return ; + } +if (buff->is_ip_cso) { +__skb_incr_checksum_unnecessary (skb); +if (buff->is_udp_cso || buff->is_tcp_cso) +__skb_incr_checksum_unnecessary (skb); + }else { + skb->ip_summed =CHECKSUM_NONE ; + } +} +#define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) int aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi,
@@ -267,18 +288,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self, } skb->protocol =eth_type_trans (skb, ndev); -if (unlikely (buff->is_cso_err)) { - ++self->stats.rx.errors; - skb->ip_summed =CHECKSUM_NONE ; - }else { -if (buff->is_ip_cso) { -__skb_incr_checksum_unnecessary (skb); -if (buff->is_udp_cso || buff->is_tcp_cso) -__skb_incr_checksum_unnecessary (skb); - }else { - skb->ip_summed =CHECKSUM_NONE ; - } - } + +aq_rx_checksum (self, buff, skb); skb_set_hash(skb, buff->rss_hash, buff->is_hash_l4 ? PKT_HASH_TYPE_L4 :
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +18 -18
@@ -660,9 +660,9 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,struct hw_atl_rxd_wb_s *rxd_wb = (struct hw_atl_rxd_wb_s *) &ring->dx_ring[ring->hw_head *HW_ATL_B0_RXD_SIZE ]; -unsigned int is_err =1U ;unsigned int is_rx_check_sum_enabled =0U ;unsigned int pkt_type =0U ; +u8 rx_stat =0U ;if (!(rxd_wb->status &0x1U )) {/* RxD is not done */ break ;
@@ -670,35 +670,35 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, buff = &ring->buff_ring[ring->hw_head]; - is_err = (0x0000003CU & rxd_wb->status); + rx_stat = (0x0000003CU & rxd_wb->status) >>2 ; is_rx_check_sum_enabled = (rxd_wb->type) & (0x3U <<19 ); - is_err &= ~0x20U ;/* exclude validity bit */ 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 ) ?0U :1U ; +if (is_rx_check_sum_enabled &BIT (0 ) && + (0x0U == (pkt_type &0x3U ))) + buff->is_ip_cso = (rx_stat &BIT (1 )) ?0U :1U ; +if (is_rx_check_sum_enabled &BIT (1 )) {if (0x4U == (pkt_type &0x1CU )) - buff->is_udp_cso = buff->is_cso_err ?0U :1U ; + buff->is_udp_cso = (rx_stat &BIT (2 )) ?0U : + !!(rx_stat &BIT (3 ));else if (0x0U == (pkt_type &0x1CU )) - buff->is_tcp_cso = buff->is_cso_err ?0U :1U ; - -/* Checksum offload workaround for small packets */ -if (rxd_wb->pkt_len <=60 ) { - buff->is_ip_cso =0U ; - buff->is_cso_err =0U ; - } + buff->is_tcp_cso = (rx_stat &BIT (2 )) ?0U : + !!(rx_stat &BIT (3 )); + } + buff->is_cso_err = !!(rx_stat &0x6 ); +/* Checksum offload workaround for small packets */ +if (unlikely (rxd_wb->pkt_len <=60 )) { + buff->is_ip_cso =0U ; + buff->is_cso_err =0U ; } - - is_err &= ~0x18U ;dma_unmap_page (ndev, buff->pa, buff->len,DMA_FROM_DEVICE ); -if (is_err || rxd_wb->type &0x1000U ) { -/* status error or DMA error */ +if ((rx_stat &BIT (0 )) || rxd_wb->type &0x1000U ) { +/* MAC error or DMA error */ buff->is_error =1U ; }else {if (self->aq_nic_cfg->is_rss) {
Signature · 1 line
2.7.4
PATCH 5/5 net: aquantia: allow rx checksum offload configuration
In reply to Igor RusskikhFrom: Dmitry Bogdanov <[email protected]>
RX Checksum offloads could not be configured and ignored netdev features flag for checksumming.
--- drivers/net/ethernet/aquantia/atlantic/aq_hw.h | 3 +++ drivers/net/ethernet/aquantia/atlantic/aq_main.c | 10 ++++++++-- drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 +- drivers/net/ethernet/aquantia/atlantic/aq_nic.h | 2 +- drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 7 +++++-- 5 files changed, 18 insertions(+), 6 deletions(-)
drivers/net/ethernet/aquantia/atlantic/aq_hw.h +3 -0
@@ -204,6 +204,9 @@ struct aq_hw_ops {int (*hw_get_fw_version)(struct aq_hw_s *self,u32 *fw_version); +int (*hw_set_offload)(struct aq_hw_s *self, +struct aq_nic_cfg_s *aq_nic_cfg); +int (*hw_set_fc)(struct aq_hw_s *self,u32 fc,u32 tc); };
drivers/net/ethernet/aquantia/atlantic/aq_main.c +8 -2
@@ -99,8 +99,11 @@ static int aq_ndev_set_features(struct net_device *ndev,struct aq_nic_s *aq_nic =netdev_priv (ndev);struct aq_nic_cfg_s *aq_cfg =aq_nic_get_cfg (aq_nic);bool is_lro = false; +int err =0 ; + + aq_cfg->features = features; -if (aq_cfg->hw_features &NETIF_F_LRO ) { +if (aq_cfg->aq_hw_caps->hw_features &NETIF_F_LRO ) { is_lro = features &NETIF_F_LRO ;if (aq_cfg->is_lro != is_lro) {
@@ -112,8 +115,11 @@ static int aq_ndev_set_features(struct net_device *ndev, } } } +if ((aq_nic->ndev->features ^ features) &NETIF_F_RXCSUM ) + err = aq_nic->aq_hw_ops->hw_set_offload (aq_nic->aq_hw, + aq_cfg); -return 0 ; +return err; }static int aq_ndev_set_mac_address (struct net_device *ndev,void *addr)
drivers/net/ethernet/aquantia/atlantic/aq_nic.c +1 -1
@@ -118,7 +118,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self) } cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk; - cfg->hw_features = cfg->aq_hw_caps->hw_features; + cfg->features = cfg->aq_hw_caps->hw_features; }static int aq_nic_update_link_status (struct aq_nic_s *self)
drivers/net/ethernet/aquantia/atlantic/aq_nic.h +1 -1
@@ -23,7 +23,7 @@ struct aq_vec_s;struct aq_nic_cfg_s {const struct aq_hw_caps_s *aq_hw_caps; -u64 hw_features; +u64 features;u32 rxds;/* rx ring size, descriptors # */ u32 txds;/* tx ring size, descriptors # */ u32 vecs;/* vecs==allocated irqs */
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +5 -2
@@ -234,8 +234,10 @@ static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,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 ); +hw_atl_rpo_ipv4header_crc_offload_en_set (self, !!(aq_nic_cfg->features & +NETIF_F_RXCSUM )); +hw_atl_rpo_tcp_udp_crc_offload_en_set (self, !!(aq_nic_cfg->features & +NETIF_F_RXCSUM ));/* LSO offloads*/ hw_atl_tdm_large_send_offload_en_set (self,0xFFFFFFFFU );
@@ -974,5 +976,6 @@ const struct aq_hw_ops hw_atl_ops_b0 = { .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, + .hw_set_offload = hw_atl_b0_hw_offload_set, .hw_set_fc = hw_atl_b0_set_fc, };
Signature · 1 line
2.7.4
David Miller
maintainerFrom: Igor Russkikh <[email protected]>
Date: Fri, 9 Nov 2018 11:53:54 +0000
Quoted 2 lines
The patchset fixes a number of bugs found in various areas after driver validation.
Series applied, thank you.
Please, when you provide a Fixes: tag, do not separate it with the other Signed-off-by: and Acked-by: etc. tags with an empty line. It is just another tag, so keep them all together without any kind of separation like that.
A lot of people seem to do this, I wonder why :-)
Thank you.