Skip to content

Commit

Permalink
mlxsw: pci: PTP: Hook into packet transmit path
Browse files Browse the repository at this point in the history
On Spectrum-1, timestamps are delivered separately from the packets, and
need to paired up. Therefore, at some point after mlxsw_sp_port_xmit()
is invoked, it is necessary to involve the chip-specific driver code to
allow it to do the necessary bookkeeping and matching.

On Spectrum-2, timestamps are delivered in CQE. For that reason,
position the point of driver involvement into mlxsw_pci_cqe_sdq_handle()
to make it hopefully easier to extend for Spectrum-2 in the future.

To tell the driver what port the packet was sent on, keep tx_info
in SKB control buffer.

Introduce a new driver core interface mlxsw_core_ptp_transmitted(), a
driver callback ptp_transmitted, and a PTP op transmitted. The callee is
responsible for taking care of releasing the SKB passed to the new
interfaces, and correspondingly have the new stub callbacks just call
dev_kfree_skb_any().

Follow-up patches will introduce the actual content into
mlxsw_sp1_ptp_transmitted() in particular.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Petr Machata authored and David S. Miller committed Jul 2, 2019
1 parent d7cd206 commit 0714256
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 1 deletion.
9 changes: 9 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,15 @@ int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
}
EXPORT_SYMBOL(mlxsw_core_skb_transmit);

void mlxsw_core_ptp_transmitted(struct mlxsw_core *mlxsw_core,
struct sk_buff *skb, u8 local_port)
{
if (mlxsw_core->driver->ptp_transmitted)
mlxsw_core->driver->ptp_transmitted(mlxsw_core, skb,
local_port);
}
EXPORT_SYMBOL(mlxsw_core_ptp_transmitted);

static bool __is_rx_listener_equal(const struct mlxsw_rx_listener *rxl_a,
const struct mlxsw_rx_listener *rxl_b)
{
Expand Down
10 changes: 10 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ bool mlxsw_core_skb_transmit_busy(struct mlxsw_core *mlxsw_core,
const struct mlxsw_tx_info *tx_info);
int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
const struct mlxsw_tx_info *tx_info);
void mlxsw_core_ptp_transmitted(struct mlxsw_core *mlxsw_core,
struct sk_buff *skb, u8 local_port);

struct mlxsw_rx_listener {
void (*func)(struct sk_buff *skb, u8 local_port, void *priv);
Expand Down Expand Up @@ -296,6 +298,13 @@ struct mlxsw_driver {
u64 *p_linear_size);
int (*params_register)(struct mlxsw_core *mlxsw_core);
void (*params_unregister)(struct mlxsw_core *mlxsw_core);

/* Notify a driver that a timestamped packet was transmitted. Driver
* is responsible for freeing the passed-in SKB.
*/
void (*ptp_transmitted)(struct mlxsw_core *mlxsw_core,
struct sk_buff *skb, u8 local_port);

u8 txhdr_len;
const struct mlxsw_config_profile *profile;
bool res_query_enabled;
Expand Down Expand Up @@ -419,6 +428,7 @@ enum mlxsw_devlink_param_id {
};

struct mlxsw_skb_cb {
struct mlxsw_tx_info tx_info;
};

static inline struct mlxsw_skb_cb *mlxsw_skb_cb(struct sk_buff *skb)
Expand Down
17 changes: 16 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,17 +508,28 @@ static void mlxsw_pci_cqe_sdq_handle(struct mlxsw_pci *mlxsw_pci,
{
struct pci_dev *pdev = mlxsw_pci->pdev;
struct mlxsw_pci_queue_elem_info *elem_info;
struct mlxsw_tx_info tx_info;
char *wqe;
struct sk_buff *skb;
int i;

spin_lock(&q->lock);
elem_info = mlxsw_pci_queue_elem_info_consumer_get(q);
tx_info = mlxsw_skb_cb(elem_info->u.sdq.skb)->tx_info;
skb = elem_info->u.sdq.skb;
wqe = elem_info->elem;
for (i = 0; i < MLXSW_PCI_WQE_SG_ENTRIES; i++)
mlxsw_pci_wqe_frag_unmap(mlxsw_pci, wqe, i, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);

if (unlikely(!tx_info.is_emad &&
skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
mlxsw_core_ptp_transmitted(mlxsw_pci->core, skb,
tx_info.local_port);
skb = NULL;
}

if (skb)
dev_kfree_skb_any(skb);
elem_info->u.sdq.skb = NULL;

if (q->consumer_counter++ != consumer_counter_limit)
Expand Down Expand Up @@ -1548,6 +1559,7 @@ static int mlxsw_pci_skb_transmit(void *bus_priv, struct sk_buff *skb,
err = -EAGAIN;
goto unlock;
}
mlxsw_skb_cb(skb)->tx_info = *tx_info;
elem_info->u.sdq.skb = skb;

wqe = elem_info->elem;
Expand All @@ -1571,6 +1583,9 @@ static int mlxsw_pci_skb_transmit(void *bus_priv, struct sk_buff *skb,
goto unmap_frags;
}

if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;

/* Set unused sq entries byte count to zero. */
for (i++; i < MLXSW_PCI_WQE_SG_ENTRIES; i++)
mlxsw_pci_wqe_byte_count_set(wqe, i, 0);
Expand Down
19 changes: 19 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ struct mlxsw_sp_ptp_ops {
*/
void (*receive)(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
u8 local_port);

/* Notify a driver that a timestamped packet was transmitted. Driver
* is responsible for freeing the passed-in SKB.
*/
void (*transmitted)(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
u8 local_port);
};

static int mlxsw_sp_component_query(struct mlxfw_dev *mlxfw_dev,
Expand Down Expand Up @@ -4424,12 +4430,14 @@ static const struct mlxsw_sp_ptp_ops mlxsw_sp1_ptp_ops = {
.clock_init = mlxsw_sp1_ptp_clock_init,
.clock_fini = mlxsw_sp1_ptp_clock_fini,
.receive = mlxsw_sp1_ptp_receive,
.transmitted = mlxsw_sp1_ptp_transmitted,
};

static const struct mlxsw_sp_ptp_ops mlxsw_sp2_ptp_ops = {
.clock_init = mlxsw_sp2_ptp_clock_init,
.clock_fini = mlxsw_sp2_ptp_clock_fini,
.receive = mlxsw_sp2_ptp_receive,
.transmitted = mlxsw_sp2_ptp_transmitted,
};

static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
Expand Down Expand Up @@ -4995,6 +5003,15 @@ static void mlxsw_sp2_params_unregister(struct mlxsw_core *mlxsw_core)
mlxsw_sp_params_unregister(mlxsw_core);
}

static void mlxsw_sp_ptp_transmitted(struct mlxsw_core *mlxsw_core,
struct sk_buff *skb, u8 local_port)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);

skb_pull(skb, MLXSW_TXHDR_LEN);
mlxsw_sp->ptp_ops->transmitted(mlxsw_sp, skb, local_port);
}

static struct mlxsw_driver mlxsw_sp1_driver = {
.kind = mlxsw_sp1_driver_name,
.priv_size = sizeof(struct mlxsw_sp),
Expand All @@ -5019,6 +5036,7 @@ static struct mlxsw_driver mlxsw_sp1_driver = {
.kvd_sizes_get = mlxsw_sp_kvd_sizes_get,
.params_register = mlxsw_sp_params_register,
.params_unregister = mlxsw_sp_params_unregister,
.ptp_transmitted = mlxsw_sp_ptp_transmitted,
.txhdr_len = MLXSW_TXHDR_LEN,
.profile = &mlxsw_sp1_config_profile,
.res_query_enabled = true,
Expand Down Expand Up @@ -5047,6 +5065,7 @@ static struct mlxsw_driver mlxsw_sp2_driver = {
.resources_register = mlxsw_sp2_resources_register,
.params_register = mlxsw_sp2_params_register,
.params_unregister = mlxsw_sp2_params_unregister,
.ptp_transmitted = mlxsw_sp_ptp_transmitted,
.txhdr_len = MLXSW_TXHDR_LEN,
.profile = &mlxsw_sp2_config_profile,
.res_query_enabled = true,
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,9 @@ void mlxsw_sp1_ptp_receive(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
{
mlxsw_sp_rx_listener_no_mark_func(skb, local_port, mlxsw_sp);
}

void mlxsw_sp1_ptp_transmitted(struct mlxsw_sp *mlxsw_sp,
struct sk_buff *skb, u8 local_port)
{
dev_kfree_skb_any(skb);
}
15 changes: 15 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ void mlxsw_sp1_ptp_clock_fini(struct mlxsw_sp_ptp_clock *clock);
void mlxsw_sp1_ptp_receive(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
u8 local_port);

void mlxsw_sp1_ptp_transmitted(struct mlxsw_sp *mlxsw_sp,
struct sk_buff *skb, u8 local_port);

#else

static inline struct mlxsw_sp_ptp_clock *
Expand All @@ -38,6 +41,12 @@ static inline void mlxsw_sp1_ptp_receive(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_rx_listener_no_mark_func(skb, local_port, mlxsw_sp);
}

static inline void mlxsw_sp1_ptp_transmitted(struct mlxsw_sp *mlxsw_sp,
struct sk_buff *skb, u8 local_port)
{
dev_kfree_skb_any(skb);
}

#endif

static inline struct mlxsw_sp_ptp_clock *
Expand All @@ -56,4 +65,10 @@ static inline void mlxsw_sp2_ptp_receive(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_rx_listener_no_mark_func(skb, local_port, mlxsw_sp);
}

static inline void mlxsw_sp2_ptp_transmitted(struct mlxsw_sp *mlxsw_sp,
struct sk_buff *skb, u8 local_port)
{
dev_kfree_skb_any(skb);
}

#endif

0 comments on commit 0714256

Please sign in to comment.