Networking fixes for 5.14(-rc8?), including fixes from can and bpf.
Current release - regressions: - stmmac: revert "stmmac: align RX buffers" - usb: asix: ax88772: move embedded PHY detection as early as possible - usb: asix: do not call phy_disconnect() for ax88178 - Revert "net: really fix the build...", from Kalle to fix QCA6390 Current release - new code bugs: - phy: mediatek: add the missing suspend/resume callbacks Previous releases - regressions: - qrtr: fix another OOB Read in qrtr_endpoint_post - stmmac: dwmac-rk: fix unbalanced pm_runtime_enable warnings Previous releases - always broken: - inet: use siphash in exception handling - ip_gre: add validation for csum_start - bpf: fix ringbuf helper function compatibility - rtnetlink: return correct error on changing device netns - e1000e: do not try to recover the NVM checksum on Tiger Lake Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmEn4nAACgkQMUZtbf5S IrtNnBAAnF6dxSdVOMZe0pScj4YLp3Vwfxi3sFTQ/9iUf3hbwyEZTntUdJ9xQjBd V8f+V7gorvPCEszYxZKAgqwZdEuOhNZdPzmEveug9Ln8AdV84RT5Pvh0PpY2Tzop jloh58+3vnNYJKUlrCavwKcG5eF+g/hZdgDMzp5hqFAqY1W4liZAR+u3LKYHggy2 jAFk8/gRIzOHOAB0g4JuXwTUDhOxIKscUyJbvd8z/9X5MZLqnKvz8+tFIvU2ipJ+ 2P6Q7VmF57v8sDBII7tvpFqG1pR2X5JjgNasH3J1O1ttR268OlZkNwH/09vZe6Ih WZcebfcQWEOqv8HTFr992d9jHVHHnN8hlJkD1Co0yBJTsDbGfWhR3ngnKGvZ14is 5RNjHgmHEvmCnIKaZkBI2pPP6HQBmxFinP12wldVa/Na0bpqjZpDs8YFZ11H74ST DP4CXR6YKrIRWCiIxT2NDbupIZwGVzRtzNAfjbjTTkN7wgRbVtcR2xkPxV4fiEcO DJ1cE//1fpj9m9W+Ln4evRfDmbCEMsyJjozlTub4cKqCiE6ywTuSa4OZ21/nI4/k LS0CT/VF9uRU9QSElHNPuMDIIKMnJYJobdZzXh9wmniG+MQw46XC69QOfO631Ly2 BayvXf/5EvxLl0xY5Ub5K6PmECtZ/QLJCa+nxIWi/Btus9F6RfA= =ilTg -----END PGP SIGNATURE----- Merge tag 'net-5.14-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Networking fixes, including fixes from can and bpf. Closing three hw-dependent regressions. Any fixes of note are in the 'old code' category. Nothing blocking release from our perspective. Current release - regressions: - stmmac: revert "stmmac: align RX buffers" - usb: asix: ax88772: move embedded PHY detection as early as possible - usb: asix: do not call phy_disconnect() for ax88178 - Revert "net: really fix the build...", from Kalle to fix QCA6390 Current release - new code bugs: - phy: mediatek: add the missing suspend/resume callbacks Previous releases - regressions: - qrtr: fix another OOB Read in qrtr_endpoint_post - stmmac: dwmac-rk: fix unbalanced pm_runtime_enable warnings Previous releases - always broken: - inet: use siphash in exception handling - ip_gre: add validation for csum_start - bpf: fix ringbuf helper function compatibility - rtnetlink: return correct error on changing device netns - e1000e: do not try to recover the NVM checksum on Tiger Lake" * tag 'net-5.14-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (43 commits) Revert "net: really fix the build..." net: hns3: fix get wrong pfc_en when query PFC configuration net: hns3: fix GRO configuration error after reset net: hns3: change the method of getting cmd index in debugfs net: hns3: fix duplicate node in VLAN list net: hns3: fix speed unknown issue in bond 4 net: hns3: add waiting time before cmdq memory is released net: hns3: clear hardware resource when loading driver net: fix NULL pointer reference in cipso_v4_doi_free rtnetlink: Return correct error on changing device netns net: dsa: hellcreek: Adjust schedule look ahead window net: dsa: hellcreek: Fix incorrect setting of GCL cxgb4: dont touch blocked freelist bitmap after free ipv4: use siphash instead of Jenkins in fnhe_hashfun() ipv6: use siphash in rt6_exception_hash() can: usb: esd_usb2: esd_usb2_rx_event(): fix the interchange of the CAN RX and TX error counters net: usb: asix: ax88772: fix boolconv.cocci warnings net/sched: ets: fix crash when flipping from 'strict' to 'quantum' qede: Fix memset corruption net: stmmac: fix kernel panic due to NULL pointer dereference of buf->xdp ...
This commit is contained in:
commit
8a2cb8bd06
|
@ -682,7 +682,7 @@ void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
|
|||
struct image_info *img_info);
|
||||
void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl);
|
||||
int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_chan *mhi_chan, unsigned int flags);
|
||||
struct mhi_chan *mhi_chan);
|
||||
int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_chan *mhi_chan);
|
||||
void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl,
|
||||
|
|
|
@ -1430,7 +1430,7 @@ exit_unprepare_channel:
|
|||
}
|
||||
|
||||
int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_chan *mhi_chan, unsigned int flags)
|
||||
struct mhi_chan *mhi_chan)
|
||||
{
|
||||
int ret = 0;
|
||||
struct device *dev = &mhi_chan->mhi_dev->dev;
|
||||
|
@ -1455,9 +1455,6 @@ int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
|
|||
if (ret)
|
||||
goto error_pm_state;
|
||||
|
||||
if (mhi_chan->dir == DMA_FROM_DEVICE)
|
||||
mhi_chan->pre_alloc = !!(flags & MHI_CH_INBOUND_ALLOC_BUFS);
|
||||
|
||||
/* Pre-allocate buffer for xfer ring */
|
||||
if (mhi_chan->pre_alloc) {
|
||||
int nr_el = get_nr_avail_ring_elements(mhi_cntrl,
|
||||
|
@ -1613,7 +1610,7 @@ void mhi_reset_chan(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan)
|
|||
}
|
||||
|
||||
/* Move channel to start state */
|
||||
int mhi_prepare_for_transfer(struct mhi_device *mhi_dev, unsigned int flags)
|
||||
int mhi_prepare_for_transfer(struct mhi_device *mhi_dev)
|
||||
{
|
||||
int ret, dir;
|
||||
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
|
||||
|
@ -1624,7 +1621,7 @@ int mhi_prepare_for_transfer(struct mhi_device *mhi_dev, unsigned int flags)
|
|||
if (!mhi_chan)
|
||||
continue;
|
||||
|
||||
ret = mhi_prepare_channel(mhi_cntrl, mhi_chan, flags);
|
||||
ret = mhi_prepare_channel(mhi_cntrl, mhi_chan);
|
||||
if (ret)
|
||||
goto error_open_chan;
|
||||
}
|
||||
|
|
|
@ -224,8 +224,8 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
|
|||
if (id == ESD_EV_CAN_ERROR_EXT) {
|
||||
u8 state = msg->msg.rx.data[0];
|
||||
u8 ecc = msg->msg.rx.data[1];
|
||||
u8 txerr = msg->msg.rx.data[2];
|
||||
u8 rxerr = msg->msg.rx.data[3];
|
||||
u8 rxerr = msg->msg.rx.data[2];
|
||||
u8 txerr = msg->msg.rx.data[3];
|
||||
|
||||
skb = alloc_can_err_skb(priv->netdev, &cf);
|
||||
if (skb == NULL) {
|
||||
|
|
|
@ -1472,9 +1472,6 @@ static void hellcreek_setup_gcl(struct hellcreek *hellcreek, int port,
|
|||
u16 data;
|
||||
u8 gates;
|
||||
|
||||
cur++;
|
||||
next++;
|
||||
|
||||
if (i == schedule->num_entries)
|
||||
gates = initial->gate_mask ^
|
||||
cur->gate_mask;
|
||||
|
@ -1503,6 +1500,9 @@ static void hellcreek_setup_gcl(struct hellcreek *hellcreek, int port,
|
|||
(initial->gate_mask <<
|
||||
TR_GCLCMD_INIT_GATE_STATES_SHIFT);
|
||||
hellcreek_write(hellcreek, data, TR_GCLCMD);
|
||||
|
||||
cur++;
|
||||
next++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1550,7 +1550,7 @@ static bool hellcreek_schedule_startable(struct hellcreek *hellcreek, int port)
|
|||
/* Calculate difference to admin base time */
|
||||
base_time_ns = ktime_to_ns(hellcreek_port->current_schedule->base_time);
|
||||
|
||||
return base_time_ns - current_ns < (s64)8 * NSEC_PER_SEC;
|
||||
return base_time_ns - current_ns < (s64)4 * NSEC_PER_SEC;
|
||||
}
|
||||
|
||||
static void hellcreek_start_schedule(struct hellcreek *hellcreek, int port)
|
||||
|
|
|
@ -1277,15 +1277,16 @@ static int mv88e6393x_serdes_port_errata(struct mv88e6xxx_chip *chip, int lane)
|
|||
int err;
|
||||
|
||||
/* mv88e6393x family errata 4.6:
|
||||
* Cannot clear PwrDn bit on SERDES on port 0 if device is configured
|
||||
* CPU_MGD mode or P0_mode is configured for [x]MII.
|
||||
* Workaround: Set Port0 SERDES register 4.F002 bit 5=0 and bit 15=1.
|
||||
* Cannot clear PwrDn bit on SERDES if device is configured CPU_MGD
|
||||
* mode or P0_mode is configured for [x]MII.
|
||||
* Workaround: Set SERDES register 4.F002 bit 5=0 and bit 15=1.
|
||||
*
|
||||
* It seems that after this workaround the SERDES is automatically
|
||||
* powered up (the bit is cleared), so power it down.
|
||||
*/
|
||||
if (lane == MV88E6393X_PORT0_LANE) {
|
||||
err = mv88e6390_serdes_read(chip, MV88E6393X_PORT0_LANE,
|
||||
if (lane == MV88E6393X_PORT0_LANE || lane == MV88E6393X_PORT9_LANE ||
|
||||
lane == MV88E6393X_PORT10_LANE) {
|
||||
err = mv88e6390_serdes_read(chip, lane,
|
||||
MDIO_MMD_PHYXS,
|
||||
MV88E6393X_SERDES_POC, ®);
|
||||
if (err)
|
||||
|
|
|
@ -677,11 +677,13 @@ static int xge_probe(struct platform_device *pdev)
|
|||
ret = register_netdev(ndev);
|
||||
if (ret) {
|
||||
netdev_err(ndev, "Failed to register netdev\n");
|
||||
goto err;
|
||||
goto err_mdio_remove;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_mdio_remove:
|
||||
xge_mdio_remove(ndev);
|
||||
err:
|
||||
free_netdev(ndev);
|
||||
|
||||
|
|
|
@ -275,6 +275,12 @@ void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb,
|
|||
|
||||
if (GEM_BFEXT(DMA_RXVALID, desc->addr)) {
|
||||
desc_ptp = macb_ptp_desc(bp, desc);
|
||||
/* Unlikely but check */
|
||||
if (!desc_ptp) {
|
||||
dev_warn_ratelimited(&bp->pdev->dev,
|
||||
"Timestamp not supported in BD\n");
|
||||
return;
|
||||
}
|
||||
gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts);
|
||||
memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
|
||||
shhwtstamps->hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
|
||||
|
@ -307,8 +313,11 @@ int gem_ptp_txstamp(struct macb_queue *queue, struct sk_buff *skb,
|
|||
if (CIRC_SPACE(head, tail, PTP_TS_BUFFER_SIZE) == 0)
|
||||
return -ENOMEM;
|
||||
|
||||
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
|
||||
desc_ptp = macb_ptp_desc(queue->bp, desc);
|
||||
/* Unlikely but check */
|
||||
if (!desc_ptp)
|
||||
return -EINVAL;
|
||||
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
|
||||
tx_timestamp = &queue->tx_timestamps[head];
|
||||
tx_timestamp->skb = skb;
|
||||
/* ensure ts_1/ts_2 is loaded after ctrl (TX_USED check) */
|
||||
|
|
|
@ -5068,6 +5068,7 @@ static int adap_init0(struct adapter *adap, int vpd_skip)
|
|||
ret = -ENOMEM;
|
||||
goto bye;
|
||||
}
|
||||
bitmap_zero(adap->sge.blocked_fl, adap->sge.egr_sz);
|
||||
#endif
|
||||
|
||||
params[0] = FW_PARAM_PFVF(CLIP_START);
|
||||
|
@ -6788,13 +6789,11 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
setup_memwin(adapter);
|
||||
err = adap_init0(adapter, 0);
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
bitmap_zero(adapter->sge.blocked_fl, adapter->sge.egr_sz);
|
||||
#endif
|
||||
setup_memwin_rdma(adapter);
|
||||
if (err)
|
||||
goto out_unmap_bar;
|
||||
|
||||
setup_memwin_rdma(adapter);
|
||||
|
||||
/* configure SGE_STAT_CFG_A to read WC stats */
|
||||
if (!is_t4(adapter->params.chip))
|
||||
t4_write_reg(adapter, SGE_STAT_CFG_A, STATSOURCE_T5_V(7) |
|
||||
|
|
|
@ -938,20 +938,19 @@ static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hns3_dbg_get_cmd_index(struct hnae3_handle *handle,
|
||||
const unsigned char *name, u32 *index)
|
||||
static int hns3_dbg_get_cmd_index(struct hns3_dbg_data *dbg_data, u32 *index)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
|
||||
if (!strncmp(name, hns3_dbg_cmd[i].name,
|
||||
strlen(hns3_dbg_cmd[i].name))) {
|
||||
if (hns3_dbg_cmd[i].cmd == dbg_data->cmd) {
|
||||
*index = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
dev_err(&handle->pdev->dev, "unknown command(%s)\n", name);
|
||||
dev_err(&dbg_data->handle->pdev->dev, "unknown command(%d)\n",
|
||||
dbg_data->cmd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1019,8 +1018,7 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
|
|||
u32 index;
|
||||
int ret;
|
||||
|
||||
ret = hns3_dbg_get_cmd_index(handle, filp->f_path.dentry->d_iname,
|
||||
&index);
|
||||
ret = hns3_dbg_get_cmd_index(dbg_data, &index);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1090,6 +1088,7 @@ static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd)
|
|||
char name[HNS3_DBG_FILE_NAME_LEN];
|
||||
|
||||
data[i].handle = handle;
|
||||
data[i].cmd = hns3_dbg_cmd[cmd].cmd;
|
||||
data[i].qid = i;
|
||||
sprintf(name, "%s%u", hns3_dbg_cmd[cmd].name, i);
|
||||
debugfs_create_file(name, 0400, entry_dir, &data[i],
|
||||
|
@ -1110,6 +1109,7 @@ hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd)
|
|||
return -ENOMEM;
|
||||
|
||||
data->handle = handle;
|
||||
data->cmd = hns3_dbg_cmd[cmd].cmd;
|
||||
entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;
|
||||
debugfs_create_file(hns3_dbg_cmd[cmd].name, 0400, entry_dir,
|
||||
data, &hns3_dbg_fops);
|
||||
|
|
|
@ -22,6 +22,7 @@ struct hns3_dbg_item {
|
|||
|
||||
struct hns3_dbg_data {
|
||||
struct hnae3_handle *handle;
|
||||
enum hnae3_dbg_cmd cmd;
|
||||
u16 qid;
|
||||
};
|
||||
|
||||
|
|
|
@ -573,9 +573,13 @@ static void hclge_cmd_uninit_regs(struct hclge_hw *hw)
|
|||
|
||||
void hclge_cmd_uninit(struct hclge_dev *hdev)
|
||||
{
|
||||
set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state);
|
||||
/* wait to ensure that the firmware completes the possible left
|
||||
* over commands.
|
||||
*/
|
||||
msleep(HCLGE_CMDQ_CLEAR_WAIT_TIME);
|
||||
spin_lock_bh(&hdev->hw.cmq.csq.lock);
|
||||
spin_lock(&hdev->hw.cmq.crq.lock);
|
||||
set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state);
|
||||
hclge_cmd_uninit_regs(&hdev->hw);
|
||||
spin_unlock(&hdev->hw.cmq.crq.lock);
|
||||
spin_unlock_bh(&hdev->hw.cmq.csq.lock);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "hnae3.h"
|
||||
|
||||
#define HCLGE_CMDQ_TX_TIMEOUT 30000
|
||||
#define HCLGE_CMDQ_CLEAR_WAIT_TIME 200
|
||||
#define HCLGE_DESC_DATA_LEN 6
|
||||
|
||||
struct hclge_dev;
|
||||
|
@ -270,6 +271,9 @@ enum hclge_opcode_type {
|
|||
/* Led command */
|
||||
HCLGE_OPC_LED_STATUS_CFG = 0xB000,
|
||||
|
||||
/* clear hardware resource command */
|
||||
HCLGE_OPC_CLEAR_HW_RESOURCE = 0x700B,
|
||||
|
||||
/* NCL config command */
|
||||
HCLGE_OPC_QUERY_NCL_CONFIG = 0x7011,
|
||||
|
||||
|
|
|
@ -255,21 +255,12 @@ static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
|
|||
u64 requests[HNAE3_MAX_TC], indications[HNAE3_MAX_TC];
|
||||
struct hclge_vport *vport = hclge_get_vport(h);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
u8 i, j, pfc_map, *prio_tc;
|
||||
int ret;
|
||||
u8 i;
|
||||
|
||||
memset(pfc, 0, sizeof(*pfc));
|
||||
pfc->pfc_cap = hdev->pfc_max;
|
||||
prio_tc = hdev->tm_info.prio_tc;
|
||||
pfc_map = hdev->tm_info.hw_pfc_map;
|
||||
|
||||
/* Pfc setting is based on TC */
|
||||
for (i = 0; i < hdev->tm_info.num_tc; i++) {
|
||||
for (j = 0; j < HNAE3_MAX_USER_PRIO; j++) {
|
||||
if ((prio_tc[j] == i) && (pfc_map & BIT(i)))
|
||||
pfc->pfc_en |= BIT(j);
|
||||
}
|
||||
}
|
||||
pfc->pfc_en = hdev->tm_info.pfc_en;
|
||||
|
||||
ret = hclge_pfc_tx_stats_get(hdev, requests);
|
||||
if (ret)
|
||||
|
|
|
@ -1550,6 +1550,7 @@ static int hclge_configure(struct hclge_dev *hdev)
|
|||
hdev->tm_info.hw_pfc_map = 0;
|
||||
hdev->wanted_umv_size = cfg.umv_space;
|
||||
hdev->tx_spare_buf_size = cfg.tx_spare_buf_size;
|
||||
hdev->gro_en = true;
|
||||
if (cfg.vlan_fliter_cap == HCLGE_VLAN_FLTR_CAN_MDF)
|
||||
set_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps);
|
||||
|
||||
|
@ -1618,7 +1619,7 @@ static int hclge_config_tso(struct hclge_dev *hdev, u16 tso_mss_min,
|
|||
return hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
}
|
||||
|
||||
static int hclge_config_gro(struct hclge_dev *hdev, bool en)
|
||||
static int hclge_config_gro(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hclge_cfg_gro_status_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
|
@ -1630,7 +1631,7 @@ static int hclge_config_gro(struct hclge_dev *hdev, bool en)
|
|||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_GRO_GENERIC_CONFIG, false);
|
||||
req = (struct hclge_cfg_gro_status_cmd *)desc.data;
|
||||
|
||||
req->gro_en = en ? 1 : 0;
|
||||
req->gro_en = hdev->gro_en ? 1 : 0;
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret)
|
||||
|
@ -2952,12 +2953,12 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
|
|||
}
|
||||
|
||||
if (state != hdev->hw.mac.link) {
|
||||
hdev->hw.mac.link = state;
|
||||
client->ops->link_status_change(handle, state);
|
||||
hclge_config_mac_tnl_int(hdev, state);
|
||||
if (rclient && rclient->ops->link_status_change)
|
||||
rclient->ops->link_status_change(rhandle, state);
|
||||
|
||||
hdev->hw.mac.link = state;
|
||||
hclge_push_link_status(hdev);
|
||||
}
|
||||
|
||||
|
@ -10073,7 +10074,11 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
|
|||
static void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
|
||||
bool writen_to_tbl)
|
||||
{
|
||||
struct hclge_vport_vlan_cfg *vlan;
|
||||
struct hclge_vport_vlan_cfg *vlan, *tmp;
|
||||
|
||||
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node)
|
||||
if (vlan->vlan_id == vlan_id)
|
||||
return;
|
||||
|
||||
vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
|
||||
if (!vlan)
|
||||
|
@ -11443,6 +11448,28 @@ static void hclge_clear_resetting_state(struct hclge_dev *hdev)
|
|||
}
|
||||
}
|
||||
|
||||
static int hclge_clear_hw_resource(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hclge_desc desc;
|
||||
int ret;
|
||||
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CLEAR_HW_RESOURCE, false);
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
/* This new command is only supported by new firmware, it will
|
||||
* fail with older firmware. Error value -EOPNOSUPP can only be
|
||||
* returned by older firmware running this command, to keep code
|
||||
* backward compatible we will override this value and return
|
||||
* success.
|
||||
*/
|
||||
if (ret && ret != -EOPNOTSUPP) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed to clear hw resource, ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hclge_init_rxd_adv_layout(struct hclge_dev *hdev)
|
||||
{
|
||||
if (hnae3_ae_dev_rxd_adv_layout_supported(hdev->ae_dev))
|
||||
|
@ -11492,6 +11519,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
|
|||
if (ret)
|
||||
goto err_cmd_uninit;
|
||||
|
||||
ret = hclge_clear_hw_resource(hdev);
|
||||
if (ret)
|
||||
goto err_cmd_uninit;
|
||||
|
||||
ret = hclge_get_cap(hdev);
|
||||
if (ret)
|
||||
goto err_cmd_uninit;
|
||||
|
@ -11556,7 +11587,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
|
|||
goto err_mdiobus_unreg;
|
||||
}
|
||||
|
||||
ret = hclge_config_gro(hdev, true);
|
||||
ret = hclge_config_gro(hdev);
|
||||
if (ret)
|
||||
goto err_mdiobus_unreg;
|
||||
|
||||
|
@ -11937,7 +11968,7 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = hclge_config_gro(hdev, true);
|
||||
ret = hclge_config_gro(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -12671,8 +12702,15 @@ static int hclge_gro_en(struct hnae3_handle *handle, bool enable)
|
|||
{
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
bool gro_en_old = hdev->gro_en;
|
||||
int ret;
|
||||
|
||||
return hclge_config_gro(hdev, enable);
|
||||
hdev->gro_en = enable;
|
||||
ret = hclge_config_gro(hdev);
|
||||
if (ret)
|
||||
hdev->gro_en = gro_en_old;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
|
||||
|
|
|
@ -927,6 +927,7 @@ struct hclge_dev {
|
|||
unsigned long fd_bmap[BITS_TO_LONGS(MAX_FD_FILTER_NUM)];
|
||||
enum HCLGE_FD_ACTIVE_RULE_TYPE fd_active_type;
|
||||
u8 fd_en;
|
||||
bool gro_en;
|
||||
|
||||
u16 wanted_umv_size;
|
||||
/* max available unicast mac vlan space */
|
||||
|
|
|
@ -507,12 +507,17 @@ static void hclgevf_cmd_uninit_regs(struct hclgevf_hw *hw)
|
|||
|
||||
void hclgevf_cmd_uninit(struct hclgevf_dev *hdev)
|
||||
{
|
||||
set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
|
||||
/* wait to ensure that the firmware completes the possible left
|
||||
* over commands.
|
||||
*/
|
||||
msleep(HCLGEVF_CMDQ_CLEAR_WAIT_TIME);
|
||||
spin_lock_bh(&hdev->hw.cmq.csq.lock);
|
||||
spin_lock(&hdev->hw.cmq.crq.lock);
|
||||
set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
|
||||
hclgevf_cmd_uninit_regs(&hdev->hw);
|
||||
spin_unlock(&hdev->hw.cmq.crq.lock);
|
||||
spin_unlock_bh(&hdev->hw.cmq.csq.lock);
|
||||
|
||||
hclgevf_free_cmd_desc(&hdev->hw.cmq.csq);
|
||||
hclgevf_free_cmd_desc(&hdev->hw.cmq.crq);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "hnae3.h"
|
||||
|
||||
#define HCLGEVF_CMDQ_TX_TIMEOUT 30000
|
||||
#define HCLGEVF_CMDQ_CLEAR_WAIT_TIME 200
|
||||
#define HCLGEVF_CMDQ_RX_INVLD_B 0
|
||||
#define HCLGEVF_CMDQ_RX_OUTVLD_B 1
|
||||
|
||||
|
|
|
@ -506,10 +506,10 @@ void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state)
|
|||
link_state =
|
||||
test_bit(HCLGEVF_STATE_DOWN, &hdev->state) ? 0 : link_state;
|
||||
if (link_state != hdev->hw.mac.link) {
|
||||
hdev->hw.mac.link = link_state;
|
||||
client->ops->link_status_change(handle, !!link_state);
|
||||
if (rclient && rclient->ops->link_status_change)
|
||||
rclient->ops->link_status_change(rhandle, !!link_state);
|
||||
hdev->hw.mac.link = link_state;
|
||||
}
|
||||
|
||||
clear_bit(HCLGEVF_STATE_LINK_UPDATING, &hdev->state);
|
||||
|
@ -2487,6 +2487,8 @@ static int hclgevf_configure(struct hclgevf_dev *hdev)
|
|||
{
|
||||
int ret;
|
||||
|
||||
hdev->gro_en = true;
|
||||
|
||||
ret = hclgevf_get_basic_info(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -2549,7 +2551,7 @@ static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hclgevf_config_gro(struct hclgevf_dev *hdev, bool en)
|
||||
static int hclgevf_config_gro(struct hclgevf_dev *hdev)
|
||||
{
|
||||
struct hclgevf_cfg_gro_status_cmd *req;
|
||||
struct hclgevf_desc desc;
|
||||
|
@ -2562,7 +2564,7 @@ static int hclgevf_config_gro(struct hclgevf_dev *hdev, bool en)
|
|||
false);
|
||||
req = (struct hclgevf_cfg_gro_status_cmd *)desc.data;
|
||||
|
||||
req->gro_en = en ? 1 : 0;
|
||||
req->gro_en = hdev->gro_en ? 1 : 0;
|
||||
|
||||
ret = hclgevf_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret)
|
||||
|
@ -3308,7 +3310,7 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = hclgevf_config_gro(hdev, true);
|
||||
ret = hclgevf_config_gro(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -3389,7 +3391,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
|
|||
if (ret)
|
||||
goto err_config;
|
||||
|
||||
ret = hclgevf_config_gro(hdev, true);
|
||||
ret = hclgevf_config_gro(hdev);
|
||||
if (ret)
|
||||
goto err_config;
|
||||
|
||||
|
@ -3638,8 +3640,15 @@ void hclgevf_update_speed_duplex(struct hclgevf_dev *hdev, u32 speed,
|
|||
static int hclgevf_gro_en(struct hnae3_handle *handle, bool enable)
|
||||
{
|
||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
||||
bool gro_en_old = hdev->gro_en;
|
||||
int ret;
|
||||
|
||||
return hclgevf_config_gro(hdev, enable);
|
||||
hdev->gro_en = enable;
|
||||
ret = hclgevf_config_gro(hdev);
|
||||
if (ret)
|
||||
hdev->gro_en = gro_en_old;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hclgevf_get_media_type(struct hnae3_handle *handle, u8 *media_type,
|
||||
|
|
|
@ -310,6 +310,8 @@ struct hclgevf_dev {
|
|||
u16 *vector_status;
|
||||
int *vector_irq;
|
||||
|
||||
bool gro_en;
|
||||
|
||||
unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)];
|
||||
|
||||
struct hclgevf_mac_table_cfg mac_table;
|
||||
|
|
|
@ -323,8 +323,8 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
|
|||
flag = (u8)msg_q[5];
|
||||
|
||||
/* update upper layer with new link link status */
|
||||
hclgevf_update_link_status(hdev, link_status);
|
||||
hclgevf_update_speed_duplex(hdev, speed, duplex);
|
||||
hclgevf_update_link_status(hdev, link_status);
|
||||
|
||||
if (flag & HCLGE_MBX_PUSH_LINK_STATUS_EN)
|
||||
set_bit(HCLGEVF_STATE_PF_PUSH_LINK_STATUS,
|
||||
|
|
|
@ -1006,6 +1006,8 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link)
|
|||
{
|
||||
u32 reg = link << (E1000_LTRV_REQ_SHIFT + E1000_LTRV_NOSNOOP_SHIFT) |
|
||||
link << E1000_LTRV_REQ_SHIFT | E1000_LTRV_SEND;
|
||||
u16 max_ltr_enc_d = 0; /* maximum LTR decoded by platform */
|
||||
u16 lat_enc_d = 0; /* latency decoded */
|
||||
u16 lat_enc = 0; /* latency encoded */
|
||||
|
||||
if (link) {
|
||||
|
@ -1059,7 +1061,17 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link)
|
|||
E1000_PCI_LTR_CAP_LPT + 2, &max_nosnoop);
|
||||
max_ltr_enc = max_t(u16, max_snoop, max_nosnoop);
|
||||
|
||||
if (lat_enc > max_ltr_enc)
|
||||
lat_enc_d = (lat_enc & E1000_LTRV_VALUE_MASK) *
|
||||
(1U << (E1000_LTRV_SCALE_FACTOR *
|
||||
((lat_enc & E1000_LTRV_SCALE_MASK)
|
||||
>> E1000_LTRV_SCALE_SHIFT)));
|
||||
|
||||
max_ltr_enc_d = (max_ltr_enc & E1000_LTRV_VALUE_MASK) *
|
||||
(1U << (E1000_LTRV_SCALE_FACTOR *
|
||||
((max_ltr_enc & E1000_LTRV_SCALE_MASK)
|
||||
>> E1000_LTRV_SCALE_SHIFT)));
|
||||
|
||||
if (lat_enc_d > max_ltr_enc_d)
|
||||
lat_enc = max_ltr_enc;
|
||||
}
|
||||
|
||||
|
@ -4115,13 +4127,17 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
|
|||
return ret_val;
|
||||
|
||||
if (!(data & valid_csum_mask)) {
|
||||
data |= valid_csum_mask;
|
||||
ret_val = e1000_write_nvm(hw, word, 1, &data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
ret_val = e1000e_update_nvm_checksum(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
e_dbg("NVM Checksum Invalid\n");
|
||||
|
||||
if (hw->mac.type < e1000_pch_cnp) {
|
||||
data |= valid_csum_mask;
|
||||
ret_val = e1000_write_nvm(hw, word, 1, &data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
ret_val = e1000e_update_nvm_checksum(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
return e1000e_validate_nvm_checksum_generic(hw);
|
||||
|
|
|
@ -274,8 +274,11 @@
|
|||
|
||||
/* Latency Tolerance Reporting */
|
||||
#define E1000_LTRV 0x000F8
|
||||
#define E1000_LTRV_VALUE_MASK 0x000003FF
|
||||
#define E1000_LTRV_SCALE_MAX 5
|
||||
#define E1000_LTRV_SCALE_FACTOR 5
|
||||
#define E1000_LTRV_SCALE_SHIFT 10
|
||||
#define E1000_LTRV_SCALE_MASK 0x00001C00
|
||||
#define E1000_LTRV_REQ_SHIFT 15
|
||||
#define E1000_LTRV_NOSNOOP_SHIFT 16
|
||||
#define E1000_LTRV_SEND (1 << 30)
|
||||
|
|
|
@ -42,7 +42,9 @@ static int ice_info_pba(struct ice_pf *pf, struct ice_info_ctx *ctx)
|
|||
|
||||
status = ice_read_pba_string(hw, (u8 *)ctx->buf, sizeof(ctx->buf));
|
||||
if (status)
|
||||
return -EIO;
|
||||
/* We failed to locate the PBA, so just skip this entry */
|
||||
dev_dbg(ice_pf_to_dev(pf), "Failed to read Product Board Assembly string, status %s\n",
|
||||
ice_stat_str(status));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -149,6 +149,9 @@ static void igc_release_hw_control(struct igc_adapter *adapter)
|
|||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 ctrl_ext;
|
||||
|
||||
if (!pci_device_is_present(adapter->pdev))
|
||||
return;
|
||||
|
||||
/* Let firmware take over control of h/w */
|
||||
ctrl_ext = rd32(IGC_CTRL_EXT);
|
||||
wr32(IGC_CTRL_EXT,
|
||||
|
@ -4449,26 +4452,29 @@ void igc_down(struct igc_adapter *adapter)
|
|||
|
||||
igc_ptp_suspend(adapter);
|
||||
|
||||
/* disable receives in the hardware */
|
||||
rctl = rd32(IGC_RCTL);
|
||||
wr32(IGC_RCTL, rctl & ~IGC_RCTL_EN);
|
||||
/* flush and sleep below */
|
||||
|
||||
if (pci_device_is_present(adapter->pdev)) {
|
||||
/* disable receives in the hardware */
|
||||
rctl = rd32(IGC_RCTL);
|
||||
wr32(IGC_RCTL, rctl & ~IGC_RCTL_EN);
|
||||
/* flush and sleep below */
|
||||
}
|
||||
/* set trans_start so we don't get spurious watchdogs during reset */
|
||||
netif_trans_update(netdev);
|
||||
|
||||
netif_carrier_off(netdev);
|
||||
netif_tx_stop_all_queues(netdev);
|
||||
|
||||
/* disable transmits in the hardware */
|
||||
tctl = rd32(IGC_TCTL);
|
||||
tctl &= ~IGC_TCTL_EN;
|
||||
wr32(IGC_TCTL, tctl);
|
||||
/* flush both disables and wait for them to finish */
|
||||
wrfl();
|
||||
usleep_range(10000, 20000);
|
||||
if (pci_device_is_present(adapter->pdev)) {
|
||||
/* disable transmits in the hardware */
|
||||
tctl = rd32(IGC_TCTL);
|
||||
tctl &= ~IGC_TCTL_EN;
|
||||
wr32(IGC_TCTL, tctl);
|
||||
/* flush both disables and wait for them to finish */
|
||||
wrfl();
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
igc_irq_disable(adapter);
|
||||
igc_irq_disable(adapter);
|
||||
}
|
||||
|
||||
adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE;
|
||||
|
||||
|
@ -5489,7 +5495,7 @@ static bool validate_schedule(struct igc_adapter *adapter,
|
|||
if (e->command != TC_TAPRIO_CMD_SET_GATES)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < IGC_MAX_TX_QUEUES; i++) {
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
if (e->gate_mask & BIT(i))
|
||||
queue_uses[i]++;
|
||||
|
||||
|
@ -5546,7 +5552,7 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
|
|||
|
||||
end_time += e->interval;
|
||||
|
||||
for (i = 0; i < IGC_MAX_TX_QUEUES; i++) {
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
struct igc_ring *ring = adapter->tx_ring[i];
|
||||
|
||||
if (!(e->gate_mask & BIT(i)))
|
||||
|
|
|
@ -849,7 +849,8 @@ void igc_ptp_suspend(struct igc_adapter *adapter)
|
|||
adapter->ptp_tx_skb = NULL;
|
||||
clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
|
||||
|
||||
igc_ptp_time_save(adapter);
|
||||
if (pci_device_is_present(adapter->pdev))
|
||||
igc_ptp_time_save(adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
#define MVNETA_VLAN_PRIO_TO_RXQ 0x2440
|
||||
#define MVNETA_VLAN_PRIO_RXQ_MAP(prio, rxq) ((rxq) << ((prio) * 3))
|
||||
#define MVNETA_PORT_STATUS 0x2444
|
||||
#define MVNETA_TX_IN_PRGRS BIT(1)
|
||||
#define MVNETA_TX_IN_PRGRS BIT(0)
|
||||
#define MVNETA_TX_FIFO_EMPTY BIT(8)
|
||||
#define MVNETA_RX_MIN_FRAME_SIZE 0x247c
|
||||
/* Only exists on Armada XP and Armada 370 */
|
||||
|
|
|
@ -616,7 +616,12 @@ static int qed_enable_msix(struct qed_dev *cdev,
|
|||
rc = cnt;
|
||||
}
|
||||
|
||||
if (rc > 0) {
|
||||
/* For VFs, we should return with an error in case we didn't get the
|
||||
* exact number of msix vectors as we requested.
|
||||
* Not doing that will lead to a crash when starting queues for
|
||||
* this VF.
|
||||
*/
|
||||
if ((IS_PF(cdev) && rc > 0) || (IS_VF(cdev) && rc == cnt)) {
|
||||
/* MSI-x configuration was achieved */
|
||||
int_params->out.int_mode = QED_INT_MODE_MSIX;
|
||||
int_params->out.num_vectors = rc;
|
||||
|
|
|
@ -1874,6 +1874,7 @@ static void qede_sync_free_irqs(struct qede_dev *edev)
|
|||
}
|
||||
|
||||
edev->int_info.used_cnt = 0;
|
||||
edev->int_info.msix_cnt = 0;
|
||||
}
|
||||
|
||||
static int qede_req_msix_irqs(struct qede_dev *edev)
|
||||
|
@ -2427,7 +2428,6 @@ static int qede_load(struct qede_dev *edev, enum qede_load_mode mode,
|
|||
goto out;
|
||||
err4:
|
||||
qede_sync_free_irqs(edev);
|
||||
memset(&edev->int_info.msix_cnt, 0, sizeof(struct qed_int_info));
|
||||
err3:
|
||||
qede_napi_disable_remove(edev);
|
||||
err2:
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include "stmmac_platform.h"
|
||||
|
||||
|
@ -1529,9 +1528,6 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
if (bsp_priv->integrated_phy)
|
||||
rk_gmac_integrated_phy_powerup(bsp_priv);
|
||||
|
||||
|
@ -1540,14 +1536,9 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
|
|||
|
||||
static void rk_gmac_powerdown(struct rk_priv_data *gmac)
|
||||
{
|
||||
struct device *dev = &gmac->pdev->dev;
|
||||
|
||||
if (gmac->integrated_phy)
|
||||
rk_gmac_integrated_phy_powerdown(gmac);
|
||||
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
phy_power_on(gmac, false);
|
||||
gmac_clk_enable(gmac, false);
|
||||
}
|
||||
|
|
|
@ -339,9 +339,9 @@ static inline bool stmmac_xdp_is_enabled(struct stmmac_priv *priv)
|
|||
static inline unsigned int stmmac_rx_offset(struct stmmac_priv *priv)
|
||||
{
|
||||
if (stmmac_xdp_is_enabled(priv))
|
||||
return XDP_PACKET_HEADROOM + NET_IP_ALIGN;
|
||||
return XDP_PACKET_HEADROOM;
|
||||
|
||||
return NET_SKB_PAD + NET_IP_ALIGN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stmmac_disable_rx_queue(struct stmmac_priv *priv, u32 queue);
|
||||
|
|
|
@ -4914,6 +4914,10 @@ read_again:
|
|||
|
||||
prefetch(np);
|
||||
|
||||
/* Ensure a valid XSK buffer before proceed */
|
||||
if (!buf->xdp)
|
||||
break;
|
||||
|
||||
if (priv->extend_desc)
|
||||
stmmac_rx_extended_status(priv, &priv->dev->stats,
|
||||
&priv->xstats,
|
||||
|
@ -4934,10 +4938,6 @@ read_again:
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Ensure a valid XSK buffer before proceed */
|
||||
if (!buf->xdp)
|
||||
break;
|
||||
|
||||
/* XSK pool expects RX frame 1:1 mapped to XSK buffer */
|
||||
if (likely(status & rx_not_ls)) {
|
||||
xsk_buff_free(buf->xdp);
|
||||
|
|
|
@ -884,11 +884,13 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
|
|||
return 0;
|
||||
|
||||
disable:
|
||||
mutex_lock(&priv->plat->est->lock);
|
||||
priv->plat->est->enable = false;
|
||||
stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
|
||||
priv->plat->clk_ptp_rate);
|
||||
mutex_unlock(&priv->plat->est->lock);
|
||||
if (priv->plat->est) {
|
||||
mutex_lock(&priv->plat->est->lock);
|
||||
priv->plat->est->enable = false;
|
||||
stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
|
||||
priv->plat->clk_ptp_rate);
|
||||
mutex_unlock(&priv->plat->est->lock);
|
||||
}
|
||||
|
||||
priv->plat->fpe_cfg->enable = false;
|
||||
stmmac_fpe_configure(priv, priv->ioaddr,
|
||||
|
|
|
@ -34,18 +34,18 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv,
|
|||
need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
|
||||
|
||||
if (need_update) {
|
||||
stmmac_disable_rx_queue(priv, queue);
|
||||
stmmac_disable_tx_queue(priv, queue);
|
||||
napi_disable(&ch->rx_napi);
|
||||
napi_disable(&ch->tx_napi);
|
||||
stmmac_disable_rx_queue(priv, queue);
|
||||
stmmac_disable_tx_queue(priv, queue);
|
||||
}
|
||||
|
||||
set_bit(queue, priv->af_xdp_zc_qps);
|
||||
|
||||
if (need_update) {
|
||||
napi_enable(&ch->rxtx_napi);
|
||||
stmmac_enable_rx_queue(priv, queue);
|
||||
stmmac_enable_tx_queue(priv, queue);
|
||||
napi_enable(&ch->rxtx_napi);
|
||||
|
||||
err = stmmac_xsk_wakeup(priv->dev, queue, XDP_WAKEUP_RX);
|
||||
if (err)
|
||||
|
@ -72,10 +72,10 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
|
|||
need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
|
||||
|
||||
if (need_update) {
|
||||
napi_disable(&ch->rxtx_napi);
|
||||
stmmac_disable_rx_queue(priv, queue);
|
||||
stmmac_disable_tx_queue(priv, queue);
|
||||
synchronize_rcu();
|
||||
napi_disable(&ch->rxtx_napi);
|
||||
}
|
||||
|
||||
xsk_pool_dma_unmap(pool, STMMAC_RX_DMA_ATTR);
|
||||
|
@ -83,10 +83,10 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
|
|||
clear_bit(queue, priv->af_xdp_zc_qps);
|
||||
|
||||
if (need_update) {
|
||||
napi_enable(&ch->rx_napi);
|
||||
napi_enable(&ch->tx_napi);
|
||||
stmmac_enable_rx_queue(priv, queue);
|
||||
stmmac_enable_tx_queue(priv, queue);
|
||||
napi_enable(&ch->rx_napi);
|
||||
napi_enable(&ch->tx_napi);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -335,7 +335,7 @@ static int mhi_net_newlink(void *ctxt, struct net_device *ndev, u32 if_id,
|
|||
u64_stats_init(&mhi_netdev->stats.tx_syncp);
|
||||
|
||||
/* Start MHI channels */
|
||||
err = mhi_prepare_for_transfer(mhi_dev, 0);
|
||||
err = mhi_prepare_for_transfer(mhi_dev);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ static struct phy_driver mtk_gephy_driver[] = {
|
|||
*/
|
||||
.config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.read_page = mtk_gephy_read_page,
|
||||
.write_page = mtk_gephy_write_page,
|
||||
},
|
||||
|
@ -93,6 +95,8 @@ static struct phy_driver mtk_gephy_driver[] = {
|
|||
*/
|
||||
.config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.read_page = mtk_gephy_read_page,
|
||||
.write_page = mtk_gephy_write_page,
|
||||
},
|
||||
|
|
|
@ -184,6 +184,7 @@ struct asix_common_private {
|
|||
struct phy_device *phydev;
|
||||
u16 phy_addr;
|
||||
char phy_name[20];
|
||||
bool embd_phy;
|
||||
};
|
||||
|
||||
extern const struct driver_info ax88172a_info;
|
||||
|
|
|
@ -354,24 +354,23 @@ out:
|
|||
static int ax88772_hw_reset(struct usbnet *dev, int in_pm)
|
||||
{
|
||||
struct asix_data *data = (struct asix_data *)&dev->data;
|
||||
int ret, embd_phy;
|
||||
struct asix_common_private *priv = dev->driver_priv;
|
||||
u16 rx_ctl;
|
||||
int ret;
|
||||
|
||||
ret = asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 |
|
||||
AX_GPIO_GPO2EN, 5, in_pm);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0);
|
||||
|
||||
ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy,
|
||||
ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, priv->embd_phy,
|
||||
0, 0, NULL, in_pm);
|
||||
if (ret < 0) {
|
||||
netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (embd_phy) {
|
||||
if (priv->embd_phy) {
|
||||
ret = asix_sw_reset(dev, AX_SWRESET_IPPD, in_pm);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
@ -449,17 +448,16 @@ out:
|
|||
static int ax88772a_hw_reset(struct usbnet *dev, int in_pm)
|
||||
{
|
||||
struct asix_data *data = (struct asix_data *)&dev->data;
|
||||
int ret, embd_phy;
|
||||
struct asix_common_private *priv = dev->driver_priv;
|
||||
u16 rx_ctl, phy14h, phy15h, phy16h;
|
||||
u8 chipcode = 0;
|
||||
int ret;
|
||||
|
||||
ret = asix_write_gpio(dev, AX_GPIO_RSE, 5, in_pm);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0);
|
||||
|
||||
ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy |
|
||||
ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, priv->embd_phy |
|
||||
AX_PHYSEL_SSEN, 0, 0, NULL, in_pm);
|
||||
if (ret < 0) {
|
||||
netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret);
|
||||
|
@ -683,12 +681,6 @@ static int ax88772_init_phy(struct usbnet *dev)
|
|||
struct asix_common_private *priv = dev->driver_priv;
|
||||
int ret;
|
||||
|
||||
ret = asix_read_phy_addr(dev, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
priv->phy_addr = ret;
|
||||
|
||||
snprintf(priv->phy_name, sizeof(priv->phy_name), PHY_ID_FMT,
|
||||
priv->mdio->id, priv->phy_addr);
|
||||
|
||||
|
@ -716,6 +708,12 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||
int ret, i;
|
||||
u32 phyid;
|
||||
|
||||
priv = devm_kzalloc(&dev->udev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
dev->driver_priv = priv;
|
||||
|
||||
usbnet_get_endpoints(dev, intf);
|
||||
|
||||
/* Maybe the boot loader passed the MAC address via device tree */
|
||||
|
@ -751,6 +749,13 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||
dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */
|
||||
dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */
|
||||
|
||||
ret = asix_read_phy_addr(dev, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
priv->phy_addr = ret;
|
||||
priv->embd_phy = ((priv->phy_addr & 0x1f) == 0x10);
|
||||
|
||||
asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &chipcode, 0);
|
||||
chipcode &= AX_CHIPCODE_MASK;
|
||||
|
||||
|
@ -773,12 +778,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||
dev->rx_urb_size = 2048;
|
||||
}
|
||||
|
||||
priv = devm_kzalloc(&dev->udev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
dev->driver_priv = priv;
|
||||
|
||||
priv->presvd_phy_bmcr = 0;
|
||||
priv->presvd_phy_advertise = 0;
|
||||
if (chipcode == AX_AX88772_CHIPCODE) {
|
||||
|
@ -817,6 +816,12 @@ static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf)
|
|||
asix_rx_fixup_common_free(dev->driver_priv);
|
||||
}
|
||||
|
||||
static void ax88178_unbind(struct usbnet *dev, struct usb_interface *intf)
|
||||
{
|
||||
asix_rx_fixup_common_free(dev->driver_priv);
|
||||
kfree(dev->driver_priv);
|
||||
}
|
||||
|
||||
static const struct ethtool_ops ax88178_ethtool_ops = {
|
||||
.get_drvinfo = asix_get_drvinfo,
|
||||
.get_link = asix_get_link,
|
||||
|
@ -1225,7 +1230,7 @@ static const struct driver_info ax88772b_info = {
|
|||
static const struct driver_info ax88178_info = {
|
||||
.description = "ASIX AX88178 USB 2.0 Ethernet",
|
||||
.bind = ax88178_bind,
|
||||
.unbind = ax88772_unbind,
|
||||
.unbind = ax88178_unbind,
|
||||
.status = asix_status,
|
||||
.link_reset = ax88178_link_reset,
|
||||
.reset = ax88178_reset,
|
||||
|
|
|
@ -446,7 +446,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
|
|||
write_mii_word(pegasus, 0, 0x1b, &auxmode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
fail:
|
||||
netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__);
|
||||
return ret;
|
||||
|
@ -835,7 +835,7 @@ static int pegasus_open(struct net_device *net)
|
|||
if (!pegasus->rx_skb)
|
||||
goto exit;
|
||||
|
||||
res = set_registers(pegasus, EthID, 6, net->dev_addr);
|
||||
set_registers(pegasus, EthID, 6, net->dev_addr);
|
||||
|
||||
usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
|
||||
usb_rcvbulkpipe(pegasus->usb, 1),
|
||||
|
|
|
@ -110,7 +110,7 @@ static int mhi_wwan_ctrl_start(struct wwan_port *port)
|
|||
int ret;
|
||||
|
||||
/* Start mhi device's channel(s) */
|
||||
ret = mhi_prepare_for_transfer(mhiwwan->mhi_dev, 0);
|
||||
ret = mhi_prepare_for_transfer(mhiwwan->mhi_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -719,13 +719,8 @@ void mhi_device_put(struct mhi_device *mhi_dev);
|
|||
* host and device execution environments match and
|
||||
* channels are in a DISABLED state.
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @flags: MHI channel flags
|
||||
*/
|
||||
int mhi_prepare_for_transfer(struct mhi_device *mhi_dev,
|
||||
unsigned int flags);
|
||||
|
||||
/* Automatically allocate and queue inbound buffers */
|
||||
#define MHI_CH_INBOUND_ALLOC_BUFS BIT(0)
|
||||
int mhi_prepare_for_transfer(struct mhi_device *mhi_dev);
|
||||
|
||||
/**
|
||||
* mhi_unprepare_from_transfer - Reset UL and DL channels for data transfer.
|
||||
|
|
|
@ -267,7 +267,7 @@ static inline bool fib6_check_expired(const struct fib6_info *f6i)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Function to safely get fn->sernum for passed in rt
|
||||
/* Function to safely get fn->fn_sernum for passed in rt
|
||||
* and store result in passed in cookie.
|
||||
* Return true if we can get cookie safely
|
||||
* Return false if not
|
||||
|
@ -282,7 +282,7 @@ static inline bool fib6_get_cookie_safe(const struct fib6_info *f6i,
|
|||
|
||||
if (fn) {
|
||||
*cookie = fn->fn_sernum;
|
||||
/* pairs with smp_wmb() in fib6_update_sernum_upto_root() */
|
||||
/* pairs with smp_wmb() in __fib6_update_sernum_upto_root() */
|
||||
smp_rmb();
|
||||
status = true;
|
||||
}
|
||||
|
|
|
@ -5150,8 +5150,6 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
|
|||
case BPF_MAP_TYPE_RINGBUF:
|
||||
if (func_id != BPF_FUNC_ringbuf_output &&
|
||||
func_id != BPF_FUNC_ringbuf_reserve &&
|
||||
func_id != BPF_FUNC_ringbuf_submit &&
|
||||
func_id != BPF_FUNC_ringbuf_discard &&
|
||||
func_id != BPF_FUNC_ringbuf_query)
|
||||
goto error;
|
||||
break;
|
||||
|
@ -5260,6 +5258,12 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
|
|||
if (map->map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY)
|
||||
goto error;
|
||||
break;
|
||||
case BPF_FUNC_ringbuf_output:
|
||||
case BPF_FUNC_ringbuf_reserve:
|
||||
case BPF_FUNC_ringbuf_query:
|
||||
if (map->map_type != BPF_MAP_TYPE_RINGBUF)
|
||||
goto error;
|
||||
break;
|
||||
case BPF_FUNC_get_stackid:
|
||||
if (map->map_type != BPF_MAP_TYPE_STACK_TRACE)
|
||||
goto error;
|
||||
|
|
|
@ -2608,6 +2608,7 @@ static int do_setlink(const struct sk_buff *skb,
|
|||
return err;
|
||||
|
||||
if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_TARGET_NETNSID]) {
|
||||
const char *pat = ifname && ifname[0] ? ifname : NULL;
|
||||
struct net *net;
|
||||
int new_ifindex;
|
||||
|
||||
|
@ -2623,7 +2624,7 @@ static int do_setlink(const struct sk_buff *skb,
|
|||
else
|
||||
new_ifindex = 0;
|
||||
|
||||
err = __dev_change_net_namespace(dev, net, ifname, new_ifindex);
|
||||
err = __dev_change_net_namespace(dev, net, pat, new_ifindex);
|
||||
put_net(net);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
|
|
@ -465,14 +465,16 @@ void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
|
|||
if (!doi_def)
|
||||
return;
|
||||
|
||||
switch (doi_def->type) {
|
||||
case CIPSO_V4_MAP_TRANS:
|
||||
kfree(doi_def->map.std->lvl.cipso);
|
||||
kfree(doi_def->map.std->lvl.local);
|
||||
kfree(doi_def->map.std->cat.cipso);
|
||||
kfree(doi_def->map.std->cat.local);
|
||||
kfree(doi_def->map.std);
|
||||
break;
|
||||
if (doi_def->map.std) {
|
||||
switch (doi_def->type) {
|
||||
case CIPSO_V4_MAP_TRANS:
|
||||
kfree(doi_def->map.std->lvl.cipso);
|
||||
kfree(doi_def->map.std->lvl.local);
|
||||
kfree(doi_def->map.std->cat.cipso);
|
||||
kfree(doi_def->map.std->cat.local);
|
||||
kfree(doi_def->map.std);
|
||||
break;
|
||||
}
|
||||
}
|
||||
kfree(doi_def);
|
||||
}
|
||||
|
|
|
@ -473,6 +473,8 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
|
|||
|
||||
static int gre_handle_offloads(struct sk_buff *skb, bool csum)
|
||||
{
|
||||
if (csum && skb_checksum_start(skb) < skb->data)
|
||||
return -EINVAL;
|
||||
return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
|
||||
}
|
||||
|
||||
|
|
|
@ -600,14 +600,14 @@ static struct fib_nh_exception *fnhe_oldest(struct fnhe_hash_bucket *hash)
|
|||
return oldest;
|
||||
}
|
||||
|
||||
static inline u32 fnhe_hashfun(__be32 daddr)
|
||||
static u32 fnhe_hashfun(__be32 daddr)
|
||||
{
|
||||
static u32 fnhe_hashrnd __read_mostly;
|
||||
u32 hval;
|
||||
static siphash_key_t fnhe_hash_key __read_mostly;
|
||||
u64 hval;
|
||||
|
||||
net_get_random_once(&fnhe_hashrnd, sizeof(fnhe_hashrnd));
|
||||
hval = jhash_1word((__force u32)daddr, fnhe_hashrnd);
|
||||
return hash_32(hval, FNHE_HASH_SHIFT);
|
||||
net_get_random_once(&fnhe_hash_key, sizeof(fnhe_hash_key));
|
||||
hval = siphash_1u32((__force u32)daddr, &fnhe_hash_key);
|
||||
return hash_64(hval, FNHE_HASH_SHIFT);
|
||||
}
|
||||
|
||||
static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception *fnhe)
|
||||
|
|
|
@ -1341,7 +1341,7 @@ static void __fib6_update_sernum_upto_root(struct fib6_info *rt,
|
|||
struct fib6_node *fn = rcu_dereference_protected(rt->fib6_node,
|
||||
lockdep_is_held(&rt->fib6_table->tb6_lock));
|
||||
|
||||
/* paired with smp_rmb() in rt6_get_cookie_safe() */
|
||||
/* paired with smp_rmb() in fib6_get_cookie_safe() */
|
||||
smp_wmb();
|
||||
while (fn) {
|
||||
fn->fn_sernum = sernum;
|
||||
|
|
|
@ -629,6 +629,8 @@ drop:
|
|||
|
||||
static int gre_handle_offloads(struct sk_buff *skb, bool csum)
|
||||
{
|
||||
if (csum && skb_checksum_start(skb) < skb->data)
|
||||
return -EINVAL;
|
||||
return iptunnel_handle_offloads(skb,
|
||||
csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <linux/nsproxy.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jhash.h>
|
||||
#include <linux/siphash.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/snmp.h>
|
||||
#include <net/ipv6.h>
|
||||
|
@ -1484,17 +1485,24 @@ static void rt6_exception_remove_oldest(struct rt6_exception_bucket *bucket)
|
|||
static u32 rt6_exception_hash(const struct in6_addr *dst,
|
||||
const struct in6_addr *src)
|
||||
{
|
||||
static u32 seed __read_mostly;
|
||||
u32 val;
|
||||
static siphash_key_t rt6_exception_key __read_mostly;
|
||||
struct {
|
||||
struct in6_addr dst;
|
||||
struct in6_addr src;
|
||||
} __aligned(SIPHASH_ALIGNMENT) combined = {
|
||||
.dst = *dst,
|
||||
};
|
||||
u64 val;
|
||||
|
||||
net_get_random_once(&seed, sizeof(seed));
|
||||
val = jhash2((const u32 *)dst, sizeof(*dst)/sizeof(u32), seed);
|
||||
net_get_random_once(&rt6_exception_key, sizeof(rt6_exception_key));
|
||||
|
||||
#ifdef CONFIG_IPV6_SUBTREES
|
||||
if (src)
|
||||
val = jhash2((const u32 *)src, sizeof(*src)/sizeof(u32), val);
|
||||
combined.src = *src;
|
||||
#endif
|
||||
return hash_32(val, FIB6_EXCEPTION_BUCKET_SIZE_SHIFT);
|
||||
val = siphash(&combined, sizeof(combined), &rt6_exception_key);
|
||||
|
||||
return hash_64(val, FIB6_EXCEPTION_BUCKET_SIZE_SHIFT);
|
||||
}
|
||||
|
||||
/* Helper function to find the cached rt in the hash table
|
||||
|
|
|
@ -15,7 +15,6 @@ struct qrtr_mhi_dev {
|
|||
struct qrtr_endpoint ep;
|
||||
struct mhi_device *mhi_dev;
|
||||
struct device *dev;
|
||||
struct completion ready;
|
||||
};
|
||||
|
||||
/* From MHI to QRTR */
|
||||
|
@ -51,10 +50,6 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
|
|||
struct qrtr_mhi_dev *qdev = container_of(ep, struct qrtr_mhi_dev, ep);
|
||||
int rc;
|
||||
|
||||
rc = wait_for_completion_interruptible(&qdev->ready);
|
||||
if (rc)
|
||||
goto free_skb;
|
||||
|
||||
if (skb->sk)
|
||||
sock_hold(skb->sk);
|
||||
|
||||
|
@ -84,7 +79,7 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
|
|||
int rc;
|
||||
|
||||
/* start channels */
|
||||
rc = mhi_prepare_for_transfer(mhi_dev, 0);
|
||||
rc = mhi_prepare_for_transfer(mhi_dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
@ -101,15 +96,6 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* start channels */
|
||||
rc = mhi_prepare_for_transfer(mhi_dev, MHI_CH_INBOUND_ALLOC_BUFS);
|
||||
if (rc) {
|
||||
qrtr_endpoint_unregister(&qdev->ep);
|
||||
dev_set_drvdata(&mhi_dev->dev, NULL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
complete_all(&qdev->ready);
|
||||
dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n");
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -493,7 +493,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (len != ALIGN(size, 4) + hdrlen)
|
||||
if (!size || len != ALIGN(size, 4) + hdrlen)
|
||||
goto err;
|
||||
|
||||
if (cb->dst_port != QRTR_PORT_CTRL && cb->type != QRTR_TYPE_DATA &&
|
||||
|
|
|
@ -660,6 +660,13 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
|
|||
sch_tree_lock(sch);
|
||||
|
||||
q->nbands = nbands;
|
||||
for (i = nstrict; i < q->nstrict; i++) {
|
||||
INIT_LIST_HEAD(&q->classes[i].alist);
|
||||
if (q->classes[i].qdisc->q.qlen) {
|
||||
list_add_tail(&q->classes[i].alist, &q->active);
|
||||
q->classes[i].deficit = quanta[i];
|
||||
}
|
||||
}
|
||||
q->nstrict = nstrict;
|
||||
memcpy(q->prio2band, priomap, sizeof(priomap));
|
||||
|
||||
|
|
Loading…
Reference in New Issue