Commit 3af760e4 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'fix-circular-dependency-between-sja1105-and-tag_sja1105'

Vladimir Oltean says:

====================
Fix circular dependency between sja1105 and tag_sja1105

As discussed here:
https://lore.kernel.org/netdev/20210908220834.d7gmtnwrorhharna@skbuf/
DSA tagging protocols cannot use symbols exported by switch drivers.

Eliminate the two instances of that from tag_sja1105, and that allows us
to have a working setup with modules again.
====================

Re-applying to net, this was mistakenly applied to net-next,
see first Link.

Link: https://lore.kernel.org/r/20211012114044.2526146-1-vladimir.oltean@nxp.com/
Link: https://lore.kernel.org/r/20210922143726.2431036-1-vladimir.oltean@nxp.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 43a4b4db 4ac0567e
......@@ -3117,7 +3117,7 @@ static void sja1105_teardown(struct dsa_switch *ds)
sja1105_static_config_free(&priv->static_config);
}
const struct dsa_switch_ops sja1105_switch_ops = {
static const struct dsa_switch_ops sja1105_switch_ops = {
.get_tag_protocol = sja1105_get_tag_protocol,
.setup = sja1105_setup,
.teardown = sja1105_teardown,
......@@ -3166,7 +3166,6 @@ const struct dsa_switch_ops sja1105_switch_ops = {
.port_bridge_tx_fwd_offload = dsa_tag_8021q_bridge_tx_fwd_offload,
.port_bridge_tx_fwd_unoffload = dsa_tag_8021q_bridge_tx_fwd_unoffload,
};
EXPORT_SYMBOL_GPL(sja1105_switch_ops);
static const struct of_device_id sja1105_dt_ids[];
......
......@@ -64,6 +64,7 @@ enum sja1105_ptp_clk_mode {
static int sja1105_change_rxtstamping(struct sja1105_private *priv,
bool on)
{
struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
struct sja1105_general_params_entry *general_params;
struct sja1105_table *table;
......@@ -79,7 +80,7 @@ static int sja1105_change_rxtstamping(struct sja1105_private *priv,
priv->tagger_data.stampable_skb = NULL;
}
ptp_cancel_worker_sync(ptp_data->clock);
skb_queue_purge(&ptp_data->skb_txtstamp_queue);
skb_queue_purge(&tagger_data->skb_txtstamp_queue);
skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
return sja1105_static_config_reload(priv, SJA1105_RX_HWTSTAMPING);
......@@ -452,40 +453,6 @@ bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
return priv->info->rxtstamp(ds, port, skb);
}
void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, u8 ts_id,
enum sja1110_meta_tstamp dir, u64 tstamp)
{
struct sja1105_private *priv = ds->priv;
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
struct skb_shared_hwtstamps shwt = {0};
/* We don't care about RX timestamps on the CPU port */
if (dir == SJA1110_META_TSTAMP_RX)
return;
spin_lock(&ptp_data->skb_txtstamp_queue.lock);
skb_queue_walk_safe(&ptp_data->skb_txtstamp_queue, skb, skb_tmp) {
if (SJA1105_SKB_CB(skb)->ts_id != ts_id)
continue;
__skb_unlink(skb, &ptp_data->skb_txtstamp_queue);
skb_match = skb;
break;
}
spin_unlock(&ptp_data->skb_txtstamp_queue.lock);
if (WARN_ON(!skb_match))
return;
shwt.hwtstamp = ns_to_ktime(sja1105_ticks_to_ns(tstamp));
skb_complete_tx_timestamp(skb_match, &shwt);
}
EXPORT_SYMBOL_GPL(sja1110_process_meta_tstamp);
/* In addition to cloning the skb which is done by the common
* sja1105_port_txtstamp, we need to generate a timestamp ID and save the
* packet to the TX timestamping queue.
......@@ -494,7 +461,6 @@ void sja1110_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
{
struct sk_buff *clone = SJA1105_SKB_CB(skb)->clone;
struct sja1105_private *priv = ds->priv;
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
struct sja1105_port *sp = &priv->ports[port];
u8 ts_id;
......@@ -510,7 +476,7 @@ void sja1110_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
spin_unlock(&sp->data->meta_lock);
skb_queue_tail(&ptp_data->skb_txtstamp_queue, clone);
skb_queue_tail(&sp->data->skb_txtstamp_queue, clone);
}
/* Called from dsa_skb_tx_timestamp. This callback is just to clone
......@@ -953,7 +919,7 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds)
/* Only used on SJA1105 */
skb_queue_head_init(&ptp_data->skb_rxtstamp_queue);
/* Only used on SJA1110 */
skb_queue_head_init(&ptp_data->skb_txtstamp_queue);
skb_queue_head_init(&tagger_data->skb_txtstamp_queue);
spin_lock_init(&tagger_data->meta_lock);
ptp_data->clock = ptp_clock_register(&ptp_data->caps, ds->dev);
......@@ -971,6 +937,7 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds)
void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
{
struct sja1105_private *priv = ds->priv;
struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
if (IS_ERR_OR_NULL(ptp_data->clock))
......@@ -978,7 +945,7 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
del_timer_sync(&ptp_data->extts_timer);
ptp_cancel_worker_sync(ptp_data->clock);
skb_queue_purge(&ptp_data->skb_txtstamp_queue);
skb_queue_purge(&tagger_data->skb_txtstamp_queue);
skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
ptp_clock_unregister(ptp_data->clock);
ptp_data->clock = NULL;
......
......@@ -8,21 +8,6 @@
#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
/* Timestamps are in units of 8 ns clock ticks (equivalent to
* a fixed 125 MHz clock).
*/
#define SJA1105_TICK_NS 8
static inline s64 ns_to_sja1105_ticks(s64 ns)
{
return ns / SJA1105_TICK_NS;
}
static inline s64 sja1105_ticks_to_ns(s64 ticks)
{
return ticks * SJA1105_TICK_NS;
}
/* Calculate the first base_time in the future that satisfies this
* relationship:
*
......@@ -77,10 +62,6 @@ struct sja1105_ptp_data {
struct timer_list extts_timer;
/* Used only on SJA1105 to reconstruct partial timestamps */
struct sk_buff_head skb_rxtstamp_queue;
/* Used on SJA1110 where meta frames are generated only for
* 2-step TX timestamps
*/
struct sk_buff_head skb_txtstamp_queue;
struct ptp_clock_info caps;
struct ptp_clock *clock;
struct sja1105_ptp_cmd cmd;
......
......@@ -48,6 +48,10 @@ struct sja1105_tagger_data {
spinlock_t meta_lock;
unsigned long state;
u8 ts_id;
/* Used on SJA1110 where meta frames are generated only for
* 2-step TX timestamps
*/
struct sk_buff_head skb_txtstamp_queue;
};
struct sja1105_skb_cb {
......@@ -69,42 +73,24 @@ struct sja1105_port {
bool hwts_tx_en;
};
enum sja1110_meta_tstamp {
SJA1110_META_TSTAMP_TX = 0,
SJA1110_META_TSTAMP_RX = 1,
};
#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, u8 ts_id,
enum sja1110_meta_tstamp dir, u64 tstamp);
#else
/* Timestamps are in units of 8 ns clock ticks (equivalent to
* a fixed 125 MHz clock).
*/
#define SJA1105_TICK_NS 8
static inline void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port,
u8 ts_id, enum sja1110_meta_tstamp dir,
u64 tstamp)
static inline s64 ns_to_sja1105_ticks(s64 ns)
{
return ns / SJA1105_TICK_NS;
}
#endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */
#if IS_ENABLED(CONFIG_NET_DSA_SJA1105)
extern const struct dsa_switch_ops sja1105_switch_ops;
static inline bool dsa_port_is_sja1105(struct dsa_port *dp)
static inline s64 sja1105_ticks_to_ns(s64 ticks)
{
return dp->ds->ops == &sja1105_switch_ops;
return ticks * SJA1105_TICK_NS;
}
#else
static inline bool dsa_port_is_sja1105(struct dsa_port *dp)
{
return false;
return true;
}
#endif
#endif /* _NET_DSA_SJA1105_H */
......@@ -138,7 +138,6 @@ config NET_DSA_TAG_LAN9303
config NET_DSA_TAG_SJA1105
tristate "Tag driver for NXP SJA1105 switches"
depends on NET_DSA_SJA1105 || !NET_DSA_SJA1105
select PACKING
help
Say Y or M if you want to enable support for tagging frames with the
......
......@@ -4,6 +4,7 @@
#include <linux/if_vlan.h>
#include <linux/dsa/sja1105.h>
#include <linux/dsa/8021q.h>
#include <linux/skbuff.h>
#include <linux/packing.h>
#include "dsa_priv.h"
......@@ -53,6 +54,11 @@
#define SJA1110_TX_TRAILER_LEN 4
#define SJA1110_MAX_PADDING_LEN 15
enum sja1110_meta_tstamp {
SJA1110_META_TSTAMP_TX = 0,
SJA1110_META_TSTAMP_RX = 1,
};
/* Similar to is_link_local_ether_addr(hdr->h_dest) but also covers PTP */
static inline bool sja1105_is_link_local(const struct sk_buff *skb)
{
......@@ -520,6 +526,43 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
is_meta);
}
static void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port,
u8 ts_id, enum sja1110_meta_tstamp dir,
u64 tstamp)
{
struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
struct dsa_port *dp = dsa_to_port(ds, port);
struct skb_shared_hwtstamps shwt = {0};
struct sja1105_port *sp = dp->priv;
if (!dsa_port_is_sja1105(dp))
return;
/* We don't care about RX timestamps on the CPU port */
if (dir == SJA1110_META_TSTAMP_RX)
return;
spin_lock(&sp->data->skb_txtstamp_queue.lock);
skb_queue_walk_safe(&sp->data->skb_txtstamp_queue, skb, skb_tmp) {
if (SJA1105_SKB_CB(skb)->ts_id != ts_id)
continue;
__skb_unlink(skb, &sp->data->skb_txtstamp_queue);
skb_match = skb;
break;
}
spin_unlock(&sp->data->skb_txtstamp_queue.lock);
if (WARN_ON(!skb_match))
return;
shwt.hwtstamp = ns_to_ktime(sja1105_ticks_to_ns(tstamp));
skb_complete_tx_timestamp(skb_match, &shwt);
}
static struct sk_buff *sja1110_rcv_meta(struct sk_buff *skb, u16 rx_header)
{
u8 *buf = dsa_etype_header_pos_rx(skb) + SJA1110_HEADER_LEN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment