aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hnae3.h5
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.c37
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c29
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c27
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_lif.c18
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_lif.h6
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_phc.c102
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_txrx.c3
-rw-r--r--drivers/net/phy/marvell10g.c384
-rw-r--r--include/linux/marvell_phy.h6
-rw-r--r--include/linux/qed/qed_ll2_if.h1
-rw-r--r--include/uapi/linux/mdio.h2
-rw-r--r--net/batman-adv/bat_iv_ogm.c2
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c1
-rw-r--r--net/batman-adv/types.h10
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/simple.json59
17 files changed, 545 insertions, 148 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 217c7470bfa9..3ea9539821b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10695,6 +10695,7 @@ F: include/linux/mv643xx.h
MARVELL MV88X3310 PHY DRIVER
M: Russell King <[email protected]>
+M: Marek Behun <[email protected]>
S: Maintained
F: drivers/net/phy/marvell10g.c
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index a234116ba0e5..1d2189047781 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -474,8 +474,9 @@ struct hnae3_ae_dev {
struct hnae3_ae_ops {
int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev);
void (*uninit_ae_dev)(struct hnae3_ae_dev *ae_dev);
- void (*flr_prepare)(struct hnae3_ae_dev *ae_dev);
- void (*flr_done)(struct hnae3_ae_dev *ae_dev);
+ void (*reset_prepare)(struct hnae3_ae_dev *ae_dev,
+ enum hnae3_reset_type rst_type);
+ void (*reset_done)(struct hnae3_ae_dev *ae_dev);
int (*init_client_instance)(struct hnae3_client *client,
struct hnae3_ae_dev *ae_dev);
void (*uninit_client_instance)(struct hnae3_client *client,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 076bfb76bdb9..25afe5a3348c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2365,6 +2365,32 @@ static void hns3_shutdown(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D3hot);
}
+static int __maybe_unused hns3_suspend(struct device *dev)
+{
+ struct hnae3_ae_dev *ae_dev = dev_get_drvdata(dev);
+
+ if (hns3_is_phys_func(ae_dev->pdev)) {
+ dev_info(dev, "Begin to suspend.\n");
+ if (ae_dev && ae_dev->ops && ae_dev->ops->reset_prepare)
+ ae_dev->ops->reset_prepare(ae_dev, HNAE3_FUNC_RESET);
+ }
+
+ return 0;
+}
+
+static int __maybe_unused hns3_resume(struct device *dev)
+{
+ struct hnae3_ae_dev *ae_dev = dev_get_drvdata(dev);
+
+ if (hns3_is_phys_func(ae_dev->pdev)) {
+ dev_info(dev, "Begin to resume.\n");
+ if (ae_dev && ae_dev->ops && ae_dev->ops->reset_done)
+ ae_dev->ops->reset_done(ae_dev);
+ }
+
+ return 0;
+}
+
static pci_ers_result_t hns3_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
@@ -2423,8 +2449,8 @@ static void hns3_reset_prepare(struct pci_dev *pdev)
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
dev_info(&pdev->dev, "FLR prepare\n");
- if (ae_dev && ae_dev->ops && ae_dev->ops->flr_prepare)
- ae_dev->ops->flr_prepare(ae_dev);
+ if (ae_dev && ae_dev->ops && ae_dev->ops->reset_prepare)
+ ae_dev->ops->reset_prepare(ae_dev, HNAE3_FLR_RESET);
}
static void hns3_reset_done(struct pci_dev *pdev)
@@ -2432,8 +2458,8 @@ static void hns3_reset_done(struct pci_dev *pdev)
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
dev_info(&pdev->dev, "FLR done\n");
- if (ae_dev && ae_dev->ops && ae_dev->ops->flr_done)
- ae_dev->ops->flr_done(ae_dev);
+ if (ae_dev && ae_dev->ops && ae_dev->ops->reset_done)
+ ae_dev->ops->reset_done(ae_dev);
}
static const struct pci_error_handlers hns3_err_handler = {
@@ -2443,12 +2469,15 @@ static const struct pci_error_handlers hns3_err_handler = {
.reset_done = hns3_reset_done,
};
+static SIMPLE_DEV_PM_OPS(hns3_pm_ops, hns3_suspend, hns3_resume);
+
static struct pci_driver hns3_driver = {
.name = hns3_driver_name,
.id_table = hns3_pci_tbl,
.probe = hns3_probe,
.remove = hns3_remove,
.shutdown = hns3_shutdown,
+ .driver.pm = &hns3_pm_ops,
.sriov_configure = hns3_pci_sriov_configure,
.err_handler = &hns3_err_handler,
};
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index bc805d5fb16e..c446b63be503 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -11058,10 +11058,11 @@ static void hclge_state_uninit(struct hclge_dev *hdev)
cancel_delayed_work_sync(&hdev->service_task);
}
-static void hclge_flr_prepare(struct hnae3_ae_dev *ae_dev)
+static void hclge_reset_prepare_general(struct hnae3_ae_dev *ae_dev,
+ enum hnae3_reset_type rst_type)
{
-#define HCLGE_FLR_RETRY_WAIT_MS 500
-#define HCLGE_FLR_RETRY_CNT 5
+#define HCLGE_RESET_RETRY_WAIT_MS 500
+#define HCLGE_RESET_RETRY_CNT 5
struct hclge_dev *hdev = ae_dev->priv;
int retry_cnt = 0;
@@ -11070,30 +11071,34 @@ static void hclge_flr_prepare(struct hnae3_ae_dev *ae_dev)
retry:
down(&hdev->reset_sem);
set_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
- hdev->reset_type = HNAE3_FLR_RESET;
+ hdev->reset_type = rst_type;
ret = hclge_reset_prepare(hdev);
if (ret || hdev->reset_pending) {
- dev_err(&hdev->pdev->dev, "fail to prepare FLR, ret=%d\n",
+ dev_err(&hdev->pdev->dev, "fail to prepare to reset, ret=%d\n",
ret);
if (hdev->reset_pending ||
- retry_cnt++ < HCLGE_FLR_RETRY_CNT) {
+ retry_cnt++ < HCLGE_RESET_RETRY_CNT) {
dev_err(&hdev->pdev->dev,
"reset_pending:0x%lx, retry_cnt:%d\n",
hdev->reset_pending, retry_cnt);
clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
up(&hdev->reset_sem);
- msleep(HCLGE_FLR_RETRY_WAIT_MS);
+ msleep(HCLGE_RESET_RETRY_WAIT_MS);
goto retry;
}
}
- /* disable misc vector before FLR done */
+ /* disable misc vector before reset done */
hclge_enable_vector(&hdev->misc_vector, false);
set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state);
- hdev->rst_stats.flr_rst_cnt++;
+
+ if (hdev->reset_type == HNAE3_FLR_RESET)
+ hdev->rst_stats.flr_rst_cnt++;
+ else if (hdev->reset_type == HNAE3_FUNC_RESET)
+ hdev->rst_stats.pf_rst_cnt++;
}
-static void hclge_flr_done(struct hnae3_ae_dev *ae_dev)
+static void hclge_reset_done(struct hnae3_ae_dev *ae_dev)
{
struct hclge_dev *hdev = ae_dev->priv;
int ret;
@@ -12466,8 +12471,8 @@ static int hclge_get_module_eeprom(struct hnae3_handle *handle, u32 offset,
static const struct hnae3_ae_ops hclge_ops = {
.init_ae_dev = hclge_init_ae_dev,
.uninit_ae_dev = hclge_uninit_ae_dev,
- .flr_prepare = hclge_flr_prepare,
- .flr_done = hclge_flr_done,
+ .reset_prepare = hclge_reset_prepare_general,
+ .reset_done = hclge_reset_done,
.init_client_instance = hclge_init_client_instance,
.uninit_client_instance = hclge_uninit_client_instance,
.map_ring_to_vector = hclge_map_ring_to_vector,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index 1682769112d0..c7d5c1726499 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -2114,10 +2114,11 @@ static void hclgevf_enable_vector(struct hclgevf_misc_vector *vector, bool en)
writel(en ? 1 : 0, vector->addr);
}
-static void hclgevf_flr_prepare(struct hnae3_ae_dev *ae_dev)
+static void hclgevf_reset_prepare_general(struct hnae3_ae_dev *ae_dev,
+ enum hnae3_reset_type rst_type)
{
-#define HCLGEVF_FLR_RETRY_WAIT_MS 500
-#define HCLGEVF_FLR_RETRY_CNT 5
+#define HCLGEVF_RESET_RETRY_WAIT_MS 500
+#define HCLGEVF_RESET_RETRY_CNT 5
struct hclgevf_dev *hdev = ae_dev->priv;
int retry_cnt = 0;
@@ -2126,29 +2127,31 @@ static void hclgevf_flr_prepare(struct hnae3_ae_dev *ae_dev)
retry:
down(&hdev->reset_sem);
set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
- hdev->reset_type = HNAE3_FLR_RESET;
+ hdev->reset_type = rst_type;
ret = hclgevf_reset_prepare(hdev);
if (ret) {
- dev_err(&hdev->pdev->dev, "fail to prepare FLR, ret=%d\n",
+ dev_err(&hdev->pdev->dev, "fail to prepare to reset, ret=%d\n",
ret);
if (hdev->reset_pending ||
- retry_cnt++ < HCLGEVF_FLR_RETRY_CNT) {
+ retry_cnt++ < HCLGEVF_RESET_RETRY_CNT) {
dev_err(&hdev->pdev->dev,
"reset_pending:0x%lx, retry_cnt:%d\n",
hdev->reset_pending, retry_cnt);
clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
up(&hdev->reset_sem);
- msleep(HCLGEVF_FLR_RETRY_WAIT_MS);
+ msleep(HCLGEVF_RESET_RETRY_WAIT_MS);
goto retry;
}
}
- /* disable misc vector before FLR done */
+ /* disable misc vector before reset done */
hclgevf_enable_vector(&hdev->misc_vector, false);
- hdev->rst_stats.flr_rst_cnt++;
+
+ if (hdev->reset_type == HNAE3_FLR_RESET)
+ hdev->rst_stats.flr_rst_cnt++;
}
-static void hclgevf_flr_done(struct hnae3_ae_dev *ae_dev)
+static void hclgevf_reset_done(struct hnae3_ae_dev *ae_dev)
{
struct hclgevf_dev *hdev = ae_dev->priv;
int ret;
@@ -3748,8 +3751,8 @@ void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,
static const struct hnae3_ae_ops hclgevf_ops = {
.init_ae_dev = hclgevf_init_ae_dev,
.uninit_ae_dev = hclgevf_uninit_ae_dev,
- .flr_prepare = hclgevf_flr_prepare,
- .flr_done = hclgevf_flr_done,
+ .reset_prepare = hclgevf_reset_prepare_general,
+ .reset_done = hclgevf_reset_done,
.init_client_instance = hclgevf_init_client_instance,
.uninit_client_instance = hclgevf_uninit_client_instance,
.start = hclgevf_ae_start,
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index ee56fed12e07..af3a5368529c 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -135,7 +135,7 @@ static void ionic_link_status_check(struct ionic_lif *lif)
if (netdev->flags & IFF_UP && netif_running(netdev)) {
mutex_lock(&lif->queue_lock);
err = ionic_start_queues(lif);
- if (err) {
+ if (err && err != -EBUSY) {
netdev_err(lif->netdev,
"Failed to start queues: %d\n", err);
set_bit(IONIC_LIF_F_BROKEN, lif->state);
@@ -2015,9 +2015,8 @@ static void ionic_txrx_free(struct ionic_lif *lif)
static int ionic_txrx_alloc(struct ionic_lif *lif)
{
- unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
- unsigned int flags;
- unsigned int i;
+ unsigned int comp_sz, desc_sz, num_desc, sg_desc_sz;
+ unsigned int flags, i;
int err = 0;
num_desc = lif->ntxq_descs;
@@ -2584,12 +2583,11 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
int ionic_reconfigure_queues(struct ionic_lif *lif,
struct ionic_queue_params *qparam)
{
- unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
+ unsigned int comp_sz, desc_sz, num_desc, sg_desc_sz;
struct ionic_qcq **tx_qcqs = NULL;
struct ionic_qcq **rx_qcqs = NULL;
- unsigned int flags;
+ unsigned int flags, i;
int err = -ENOMEM;
- unsigned int i;
/* allocate temporary qcq arrays to hold new queue structs */
if (qparam->nxqs != lif->nxqs || qparam->ntxq_descs != lif->ntxq_descs) {
@@ -2989,14 +2987,14 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
goto err_txrx_free;
}
- /* restore the hardware timestamping queues */
- ionic_lif_hwstamp_set(lif, NULL);
-
clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
ionic_link_status_check_request(lif, CAN_SLEEP);
netif_device_attach(lif->netdev);
dev_info(ionic->dev, "FW Up: LIFs restarted\n");
+ /* restore the hardware timestamping queues */
+ ionic_lif_hwstamp_replay(lif);
+
return;
err_txrx_free:
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index ea3b086af179..346506f01715 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -302,6 +302,7 @@ int ionic_lif_identify(struct ionic *ionic, u8 lif_type,
int ionic_lif_size(struct ionic *ionic);
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
+int ionic_lif_hwstamp_replay(struct ionic_lif *lif);
int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr);
int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr);
ktime_t ionic_lif_phc_ktime(struct ionic_lif *lif, u64 counter);
@@ -310,6 +311,11 @@ void ionic_lif_unregister_phc(struct ionic_lif *lif);
void ionic_lif_alloc_phc(struct ionic_lif *lif);
void ionic_lif_free_phc(struct ionic_lif *lif);
#else
+static inline int ionic_lif_hwstamp_replay(struct ionic_lif *lif)
+{
+ return -EOPNOTSUPP;
+}
+
static inline int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
{
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_phc.c b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
index 86ae5011ac9b..177dbf89affd 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_phc.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
@@ -18,10 +18,8 @@ static int ionic_hwstamp_tx_mode(int config_tx_type)
return IONIC_TXSTAMP_ON;
case HWTSTAMP_TX_ONESTEP_SYNC:
return IONIC_TXSTAMP_ONESTEP_SYNC;
-#ifdef HAVE_HWSTAMP_TX_ONESTEP_P2P
case HWTSTAMP_TX_ONESTEP_P2P:
return IONIC_TXSTAMP_ONESTEP_P2P;
-#endif
default:
return -ERANGE;
}
@@ -66,10 +64,12 @@ static u64 ionic_hwstamp_rx_filt(int config_rx_filter)
}
}
-int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
+static int ionic_lif_hwstamp_set_ts_config(struct ionic_lif *lif,
+ struct hwtstamp_config *new_ts)
{
struct ionic *ionic = lif->ionic;
- struct hwtstamp_config config;
+ struct hwtstamp_config *config;
+ struct hwtstamp_config ts;
int tx_mode = 0;
u64 rx_filt = 0;
int err, err2;
@@ -79,39 +79,48 @@ int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
if (!lif->phc || !lif->phc->ptp)
return -EOPNOTSUPP;
- if (ifr) {
- if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
- return -EFAULT;
+ mutex_lock(&lif->phc->config_lock);
+
+ if (new_ts) {
+ config = new_ts;
} else {
- /* if called with ifr == NULL, behave as if called with the
- * current ts_config from the initial cleared state.
+ /* If called with new_ts == NULL, replay the previous request
+ * primarily for recovery after a FW_RESET.
+ * We saved the previous configuration request info, so copy
+ * the previous request for reference, clear the current state
+ * to match the device's reset state, and run with it.
*/
- memcpy(&config, &lif->phc->ts_config, sizeof(config));
- memset(&lif->phc->ts_config, 0, sizeof(config));
+ config = &ts;
+ memcpy(config, &lif->phc->ts_config, sizeof(*config));
+ memset(&lif->phc->ts_config, 0, sizeof(lif->phc->ts_config));
+ lif->phc->ts_config_tx_mode = 0;
+ lif->phc->ts_config_rx_filt = 0;
}
- tx_mode = ionic_hwstamp_tx_mode(config.tx_type);
- if (tx_mode < 0)
- return tx_mode;
+ tx_mode = ionic_hwstamp_tx_mode(config->tx_type);
+ if (tx_mode < 0) {
+ err = tx_mode;
+ goto err_queues;
+ }
mask = cpu_to_le64(BIT_ULL(tx_mode));
- if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask)
- return -ERANGE;
+ if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask) {
+ err = -ERANGE;
+ goto err_queues;
+ }
- rx_filt = ionic_hwstamp_rx_filt(config.rx_filter);
- rx_all = config.rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
+ rx_filt = ionic_hwstamp_rx_filt(config->rx_filter);
+ rx_all = config->rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
mask = cpu_to_le64(rx_filt);
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) != mask) {
rx_filt = 0;
rx_all = true;
- config.rx_filter = HWTSTAMP_FILTER_ALL;
+ config->rx_filter = HWTSTAMP_FILTER_ALL;
}
dev_dbg(ionic->dev, "config_rx_filter %d rx_filt %#llx rx_all %d\n",
- config.rx_filter, rx_filt, rx_all);
-
- mutex_lock(&lif->phc->config_lock);
+ config->rx_filter, rx_filt, rx_all);
if (tx_mode) {
err = ionic_lif_create_hwstamp_txq(lif);
@@ -143,15 +152,7 @@ int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
goto err_rxall;
}
- if (ifr) {
- err = copy_to_user(ifr->ifr_data, &config, sizeof(config));
- if (err) {
- err = -EFAULT;
- goto err_final;
- }
- }
-
- memcpy(&lif->phc->ts_config, &config, sizeof(config));
+ memcpy(&lif->phc->ts_config, config, sizeof(*config));
lif->phc->ts_config_rx_filt = rx_filt;
lif->phc->ts_config_tx_mode = tx_mode;
@@ -159,14 +160,6 @@ int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
return 0;
-err_final:
- if (rx_all != (lif->phc->ts_config.rx_filter == HWTSTAMP_FILTER_ALL)) {
- rx_all = lif->phc->ts_config.rx_filter == HWTSTAMP_FILTER_ALL;
- err2 = ionic_lif_config_hwstamp_rxq_all(lif, rx_all);
- if (err2)
- dev_err(ionic->dev,
- "Failed to revert all-rxq timestamp config: %d\n", err2);
- }
err_rxall:
if (rx_filt != lif->phc->ts_config_rx_filt) {
rx_filt = lif->phc->ts_config_rx_filt;
@@ -190,6 +183,37 @@ err_queues:
return err;
}
+int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
+{
+ struct hwtstamp_config config;
+ int err;
+
+ if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ err = ionic_lif_hwstamp_set_ts_config(lif, &config);
+ if (err) {
+ netdev_info(lif->netdev, "hwstamp set failed: %d\n", err);
+ return err;
+ }
+
+ if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
+ return -EFAULT;
+
+ return 0;
+}
+
+int ionic_lif_hwstamp_replay(struct ionic_lif *lif)
+{
+ int err;
+
+ err = ionic_lif_hwstamp_set_ts_config(lif, NULL);
+ if (err)
+ netdev_info(lif->netdev, "hwstamp replay failed: %d\n", err);
+
+ return err;
+}
+
int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr)
{
struct hwtstamp_config config;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 3478b0f2495f..08934888575c 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -1203,6 +1203,7 @@ static netdev_tx_t ionic_start_hwstamp_xmit(struct sk_buff *skb,
if (unlikely(!ionic_q_has_space(q, ndescs)))
goto err_out_drop;
+ skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP;
if (skb_is_gso(skb))
err = ionic_tx_tso(q, skb);
else
@@ -1233,7 +1234,7 @@ netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev)
}
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
- if (lif->hwstamp_txq)
+ if (lif->hwstamp_txq && lif->phc->ts_config_tx_mode)
return ionic_start_hwstamp_xmit(skb, netdev);
if (unlikely(queue_index >= lif->nxqs))
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index 74b64e52ffa2..bbbc6ac8fa82 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -35,6 +35,15 @@
enum {
MV_PMA_FW_VER0 = 0xc011,
MV_PMA_FW_VER1 = 0xc012,
+ MV_PMA_21X0_PORT_CTRL = 0xc04a,
+ MV_PMA_21X0_PORT_CTRL_SWRST = BIT(15),
+ MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK = 0x7,
+ MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII = 0x0,
+ MV_PMA_2180_PORT_CTRL_MACTYPE_DXGMII = 0x1,
+ MV_PMA_2180_PORT_CTRL_MACTYPE_QXGMII = 0x2,
+ MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER = 0x4,
+ MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN = 0x5,
+ MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
MV_PMA_BOOT = 0xc050,
MV_PMA_BOOT_FATAL = BIT(0),
@@ -78,10 +87,18 @@ enum {
/* Vendor2 MMD registers */
MV_V2_PORT_CTRL = 0xf001,
- MV_V2_PORT_CTRL_SWRST = BIT(15),
- MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
- MV_V2_PORT_MAC_TYPE_MASK = 0x7,
- MV_V2_PORT_MAC_TYPE_RATE_MATCH = 0x6,
+ MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
+ MV_V2_33X0_PORT_CTRL_SWRST = BIT(15),
+ MV_V2_33X0_PORT_CTRL_MACTYPE_MASK = 0x7,
+ MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI = 0x0,
+ MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH = 0x1,
+ MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN = 0x1,
+ MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH = 0x2,
+ MV_V2_3310_PORT_CTRL_MACTYPE_XAUI = 0x3,
+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER = 0x4,
+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN = 0x5,
+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
+ MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII = 0x7,
/* Temperature control/read registers (88X3310 only) */
MV_V2_TEMP_CTRL = 0xf08a,
MV_V2_TEMP_CTRL_MASK = 0xc000,
@@ -91,14 +108,32 @@ enum {
MV_V2_TEMP_UNKNOWN = 0x9600, /* unknown function */
};
+struct mv3310_chip {
+ void (*init_supported_interfaces)(unsigned long *mask);
+ int (*get_mactype)(struct phy_device *phydev);
+ int (*init_interface)(struct phy_device *phydev, int mactype);
+
+#ifdef CONFIG_HWMON
+ int (*hwmon_read_temp_reg)(struct phy_device *phydev);
+#endif
+};
+
struct mv3310_priv {
+ DECLARE_BITMAP(supported_interfaces, PHY_INTERFACE_MODE_MAX);
+
u32 firmware_ver;
bool rate_match;
+ phy_interface_t const_interface;
struct device *hwmon_dev;
char *hwmon_name;
};
+static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
+{
+ return phydev->drv->driver_data;
+}
+
#ifdef CONFIG_HWMON
static umode_t mv3310_hwmon_is_visible(const void *data,
enum hwmon_sensor_types type,
@@ -121,18 +156,11 @@ static int mv2110_hwmon_read_temp_reg(struct phy_device *phydev)
return phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_TEMP);
}
-static int mv10g_hwmon_read_temp_reg(struct phy_device *phydev)
-{
- if (phydev->drv->phy_id == MARVELL_PHY_ID_88X3310)
- return mv3310_hwmon_read_temp_reg(phydev);
- else /* MARVELL_PHY_ID_88E2110 */
- return mv2110_hwmon_read_temp_reg(phydev);
-}
-
static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *value)
{
struct phy_device *phydev = dev_get_drvdata(dev);
+ const struct mv3310_chip *chip = to_mv3310_chip(phydev);
int temp;
if (type == hwmon_chip && attr == hwmon_chip_update_interval) {
@@ -141,7 +169,7 @@ static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
}
if (type == hwmon_temp && attr == hwmon_temp_input) {
- temp = mv10g_hwmon_read_temp_reg(phydev);
+ temp = chip->hwmon_read_temp_reg(phydev);
if (temp < 0)
return temp;
@@ -268,7 +296,7 @@ static int mv3310_power_up(struct phy_device *phydev)
return ret;
return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
- MV_V2_PORT_CTRL_SWRST);
+ MV_V2_33X0_PORT_CTRL_SWRST);
}
static int mv3310_reset(struct phy_device *phydev, u32 unit)
@@ -363,6 +391,7 @@ static const struct sfp_upstream_ops mv3310_sfp_ops = {
static int mv3310_probe(struct phy_device *phydev)
{
+ const struct mv3310_chip *chip = to_mv3310_chip(phydev);
struct mv3310_priv *priv;
u32 mmd_mask = MDIO_DEVS_PMAPMD | MDIO_DEVS_AN;
int ret;
@@ -412,6 +441,8 @@ static int mv3310_probe(struct phy_device *phydev)
if (ret)
return ret;
+ chip->init_supported_interfaces(priv->supported_interfaces);
+
return phy_sfp_probe(phydev, &mv3310_sfp_ops);
}
@@ -453,18 +484,102 @@ static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev)
MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV;
}
+static int mv2110_get_mactype(struct phy_device *phydev)
+{
+ int mactype;
+
+ mactype = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_21X0_PORT_CTRL);
+ if (mactype < 0)
+ return mactype;
+
+ return mactype & MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK;
+}
+
+static int mv3310_get_mactype(struct phy_device *phydev)
+{
+ int mactype;
+
+ mactype = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
+ if (mactype < 0)
+ return mactype;
+
+ return mactype & MV_V2_33X0_PORT_CTRL_MACTYPE_MASK;
+}
+
+static int mv2110_init_interface(struct phy_device *phydev, int mactype)
+{
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
+
+ priv->rate_match = false;
+
+ if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
+ priv->rate_match = true;
+
+ if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII)
+ priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
+ else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
+ priv->const_interface = PHY_INTERFACE_MODE_10GBASER;
+ else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER ||
+ mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN)
+ priv->const_interface = PHY_INTERFACE_MODE_NA;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static int mv3310_init_interface(struct phy_device *phydev, int mactype)
+{
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
+
+ priv->rate_match = false;
+
+ if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
+ mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH)
+ priv->rate_match = true;
+
+ if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII)
+ priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
+ else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN ||
+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER)
+ priv->const_interface = PHY_INTERFACE_MODE_10GBASER;
+ else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI)
+ priv->const_interface = PHY_INTERFACE_MODE_RXAUI;
+ else if (mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH ||
+ mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI)
+ priv->const_interface = PHY_INTERFACE_MODE_XAUI;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static int mv3340_init_interface(struct phy_device *phydev, int mactype)
+{
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
+ int err = 0;
+
+ priv->rate_match = false;
+
+ if (mactype == MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN)
+ priv->const_interface = PHY_INTERFACE_MODE_RXAUI;
+ else
+ err = mv3310_init_interface(phydev, mactype);
+
+ return err;
+}
+
static int mv3310_config_init(struct phy_device *phydev)
{
struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
- int err;
- int val;
+ const struct mv3310_chip *chip = to_mv3310_chip(phydev);
+ int err, mactype;
/* Check that the PHY interface type is compatible */
- if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
- phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
- phydev->interface != PHY_INTERFACE_MODE_XAUI &&
- phydev->interface != PHY_INTERFACE_MODE_RXAUI &&
- phydev->interface != PHY_INTERFACE_MODE_10GBASER)
+ if (!test_bit(phydev->interface, priv->supported_interfaces))
return -ENODEV;
phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
@@ -474,11 +589,15 @@ static int mv3310_config_init(struct phy_device *phydev)
if (err)
return err;
- val = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
- if (val < 0)
- return val;
- priv->rate_match = ((val & MV_V2_PORT_MAC_TYPE_MASK) ==
- MV_V2_PORT_MAC_TYPE_RATE_MATCH);
+ mactype = chip->get_mactype(phydev);
+ if (mactype < 0)
+ return mactype;
+
+ err = chip->init_interface(phydev, mactype);
+ if (err) {
+ phydev_err(phydev, "MACTYPE configuration invalid\n");
+ return err;
+ }
/* Enable EDPD mode - saving 600mW */
return mv3310_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS);
@@ -588,40 +707,44 @@ static void mv3310_update_interface(struct phy_device *phydev)
{
struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
- /* In "XFI with Rate Matching" mode the PHY interface is fixed at
- * 10Gb. The PHY adapts the rate to actual wire speed with help of
+ if (!phydev->link)
+ return;
+
+ /* In all of the "* with Rate Matching" modes the PHY interface is fixed
+ * at 10Gb. The PHY adapts the rate to actual wire speed with help of
* internal 16KB buffer.
+ *
+ * In USXGMII mode the PHY interface mode is also fixed.
*/
- if (priv->rate_match) {
- phydev->interface = PHY_INTERFACE_MODE_10GBASER;
+ if (priv->rate_match ||
+ priv->const_interface == PHY_INTERFACE_MODE_USXGMII) {
+ phydev->interface = priv->const_interface;
return;
}
- if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
- phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
- phydev->interface == PHY_INTERFACE_MODE_10GBASER) &&
- phydev->link) {
- /* The PHY automatically switches its serdes interface (and
- * active PHYXS instance) between Cisco SGMII, 10GBase-R and
- * 2500BaseX modes according to the speed. Florian suggests
- * setting phydev->interface to communicate this to the MAC.
- * Only do this if we are already in one of the above modes.
- */
- switch (phydev->speed) {
- case SPEED_10000:
- phydev->interface = PHY_INTERFACE_MODE_10GBASER;
- break;
- case SPEED_2500:
- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
- break;
- case SPEED_1000:
- case SPEED_100:
- case SPEED_10:
- phydev->interface = PHY_INTERFACE_MODE_SGMII;
- break;
- default:
- break;
- }
+ /* The PHY automatically switches its serdes interface (and active PHYXS
+ * instance) between Cisco SGMII, 2500BaseX, 5GBase-R and 10GBase-R /
+ * xaui / rxaui modes according to the speed.
+ * Florian suggests setting phydev->interface to communicate this to the
+ * MAC. Only do this if we are already in one of the above modes.
+ */
+ switch (phydev->speed) {
+ case SPEED_10000:
+ phydev->interface = priv->const_interface;
+ break;
+ case SPEED_5000:
+ phydev->interface = PHY_INTERFACE_MODE_5GBASER;
+ break;
+ case SPEED_2500:
+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
+ break;
+ case SPEED_1000:
+ case SPEED_100:
+ case SPEED_10:
+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
+ break;
+ default:
+ break;
}
}
@@ -765,11 +888,133 @@ static int mv3310_set_tunable(struct phy_device *phydev,
}
}
+static void mv3310_init_supported_interfaces(unsigned long *mask)
+{
+ __set_bit(PHY_INTERFACE_MODE_SGMII, mask);
+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, mask);
+ __set_bit(PHY_INTERFACE_MODE_5GBASER, mask);
+ __set_bit(PHY_INTERFACE_MODE_XAUI, mask);
+ __set_bit(PHY_INTERFACE_MODE_RXAUI, mask);
+ __set_bit(PHY_INTERFACE_MODE_10GBASER, mask);
+ __set_bit(PHY_INTERFACE_MODE_USXGMII, mask);
+}
+
+static void mv3340_init_supported_interfaces(unsigned long *mask)
+{
+ __set_bit(PHY_INTERFACE_MODE_SGMII, mask);
+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, mask);
+ __set_bit(PHY_INTERFACE_MODE_5GBASER, mask);
+ __set_bit(PHY_INTERFACE_MODE_RXAUI, mask);
+ __set_bit(PHY_INTERFACE_MODE_10GBASER, mask);
+ __set_bit(PHY_INTERFACE_MODE_USXGMII, mask);
+}
+
+static void mv2110_init_supported_interfaces(unsigned long *mask)
+{
+ __set_bit(PHY_INTERFACE_MODE_SGMII, mask);
+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, mask);
+ __set_bit(PHY_INTERFACE_MODE_5GBASER, mask);
+ __set_bit(PHY_INTERFACE_MODE_10GBASER, mask);
+ __set_bit(PHY_INTERFACE_MODE_USXGMII, mask);
+}
+
+static void mv2111_init_supported_interfaces(unsigned long *mask)
+{
+ __set_bit(PHY_INTERFACE_MODE_SGMII, mask);
+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, mask);
+ __set_bit(PHY_INTERFACE_MODE_10GBASER, mask);
+ __set_bit(PHY_INTERFACE_MODE_USXGMII, mask);
+}
+
+static const struct mv3310_chip mv3310_type = {
+ .init_supported_interfaces = mv3310_init_supported_interfaces,
+ .get_mactype = mv3310_get_mactype,
+ .init_interface = mv3310_init_interface,
+
+#ifdef CONFIG_HWMON
+ .hwmon_read_temp_reg = mv3310_hwmon_read_temp_reg,
+#endif
+};
+
+static const struct mv3310_chip mv3340_type = {
+ .init_supported_interfaces = mv3340_init_supported_interfaces,
+ .get_mactype = mv3310_get_mactype,
+ .init_interface = mv3340_init_interface,
+
+#ifdef CONFIG_HWMON
+ .hwmon_read_temp_reg = mv3310_hwmon_read_temp_reg,
+#endif
+};
+
+static const struct mv3310_chip mv2110_type = {
+ .init_supported_interfaces = mv2110_init_supported_interfaces,
+ .get_mactype = mv2110_get_mactype,
+ .init_interface = mv2110_init_interface,
+
+#ifdef CONFIG_HWMON
+ .hwmon_read_temp_reg = mv2110_hwmon_read_temp_reg,
+#endif
+};
+
+static const struct mv3310_chip mv2111_type = {
+ .init_supported_interfaces = mv2111_init_supported_interfaces,
+ .get_mactype = mv2110_get_mactype,
+ .init_interface = mv2110_init_interface,
+
+#ifdef CONFIG_HWMON
+ .hwmon_read_temp_reg = mv2110_hwmon_read_temp_reg,
+#endif
+};
+
+static int mv211x_match_phy_device(struct phy_device *phydev, bool has_5g)
+{
+ int val;
+
+ if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
+ MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88E2110)
+ return 0;
+
+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_SPEED);
+ if (val < 0)
+ return val;
+
+ return !!(val & MDIO_PCS_SPEED_5G) == has_5g;
+}
+
+static int mv2110_match_phy_device(struct phy_device *phydev)
+{
+ return mv211x_match_phy_device(phydev, true);
+}
+
+static int mv2111_match_phy_device(struct phy_device *phydev)
+{
+ return mv211x_match_phy_device(phydev, false);
+}
+
static struct phy_driver mv3310_drivers[] = {
{
.phy_id = MARVELL_PHY_ID_88X3310,
- .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .phy_id_mask = MARVELL_PHY_ID_88X33X0_MASK,
.name = "mv88x3310",
+ .driver_data = &mv3310_type,
+ .get_features = mv3310_get_features,
+ .config_init = mv3310_config_init,
+ .probe = mv3310_probe,
+ .suspend = mv3310_suspend,
+ .resume = mv3310_resume,
+ .config_aneg = mv3310_config_aneg,
+ .aneg_done = mv3310_aneg_done,
+ .read_status = mv3310_read_status,
+ .get_tunable = mv3310_get_tunable,
+ .set_tunable = mv3310_set_tunable,
+ .remove = mv3310_remove,
+ .set_loopback = genphy_c45_loopback,
+ },
+ {
+ .phy_id = MARVELL_PHY_ID_88X3340,
+ .phy_id_mask = MARVELL_PHY_ID_88X33X0_MASK,
+ .name = "mv88x3340",
+ .driver_data = &mv3340_type,
.get_features = mv3310_get_features,
.config_init = mv3310_config_init,
.probe = mv3310_probe,
@@ -786,7 +1031,27 @@ static struct phy_driver mv3310_drivers[] = {
{
.phy_id = MARVELL_PHY_ID_88E2110,
.phy_id_mask = MARVELL_PHY_ID_MASK,
- .name = "mv88x2110",
+ .match_phy_device = mv2110_match_phy_device,
+ .name = "mv88e2110",
+ .driver_data = &mv2110_type,
+ .probe = mv3310_probe,
+ .suspend = mv3310_suspend,
+ .resume = mv3310_resume,
+ .config_init = mv3310_config_init,
+ .config_aneg = mv3310_config_aneg,
+ .aneg_done = mv3310_aneg_done,
+ .read_status = mv3310_read_status,
+ .get_tunable = mv3310_get_tunable,
+ .set_tunable = mv3310_set_tunable,
+ .remove = mv3310_remove,
+ .set_loopback = genphy_c45_loopback,
+ },
+ {
+ .phy_id = MARVELL_PHY_ID_88E2110,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .match_phy_device = mv2111_match_phy_device,
+ .name = "mv88e2111",
+ .driver_data = &mv2111_type,
.probe = mv3310_probe,
.suspend = mv3310_suspend,
.resume = mv3310_resume,
@@ -804,10 +1069,11 @@ static struct phy_driver mv3310_drivers[] = {
module_phy_driver(mv3310_drivers);
static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
- { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_88X33X0_MASK },
+ { MARVELL_PHY_ID_88X3340, MARVELL_PHY_ID_88X33X0_MASK },
{ MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK },
{ },
};
MODULE_DEVICE_TABLE(mdio, mv3310_tbl);
-MODULE_DESCRIPTION("Marvell Alaska X 10Gigabit Ethernet PHY driver (MV88X3310)");
+MODULE_DESCRIPTION("Marvell Alaska X/M multi-gigabit Ethernet PHY driver");
MODULE_LICENSE("GPL");
diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h
index 274abd5fbac3..6b11a5411082 100644
--- a/include/linux/marvell_phy.h
+++ b/include/linux/marvell_phy.h
@@ -22,10 +22,14 @@
#define MARVELL_PHY_ID_88E1545 0x01410ea0
#define MARVELL_PHY_ID_88E1548P 0x01410ec0
#define MARVELL_PHY_ID_88E3016 0x01410e60
-#define MARVELL_PHY_ID_88X3310 0x002b09a0
#define MARVELL_PHY_ID_88E2110 0x002b09b0
#define MARVELL_PHY_ID_88X2222 0x01410f10
+/* PHY IDs and mask for Alaska 10G PHYs */
+#define MARVELL_PHY_ID_88X33X0_MASK 0xfffffff8
+#define MARVELL_PHY_ID_88X3310 0x002b09a0
+#define MARVELL_PHY_ID_88X3340 0x002b09a8
+
/* Marvel 88E1111 in Finisar SFP module with modified PHY ID */
#define MARVELL_PHY_ID_88E1111_FINISAR 0x01ff0cc0
diff --git a/include/linux/qed/qed_ll2_if.h b/include/linux/qed/qed_ll2_if.h
index 2f64ed79cee9..ea273ba1c991 100644
--- a/include/linux/qed/qed_ll2_if.h
+++ b/include/linux/qed/qed_ll2_if.h
@@ -12,7 +12,6 @@
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/skbuff.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/qed/qed_if.h>
diff --git a/include/uapi/linux/mdio.h b/include/uapi/linux/mdio.h
index 3f302e2523b2..bdf77dffa5a4 100644
--- a/include/uapi/linux/mdio.h
+++ b/include/uapi/linux/mdio.h
@@ -120,6 +120,8 @@
#define MDIO_PMA_SPEED_100 0x0020 /* 100M capable */
#define MDIO_PMA_SPEED_10 0x0040 /* 10M capable */
#define MDIO_PCS_SPEED_10P2B 0x0002 /* 10PASS-TS/2BASE-TL capable */
+#define MDIO_PCS_SPEED_2_5G 0x0040 /* 2.5G capable */
+#define MDIO_PCS_SPEED_5G 0x0080 /* 5G capable */
/* Device present registers. */
#define MDIO_DEVS_PRESENT(devad) (1 << (devad))
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index a5e313cd6f44..789f257be24f 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -456,7 +456,7 @@ batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
* if:
*
* - the send time is within our MAX_AGGREGATION_MS time
- * - the resulting packet wont be bigger than
+ * - the resulting packet won't be bigger than
* MAX_AGGREGATION_BYTES
* otherwise aggregation is not possible
*/
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index bcd543ce835b..7dc133cfc363 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -25,7 +25,6 @@
#include <linux/lockdep.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
-#include <linux/preempt.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/skbuff.h>
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 7c0b475cc22a..2be5d4a712c5 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1659,19 +1659,19 @@ struct batadv_priv {
/** @tp_list: list of tp sessions */
struct hlist_head tp_list;
- /** @tp_num: number of currently active tp sessions */
+ /** @orig_hash: hash table containing mesh participants (orig nodes) */
struct batadv_hashtable *orig_hash;
- /** @orig_hash: hash table containing mesh participants (orig nodes) */
+ /** @forw_bat_list_lock: lock protecting forw_bat_list */
spinlock_t forw_bat_list_lock;
- /** @forw_bat_list_lock: lock protecting forw_bat_list */
+ /** @forw_bcast_list_lock: lock protecting forw_bcast_list */
spinlock_t forw_bcast_list_lock;
- /** @forw_bcast_list_lock: lock protecting forw_bcast_list */
+ /** @tp_list_lock: spinlock protecting @tp_list */
spinlock_t tp_list_lock;
- /** @tp_list_lock: spinlock protecting @tp_list */
+ /** @tp_num: number of currently active tp sessions */
atomic_t tp_num;
/** @orig_work: work queue callback item for orig node purging */
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/simple.json b/tools/testing/selftests/tc-testing/tc-tests/actions/simple.json
index e15f708b0fa4..e0c5f060ccb9 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/actions/simple.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/simple.json
@@ -175,5 +175,64 @@
"teardown": [
"$TC actions flush action simple"
]
+ },
+ {
+ "id": "8d07",
+ "name": "Verify cleanup of failed actions batch add",
+ "category": [
+ "actions",
+ "simple"
+ ],
+ "setup": [
+ [
+ "$TC actions flush action simple",
+ 0,
+ 1,
+ 255
+ ],
+ "$TC actions add action simple sdata \"2\" index 2",
+ [
+ "$TC actions add action simple sdata \"1\" index 1 action simple sdata \"2\" index 2",
+ 255
+ ],
+ "$TC actions flush action simple"
+ ],
+ "cmdUnderTest": "$TC actions add action simple sdata \"2\" index 2",
+ "expExitCode": "0",
+ "verifyCmd": "$TC actions list action simple",
+ "matchPattern": "action order [0-9]*: Simple <2>.*index 2 ref",
+ "matchCount": "1",
+ "teardown": [
+ "$TC actions flush action simple"
+ ]
+ },
+ {
+ "id": "a68a",
+ "name": "Verify cleanup of failed actions batch change",
+ "category": [
+ "actions",
+ "simple"
+ ],
+ "setup": [
+ [
+ "$TC actions flush action simple",
+ 0,
+ 1,
+ 255
+ ],
+ [
+ "$TC actions change action simple sdata \"1\" index 1 action simple sdata \"2\" goto chain 42 index 2",
+ 255
+ ],
+ "$TC actions flush action simple"
+ ],
+ "cmdUnderTest": "$TC actions add action simple sdata \"1\" index 1",
+ "expExitCode": "0",
+ "verifyCmd": "$TC actions list action simple",
+ "matchPattern": "action order [0-9]*: Simple <1>.*index 1 ref",
+ "matchCount": "1",
+ "teardown": [
+ "$TC actions flush action simple"
+ ]
}
]