mirror of
https://github.com/torvalds/linux.git
synced 2026-06-05 13:06:59 +02:00
Merge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue
Tony Nguyen says: ==================== Intel Wired LAN Driver Updates 2025-07-03 Vladimir Oltean converts Intel drivers (ice, igc, igb, ixgbe, i40e) to utilize new timestamping API (ndo_hwtstamp_get() and ndo_hwtstamp_set()). For ixgbe: Paul, Don, Slawomir, and Radoslaw add Malicious Driver Detection (MDD) support for X550 and E610 devices to detect, report, and handle potentially malicious VFs. Simon Horman corrects spelling mistakes. For igbvf: Kohei Enju removes a couple of unreported counters and adds reporting of Tx timeouts. * '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue: igbvf: add tx_timeout_count to ethtool statistics igbvf: remove unused interrupt counter fields from struct igbvf_adapter ixgbe: spelling corrections ixgbe: turn off MDD while modifying SRRCTL ixgbe: add Tx hang detection unhandled MDD ixgbe: check for MDD events ixgbe: add MDD support i40e: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set() ixgbe: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set() igb: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set() igc: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set() ice: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set() ==================== Link: https://patch.msgid.link/20250703174242.3829277-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
4b62261def
|
|
@ -661,7 +661,7 @@ struct i40e_pf {
|
|||
struct ptp_clock_info ptp_caps;
|
||||
struct sk_buff *ptp_tx_skb;
|
||||
unsigned long ptp_tx_start;
|
||||
struct hwtstamp_config tstamp_config;
|
||||
struct kernel_hwtstamp_config tstamp_config;
|
||||
struct timespec64 ptp_prev_hw_time;
|
||||
struct work_struct ptp_extts0_work;
|
||||
ktime_t ptp_reset_start;
|
||||
|
|
@ -1303,8 +1303,11 @@ void i40e_ptp_tx_hang(struct i40e_pf *pf);
|
|||
void i40e_ptp_tx_hwtstamp(struct i40e_pf *pf);
|
||||
void i40e_ptp_rx_hwtstamp(struct i40e_pf *pf, struct sk_buff *skb, u8 index);
|
||||
void i40e_ptp_set_increment(struct i40e_pf *pf);
|
||||
int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr);
|
||||
int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr);
|
||||
int i40e_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config);
|
||||
int i40e_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack);
|
||||
void i40e_ptp_save_hw_time(struct i40e_pf *pf);
|
||||
void i40e_ptp_restore_hw_time(struct i40e_pf *pf);
|
||||
void i40e_ptp_init(struct i40e_pf *pf);
|
||||
|
|
|
|||
|
|
@ -2954,27 +2954,6 @@ static int i40e_change_mtu(struct net_device *netdev, int new_mtu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_ioctl - Access the hwtstamp interface
|
||||
* @netdev: network interface device structure
|
||||
* @ifr: interface request data
|
||||
* @cmd: ioctl command
|
||||
**/
|
||||
int i40e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
||||
struct i40e_pf *pf = np->vsi->back;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCGHWTSTAMP:
|
||||
return i40e_ptp_get_ts_config(pf, ifr);
|
||||
case SIOCSHWTSTAMP:
|
||||
return i40e_ptp_set_ts_config(pf, ifr);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_vlan_stripping_enable - Turn on vlan stripping for the VSI
|
||||
* @vsi: the vsi being adjusted
|
||||
|
|
@ -13626,7 +13605,6 @@ static const struct net_device_ops i40e_netdev_ops = {
|
|||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_set_mac_address = i40e_set_mac,
|
||||
.ndo_change_mtu = i40e_change_mtu,
|
||||
.ndo_eth_ioctl = i40e_ioctl,
|
||||
.ndo_tx_timeout = i40e_tx_timeout,
|
||||
.ndo_vlan_rx_add_vid = i40e_vlan_rx_add_vid,
|
||||
.ndo_vlan_rx_kill_vid = i40e_vlan_rx_kill_vid,
|
||||
|
|
@ -13654,6 +13632,8 @@ static const struct net_device_ops i40e_netdev_ops = {
|
|||
.ndo_xsk_wakeup = i40e_xsk_wakeup,
|
||||
.ndo_dfwd_add_station = i40e_fwd_add,
|
||||
.ndo_dfwd_del_station = i40e_fwd_del,
|
||||
.ndo_hwtstamp_get = i40e_ptp_hwtstamp_get,
|
||||
.ndo_hwtstamp_set = i40e_ptp_hwtstamp_set,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -912,23 +912,26 @@ void i40e_ptp_set_increment(struct i40e_pf *pf)
|
|||
}
|
||||
|
||||
/**
|
||||
* i40e_ptp_get_ts_config - ioctl interface to read the HW timestamping
|
||||
* @pf: Board private structure
|
||||
* @ifr: ioctl data
|
||||
* i40e_ptp_hwtstamp_get - interface to read the HW timestamping
|
||||
* @netdev: Network device structure
|
||||
* @config: Timestamping configuration structure
|
||||
*
|
||||
* Obtain the current hardware timestamping settigs as requested. To do this,
|
||||
* keep a shadow copy of the timestamp settings rather than attempting to
|
||||
* deconstruct it from the registers.
|
||||
**/
|
||||
int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
|
||||
int i40e_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
struct hwtstamp_config *config = &pf->tstamp_config;
|
||||
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
||||
struct i40e_pf *pf = np->vsi->back;
|
||||
|
||||
if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
|
||||
-EFAULT : 0;
|
||||
*config = pf->tstamp_config;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1167,7 +1170,7 @@ int i40e_ptp_alloc_pins(struct i40e_pf *pf)
|
|||
* more broad if the specific filter is not directly supported.
|
||||
**/
|
||||
static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
|
||||
struct hwtstamp_config *config)
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
struct i40e_hw *hw = &pf->hw;
|
||||
u32 tsyntype, regval;
|
||||
|
|
@ -1290,9 +1293,10 @@ static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
|
|||
}
|
||||
|
||||
/**
|
||||
* i40e_ptp_set_ts_config - ioctl interface to control the HW timestamping
|
||||
* @pf: Board private structure
|
||||
* @ifr: ioctl data
|
||||
* i40e_ptp_hwtstamp_set - interface to control the HW timestamping
|
||||
* @netdev: Network device structure
|
||||
* @config: Timestamping configuration structure
|
||||
* @extack: Netlink extended ack structure for error reporting
|
||||
*
|
||||
* Respond to the user filter requests and make the appropriate hardware
|
||||
* changes here. The XL710 cannot support splitting of the Tx/Rx timestamping
|
||||
|
|
@ -1303,26 +1307,25 @@ static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
|
|||
* as the user receives the timestamps they care about and the user is notified
|
||||
* the filter has been broadened.
|
||||
**/
|
||||
int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
|
||||
int i40e_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct hwtstamp_config config;
|
||||
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
||||
struct i40e_pf *pf = np->vsi->back;
|
||||
int err;
|
||||
|
||||
if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
||||
return -EFAULT;
|
||||
|
||||
err = i40e_ptp_set_timestamp_mode(pf, &config);
|
||||
err = i40e_ptp_set_timestamp_mode(pf, config);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* save these settings for future reference */
|
||||
pf->tstamp_config = config;
|
||||
pf->tstamp_config = *config;
|
||||
|
||||
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
|
||||
-EFAULT : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7901,27 +7901,6 @@ int ice_change_mtu(struct net_device *netdev, int new_mtu)
|
|||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_eth_ioctl - Access the hwtstamp interface
|
||||
* @netdev: network interface device structure
|
||||
* @ifr: interface request data
|
||||
* @cmd: ioctl command
|
||||
*/
|
||||
static int ice_eth_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
struct ice_netdev_priv *np = netdev_priv(netdev);
|
||||
struct ice_pf *pf = np->vsi->back;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCGHWTSTAMP:
|
||||
return ice_ptp_get_ts_config(pf, ifr);
|
||||
case SIOCSHWTSTAMP:
|
||||
return ice_ptp_set_ts_config(pf, ifr);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_aq_str - convert AQ err code to a string
|
||||
* @aq_err: the AQ error code to convert
|
||||
|
|
@ -9761,7 +9740,6 @@ static const struct net_device_ops ice_netdev_ops = {
|
|||
.ndo_change_mtu = ice_change_mtu,
|
||||
.ndo_get_stats64 = ice_get_stats64,
|
||||
.ndo_set_tx_maxrate = ice_set_tx_maxrate,
|
||||
.ndo_eth_ioctl = ice_eth_ioctl,
|
||||
.ndo_set_vf_spoofchk = ice_set_vf_spoofchk,
|
||||
.ndo_set_vf_mac = ice_set_vf_mac,
|
||||
.ndo_get_vf_config = ice_get_vf_cfg,
|
||||
|
|
@ -9785,4 +9763,6 @@ static const struct net_device_ops ice_netdev_ops = {
|
|||
.ndo_bpf = ice_xdp,
|
||||
.ndo_xdp_xmit = ice_xdp_xmit,
|
||||
.ndo_xsk_wakeup = ice_xsk_wakeup,
|
||||
.ndo_hwtstamp_get = ice_ptp_hwtstamp_get,
|
||||
.ndo_hwtstamp_set = ice_ptp_hwtstamp_set,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2197,23 +2197,24 @@ static int ice_ptp_getcrosststamp(struct ptp_clock_info *info,
|
|||
}
|
||||
|
||||
/**
|
||||
* ice_ptp_get_ts_config - ioctl interface to read the timestamping config
|
||||
* @pf: Board private structure
|
||||
* @ifr: ioctl data
|
||||
* ice_ptp_hwtstamp_get - interface to read the timestamping config
|
||||
* @netdev: Pointer to network interface device structure
|
||||
* @config: Timestamping configuration structure
|
||||
*
|
||||
* Copy the timestamping config to user buffer
|
||||
*/
|
||||
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
int ice_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
struct hwtstamp_config *config;
|
||||
struct ice_netdev_priv *np = netdev_priv(netdev);
|
||||
struct ice_pf *pf = np->vsi->back;
|
||||
|
||||
if (pf->ptp.state != ICE_PTP_READY)
|
||||
return -EIO;
|
||||
|
||||
config = &pf->ptp.tstamp_config;
|
||||
*config = pf->ptp.tstamp_config;
|
||||
|
||||
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
|
||||
-EFAULT : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2221,8 +2222,8 @@ int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
|||
* @pf: Board private structure
|
||||
* @config: hwtstamp settings requested or saved
|
||||
*/
|
||||
static int
|
||||
ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
||||
static int ice_ptp_set_timestamp_mode(struct ice_pf *pf,
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
switch (config->tx_type) {
|
||||
case HWTSTAMP_TX_OFF:
|
||||
|
|
@ -2266,32 +2267,32 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
|||
}
|
||||
|
||||
/**
|
||||
* ice_ptp_set_ts_config - ioctl interface to control the timestamping
|
||||
* @pf: Board private structure
|
||||
* @ifr: ioctl data
|
||||
* ice_ptp_hwtstamp_set - interface to control the timestamping
|
||||
* @netdev: Pointer to network interface device structure
|
||||
* @config: Timestamping configuration structure
|
||||
* @extack: Netlink extended ack structure for error reporting
|
||||
*
|
||||
* Get the user config and store it
|
||||
*/
|
||||
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
int ice_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct hwtstamp_config config;
|
||||
struct ice_netdev_priv *np = netdev_priv(netdev);
|
||||
struct ice_pf *pf = np->vsi->back;
|
||||
int err;
|
||||
|
||||
if (pf->ptp.state != ICE_PTP_READY)
|
||||
return -EAGAIN;
|
||||
|
||||
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
||||
return -EFAULT;
|
||||
|
||||
err = ice_ptp_set_timestamp_mode(pf, &config);
|
||||
err = ice_ptp_set_timestamp_mode(pf, config);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Return the actual configuration set */
|
||||
config = pf->ptp.tstamp_config;
|
||||
*config = pf->ptp.tstamp_config;
|
||||
|
||||
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
|
||||
-EFAULT : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ struct ice_ptp {
|
|||
struct ptp_extts_request extts_rqs[GLTSYN_EVNT_H_IDX_MAX];
|
||||
struct ptp_clock_info info;
|
||||
struct ptp_clock *clock;
|
||||
struct hwtstamp_config tstamp_config;
|
||||
struct kernel_hwtstamp_config tstamp_config;
|
||||
u64 reset_time;
|
||||
u32 tx_hwtstamp_skipped;
|
||||
u32 tx_hwtstamp_timeouts;
|
||||
|
|
@ -291,8 +291,11 @@ struct ice_ptp {
|
|||
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
|
||||
int ice_ptp_clock_index(struct ice_pf *pf);
|
||||
struct ice_pf;
|
||||
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr);
|
||||
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr);
|
||||
int ice_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config);
|
||||
int ice_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack);
|
||||
void ice_ptp_restore_timestamp_mode(struct ice_pf *pf);
|
||||
|
||||
void ice_ptp_extts_event(struct ice_pf *pf);
|
||||
|
|
@ -313,12 +316,16 @@ void ice_ptp_init(struct ice_pf *pf);
|
|||
void ice_ptp_release(struct ice_pf *pf);
|
||||
void ice_ptp_link_change(struct ice_pf *pf, bool linkup);
|
||||
#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
|
||||
static inline int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
|
||||
static inline int ice_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
static inline int ice_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -626,7 +626,7 @@ struct igb_adapter {
|
|||
struct delayed_work ptp_overflow_work;
|
||||
struct work_struct ptp_tx_work;
|
||||
struct sk_buff *ptp_tx_skb;
|
||||
struct hwtstamp_config tstamp_config;
|
||||
struct kernel_hwtstamp_config tstamp_config;
|
||||
unsigned long ptp_tx_start;
|
||||
unsigned long last_rx_ptp_check;
|
||||
unsigned long last_rx_timestamp;
|
||||
|
|
@ -771,8 +771,11 @@ void igb_ptp_tx_hang(struct igb_adapter *adapter);
|
|||
void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb);
|
||||
int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,
|
||||
ktime_t *timestamp);
|
||||
int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
|
||||
int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
|
||||
int igb_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config);
|
||||
int igb_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack);
|
||||
void igb_set_flag_queue_pairs(struct igb_adapter *, const u32);
|
||||
unsigned int igb_get_max_rss_queues(struct igb_adapter *);
|
||||
#ifdef CONFIG_IGB_HWMON
|
||||
|
|
|
|||
|
|
@ -3062,6 +3062,8 @@ static const struct net_device_ops igb_netdev_ops = {
|
|||
.ndo_bpf = igb_xdp,
|
||||
.ndo_xdp_xmit = igb_xdp_xmit,
|
||||
.ndo_xsk_wakeup = igb_xsk_wakeup,
|
||||
.ndo_hwtstamp_get = igb_ptp_hwtstamp_get,
|
||||
.ndo_hwtstamp_set = igb_ptp_hwtstamp_set,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -9317,10 +9319,6 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
|||
case SIOCGMIIREG:
|
||||
case SIOCSMIIREG:
|
||||
return igb_mii_ioctl(netdev, ifr, cmd);
|
||||
case SIOCGHWTSTAMP:
|
||||
return igb_ptp_get_ts_config(netdev, ifr);
|
||||
case SIOCSHWTSTAMP:
|
||||
return igb_ptp_set_ts_config(netdev, ifr);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1094,21 +1094,22 @@ void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb)
|
|||
}
|
||||
|
||||
/**
|
||||
* igb_ptp_get_ts_config - get hardware time stamping config
|
||||
* igb_ptp_hwtstamp_get - get hardware time stamping config
|
||||
* @netdev: netdev struct
|
||||
* @ifr: interface struct
|
||||
* @config: timestamping configuration structure
|
||||
*
|
||||
* Get the hwtstamp_config settings to return to the user. Rather than attempt
|
||||
* to deconstruct the settings from the registers, just return a shadow copy
|
||||
* of the last known settings.
|
||||
**/
|
||||
int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr)
|
||||
int igb_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
struct igb_adapter *adapter = netdev_priv(netdev);
|
||||
struct hwtstamp_config *config = &adapter->tstamp_config;
|
||||
|
||||
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
|
||||
-EFAULT : 0;
|
||||
*config = adapter->tstamp_config;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1129,7 +1130,7 @@ int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr)
|
|||
* level 2 or 4".
|
||||
*/
|
||||
static int igb_ptp_set_timestamp_mode(struct igb_adapter *adapter,
|
||||
struct hwtstamp_config *config)
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED;
|
||||
|
|
@ -1275,30 +1276,26 @@ static int igb_ptp_set_timestamp_mode(struct igb_adapter *adapter,
|
|||
}
|
||||
|
||||
/**
|
||||
* igb_ptp_set_ts_config - set hardware time stamping config
|
||||
* igb_ptp_hwtstamp_set - set hardware time stamping config
|
||||
* @netdev: netdev struct
|
||||
* @ifr: interface struct
|
||||
*
|
||||
* @config: timestamping configuration structure
|
||||
* @extack: netlink extended ack structure for error reporting
|
||||
**/
|
||||
int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr)
|
||||
int igb_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct igb_adapter *adapter = netdev_priv(netdev);
|
||||
struct hwtstamp_config config;
|
||||
int err;
|
||||
|
||||
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
||||
return -EFAULT;
|
||||
|
||||
err = igb_ptp_set_timestamp_mode(adapter, &config);
|
||||
err = igb_ptp_set_timestamp_mode(adapter, config);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* save these settings for future reference */
|
||||
memcpy(&adapter->tstamp_config, &config,
|
||||
sizeof(adapter->tstamp_config));
|
||||
adapter->tstamp_config = *config;
|
||||
|
||||
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
|
||||
-EFAULT : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ static const struct igbvf_stats igbvf_gstrings_stats[] = {
|
|||
{ "lbrx_bytes", IGBVF_STAT(stats.gorlbc, stats.base_gorlbc) },
|
||||
{ "lbrx_packets", IGBVF_STAT(stats.gprlbc, stats.base_gprlbc) },
|
||||
{ "tx_restart_queue", IGBVF_STAT(restart_queue, zero_base) },
|
||||
{ "tx_timeout_count", IGBVF_STAT(tx_timeout_count, zero_base) },
|
||||
{ "rx_long_byte_count", IGBVF_STAT(stats.gorc, stats.base_gorc) },
|
||||
{ "rx_csum_offload_good", IGBVF_STAT(hw_csum_good, zero_base) },
|
||||
{ "rx_csum_offload_errors", IGBVF_STAT(hw_csum_err, zero_base) },
|
||||
|
|
|
|||
|
|
@ -238,8 +238,6 @@ struct igbvf_adapter {
|
|||
int int_mode;
|
||||
u32 eims_enable_mask;
|
||||
u32 eims_other;
|
||||
u32 int_counter0;
|
||||
u32 int_counter1;
|
||||
|
||||
u32 eeprom_wol;
|
||||
u32 wol;
|
||||
|
|
|
|||
|
|
@ -855,8 +855,6 @@ static irqreturn_t igbvf_msix_other(int irq, void *data)
|
|||
struct igbvf_adapter *adapter = netdev_priv(netdev);
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
|
||||
adapter->int_counter1++;
|
||||
|
||||
hw->mac.get_link_status = 1;
|
||||
if (!test_bit(__IGBVF_DOWN, &adapter->state))
|
||||
mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
||||
|
|
@ -899,8 +897,6 @@ static irqreturn_t igbvf_intr_msix_rx(int irq, void *data)
|
|||
struct net_device *netdev = data;
|
||||
struct igbvf_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
adapter->int_counter0++;
|
||||
|
||||
/* Write the ITR value calculated at the end of the
|
||||
* previous interrupt.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ struct igc_adapter {
|
|||
*/
|
||||
spinlock_t ptp_tx_lock;
|
||||
struct igc_tx_timestamp_request tx_tstamp[IGC_MAX_TX_TSTAMP_REGS];
|
||||
struct hwtstamp_config tstamp_config;
|
||||
struct kernel_hwtstamp_config tstamp_config;
|
||||
unsigned int ptp_flags;
|
||||
/* System time value lock */
|
||||
spinlock_t tmreg_lock;
|
||||
|
|
@ -773,8 +773,11 @@ void igc_ptp_reset(struct igc_adapter *adapter);
|
|||
void igc_ptp_suspend(struct igc_adapter *adapter);
|
||||
void igc_ptp_stop(struct igc_adapter *adapter);
|
||||
ktime_t igc_ptp_rx_pktstamp(struct igc_adapter *adapter, __le32 *buf);
|
||||
int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
|
||||
int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
|
||||
int igc_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config);
|
||||
int igc_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack);
|
||||
void igc_ptp_tx_hang(struct igc_adapter *adapter);
|
||||
void igc_ptp_read(struct igc_adapter *adapter, struct timespec64 *ts);
|
||||
void igc_ptp_tx_tstamp_event(struct igc_adapter *adapter);
|
||||
|
|
|
|||
|
|
@ -6303,24 +6303,6 @@ int igc_close(struct net_device *netdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_ioctl - Access the hwtstamp interface
|
||||
* @netdev: network interface device structure
|
||||
* @ifr: interface request data
|
||||
* @cmd: ioctl command
|
||||
**/
|
||||
static int igc_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
case SIOCGHWTSTAMP:
|
||||
return igc_ptp_get_ts_config(netdev, ifr);
|
||||
case SIOCSHWTSTAMP:
|
||||
return igc_ptp_set_ts_config(netdev, ifr);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
static int igc_save_launchtime_params(struct igc_adapter *adapter, int queue,
|
||||
bool enable)
|
||||
{
|
||||
|
|
@ -6971,12 +6953,13 @@ static const struct net_device_ops igc_netdev_ops = {
|
|||
.ndo_fix_features = igc_fix_features,
|
||||
.ndo_set_features = igc_set_features,
|
||||
.ndo_features_check = igc_features_check,
|
||||
.ndo_eth_ioctl = igc_ioctl,
|
||||
.ndo_setup_tc = igc_setup_tc,
|
||||
.ndo_bpf = igc_bpf,
|
||||
.ndo_xdp_xmit = igc_xdp_xmit,
|
||||
.ndo_xsk_wakeup = igc_xsk_wakeup,
|
||||
.ndo_get_tstamp = igc_get_tstamp,
|
||||
.ndo_hwtstamp_get = igc_ptp_hwtstamp_get,
|
||||
.ndo_hwtstamp_set = igc_ptp_hwtstamp_set,
|
||||
};
|
||||
|
||||
u32 igc_rd32(struct igc_hw *hw, u32 reg)
|
||||
|
|
|
|||
|
|
@ -626,7 +626,7 @@ static void igc_ptp_enable_tx_timestamp(struct igc_adapter *adapter)
|
|||
* Return: 0 in case of success, negative errno code otherwise.
|
||||
*/
|
||||
static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter,
|
||||
struct hwtstamp_config *config)
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
switch (config->tx_type) {
|
||||
case HWTSTAMP_TX_OFF:
|
||||
|
|
@ -853,48 +853,46 @@ void igc_ptp_tx_tstamp_event(struct igc_adapter *adapter)
|
|||
}
|
||||
|
||||
/**
|
||||
* igc_ptp_set_ts_config - set hardware time stamping config
|
||||
* igc_ptp_hwtstamp_set - set hardware time stamping config
|
||||
* @netdev: network interface device structure
|
||||
* @ifr: interface request data
|
||||
* @config: timestamping configuration structure
|
||||
* @extack: netlink extended ack structure for error reporting
|
||||
*
|
||||
**/
|
||||
int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr)
|
||||
int igc_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct igc_adapter *adapter = netdev_priv(netdev);
|
||||
struct hwtstamp_config config;
|
||||
int err;
|
||||
|
||||
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
||||
return -EFAULT;
|
||||
|
||||
err = igc_ptp_set_timestamp_mode(adapter, &config);
|
||||
err = igc_ptp_set_timestamp_mode(adapter, config);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* save these settings for future reference */
|
||||
memcpy(&adapter->tstamp_config, &config,
|
||||
sizeof(adapter->tstamp_config));
|
||||
adapter->tstamp_config = *config;
|
||||
|
||||
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
|
||||
-EFAULT : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_ptp_get_ts_config - get hardware time stamping config
|
||||
* igc_ptp_hwtstamp_get - get hardware time stamping config
|
||||
* @netdev: network interface device structure
|
||||
* @ifr: interface request data
|
||||
* @config: timestamping configuration structure
|
||||
*
|
||||
* Get the hwtstamp_config settings to return to the user. Rather than attempt
|
||||
* to deconstruct the settings from the registers, just return a shadow copy
|
||||
* of the last known settings.
|
||||
**/
|
||||
int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr)
|
||||
int igc_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
struct igc_adapter *adapter = netdev_priv(netdev);
|
||||
struct hwtstamp_config *config = &adapter->tstamp_config;
|
||||
|
||||
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
|
||||
-EFAULT : 0;
|
||||
*config = adapter->tstamp_config;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The two conditions below must be met for cross timestamping via
|
||||
|
|
|
|||
|
|
@ -429,6 +429,10 @@ enum ixgbe_ring_f_enum {
|
|||
#define IXGBE_BAD_L2A_QUEUE 3
|
||||
#define IXGBE_MAX_MACVLANS 63
|
||||
|
||||
#define IXGBE_MAX_TX_QUEUES 128
|
||||
#define IXGBE_MAX_TX_DESCRIPTORS 40
|
||||
#define IXGBE_MAX_TX_VF_HANGS 4
|
||||
|
||||
DECLARE_STATIC_KEY_FALSE(ixgbe_xdp_locking_key);
|
||||
|
||||
struct ixgbe_ring_feature {
|
||||
|
|
@ -785,7 +789,7 @@ struct ixgbe_adapter {
|
|||
struct ptp_clock_info ptp_caps;
|
||||
struct work_struct ptp_tx_work;
|
||||
struct sk_buff *ptp_tx_skb;
|
||||
struct hwtstamp_config tstamp_config;
|
||||
struct kernel_hwtstamp_config tstamp_config;
|
||||
unsigned long ptp_tx_start;
|
||||
unsigned long last_overflow_check;
|
||||
unsigned long last_rx_ptp_check;
|
||||
|
|
@ -810,6 +814,7 @@ struct ixgbe_adapter {
|
|||
u32 timer_event_accumulator;
|
||||
u32 vferr_refcount;
|
||||
struct ixgbe_mac_addr *mac_table;
|
||||
u8 tx_hang_count[IXGBE_MAX_TX_QUEUES];
|
||||
struct kobject *info_kobj;
|
||||
u16 lse_mask;
|
||||
#ifdef CONFIG_IXGBE_HWMON
|
||||
|
|
@ -1080,8 +1085,11 @@ static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
|
|||
rx_ring->last_rx_timestamp = jiffies;
|
||||
}
|
||||
|
||||
int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
|
||||
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
|
||||
int ixgbe_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config);
|
||||
int ixgbe_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack);
|
||||
void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
|
||||
void ixgbe_ptp_reset(struct ixgbe_adapter *adapter);
|
||||
void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ static void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
|
|||
goto out;
|
||||
|
||||
/*
|
||||
* if capababilities version is type 1 we can write the
|
||||
* if capabilities version is type 1 we can write the
|
||||
* timeout of 10ms to 250ms through the GCR register
|
||||
*/
|
||||
if (!(gcr & IXGBE_GCR_CAP_VER2)) {
|
||||
|
|
@ -751,7 +751,7 @@ static int ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
|
|||
/*
|
||||
* Store the original AUTOC value if it has not been
|
||||
* stored off yet. Otherwise restore the stored original
|
||||
* AUTOC value since the reset operation sets back to deaults.
|
||||
* AUTOC value since the reset operation sets back to defaults.
|
||||
*/
|
||||
autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
if (hw->mac.orig_link_settings_stored == false) {
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ int ixgbe_setup_fc_generic(struct ixgbe_hw *hw)
|
|||
*/
|
||||
if (hw->phy.media_type == ixgbe_media_type_backplane) {
|
||||
/* Need the SW/FW semaphore around AUTOC writes if 82599 and
|
||||
* LESM is on, likewise reset_pipeline requries the lock as
|
||||
* LESM is on, likewise reset_pipeline requires the lock as
|
||||
* it also writes AUTOC.
|
||||
*/
|
||||
ret_val = hw->mac.ops.prot_autoc_write(hw, reg_bp, locked);
|
||||
|
|
@ -301,7 +301,7 @@ int ixgbe_start_hw_generic(struct ixgbe_hw *hw)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/* Cashe bit indicating need for crosstalk fix */
|
||||
/* Cache bit indicating need for crosstalk fix */
|
||||
switch (hw->mac.type) {
|
||||
case ixgbe_mac_82599EB:
|
||||
case ixgbe_mac_X550EM_x:
|
||||
|
|
|
|||
|
|
@ -3965,6 +3965,10 @@ static const struct ixgbe_mac_operations mac_ops_e610 = {
|
|||
.prot_autoc_write = prot_autoc_write_generic,
|
||||
.setup_fc = ixgbe_setup_fc_e610,
|
||||
.fc_autoneg = ixgbe_fc_autoneg_e610,
|
||||
.enable_mdd = ixgbe_enable_mdd_x550,
|
||||
.disable_mdd = ixgbe_disable_mdd_x550,
|
||||
.restore_mdd_vf = ixgbe_restore_mdd_vf_x550,
|
||||
.handle_mdd = ixgbe_handle_mdd_x550,
|
||||
};
|
||||
|
||||
static const struct ixgbe_phy_operations phy_ops_e610 = {
|
||||
|
|
|
|||
|
|
@ -744,7 +744,7 @@ void ixgbe_free_fcoe_ddp_resources(struct ixgbe_adapter *adapter)
|
|||
* ixgbe_setup_fcoe_ddp_resources - setup all fcoe ddp context resources
|
||||
* @adapter: ixgbe adapter
|
||||
*
|
||||
* Sets up ddp context resouces
|
||||
* Sets up ddp context resources
|
||||
*
|
||||
* Returns : 0 indicates success or -EINVAL on failure
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -891,7 +891,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
|
|||
q_vector->rx.itr = IXGBE_ITR_ADAPTIVE_MAX_USECS |
|
||||
IXGBE_ITR_ADAPTIVE_LATENCY;
|
||||
|
||||
/* intialize ITR */
|
||||
/* initialize ITR */
|
||||
if (txr_count && !rxr_count) {
|
||||
/* tx only vector */
|
||||
if (adapter->tx_itr_setting == 1)
|
||||
|
|
@ -1293,7 +1293,8 @@ void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
|
|||
tx_ring->next_to_use = (i < tx_ring->count) ? i : 0;
|
||||
|
||||
/* set bits to identify this as an advanced context descriptor */
|
||||
type_tucmd |= IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
|
||||
type_tucmd |= IXGBE_TXD_CMD_DEXT |
|
||||
FIELD_PREP(IXGBE_ADVTXD_DTYP_MASK, IXGBE_ADVTXD_DTYP_CTXT);
|
||||
|
||||
context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
|
||||
context_desc->fceof_saidx = cpu_to_le32(fceof_saidx);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/sctp.h>
|
||||
|
|
@ -1040,6 +1041,48 @@ static u64 ixgbe_get_tx_pending(struct ixgbe_ring *ring)
|
|||
return ((head <= tail) ? tail : tail + ring->count) - head;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_get_vf_idx - provide VF index number based on queue index
|
||||
* @adapter: pointer to the adapter struct
|
||||
* @queue: Tx queue identifier
|
||||
* @vf: output VF index
|
||||
*
|
||||
* Provide VF index number associated to the input queue.
|
||||
*
|
||||
* Returns: 0 if VF provided or error number.
|
||||
*/
|
||||
static int ixgbe_get_vf_idx(struct ixgbe_adapter *adapter, u16 queue, u16 *vf)
|
||||
{
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
u8 queue_count;
|
||||
u32 reg;
|
||||
|
||||
if (queue >= adapter->num_tx_queues)
|
||||
return -EINVAL;
|
||||
|
||||
/* Determine number of queues by checking
|
||||
* number of virtual functions
|
||||
*/
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
|
||||
switch (reg & IXGBE_GCR_EXT_VT_MODE_MASK) {
|
||||
case IXGBE_GCR_EXT_VT_MODE_64:
|
||||
queue_count = IXGBE_64VFS_QUEUES;
|
||||
break;
|
||||
case IXGBE_GCR_EXT_VT_MODE_32:
|
||||
queue_count = IXGBE_32VFS_QUEUES;
|
||||
break;
|
||||
case IXGBE_GCR_EXT_VT_MODE_16:
|
||||
queue_count = IXGBE_16VFS_QUEUES;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*vf = queue / queue_count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring)
|
||||
{
|
||||
u32 tx_done = ixgbe_get_tx_completed(tx_ring);
|
||||
|
|
@ -1158,6 +1201,150 @@ void ixgbe_update_rx_ring_stats(struct ixgbe_ring *rx_ring,
|
|||
q_vector->rx.total_packets += pkts;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_pf_handle_tx_hang - handle Tx hang on PF
|
||||
* @tx_ring: tx ring number
|
||||
* @next: next ring
|
||||
*
|
||||
* Prints a message containing details about the tx hang.
|
||||
*/
|
||||
static void ixgbe_pf_handle_tx_hang(struct ixgbe_ring *tx_ring,
|
||||
unsigned int next)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = netdev_priv(tx_ring->netdev);
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
|
||||
e_err(drv, "Detected Tx Unit Hang%s\n"
|
||||
" Tx Queue <%d>\n"
|
||||
" TDH, TDT <%x>, <%x>\n"
|
||||
" next_to_use <%x>\n"
|
||||
" next_to_clean <%x>\n"
|
||||
"tx_buffer_info[next_to_clean]\n"
|
||||
" time_stamp <%lx>\n"
|
||||
" jiffies <%lx>\n",
|
||||
ring_is_xdp(tx_ring) ? " (XDP)" : "",
|
||||
tx_ring->queue_index,
|
||||
IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)),
|
||||
IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)),
|
||||
tx_ring->next_to_use, next,
|
||||
tx_ring->tx_buffer_info[next].time_stamp, jiffies);
|
||||
|
||||
if (!ring_is_xdp(tx_ring))
|
||||
netif_stop_subqueue(tx_ring->netdev,
|
||||
tx_ring->queue_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_vf_handle_tx_hang - handle Tx hang on VF
|
||||
* @adapter: structure containing ring specific data
|
||||
* @vf: VF index
|
||||
*
|
||||
* Print a message containing details about malicious driver detection.
|
||||
* Set malicious VF link down if the detection happened several times.
|
||||
*/
|
||||
static void ixgbe_vf_handle_tx_hang(struct ixgbe_adapter *adapter, u16 vf)
|
||||
{
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
|
||||
if (adapter->hw.mac.type != ixgbe_mac_e610)
|
||||
return;
|
||||
|
||||
e_warn(drv,
|
||||
"Malicious Driver Detection tx hang detected on PF %d VF %d MAC: %pM",
|
||||
hw->bus.func, vf, adapter->vfinfo[vf].vf_mac_addresses);
|
||||
|
||||
adapter->tx_hang_count[vf]++;
|
||||
if (adapter->tx_hang_count[vf] == IXGBE_MAX_TX_VF_HANGS) {
|
||||
ixgbe_set_vf_link_state(adapter, vf,
|
||||
IFLA_VF_LINK_STATE_DISABLE);
|
||||
adapter->tx_hang_count[vf] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 ixgbe_poll_tx_icache(struct ixgbe_hw *hw, u16 queue, u16 idx)
|
||||
{
|
||||
IXGBE_WRITE_REG(hw, IXGBE_TXDESCIC, queue * idx);
|
||||
return IXGBE_READ_REG(hw, IXGBE_TXDESCIC);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_check_illegal_queue - search for queue with illegal packet
|
||||
* @adapter: structure containing ring specific data
|
||||
* @queue: queue index
|
||||
*
|
||||
* Check if tx descriptor connected with input queue
|
||||
* contains illegal packet.
|
||||
*
|
||||
* Returns: true if queue contain illegal packet.
|
||||
*/
|
||||
static bool ixgbe_check_illegal_queue(struct ixgbe_adapter *adapter,
|
||||
u16 queue)
|
||||
{
|
||||
u32 hdr_len_reg, mss_len_reg, type_reg;
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
u32 mss_len, header_len, reg;
|
||||
|
||||
for (u16 i = 0; i < IXGBE_MAX_TX_DESCRIPTORS; i++) {
|
||||
/* HW will clear bit IXGBE_TXDESCIC_READY when address
|
||||
* is written to address field. HW will set this bit
|
||||
* when iCache read is done, and data is ready at TIC_DWx.
|
||||
* Set descriptor address.
|
||||
*/
|
||||
read_poll_timeout(ixgbe_poll_tx_icache, reg,
|
||||
!(reg & IXGBE_TXDESCIC_READY), 0, 0, false,
|
||||
hw, queue, i);
|
||||
|
||||
/* read tx descriptor access registers */
|
||||
hdr_len_reg = IXGBE_READ_REG(hw, IXGBE_TIC_DW2(IXGBE_VLAN_MACIP_LENS_REG));
|
||||
type_reg = IXGBE_READ_REG(hw, IXGBE_TIC_DW2(IXGBE_TYPE_TUCMD_MLHL));
|
||||
mss_len_reg = IXGBE_READ_REG(hw, IXGBE_TIC_DW2(IXGBE_MSS_L4LEN_IDX));
|
||||
|
||||
/* check if Advanced Context Descriptor */
|
||||
if (FIELD_GET(IXGBE_ADVTXD_DTYP_MASK, type_reg) !=
|
||||
IXGBE_ADVTXD_DTYP_CTXT)
|
||||
continue;
|
||||
|
||||
/* check for illegal MSS and Header length */
|
||||
mss_len = FIELD_GET(IXGBE_ADVTXD_MSS_MASK, mss_len_reg);
|
||||
header_len = FIELD_GET(IXGBE_ADVTXD_HEADER_LEN_MASK,
|
||||
hdr_len_reg);
|
||||
if ((mss_len + header_len) > SZ_16K) {
|
||||
e_warn(probe, "mss len + header len too long\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_handle_mdd_event - handle mdd event
|
||||
* @adapter: structure containing ring specific data
|
||||
* @tx_ring: tx descriptor ring to handle
|
||||
*
|
||||
* Reset VF driver if malicious vf detected or
|
||||
* illegal packet in an any queue detected.
|
||||
*/
|
||||
static void ixgbe_handle_mdd_event(struct ixgbe_adapter *adapter,
|
||||
struct ixgbe_ring *tx_ring)
|
||||
{
|
||||
u16 vf, q;
|
||||
|
||||
if (adapter->vfinfo && ixgbe_check_mdd_event(adapter)) {
|
||||
/* vf mdd info and malicious vf detected */
|
||||
if (!ixgbe_get_vf_idx(adapter, tx_ring->queue_index, &vf))
|
||||
ixgbe_vf_handle_tx_hang(adapter, vf);
|
||||
} else {
|
||||
/* malicious vf not detected */
|
||||
for (q = 0; q < IXGBE_MAX_TX_QUEUES; q++) {
|
||||
if (ixgbe_check_illegal_queue(adapter, q) &&
|
||||
!ixgbe_get_vf_idx(adapter, q, &vf))
|
||||
/* illegal queue detected */
|
||||
ixgbe_vf_handle_tx_hang(adapter, vf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_clean_tx_irq - Reclaim resources after transmit completes
|
||||
* @q_vector: structure containing interrupt and ring information
|
||||
|
|
@ -1265,26 +1452,10 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
|
|||
adapter->tx_ipsec += total_ipsec;
|
||||
|
||||
if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) {
|
||||
/* schedule immediate reset if we believe we hung */
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
e_err(drv, "Detected Tx Unit Hang %s\n"
|
||||
" Tx Queue <%d>\n"
|
||||
" TDH, TDT <%x>, <%x>\n"
|
||||
" next_to_use <%x>\n"
|
||||
" next_to_clean <%x>\n"
|
||||
"tx_buffer_info[next_to_clean]\n"
|
||||
" time_stamp <%lx>\n"
|
||||
" jiffies <%lx>\n",
|
||||
ring_is_xdp(tx_ring) ? "(XDP)" : "",
|
||||
tx_ring->queue_index,
|
||||
IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)),
|
||||
IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)),
|
||||
tx_ring->next_to_use, i,
|
||||
tx_ring->tx_buffer_info[i].time_stamp, jiffies);
|
||||
if (adapter->hw.mac.type == ixgbe_mac_e610)
|
||||
ixgbe_handle_mdd_event(adapter, tx_ring);
|
||||
|
||||
if (!ring_is_xdp(tx_ring))
|
||||
netif_stop_subqueue(tx_ring->netdev,
|
||||
tx_ring->queue_index);
|
||||
ixgbe_pf_handle_tx_hang(tx_ring, i);
|
||||
|
||||
e_info(probe,
|
||||
"tx hang %d detected on queue %d, resetting adapter\n",
|
||||
|
|
@ -2200,7 +2371,7 @@ static struct sk_buff *ixgbe_build_skb(struct ixgbe_ring *rx_ring,
|
|||
struct sk_buff *skb;
|
||||
|
||||
/* Prefetch first cache line of first page. If xdp->data_meta
|
||||
* is unused, this points extactly as xdp->data, otherwise we
|
||||
* is unused, this points exactly as xdp->data, otherwise we
|
||||
* likely have a consumer accessing first few bytes of meta
|
||||
* data, and then actual data.
|
||||
*/
|
||||
|
|
@ -2323,7 +2494,7 @@ static void ixgbe_rx_buffer_flip(struct ixgbe_ring *rx_ring,
|
|||
* This function provides a "bounce buffer" approach to Rx interrupt
|
||||
* processing. The advantage to this is that on systems that have
|
||||
* expensive overhead for IOMMU access this provides a means of avoiding
|
||||
* it by maintaining the mapping of the page to the syste.
|
||||
* it by maintaining the mapping of the page to the system.
|
||||
*
|
||||
* Returns amount of work completed
|
||||
**/
|
||||
|
|
@ -3933,8 +4104,12 @@ void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter)
|
|||
static void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter)
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
bool pfc_en = adapter->dcb_cfg.pfc_mode_enable;
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
int i;
|
||||
|
||||
if (hw->mac.ops.disable_mdd)
|
||||
hw->mac.ops.disable_mdd(hw);
|
||||
|
||||
if (adapter->ixgbe_ieee_pfc)
|
||||
pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en);
|
||||
|
|
@ -3956,6 +4131,9 @@ static void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter)
|
|||
for (i = 0; i < adapter->num_rx_queues; i++)
|
||||
ixgbe_disable_rx_drop(adapter, adapter->rx_ring[i]);
|
||||
}
|
||||
|
||||
if (hw->mac.ops.enable_mdd)
|
||||
hw->mac.ops.enable_mdd(hw);
|
||||
}
|
||||
|
||||
#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
|
||||
|
|
@ -4885,7 +5063,7 @@ static void ixgbe_scrub_vfta(struct ixgbe_adapter *adapter, u32 vfta_offset)
|
|||
/* pull VLAN ID from VLVF */
|
||||
vid = vlvf & VLAN_VID_MASK;
|
||||
|
||||
/* only concern outselves with a certain range */
|
||||
/* only concern ourselves with a certain range */
|
||||
if (vid < vid_start || vid >= vid_end)
|
||||
continue;
|
||||
|
||||
|
|
@ -7964,6 +8142,9 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
|
|||
netif_carrier_on(netdev);
|
||||
ixgbe_check_vf_rate_limit(adapter);
|
||||
|
||||
if (adapter->num_vfs && hw->mac.ops.enable_mdd)
|
||||
hw->mac.ops.enable_mdd(hw);
|
||||
|
||||
/* enable transmits */
|
||||
netif_tx_wake_all_queues(adapter->netdev);
|
||||
|
||||
|
|
@ -9441,10 +9622,6 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
|
|||
struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSHWTSTAMP:
|
||||
return ixgbe_ptp_set_ts_config(adapter, req);
|
||||
case SIOCGHWTSTAMP:
|
||||
return ixgbe_ptp_get_ts_config(adapter, req);
|
||||
case SIOCGMIIPHY:
|
||||
if (!adapter->hw.phy.ops.read_reg)
|
||||
return -EOPNOTSUPP;
|
||||
|
|
@ -10908,6 +11085,8 @@ static const struct net_device_ops ixgbe_netdev_ops = {
|
|||
.ndo_bpf = ixgbe_xdp,
|
||||
.ndo_xdp_xmit = ixgbe_xdp_xmit,
|
||||
.ndo_xsk_wakeup = ixgbe_xsk_wakeup,
|
||||
.ndo_hwtstamp_get = ixgbe_ptp_hwtstamp_get,
|
||||
.ndo_hwtstamp_set = ixgbe_ptp_hwtstamp_set,
|
||||
};
|
||||
|
||||
static void ixgbe_disable_txr_hw(struct ixgbe_adapter *adapter,
|
||||
|
|
@ -11110,7 +11289,7 @@ void ixgbe_txrx_ring_enable(struct ixgbe_adapter *adapter, int ring)
|
|||
* ixgbe_enumerate_functions - Get the number of ports this device has
|
||||
* @adapter: adapter structure
|
||||
*
|
||||
* This function enumerates the phsyical functions co-located on a single slot,
|
||||
* This function enumerates the physical functions co-located on a single slot,
|
||||
* in order to determine how many ports a device has. This is most useful in
|
||||
* determining the required GT/s of PCIe bandwidth necessary for optimal
|
||||
* performance.
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#define IXGBE_VT_MSGTYPE_CTS 0x20000000 /* Indicates that VF is still
|
||||
clear to send requests */
|
||||
#define IXGBE_VT_MSGINFO_SHIFT 16
|
||||
/* bits 23:16 are used for exra info for certain messages */
|
||||
/* bits 23:16 are used for extra info for certain messages */
|
||||
#define IXGBE_VT_MSGINFO_MASK (0xFF << IXGBE_VT_MSGINFO_SHIFT)
|
||||
|
||||
/* definitions to support mailbox API version negotiation */
|
||||
|
|
|
|||
|
|
@ -1323,7 +1323,7 @@ int ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
|
|||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Restart autonegotiation and PHY and waits for completion.
|
||||
* This function always returns success, this is nessary since
|
||||
* This function always returns success, this is necessary since
|
||||
* it is called via a function pointer that could call other
|
||||
* functions that could return an error.
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -936,20 +936,22 @@ void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *q_vector,
|
|||
}
|
||||
|
||||
/**
|
||||
* ixgbe_ptp_get_ts_config - get current hardware timestamping configuration
|
||||
* @adapter: pointer to adapter structure
|
||||
* @ifr: ioctl data
|
||||
* ixgbe_ptp_hwtstamp_get - get current hardware timestamping configuration
|
||||
* @netdev: pointer to net device structure
|
||||
* @config: timestamping configuration structure
|
||||
*
|
||||
* This function returns the current timestamping settings. Rather than
|
||||
* attempt to deconstruct registers to fill in the values, simply keep a copy
|
||||
* of the old settings around, and return a copy when requested.
|
||||
*/
|
||||
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
|
||||
int ixgbe_ptp_hwtstamp_get(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
struct hwtstamp_config *config = &adapter->tstamp_config;
|
||||
struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
|
||||
|
||||
return copy_to_user(ifr->ifr_data, config,
|
||||
sizeof(*config)) ? -EFAULT : 0;
|
||||
*config = adapter->tstamp_config;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -978,7 +980,7 @@ int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
|
|||
* mode, if required to support the specifically requested mode.
|
||||
*/
|
||||
static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
|
||||
struct hwtstamp_config *config)
|
||||
struct kernel_hwtstamp_config *config)
|
||||
{
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED;
|
||||
|
|
@ -1129,31 +1131,29 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
|
|||
}
|
||||
|
||||
/**
|
||||
* ixgbe_ptp_set_ts_config - user entry point for timestamp mode
|
||||
* @adapter: pointer to adapter struct
|
||||
* @ifr: ioctl data
|
||||
* ixgbe_ptp_hwtstamp_set - user entry point for timestamp mode
|
||||
* @netdev: pointer to net device structure
|
||||
* @config: timestamping configuration structure
|
||||
* @extack: netlink extended ack structure for error reporting
|
||||
*
|
||||
* Set hardware to requested mode. If unsupported, return an error with no
|
||||
* changes. Otherwise, store the mode for future reference.
|
||||
*/
|
||||
int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
|
||||
int ixgbe_ptp_hwtstamp_set(struct net_device *netdev,
|
||||
struct kernel_hwtstamp_config *config,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct hwtstamp_config config;
|
||||
struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
|
||||
int err;
|
||||
|
||||
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
||||
return -EFAULT;
|
||||
|
||||
err = ixgbe_ptp_set_timestamp_mode(adapter, &config);
|
||||
err = ixgbe_ptp_set_timestamp_mode(adapter, config);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* save these settings for future reference */
|
||||
memcpy(&adapter->tstamp_config, &config,
|
||||
sizeof(adapter->tstamp_config));
|
||||
adapter->tstamp_config = *config;
|
||||
|
||||
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
|
||||
-EFAULT : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ixgbe_ptp_link_speed_adjust(struct ixgbe_adapter *adapter,
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsigned int max_vfs)
|
|||
int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
unsigned int num_vfs = adapter->num_vfs, vf;
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
unsigned long flags;
|
||||
int rss;
|
||||
|
||||
|
|
@ -237,6 +238,9 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
|
|||
if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
|
||||
return 0;
|
||||
|
||||
if (hw->mac.ops.disable_mdd)
|
||||
hw->mac.ops.disable_mdd(hw);
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
/*
|
||||
* If our VFs are assigned we cannot shut down SR-IOV
|
||||
|
|
@ -702,7 +706,7 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
|
|||
u32 reg_val;
|
||||
u32 queue;
|
||||
|
||||
/* remove VLAN filters beloning to this VF */
|
||||
/* remove VLAN filters belonging to this VF */
|
||||
ixgbe_clear_vf_vlans(adapter, vf);
|
||||
|
||||
/* add back PF assigned VLAN or VLAN 0 */
|
||||
|
|
@ -1353,12 +1357,59 @@ static void ixgbe_rcv_ack_from_vf(struct ixgbe_adapter *adapter, u32 vf)
|
|||
ixgbe_write_mbx(hw, &msg, 1, vf);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_check_mdd_event - check for MDD event on all VFs
|
||||
* @adapter: pointer to ixgbe adapter
|
||||
*
|
||||
* Return: true if there is a VF on which MDD event occurred, false otherwise.
|
||||
*/
|
||||
bool ixgbe_check_mdd_event(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
DECLARE_BITMAP(vf_bitmap, 64);
|
||||
bool ret = false;
|
||||
int i;
|
||||
|
||||
if (!hw->mac.ops.handle_mdd)
|
||||
return false;
|
||||
|
||||
/* Did we have a malicious event */
|
||||
bitmap_zero(vf_bitmap, 64);
|
||||
hw->mac.ops.handle_mdd(hw, vf_bitmap);
|
||||
|
||||
/* Log any blocked queues and release lock */
|
||||
for_each_set_bit(i, vf_bitmap, 64) {
|
||||
dev_warn(&adapter->pdev->dev,
|
||||
"Malicious event on VF %d tx:%x rx:%x\n", i,
|
||||
IXGBE_READ_REG(hw, IXGBE_LVMMC_TX),
|
||||
IXGBE_READ_REG(hw, IXGBE_LVMMC_RX));
|
||||
|
||||
if (hw->mac.ops.restore_mdd_vf) {
|
||||
u32 ping;
|
||||
|
||||
hw->mac.ops.restore_mdd_vf(hw, i);
|
||||
|
||||
/* get the VF to rebuild its queues */
|
||||
adapter->vfinfo[i].clear_to_send = 0;
|
||||
ping = IXGBE_PF_CONTROL_MSG |
|
||||
IXGBE_VT_MSGTYPE_CTS;
|
||||
ixgbe_write_mbx(hw, &ping, 1, i);
|
||||
}
|
||||
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ixgbe_msg_task(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
unsigned long flags;
|
||||
u32 vf;
|
||||
|
||||
ixgbe_check_mdd_event(adapter);
|
||||
|
||||
spin_lock_irqsave(&adapter->vfs_lock, flags);
|
||||
for (vf = 0; vf < adapter->num_vfs; vf++) {
|
||||
/* process any reset requests */
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#ifdef CONFIG_PCI_IOV
|
||||
void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter);
|
||||
#endif
|
||||
bool ixgbe_check_mdd_event(struct ixgbe_adapter *adapter);
|
||||
void ixgbe_msg_task(struct ixgbe_adapter *adapter);
|
||||
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
|
||||
void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ struct ixgbe_thermal_sensor_data {
|
|||
#define NVM_VER_INVALID 0xFFFF
|
||||
#define NVM_ETK_VALID 0x8000
|
||||
#define NVM_INVALID_PTR 0xFFFF
|
||||
#define NVM_VER_SIZE 32 /* version sting size */
|
||||
#define NVM_VER_SIZE 32 /* version string size */
|
||||
|
||||
struct ixgbe_nvm_version {
|
||||
u32 etk_id;
|
||||
|
|
@ -402,6 +402,8 @@ struct ixgbe_nvm_version {
|
|||
#define IXGBE_MRCTL(_i) (0x0F600 + ((_i) * 4))
|
||||
#define IXGBE_VMRVLAN(_i) (0x0F610 + ((_i) * 4))
|
||||
#define IXGBE_VMRVM(_i) (0x0F630 + ((_i) * 4))
|
||||
#define IXGBE_LVMMC_RX 0x2FA8
|
||||
#define IXGBE_LVMMC_TX 0x8108
|
||||
#define IXGBE_WQBR_RX(_i) (0x2FB0 + ((_i) * 4)) /* 4 total */
|
||||
#define IXGBE_WQBR_TX(_i) (0x8130 + ((_i) * 4)) /* 4 total */
|
||||
#define IXGBE_L34T_IMIR(_i) (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
|
||||
|
|
@ -1042,6 +1044,7 @@ struct ixgbe_nvm_version {
|
|||
#define IXGBE_GCR_EXT_VT_MODE_16 0x00000001
|
||||
#define IXGBE_GCR_EXT_VT_MODE_32 0x00000002
|
||||
#define IXGBE_GCR_EXT_VT_MODE_64 0x00000003
|
||||
#define IXGBE_GCR_EXT_VT_MODE_MASK 0x00000003
|
||||
#define IXGBE_GCR_EXT_SRIOV (IXGBE_GCR_EXT_MSIX_EN | \
|
||||
IXGBE_GCR_EXT_VT_MODE_64)
|
||||
|
||||
|
|
@ -2021,7 +2024,7 @@ enum {
|
|||
/* EEPROM Addressing bits based on type (0-small, 1-large) */
|
||||
#define IXGBE_EEC_ADDR_SIZE 0x00000400
|
||||
#define IXGBE_EEC_SIZE 0x00007800 /* EEPROM Size */
|
||||
#define IXGBE_EERD_MAX_ADDR 0x00003FFF /* EERD alows 14 bits for addr. */
|
||||
#define IXGBE_EERD_MAX_ADDR 0x00003FFF /* EERD allows 14 bits for addr. */
|
||||
|
||||
#define IXGBE_EEC_SIZE_SHIFT 11
|
||||
#define IXGBE_EEPROM_WORD_SIZE_SHIFT 6
|
||||
|
|
@ -2746,6 +2749,28 @@ enum ixgbe_fdir_pballoc_type {
|
|||
#define FW_PHY_INFO_ID_HI_MASK 0xFFFF0000u
|
||||
#define FW_PHY_INFO_ID_LO_MASK 0x0000FFFFu
|
||||
|
||||
/* There are only 3 options for VFs creation on this device:
|
||||
* 16 VFs pool with 8 queues each
|
||||
* 32 VFs pool with 4 queues each
|
||||
* 64 VFs pool with 2 queues each
|
||||
*
|
||||
* That means reading some VF registers that map VF to queue depending on
|
||||
* chosen option. Define values that help dealing with each scenario.
|
||||
*/
|
||||
/* Number of queues based on VFs pool */
|
||||
#define IXGBE_16VFS_QUEUES 8
|
||||
#define IXGBE_32VFS_QUEUES 4
|
||||
#define IXGBE_64VFS_QUEUES 2
|
||||
/* Mask for getting queues bits based on VFs pool */
|
||||
#define IXGBE_16VFS_BITMASK GENMASK(IXGBE_16VFS_QUEUES - 1, 0)
|
||||
#define IXGBE_32VFS_BITMASK GENMASK(IXGBE_32VFS_QUEUES - 1, 0)
|
||||
#define IXGBE_64VFS_BITMASK GENMASK(IXGBE_64VFS_QUEUES - 1, 0)
|
||||
/* Convert queue index to register number.
|
||||
* We have 4 registers with 32 queues in each.
|
||||
*/
|
||||
#define IXGBE_QUEUES_PER_REG 32
|
||||
#define IXGBE_QUEUES_REG_AMOUNT 4
|
||||
|
||||
/* Host Interface Command Structures */
|
||||
struct ixgbe_hic_hdr {
|
||||
u8 cmd;
|
||||
|
|
@ -2911,6 +2936,13 @@ struct ixgbe_adv_tx_context_desc {
|
|||
__le32 mss_l4len_idx;
|
||||
};
|
||||
|
||||
enum {
|
||||
IXGBE_VLAN_MACIP_LENS_REG = 0,
|
||||
IXGBE_FCEOF_SAIDX_REG = 1,
|
||||
IXGBE_TYPE_TUCMD_MLHL = 2,
|
||||
IXGBE_MSS_L4LEN_IDX = 3,
|
||||
};
|
||||
|
||||
/* Adv Transmit Descriptor Config Masks */
|
||||
#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */
|
||||
#define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */
|
||||
|
|
@ -2918,7 +2950,7 @@ struct ixgbe_adv_tx_context_desc {
|
|||
#define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */
|
||||
#define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */
|
||||
#define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */
|
||||
#define IXGBE_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Desc */
|
||||
#define IXGBE_ADVTXD_DTYP_CTXT 0x2 /* Advanced Context Desc */
|
||||
#define IXGBE_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
|
||||
#define IXGBE_ADVTXD_DCMD_EOP IXGBE_TXD_CMD_EOP /* End of Packet */
|
||||
#define IXGBE_ADVTXD_DCMD_IFCS IXGBE_TXD_CMD_IFCS /* Insert FCS */
|
||||
|
|
@ -2967,6 +2999,8 @@ struct ixgbe_adv_tx_context_desc {
|
|||
#define IXGBE_ADVTXD_FCOEF_EOF_MASK (3u << 10) /* FC EOF index */
|
||||
#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
|
||||
#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
|
||||
#define IXGBE_ADVTXD_MSS_MASK GENMASK(31, IXGBE_ADVTXD_MSS_SHIFT)
|
||||
#define IXGBE_ADVTXD_HEADER_LEN_MASK GENMASK(8, 0)
|
||||
|
||||
/* Autonegotiation advertised speeds */
|
||||
typedef u32 ixgbe_autoneg_advertised;
|
||||
|
|
@ -3539,6 +3573,12 @@ struct ixgbe_mac_operations {
|
|||
int (*dmac_config_tcs)(struct ixgbe_hw *hw);
|
||||
int (*read_iosf_sb_reg)(struct ixgbe_hw *, u32, u32, u32 *);
|
||||
int (*write_iosf_sb_reg)(struct ixgbe_hw *, u32, u32, u32);
|
||||
|
||||
/* MDD events */
|
||||
void (*enable_mdd)(struct ixgbe_hw *hw);
|
||||
void (*disable_mdd)(struct ixgbe_hw *hw);
|
||||
void (*restore_mdd_vf)(struct ixgbe_hw *hw, u32 vf);
|
||||
void (*handle_mdd)(struct ixgbe_hw *hw, unsigned long *vf_bitmap);
|
||||
};
|
||||
|
||||
struct ixgbe_phy_operations {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ int ixgbe_get_invariants_X540(struct ixgbe_hw *hw)
|
|||
}
|
||||
|
||||
/**
|
||||
* ixgbe_setup_mac_link_X540 - Set the auto advertised capabilitires
|
||||
* ixgbe_setup_mac_link_X540 - Set the auto advertised capabilities
|
||||
* @hw: pointer to hardware structure
|
||||
* @speed: new link speed
|
||||
* @autoneg_wait_to_complete: true when waiting for completion is needed
|
||||
|
|
|
|||
|
|
@ -3316,7 +3316,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
|
|||
return media_type;
|
||||
}
|
||||
|
||||
/** ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
|
||||
/** ixgbe_init_ext_t_x550em - Start (uninstall) the external Base T PHY.
|
||||
** @hw: pointer to hardware structure
|
||||
**/
|
||||
static int ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
|
||||
|
|
@ -3800,6 +3800,122 @@ static int ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
|
|||
return status;
|
||||
}
|
||||
|
||||
static void ixgbe_set_mdd_x550(struct ixgbe_hw *hw, bool ena)
|
||||
{
|
||||
u32 reg_dma, reg_rdr;
|
||||
|
||||
reg_dma = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
|
||||
reg_rdr = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
|
||||
|
||||
if (ena) {
|
||||
reg_dma |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
|
||||
reg_rdr |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
|
||||
} else {
|
||||
reg_dma &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
|
||||
reg_rdr &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
|
||||
}
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_dma);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg_rdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_enable_mdd_x550 - enable malicious driver detection
|
||||
* @hw: pointer to hardware structure
|
||||
*/
|
||||
void ixgbe_enable_mdd_x550(struct ixgbe_hw *hw)
|
||||
{
|
||||
ixgbe_set_mdd_x550(hw, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_disable_mdd_x550 - disable malicious driver detection
|
||||
* @hw: pointer to hardware structure
|
||||
*/
|
||||
void ixgbe_disable_mdd_x550(struct ixgbe_hw *hw)
|
||||
{
|
||||
ixgbe_set_mdd_x550(hw, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_restore_mdd_vf_x550 - restore VF that was disabled during MDD event
|
||||
* @hw: pointer to hardware structure
|
||||
* @vf: vf index
|
||||
*/
|
||||
void ixgbe_restore_mdd_vf_x550(struct ixgbe_hw *hw, u32 vf)
|
||||
{
|
||||
u32 idx, reg, val, num_qs, start_q, bitmask;
|
||||
|
||||
/* Map VF to queues */
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
|
||||
switch (reg & IXGBE_MRQC_MRQE_MASK) {
|
||||
case IXGBE_MRQC_VMDQRT8TCEN:
|
||||
num_qs = IXGBE_16VFS_QUEUES;
|
||||
bitmask = IXGBE_16VFS_BITMASK;
|
||||
break;
|
||||
case IXGBE_MRQC_VMDQRSS32EN:
|
||||
case IXGBE_MRQC_VMDQRT4TCEN:
|
||||
num_qs = IXGBE_32VFS_QUEUES;
|
||||
bitmask = IXGBE_32VFS_BITMASK;
|
||||
break;
|
||||
default:
|
||||
num_qs = IXGBE_64VFS_QUEUES;
|
||||
bitmask = IXGBE_64VFS_BITMASK;
|
||||
break;
|
||||
}
|
||||
start_q = vf * num_qs;
|
||||
|
||||
/* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */
|
||||
idx = start_q / IXGBE_QUEUES_PER_REG;
|
||||
val = bitmask << (start_q % IXGBE_QUEUES_PER_REG);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), val);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), val);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_handle_mdd_x550 - handle malicious driver detection event
|
||||
* @hw: pointer to hardware structure
|
||||
* @vf_bitmap: output vf bitmap of malicious vfs
|
||||
*/
|
||||
void ixgbe_handle_mdd_x550(struct ixgbe_hw *hw, unsigned long *vf_bitmap)
|
||||
{
|
||||
u32 i, j, reg, q, div, vf;
|
||||
unsigned long wqbr;
|
||||
|
||||
/* figure out pool size for mapping to vf's */
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
|
||||
switch (reg & IXGBE_MRQC_MRQE_MASK) {
|
||||
case IXGBE_MRQC_VMDQRT8TCEN:
|
||||
div = IXGBE_16VFS_QUEUES;
|
||||
break;
|
||||
case IXGBE_MRQC_VMDQRSS32EN:
|
||||
case IXGBE_MRQC_VMDQRT4TCEN:
|
||||
div = IXGBE_32VFS_QUEUES;
|
||||
break;
|
||||
default:
|
||||
div = IXGBE_64VFS_QUEUES;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read WQBR_TX and WQBR_RX and check for malicious queues */
|
||||
for (i = 0; i < IXGBE_QUEUES_REG_AMOUNT; i++) {
|
||||
wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i)) |
|
||||
IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i));
|
||||
if (!wqbr)
|
||||
continue;
|
||||
|
||||
/* Get malicious queue */
|
||||
for_each_set_bit(j, (unsigned long *)&wqbr,
|
||||
IXGBE_QUEUES_PER_REG) {
|
||||
/* Get queue from bitmask */
|
||||
q = j + (i * IXGBE_QUEUES_PER_REG);
|
||||
/* Map queue to vf */
|
||||
vf = q / div;
|
||||
set_bit(vf, vf_bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define X550_COMMON_MAC \
|
||||
.init_hw = &ixgbe_init_hw_generic, \
|
||||
.start_hw = &ixgbe_start_hw_X540, \
|
||||
|
|
@ -3863,6 +3979,10 @@ static const struct ixgbe_mac_operations mac_ops_X550 = {
|
|||
.prot_autoc_write = prot_autoc_write_generic,
|
||||
.setup_fc = ixgbe_setup_fc_generic,
|
||||
.fc_autoneg = ixgbe_fc_autoneg,
|
||||
.enable_mdd = ixgbe_enable_mdd_x550,
|
||||
.disable_mdd = ixgbe_disable_mdd_x550,
|
||||
.restore_mdd_vf = ixgbe_restore_mdd_vf_x550,
|
||||
.handle_mdd = ixgbe_handle_mdd_x550,
|
||||
};
|
||||
|
||||
static const struct ixgbe_mac_operations mac_ops_X550EM_x = {
|
||||
|
|
|
|||
|
|
@ -17,4 +17,9 @@ void ixgbe_set_source_address_pruning_x550(struct ixgbe_hw *hw,
|
|||
void ixgbe_set_ethertype_anti_spoofing_x550(struct ixgbe_hw *hw,
|
||||
bool enable, int vf);
|
||||
|
||||
void ixgbe_enable_mdd_x550(struct ixgbe_hw *hw);
|
||||
void ixgbe_disable_mdd_x550(struct ixgbe_hw *hw);
|
||||
void ixgbe_restore_mdd_vf_x550(struct ixgbe_hw *hw, u32 vf);
|
||||
void ixgbe_handle_mdd_x550(struct ixgbe_hw *hw, unsigned long *vf_bitmap);
|
||||
|
||||
#endif /* _IXGBE_X550_H_ */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user