The following commit has been merged in the master branch:
commit 9640277000475d56814ef11c46b2089dc4a6338d
Merge: 3c2686aaa75edab453d941ad6e919d10d8874a76 2ac757e4152e3322a04a6dfb3d1fa010d3521abf
Author: Stephen Rothwell <sfr(a)canb.auug.org.au>
Date: Tue Apr 28 11:53:05 2020 +1000
Merge remote-tracking branch 'net-next/master'
diff --combined drivers/net/ethernet/intel/e1000e/netdev.c
index 2730b1c7dddb,e0b074820b47..53e53164188f
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@@ -6404,6 -6404,31 +6404,31 @@@ static void e1000e_s0ix_entry_flow(stru
mac_data |= BIT(3);
ew32(CTRL_EXT, mac_data);
+ /* Disable disconnected cable conditioning for Power Gating */
+ mac_data = er32(DPGFR);
+ mac_data |= BIT(2);
+ ew32(DPGFR, mac_data);
+
+ /* Don't wake from dynamic Power Gating with clock request */
+ mac_data = er32(FEXTNVM12);
+ mac_data |= BIT(12);
+ ew32(FEXTNVM12, mac_data);
+
+ /* Ungate PGCB clock */
+ mac_data = er32(FEXTNVM9);
+ mac_data |= BIT(28);
+ ew32(FEXTNVM9, mac_data);
+
+ /* Enable K1 off to enable mPHY Power Gating */
+ mac_data = er32(FEXTNVM6);
+ mac_data |= BIT(31);
+ ew32(FEXTNVM12, mac_data);
+
+ /* Enable mPHY power gating for any link and speed */
+ mac_data = er32(FEXTNVM8);
+ mac_data |= BIT(9);
+ ew32(FEXTNVM8, mac_data);
+
/* Enable the Dynamic Clock Gating in the DMA and MAC */
mac_data = er32(CTRL_EXT);
mac_data |= E1000_CTRL_EXT_DMA_DYN_CLK_EN;
@@@ -6433,6 -6458,35 +6458,35 @@@ static void e1000e_s0ix_exit_flow(struc
mac_data |= BIT(0);
ew32(FEXTNVM7, mac_data);
+ /* Disable mPHY power gating for any link and speed */
+ mac_data = er32(FEXTNVM8);
+ mac_data &= ~BIT(9);
+ ew32(FEXTNVM8, mac_data);
+
+ /* Disable K1 off */
+ mac_data = er32(FEXTNVM6);
+ mac_data &= ~BIT(31);
+ ew32(FEXTNVM12, mac_data);
+
+ /* Disable Ungate PGCB clock */
+ mac_data = er32(FEXTNVM9);
+ mac_data &= ~BIT(28);
+ ew32(FEXTNVM9, mac_data);
+
+ /* Cancel not waking from dynamic
+ * Power Gating with clock request
+ */
+ mac_data = er32(FEXTNVM12);
+ mac_data &= ~BIT(12);
+ ew32(FEXTNVM12, mac_data);
+
+ /* Cancel disable disconnected cable conditioning
+ * for Power Gating
+ */
+ mac_data = er32(DPGFR);
+ mac_data &= ~BIT(2);
+ ew32(DPGFR, mac_data);
+
/* Disable Dynamic Power Gating */
mac_data = er32(CTRL_EXT);
mac_data &= 0xFFFFFFF7;
@@@ -7549,7 -7603,7 +7603,7 @@@ static int e1000_probe(struct pci_dev *
e1000_print_device_info(adapter);
- dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP);
+ dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);
if (pci_dev_run_wake(pdev) && hw->mac.type < e1000_pch_cnp)
pm_runtime_put_noidle(&pdev->dev);
diff --combined drivers/net/ethernet/intel/igc/igc_main.c
index 59fc0097438f,9d5f8287c704..927fc95c5684
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@@ -9,11 -9,13 +9,13 @@@
#include <linux/udp.h>
#include <linux/ip.h>
#include <linux/pm_runtime.h>
+ #include <net/pkt_sched.h>
#include <net/ipv6.h>
#include "igc.h"
#include "igc_hw.h"
+ #include "igc_tsn.h"
#define DRV_VERSION "0.0.1-k"
#define DRV_SUMMARY "Intel(R) 2.5G Ethernet Linux Driver"
@@@ -45,6 -47,9 +47,9 @@@ static const struct pci_device_id igc_p
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I225_I), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I220_V), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I225_K), board_base },
+ { PCI_VDEVICE(INTEL, IGC_DEV_ID_I225_K2), board_base },
+ { PCI_VDEVICE(INTEL, IGC_DEV_ID_I225_LMVP), board_base },
+ { PCI_VDEVICE(INTEL, IGC_DEV_ID_I225_IT), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I225_BLANK_NVM), board_base },
/* required last entry */
{0, }
@@@ -106,6 -111,9 +111,9 @@@ void igc_reset(struct igc_adapter *adap
/* Re-enable PTP, where applicable. */
igc_ptp_reset(adapter);
+ /* Re-enable TSN offloading, where applicable. */
+ igc_tsn_offload_apply(adapter);
+
igc_get_phy_info(hw);
}
@@@ -757,48 -765,74 +765,74 @@@ static void igc_setup_tctl(struct igc_a
}
/**
- * igc_rar_set_index - Sync RAL[index] and RAH[index] registers with MAC table
- * @adapter: address of board private structure
- * @index: Index of the RAR entry which need to be synced with MAC table
+ * igc_set_mac_filter_hw() - Set MAC address filter in hardware
+ * @adapter: Pointer to adapter where the filter should be set
+ * @index: Filter index
+ * @addr: Destination MAC address
+ * @queue: If non-negative, queue assignment feature is enabled and frames
+ * matching the filter are enqueued onto 'queue'. Otherwise, queue
+ * assignment is disabled.
*/
- static void igc_rar_set_index(struct igc_adapter *adapter, u32 index)
+ static void igc_set_mac_filter_hw(struct igc_adapter *adapter, int index,
+ const u8 *addr, int queue)
{
- u8 *addr = adapter->mac_table[index].addr;
+ struct net_device *dev = adapter->netdev;
struct igc_hw *hw = &adapter->hw;
- u32 rar_low, rar_high;
+ u32 ral, rah;
- /* HW expects these to be in network order when they are plugged
- * into the registers which are little endian. In order to guarantee
- * that ordering we need to do an leXX_to_cpup here in order to be
- * ready for the byteswap that occurs with writel
- */
- rar_low = le32_to_cpup((__le32 *)(addr));
- rar_high = le16_to_cpup((__le16 *)(addr + 4));
+ if (WARN_ON(index >= hw->mac.rar_entry_count))
+ return;
- /* Indicate to hardware the Address is Valid. */
- if (adapter->mac_table[index].state & IGC_MAC_STATE_IN_USE) {
- if (is_valid_ether_addr(addr))
- rar_high |= IGC_RAH_AV;
+ ral = le32_to_cpup((__le32 *)(addr));
+ rah = le16_to_cpup((__le16 *)(addr + 4));
- rar_high |= IGC_RAH_POOL_1 <<
- adapter->mac_table[index].queue;
+ if (queue >= 0) {
+ rah &= ~IGC_RAH_QSEL_MASK;
+ rah |= (queue << IGC_RAH_QSEL_SHIFT);
+ rah |= IGC_RAH_QSEL_ENABLE;
}
- wr32(IGC_RAL(index), rar_low);
- wrfl();
- wr32(IGC_RAH(index), rar_high);
- wrfl();
+ rah |= IGC_RAH_AV;
+
+ wr32(IGC_RAL(index), ral);
+ wr32(IGC_RAH(index), rah);
+
+ netdev_dbg(dev, "MAC address filter set in HW: index %d", index);
+ }
+
+ /**
+ * igc_clear_mac_filter_hw() - Clear MAC address filter in hardware
+ * @adapter: Pointer to adapter where the filter should be cleared
+ * @index: Filter index
+ */
+ static void igc_clear_mac_filter_hw(struct igc_adapter *adapter, int index)
+ {
+ struct net_device *dev = adapter->netdev;
+ struct igc_hw *hw = &adapter->hw;
+
+ if (WARN_ON(index >= hw->mac.rar_entry_count))
+ return;
+
+ wr32(IGC_RAL(index), 0);
+ wr32(IGC_RAH(index), 0);
+
+ netdev_dbg(dev, "MAC address filter cleared in HW: index %d", index);
}
/* Set default MAC address for the PF in the first RAR entry */
static void igc_set_default_mac_filter(struct igc_adapter *adapter)
{
struct igc_mac_addr *mac_table = &adapter->mac_table[0];
+ struct net_device *dev = adapter->netdev;
+ u8 *addr = adapter->hw.mac.addr;
- ether_addr_copy(mac_table->addr, adapter->hw.mac.addr);
+ netdev_dbg(dev, "Set default MAC address filter: address %pM", addr);
+
+ ether_addr_copy(mac_table->addr, addr);
mac_table->state = IGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE;
+ mac_table->queue = -1;
- igc_rar_set_index(adapter, 0);
+ igc_set_mac_filter_hw(adapter, 0, addr, mac_table->queue);
}
/**
@@@ -864,6 -898,23 +898,23 @@@ static int igc_write_mc_addr_list(struc
return netdev_mc_count(netdev);
}
+ static __le32 igc_tx_launchtime(struct igc_adapter *adapter, ktime_t txtime)
+ {
+ ktime_t cycle_time = adapter->cycle_time;
+ ktime_t base_time = adapter->base_time;
+ u32 launchtime;
+
+ /* FIXME: when using ETF together with taprio, we may have a
+ * case where 'delta' is larger than the cycle_time, this may
+ * cause problems if we don't read the current value of
+ * IGC_BASET, as the value writen into the launchtime
+ * descriptor field may be misinterpreted.
+ */
+ div_s64_rem(ktime_sub_ns(txtime, base_time), cycle_time, &launchtime);
+
+ return cpu_to_le32(launchtime);
+ }
+
static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
struct igc_tx_buffer *first,
u32 vlan_macip_lens, u32 type_tucmd,
@@@ -871,7 -922,6 +922,6 @@@
{
struct igc_adv_tx_context_desc *context_desc;
u16 i = tx_ring->next_to_use;
- struct timespec64 ts;
context_desc = IGC_TX_CTXTDESC(tx_ring, i);
@@@ -893,9 -943,12 +943,12 @@@
* should have been handled by the upper layers.
*/
if (tx_ring->launchtime_enable) {
- ts = ktime_to_timespec64(first->skb->tstamp);
+ struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
+ ktime_t txtime = first->skb->tstamp;
+
first->skb->tstamp = ktime_set(0, 0);
- context_desc->launch_time = cpu_to_le32(ts.tv_nsec / 32);
+ context_desc->launch_time = igc_tx_launchtime(adapter,
+ txtime);
} else {
context_desc->launch_time = 0;
}
@@@ -2133,129 -2186,148 +2186,148 @@@ static void igc_nfc_filter_restore(stru
spin_unlock(&adapter->nfc_lock);
}
- /* If the filter to be added and an already existing filter express
- * the same address and address type, it should be possible to only
- * override the other configurations, for example the queue to steer
- * traffic.
- */
- static bool igc_mac_entry_can_be_used(const struct igc_mac_addr *entry,
- const u8 *addr, const u8 flags)
+ static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr,
+ u8 flags)
{
- if (!(entry->state & IGC_MAC_STATE_IN_USE))
- return true;
+ int max_entries = adapter->hw.mac.rar_entry_count;
+ struct igc_mac_addr *entry;
+ int i;
- if ((entry->state & IGC_MAC_STATE_SRC_ADDR) !=
- (flags & IGC_MAC_STATE_SRC_ADDR))
- return false;
+ for (i = 0; i < max_entries; i++) {
+ entry = &adapter->mac_table[i];
- if (!ether_addr_equal(addr, entry->addr))
- return false;
+ if (!(entry->state & IGC_MAC_STATE_IN_USE))
+ continue;
+ if (!ether_addr_equal(addr, entry->addr))
+ continue;
+ if ((entry->state & IGC_MAC_STATE_SRC_ADDR) !=
+ (flags & IGC_MAC_STATE_SRC_ADDR))
+ continue;
- return true;
+ return i;
+ }
+
+ return -1;
}
- /* Add a MAC filter for 'addr' directing matching traffic to 'queue',
- * 'flags' is used to indicate what kind of match is made, match is by
- * default for the destination address, if matching by source address
- * is desired the flag IGC_MAC_STATE_SRC_ADDR can be used.
- */
- static int igc_add_mac_filter(struct igc_adapter *adapter,
- const u8 *addr, const u8 queue)
+ static int igc_get_avail_mac_filter_slot(struct igc_adapter *adapter)
{
- struct igc_hw *hw = &adapter->hw;
- int rar_entries = hw->mac.rar_entry_count;
+ int max_entries = adapter->hw.mac.rar_entry_count;
+ struct igc_mac_addr *entry;
int i;
- if (is_zero_ether_addr(addr))
+ for (i = 0; i < max_entries; i++) {
+ entry = &adapter->mac_table[i];
+
+ if (!(entry->state & IGC_MAC_STATE_IN_USE))
+ return i;
+ }
+
+ return -1;
+ }
+
+ /**
+ * igc_add_mac_filter() - Add MAC address filter
+ * @adapter: Pointer to adapter where the filter should be added
+ * @addr: MAC address
+ * @queue: If non-negative, queue assignment feature is enabled and frames
+ * matching the filter are enqueued onto 'queue'. Otherwise, queue
+ * assignment is disabled.
+ * @flags: Set IGC_MAC_STATE_SRC_ADDR bit to indicate @address is a source
+ * address
+ *
+ * Return: 0 in case of success, negative errno code otherwise.
+ */
+ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
+ const s8 queue, const u8 flags)
+ {
+ struct net_device *dev = adapter->netdev;
+ int index;
+
+ if (!is_valid_ether_addr(addr))
return -EINVAL;
+ if (flags & IGC_MAC_STATE_SRC_ADDR)
+ return -ENOTSUPP;
- /* Search for the first empty entry in the MAC table.
- * Do not touch entries at the end of the table reserved for the VF MAC
- * addresses.
- */
- for (i = 0; i < rar_entries; i++) {
- if (!igc_mac_entry_can_be_used(&adapter->mac_table[i],
- addr, 0))
- continue;
+ index = igc_find_mac_filter(adapter, addr, flags);
+ if (index >= 0)
+ goto update_queue_assignment;
- ether_addr_copy(adapter->mac_table[i].addr, addr);
- adapter->mac_table[i].queue = queue;
- adapter->mac_table[i].state |= IGC_MAC_STATE_IN_USE;
+ index = igc_get_avail_mac_filter_slot(adapter);
+ if (index < 0)
+ return -ENOSPC;
- igc_rar_set_index(adapter, i);
- return i;
- }
+ netdev_dbg(dev, "Add MAC address filter: index %d address %pM queue %d",
+ index, addr, queue);
+
+ ether_addr_copy(adapter->mac_table[index].addr, addr);
+ adapter->mac_table[index].state |= IGC_MAC_STATE_IN_USE | flags;
+ update_queue_assignment:
+ adapter->mac_table[index].queue = queue;
- return -ENOSPC;
+ igc_set_mac_filter_hw(adapter, index, addr, queue);
+ return 0;
}
- /* Remove a MAC filter for 'addr' directing matching traffic to
- * 'queue', 'flags' is used to indicate what kind of match need to be
- * removed, match is by default for the destination address, if
- * matching by source address is to be removed the flag
- * IGC_MAC_STATE_SRC_ADDR can be used.
+ /**
+ * igc_del_mac_filter() - Delete MAC address filter
+ * @adapter: Pointer to adapter where the filter should be deleted from
+ * @addr: MAC address
+ * @flags: Set IGC_MAC_STATE_SRC_ADDR bit to indicate @address is a source
+ * address
+ *
+ * Return: 0 in case of success, negative errno code otherwise.
*/
- static int igc_del_mac_filter(struct igc_adapter *adapter,
- const u8 *addr, const u8 queue)
+ int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr,
+ const u8 flags)
{
- struct igc_hw *hw = &adapter->hw;
- int rar_entries = hw->mac.rar_entry_count;
- int i;
+ struct net_device *dev = adapter->netdev;
+ struct igc_mac_addr *entry;
+ int index;
- if (is_zero_ether_addr(addr))
+ if (!is_valid_ether_addr(addr))
return -EINVAL;
- /* Search for matching entry in the MAC table based on given address
- * and queue. Do not touch entries at the end of the table reserved
- * for the VF MAC addresses.
- */
- for (i = 0; i < rar_entries; i++) {
- if (!(adapter->mac_table[i].state & IGC_MAC_STATE_IN_USE))
- continue;
- if (adapter->mac_table[i].state != 0)
- continue;
- if (adapter->mac_table[i].queue != queue)
- continue;
- if (!ether_addr_equal(adapter->mac_table[i].addr, addr))
- continue;
+ index = igc_find_mac_filter(adapter, addr, flags);
+ if (index < 0)
+ return -ENOENT;
- /* When a filter for the default address is "deleted",
- * we return it to its initial configuration
+ entry = &adapter->mac_table[index];
+
+ if (entry->state & IGC_MAC_STATE_DEFAULT) {
+ /* If this is the default filter, we don't actually delete it.
+ * We just reset to its default value i.e. disable queue
+ * assignment.
*/
- if (adapter->mac_table[i].state & IGC_MAC_STATE_DEFAULT) {
- adapter->mac_table[i].state =
- IGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE;
- adapter->mac_table[i].queue = 0;
- } else {
- adapter->mac_table[i].state = 0;
- adapter->mac_table[i].queue = 0;
- memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
- }
+ netdev_dbg(dev, "Disable default MAC filter queue assignment");
- igc_rar_set_index(adapter, i);
- return 0;
+ entry->queue = -1;
+ igc_set_mac_filter_hw(adapter, 0, addr, entry->queue);
+ } else {
+ netdev_dbg(dev, "Delete MAC address filter: index %d address %pM",
+ index, addr);
+
+ entry->state = 0;
+ entry->queue = -1;
+ memset(entry->addr, 0, ETH_ALEN);
+ igc_clear_mac_filter_hw(adapter, index);
}
- return -ENOENT;
+ return 0;
}
static int igc_uc_sync(struct net_device *netdev, const unsigned char *addr)
{
struct igc_adapter *adapter = netdev_priv(netdev);
- int ret;
- ret = igc_add_mac_filter(adapter, addr, adapter->num_rx_queues);
-
- return min_t(int, ret, 0);
+ return igc_add_mac_filter(adapter, addr, -1, 0);
}
static int igc_uc_unsync(struct net_device *netdev, const unsigned char *addr)
{
struct igc_adapter *adapter = netdev_priv(netdev);
- igc_del_mac_filter(adapter, addr, adapter->num_rx_queues);
-
- return 0;
+ return igc_del_mac_filter(adapter, addr, 0);
}
/**
@@@ -2325,7 -2397,9 +2397,9 @@@ static void igc_configure(struct igc_ad
igc_setup_mrqc(adapter);
igc_setup_rctl(adapter);
+ igc_set_default_mac_filter(adapter);
igc_nfc_filter_restore(adapter);
+
igc_configure_tx(adapter);
igc_configure_rx(adapter);
@@@ -3458,9 -3532,6 +3532,6 @@@ static void igc_nfc_filter_exit(struct
hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node)
igc_erase_filter(adapter, rule);
- hlist_for_each_entry(rule, &adapter->cls_flower_list, nfc_node)
- igc_erase_filter(adapter, rule);
-
spin_unlock(&adapter->nfc_lock);
}
@@@ -3689,106 -3760,6 +3760,6 @@@ igc_features_check(struct sk_buff *skb
return features;
}
- /* Add a MAC filter for 'addr' directing matching traffic to 'queue',
- * 'flags' is used to indicate what kind of match is made, match is by
- * default for the destination address, if matching by source address
- * is desired the flag IGC_MAC_STATE_SRC_ADDR can be used.
- */
- static int igc_add_mac_filter_flags(struct igc_adapter *adapter,
- const u8 *addr, const u8 queue,
- const u8 flags)
- {
- struct igc_hw *hw = &adapter->hw;
- int rar_entries = hw->mac.rar_entry_count;
- int i;
-
- if (is_zero_ether_addr(addr))
- return -EINVAL;
-
- /* Search for the first empty entry in the MAC table.
- * Do not touch entries at the end of the table reserved for the VF MAC
- * addresses.
- */
- for (i = 0; i < rar_entries; i++) {
- if (!igc_mac_entry_can_be_used(&adapter->mac_table[i],
- addr, flags))
- continue;
-
- ether_addr_copy(adapter->mac_table[i].addr, addr);
- adapter->mac_table[i].queue = queue;
- adapter->mac_table[i].state |= IGC_MAC_STATE_IN_USE | flags;
-
- igc_rar_set_index(adapter, i);
- return i;
- }
-
- return -ENOSPC;
- }
-
- int igc_add_mac_steering_filter(struct igc_adapter *adapter,
- const u8 *addr, u8 queue, u8 flags)
- {
- return igc_add_mac_filter_flags(adapter, addr, queue,
- IGC_MAC_STATE_QUEUE_STEERING | flags);
- }
-
- /* Remove a MAC filter for 'addr' directing matching traffic to
- * 'queue', 'flags' is used to indicate what kind of match need to be
- * removed, match is by default for the destination address, if
- * matching by source address is to be removed the flag
- * IGC_MAC_STATE_SRC_ADDR can be used.
- */
- static int igc_del_mac_filter_flags(struct igc_adapter *adapter,
- const u8 *addr, const u8 queue,
- const u8 flags)
- {
- struct igc_hw *hw = &adapter->hw;
- int rar_entries = hw->mac.rar_entry_count;
- int i;
-
- if (is_zero_ether_addr(addr))
- return -EINVAL;
-
- /* Search for matching entry in the MAC table based on given address
- * and queue. Do not touch entries at the end of the table reserved
- * for the VF MAC addresses.
- */
- for (i = 0; i < rar_entries; i++) {
- if (!(adapter->mac_table[i].state & IGC_MAC_STATE_IN_USE))
- continue;
- if ((adapter->mac_table[i].state & flags) != flags)
- continue;
- if (adapter->mac_table[i].queue != queue)
- continue;
- if (!ether_addr_equal(adapter->mac_table[i].addr, addr))
- continue;
-
- /* When a filter for the default address is "deleted",
- * we return it to its initial configuration
- */
- if (adapter->mac_table[i].state & IGC_MAC_STATE_DEFAULT) {
- adapter->mac_table[i].state =
- IGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE;
- } else {
- adapter->mac_table[i].state = 0;
- adapter->mac_table[i].queue = 0;
- memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
- }
-
- igc_rar_set_index(adapter, i);
- return 0;
- }
-
- return -ENOENT;
- }
-
- int igc_del_mac_steering_filter(struct igc_adapter *adapter,
- const u8 *addr, u8 queue, u8 flags)
- {
- return igc_del_mac_filter_flags(adapter, addr, queue,
- IGC_MAC_STATE_QUEUE_STEERING | flags);
- }
-
static void igc_tsync_interrupt(struct igc_adapter *adapter)
{
struct igc_hw *hw = &adapter->hw;
@@@ -4009,7 -3980,6 +3980,6 @@@ static void igc_watchdog_task(struct wo
struct igc_hw *hw = &adapter->hw;
struct igc_phy_info *phy = &hw->phy;
u16 phy_data, retry_count = 20;
- u32 connsw;
u32 link;
int i;
@@@ -4022,14 -3992,6 +3992,6 @@@
link = false;
}
- /* Force link down if we have fiber to swap to */
- if (adapter->flags & IGC_FLAG_MAS_ENABLE) {
- if (hw->phy.media_type == igc_media_type_copper) {
- connsw = rd32(IGC_CONNSW);
- if (!(connsw & IGC_CONNSW_AUTOSENSE_EN))
- link = 0;
- }
- }
if (link) {
/* Cancel scheduled suspend requests. */
pm_runtime_resume(netdev->dev.parent);
@@@ -4491,6 -4453,158 +4453,158 @@@ static int igc_ioctl(struct net_device
}
}
+ static int igc_save_launchtime_params(struct igc_adapter *adapter, int queue,
+ bool enable)
+ {
+ struct igc_ring *ring;
+ int i;
+
+ if (queue < 0 || queue >= adapter->num_tx_queues)
+ return -EINVAL;
+
+ ring = adapter->tx_ring[queue];
+ ring->launchtime_enable = enable;
+
+ if (adapter->base_time)
+ return 0;
+
+ adapter->cycle_time = NSEC_PER_SEC;
+
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ ring = adapter->tx_ring[i];
+ ring->start_time = 0;
+ ring->end_time = NSEC_PER_SEC;
+ }
+
+ return 0;
+ }
+
+ static bool validate_schedule(const struct tc_taprio_qopt_offload *qopt)
+ {
+ int queue_uses[IGC_MAX_TX_QUEUES] = { };
+ size_t n;
+
+ if (qopt->cycle_time_extension)
+ return false;
+
+ for (n = 0; n < qopt->num_entries; n++) {
+ const struct tc_taprio_sched_entry *e;
+ int i;
+
+ e = &qopt->entries[n];
+
+ /* i225 only supports "global" frame preemption
+ * settings.
+ */
+ if (e->command != TC_TAPRIO_CMD_SET_GATES)
+ return false;
+
+ for (i = 0; i < IGC_MAX_TX_QUEUES; i++) {
+ if (e->gate_mask & BIT(i))
+ queue_uses[i]++;
+
+ if (queue_uses[i] > 1)
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ static int igc_tsn_enable_launchtime(struct igc_adapter *adapter,
+ struct tc_etf_qopt_offload *qopt)
+ {
+ struct igc_hw *hw = &adapter->hw;
+ int err;
+
+ if (hw->mac.type != igc_i225)
+ return -EOPNOTSUPP;
+
+ err = igc_save_launchtime_params(adapter, qopt->queue, qopt->enable);
+ if (err)
+ return err;
+
+ return igc_tsn_offload_apply(adapter);
+ }
+
+ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+ struct tc_taprio_qopt_offload *qopt)
+ {
+ u32 start_time = 0, end_time = 0;
+ size_t n;
+
+ if (!qopt->enable) {
+ adapter->base_time = 0;
+ return 0;
+ }
+
+ if (adapter->base_time)
+ return -EALREADY;
+
+ if (!validate_schedule(qopt))
+ return -EINVAL;
+
+ adapter->cycle_time = qopt->cycle_time;
+ adapter->base_time = qopt->base_time;
+
+ /* FIXME: be a little smarter about cases when the gate for a
+ * queue stays open for more than one entry.
+ */
+ for (n = 0; n < qopt->num_entries; n++) {
+ struct tc_taprio_sched_entry *e = &qopt->entries[n];
+ int i;
+
+ end_time += e->interval;
+
+ for (i = 0; i < IGC_MAX_TX_QUEUES; i++) {
+ struct igc_ring *ring = adapter->tx_ring[i];
+
+ if (!(e->gate_mask & BIT(i)))
+ continue;
+
+ ring->start_time = start_time;
+ ring->end_time = end_time;
+ }
+
+ start_time += e->interval;
+ }
+
+ return 0;
+ }
+
+ static int igc_tsn_enable_qbv_scheduling(struct igc_adapter *adapter,
+ struct tc_taprio_qopt_offload *qopt)
+ {
+ struct igc_hw *hw = &adapter->hw;
+ int err;
+
+ if (hw->mac.type != igc_i225)
+ return -EOPNOTSUPP;
+
+ err = igc_save_qbv_schedule(adapter, qopt);
+ if (err)
+ return err;
+
+ return igc_tsn_offload_apply(adapter);
+ }
+
+ static int igc_setup_tc(struct net_device *dev, enum tc_setup_type type,
+ void *type_data)
+ {
+ struct igc_adapter *adapter = netdev_priv(dev);
+
+ switch (type) {
+ case TC_SETUP_QDISC_TAPRIO:
+ return igc_tsn_enable_qbv_scheduling(adapter, type_data);
+
+ case TC_SETUP_QDISC_ETF:
+ return igc_tsn_enable_launchtime(adapter, type_data);
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ }
+
static const struct net_device_ops igc_netdev_ops = {
.ndo_open = igc_open,
.ndo_stop = igc_close,
@@@ -4503,6 -4617,7 +4617,7 @@@
.ndo_set_features = igc_set_features,
.ndo_features_check = igc_features_check,
.ndo_do_ioctl = igc_ioctl,
+ .ndo_setup_tc = igc_setup_tc,
};
/* PCIe configuration access */
@@@ -4726,6 -4841,17 +4841,17 @@@ static int igc_probe(struct pci_dev *pd
netdev->features |= NETIF_F_RXCSUM;
netdev->features |= NETIF_F_HW_CSUM;
netdev->features |= NETIF_F_SCTP_CRC;
+ netdev->features |= NETIF_F_HW_TC;
+
+ #define IGC_GSO_PARTIAL_FEATURES (NETIF_F_GSO_GRE | \
+ NETIF_F_GSO_GRE_CSUM | \
+ NETIF_F_GSO_IPXIP4 | \
+ NETIF_F_GSO_IPXIP6 | \
+ NETIF_F_GSO_UDP_TUNNEL | \
+ NETIF_F_GSO_UDP_TUNNEL_CSUM)
+
+ netdev->gso_partial_features = IGC_GSO_PARTIAL_FEATURES;
+ netdev->features |= NETIF_F_GSO_PARTIAL | IGC_GSO_PARTIAL_FEATURES;
/* setup the private structure */
err = igc_sw_init(adapter);
@@@ -4825,7 -4951,7 +4951,7 @@@
pcie_print_link_status(pdev);
netdev_info(netdev, "MAC: %pM\n", netdev->dev_addr);
- dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP);
+ dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);
pm_runtime_put_noidle(&pdev->dev);
diff --combined drivers/net/phy/marvell10g.c
index 1f1a01c98e44,8352c09004c7..d4c2e62b2439
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@@ -66,9 -66,6 +66,9 @@@ enum
MV_PCS_CSSR1_SPD2_2500 = 0x0004,
MV_PCS_CSSR1_SPD2_10000 = 0x0000,
+ /* Temperature read register (88E2110 only) */
+ MV_PCS_TEMP = 0x8042,
+
/* These registers appear at 0x800X and 0xa00X - the 0xa00X control
* registers appear to set themselves to the 0x800X when AN is
* restarted, but status registers appear readable from either.
@@@ -80,7 -77,6 +80,7 @@@
MV_V2_PORT_CTRL = 0xf001,
MV_V2_PORT_CTRL_SWRST = BIT(15),
MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
+ /* Temperature control/read registers (88X3310 only) */
MV_V2_TEMP_CTRL = 0xf08a,
MV_V2_TEMP_CTRL_MASK = 0xc000,
MV_V2_TEMP_CTRL_SAMPLE = 0x0000,
@@@ -108,24 -104,6 +108,24 @@@ static umode_t mv3310_hwmon_is_visible(
return 0;
}
+static int mv3310_hwmon_read_temp_reg(struct phy_device *phydev)
+{
+ return phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP);
+}
+
+static int mv2110_hwmon_read_temp_reg(struct phy_device *phydev)
+{
+ return phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_TEMP);
+}
+
+static int mv10g_hwmon_read_temp_reg(struct phy_device *phydev)
+{
+ if (phydev->drv->phy_id == MARVELL_PHY_ID_88X3310)
+ return mv3310_hwmon_read_temp_reg(phydev);
+ else /* MARVELL_PHY_ID_88E2110 */
+ return mv2110_hwmon_read_temp_reg(phydev);
+}
+
static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *value)
{
@@@ -138,7 -116,7 +138,7 @@@
}
if (type == hwmon_temp && attr == hwmon_temp_input) {
- temp = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP);
+ temp = mv10g_hwmon_read_temp_reg(phydev);
if (temp < 0)
return temp;
@@@ -191,9 -169,6 +191,9 @@@ static int mv3310_hwmon_config(struct p
u16 val;
int ret;
+ if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310)
+ return 0;
+
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP,
MV_V2_TEMP_UNKNOWN);
if (ret < 0)
@@@ -753,7 -728,6 +753,6 @@@ static struct phy_driver mv3310_drivers
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "mv88x3310",
.get_features = mv3310_get_features,
- .soft_reset = genphy_no_soft_reset,
.config_init = mv3310_config_init,
.probe = mv3310_probe,
.suspend = mv3310_suspend,
@@@ -771,7 -745,6 +770,6 @@@
.probe = mv3310_probe,
.suspend = mv3310_suspend,
.resume = mv3310_resume,
- .soft_reset = genphy_no_soft_reset,
.config_init = mv3310_config_init,
.config_aneg = mv3310_config_aneg,
.aneg_done = mv3310_aneg_done,
diff --combined include/net/bluetooth/mgmt.h
index e104329e227f,65dd6fd1fff3..3303d4bc00cf
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@@ -70,14 -70,14 +70,14 @@@ struct mgmt_rp_read_version
struct mgmt_rp_read_commands {
__le16 num_commands;
__le16 num_events;
- __le16 opcodes[0];
+ __le16 opcodes[];
} __packed;
#define MGMT_OP_READ_INDEX_LIST 0x0003
#define MGMT_READ_INDEX_LIST_SIZE 0
struct mgmt_rp_read_index_list {
__le16 num_controllers;
- __le16 index[0];
+ __le16 index[];
} __packed;
/* Reserve one extra byte for names in management messages so that they
@@@ -183,7 -183,7 +183,7 @@@ struct mgmt_link_key_info
struct mgmt_cp_load_link_keys {
__u8 debug_keys;
__le16 key_count;
- struct mgmt_link_key_info keys[0];
+ struct mgmt_link_key_info keys[];
} __packed;
#define MGMT_LOAD_LINK_KEYS_SIZE 3
@@@ -206,7 -206,7 +206,7 @@@ struct mgmt_ltk_info
#define MGMT_OP_LOAD_LONG_TERM_KEYS 0x0013
struct mgmt_cp_load_long_term_keys {
__le16 key_count;
- struct mgmt_ltk_info keys[0];
+ struct mgmt_ltk_info keys[];
} __packed;
#define MGMT_LOAD_LONG_TERM_KEYS_SIZE 2
@@@ -223,7 -223,7 +223,7 @@@ struct mgmt_rp_disconnect
#define MGMT_GET_CONNECTIONS_SIZE 0
struct mgmt_rp_get_connections {
__le16 conn_count;
- struct mgmt_addr_info addr[0];
+ struct mgmt_addr_info addr[];
} __packed;
#define MGMT_OP_PIN_CODE_REPLY 0x0016
@@@ -413,7 -413,7 +413,7 @@@ struct mgmt_irk_info
#define MGMT_OP_LOAD_IRKS 0x0030
struct mgmt_cp_load_irks {
__le16 irk_count;
- struct mgmt_irk_info irks[0];
+ struct mgmt_irk_info irks[];
} __packed;
#define MGMT_LOAD_IRKS_SIZE 2
@@@ -465,7 -465,7 +465,7 @@@ struct mgmt_conn_param
#define MGMT_OP_LOAD_CONN_PARAM 0x0035
struct mgmt_cp_load_conn_param {
__le16 param_count;
- struct mgmt_conn_param params[0];
+ struct mgmt_conn_param params[];
} __packed;
#define MGMT_LOAD_CONN_PARAM_SIZE 2
@@@ -473,7 -473,7 +473,7 @@@
#define MGMT_READ_UNCONF_INDEX_LIST_SIZE 0
struct mgmt_rp_read_unconf_index_list {
__le16 num_controllers;
- __le16 index[0];
+ __le16 index[];
} __packed;
#define MGMT_OPTION_EXTERNAL_CONFIG 0x00000001
@@@ -504,7 -504,7 +504,7 @@@ struct mgmt_cp_start_service_discovery
__u8 type;
__s8 rssi;
__le16 uuid_count;
- __u8 uuids[0][16];
+ __u8 uuids[][16];
} __packed;
#define MGMT_START_SERVICE_DISCOVERY_SIZE 4
@@@ -516,7 -516,7 +516,7 @@@ struct mgmt_cp_read_local_oob_ext_data
struct mgmt_rp_read_local_oob_ext_data {
__u8 type;
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_OP_READ_EXT_INDEX_LIST 0x003C
@@@ -527,7 -527,7 +527,7 @@@ struct mgmt_rp_read_ext_index_list
__le16 index;
__u8 type;
__u8 bus;
- } entry[0];
+ } entry[];
} __packed;
#define MGMT_OP_READ_ADV_FEATURES 0x0003D
@@@ -538,7 -538,7 +538,7 @@@ struct mgmt_rp_read_adv_features
__u8 max_scan_rsp_len;
__u8 max_instances;
__u8 num_instances;
- __u8 instance[0];
+ __u8 instance[];
} __packed;
#define MGMT_OP_ADD_ADVERTISING 0x003E
@@@ -549,7 -549,7 +549,7 @@@ struct mgmt_cp_add_advertising
__le16 timeout;
__u8 adv_data_len;
__u8 scan_rsp_len;
- __u8 data[0];
+ __u8 data[];
} __packed;
#define MGMT_ADD_ADVERTISING_SIZE 11
struct mgmt_rp_add_advertising {
@@@ -603,7 -603,7 +603,7 @@@ struct mgmt_rp_read_ext_info
__le32 supported_settings;
__le32 current_settings;
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_OP_SET_APPEARANCE 0x0043
@@@ -668,17 -668,24 +668,24 @@@ struct mgmt_blocked_key_info
struct mgmt_cp_set_blocked_keys {
__le16 key_count;
- struct mgmt_blocked_key_info keys[0];
+ struct mgmt_blocked_key_info keys[];
} __packed;
#define MGMT_OP_SET_BLOCKED_KEYS_SIZE 2
#define MGMT_OP_SET_WIDEBAND_SPEECH 0x0047
+ #define MGMT_OP_READ_SECURITY_INFO 0x0048
+ #define MGMT_READ_SECURITY_INFO_SIZE 0
+ struct mgmt_rp_read_security_info {
+ __le16 sec_len;
+ __u8 sec[0];
+ } __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
__u8 status;
- __u8 data[0];
+ __u8 data[];
} __packed;
#define MGMT_EV_CMD_STATUS 0x0002
@@@ -726,7 -733,7 +733,7 @@@ struct mgmt_ev_device_connected
struct mgmt_addr_info addr;
__le32 flags;
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_DEV_DISCONN_UNKNOWN 0x00
@@@ -781,7 -788,7 +788,7 @@@ struct mgmt_ev_device_found
__s8 rssi;
__le32 flags;
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_EV_DISCOVERING 0x0013
@@@ -876,7 -883,7 +883,7 @@@ struct mgmt_ev_ext_index
struct mgmt_ev_local_oob_data_updated {
__u8 type;
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_EV_ADVERTISING_ADDED 0x0023
@@@ -892,7 -899,7 +899,7 @@@ struct mgmt_ev_advertising_removed
#define MGMT_EV_EXT_INFO_CHANGED 0x0025
struct mgmt_ev_ext_info_changed {
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_EV_PHY_CONFIGURATION_CHANGED 0x0026
diff --combined net/batman-adv/bat_v_ogm.c
index 80b87b1f4e3a,0959d32be65c..18028b9f95f0
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@@ -88,7 -88,7 +88,7 @@@ static void batadv_v_ogm_start_queue_ti
unsigned int msecs = BATADV_MAX_AGGREGATION_MS * 1000;
/* msecs * [0.9, 1.1] */
- msecs += prandom_u32() % (msecs / 5) - (msecs / 10);
+ msecs += prandom_u32_max(msecs / 5) - (msecs / 10);
queue_delayed_work(batadv_event_workqueue, &hard_iface->bat_v.aggr_wq,
msecs_to_jiffies(msecs / 1000));
}
@@@ -107,7 -107,7 +107,7 @@@ static void batadv_v_ogm_start_timer(st
return;
msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
- msecs += prandom_u32() % (2 * BATADV_JITTER);
+ msecs += prandom_u32_max(2 * BATADV_JITTER);
queue_delayed_work(batadv_event_workqueue, &bat_priv->bat_v.ogm_wq,
msecs_to_jiffies(msecs));
}
@@@ -893,7 -893,7 +893,7 @@@ static void batadv_v_ogm_process(const
orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig);
if (!orig_node)
- return;
+ goto out;
neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming,
ethhdr->h_source);
diff --combined net/mptcp/subflow.c
index 71256f03707f,87c094702d63..2488e011048c
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@@ -225,7 -225,7 +225,7 @@@ static void subflow_finish_connect(stru
subflow->icsk_af_ops->sk_rx_dst_set(sk, skb);
- if (inet_sk_state_load(parent) != TCP_ESTABLISHED) {
+ if (inet_sk_state_load(parent) == TCP_SYN_SENT) {
inet_sk_state_store(parent, TCP_ESTABLISHED);
parent->sk_state_change(parent);
}
@@@ -821,6 -821,24 +821,24 @@@ bool mptcp_subflow_data_available(struc
return subflow->data_avail;
}
+ /* If ssk has an mptcp parent socket, use the mptcp rcvbuf occupancy,
+ * not the ssk one.
+ *
+ * In mptcp, rwin is about the mptcp-level connection data.
+ *
+ * Data that is still on the ssk rx queue can thus be ignored,
+ * as far as mptcp peer is concerened that data is still inflight.
+ * DSS ACK is updated when skb is moved to the mptcp rx queue.
+ */
+ void mptcp_space(const struct sock *ssk, int *space, int *full_space)
+ {
+ const struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
+ const struct sock *sk = subflow->conn;
+
+ *space = tcp_space(sk);
+ *full_space = tcp_full_space(sk);
+ }
+
static void subflow_data_ready(struct sock *sk)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
diff --combined scripts/mod/modpost.c
index 4d4b979d76be,7f7d4ee7b652..5826c6483b85
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@@ -166,7 -166,7 +166,7 @@@ struct symbol
* (only for external modules) **/
unsigned int is_static:1; /* 1 if symbol is not global */
enum export export; /* Type of export */
- char name[0];
+ char name[];
};
static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
@@@ -2251,6 -2251,7 +2251,7 @@@ static void add_header(struct buffer *b
* Include build-salt.h after module.h in order to
* inherit the definitions.
*/
+ buf_printf(b, "#define INCLUDE_VERMAGIC\n");
buf_printf(b, "#include <linux/build-salt.h>\n");
buf_printf(b, "#include <linux/vermagic.h>\n");
buf_printf(b, "#include <linux/compiler.h>\n");
--
LinuxNextTracking