* Pull request: sfc 2013-12-10
@ 2013-12-11 1:51 Ben Hutchings
2013-12-11 1:54 ` [PATCH net 1/8] sfc: Add length checks to efx_xmit_with_hwtstamp() and efx_ptp_is_ptp_tx() Ben Hutchings
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Ben Hutchings @ 2013-12-11 1:51 UTC (permalink / raw)
To: David Miller; +Cc: linux-net-drivers, netdev
[-- Attachment #1: Type: text/plain, Size: 2631 bytes --]
The following changes since commit e1ca87bb1b64b044163e686ff3bb71405156c561:
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless (2013-12-05 16:02:56 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc.git sfc-3.13
for you to fetch changes up to 6b294b8efedaa7cf7507154148e2c79766ad6f96:
sfc: Poll for MCDI completion once before timeout occurs (2013-12-06 22:27:55 +0000)
Several fixes for the PTP hardware support added in 3.7:
1. Fix filtering of PTP packets on the TX path to be robust against bad
header lengths.
2. Limit logging on the RX path in case of a PTP packet flood, partly
from Laurence Evans.
3. Disable PTP hardware when the interface is down so that we don't
receive RX timestamp events, from Alexandre Rames.
4. Maintain clock frequency adjustment when a time offset is applied.
Also fixes for the SFC9100 family support added in 3.12:
5. Take the RX prefix length into account when applying NET_IP_ALIGN,
from Andrew Rybchenko.
6. Work around a bug that breaks communication between the driver and
firmware, from Robert Stonehouse.
Please also queue these up for the appropriate stable branches.
Ben.
----------------------------------------------------------------
Alexandre Rames (1):
sfc: Stop/re-start PTP when stopping/starting the datapath.
Andrew Rybchenko (1):
sfc: RX buffer allocation takes prefix size into account in IP header alignment
Ben Hutchings (3):
sfc: Add length checks to efx_xmit_with_hwtstamp() and efx_ptp_is_ptp_tx()
sfc: Rate-limit log message for PTP packets without a matching timestamp event
sfc: Maintain current frequency adjustment when applying a time offset
Laurence Evans (1):
sfc: PTP: Moderate log message on event queue overflow
Robert Stonehouse (2):
sfc: Refactor efx_mcdi_poll() by introducing efx_mcdi_poll_once()
sfc: Poll for MCDI completion once before timeout occurs
drivers/net/ethernet/sfc/efx.c | 8 ++++-
drivers/net/ethernet/sfc/mcdi.c | 39 +++++++++++++++------
drivers/net/ethernet/sfc/net_driver.h | 3 ++
drivers/net/ethernet/sfc/nic.h | 2 ++
drivers/net/ethernet/sfc/ptp.c | 66 ++++++++++++++++++++++++++++++-----
drivers/net/ethernet/sfc/rx.c | 6 ++--
6 files changed, 101 insertions(+), 23 deletions(-)
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net 1/8] sfc: Add length checks to efx_xmit_with_hwtstamp() and efx_ptp_is_ptp_tx()
2013-12-11 1:51 Pull request: sfc 2013-12-10 Ben Hutchings
@ 2013-12-11 1:54 ` Ben Hutchings
2013-12-11 1:55 ` [PATCH net 2/8] sfc: PTP: Moderate log message on event queue overflow Ben Hutchings
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Hutchings @ 2013-12-11 1:54 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
efx_ptp_is_ptp_tx() must be robust against skbs from raw sockets that
have invalid IPv4 and UDP headers.
Add checks that:
- the transport header has been found
- there is enough space between network and transport header offset
for an IPv4 header
- there is enough space after the transport header offset for a
UDP header
Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
Re-sending this in the proper thread.
Ben.
drivers/net/ethernet/sfc/ptp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 03acf57df045..93a61a157d10 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -989,7 +989,11 @@ bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb)
skb->len >= PTP_MIN_LENGTH &&
skb->len <= MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM &&
likely(skb->protocol == htons(ETH_P_IP)) &&
+ skb_transport_header_was_set(skb) &&
+ skb_network_header_len(skb) >= sizeof(struct iphdr) &&
ip_hdr(skb)->protocol == IPPROTO_UDP &&
+ skb_headlen(skb) >=
+ skb_transport_offset(skb) + sizeof(struct udphdr) &&
udp_hdr(skb)->dest == htons(PTP_EVENT_PORT);
}
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net 2/8] sfc: PTP: Moderate log message on event queue overflow
2013-12-11 1:51 Pull request: sfc 2013-12-10 Ben Hutchings
2013-12-11 1:54 ` [PATCH net 1/8] sfc: Add length checks to efx_xmit_with_hwtstamp() and efx_ptp_is_ptp_tx() Ben Hutchings
@ 2013-12-11 1:55 ` Ben Hutchings
2013-12-11 1:55 ` [PATCH net 3/8] sfc: Rate-limit log message for PTP packets without a matching timestamp event Ben Hutchings
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Hutchings @ 2013-12-11 1:55 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
From: Laurence Evans <levans@solarflare.com>
Limit syslog flood if a PTP packet storm occurs.
Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
Re-sending this in the proper thread.
Ben.
drivers/net/ethernet/sfc/ptp.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 93a61a157d10..8b2cf783217c 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -220,6 +220,7 @@ struct efx_ptp_timeset {
* @evt_list: List of MC receive events awaiting packets
* @evt_free_list: List of free events
* @evt_lock: Lock for manipulating evt_list and evt_free_list
+ * @evt_overflow: Boolean indicating that event list has overflowed
* @rx_evts: Instantiated events (on evt_list and evt_free_list)
* @workwq: Work queue for processing pending PTP operations
* @work: Work task
@@ -270,6 +271,7 @@ struct efx_ptp_data {
struct list_head evt_list;
struct list_head evt_free_list;
spinlock_t evt_lock;
+ bool evt_overflow;
struct efx_ptp_event_rx rx_evts[MAX_RECEIVE_EVENTS];
struct workqueue_struct *workwq;
struct work_struct work;
@@ -635,6 +637,11 @@ static void efx_ptp_drop_time_expired_events(struct efx_nic *efx)
}
}
}
+ /* If the event overflow flag is set and the event list is now empty
+ * clear the flag to re-enable the overflow warning message.
+ */
+ if (ptp->evt_overflow && list_empty(&ptp->evt_list))
+ ptp->evt_overflow = false;
spin_unlock_bh(&ptp->evt_lock);
}
@@ -676,6 +683,11 @@ static enum ptp_packet_state efx_ptp_match_rx(struct efx_nic *efx,
break;
}
}
+ /* If the event overflow flag is set and the event list is now empty
+ * clear the flag to re-enable the overflow warning message.
+ */
+ if (ptp->evt_overflow && list_empty(&ptp->evt_list))
+ ptp->evt_overflow = false;
spin_unlock_bh(&ptp->evt_lock);
return rc;
@@ -809,6 +821,7 @@ static int efx_ptp_stop(struct efx_nic *efx)
list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) {
list_move(cursor, &efx->ptp_data->evt_free_list);
}
+ ptp->evt_overflow = false;
spin_unlock_bh(&efx->ptp_data->evt_lock);
return rc;
@@ -901,6 +914,7 @@ static int efx_ptp_probe_channel(struct efx_channel *channel)
spin_lock_init(&ptp->evt_lock);
for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++)
list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list);
+ ptp->evt_overflow = false;
ptp->phc_clock_info.owner = THIS_MODULE;
snprintf(ptp->phc_clock_info.name,
@@ -1299,8 +1313,13 @@ static void ptp_event_rx(struct efx_nic *efx, struct efx_ptp_data *ptp)
list_add_tail(&evt->link, &ptp->evt_list);
queue_work(ptp->workwq, &ptp->work);
- } else {
- netif_err(efx, rx_err, efx->net_dev, "No free PTP event");
+ } else if (!ptp->evt_overflow) {
+ /* Log a warning message and set the event overflow flag.
+ * The message won't be logged again until the event queue
+ * becomes empty.
+ */
+ netif_err(efx, rx_err, efx->net_dev, "PTP event queue overflow\n");
+ ptp->evt_overflow = true;
}
spin_unlock_bh(&ptp->evt_lock);
}
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net 3/8] sfc: Rate-limit log message for PTP packets without a matching timestamp event
2013-12-11 1:51 Pull request: sfc 2013-12-10 Ben Hutchings
2013-12-11 1:54 ` [PATCH net 1/8] sfc: Add length checks to efx_xmit_with_hwtstamp() and efx_ptp_is_ptp_tx() Ben Hutchings
2013-12-11 1:55 ` [PATCH net 2/8] sfc: PTP: Moderate log message on event queue overflow Ben Hutchings
@ 2013-12-11 1:55 ` Ben Hutchings
2013-12-11 1:56 ` [PATCH net 4/8] sfc: Stop/re-start PTP when stopping/starting the datapath Ben Hutchings
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Hutchings @ 2013-12-11 1:55 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In case of a flood of PTP packets, the timestamp peripheral and MC
firmware on the SFN[56]322F boards may not be able to provide
timestamp events for all packets. Don't complain too much about this.
Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/sfc/ptp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 8b2cf783217c..8c665f1b5480 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -717,8 +717,9 @@ static bool efx_ptp_process_events(struct efx_nic *efx, struct sk_buff_head *q)
__skb_queue_tail(q, skb);
} else if (time_after(jiffies, match->expiry)) {
match->state = PTP_PACKET_STATE_TIMED_OUT;
- netif_warn(efx, rx_err, efx->net_dev,
- "PTP packet - no timestamp seen\n");
+ if (net_ratelimit())
+ netif_warn(efx, rx_err, efx->net_dev,
+ "PTP packet - no timestamp seen\n");
__skb_queue_tail(q, skb);
} else {
/* Replace unprocessed entry and stop */
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net 4/8] sfc: Stop/re-start PTP when stopping/starting the datapath.
2013-12-11 1:51 Pull request: sfc 2013-12-10 Ben Hutchings
` (2 preceding siblings ...)
2013-12-11 1:55 ` [PATCH net 3/8] sfc: Rate-limit log message for PTP packets without a matching timestamp event Ben Hutchings
@ 2013-12-11 1:56 ` Ben Hutchings
2013-12-11 1:56 ` [PATCH net 5/8] sfc: Maintain current frequency adjustment when applying a time offset Ben Hutchings
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Hutchings @ 2013-12-11 1:56 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
From: Alexandre Rames <arames@solarflare.com>
This disables PTP when we bring the interface down to avoid getting
unmatched RX timestamp events, and tries to re-enable it when bringing
the interface up.
[bwh: Make efx_ptp_stop() safe on Falcon. Introduce
efx_ptp_{start,stop}_datapath() functions; we'll expand them later.]
Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/sfc/efx.c | 4 ++++
drivers/net/ethernet/sfc/nic.h | 2 ++
drivers/net/ethernet/sfc/ptp.c | 30 +++++++++++++++++++++++++++---
3 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 2e27837ce6a2..8bd5b485f1bc 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -645,6 +645,8 @@ static void efx_start_datapath(struct efx_nic *efx)
WARN_ON(channel->rx_pkt_n_frags);
}
+ efx_ptp_start_datapath(efx);
+
if (netif_device_present(efx->net_dev))
netif_tx_wake_all_queues(efx->net_dev);
}
@@ -659,6 +661,8 @@ static void efx_stop_datapath(struct efx_nic *efx)
EFX_ASSERT_RESET_SERIALISED(efx);
BUG_ON(efx->port_enabled);
+ efx_ptp_stop_datapath(efx);
+
/* Stop RX refill */
efx_for_each_channel(channel, efx) {
efx_for_each_channel_rx_queue(rx_queue, channel)
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index 11b6112d9249..91c63ec79c5f 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -560,6 +560,8 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
+void efx_ptp_start_datapath(struct efx_nic *efx);
+void efx_ptp_stop_datapath(struct efx_nic *efx);
extern const struct efx_nic_type falcon_a1_nic_type;
extern const struct efx_nic_type falcon_b0_nic_type;
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 8c665f1b5480..9bd99edf3f95 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -801,9 +801,14 @@ fail:
static int efx_ptp_stop(struct efx_nic *efx)
{
struct efx_ptp_data *ptp = efx->ptp_data;
- int rc = efx_ptp_disable(efx);
struct list_head *cursor;
struct list_head *next;
+ int rc;
+
+ if (ptp == NULL)
+ return 0;
+
+ rc = efx_ptp_disable(efx);
if (ptp->rxfilter_installed) {
efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
@@ -828,6 +833,13 @@ static int efx_ptp_stop(struct efx_nic *efx)
return rc;
}
+static int efx_ptp_restart(struct efx_nic *efx)
+{
+ if (efx->ptp_data && efx->ptp_data->enabled)
+ return efx_ptp_start(efx);
+ return 0;
+}
+
static void efx_ptp_pps_worker(struct work_struct *work)
{
struct efx_ptp_data *ptp =
@@ -1125,7 +1137,7 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
{
if ((enable_wanted != efx->ptp_data->enabled) ||
(enable_wanted && (efx->ptp_data->mode != new_mode))) {
- int rc;
+ int rc = 0;
if (enable_wanted) {
/* Change of mode requires disable */
@@ -1142,7 +1154,8 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
* succeed.
*/
efx->ptp_data->mode = new_mode;
- rc = efx_ptp_start(efx);
+ if (netif_running(efx->net_dev))
+ rc = efx_ptp_start(efx);
if (rc == 0) {
rc = efx_ptp_synchronize(efx,
PTP_SYNC_ATTEMPTS * 2);
@@ -1515,3 +1528,14 @@ void efx_ptp_probe(struct efx_nic *efx)
efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] =
&efx_ptp_channel_type;
}
+
+void efx_ptp_start_datapath(struct efx_nic *efx)
+{
+ if (efx_ptp_restart(efx))
+ netif_err(efx, drv, efx->net_dev, "Failed to restart PTP.\n");
+}
+
+void efx_ptp_stop_datapath(struct efx_nic *efx)
+{
+ efx_ptp_stop(efx);
+}
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net 5/8] sfc: Maintain current frequency adjustment when applying a time offset
2013-12-11 1:51 Pull request: sfc 2013-12-10 Ben Hutchings
` (3 preceding siblings ...)
2013-12-11 1:56 ` [PATCH net 4/8] sfc: Stop/re-start PTP when stopping/starting the datapath Ben Hutchings
@ 2013-12-11 1:56 ` Ben Hutchings
2013-12-11 1:57 ` [PATCH net 6/8] sfc: RX buffer allocation takes prefix size into account in IP header alignment Ben Hutchings
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Hutchings @ 2013-12-11 1:56 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
There is a single MCDI PTP operation for setting the frequency
adjustment and applying a time offset to the hardware clock. When
applying a time offset we should not change the frequency adjustment.
These two operations can now be requested separately but this requires
a flash firmware update. Keep using the single operation, but
remember and repeat the previous frequency adjustment.
Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/sfc/ptp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 9bd99edf3f95..3dd39dcfe36b 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -1426,7 +1426,7 @@ static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
if (rc != 0)
return rc;
- ptp_data->current_adjfreq = delta;
+ ptp_data->current_adjfreq = adjustment_ns;
return 0;
}
@@ -1441,7 +1441,7 @@ static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ADJUST);
MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
- MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, 0);
+ MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, ptp_data->current_adjfreq);
MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_SECONDS, (u32)delta_ts.tv_sec);
MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_NANOSECONDS, (u32)delta_ts.tv_nsec);
return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf),
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net 6/8] sfc: RX buffer allocation takes prefix size into account in IP header alignment
2013-12-11 1:51 Pull request: sfc 2013-12-10 Ben Hutchings
` (4 preceding siblings ...)
2013-12-11 1:56 ` [PATCH net 5/8] sfc: Maintain current frequency adjustment when applying a time offset Ben Hutchings
@ 2013-12-11 1:57 ` Ben Hutchings
2013-12-11 1:57 ` [PATCH net 7/8] sfc: Refactor efx_mcdi_poll() by introducing efx_mcdi_poll_once() Ben Hutchings
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Hutchings @ 2013-12-11 1:57 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
From: Andrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru>
rx_prefix_size is 4-bytes aligned on Falcon/Siena (16 bytes), but it is equal
to 14 on EF10. So, it should be taken into account if arch requires IP header
to be 4-bytes aligned (via NET_IP_ALIGN).
Fixes: 8127d661e77f ('sfc: Add support for Solarflare SFC9100 family')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/sfc/efx.c | 4 +++-
drivers/net/ethernet/sfc/net_driver.h | 3 +++
drivers/net/ethernet/sfc/rx.c | 6 +++---
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 8bd5b485f1bc..fd844b53e385 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -585,7 +585,7 @@ static void efx_start_datapath(struct efx_nic *efx)
EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
efx->type->rx_buffer_padding);
rx_buf_len = (sizeof(struct efx_rx_page_state) +
- NET_IP_ALIGN + efx->rx_dma_len);
+ efx->rx_ip_align + efx->rx_dma_len);
if (rx_buf_len <= PAGE_SIZE) {
efx->rx_scatter = efx->type->always_rx_scatter;
efx->rx_buffer_order = 0;
@@ -2544,6 +2544,8 @@ static int efx_init_struct(struct efx_nic *efx,
efx->net_dev = net_dev;
efx->rx_prefix_size = efx->type->rx_prefix_size;
+ efx->rx_ip_align =
+ NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0;
efx->rx_packet_hash_offset =
efx->type->rx_hash_offset - efx->type->rx_prefix_size;
spin_lock_init(&efx->stats_lock);
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index b14a717ac3e8..542a0d252ae0 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -683,6 +683,8 @@ struct vfdi_status;
* @n_channels: Number of channels in use
* @n_rx_channels: Number of channels used for RX (= number of RX queues)
* @n_tx_channels: Number of channels used for TX
+ * @rx_ip_align: RX DMA address offset to have IP header aligned in
+ * in accordance with NET_IP_ALIGN
* @rx_dma_len: Current maximum RX DMA length
* @rx_buffer_order: Order (log2) of number of pages for each RX buffer
* @rx_buffer_truesize: Amortised allocation size of an RX buffer,
@@ -816,6 +818,7 @@ struct efx_nic {
unsigned rss_spread;
unsigned tx_channel_offset;
unsigned n_tx_channels;
+ unsigned int rx_ip_align;
unsigned int rx_dma_len;
unsigned int rx_buffer_order;
unsigned int rx_buffer_truesize;
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 8f09e686fc23..42488df1f4ec 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -94,7 +94,7 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx,
void efx_rx_config_page_split(struct efx_nic *efx)
{
- efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN,
+ efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + efx->rx_ip_align,
EFX_RX_BUF_ALIGNMENT);
efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 :
((PAGE_SIZE - sizeof(struct efx_rx_page_state)) /
@@ -189,9 +189,9 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue)
do {
index = rx_queue->added_count & rx_queue->ptr_mask;
rx_buf = efx_rx_buffer(rx_queue, index);
- rx_buf->dma_addr = dma_addr + NET_IP_ALIGN;
+ rx_buf->dma_addr = dma_addr + efx->rx_ip_align;
rx_buf->page = page;
- rx_buf->page_offset = page_offset + NET_IP_ALIGN;
+ rx_buf->page_offset = page_offset + efx->rx_ip_align;
rx_buf->len = efx->rx_dma_len;
rx_buf->flags = 0;
++rx_queue->added_count;
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net 7/8] sfc: Refactor efx_mcdi_poll() by introducing efx_mcdi_poll_once()
2013-12-11 1:51 Pull request: sfc 2013-12-10 Ben Hutchings
` (5 preceding siblings ...)
2013-12-11 1:57 ` [PATCH net 6/8] sfc: RX buffer allocation takes prefix size into account in IP header alignment Ben Hutchings
@ 2013-12-11 1:57 ` Ben Hutchings
2013-12-11 1:58 ` [PATCH net 8/8] sfc: Poll for MCDI completion once before timeout occurs Ben Hutchings
2013-12-11 2:21 ` Pull request: sfc 2013-12-10 David Miller
8 siblings, 0 replies; 10+ messages in thread
From: Ben Hutchings @ 2013-12-11 1:57 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
From: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/sfc/mcdi.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 366c8e3e3784..9f26e46ee283 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -50,6 +50,7 @@ struct efx_mcdi_async_param {
static void efx_mcdi_timeout_async(unsigned long context);
static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
bool *was_attached_out);
+static bool efx_mcdi_poll_once(struct efx_nic *efx);
static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx)
{
@@ -237,6 +238,21 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx)
}
}
+static bool efx_mcdi_poll_once(struct efx_nic *efx)
+{
+ struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+
+ rmb();
+ if (!efx->type->mcdi_poll_response(efx))
+ return false;
+
+ spin_lock_bh(&mcdi->iface_lock);
+ efx_mcdi_read_response_header(efx);
+ spin_unlock_bh(&mcdi->iface_lock);
+
+ return true;
+}
+
static int efx_mcdi_poll(struct efx_nic *efx)
{
struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
@@ -272,18 +288,13 @@ static int efx_mcdi_poll(struct efx_nic *efx)
time = jiffies;
- rmb();
- if (efx->type->mcdi_poll_response(efx))
+ if (efx_mcdi_poll_once(efx))
break;
if (time_after(time, finish))
return -ETIMEDOUT;
}
- spin_lock_bh(&mcdi->iface_lock);
- efx_mcdi_read_response_header(efx);
- spin_unlock_bh(&mcdi->iface_lock);
-
/* Return rc=0 like wait_event_timeout() */
return 0;
}
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net 8/8] sfc: Poll for MCDI completion once before timeout occurs
2013-12-11 1:51 Pull request: sfc 2013-12-10 Ben Hutchings
` (6 preceding siblings ...)
2013-12-11 1:57 ` [PATCH net 7/8] sfc: Refactor efx_mcdi_poll() by introducing efx_mcdi_poll_once() Ben Hutchings
@ 2013-12-11 1:58 ` Ben Hutchings
2013-12-11 2:21 ` Pull request: sfc 2013-12-10 David Miller
8 siblings, 0 replies; 10+ messages in thread
From: Ben Hutchings @ 2013-12-11 1:58 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
From: Robert Stonehouse <rstonehouse@solarflare.com>
There is an as-yet unexplained bug that sometimes prevents (or delays)
the driver seeing the completion event for a completed MCDI request on
the SFC9120. The requested configuration change will have happened
but the driver assumes it to have failed, and this can result in
further failures. We can mitigate this by polling for completion
after unsuccessfully waiting for an event.
Fixes: 8127d661e77f ('sfc: Add support for Solarflare SFC9100 family')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/sfc/mcdi.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 9f26e46ee283..4b0bd8a1514d 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -630,6 +630,16 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
rc = efx_mcdi_await_completion(efx);
if (rc != 0) {
+ netif_err(efx, hw, efx->net_dev,
+ "MC command 0x%x inlen %d mode %d timed out\n",
+ cmd, (int)inlen, mcdi->mode);
+
+ if (mcdi->mode == MCDI_MODE_EVENTS && efx_mcdi_poll_once(efx)) {
+ netif_err(efx, hw, efx->net_dev,
+ "MCDI request was completed without an event\n");
+ rc = 0;
+ }
+
/* Close the race with efx_mcdi_ev_cpl() executing just too late
* and completing a request we've just cancelled, by ensuring
* that the seqno check therein fails.
@@ -638,11 +648,9 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
++mcdi->seqno;
++mcdi->credits;
spin_unlock_bh(&mcdi->iface_lock);
+ }
- netif_err(efx, hw, efx->net_dev,
- "MC command 0x%x inlen %d mode %d timed out\n",
- cmd, (int)inlen, mcdi->mode);
- } else {
+ if (rc == 0) {
size_t hdr_len, data_len;
/* At the very least we need a memory barrier here to ensure
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: Pull request: sfc 2013-12-10
2013-12-11 1:51 Pull request: sfc 2013-12-10 Ben Hutchings
` (7 preceding siblings ...)
2013-12-11 1:58 ` [PATCH net 8/8] sfc: Poll for MCDI completion once before timeout occurs Ben Hutchings
@ 2013-12-11 2:21 ` David Miller
8 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2013-12-11 2:21 UTC (permalink / raw)
To: bhutchings; +Cc: linux-net-drivers, netdev
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Wed, 11 Dec 2013 01:51:54 +0000
> git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc.git sfc-3.13
...
> Several fixes for the PTP hardware support added in 3.7:
> 1. Fix filtering of PTP packets on the TX path to be robust against bad
> header lengths.
> 2. Limit logging on the RX path in case of a PTP packet flood, partly
> from Laurence Evans.
> 3. Disable PTP hardware when the interface is down so that we don't
> receive RX timestamp events, from Alexandre Rames.
> 4. Maintain clock frequency adjustment when a time offset is applied.
>
> Also fixes for the SFC9100 family support added in 3.12:
> 5. Take the RX prefix length into account when applying NET_IP_ALIGN,
> from Andrew Rybchenko.
> 6. Work around a bug that breaks communication between the driver and
> firmware, from Robert Stonehouse.
>
> Please also queue these up for the appropriate stable branches.
Pulled and queued up for -stable, thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2013-12-11 2:21 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-11 1:51 Pull request: sfc 2013-12-10 Ben Hutchings
2013-12-11 1:54 ` [PATCH net 1/8] sfc: Add length checks to efx_xmit_with_hwtstamp() and efx_ptp_is_ptp_tx() Ben Hutchings
2013-12-11 1:55 ` [PATCH net 2/8] sfc: PTP: Moderate log message on event queue overflow Ben Hutchings
2013-12-11 1:55 ` [PATCH net 3/8] sfc: Rate-limit log message for PTP packets without a matching timestamp event Ben Hutchings
2013-12-11 1:56 ` [PATCH net 4/8] sfc: Stop/re-start PTP when stopping/starting the datapath Ben Hutchings
2013-12-11 1:56 ` [PATCH net 5/8] sfc: Maintain current frequency adjustment when applying a time offset Ben Hutchings
2013-12-11 1:57 ` [PATCH net 6/8] sfc: RX buffer allocation takes prefix size into account in IP header alignment Ben Hutchings
2013-12-11 1:57 ` [PATCH net 7/8] sfc: Refactor efx_mcdi_poll() by introducing efx_mcdi_poll_once() Ben Hutchings
2013-12-11 1:58 ` [PATCH net 8/8] sfc: Poll for MCDI completion once before timeout occurs Ben Hutchings
2013-12-11 2:21 ` Pull request: sfc 2013-12-10 David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).