Merge branch 'ionic-hwtstamp-tweaks'
Shannon Nelson says: ==================== ionic: hwstamp tweaks A few little changes after review comments and additional internal testing. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
c69b67185c
|
@ -135,7 +135,7 @@ static void ionic_link_status_check(struct ionic_lif *lif)
|
||||||
if (netdev->flags & IFF_UP && netif_running(netdev)) {
|
if (netdev->flags & IFF_UP && netif_running(netdev)) {
|
||||||
mutex_lock(&lif->queue_lock);
|
mutex_lock(&lif->queue_lock);
|
||||||
err = ionic_start_queues(lif);
|
err = ionic_start_queues(lif);
|
||||||
if (err) {
|
if (err && err != -EBUSY) {
|
||||||
netdev_err(lif->netdev,
|
netdev_err(lif->netdev,
|
||||||
"Failed to start queues: %d\n", err);
|
"Failed to start queues: %d\n", err);
|
||||||
set_bit(IONIC_LIF_F_BROKEN, lif->state);
|
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)
|
static int ionic_txrx_alloc(struct ionic_lif *lif)
|
||||||
{
|
{
|
||||||
unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
|
unsigned int comp_sz, desc_sz, num_desc, sg_desc_sz;
|
||||||
unsigned int flags;
|
unsigned int flags, i;
|
||||||
unsigned int i;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
num_desc = lif->ntxq_descs;
|
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,
|
int ionic_reconfigure_queues(struct ionic_lif *lif,
|
||||||
struct ionic_queue_params *qparam)
|
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 **tx_qcqs = NULL;
|
||||||
struct ionic_qcq **rx_qcqs = NULL;
|
struct ionic_qcq **rx_qcqs = NULL;
|
||||||
unsigned int flags;
|
unsigned int flags, i;
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
/* allocate temporary qcq arrays to hold new queue structs */
|
/* allocate temporary qcq arrays to hold new queue structs */
|
||||||
if (qparam->nxqs != lif->nxqs || qparam->ntxq_descs != lif->ntxq_descs) {
|
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;
|
goto err_txrx_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* restore the hardware timestamping queues */
|
|
||||||
ionic_lif_hwstamp_set(lif, NULL);
|
|
||||||
|
|
||||||
clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
|
clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
|
||||||
ionic_link_status_check_request(lif, CAN_SLEEP);
|
ionic_link_status_check_request(lif, CAN_SLEEP);
|
||||||
netif_device_attach(lif->netdev);
|
netif_device_attach(lif->netdev);
|
||||||
dev_info(ionic->dev, "FW Up: LIFs restarted\n");
|
dev_info(ionic->dev, "FW Up: LIFs restarted\n");
|
||||||
|
|
||||||
|
/* restore the hardware timestamping queues */
|
||||||
|
ionic_lif_hwstamp_replay(lif);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err_txrx_free:
|
err_txrx_free:
|
||||||
|
|
|
@ -302,6 +302,7 @@ int ionic_lif_identify(struct ionic *ionic, u8 lif_type,
|
||||||
int ionic_lif_size(struct ionic *ionic);
|
int ionic_lif_size(struct ionic *ionic);
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
|
#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_set(struct ionic_lif *lif, struct ifreq *ifr);
|
||||||
int ionic_lif_hwstamp_get(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);
|
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_alloc_phc(struct ionic_lif *lif);
|
||||||
void ionic_lif_free_phc(struct ionic_lif *lif);
|
void ionic_lif_free_phc(struct ionic_lif *lif);
|
||||||
#else
|
#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)
|
static inline int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
|
@ -18,10 +18,8 @@ static int ionic_hwstamp_tx_mode(int config_tx_type)
|
||||||
return IONIC_TXSTAMP_ON;
|
return IONIC_TXSTAMP_ON;
|
||||||
case HWTSTAMP_TX_ONESTEP_SYNC:
|
case HWTSTAMP_TX_ONESTEP_SYNC:
|
||||||
return IONIC_TXSTAMP_ONESTEP_SYNC;
|
return IONIC_TXSTAMP_ONESTEP_SYNC;
|
||||||
#ifdef HAVE_HWSTAMP_TX_ONESTEP_P2P
|
|
||||||
case HWTSTAMP_TX_ONESTEP_P2P:
|
case HWTSTAMP_TX_ONESTEP_P2P:
|
||||||
return IONIC_TXSTAMP_ONESTEP_P2P;
|
return IONIC_TXSTAMP_ONESTEP_P2P;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
return -ERANGE;
|
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 ionic *ionic = lif->ionic;
|
||||||
struct hwtstamp_config config;
|
struct hwtstamp_config *config;
|
||||||
|
struct hwtstamp_config ts;
|
||||||
int tx_mode = 0;
|
int tx_mode = 0;
|
||||||
u64 rx_filt = 0;
|
u64 rx_filt = 0;
|
||||||
int err, err2;
|
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)
|
if (!lif->phc || !lif->phc->ptp)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (ifr) {
|
mutex_lock(&lif->phc->config_lock);
|
||||||
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
|
||||||
return -EFAULT;
|
if (new_ts) {
|
||||||
|
config = new_ts;
|
||||||
} else {
|
} else {
|
||||||
/* if called with ifr == NULL, behave as if called with the
|
/* If called with new_ts == NULL, replay the previous request
|
||||||
* current ts_config from the initial cleared state.
|
* 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));
|
config = &ts;
|
||||||
memset(&lif->phc->ts_config, 0, sizeof(config));
|
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);
|
tx_mode = ionic_hwstamp_tx_mode(config->tx_type);
|
||||||
if (tx_mode < 0)
|
if (tx_mode < 0) {
|
||||||
return tx_mode;
|
err = tx_mode;
|
||||||
|
goto err_queues;
|
||||||
|
}
|
||||||
|
|
||||||
mask = cpu_to_le64(BIT_ULL(tx_mode));
|
mask = cpu_to_le64(BIT_ULL(tx_mode));
|
||||||
if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask)
|
if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask) {
|
||||||
return -ERANGE;
|
err = -ERANGE;
|
||||||
|
goto err_queues;
|
||||||
|
}
|
||||||
|
|
||||||
rx_filt = ionic_hwstamp_rx_filt(config.rx_filter);
|
rx_filt = ionic_hwstamp_rx_filt(config->rx_filter);
|
||||||
rx_all = config.rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
|
rx_all = config->rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
|
||||||
|
|
||||||
mask = cpu_to_le64(rx_filt);
|
mask = cpu_to_le64(rx_filt);
|
||||||
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) != mask) {
|
if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) != mask) {
|
||||||
rx_filt = 0;
|
rx_filt = 0;
|
||||||
rx_all = true;
|
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",
|
dev_dbg(ionic->dev, "config_rx_filter %d rx_filt %#llx rx_all %d\n",
|
||||||
config.rx_filter, rx_filt, rx_all);
|
config->rx_filter, rx_filt, rx_all);
|
||||||
|
|
||||||
mutex_lock(&lif->phc->config_lock);
|
|
||||||
|
|
||||||
if (tx_mode) {
|
if (tx_mode) {
|
||||||
err = ionic_lif_create_hwstamp_txq(lif);
|
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;
|
goto err_rxall;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifr) {
|
memcpy(&lif->phc->ts_config, config, sizeof(*config));
|
||||||
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));
|
|
||||||
lif->phc->ts_config_rx_filt = rx_filt;
|
lif->phc->ts_config_rx_filt = rx_filt;
|
||||||
lif->phc->ts_config_tx_mode = tx_mode;
|
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;
|
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:
|
err_rxall:
|
||||||
if (rx_filt != lif->phc->ts_config_rx_filt) {
|
if (rx_filt != lif->phc->ts_config_rx_filt) {
|
||||||
rx_filt = lif->phc->ts_config_rx_filt;
|
rx_filt = lif->phc->ts_config_rx_filt;
|
||||||
|
@ -190,6 +183,37 @@ err_queues:
|
||||||
return err;
|
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)
|
int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
struct hwtstamp_config config;
|
struct hwtstamp_config config;
|
||||||
|
|
|
@ -1203,6 +1203,7 @@ static netdev_tx_t ionic_start_hwstamp_xmit(struct sk_buff *skb,
|
||||||
if (unlikely(!ionic_q_has_space(q, ndescs)))
|
if (unlikely(!ionic_q_has_space(q, ndescs)))
|
||||||
goto err_out_drop;
|
goto err_out_drop;
|
||||||
|
|
||||||
|
skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP;
|
||||||
if (skb_is_gso(skb))
|
if (skb_is_gso(skb))
|
||||||
err = ionic_tx_tso(q, skb);
|
err = ionic_tx_tso(q, skb);
|
||||||
else
|
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 (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);
|
return ionic_start_hwstamp_xmit(skb, netdev);
|
||||||
|
|
||||||
if (unlikely(queue_index >= lif->nxqs))
|
if (unlikely(queue_index >= lif->nxqs))
|
||||||
|
|
Loading…
Reference in New Issue