summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/dsa/sja1105/sja1105_main.c19
-rw-r--r--include/linux/dsa/sja1105.h4
-rw-r--r--net/dsa/tag_sja1105.c12
3 files changed, 25 insertions, 10 deletions
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index ea2e7f4f96d0..7687ddcae159 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1897,7 +1897,9 @@ static int sja1105_set_ageing_time(struct dsa_switch *ds,
1897 return sja1105_static_config_reload(priv); 1897 return sja1105_static_config_reload(priv);
1898} 1898}
1899 1899
1900/* Caller must hold priv->tagger_data.meta_lock */ 1900/* Must be called only with priv->tagger_data.state bit
1901 * SJA1105_HWTS_RX_EN cleared
1902 */
1901static int sja1105_change_rxtstamping(struct sja1105_private *priv, 1903static int sja1105_change_rxtstamping(struct sja1105_private *priv,
1902 bool on) 1904 bool on)
1903{ 1905{
@@ -1954,16 +1956,17 @@ static int sja1105_hwtstamp_set(struct dsa_switch *ds, int port,
1954 break; 1956 break;
1955 } 1957 }
1956 1958
1957 if (rx_on != priv->tagger_data.hwts_rx_en) { 1959 if (rx_on != test_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state)) {
1958 spin_lock(&priv->tagger_data.meta_lock); 1960 clear_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state);
1961
1959 rc = sja1105_change_rxtstamping(priv, rx_on); 1962 rc = sja1105_change_rxtstamping(priv, rx_on);
1960 spin_unlock(&priv->tagger_data.meta_lock);
1961 if (rc < 0) { 1963 if (rc < 0) {
1962 dev_err(ds->dev, 1964 dev_err(ds->dev,
1963 "Failed to change RX timestamping: %d\n", rc); 1965 "Failed to change RX timestamping: %d\n", rc);
1964 return -EFAULT; 1966 return rc;
1965 } 1967 }
1966 priv->tagger_data.hwts_rx_en = rx_on; 1968 if (rx_on)
1969 set_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state);
1967 } 1970 }
1968 1971
1969 if (copy_to_user(ifr->ifr_data, &config, sizeof(config))) 1972 if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
@@ -1982,7 +1985,7 @@ static int sja1105_hwtstamp_get(struct dsa_switch *ds, int port,
1982 config.tx_type = HWTSTAMP_TX_ON; 1985 config.tx_type = HWTSTAMP_TX_ON;
1983 else 1986 else
1984 config.tx_type = HWTSTAMP_TX_OFF; 1987 config.tx_type = HWTSTAMP_TX_OFF;
1985 if (priv->tagger_data.hwts_rx_en) 1988 if (test_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state))
1986 config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 1989 config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
1987 else 1990 else
1988 config.rx_filter = HWTSTAMP_FILTER_NONE; 1991 config.rx_filter = HWTSTAMP_FILTER_NONE;
@@ -2031,7 +2034,7 @@ static bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
2031 struct sja1105_private *priv = ds->priv; 2034 struct sja1105_private *priv = ds->priv;
2032 struct sja1105_tagger_data *data = &priv->tagger_data; 2035 struct sja1105_tagger_data *data = &priv->tagger_data;
2033 2036
2034 if (!data->hwts_rx_en) 2037 if (!test_bit(SJA1105_HWTS_RX_EN, &data->state))
2035 return false; 2038 return false;
2036 2039
2037 /* We need to read the full PTP clock to reconstruct the Rx 2040 /* We need to read the full PTP clock to reconstruct the Rx
diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h
index 79435cfc20eb..897e799dbcb9 100644
--- a/include/linux/dsa/sja1105.h
+++ b/include/linux/dsa/sja1105.h
@@ -31,6 +31,8 @@
31#define SJA1105_META_SMAC 0x222222222222ull 31#define SJA1105_META_SMAC 0x222222222222ull
32#define SJA1105_META_DMAC 0x0180C200000Eull 32#define SJA1105_META_DMAC 0x0180C200000Eull
33 33
34#define SJA1105_HWTS_RX_EN 0
35
34/* Global tagger data: each struct sja1105_port has a reference to 36/* Global tagger data: each struct sja1105_port has a reference to
35 * the structure defined in struct sja1105_private. 37 * the structure defined in struct sja1105_private.
36 */ 38 */
@@ -42,7 +44,7 @@ struct sja1105_tagger_data {
42 * from taggers running on multiple ports on SMP systems 44 * from taggers running on multiple ports on SMP systems
43 */ 45 */
44 spinlock_t meta_lock; 46 spinlock_t meta_lock;
45 bool hwts_rx_en; 47 unsigned long state;
46}; 48};
47 49
48struct sja1105_skb_cb { 50struct sja1105_skb_cb {
diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index 9c9aff3e52cf..63ef2a14c934 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -156,7 +156,11 @@ static struct sk_buff
156 /* Step 1: A timestampable frame was received. 156 /* Step 1: A timestampable frame was received.
157 * Buffer it until we get its meta frame. 157 * Buffer it until we get its meta frame.
158 */ 158 */
159 if (is_link_local && sp->data->hwts_rx_en) { 159 if (is_link_local) {
160 if (!test_bit(SJA1105_HWTS_RX_EN, &sp->data->state))
161 /* Do normal processing. */
162 return skb;
163
160 spin_lock(&sp->data->meta_lock); 164 spin_lock(&sp->data->meta_lock);
161 /* Was this a link-local frame instead of the meta 165 /* Was this a link-local frame instead of the meta
162 * that we were expecting? 166 * that we were expecting?
@@ -187,6 +191,12 @@ static struct sk_buff
187 } else if (is_meta) { 191 } else if (is_meta) {
188 struct sk_buff *stampable_skb; 192 struct sk_buff *stampable_skb;
189 193
194 /* Drop the meta frame if we're not in the right state
195 * to process it.
196 */
197 if (!test_bit(SJA1105_HWTS_RX_EN, &sp->data->state))
198 return NULL;
199
190 spin_lock(&sp->data->meta_lock); 200 spin_lock(&sp->data->meta_lock);
191 201
192 stampable_skb = sp->data->stampable_skb; 202 stampable_skb = sp->data->stampable_skb;