aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/siena.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/siena.c')
-rw-r--r--drivers/net/sfc/siena.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c
index 1619fb5a64f5..727b4228e081 100644
--- a/drivers/net/sfc/siena.c
+++ b/drivers/net/sfc/siena.c
@@ -12,6 +12,8 @@
12#include <linux/delay.h> 12#include <linux/delay.h>
13#include <linux/pci.h> 13#include <linux/pci.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/random.h>
15#include "net_driver.h" 17#include "net_driver.h"
16#include "bitfield.h" 18#include "bitfield.h"
17#include "efx.h" 19#include "efx.h"
@@ -273,6 +275,9 @@ static int siena_probe_nic(struct efx_nic *efx)
273 goto fail5; 275 goto fail5;
274 } 276 }
275 277
278 get_random_bytes(&nic_data->ipv6_rss_key,
279 sizeof(nic_data->ipv6_rss_key));
280
276 return 0; 281 return 0;
277 282
278fail5: 283fail5:
@@ -292,6 +297,7 @@ fail1:
292 */ 297 */
293static int siena_init_nic(struct efx_nic *efx) 298static int siena_init_nic(struct efx_nic *efx)
294{ 299{
300 struct siena_nic_data *nic_data = efx->nic_data;
295 efx_oword_t temp; 301 efx_oword_t temp;
296 int rc; 302 int rc;
297 303
@@ -318,6 +324,20 @@ static int siena_init_nic(struct efx_nic *efx)
318 EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_INGR_EN, 1); 324 EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_INGR_EN, 1);
319 efx_writeo(efx, &temp, FR_AZ_RX_CFG); 325 efx_writeo(efx, &temp, FR_AZ_RX_CFG);
320 326
327 /* Enable IPv6 RSS */
328 BUILD_BUG_ON(sizeof(nic_data->ipv6_rss_key) !=
329 2 * sizeof(temp) + FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8 ||
330 FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN != 0);
331 memcpy(&temp, nic_data->ipv6_rss_key, sizeof(temp));
332 efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG1);
333 memcpy(&temp, nic_data->ipv6_rss_key + sizeof(temp), sizeof(temp));
334 efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG2);
335 EFX_POPULATE_OWORD_2(temp, FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1,
336 FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, 1);
337 memcpy(&temp, nic_data->ipv6_rss_key + 2 * sizeof(temp),
338 FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8);
339 efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG3);
340
321 if (efx_nic_rx_xoff_thresh >= 0 || efx_nic_rx_xon_thresh >= 0) 341 if (efx_nic_rx_xoff_thresh >= 0 || efx_nic_rx_xon_thresh >= 0)
322 /* No MCDI operation has been defined to set thresholds */ 342 /* No MCDI operation has been defined to set thresholds */
323 EFX_ERR(efx, "ignoring RX flow control thresholds\n"); 343 EFX_ERR(efx, "ignoring RX flow control thresholds\n");
@@ -455,8 +475,17 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
455 475
456static void siena_update_nic_stats(struct efx_nic *efx) 476static void siena_update_nic_stats(struct efx_nic *efx)
457{ 477{
458 while (siena_try_update_nic_stats(efx) == -EAGAIN) 478 int retry;
459 cpu_relax(); 479
480 /* If we're unlucky enough to read statistics wduring the DMA, wait
481 * up to 10ms for it to finish (typically takes <500us) */
482 for (retry = 0; retry < 100; ++retry) {
483 if (siena_try_update_nic_stats(efx) == 0)
484 return;
485 udelay(100);
486 }
487
488 /* Use the old values instead */
460} 489}
461 490
462static void siena_start_nic_stats(struct efx_nic *efx) 491static void siena_start_nic_stats(struct efx_nic *efx)