pci_restore_state(pdev);
if (deep) {
+ /* Reinitialize Nic/Vecs objects */
+ aq_nic_deinit(nic, !nic->aq_hw->aq_nic_cfg->wol);
+
ret = aq_nic_init(nic);
if (ret)
goto err_exit;
struct ice_hw *hw = &pf->hw;
struct sockaddr *addr = pi;
enum ice_status status;
+ u8 old_mac[ETH_ALEN];
u8 flags = 0;
int err = 0;
u8 *mac;
}
netif_addr_lock_bh(netdev);
+ ether_addr_copy(old_mac, netdev->dev_addr);
+ /* change the netdev's MAC address */
+ memcpy(netdev->dev_addr, mac, netdev->addr_len);
+ netif_addr_unlock_bh(netdev);
+
/* Clean up old MAC filter. Not an error if old filter doesn't exist */
- status = ice_fltr_remove_mac(vsi, netdev->dev_addr, ICE_FWD_TO_VSI);
+ status = ice_fltr_remove_mac(vsi, old_mac, ICE_FWD_TO_VSI);
if (status && status != ICE_ERR_DOES_NOT_EXIST) {
err = -EADDRNOTAVAIL;
goto err_update_filters;
if (err) {
netdev_err(netdev, "can't set MAC %pM. filter update failed\n",
mac);
+ netif_addr_lock_bh(netdev);
+ ether_addr_copy(netdev->dev_addr, old_mac);
netif_addr_unlock_bh(netdev);
return err;
}
- /* change the netdev's MAC address */
- memcpy(netdev->dev_addr, mac, netdev->addr_len);
- netif_addr_unlock_bh(netdev);
netdev_dbg(vsi->netdev, "updated MAC address to %pM\n",
netdev->dev_addr);
return;
/* Set the timestamp enable flag for all the Tx rings */
- ice_for_each_rxq(vsi, i) {
+ ice_for_each_txq(vsi, i) {
if (!vsi->tx_rings[i])
continue;
vsi->tx_rings[i]->ptp_tx = on;
return -EFAULT;
}
+/**
+ * ice_ptp_disable_all_clkout - Disable all currently configured outputs
+ * @pf: pointer to the PF structure
+ *
+ * Disable all currently configured clock outputs. This is necessary before
+ * certain changes to the PTP hardware clock. Use ice_ptp_enable_all_clkout to
+ * re-enable the clocks again.
+ */
+static void ice_ptp_disable_all_clkout(struct ice_pf *pf)
+{
+ uint i;
+
+ for (i = 0; i < pf->ptp.info.n_per_out; i++)
+ if (pf->ptp.perout_channels[i].ena)
+ ice_ptp_cfg_clkout(pf, i, NULL, false);
+}
+
+/**
+ * ice_ptp_enable_all_clkout - Enable all configured periodic clock outputs
+ * @pf: pointer to the PF structure
+ *
+ * Enable all currently configured clock outputs. Use this after
+ * ice_ptp_disable_all_clkout to reconfigure the output signals according to
+ * their configuration.
+ */
+static void ice_ptp_enable_all_clkout(struct ice_pf *pf)
+{
+ uint i;
+
+ for (i = 0; i < pf->ptp.info.n_per_out; i++)
+ if (pf->ptp.perout_channels[i].ena)
+ ice_ptp_cfg_clkout(pf, i, &pf->ptp.perout_channels[i],
+ false);
+}
+
/**
* ice_ptp_gpio_enable_e810 - Enable/disable ancillary features of PHC
* @info: the driver's PTP info structure
goto exit;
}
+ /* Disable periodic outputs */
+ ice_ptp_disable_all_clkout(pf);
+
err = ice_ptp_write_init(pf, &ts64);
ice_ptp_unlock(hw);
if (!err)
ice_ptp_update_cached_phctime(pf);
+ /* Reenable periodic outputs */
+ ice_ptp_enable_all_clkout(pf);
exit:
if (err) {
dev_err(ice_pf_to_dev(pf), "PTP failed to set time %d\n", err);
return -EBUSY;
}
+ /* Disable periodic outputs */
+ ice_ptp_disable_all_clkout(pf);
+
err = ice_ptp_write_adj(pf, delta);
+ /* Reenable periodic outputs */
+ ice_ptp_enable_all_clkout(pf);
+
ice_ptp_unlock(hw);
if (err) {
info = &pf->ptp.info;
dev = ice_pf_to_dev(pf);
- /* Allocate memory for kernel pins interface */
- if (info->n_pins) {
- info->pin_config = devm_kcalloc(dev, info->n_pins,
- sizeof(*info->pin_config),
- GFP_KERNEL);
- if (!info->pin_config) {
- info->n_pins = 0;
- return -ENOMEM;
- }
- }
-
/* Attempt to register the clock before enabling the hardware. */
clock = ptp_clock_register(info, dev);
if (IS_ERR(clock))
{
u8 idx;
+ spin_lock(&tx->lock);
+
for (idx = 0; idx < tx->len; idx++) {
u8 phy_idx = idx + tx->quad_offset;
tx->tstamps[idx].skb = NULL;
}
}
+
+ spin_unlock(&tx->lock);
}
/**
if (!pf->ptp.clock)
return;
+ /* Disable periodic outputs */
+ ice_ptp_disable_all_clkout(pf);
+
ice_clear_ptp_clock_index(pf);
ptp_clock_unregister(pf->ptp.clock);
pf->ptp.clock = NULL;
void mlx5_unregister_device(struct mlx5_core_dev *dev)
{
mutex_lock(&mlx5_intf_mutex);
- dev->priv.flags |= MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV;
+ dev->priv.flags = MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV;
mlx5_rescan_drivers_locked(dev);
mutex_unlock(&mlx5_intf_mutex);
}
mlx5e_rep_queue_neigh_stats_work(priv);
list_for_each_entry(flow, flow_list, tmp_list) {
- if (!mlx5e_is_offloaded_flow(flow))
+ if (!mlx5e_is_offloaded_flow(flow) || !flow_flag_test(flow, SLOW))
continue;
attr = flow->attr;
esw_attr = attr->esw_attr;
int err;
list_for_each_entry(flow, flow_list, tmp_list) {
- if (!mlx5e_is_offloaded_flow(flow))
+ if (!mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, SLOW))
continue;
attr = flow->attr;
esw_attr = attr->esw_attr;
int mlx5e_tc_query_route_vport(struct net_device *out_dev, struct net_device *route_dev, u16 *vport)
{
struct mlx5e_priv *out_priv, *route_priv;
+ struct mlx5_devcom *devcom = NULL;
struct mlx5_core_dev *route_mdev;
struct mlx5_eswitch *esw;
u16 vhca_id;
route_mdev = route_priv->mdev;
vhca_id = MLX5_CAP_GEN(route_mdev, vhca_id);
+ if (mlx5_lag_is_active(out_priv->mdev)) {
+ /* In lag case we may get devices from different eswitch instances.
+ * If we failed to get vport num, it means, mostly, that we on the wrong
+ * eswitch.
+ */
+ err = mlx5_eswitch_vhca_id_to_vport(esw, vhca_id, vport);
+ if (err != -ENOENT)
+ return err;
+
+ devcom = out_priv->mdev->priv.devcom;
+ esw = mlx5_devcom_get_peer_data(devcom, MLX5_DEVCOM_ESW_OFFLOADS);
+ if (!esw)
+ return -ENODEV;
+ }
+
err = mlx5_eswitch_vhca_id_to_vport(esw, vhca_id, vport);
+ if (devcom)
+ mlx5_devcom_release_peer_data(devcom, MLX5_DEVCOM_ESW_OFFLOADS);
return err;
}
dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
dest.vport.num = e->vport;
dest.vport.vhca_id = MLX5_CAP_GEN(esw->dev, vhca_id);
+ dest.vport.flags = MLX5_FLOW_DEST_VPORT_VHCA_ID;
e->fwd_rule = mlx5_add_flow_rules(e->ft, spec, &flow_act, &dest, 1);
if (IS_ERR(e->fwd_rule)) {
mlx5_destroy_flow_group(e->fwd_grp);
int err;
ldev->flags &= ~MLX5_LAG_MODE_FLAGS;
+ mlx5_lag_mp_reset(ldev);
if (ldev->shared_fdb) {
mlx5_eswitch_offloads_destroy_single_fdb(ldev->pf[MLX5_LAG_P1].dev->priv.eswitch,
return NOTIFY_DONE;
}
+void mlx5_lag_mp_reset(struct mlx5_lag *ldev)
+{
+ /* Clear mfi, as it might become stale when a route delete event
+ * has been missed, see mlx5_lag_fib_route_event().
+ */
+ ldev->lag_mp.mfi = NULL;
+}
+
int mlx5_lag_mp_init(struct mlx5_lag *ldev)
{
struct lag_mp *mp = &ldev->lag_mp;
#ifdef CONFIG_MLX5_ESWITCH
+void mlx5_lag_mp_reset(struct mlx5_lag *ldev);
int mlx5_lag_mp_init(struct mlx5_lag *ldev);
void mlx5_lag_mp_cleanup(struct mlx5_lag *ldev);
#else /* CONFIG_MLX5_ESWITCH */
+static inline void mlx5_lag_mp_reset(struct mlx5_lag *ldev) {};
static inline int mlx5_lag_mp_init(struct mlx5_lag *ldev) { return 0; }
static inline void mlx5_lag_mp_cleanup(struct mlx5_lag *ldev) {}
new_htbl = dr_rule_rehash(rule, nic_rule, cur_htbl,
ste_location, send_ste_list);
if (!new_htbl) {
- mlx5dr_htbl_put(cur_htbl);
mlx5dr_err(dmn, "Failed creating rehash table, htbl-log_size: %d\n",
cur_htbl->chunk_size);
+ mlx5dr_htbl_put(cur_htbl);
} else {
cur_htbl = new_htbl;
}
static int mv3310_match_phy_device(struct phy_device *phydev)
{
+ if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
+ MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310)
+ return 0;
+
return mv3310_get_number_of_ports(phydev) == 1;
}
static int mv3340_match_phy_device(struct phy_device *phydev)
{
+ if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
+ MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310)
+ return 0;
+
return mv3310_get_number_of_ports(phydev) == 4;
}
void netdev_rx_handler_unregister(struct net_device *dev);
bool dev_valid_name(const char *name);
+static inline bool is_socket_ioctl_cmd(unsigned int cmd)
+{
+ return _IOC_TYPE(cmd) == SOCK_IOC_TYPE;
+}
int get_user_ifreq(struct ifreq *ifr, void __user **ifrdata, void __user *arg);
int put_user_ifreq(struct ifreq *ifr, void __user *arg);
int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr,
if (err != -ENOIOCTLCMD)
return err;
+ if (!is_socket_ioctl_cmd(cmd))
+ return -ENOTTY;
+
if (get_user_ifreq(&ifr, &data, argp))
return -EFAULT;
err = dev_ioctl(net, cmd, &ifr, data, &need_copyout);
struct ifreq ifreq;
void __user *data;
+ if (!is_socket_ioctl_cmd(cmd))
+ return -ENOTTY;
if (get_user_ifreq(&ifreq, &data, u_ifreq32))
return -EFAULT;
ifreq.ifr_data = data;