The following commit has been merged in the master branch: commit 9640277000475d56814ef11c46b2089dc4a6338d Merge: 3c2686aaa75edab453d941ad6e919d10d8874a76 2ac757e4152e3322a04a6dfb3d1fa010d3521abf Author: Stephen Rothwell sfr@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");
linux-merge@lists.open-mesh.org