diff options
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_main.c | 19 | ||||
-rw-r--r-- | include/linux/dsa/sja1105.h | 4 | ||||
-rw-r--r-- | net/dsa/tag_sja1105.c | 12 |
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 | */ | ||
1901 | static int sja1105_change_rxtstamping(struct sja1105_private *priv, | 1903 | static 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 | ||
48 | struct sja1105_skb_cb { | 50 | struct 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; |