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.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
3af760e4d3
@ -3117,7 +3117,7 @@ static void sja1105_teardown(struct dsa_switch *ds)
|
|||||||
sja1105_static_config_free(&priv->static_config);
|
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,
|
.get_tag_protocol = sja1105_get_tag_protocol,
|
||||||
.setup = sja1105_setup,
|
.setup = sja1105_setup,
|
||||||
.teardown = sja1105_teardown,
|
.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_offload = dsa_tag_8021q_bridge_tx_fwd_offload,
|
||||||
.port_bridge_tx_fwd_unoffload = dsa_tag_8021q_bridge_tx_fwd_unoffload,
|
.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[];
|
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,
|
static int sja1105_change_rxtstamping(struct sja1105_private *priv,
|
||||||
bool on)
|
bool on)
|
||||||
{
|
{
|
||||||
|
struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
|
||||||
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
|
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
|
||||||
struct sja1105_general_params_entry *general_params;
|
struct sja1105_general_params_entry *general_params;
|
||||||
struct sja1105_table *table;
|
struct sja1105_table *table;
|
||||||
@ -79,7 +80,7 @@ static int sja1105_change_rxtstamping(struct sja1105_private *priv,
|
|||||||
priv->tagger_data.stampable_skb = NULL;
|
priv->tagger_data.stampable_skb = NULL;
|
||||||
}
|
}
|
||||||
ptp_cancel_worker_sync(ptp_data->clock);
|
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);
|
skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
|
||||||
|
|
||||||
return sja1105_static_config_reload(priv, SJA1105_RX_HWTSTAMPING);
|
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);
|
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
|
/* 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
|
* sja1105_port_txtstamp, we need to generate a timestamp ID and save the
|
||||||
* packet to the TX timestamping queue.
|
* 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 sk_buff *clone = SJA1105_SKB_CB(skb)->clone;
|
||||||
struct sja1105_private *priv = ds->priv;
|
struct sja1105_private *priv = ds->priv;
|
||||||
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
|
|
||||||
struct sja1105_port *sp = &priv->ports[port];
|
struct sja1105_port *sp = &priv->ports[port];
|
||||||
u8 ts_id;
|
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);
|
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
|
/* 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 */
|
/* Only used on SJA1105 */
|
||||||
skb_queue_head_init(&ptp_data->skb_rxtstamp_queue);
|
skb_queue_head_init(&ptp_data->skb_rxtstamp_queue);
|
||||||
/* Only used on SJA1110 */
|
/* 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);
|
spin_lock_init(&tagger_data->meta_lock);
|
||||||
|
|
||||||
ptp_data->clock = ptp_clock_register(&ptp_data->caps, ds->dev);
|
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)
|
void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
|
||||||
{
|
{
|
||||||
struct sja1105_private *priv = ds->priv;
|
struct sja1105_private *priv = ds->priv;
|
||||||
|
struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
|
||||||
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
|
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(ptp_data->clock))
|
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);
|
del_timer_sync(&ptp_data->extts_timer);
|
||||||
ptp_cancel_worker_sync(ptp_data->clock);
|
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);
|
skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
|
||||||
ptp_clock_unregister(ptp_data->clock);
|
ptp_clock_unregister(ptp_data->clock);
|
||||||
ptp_data->clock = NULL;
|
ptp_data->clock = NULL;
|
||||||
|
@ -8,21 +8,6 @@
|
|||||||
|
|
||||||
#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
|
#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
|
/* Calculate the first base_time in the future that satisfies this
|
||||||
* relationship:
|
* relationship:
|
||||||
*
|
*
|
||||||
@ -77,10 +62,6 @@ struct sja1105_ptp_data {
|
|||||||
struct timer_list extts_timer;
|
struct timer_list extts_timer;
|
||||||
/* Used only on SJA1105 to reconstruct partial timestamps */
|
/* Used only on SJA1105 to reconstruct partial timestamps */
|
||||||
struct sk_buff_head skb_rxtstamp_queue;
|
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_info caps;
|
||||||
struct ptp_clock *clock;
|
struct ptp_clock *clock;
|
||||||
struct sja1105_ptp_cmd cmd;
|
struct sja1105_ptp_cmd cmd;
|
||||||
|
@ -48,6 +48,10 @@ struct sja1105_tagger_data {
|
|||||||
spinlock_t meta_lock;
|
spinlock_t meta_lock;
|
||||||
unsigned long state;
|
unsigned long state;
|
||||||
u8 ts_id;
|
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 {
|
struct sja1105_skb_cb {
|
||||||
@ -69,42 +73,24 @@ struct sja1105_port {
|
|||||||
bool hwts_tx_en;
|
bool hwts_tx_en;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sja1110_meta_tstamp {
|
/* Timestamps are in units of 8 ns clock ticks (equivalent to
|
||||||
SJA1110_META_TSTAMP_TX = 0,
|
* a fixed 125 MHz clock).
|
||||||
SJA1110_META_TSTAMP_RX = 1,
|
*/
|
||||||
};
|
#define SJA1105_TICK_NS 8
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
|
static inline s64 ns_to_sja1105_ticks(s64 ns)
|
||||||
|
|
||||||
void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, u8 ts_id,
|
|
||||||
enum sja1110_meta_tstamp dir, u64 tstamp);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port,
|
|
||||||
u8 ts_id, enum sja1110_meta_tstamp dir,
|
|
||||||
u64 tstamp)
|
|
||||||
{
|
{
|
||||||
|
return ns / SJA1105_TICK_NS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */
|
static inline s64 sja1105_ticks_to_ns(s64 ticks)
|
||||||
|
{
|
||||||
#if IS_ENABLED(CONFIG_NET_DSA_SJA1105)
|
return ticks * SJA1105_TICK_NS;
|
||||||
|
}
|
||||||
extern const struct dsa_switch_ops sja1105_switch_ops;
|
|
||||||
|
|
||||||
static inline bool dsa_port_is_sja1105(struct dsa_port *dp)
|
static inline bool dsa_port_is_sja1105(struct dsa_port *dp)
|
||||||
{
|
{
|
||||||
return dp->ds->ops == &sja1105_switch_ops;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline bool dsa_port_is_sja1105(struct dsa_port *dp)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _NET_DSA_SJA1105_H */
|
#endif /* _NET_DSA_SJA1105_H */
|
||||||
|
@ -138,7 +138,6 @@ config NET_DSA_TAG_LAN9303
|
|||||||
|
|
||||||
config NET_DSA_TAG_SJA1105
|
config NET_DSA_TAG_SJA1105
|
||||||
tristate "Tag driver for NXP SJA1105 switches"
|
tristate "Tag driver for NXP SJA1105 switches"
|
||||||
depends on NET_DSA_SJA1105 || !NET_DSA_SJA1105
|
|
||||||
select PACKING
|
select PACKING
|
||||||
help
|
help
|
||||||
Say Y or M if you want to enable support for tagging frames with the
|
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/if_vlan.h>
|
||||||
#include <linux/dsa/sja1105.h>
|
#include <linux/dsa/sja1105.h>
|
||||||
#include <linux/dsa/8021q.h>
|
#include <linux/dsa/8021q.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
#include <linux/packing.h>
|
#include <linux/packing.h>
|
||||||
#include "dsa_priv.h"
|
#include "dsa_priv.h"
|
||||||
|
|
||||||
@ -53,6 +54,11 @@
|
|||||||
#define SJA1110_TX_TRAILER_LEN 4
|
#define SJA1110_TX_TRAILER_LEN 4
|
||||||
#define SJA1110_MAX_PADDING_LEN 15
|
#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 */
|
/* 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)
|
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);
|
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)
|
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;
|
u8 *buf = dsa_etype_header_pos_rx(skb) + SJA1110_HEADER_LEN;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user