mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 01:53:29 +02:00
Add protection against TX pause storms. A pause storm occurs when a device fails to send received packets up to the stack. When a pause storm is detected (pause state persists beyond the configured timeout), the device stops sending the pause frames and begins dropping packets instead of back-pressuring. The timeout is configurable via ethtool tunable (pfc-prevention-tout) with a maximum value of 10485ms, and the default value of 500ms. Once the device transitions to the storm-detected state, the service task periodically attempts recovery, returning the device to normal operation to handle any subsequent pause storm episodes. Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com> Link: https://patch.msgid.link/20260302230149.1580195-4-mohsin.bashr@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
150 lines
5.1 KiB
C
150 lines
5.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Copyright (c) Meta Platforms, Inc. and affiliates. */
|
|
|
|
#ifndef _FBNIC_MAC_H_
|
|
#define _FBNIC_MAC_H_
|
|
|
|
#include <linux/types.h>
|
|
|
|
struct fbnic_dev;
|
|
|
|
/* The RXB clock runs at 600 MHZ in the ASIC and the PAUSE_STORM_UNIT_WR
|
|
* is 10us granularity, so set the clock to 6000 (0x1770)
|
|
*/
|
|
#define FBNIC_RXB_PS_CLK_DIV 0x1770
|
|
|
|
/* Convert milliseconds to pause storm timeout units (10us granularity) */
|
|
#define FBNIC_MAC_RXB_PS_TO(ms) ((ms) * 100)
|
|
|
|
/* Convert pause storm timeout units (10us granularity) to milliseconds */
|
|
#define FBNIC_MAC_RXB_PS_TO_MS(ps) ((ps) / 100)
|
|
|
|
/* Set the default timer to 500ms, which should be longer than any
|
|
* reasonable period of continuous pausing. The service task, which runs
|
|
* once per second, periodically resets the pause storm trigger.
|
|
*
|
|
* As a result, on a functioning system, if pause continues, we enforce
|
|
* a duty cycle determined by the configured pause storm timeout (50%
|
|
* default). A crashed system will not have the service task and therefore
|
|
* pause will remain disabled until reboot recovery.
|
|
*/
|
|
#define FBNIC_MAC_PS_TO_DEFAULT_MS 500
|
|
#define FBNIC_MAC_PS_TO_MAX_MS \
|
|
FBNIC_MAC_RXB_PS_TO_MS(FIELD_MAX(FBNIC_RXB_PAUSE_STORM_THLD_TIME))
|
|
|
|
#define FBNIC_MAX_JUMBO_FRAME_SIZE 9742
|
|
|
|
/* States loosely based on section 136.8.11.7.5 of IEEE 802.3-2022 Ethernet
|
|
* Standard. These are needed to track the state of the PHY as it has a delay
|
|
* of several seconds from the time link comes up until it has completed
|
|
* training that we need to wait to report the link.
|
|
*
|
|
* Currently we treat training as a single block as this is managed by the
|
|
* firmware.
|
|
*
|
|
* We have FBNIC_PMD_SEND_DATA set to 0 as the expected default at driver load
|
|
* and we initialize the structure containing it to zero at allocation.
|
|
*/
|
|
enum {
|
|
FBNIC_PMD_SEND_DATA = 0x0,
|
|
FBNIC_PMD_INITIALIZE = 0x1,
|
|
FBNIC_PMD_TRAINING = 0x2,
|
|
FBNIC_PMD_LINK_READY = 0x3,
|
|
};
|
|
|
|
enum {
|
|
FBNIC_LINK_EVENT_NONE = 0,
|
|
FBNIC_LINK_EVENT_UP = 1,
|
|
FBNIC_LINK_EVENT_DOWN = 2,
|
|
};
|
|
|
|
/* Treat the FEC bits as a bitmask laid out as follows:
|
|
* Bit 0: RS Enabled
|
|
* Bit 1: BASER(Firecode) Enabled
|
|
* Bit 2: Retrieve FEC from FW
|
|
*/
|
|
enum {
|
|
FBNIC_FEC_OFF = 0,
|
|
FBNIC_FEC_RS = 1,
|
|
FBNIC_FEC_BASER = 2,
|
|
};
|
|
|
|
/* Treat the AUI modes as a modulation/lanes bitmask:
|
|
* Bit 0: Lane Count, 0 = R1, 1 = R2
|
|
* Bit 1: Modulation, 0 = NRZ, 1 = PAM4
|
|
* Bit 2: Unknown Modulation/Lane Configuration
|
|
*/
|
|
enum {
|
|
FBNIC_AUI_25GAUI = 0, /* 25.7812GBd 25.78125 * 1 */
|
|
FBNIC_AUI_LAUI2 = 1, /* 51.5625GBd 25.78128 * 2 */
|
|
FBNIC_AUI_50GAUI1 = 2, /* 53.125GBd 53.125 * 1 */
|
|
FBNIC_AUI_100GAUI2 = 3, /* 106.25GBd 53.125 * 2 */
|
|
FBNIC_AUI_UNKNOWN = 4,
|
|
__FBNIC_AUI_MAX__
|
|
};
|
|
|
|
#define FBNIC_AUI_MODE_R2 (FBNIC_AUI_LAUI2)
|
|
#define FBNIC_AUI_MODE_PAM4 (FBNIC_AUI_50GAUI1)
|
|
|
|
enum fbnic_sensor_id {
|
|
FBNIC_SENSOR_TEMP, /* Temp in millidegrees Centigrade */
|
|
FBNIC_SENSOR_VOLTAGE, /* Voltage in millivolts */
|
|
};
|
|
|
|
/* This structure defines the interface hooks for the MAC. The MAC hooks
|
|
* will be configured as a const struct provided with a set of function
|
|
* pointers.
|
|
*
|
|
* void (*init_regs)(struct fbnic_dev *fbd);
|
|
* Initialize MAC registers to enable Tx/Rx paths and FIFOs.
|
|
*
|
|
* int (*get_link_event)(struct fbnic_dev *fbd)
|
|
* Get the current link event status, reports true if link has
|
|
* changed to either FBNIC_LINK_EVENT_DOWN or FBNIC_LINK_EVENT_UP
|
|
* bool (*get_link)(struct fbnic_dev *fbd, u8 aui, u8 fec);
|
|
* Check link status
|
|
*
|
|
* void (*prepare)(struct fbnic_dev *fbd, u8 aui, u8 fec);
|
|
* Prepare PHY for init by fetching settings, disabling interrupts,
|
|
* and sending an updated PHY config to FW if needed.
|
|
*
|
|
* void (*link_down)(struct fbnic_dev *fbd);
|
|
* Configure MAC for link down event
|
|
* void (*link_up)(struct fbnic_dev *fbd, bool tx_pause, bool rx_pause);
|
|
* Configure MAC for link up event;
|
|
*
|
|
*/
|
|
struct fbnic_mac {
|
|
void (*init_regs)(struct fbnic_dev *fbd);
|
|
|
|
int (*get_link_event)(struct fbnic_dev *fbd);
|
|
bool (*get_link)(struct fbnic_dev *fbd, u8 aui, u8 fec);
|
|
|
|
void (*prepare)(struct fbnic_dev *fbd, u8 aui, u8 fec);
|
|
|
|
void (*get_fec_stats)(struct fbnic_dev *fbd, bool reset,
|
|
struct fbnic_fec_stats *fec_stats);
|
|
void (*get_pcs_stats)(struct fbnic_dev *fbd, bool reset,
|
|
struct fbnic_pcs_stats *pcs_stats);
|
|
void (*get_eth_mac_stats)(struct fbnic_dev *fbd, bool reset,
|
|
struct fbnic_eth_mac_stats *mac_stats);
|
|
void (*get_pause_stats)(struct fbnic_dev *fbd, bool reset,
|
|
struct fbnic_pause_stats *pause_stats);
|
|
void (*get_eth_ctrl_stats)(struct fbnic_dev *fbd, bool reset,
|
|
struct fbnic_eth_ctrl_stats *ctrl_stats);
|
|
void (*get_rmon_stats)(struct fbnic_dev *fbd, bool reset,
|
|
struct fbnic_rmon_stats *rmon_stats);
|
|
|
|
void (*link_down)(struct fbnic_dev *fbd);
|
|
void (*link_up)(struct fbnic_dev *fbd, bool tx_pause, bool rx_pause);
|
|
|
|
int (*get_sensor)(struct fbnic_dev *fbd, int id, long *val);
|
|
};
|
|
|
|
int fbnic_mac_init(struct fbnic_dev *fbd);
|
|
void fbnic_mac_get_fw_settings(struct fbnic_dev *fbd, u8 *aui, u8 *fec);
|
|
int fbnic_mac_ps_protect_to_config(struct fbnic_dev *fbd, u16 timeout);
|
|
void fbnic_mac_ps_protect_handler(struct fbnic_dev *fbd);
|
|
bool fbnic_mac_check_tx_pause(struct fbnic_dev *fbd);
|
|
#endif /* _FBNIC_MAC_H_ */
|