diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igc/igc_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_main.c | 96 | 
1 files changed, 85 insertions, 11 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index b1669d7cf435..686793c539f2 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -2464,8 +2464,7 @@ unmap:  	return -ENOMEM;  } -static struct igc_ring *igc_xdp_get_tx_ring(struct igc_adapter *adapter, -					    int cpu) +struct igc_ring *igc_get_tx_ring(struct igc_adapter *adapter, int cpu)  {  	int index = cpu; @@ -2489,7 +2488,7 @@ static int igc_xdp_xmit_back(struct igc_adapter *adapter, struct xdp_buff *xdp)  	if (unlikely(!xdpf))  		return -EFAULT; -	ring = igc_xdp_get_tx_ring(adapter, cpu); +	ring = igc_get_tx_ring(adapter, cpu);  	nq = txring_txq(ring);  	__netif_tx_lock(nq, cpu); @@ -2549,7 +2548,7 @@ out:  }  /* This function assumes __netif_tx_lock is held by the caller. */ -static void igc_flush_tx_descriptors(struct igc_ring *ring) +void igc_flush_tx_descriptors(struct igc_ring *ring)  {  	/* Once tail pointer is updated, hardware can fetch the descriptors  	 * any time so we issue a write membar here to ensure all memory @@ -2566,7 +2565,7 @@ static void igc_finalize_xdp(struct igc_adapter *adapter, int status)  	struct igc_ring *ring;  	if (status & IGC_XDP_TX) { -		ring = igc_xdp_get_tx_ring(adapter, cpu); +		ring = igc_get_tx_ring(adapter, cpu);  		nq = txring_txq(ring);  		__netif_tx_lock(nq, cpu); @@ -2638,6 +2637,14 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)  			size -= IGC_TS_HDR_LEN;  		} +		if (igc_fpe_is_pmac_enabled(adapter) && +		    igc_fpe_handle_mpacket(adapter, rx_desc, size, pktbuf)) { +			/* Advance the ring next-to-clean */ +			igc_is_non_eop(rx_ring, rx_desc); +			cleaned_count++; +			continue; +		} +  		if (!skb) {  			xdp_init_buff(&ctx.xdp, truesize, &rx_ring->xdp_rxq);  			xdp_prepare_buff(&ctx.xdp, pktbuf - igc_rx_offset(rx_ring), @@ -3145,6 +3152,11 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)  		if (!(eop_desc->wb.status & cpu_to_le32(IGC_TXD_STAT_DD)))  			break; +		if (igc_fpe_is_pmac_enabled(adapter) && +		    igc_fpe_transmitted_smd_v(tx_desc)) +			ethtool_mmsv_event_handle(&adapter->fpe.mmsv, +						  ETHTOOL_MMSV_LD_SENT_VERIFY_MPACKET); +  		/* Hold the completions while there's a pending tx hardware  		 * timestamp request from XDP Tx metadata.  		 */ @@ -4037,6 +4049,30 @@ static int igc_uc_unsync(struct net_device *netdev, const unsigned char *addr)  }  /** + * igc_enable_empty_addr_recv - Enable Rx of packets with all-zeroes MAC address + * @adapter: Pointer to the igc_adapter structure. + * + * Frame preemption verification requires that packets with the all-zeroes + * MAC address are allowed to be received by the driver. This function adds the + * all-zeroes destination address to the list of acceptable addresses. + * + * Return: 0 on success, negative value otherwise. + */ +int igc_enable_empty_addr_recv(struct igc_adapter *adapter) +{ +	u8 empty[ETH_ALEN] = {}; + +	return igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST, empty, -1); +} + +void igc_disable_empty_addr_recv(struct igc_adapter *adapter) +{ +	u8 empty[ETH_ALEN] = {}; + +	igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST, empty); +} + +/**   * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set   * @netdev: network interface device structure   * @@ -5311,6 +5347,9 @@ void igc_down(struct igc_adapter *adapter)  	igc_disable_all_tx_rings_hw(adapter);  	igc_clean_all_tx_rings(adapter);  	igc_clean_all_rx_rings(adapter); + +	if (adapter->fpe.mmsv.pmac_enabled) +		ethtool_mmsv_stop(&adapter->fpe.mmsv);  }  void igc_reinit_locked(struct igc_adapter *adapter) @@ -5710,7 +5749,8 @@ static void igc_clear_interrupt_scheme(struct igc_adapter *adapter)   */  static void igc_update_phy_info(struct timer_list *t)  { -	struct igc_adapter *adapter = from_timer(adapter, t, phy_info_timer); +	struct igc_adapter *adapter = timer_container_of(adapter, t, +							 phy_info_timer);  	igc_get_phy_info(&adapter->hw);  } @@ -5752,7 +5792,8 @@ bool igc_has_link(struct igc_adapter *adapter)   */  static void igc_watchdog(struct timer_list *t)  { -	struct igc_adapter *adapter = from_timer(adapter, t, watchdog_timer); +	struct igc_adapter *adapter = timer_container_of(adapter, t, +							 watchdog_timer);  	/* Do the rest outside of interrupt context */  	schedule_work(&adapter->watchdog_task);  } @@ -5835,6 +5876,10 @@ static void igc_watchdog_task(struct work_struct *work)  			 */  			igc_tsn_adjust_txtime_offset(adapter); +			if (adapter->fpe.mmsv.pmac_enabled) +				ethtool_mmsv_link_state_handle(&adapter->fpe.mmsv, +							       true); +  			if (adapter->link_speed != SPEED_1000)  				goto no_wait; @@ -5870,6 +5915,10 @@ no_wait:  			netdev_info(netdev, "NIC Link is Down\n");  			netif_carrier_off(netdev); +			if (adapter->fpe.mmsv.pmac_enabled) +				ethtool_mmsv_link_state_handle(&adapter->fpe.mmsv, +							       false); +  			/* link state has changed, schedule phy info update */  			if (!test_bit(__IGC_DOWN, &adapter->state))  				mod_timer(&adapter->phy_info_timer, @@ -6439,6 +6488,10 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,  	if (!validate_schedule(adapter, qopt))  		return -EINVAL; +	/* preemptible isn't supported yet */ +	if (qopt->mqprio.preemptible_tcs) +		return -EOPNOTSUPP; +  	igc_ptp_read(adapter, &now);  	if (igc_tsn_is_taprio_activated_by_user(adapter) && @@ -6679,13 +6732,14 @@ static int igc_tsn_enable_mqprio(struct igc_adapter *adapter,  				 struct tc_mqprio_qopt_offload *mqprio)  {  	struct igc_hw *hw = &adapter->hw; -	int i; +	int err, i;  	if (hw->mac.type != igc_i225)  		return -EOPNOTSUPP;  	if (!mqprio->qopt.num_tc) {  		adapter->strict_priority_enable = false; +		netdev_reset_tc(adapter->netdev);  		goto apply;  	} @@ -6716,6 +6770,21 @@ static int igc_tsn_enable_mqprio(struct igc_adapter *adapter,  	igc_save_mqprio_params(adapter, mqprio->qopt.num_tc,  			       mqprio->qopt.offset); +	err = netdev_set_num_tc(adapter->netdev, adapter->num_tc); +	if (err) +		return err; + +	for (i = 0; i < adapter->num_tc; i++) { +		err = netdev_set_tc_queue(adapter->netdev, i, 1, +					  adapter->queue_per_tc[i]); +		if (err) +			return err; +	} + +	/* In case the card is configured with less than four queues. */ +	for (; i < IGC_MAX_TX_QUEUES; i++) +		adapter->queue_per_tc[i] = i; +  	mqprio->qopt.hw = TC_MQPRIO_HW_OFFLOAD_TCS;  apply: @@ -6779,7 +6848,7 @@ static int igc_xdp_xmit(struct net_device *dev, int num_frames,  	if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))  		return -EINVAL; -	ring = igc_xdp_get_tx_ring(adapter, cpu); +	ring = igc_get_tx_ring(adapter, cpu);  	nq = txring_txq(ring);  	__netif_tx_lock(nq, cpu); @@ -7125,6 +7194,9 @@ static int igc_probe(struct pci_dev *pdev,  	netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |  			       NETDEV_XDP_ACT_XSK_ZEROCOPY; +	/* enable HW vlan tag insertion/stripping by default */ +	netdev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; +  	/* MTU range: 68 - 9216 */  	netdev->min_mtu = ETH_MIN_MTU;  	netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE; @@ -7157,8 +7229,8 @@ static int igc_probe(struct pci_dev *pdev,  	}  	/* configure RXPBSIZE and TXPBSIZE */ -	wr32(IGC_RXPBS, I225_RXPBSIZE_DEFAULT); -	wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT); +	wr32(IGC_RXPBS, IGC_RXPBSIZE_EXP_BMC_DEFAULT); +	wr32(IGC_TXPBS, IGC_TXPBSIZE_DEFAULT);  	timer_setup(&adapter->watchdog_timer, igc_watchdog, 0);  	timer_setup(&adapter->phy_info_timer, igc_update_phy_info, 0); @@ -7190,6 +7262,8 @@ static int igc_probe(struct pci_dev *pdev,  	igc_tsn_clear_schedule(adapter); +	igc_fpe_init(adapter); +  	/* reset the hardware with the new settings */  	igc_reset(adapter);  | 
