diff options
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r-- | drivers/net/sfc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/sfc/bitfield.h | 4 | ||||
-rw-r--r-- | drivers/net/sfc/boards.c | 74 | ||||
-rw-r--r-- | drivers/net/sfc/boards.h | 1 | ||||
-rw-r--r-- | drivers/net/sfc/efx.c | 74 | ||||
-rw-r--r-- | drivers/net/sfc/efx.h | 4 | ||||
-rw-r--r-- | drivers/net/sfc/ethtool.c | 28 | ||||
-rw-r--r-- | drivers/net/sfc/falcon.c | 96 | ||||
-rw-r--r-- | drivers/net/sfc/falcon.h | 2 | ||||
-rw-r--r-- | drivers/net/sfc/falcon_io.h | 13 | ||||
-rw-r--r-- | drivers/net/sfc/mdio_10g.c | 28 | ||||
-rw-r--r-- | drivers/net/sfc/mdio_10g.h | 8 | ||||
-rw-r--r-- | drivers/net/sfc/mtd.c | 1 | ||||
-rw-r--r-- | drivers/net/sfc/net_driver.h | 29 | ||||
-rw-r--r-- | drivers/net/sfc/phy.h | 8 | ||||
-rw-r--r-- | drivers/net/sfc/rx.c | 209 | ||||
-rw-r--r-- | drivers/net/sfc/rx.h | 3 | ||||
-rw-r--r-- | drivers/net/sfc/sfe4001.c | 21 | ||||
-rw-r--r-- | drivers/net/sfc/tenxpress.c | 141 | ||||
-rw-r--r-- | drivers/net/sfc/tx.c | 13 | ||||
-rw-r--r-- | drivers/net/sfc/workarounds.h | 2 | ||||
-rw-r--r-- | drivers/net/sfc/xfp_phy.c | 105 |
22 files changed, 475 insertions, 390 deletions
diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig index c535408ad6be..12a82966b577 100644 --- a/drivers/net/sfc/Kconfig +++ b/drivers/net/sfc/Kconfig | |||
@@ -2,7 +2,6 @@ config SFC | |||
2 | tristate "Solarflare Solarstorm SFC4000 support" | 2 | tristate "Solarflare Solarstorm SFC4000 support" |
3 | depends on PCI && INET | 3 | depends on PCI && INET |
4 | select MII | 4 | select MII |
5 | select INET_LRO | ||
6 | select CRC32 | 5 | select CRC32 |
7 | select I2C | 6 | select I2C |
8 | select I2C_ALGOBIT | 7 | select I2C_ALGOBIT |
diff --git a/drivers/net/sfc/bitfield.h b/drivers/net/sfc/bitfield.h index d95c21828014..d54d84c267b9 100644 --- a/drivers/net/sfc/bitfield.h +++ b/drivers/net/sfc/bitfield.h | |||
@@ -543,7 +543,7 @@ typedef union efx_oword { | |||
543 | 543 | ||
544 | /* Static initialiser */ | 544 | /* Static initialiser */ |
545 | #define EFX_OWORD32(a, b, c, d) \ | 545 | #define EFX_OWORD32(a, b, c, d) \ |
546 | { .u32 = { __constant_cpu_to_le32(a), __constant_cpu_to_le32(b), \ | 546 | { .u32 = { cpu_to_le32(a), cpu_to_le32(b), \ |
547 | __constant_cpu_to_le32(c), __constant_cpu_to_le32(d) } } | 547 | cpu_to_le32(c), cpu_to_le32(d) } } |
548 | 548 | ||
549 | #endif /* EFX_BITFIELD_H */ | 549 | #endif /* EFX_BITFIELD_H */ |
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c index 64903496aa9a..5182ac5a1034 100644 --- a/drivers/net/sfc/boards.c +++ b/drivers/net/sfc/boards.c | |||
@@ -26,7 +26,7 @@ static void blink_led_timer(unsigned long context) | |||
26 | { | 26 | { |
27 | struct efx_nic *efx = (struct efx_nic *)context; | 27 | struct efx_nic *efx = (struct efx_nic *)context; |
28 | struct efx_blinker *bl = &efx->board_info.blinker; | 28 | struct efx_blinker *bl = &efx->board_info.blinker; |
29 | efx->board_info.set_fault_led(efx, bl->state); | 29 | efx->board_info.set_id_led(efx, bl->state); |
30 | bl->state = !bl->state; | 30 | bl->state = !bl->state; |
31 | if (bl->resubmit) | 31 | if (bl->resubmit) |
32 | mod_timer(&bl->timer, jiffies + BLINK_INTERVAL); | 32 | mod_timer(&bl->timer, jiffies + BLINK_INTERVAL); |
@@ -48,7 +48,7 @@ static void board_blink(struct efx_nic *efx, bool blink) | |||
48 | blinker->resubmit = false; | 48 | blinker->resubmit = false; |
49 | if (blinker->timer.function) | 49 | if (blinker->timer.function) |
50 | del_timer_sync(&blinker->timer); | 50 | del_timer_sync(&blinker->timer); |
51 | efx->board_info.set_fault_led(efx, false); | 51 | efx->board_info.init_leds(efx); |
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
@@ -185,7 +185,7 @@ static struct i2c_board_info sfe4002_hwmon_info = { | |||
185 | #define SFE4002_RX_LED (0) /* Green */ | 185 | #define SFE4002_RX_LED (0) /* Green */ |
186 | #define SFE4002_TX_LED (1) /* Amber */ | 186 | #define SFE4002_TX_LED (1) /* Amber */ |
187 | 187 | ||
188 | static int sfe4002_init_leds(struct efx_nic *efx) | 188 | static void sfe4002_init_leds(struct efx_nic *efx) |
189 | { | 189 | { |
190 | /* Set the TX and RX LEDs to reflect status and activity, and the | 190 | /* Set the TX and RX LEDs to reflect status and activity, and the |
191 | * fault LED off */ | 191 | * fault LED off */ |
@@ -194,11 +194,9 @@ static int sfe4002_init_leds(struct efx_nic *efx) | |||
194 | xfp_set_led(efx, SFE4002_RX_LED, | 194 | xfp_set_led(efx, SFE4002_RX_LED, |
195 | QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT); | 195 | QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT); |
196 | xfp_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF); | 196 | xfp_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF); |
197 | efx->board_info.blinker.led_num = SFE4002_FAULT_LED; | ||
198 | return 0; | ||
199 | } | 197 | } |
200 | 198 | ||
201 | static void sfe4002_fault_led(struct efx_nic *efx, bool state) | 199 | static void sfe4002_set_id_led(struct efx_nic *efx, bool state) |
202 | { | 200 | { |
203 | xfp_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON : | 201 | xfp_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON : |
204 | QUAKE_LED_OFF); | 202 | QUAKE_LED_OFF); |
@@ -222,7 +220,67 @@ static int sfe4002_init(struct efx_nic *efx) | |||
222 | return rc; | 220 | return rc; |
223 | efx->board_info.monitor = sfe4002_check_hw; | 221 | efx->board_info.monitor = sfe4002_check_hw; |
224 | efx->board_info.init_leds = sfe4002_init_leds; | 222 | efx->board_info.init_leds = sfe4002_init_leds; |
225 | efx->board_info.set_fault_led = sfe4002_fault_led; | 223 | efx->board_info.set_id_led = sfe4002_set_id_led; |
224 | efx->board_info.blink = board_blink; | ||
225 | efx->board_info.fini = efx_fini_lm87; | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | /***************************************************************************** | ||
230 | * Support for the SFN4112F | ||
231 | * | ||
232 | */ | ||
233 | static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */ | ||
234 | |||
235 | static const u8 sfn4112f_lm87_regs[] = { | ||
236 | LM87_IN_LIMITS(0, 0x83, 0x91), /* 2.5V: 1.8V +/- 5% */ | ||
237 | LM87_IN_LIMITS(1, 0x51, 0x5a), /* Vccp1: 1.2V +/- 5% */ | ||
238 | LM87_IN_LIMITS(2, 0xb6, 0xca), /* 3.3V: 3.3V +/- 5% */ | ||
239 | LM87_IN_LIMITS(4, 0xb0, 0xe0), /* 12V: 11-14V */ | ||
240 | LM87_IN_LIMITS(5, 0x44, 0x4b), /* Vccp2: 1.0V +/- 5% */ | ||
241 | LM87_AIN_LIMITS(1, 0x91, 0xa1), /* AIN2: 1.5V +/- 5% */ | ||
242 | LM87_TEMP_INT_LIMITS(10, 60), /* board */ | ||
243 | LM87_TEMP_EXT1_LIMITS(10, 70), /* Falcon */ | ||
244 | 0 | ||
245 | }; | ||
246 | |||
247 | static struct i2c_board_info sfn4112f_hwmon_info = { | ||
248 | I2C_BOARD_INFO("lm87", 0x2e), | ||
249 | .platform_data = &sfn4112f_lm87_channel, | ||
250 | .irq = -1, | ||
251 | }; | ||
252 | |||
253 | #define SFN4112F_ACT_LED 0 | ||
254 | #define SFN4112F_LINK_LED 1 | ||
255 | |||
256 | static void sfn4112f_init_leds(struct efx_nic *efx) | ||
257 | { | ||
258 | xfp_set_led(efx, SFN4112F_ACT_LED, | ||
259 | QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACT); | ||
260 | xfp_set_led(efx, SFN4112F_LINK_LED, | ||
261 | QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT); | ||
262 | } | ||
263 | |||
264 | static void sfn4112f_set_id_led(struct efx_nic *efx, bool state) | ||
265 | { | ||
266 | xfp_set_led(efx, SFN4112F_LINK_LED, | ||
267 | state ? QUAKE_LED_ON : QUAKE_LED_OFF); | ||
268 | } | ||
269 | |||
270 | static int sfn4112f_check_hw(struct efx_nic *efx) | ||
271 | { | ||
272 | /* Mask out unused sensors */ | ||
273 | return efx_check_lm87(efx, ~0x48); | ||
274 | } | ||
275 | |||
276 | static int sfn4112f_init(struct efx_nic *efx) | ||
277 | { | ||
278 | int rc = efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs); | ||
279 | if (rc) | ||
280 | return rc; | ||
281 | efx->board_info.monitor = sfn4112f_check_hw; | ||
282 | efx->board_info.init_leds = sfn4112f_init_leds; | ||
283 | efx->board_info.set_id_led = sfn4112f_set_id_led; | ||
226 | efx->board_info.blink = board_blink; | 284 | efx->board_info.blink = board_blink; |
227 | efx->board_info.fini = efx_fini_lm87; | 285 | efx->board_info.fini = efx_fini_lm87; |
228 | return 0; | 286 | return 0; |
@@ -243,6 +301,8 @@ static struct efx_board_data board_data[] = { | |||
243 | { EFX_BOARD_SFE4002, "SFE4002", "XFP adapter", sfe4002_init }, | 301 | { EFX_BOARD_SFE4002, "SFE4002", "XFP adapter", sfe4002_init }, |
244 | { EFX_BOARD_SFN4111T, "SFN4111T", "100/1000/10GBASE-T adapter", | 302 | { EFX_BOARD_SFN4111T, "SFN4111T", "100/1000/10GBASE-T adapter", |
245 | sfn4111t_init }, | 303 | sfn4111t_init }, |
304 | { EFX_BOARD_SFN4112F, "SFN4112F", "SFP+ adapter", | ||
305 | sfn4112f_init }, | ||
246 | }; | 306 | }; |
247 | 307 | ||
248 | void efx_set_board_info(struct efx_nic *efx, u16 revision_info) | 308 | void efx_set_board_info(struct efx_nic *efx, u16 revision_info) |
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h index d93c6c6a7548..44942de0e080 100644 --- a/drivers/net/sfc/boards.h +++ b/drivers/net/sfc/boards.h | |||
@@ -15,6 +15,7 @@ enum efx_board_type { | |||
15 | EFX_BOARD_SFE4001 = 1, | 15 | EFX_BOARD_SFE4001 = 1, |
16 | EFX_BOARD_SFE4002 = 2, | 16 | EFX_BOARD_SFE4002 = 2, |
17 | EFX_BOARD_SFN4111T = 0x51, | 17 | EFX_BOARD_SFN4111T = 0x51, |
18 | EFX_BOARD_SFN4112F = 0x52, | ||
18 | }; | 19 | }; |
19 | 20 | ||
20 | extern void efx_set_board_info(struct efx_nic *efx, u16 revision_info); | 21 | extern void efx_set_board_info(struct efx_nic *efx, u16 revision_info); |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 847e9bb0098f..00c23b1babca 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -133,6 +133,16 @@ static int phy_flash_cfg; | |||
133 | module_param(phy_flash_cfg, int, 0644); | 133 | module_param(phy_flash_cfg, int, 0644); |
134 | MODULE_PARM_DESC(phy_flash_cfg, "Set PHYs into reflash mode initially"); | 134 | MODULE_PARM_DESC(phy_flash_cfg, "Set PHYs into reflash mode initially"); |
135 | 135 | ||
136 | static unsigned irq_adapt_low_thresh = 10000; | ||
137 | module_param(irq_adapt_low_thresh, uint, 0644); | ||
138 | MODULE_PARM_DESC(irq_adapt_low_thresh, | ||
139 | "Threshold score for reducing IRQ moderation"); | ||
140 | |||
141 | static unsigned irq_adapt_high_thresh = 20000; | ||
142 | module_param(irq_adapt_high_thresh, uint, 0644); | ||
143 | MODULE_PARM_DESC(irq_adapt_high_thresh, | ||
144 | "Threshold score for increasing IRQ moderation"); | ||
145 | |||
136 | /************************************************************************** | 146 | /************************************************************************** |
137 | * | 147 | * |
138 | * Utility functions and prototypes | 148 | * Utility functions and prototypes |
@@ -182,7 +192,6 @@ static int efx_process_channel(struct efx_channel *channel, int rx_quota) | |||
182 | channel->rx_pkt = NULL; | 192 | channel->rx_pkt = NULL; |
183 | } | 193 | } |
184 | 194 | ||
185 | efx_flush_lro(channel); | ||
186 | efx_rx_strategy(channel); | 195 | efx_rx_strategy(channel); |
187 | 196 | ||
188 | efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]); | 197 | efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]); |
@@ -224,12 +233,41 @@ static int efx_poll(struct napi_struct *napi, int budget) | |||
224 | rx_packets = efx_process_channel(channel, budget); | 233 | rx_packets = efx_process_channel(channel, budget); |
225 | 234 | ||
226 | if (rx_packets < budget) { | 235 | if (rx_packets < budget) { |
236 | struct efx_nic *efx = channel->efx; | ||
237 | |||
238 | if (channel->used_flags & EFX_USED_BY_RX && | ||
239 | efx->irq_rx_adaptive && | ||
240 | unlikely(++channel->irq_count == 1000)) { | ||
241 | unsigned old_irq_moderation = channel->irq_moderation; | ||
242 | |||
243 | if (unlikely(channel->irq_mod_score < | ||
244 | irq_adapt_low_thresh)) { | ||
245 | channel->irq_moderation = | ||
246 | max_t(int, | ||
247 | channel->irq_moderation - | ||
248 | FALCON_IRQ_MOD_RESOLUTION, | ||
249 | FALCON_IRQ_MOD_RESOLUTION); | ||
250 | } else if (unlikely(channel->irq_mod_score > | ||
251 | irq_adapt_high_thresh)) { | ||
252 | channel->irq_moderation = | ||
253 | min(channel->irq_moderation + | ||
254 | FALCON_IRQ_MOD_RESOLUTION, | ||
255 | efx->irq_rx_moderation); | ||
256 | } | ||
257 | |||
258 | if (channel->irq_moderation != old_irq_moderation) | ||
259 | falcon_set_int_moderation(channel); | ||
260 | |||
261 | channel->irq_count = 0; | ||
262 | channel->irq_mod_score = 0; | ||
263 | } | ||
264 | |||
227 | /* There is no race here; although napi_disable() will | 265 | /* There is no race here; although napi_disable() will |
228 | * only wait for netif_rx_complete(), this isn't a problem | 266 | * only wait for napi_complete(), this isn't a problem |
229 | * since efx_channel_processed() will have no effect if | 267 | * since efx_channel_processed() will have no effect if |
230 | * interrupts have already been disabled. | 268 | * interrupts have already been disabled. |
231 | */ | 269 | */ |
232 | netif_rx_complete(napi); | 270 | napi_complete(napi); |
233 | efx_channel_processed(channel); | 271 | efx_channel_processed(channel); |
234 | } | 272 | } |
235 | 273 | ||
@@ -558,6 +596,8 @@ static void efx_link_status_changed(struct efx_nic *efx) | |||
558 | 596 | ||
559 | } | 597 | } |
560 | 598 | ||
599 | static void efx_fini_port(struct efx_nic *efx); | ||
600 | |||
561 | /* This call reinitialises the MAC to pick up new PHY settings. The | 601 | /* This call reinitialises the MAC to pick up new PHY settings. The |
562 | * caller must hold the mac_lock */ | 602 | * caller must hold the mac_lock */ |
563 | void __efx_reconfigure_port(struct efx_nic *efx) | 603 | void __efx_reconfigure_port(struct efx_nic *efx) |
@@ -593,8 +633,8 @@ void __efx_reconfigure_port(struct efx_nic *efx) | |||
593 | 633 | ||
594 | fail: | 634 | fail: |
595 | EFX_ERR(efx, "failed to reconfigure MAC\n"); | 635 | EFX_ERR(efx, "failed to reconfigure MAC\n"); |
596 | efx->phy_op->fini(efx); | 636 | efx->port_enabled = false; |
597 | efx->port_initialized = false; | 637 | efx_fini_port(efx); |
598 | } | 638 | } |
599 | 639 | ||
600 | /* Reinitialise the MAC to pick up new PHY settings, even if the port is | 640 | /* Reinitialise the MAC to pick up new PHY settings, even if the port is |
@@ -997,7 +1037,7 @@ static int efx_probe_nic(struct efx_nic *efx) | |||
997 | efx_set_channels(efx); | 1037 | efx_set_channels(efx); |
998 | 1038 | ||
999 | /* Initialise the interrupt moderation settings */ | 1039 | /* Initialise the interrupt moderation settings */ |
1000 | efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec); | 1040 | efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true); |
1001 | 1041 | ||
1002 | return 0; | 1042 | return 0; |
1003 | } | 1043 | } |
@@ -1194,7 +1234,8 @@ void efx_flush_queues(struct efx_nic *efx) | |||
1194 | **************************************************************************/ | 1234 | **************************************************************************/ |
1195 | 1235 | ||
1196 | /* Set interrupt moderation parameters */ | 1236 | /* Set interrupt moderation parameters */ |
1197 | void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs) | 1237 | void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs, |
1238 | bool rx_adaptive) | ||
1198 | { | 1239 | { |
1199 | struct efx_tx_queue *tx_queue; | 1240 | struct efx_tx_queue *tx_queue; |
1200 | struct efx_rx_queue *rx_queue; | 1241 | struct efx_rx_queue *rx_queue; |
@@ -1204,6 +1245,8 @@ void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs) | |||
1204 | efx_for_each_tx_queue(tx_queue, efx) | 1245 | efx_for_each_tx_queue(tx_queue, efx) |
1205 | tx_queue->channel->irq_moderation = tx_usecs; | 1246 | tx_queue->channel->irq_moderation = tx_usecs; |
1206 | 1247 | ||
1248 | efx->irq_rx_adaptive = rx_adaptive; | ||
1249 | efx->irq_rx_moderation = rx_usecs; | ||
1207 | efx_for_each_rx_queue(rx_queue, efx) | 1250 | efx_for_each_rx_queue(rx_queue, efx) |
1208 | rx_queue->channel->irq_moderation = rx_usecs; | 1251 | rx_queue->channel->irq_moderation = rx_usecs; |
1209 | } | 1252 | } |
@@ -1276,18 +1319,11 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) | |||
1276 | static int efx_init_napi(struct efx_nic *efx) | 1319 | static int efx_init_napi(struct efx_nic *efx) |
1277 | { | 1320 | { |
1278 | struct efx_channel *channel; | 1321 | struct efx_channel *channel; |
1279 | int rc; | ||
1280 | 1322 | ||
1281 | efx_for_each_channel(channel, efx) { | 1323 | efx_for_each_channel(channel, efx) { |
1282 | channel->napi_dev = efx->net_dev; | 1324 | channel->napi_dev = efx->net_dev; |
1283 | rc = efx_lro_init(&channel->lro_mgr, efx); | ||
1284 | if (rc) | ||
1285 | goto err; | ||
1286 | } | 1325 | } |
1287 | return 0; | 1326 | return 0; |
1288 | err: | ||
1289 | efx_fini_napi(efx); | ||
1290 | return rc; | ||
1291 | } | 1327 | } |
1292 | 1328 | ||
1293 | static void efx_fini_napi(struct efx_nic *efx) | 1329 | static void efx_fini_napi(struct efx_nic *efx) |
@@ -1295,7 +1331,6 @@ static void efx_fini_napi(struct efx_nic *efx) | |||
1295 | struct efx_channel *channel; | 1331 | struct efx_channel *channel; |
1296 | 1332 | ||
1297 | efx_for_each_channel(channel, efx) { | 1333 | efx_for_each_channel(channel, efx) { |
1298 | efx_lro_fini(&channel->lro_mgr); | ||
1299 | channel->napi_dev = NULL; | 1334 | channel->napi_dev = NULL; |
1300 | } | 1335 | } |
1301 | } | 1336 | } |
@@ -1683,7 +1718,8 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, | |||
1683 | rc = efx->phy_op->init(efx); | 1718 | rc = efx->phy_op->init(efx); |
1684 | if (rc) | 1719 | if (rc) |
1685 | ok = false; | 1720 | ok = false; |
1686 | } else | 1721 | } |
1722 | if (!ok) | ||
1687 | efx->port_initialized = false; | 1723 | efx->port_initialized = false; |
1688 | } | 1724 | } |
1689 | 1725 | ||
@@ -1864,8 +1900,8 @@ static struct efx_phy_operations efx_dummy_phy_operations = { | |||
1864 | 1900 | ||
1865 | static struct efx_board efx_dummy_board_info = { | 1901 | static struct efx_board efx_dummy_board_info = { |
1866 | .init = efx_port_dummy_op_int, | 1902 | .init = efx_port_dummy_op_int, |
1867 | .init_leds = efx_port_dummy_op_int, | 1903 | .init_leds = efx_port_dummy_op_void, |
1868 | .set_fault_led = efx_port_dummy_op_blink, | 1904 | .set_id_led = efx_port_dummy_op_blink, |
1869 | .monitor = efx_port_dummy_op_int, | 1905 | .monitor = efx_port_dummy_op_int, |
1870 | .blink = efx_port_dummy_op_blink, | 1906 | .blink = efx_port_dummy_op_blink, |
1871 | .fini = efx_port_dummy_op_void, | 1907 | .fini = efx_port_dummy_op_void, |
@@ -2127,7 +2163,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, | |||
2127 | net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG | | 2163 | net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG | |
2128 | NETIF_F_HIGHDMA | NETIF_F_TSO); | 2164 | NETIF_F_HIGHDMA | NETIF_F_TSO); |
2129 | if (lro) | 2165 | if (lro) |
2130 | net_dev->features |= NETIF_F_LRO; | 2166 | net_dev->features |= NETIF_F_GRO; |
2131 | /* Mask for features that also apply to VLAN devices */ | 2167 | /* Mask for features that also apply to VLAN devices */ |
2132 | net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG | | 2168 | net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG | |
2133 | NETIF_F_HIGHDMA | NETIF_F_TSO); | 2169 | NETIF_F_HIGHDMA | NETIF_F_TSO); |
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index 55d0f131b0e9..da157aa74b83 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h | |||
@@ -52,7 +52,7 @@ extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); | |||
52 | extern void efx_suspend(struct efx_nic *efx); | 52 | extern void efx_suspend(struct efx_nic *efx); |
53 | extern void efx_resume(struct efx_nic *efx); | 53 | extern void efx_resume(struct efx_nic *efx); |
54 | extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, | 54 | extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, |
55 | int rx_usecs); | 55 | int rx_usecs, bool rx_adaptive); |
56 | extern int efx_request_power(struct efx_nic *efx, int mw, const char *name); | 56 | extern int efx_request_power(struct efx_nic *efx, int mw, const char *name); |
57 | extern void efx_hex_dump(const u8 *, unsigned int, const char *); | 57 | extern void efx_hex_dump(const u8 *, unsigned int, const char *); |
58 | 58 | ||
@@ -80,7 +80,7 @@ static inline void efx_schedule_channel(struct efx_channel *channel) | |||
80 | channel->channel, raw_smp_processor_id()); | 80 | channel->channel, raw_smp_processor_id()); |
81 | channel->work_pending = true; | 81 | channel->work_pending = true; |
82 | 82 | ||
83 | netif_rx_schedule(&channel->napi_str); | 83 | napi_schedule(&channel->napi_str); |
84 | } | 84 | } |
85 | 85 | ||
86 | #endif /* EFX_EFX_H */ | 86 | #endif /* EFX_EFX_H */ |
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 7b5924c039b3..64309f4e8b19 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
@@ -529,7 +529,14 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev) | |||
529 | { | 529 | { |
530 | struct efx_nic *efx = netdev_priv(net_dev); | 530 | struct efx_nic *efx = netdev_priv(net_dev); |
531 | 531 | ||
532 | return mii_nway_restart(&efx->mii); | 532 | if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) { |
533 | mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN, | ||
534 | MDIO_MMDREG_CTRL1, | ||
535 | __ffs(BMCR_ANRESTART), true); | ||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | return -EOPNOTSUPP; | ||
533 | } | 540 | } |
534 | 541 | ||
535 | static u32 efx_ethtool_get_link(struct net_device *net_dev) | 542 | static u32 efx_ethtool_get_link(struct net_device *net_dev) |
@@ -597,7 +604,6 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev, | |||
597 | { | 604 | { |
598 | struct efx_nic *efx = netdev_priv(net_dev); | 605 | struct efx_nic *efx = netdev_priv(net_dev); |
599 | struct efx_tx_queue *tx_queue; | 606 | struct efx_tx_queue *tx_queue; |
600 | struct efx_rx_queue *rx_queue; | ||
601 | struct efx_channel *channel; | 607 | struct efx_channel *channel; |
602 | 608 | ||
603 | memset(coalesce, 0, sizeof(*coalesce)); | 609 | memset(coalesce, 0, sizeof(*coalesce)); |
@@ -615,14 +621,8 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev, | |||
615 | } | 621 | } |
616 | } | 622 | } |
617 | 623 | ||
618 | /* Find lowest IRQ moderation across all used RX queues */ | 624 | coalesce->use_adaptive_rx_coalesce = efx->irq_rx_adaptive; |
619 | coalesce->rx_coalesce_usecs_irq = ~((u32) 0); | 625 | coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation; |
620 | efx_for_each_rx_queue(rx_queue, efx) { | ||
621 | channel = rx_queue->channel; | ||
622 | if (channel->irq_moderation < coalesce->rx_coalesce_usecs_irq) | ||
623 | coalesce->rx_coalesce_usecs_irq = | ||
624 | channel->irq_moderation; | ||
625 | } | ||
626 | 626 | ||
627 | return 0; | 627 | return 0; |
628 | } | 628 | } |
@@ -636,10 +636,9 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, | |||
636 | struct efx_nic *efx = netdev_priv(net_dev); | 636 | struct efx_nic *efx = netdev_priv(net_dev); |
637 | struct efx_channel *channel; | 637 | struct efx_channel *channel; |
638 | struct efx_tx_queue *tx_queue; | 638 | struct efx_tx_queue *tx_queue; |
639 | unsigned tx_usecs, rx_usecs; | 639 | unsigned tx_usecs, rx_usecs, adaptive; |
640 | 640 | ||
641 | if (coalesce->use_adaptive_rx_coalesce || | 641 | if (coalesce->use_adaptive_tx_coalesce) |
642 | coalesce->use_adaptive_tx_coalesce) | ||
643 | return -EOPNOTSUPP; | 642 | return -EOPNOTSUPP; |
644 | 643 | ||
645 | if (coalesce->rx_coalesce_usecs || coalesce->tx_coalesce_usecs) { | 644 | if (coalesce->rx_coalesce_usecs || coalesce->tx_coalesce_usecs) { |
@@ -650,6 +649,7 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, | |||
650 | 649 | ||
651 | rx_usecs = coalesce->rx_coalesce_usecs_irq; | 650 | rx_usecs = coalesce->rx_coalesce_usecs_irq; |
652 | tx_usecs = coalesce->tx_coalesce_usecs_irq; | 651 | tx_usecs = coalesce->tx_coalesce_usecs_irq; |
652 | adaptive = coalesce->use_adaptive_rx_coalesce; | ||
653 | 653 | ||
654 | /* If the channel is shared only allow RX parameters to be set */ | 654 | /* If the channel is shared only allow RX parameters to be set */ |
655 | efx_for_each_tx_queue(tx_queue, efx) { | 655 | efx_for_each_tx_queue(tx_queue, efx) { |
@@ -661,7 +661,7 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, | |||
661 | } | 661 | } |
662 | } | 662 | } |
663 | 663 | ||
664 | efx_init_irq_moderation(efx, tx_usecs, rx_usecs); | 664 | efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive); |
665 | 665 | ||
666 | /* Reset channel to pick up new moderation value. Note that | 666 | /* Reset channel to pick up new moderation value. Note that |
667 | * this may change the value of the irq_moderation field | 667 | * this may change the value of the irq_moderation field |
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 064307c2277e..d4629ab2c614 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
@@ -39,11 +39,16 @@ | |||
39 | * @next_buffer_table: First available buffer table id | 39 | * @next_buffer_table: First available buffer table id |
40 | * @pci_dev2: The secondary PCI device if present | 40 | * @pci_dev2: The secondary PCI device if present |
41 | * @i2c_data: Operations and state for I2C bit-bashing algorithm | 41 | * @i2c_data: Operations and state for I2C bit-bashing algorithm |
42 | * @int_error_count: Number of internal errors seen recently | ||
43 | * @int_error_expire: Time at which error count will be expired | ||
42 | */ | 44 | */ |
43 | struct falcon_nic_data { | 45 | struct falcon_nic_data { |
44 | unsigned next_buffer_table; | 46 | unsigned next_buffer_table; |
45 | struct pci_dev *pci_dev2; | 47 | struct pci_dev *pci_dev2; |
46 | struct i2c_algo_bit_data i2c_data; | 48 | struct i2c_algo_bit_data i2c_data; |
49 | |||
50 | unsigned int_error_count; | ||
51 | unsigned long int_error_expire; | ||
47 | }; | 52 | }; |
48 | 53 | ||
49 | /************************************************************************** | 54 | /************************************************************************** |
@@ -119,8 +124,12 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); | |||
119 | #define FALCON_EVQ_SIZE 4096 | 124 | #define FALCON_EVQ_SIZE 4096 |
120 | #define FALCON_EVQ_MASK (FALCON_EVQ_SIZE - 1) | 125 | #define FALCON_EVQ_MASK (FALCON_EVQ_SIZE - 1) |
121 | 126 | ||
122 | /* Max number of internal errors. After this resets will not be performed */ | 127 | /* If FALCON_MAX_INT_ERRORS internal errors occur within |
123 | #define FALCON_MAX_INT_ERRORS 4 | 128 | * FALCON_INT_ERROR_EXPIRE seconds, we consider the NIC broken and |
129 | * disable it. | ||
130 | */ | ||
131 | #define FALCON_INT_ERROR_EXPIRE 3600 | ||
132 | #define FALCON_MAX_INT_ERRORS 5 | ||
124 | 133 | ||
125 | /* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times | 134 | /* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times |
126 | */ | 135 | */ |
@@ -146,13 +155,6 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); | |||
146 | /* Dummy SRAM size code */ | 155 | /* Dummy SRAM size code */ |
147 | #define SRM_NB_BSZ_ONCHIP_ONLY (-1) | 156 | #define SRM_NB_BSZ_ONCHIP_ONLY (-1) |
148 | 157 | ||
149 | /* Be nice if these (or equiv.) were in linux/pci_regs.h, but they're not. */ | ||
150 | #define PCI_EXP_DEVCAP_PWR_VAL_LBN 18 | ||
151 | #define PCI_EXP_DEVCAP_PWR_SCL_LBN 26 | ||
152 | #define PCI_EXP_DEVCTL_PAYLOAD_LBN 5 | ||
153 | #define PCI_EXP_LNKSTA_LNK_WID 0x3f0 | ||
154 | #define PCI_EXP_LNKSTA_LNK_WID_LBN 4 | ||
155 | |||
156 | #define FALCON_IS_DUAL_FUNC(efx) \ | 158 | #define FALCON_IS_DUAL_FUNC(efx) \ |
157 | (falcon_rev(efx) < FALCON_REV_B0) | 159 | (falcon_rev(efx) < FALCON_REV_B0) |
158 | 160 | ||
@@ -727,6 +729,9 @@ static void falcon_handle_tx_event(struct efx_channel *channel, | |||
727 | tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, TX_EV_DESC_PTR); | 729 | tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, TX_EV_DESC_PTR); |
728 | tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL); | 730 | tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL); |
729 | tx_queue = &efx->tx_queue[tx_ev_q_label]; | 731 | tx_queue = &efx->tx_queue[tx_ev_q_label]; |
732 | channel->irq_mod_score += | ||
733 | (tx_ev_desc_ptr - tx_queue->read_count) & | ||
734 | efx->type->txd_ring_mask; | ||
730 | efx_xmit_done(tx_queue, tx_ev_desc_ptr); | 735 | efx_xmit_done(tx_queue, tx_ev_desc_ptr); |
731 | } else if (EFX_QWORD_FIELD(*event, TX_EV_WQ_FF_FULL)) { | 736 | } else if (EFX_QWORD_FIELD(*event, TX_EV_WQ_FF_FULL)) { |
732 | /* Rewrite the FIFO write pointer */ | 737 | /* Rewrite the FIFO write pointer */ |
@@ -896,6 +901,8 @@ static void falcon_handle_rx_event(struct efx_channel *channel, | |||
896 | discard = true; | 901 | discard = true; |
897 | } | 902 | } |
898 | 903 | ||
904 | channel->irq_mod_score += 2; | ||
905 | |||
899 | /* Handle received packet */ | 906 | /* Handle received packet */ |
900 | efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt, | 907 | efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt, |
901 | checksummed, discard); | 908 | checksummed, discard); |
@@ -1073,14 +1080,15 @@ void falcon_set_int_moderation(struct efx_channel *channel) | |||
1073 | * program is based at 0. So actual interrupt moderation | 1080 | * program is based at 0. So actual interrupt moderation |
1074 | * achieved is ((x + 1) * res). | 1081 | * achieved is ((x + 1) * res). |
1075 | */ | 1082 | */ |
1076 | unsigned int res = 5; | 1083 | channel->irq_moderation -= (channel->irq_moderation % |
1077 | channel->irq_moderation -= (channel->irq_moderation % res); | 1084 | FALCON_IRQ_MOD_RESOLUTION); |
1078 | if (channel->irq_moderation < res) | 1085 | if (channel->irq_moderation < FALCON_IRQ_MOD_RESOLUTION) |
1079 | channel->irq_moderation = res; | 1086 | channel->irq_moderation = FALCON_IRQ_MOD_RESOLUTION; |
1080 | EFX_POPULATE_DWORD_2(timer_cmd, | 1087 | EFX_POPULATE_DWORD_2(timer_cmd, |
1081 | TIMER_MODE, TIMER_MODE_INT_HLDOFF, | 1088 | TIMER_MODE, TIMER_MODE_INT_HLDOFF, |
1082 | TIMER_VAL, | 1089 | TIMER_VAL, |
1083 | (channel->irq_moderation / res) - 1); | 1090 | channel->irq_moderation / |
1091 | FALCON_IRQ_MOD_RESOLUTION - 1); | ||
1084 | } else { | 1092 | } else { |
1085 | EFX_POPULATE_DWORD_2(timer_cmd, | 1093 | EFX_POPULATE_DWORD_2(timer_cmd, |
1086 | TIMER_MODE, TIMER_MODE_DIS, | 1094 | TIMER_MODE, TIMER_MODE_DIS, |
@@ -1187,31 +1195,29 @@ static void falcon_poll_flush_events(struct efx_nic *efx) | |||
1187 | struct efx_channel *channel = &efx->channel[0]; | 1195 | struct efx_channel *channel = &efx->channel[0]; |
1188 | struct efx_tx_queue *tx_queue; | 1196 | struct efx_tx_queue *tx_queue; |
1189 | struct efx_rx_queue *rx_queue; | 1197 | struct efx_rx_queue *rx_queue; |
1190 | unsigned int read_ptr, i; | 1198 | unsigned int read_ptr = channel->eventq_read_ptr; |
1199 | unsigned int end_ptr = (read_ptr - 1) & FALCON_EVQ_MASK; | ||
1191 | 1200 | ||
1192 | read_ptr = channel->eventq_read_ptr; | 1201 | do { |
1193 | for (i = 0; i < FALCON_EVQ_SIZE; ++i) { | ||
1194 | efx_qword_t *event = falcon_event(channel, read_ptr); | 1202 | efx_qword_t *event = falcon_event(channel, read_ptr); |
1195 | int ev_code, ev_sub_code, ev_queue; | 1203 | int ev_code, ev_sub_code, ev_queue; |
1196 | bool ev_failed; | 1204 | bool ev_failed; |
1205 | |||
1197 | if (!falcon_event_present(event)) | 1206 | if (!falcon_event_present(event)) |
1198 | break; | 1207 | break; |
1199 | 1208 | ||
1200 | ev_code = EFX_QWORD_FIELD(*event, EV_CODE); | 1209 | ev_code = EFX_QWORD_FIELD(*event, EV_CODE); |
1201 | if (ev_code != DRIVER_EV_DECODE) | ||
1202 | continue; | ||
1203 | |||
1204 | ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE); | 1210 | ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE); |
1205 | switch (ev_sub_code) { | 1211 | if (ev_code == DRIVER_EV_DECODE && |
1206 | case TX_DESCQ_FLS_DONE_EV_DECODE: | 1212 | ev_sub_code == TX_DESCQ_FLS_DONE_EV_DECODE) { |
1207 | ev_queue = EFX_QWORD_FIELD(*event, | 1213 | ev_queue = EFX_QWORD_FIELD(*event, |
1208 | DRIVER_EV_TX_DESCQ_ID); | 1214 | DRIVER_EV_TX_DESCQ_ID); |
1209 | if (ev_queue < EFX_TX_QUEUE_COUNT) { | 1215 | if (ev_queue < EFX_TX_QUEUE_COUNT) { |
1210 | tx_queue = efx->tx_queue + ev_queue; | 1216 | tx_queue = efx->tx_queue + ev_queue; |
1211 | tx_queue->flushed = true; | 1217 | tx_queue->flushed = true; |
1212 | } | 1218 | } |
1213 | break; | 1219 | } else if (ev_code == DRIVER_EV_DECODE && |
1214 | case RX_DESCQ_FLS_DONE_EV_DECODE: | 1220 | ev_sub_code == RX_DESCQ_FLS_DONE_EV_DECODE) { |
1215 | ev_queue = EFX_QWORD_FIELD(*event, | 1221 | ev_queue = EFX_QWORD_FIELD(*event, |
1216 | DRIVER_EV_RX_DESCQ_ID); | 1222 | DRIVER_EV_RX_DESCQ_ID); |
1217 | ev_failed = EFX_QWORD_FIELD(*event, | 1223 | ev_failed = EFX_QWORD_FIELD(*event, |
@@ -1225,11 +1231,10 @@ static void falcon_poll_flush_events(struct efx_nic *efx) | |||
1225 | else | 1231 | else |
1226 | rx_queue->flushed = true; | 1232 | rx_queue->flushed = true; |
1227 | } | 1233 | } |
1228 | break; | ||
1229 | } | 1234 | } |
1230 | 1235 | ||
1231 | read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK; | 1236 | read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK; |
1232 | } | 1237 | } while (read_ptr != end_ptr); |
1233 | } | 1238 | } |
1234 | 1239 | ||
1235 | /* Handle tx and rx flushes at the same time, since they run in | 1240 | /* Handle tx and rx flushes at the same time, since they run in |
@@ -1377,7 +1382,6 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) | |||
1377 | efx_oword_t *int_ker = efx->irq_status.addr; | 1382 | efx_oword_t *int_ker = efx->irq_status.addr; |
1378 | efx_oword_t fatal_intr; | 1383 | efx_oword_t fatal_intr; |
1379 | int error, mem_perr; | 1384 | int error, mem_perr; |
1380 | static int n_int_errors; | ||
1381 | 1385 | ||
1382 | falcon_read(efx, &fatal_intr, FATAL_INTR_REG_KER); | 1386 | falcon_read(efx, &fatal_intr, FATAL_INTR_REG_KER); |
1383 | error = EFX_OWORD_FIELD(fatal_intr, INT_KER_ERROR); | 1387 | error = EFX_OWORD_FIELD(fatal_intr, INT_KER_ERROR); |
@@ -1404,7 +1408,14 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) | |||
1404 | pci_clear_master(nic_data->pci_dev2); | 1408 | pci_clear_master(nic_data->pci_dev2); |
1405 | falcon_disable_interrupts(efx); | 1409 | falcon_disable_interrupts(efx); |
1406 | 1410 | ||
1407 | if (++n_int_errors < FALCON_MAX_INT_ERRORS) { | 1411 | /* Count errors and reset or disable the NIC accordingly */ |
1412 | if (nic_data->int_error_count == 0 || | ||
1413 | time_after(jiffies, nic_data->int_error_expire)) { | ||
1414 | nic_data->int_error_count = 0; | ||
1415 | nic_data->int_error_expire = | ||
1416 | jiffies + FALCON_INT_ERROR_EXPIRE * HZ; | ||
1417 | } | ||
1418 | if (++nic_data->int_error_count < FALCON_MAX_INT_ERRORS) { | ||
1408 | EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n"); | 1419 | EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n"); |
1409 | efx_schedule_reset(efx, RESET_TYPE_INT_ERROR); | 1420 | efx_schedule_reset(efx, RESET_TYPE_INT_ERROR); |
1410 | } else { | 1421 | } else { |
@@ -1423,6 +1434,7 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) | |||
1423 | { | 1434 | { |
1424 | struct efx_nic *efx = dev_id; | 1435 | struct efx_nic *efx = dev_id; |
1425 | efx_oword_t *int_ker = efx->irq_status.addr; | 1436 | efx_oword_t *int_ker = efx->irq_status.addr; |
1437 | irqreturn_t result = IRQ_NONE; | ||
1426 | struct efx_channel *channel; | 1438 | struct efx_channel *channel; |
1427 | efx_dword_t reg; | 1439 | efx_dword_t reg; |
1428 | u32 queues; | 1440 | u32 queues; |
@@ -1437,23 +1449,24 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) | |||
1437 | if (unlikely(syserr)) | 1449 | if (unlikely(syserr)) |
1438 | return falcon_fatal_interrupt(efx); | 1450 | return falcon_fatal_interrupt(efx); |
1439 | 1451 | ||
1440 | if (queues == 0) | ||
1441 | return IRQ_NONE; | ||
1442 | |||
1443 | efx->last_irq_cpu = raw_smp_processor_id(); | ||
1444 | EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n", | ||
1445 | irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg)); | ||
1446 | |||
1447 | /* Schedule processing of any interrupting queues */ | 1452 | /* Schedule processing of any interrupting queues */ |
1448 | channel = &efx->channel[0]; | 1453 | efx_for_each_channel(channel, efx) { |
1449 | while (queues) { | 1454 | if ((queues & 1) || |
1450 | if (queues & 0x01) | 1455 | falcon_event_present( |
1456 | falcon_event(channel, channel->eventq_read_ptr))) { | ||
1451 | efx_schedule_channel(channel); | 1457 | efx_schedule_channel(channel); |
1452 | channel++; | 1458 | result = IRQ_HANDLED; |
1459 | } | ||
1453 | queues >>= 1; | 1460 | queues >>= 1; |
1454 | } | 1461 | } |
1455 | 1462 | ||
1456 | return IRQ_HANDLED; | 1463 | if (result == IRQ_HANDLED) { |
1464 | efx->last_irq_cpu = raw_smp_processor_id(); | ||
1465 | EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n", | ||
1466 | irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg)); | ||
1467 | } | ||
1468 | |||
1469 | return result; | ||
1457 | } | 1470 | } |
1458 | 1471 | ||
1459 | 1472 | ||
@@ -2249,6 +2262,7 @@ static int falcon_probe_phy(struct efx_nic *efx) | |||
2249 | efx->phy_op = &falcon_sft9001_phy_ops; | 2262 | efx->phy_op = &falcon_sft9001_phy_ops; |
2250 | break; | 2263 | break; |
2251 | case PHY_TYPE_QT2022C2: | 2264 | case PHY_TYPE_QT2022C2: |
2265 | case PHY_TYPE_QT2025C: | ||
2252 | efx->phy_op = &falcon_xfp_phy_ops; | 2266 | efx->phy_op = &falcon_xfp_phy_ops; |
2253 | break; | 2267 | break; |
2254 | default: | 2268 | default: |
@@ -3113,8 +3127,10 @@ void falcon_remove_nic(struct efx_nic *efx) | |||
3113 | struct falcon_nic_data *nic_data = efx->nic_data; | 3127 | struct falcon_nic_data *nic_data = efx->nic_data; |
3114 | int rc; | 3128 | int rc; |
3115 | 3129 | ||
3130 | /* Remove I2C adapter and clear it in preparation for a retry */ | ||
3116 | rc = i2c_del_adapter(&efx->i2c_adap); | 3131 | rc = i2c_del_adapter(&efx->i2c_adap); |
3117 | BUG_ON(rc); | 3132 | BUG_ON(rc); |
3133 | memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap)); | ||
3118 | 3134 | ||
3119 | falcon_remove_spi_devices(efx); | 3135 | falcon_remove_spi_devices(efx); |
3120 | falcon_free_buffer(efx, &efx->irq_status); | 3136 | falcon_free_buffer(efx, &efx->irq_status); |
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h index 7869c3d74383..77f2e0db7ca1 100644 --- a/drivers/net/sfc/falcon.h +++ b/drivers/net/sfc/falcon.h | |||
@@ -85,6 +85,8 @@ extern void falcon_set_int_moderation(struct efx_channel *channel); | |||
85 | extern void falcon_disable_interrupts(struct efx_nic *efx); | 85 | extern void falcon_disable_interrupts(struct efx_nic *efx); |
86 | extern void falcon_fini_interrupt(struct efx_nic *efx); | 86 | extern void falcon_fini_interrupt(struct efx_nic *efx); |
87 | 87 | ||
88 | #define FALCON_IRQ_MOD_RESOLUTION 5 | ||
89 | |||
88 | /* Global Resources */ | 90 | /* Global Resources */ |
89 | extern int falcon_probe_nic(struct efx_nic *efx); | 91 | extern int falcon_probe_nic(struct efx_nic *efx); |
90 | extern int falcon_probe_resources(struct efx_nic *efx); | 92 | extern int falcon_probe_resources(struct efx_nic *efx); |
diff --git a/drivers/net/sfc/falcon_io.h b/drivers/net/sfc/falcon_io.h index c16da3149fa9..8883092dae97 100644 --- a/drivers/net/sfc/falcon_io.h +++ b/drivers/net/sfc/falcon_io.h | |||
@@ -238,18 +238,21 @@ static inline void falcon_writel_page(struct efx_nic *efx, efx_dword_t *value, | |||
238 | /* Write dword to Falcon page-mapped register with an extra lock. | 238 | /* Write dword to Falcon page-mapped register with an extra lock. |
239 | * | 239 | * |
240 | * As for falcon_writel_page(), but for a register that suffers from | 240 | * As for falcon_writel_page(), but for a register that suffers from |
241 | * SFC bug 3181. Take out a lock so the BIU collector cannot be | 241 | * SFC bug 3181. If writing to page 0, take out a lock so the BIU |
242 | * confused. */ | 242 | * collector cannot be confused. |
243 | */ | ||
243 | static inline void falcon_writel_page_locked(struct efx_nic *efx, | 244 | static inline void falcon_writel_page_locked(struct efx_nic *efx, |
244 | efx_dword_t *value, | 245 | efx_dword_t *value, |
245 | unsigned int reg, | 246 | unsigned int reg, |
246 | unsigned int page) | 247 | unsigned int page) |
247 | { | 248 | { |
248 | unsigned long flags; | 249 | unsigned long flags = 0; |
249 | 250 | ||
250 | spin_lock_irqsave(&efx->biu_lock, flags); | 251 | if (page == 0) |
252 | spin_lock_irqsave(&efx->biu_lock, flags); | ||
251 | falcon_writel(efx, value, FALCON_PAGED_REG(page, reg)); | 253 | falcon_writel(efx, value, FALCON_PAGED_REG(page, reg)); |
252 | spin_unlock_irqrestore(&efx->biu_lock, flags); | 254 | if (page == 0) |
255 | spin_unlock_irqrestore(&efx->biu_lock, flags); | ||
253 | } | 256 | } |
254 | 257 | ||
255 | #endif /* EFX_FALCON_IO_H */ | 258 | #endif /* EFX_FALCON_IO_H */ |
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index f9e2f95c3b48..9f5ec3eb3418 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c | |||
@@ -17,6 +17,21 @@ | |||
17 | #include "boards.h" | 17 | #include "boards.h" |
18 | #include "workarounds.h" | 18 | #include "workarounds.h" |
19 | 19 | ||
20 | unsigned mdio_id_oui(u32 id) | ||
21 | { | ||
22 | unsigned oui = 0; | ||
23 | int i; | ||
24 | |||
25 | /* The bits of the OUI are designated a..x, with a=0 and b variable. | ||
26 | * In the id register c is the MSB but the OUI is conventionally | ||
27 | * written as bytes h..a, p..i, x..q. Reorder the bits accordingly. */ | ||
28 | for (i = 0; i < 22; ++i) | ||
29 | if (id & (1 << (i + 10))) | ||
30 | oui |= 1 << (i ^ 7); | ||
31 | |||
32 | return oui; | ||
33 | } | ||
34 | |||
20 | int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, | 35 | int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, |
21 | int spins, int spintime) | 36 | int spins, int spintime) |
22 | { | 37 | { |
@@ -125,24 +140,25 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, | |||
125 | int mdio_clause45_check_mmds(struct efx_nic *efx, | 140 | int mdio_clause45_check_mmds(struct efx_nic *efx, |
126 | unsigned int mmd_mask, unsigned int fatal_mask) | 141 | unsigned int mmd_mask, unsigned int fatal_mask) |
127 | { | 142 | { |
143 | int mmd = 0, probe_mmd, devs0, devs1; | ||
128 | u32 devices; | 144 | u32 devices; |
129 | int mmd = 0, probe_mmd; | ||
130 | 145 | ||
131 | /* Historically we have probed the PHYXS to find out what devices are | 146 | /* Historically we have probed the PHYXS to find out what devices are |
132 | * present,but that doesn't work so well if the PHYXS isn't expected | 147 | * present,but that doesn't work so well if the PHYXS isn't expected |
133 | * to exist, if so just find the first item in the list supplied. */ | 148 | * to exist, if so just find the first item in the list supplied. */ |
134 | probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS : | 149 | probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS : |
135 | __ffs(mmd_mask); | 150 | __ffs(mmd_mask); |
136 | devices = (mdio_clause45_read(efx, efx->mii.phy_id, | ||
137 | probe_mmd, MDIO_MMDREG_DEVS0) | | ||
138 | mdio_clause45_read(efx, efx->mii.phy_id, | ||
139 | probe_mmd, MDIO_MMDREG_DEVS1) << 16); | ||
140 | 151 | ||
141 | /* Check all the expected MMDs are present */ | 152 | /* Check all the expected MMDs are present */ |
142 | if (devices < 0) { | 153 | devs0 = mdio_clause45_read(efx, efx->mii.phy_id, |
154 | probe_mmd, MDIO_MMDREG_DEVS0); | ||
155 | devs1 = mdio_clause45_read(efx, efx->mii.phy_id, | ||
156 | probe_mmd, MDIO_MMDREG_DEVS1); | ||
157 | if (devs0 < 0 || devs1 < 0) { | ||
143 | EFX_ERR(efx, "failed to read devices present\n"); | 158 | EFX_ERR(efx, "failed to read devices present\n"); |
144 | return -EIO; | 159 | return -EIO; |
145 | } | 160 | } |
161 | devices = devs0 | (devs1 << 16); | ||
146 | if ((devices & mmd_mask) != mmd_mask) { | 162 | if ((devices & mmd_mask) != mmd_mask) { |
147 | EFX_ERR(efx, "required MMDs not present: got %x, " | 163 | EFX_ERR(efx, "required MMDs not present: got %x, " |
148 | "wanted %x\n", devices, mmd_mask); | 164 | "wanted %x\n", devices, mmd_mask); |
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index 8ba49773ce7e..7014d2279c20 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h | |||
@@ -70,10 +70,10 @@ | |||
70 | #define MDIO_MMDREG_STAT1_LPABLE_LBN (1) | 70 | #define MDIO_MMDREG_STAT1_LPABLE_LBN (1) |
71 | #define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1) | 71 | #define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1) |
72 | 72 | ||
73 | /* Bits in ID reg */ | 73 | /* Bits in combined ID regs */ |
74 | #define MDIO_ID_REV(_id32) (_id32 & 0xf) | 74 | static inline unsigned mdio_id_rev(u32 id) { return id & 0xf; } |
75 | #define MDIO_ID_MODEL(_id32) ((_id32 >> 4) & 0x3f) | 75 | static inline unsigned mdio_id_model(u32 id) { return (id >> 4) & 0x3f; } |
76 | #define MDIO_ID_OUI(_id32) (_id32 >> 10) | 76 | extern unsigned mdio_id_oui(u32 id); |
77 | 77 | ||
78 | /* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out | 78 | /* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out |
79 | * so the 'bit present' bit number of an MMD is the number of | 79 | * so the 'bit present' bit number of an MMD is the number of |
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c index 665cafb88d6a..820c233c3ea0 100644 --- a/drivers/net/sfc/mtd.c +++ b/drivers/net/sfc/mtd.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #define EFX_DRIVER_NAME "sfc_mtd" | 15 | #define EFX_DRIVER_NAME "sfc_mtd" |
16 | #include "net_driver.h" | 16 | #include "net_driver.h" |
17 | #include "spi.h" | 17 | #include "spi.h" |
18 | #include "efx.h" | ||
18 | 19 | ||
19 | #define EFX_SPI_VERIFY_BUF_LEN 16 | 20 | #define EFX_SPI_VERIFY_BUF_LEN 16 |
20 | 21 | ||
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index e019ad1fb9a0..e169e5dcd1e6 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -25,15 +25,11 @@ | |||
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | #include <linux/highmem.h> | 26 | #include <linux/highmem.h> |
27 | #include <linux/workqueue.h> | 27 | #include <linux/workqueue.h> |
28 | #include <linux/inet_lro.h> | ||
29 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
30 | 29 | ||
31 | #include "enum.h" | 30 | #include "enum.h" |
32 | #include "bitfield.h" | 31 | #include "bitfield.h" |
33 | 32 | ||
34 | #define EFX_MAX_LRO_DESCRIPTORS 8 | ||
35 | #define EFX_MAX_LRO_AGGR MAX_SKB_FRAGS | ||
36 | |||
37 | /************************************************************************** | 33 | /************************************************************************** |
38 | * | 34 | * |
39 | * Build definitions | 35 | * Build definitions |
@@ -340,13 +336,12 @@ enum efx_rx_alloc_method { | |||
340 | * @eventq_read_ptr: Event queue read pointer | 336 | * @eventq_read_ptr: Event queue read pointer |
341 | * @last_eventq_read_ptr: Last event queue read pointer value. | 337 | * @last_eventq_read_ptr: Last event queue read pointer value. |
342 | * @eventq_magic: Event queue magic value for driver-generated test events | 338 | * @eventq_magic: Event queue magic value for driver-generated test events |
343 | * @lro_mgr: LRO state | 339 | * @irq_count: Number of IRQs since last adaptive moderation decision |
340 | * @irq_mod_score: IRQ moderation score | ||
344 | * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors | 341 | * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors |
345 | * and diagnostic counters | 342 | * and diagnostic counters |
346 | * @rx_alloc_push_pages: RX allocation method currently in use for pushing | 343 | * @rx_alloc_push_pages: RX allocation method currently in use for pushing |
347 | * descriptors | 344 | * descriptors |
348 | * @rx_alloc_pop_pages: RX allocation method currently in use for popping | ||
349 | * descriptors | ||
350 | * @n_rx_tobe_disc: Count of RX_TOBE_DISC errors | 345 | * @n_rx_tobe_disc: Count of RX_TOBE_DISC errors |
351 | * @n_rx_ip_frag_err: Count of RX IP fragment errors | 346 | * @n_rx_ip_frag_err: Count of RX IP fragment errors |
352 | * @n_rx_ip_hdr_chksum_err: Count of RX IP header checksum errors | 347 | * @n_rx_ip_hdr_chksum_err: Count of RX IP header checksum errors |
@@ -371,10 +366,11 @@ struct efx_channel { | |||
371 | unsigned int last_eventq_read_ptr; | 366 | unsigned int last_eventq_read_ptr; |
372 | unsigned int eventq_magic; | 367 | unsigned int eventq_magic; |
373 | 368 | ||
374 | struct net_lro_mgr lro_mgr; | 369 | unsigned int irq_count; |
370 | unsigned int irq_mod_score; | ||
371 | |||
375 | int rx_alloc_level; | 372 | int rx_alloc_level; |
376 | int rx_alloc_push_pages; | 373 | int rx_alloc_push_pages; |
377 | int rx_alloc_pop_pages; | ||
378 | 374 | ||
379 | unsigned n_rx_tobe_disc; | 375 | unsigned n_rx_tobe_disc; |
380 | unsigned n_rx_ip_frag_err; | 376 | unsigned n_rx_ip_frag_err; |
@@ -394,13 +390,11 @@ struct efx_channel { | |||
394 | 390 | ||
395 | /** | 391 | /** |
396 | * struct efx_blinker - S/W LED blinking context | 392 | * struct efx_blinker - S/W LED blinking context |
397 | * @led_num: LED ID (board-specific meaning) | ||
398 | * @state: Current state - on or off | 393 | * @state: Current state - on or off |
399 | * @resubmit: Timer resubmission flag | 394 | * @resubmit: Timer resubmission flag |
400 | * @timer: Control timer for blinking | 395 | * @timer: Control timer for blinking |
401 | */ | 396 | */ |
402 | struct efx_blinker { | 397 | struct efx_blinker { |
403 | int led_num; | ||
404 | bool state; | 398 | bool state; |
405 | bool resubmit; | 399 | bool resubmit; |
406 | struct timer_list timer; | 400 | struct timer_list timer; |
@@ -413,8 +407,8 @@ struct efx_blinker { | |||
413 | * @major: Major rev. ('A', 'B' ...) | 407 | * @major: Major rev. ('A', 'B' ...) |
414 | * @minor: Minor rev. (0, 1, ...) | 408 | * @minor: Minor rev. (0, 1, ...) |
415 | * @init: Initialisation function | 409 | * @init: Initialisation function |
416 | * @init_leds: Sets up board LEDs | 410 | * @init_leds: Sets up board LEDs. May be called repeatedly. |
417 | * @set_fault_led: Turns the fault LED on or off | 411 | * @set_id_led: Turns the identification LED on or off |
418 | * @blink: Starts/stops blinking | 412 | * @blink: Starts/stops blinking |
419 | * @monitor: Board-specific health check function | 413 | * @monitor: Board-specific health check function |
420 | * @fini: Cleanup function | 414 | * @fini: Cleanup function |
@@ -430,9 +424,9 @@ struct efx_board { | |||
430 | /* As the LEDs are typically attached to the PHY, LEDs | 424 | /* As the LEDs are typically attached to the PHY, LEDs |
431 | * have a separate init callback that happens later than | 425 | * have a separate init callback that happens later than |
432 | * board init. */ | 426 | * board init. */ |
433 | int (*init_leds)(struct efx_nic *efx); | 427 | void (*init_leds)(struct efx_nic *efx); |
428 | void (*set_id_led) (struct efx_nic *efx, bool state); | ||
434 | int (*monitor) (struct efx_nic *nic); | 429 | int (*monitor) (struct efx_nic *nic); |
435 | void (*set_fault_led) (struct efx_nic *efx, bool state); | ||
436 | void (*blink) (struct efx_nic *efx, bool start); | 430 | void (*blink) (struct efx_nic *efx, bool start); |
437 | void (*fini) (struct efx_nic *nic); | 431 | void (*fini) (struct efx_nic *nic); |
438 | struct efx_blinker blinker; | 432 | struct efx_blinker blinker; |
@@ -459,6 +453,7 @@ enum phy_type { | |||
459 | PHY_TYPE_QT2022C2 = 4, | 453 | PHY_TYPE_QT2022C2 = 4, |
460 | PHY_TYPE_PM8358 = 6, | 454 | PHY_TYPE_PM8358 = 6, |
461 | PHY_TYPE_SFT9001A = 8, | 455 | PHY_TYPE_SFT9001A = 8, |
456 | PHY_TYPE_QT2025C = 9, | ||
462 | PHY_TYPE_SFT9001B = 10, | 457 | PHY_TYPE_SFT9001B = 10, |
463 | PHY_TYPE_MAX /* Insert any new items before this */ | 458 | PHY_TYPE_MAX /* Insert any new items before this */ |
464 | }; | 459 | }; |
@@ -713,6 +708,8 @@ union efx_multicast_hash { | |||
713 | * @membase: Memory BAR value | 708 | * @membase: Memory BAR value |
714 | * @biu_lock: BIU (bus interface unit) lock | 709 | * @biu_lock: BIU (bus interface unit) lock |
715 | * @interrupt_mode: Interrupt mode | 710 | * @interrupt_mode: Interrupt mode |
711 | * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues | ||
712 | * @irq_rx_moderation: IRQ moderation time for RX event queues | ||
716 | * @i2c_adap: I2C adapter | 713 | * @i2c_adap: I2C adapter |
717 | * @board_info: Board-level information | 714 | * @board_info: Board-level information |
718 | * @state: Device state flag. Serialised by the rtnl_lock. | 715 | * @state: Device state flag. Serialised by the rtnl_lock. |
@@ -794,6 +791,8 @@ struct efx_nic { | |||
794 | void __iomem *membase; | 791 | void __iomem *membase; |
795 | spinlock_t biu_lock; | 792 | spinlock_t biu_lock; |
796 | enum efx_int_mode interrupt_mode; | 793 | enum efx_int_mode interrupt_mode; |
794 | bool irq_rx_adaptive; | ||
795 | unsigned int irq_rx_moderation; | ||
797 | 796 | ||
798 | struct i2c_adapter i2c_adap; | 797 | struct i2c_adapter i2c_adap; |
799 | struct efx_board board_info; | 798 | struct efx_board board_info; |
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h index 07e855c148bc..c1cff9c0c173 100644 --- a/drivers/net/sfc/phy.h +++ b/drivers/net/sfc/phy.h | |||
@@ -18,12 +18,16 @@ extern struct efx_phy_operations falcon_sft9001_phy_ops; | |||
18 | 18 | ||
19 | extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); | 19 | extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); |
20 | 20 | ||
21 | /* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed | ||
22 | * to boot due to corrupt flash, or some other negative error code. */ | ||
23 | extern int sft9001_wait_boot(struct efx_nic *efx); | ||
24 | |||
21 | /**************************************************************************** | 25 | /**************************************************************************** |
22 | * Exported functions from the driver for XFP optical PHYs | 26 | * AMCC/Quake QT20xx PHYs |
23 | */ | 27 | */ |
24 | extern struct efx_phy_operations falcon_xfp_phy_ops; | 28 | extern struct efx_phy_operations falcon_xfp_phy_ops; |
25 | 29 | ||
26 | /* The QUAKE XFP PHY provides various H/W control states for LEDs */ | 30 | /* These PHYs provide various H/W control states for LEDs */ |
27 | #define QUAKE_LED_LINK_INVAL (0) | 31 | #define QUAKE_LED_LINK_INVAL (0) |
28 | #define QUAKE_LED_LINK_STAT (1) | 32 | #define QUAKE_LED_LINK_STAT (1) |
29 | #define QUAKE_LED_LINK_ACT (2) | 33 | #define QUAKE_LED_LINK_ACT (2) |
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index b8ba4bbad889..66d7fe3db3e6 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c | |||
@@ -99,109 +99,6 @@ static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | 101 | ||
102 | /************************************************************************** | ||
103 | * | ||
104 | * Linux generic LRO handling | ||
105 | * | ||
106 | ************************************************************************** | ||
107 | */ | ||
108 | |||
109 | static int efx_lro_get_skb_hdr(struct sk_buff *skb, void **ip_hdr, | ||
110 | void **tcpudp_hdr, u64 *hdr_flags, void *priv) | ||
111 | { | ||
112 | struct efx_channel *channel = priv; | ||
113 | struct iphdr *iph; | ||
114 | struct tcphdr *th; | ||
115 | |||
116 | iph = (struct iphdr *)skb->data; | ||
117 | if (skb->protocol != htons(ETH_P_IP) || iph->protocol != IPPROTO_TCP) | ||
118 | goto fail; | ||
119 | |||
120 | th = (struct tcphdr *)(skb->data + iph->ihl * 4); | ||
121 | |||
122 | *tcpudp_hdr = th; | ||
123 | *ip_hdr = iph; | ||
124 | *hdr_flags = LRO_IPV4 | LRO_TCP; | ||
125 | |||
126 | channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO; | ||
127 | return 0; | ||
128 | fail: | ||
129 | channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; | ||
130 | return -1; | ||
131 | } | ||
132 | |||
133 | static int efx_get_frag_hdr(struct skb_frag_struct *frag, void **mac_hdr, | ||
134 | void **ip_hdr, void **tcpudp_hdr, u64 *hdr_flags, | ||
135 | void *priv) | ||
136 | { | ||
137 | struct efx_channel *channel = priv; | ||
138 | struct ethhdr *eh; | ||
139 | struct iphdr *iph; | ||
140 | |||
141 | /* We support EtherII and VLAN encapsulated IPv4 */ | ||
142 | eh = page_address(frag->page) + frag->page_offset; | ||
143 | *mac_hdr = eh; | ||
144 | |||
145 | if (eh->h_proto == htons(ETH_P_IP)) { | ||
146 | iph = (struct iphdr *)(eh + 1); | ||
147 | } else { | ||
148 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)eh; | ||
149 | if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP)) | ||
150 | goto fail; | ||
151 | |||
152 | iph = (struct iphdr *)(veh + 1); | ||
153 | } | ||
154 | *ip_hdr = iph; | ||
155 | |||
156 | /* We can only do LRO over TCP */ | ||
157 | if (iph->protocol != IPPROTO_TCP) | ||
158 | goto fail; | ||
159 | |||
160 | *hdr_flags = LRO_IPV4 | LRO_TCP; | ||
161 | *tcpudp_hdr = (struct tcphdr *)((u8 *) iph + iph->ihl * 4); | ||
162 | |||
163 | channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO; | ||
164 | return 0; | ||
165 | fail: | ||
166 | channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; | ||
167 | return -1; | ||
168 | } | ||
169 | |||
170 | int efx_lro_init(struct net_lro_mgr *lro_mgr, struct efx_nic *efx) | ||
171 | { | ||
172 | size_t s = sizeof(struct net_lro_desc) * EFX_MAX_LRO_DESCRIPTORS; | ||
173 | struct net_lro_desc *lro_arr; | ||
174 | |||
175 | /* Allocate the LRO descriptors structure */ | ||
176 | lro_arr = kzalloc(s, GFP_KERNEL); | ||
177 | if (lro_arr == NULL) | ||
178 | return -ENOMEM; | ||
179 | |||
180 | lro_mgr->lro_arr = lro_arr; | ||
181 | lro_mgr->max_desc = EFX_MAX_LRO_DESCRIPTORS; | ||
182 | lro_mgr->max_aggr = EFX_MAX_LRO_AGGR; | ||
183 | lro_mgr->frag_align_pad = EFX_PAGE_SKB_ALIGN; | ||
184 | |||
185 | lro_mgr->get_skb_header = efx_lro_get_skb_hdr; | ||
186 | lro_mgr->get_frag_header = efx_get_frag_hdr; | ||
187 | lro_mgr->dev = efx->net_dev; | ||
188 | |||
189 | lro_mgr->features = LRO_F_NAPI; | ||
190 | |||
191 | /* We can pass packets up with the checksum intact */ | ||
192 | lro_mgr->ip_summed = CHECKSUM_UNNECESSARY; | ||
193 | |||
194 | lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | void efx_lro_fini(struct net_lro_mgr *lro_mgr) | ||
200 | { | ||
201 | kfree(lro_mgr->lro_arr); | ||
202 | lro_mgr->lro_arr = NULL; | ||
203 | } | ||
204 | |||
205 | /** | 102 | /** |
206 | * efx_init_rx_buffer_skb - create new RX buffer using skb-based allocation | 103 | * efx_init_rx_buffer_skb - create new RX buffer using skb-based allocation |
207 | * | 104 | * |
@@ -549,77 +446,31 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, | |||
549 | static void efx_rx_packet_lro(struct efx_channel *channel, | 446 | static void efx_rx_packet_lro(struct efx_channel *channel, |
550 | struct efx_rx_buffer *rx_buf) | 447 | struct efx_rx_buffer *rx_buf) |
551 | { | 448 | { |
552 | struct net_lro_mgr *lro_mgr = &channel->lro_mgr; | 449 | struct napi_struct *napi = &channel->napi_str; |
553 | void *priv = channel; | ||
554 | 450 | ||
555 | /* Pass the skb/page into the LRO engine */ | 451 | /* Pass the skb/page into the LRO engine */ |
556 | if (rx_buf->page) { | 452 | if (rx_buf->page) { |
557 | struct skb_frag_struct frags; | 453 | struct napi_gro_fraginfo info; |
558 | 454 | ||
559 | frags.page = rx_buf->page; | 455 | info.frags[0].page = rx_buf->page; |
560 | frags.page_offset = efx_rx_buf_offset(rx_buf); | 456 | info.frags[0].page_offset = efx_rx_buf_offset(rx_buf); |
561 | frags.size = rx_buf->len; | 457 | info.frags[0].size = rx_buf->len; |
458 | info.nr_frags = 1; | ||
459 | info.ip_summed = CHECKSUM_UNNECESSARY; | ||
460 | info.len = rx_buf->len; | ||
562 | 461 | ||
563 | lro_receive_frags(lro_mgr, &frags, rx_buf->len, | 462 | napi_gro_frags(napi, &info); |
564 | rx_buf->len, priv, 0); | ||
565 | 463 | ||
566 | EFX_BUG_ON_PARANOID(rx_buf->skb); | 464 | EFX_BUG_ON_PARANOID(rx_buf->skb); |
567 | rx_buf->page = NULL; | 465 | rx_buf->page = NULL; |
568 | } else { | 466 | } else { |
569 | EFX_BUG_ON_PARANOID(!rx_buf->skb); | 467 | EFX_BUG_ON_PARANOID(!rx_buf->skb); |
570 | 468 | ||
571 | lro_receive_skb(lro_mgr, rx_buf->skb, priv); | 469 | napi_gro_receive(napi, rx_buf->skb); |
572 | rx_buf->skb = NULL; | 470 | rx_buf->skb = NULL; |
573 | } | 471 | } |
574 | } | 472 | } |
575 | 473 | ||
576 | /* Allocate and construct an SKB around a struct page.*/ | ||
577 | static struct sk_buff *efx_rx_mk_skb(struct efx_rx_buffer *rx_buf, | ||
578 | struct efx_nic *efx, | ||
579 | int hdr_len) | ||
580 | { | ||
581 | struct sk_buff *skb; | ||
582 | |||
583 | /* Allocate an SKB to store the headers */ | ||
584 | skb = netdev_alloc_skb(efx->net_dev, hdr_len + EFX_PAGE_SKB_ALIGN); | ||
585 | if (unlikely(skb == NULL)) { | ||
586 | EFX_ERR_RL(efx, "RX out of memory for skb\n"); | ||
587 | return NULL; | ||
588 | } | ||
589 | |||
590 | EFX_BUG_ON_PARANOID(skb_shinfo(skb)->nr_frags); | ||
591 | EFX_BUG_ON_PARANOID(rx_buf->len < hdr_len); | ||
592 | |||
593 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
594 | skb_reserve(skb, EFX_PAGE_SKB_ALIGN); | ||
595 | |||
596 | skb->len = rx_buf->len; | ||
597 | skb->truesize = rx_buf->len + sizeof(struct sk_buff); | ||
598 | memcpy(skb->data, rx_buf->data, hdr_len); | ||
599 | skb->tail += hdr_len; | ||
600 | |||
601 | /* Append the remaining page onto the frag list */ | ||
602 | if (unlikely(rx_buf->len > hdr_len)) { | ||
603 | struct skb_frag_struct *frag = skb_shinfo(skb)->frags; | ||
604 | frag->page = rx_buf->page; | ||
605 | frag->page_offset = efx_rx_buf_offset(rx_buf) + hdr_len; | ||
606 | frag->size = skb->len - hdr_len; | ||
607 | skb_shinfo(skb)->nr_frags = 1; | ||
608 | skb->data_len = frag->size; | ||
609 | } else { | ||
610 | __free_pages(rx_buf->page, efx->rx_buffer_order); | ||
611 | skb->data_len = 0; | ||
612 | } | ||
613 | |||
614 | /* Ownership has transferred from the rx_buf to skb */ | ||
615 | rx_buf->page = NULL; | ||
616 | |||
617 | /* Move past the ethernet header */ | ||
618 | skb->protocol = eth_type_trans(skb, efx->net_dev); | ||
619 | |||
620 | return skb; | ||
621 | } | ||
622 | |||
623 | void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, | 474 | void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, |
624 | unsigned int len, bool checksummed, bool discard) | 475 | unsigned int len, bool checksummed, bool discard) |
625 | { | 476 | { |
@@ -687,7 +538,6 @@ void __efx_rx_packet(struct efx_channel *channel, | |||
687 | { | 538 | { |
688 | struct efx_nic *efx = channel->efx; | 539 | struct efx_nic *efx = channel->efx; |
689 | struct sk_buff *skb; | 540 | struct sk_buff *skb; |
690 | bool lro = !!(efx->net_dev->features & NETIF_F_LRO); | ||
691 | 541 | ||
692 | /* If we're in loopback test, then pass the packet directly to the | 542 | /* If we're in loopback test, then pass the packet directly to the |
693 | * loopback layer, and free the rx_buf here | 543 | * loopback layer, and free the rx_buf here |
@@ -709,41 +559,23 @@ void __efx_rx_packet(struct efx_channel *channel, | |||
709 | efx->net_dev); | 559 | efx->net_dev); |
710 | } | 560 | } |
711 | 561 | ||
712 | /* Both our generic-LRO and SFC-SSR support skb and page based | 562 | if (likely(checksummed || rx_buf->page)) { |
713 | * allocation, but neither support switching from one to the | ||
714 | * other on the fly. If we spot that the allocation mode has | ||
715 | * changed, then flush the LRO state. | ||
716 | */ | ||
717 | if (unlikely(channel->rx_alloc_pop_pages != (rx_buf->page != NULL))) { | ||
718 | efx_flush_lro(channel); | ||
719 | channel->rx_alloc_pop_pages = (rx_buf->page != NULL); | ||
720 | } | ||
721 | if (likely(checksummed && lro)) { | ||
722 | efx_rx_packet_lro(channel, rx_buf); | 563 | efx_rx_packet_lro(channel, rx_buf); |
723 | goto done; | 564 | goto done; |
724 | } | 565 | } |
725 | 566 | ||
726 | /* Form an skb if required */ | 567 | /* We now own the SKB */ |
727 | if (rx_buf->page) { | 568 | skb = rx_buf->skb; |
728 | int hdr_len = min(rx_buf->len, EFX_SKB_HEADERS); | 569 | rx_buf->skb = NULL; |
729 | skb = efx_rx_mk_skb(rx_buf, efx, hdr_len); | ||
730 | if (unlikely(skb == NULL)) { | ||
731 | efx_free_rx_buffer(efx, rx_buf); | ||
732 | goto done; | ||
733 | } | ||
734 | } else { | ||
735 | /* We now own the SKB */ | ||
736 | skb = rx_buf->skb; | ||
737 | rx_buf->skb = NULL; | ||
738 | } | ||
739 | 570 | ||
740 | EFX_BUG_ON_PARANOID(rx_buf->page); | 571 | EFX_BUG_ON_PARANOID(rx_buf->page); |
741 | EFX_BUG_ON_PARANOID(rx_buf->skb); | 572 | EFX_BUG_ON_PARANOID(rx_buf->skb); |
742 | EFX_BUG_ON_PARANOID(!skb); | 573 | EFX_BUG_ON_PARANOID(!skb); |
743 | 574 | ||
744 | /* Set the SKB flags */ | 575 | /* Set the SKB flags */ |
745 | if (unlikely(!checksummed || !efx->rx_checksum_enabled)) | 576 | skb->ip_summed = CHECKSUM_NONE; |
746 | skb->ip_summed = CHECKSUM_NONE; | 577 | |
578 | skb_record_rx_queue(skb, channel->channel); | ||
747 | 579 | ||
748 | /* Pass the packet up */ | 580 | /* Pass the packet up */ |
749 | netif_receive_skb(skb); | 581 | netif_receive_skb(skb); |
@@ -760,7 +592,7 @@ void efx_rx_strategy(struct efx_channel *channel) | |||
760 | enum efx_rx_alloc_method method = rx_alloc_method; | 592 | enum efx_rx_alloc_method method = rx_alloc_method; |
761 | 593 | ||
762 | /* Only makes sense to use page based allocation if LRO is enabled */ | 594 | /* Only makes sense to use page based allocation if LRO is enabled */ |
763 | if (!(channel->efx->net_dev->features & NETIF_F_LRO)) { | 595 | if (!(channel->efx->net_dev->features & NETIF_F_GRO)) { |
764 | method = RX_ALLOC_METHOD_SKB; | 596 | method = RX_ALLOC_METHOD_SKB; |
765 | } else if (method == RX_ALLOC_METHOD_AUTO) { | 597 | } else if (method == RX_ALLOC_METHOD_AUTO) { |
766 | /* Constrain the rx_alloc_level */ | 598 | /* Constrain the rx_alloc_level */ |
@@ -865,11 +697,6 @@ void efx_remove_rx_queue(struct efx_rx_queue *rx_queue) | |||
865 | rx_queue->buffer = NULL; | 697 | rx_queue->buffer = NULL; |
866 | } | 698 | } |
867 | 699 | ||
868 | void efx_flush_lro(struct efx_channel *channel) | ||
869 | { | ||
870 | lro_flush_all(&channel->lro_mgr); | ||
871 | } | ||
872 | |||
873 | 700 | ||
874 | module_param(rx_alloc_method, int, 0644); | 701 | module_param(rx_alloc_method, int, 0644); |
875 | MODULE_PARM_DESC(rx_alloc_method, "Allocation method used for RX buffers"); | 702 | MODULE_PARM_DESC(rx_alloc_method, "Allocation method used for RX buffers"); |
diff --git a/drivers/net/sfc/rx.h b/drivers/net/sfc/rx.h index 0e88a9ddc1c6..42ee7555a80b 100644 --- a/drivers/net/sfc/rx.h +++ b/drivers/net/sfc/rx.h | |||
@@ -17,9 +17,6 @@ void efx_remove_rx_queue(struct efx_rx_queue *rx_queue); | |||
17 | void efx_init_rx_queue(struct efx_rx_queue *rx_queue); | 17 | void efx_init_rx_queue(struct efx_rx_queue *rx_queue); |
18 | void efx_fini_rx_queue(struct efx_rx_queue *rx_queue); | 18 | void efx_fini_rx_queue(struct efx_rx_queue *rx_queue); |
19 | 19 | ||
20 | int efx_lro_init(struct net_lro_mgr *lro_mgr, struct efx_nic *efx); | ||
21 | void efx_lro_fini(struct net_lro_mgr *lro_mgr); | ||
22 | void efx_flush_lro(struct efx_channel *channel); | ||
23 | void efx_rx_strategy(struct efx_channel *channel); | 20 | void efx_rx_strategy(struct efx_channel *channel); |
24 | void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue); | 21 | void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue); |
25 | void efx_rx_work(struct work_struct *data); | 22 | void efx_rx_work(struct work_struct *data); |
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index cb25ae5b257a..4eac5da81e5a 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c | |||
@@ -24,6 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/rtnetlink.h> | ||
27 | #include "net_driver.h" | 28 | #include "net_driver.h" |
28 | #include "efx.h" | 29 | #include "efx.h" |
29 | #include "phy.h" | 30 | #include "phy.h" |
@@ -398,6 +399,7 @@ static struct i2c_board_info sfn4111t_r5_hwmon_info = { | |||
398 | 399 | ||
399 | int sfn4111t_init(struct efx_nic *efx) | 400 | int sfn4111t_init(struct efx_nic *efx) |
400 | { | 401 | { |
402 | int i = 0; | ||
401 | int rc; | 403 | int rc; |
402 | 404 | ||
403 | efx->board_info.hwmon_client = | 405 | efx->board_info.hwmon_client = |
@@ -416,13 +418,20 @@ int sfn4111t_init(struct efx_nic *efx) | |||
416 | if (rc) | 418 | if (rc) |
417 | goto fail_hwmon; | 419 | goto fail_hwmon; |
418 | 420 | ||
419 | if (efx->phy_mode & PHY_MODE_SPECIAL) { | 421 | do { |
420 | efx_stats_disable(efx); | 422 | if (efx->phy_mode & PHY_MODE_SPECIAL) { |
421 | sfn4111t_reset(efx); | 423 | /* PHY may not generate a 156.25 MHz clock and MAC |
422 | } | 424 | * stats fetch will fail. */ |
423 | 425 | efx_stats_disable(efx); | |
424 | return 0; | 426 | sfn4111t_reset(efx); |
427 | } | ||
428 | rc = sft9001_wait_boot(efx); | ||
429 | if (rc == 0) | ||
430 | return 0; | ||
431 | efx->phy_mode = PHY_MODE_SPECIAL; | ||
432 | } while (rc == -EINVAL && ++i < 2); | ||
425 | 433 | ||
434 | device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); | ||
426 | fail_hwmon: | 435 | fail_hwmon: |
427 | i2c_unregister_device(efx->board_info.hwmon_client); | 436 | i2c_unregister_device(efx->board_info.hwmon_client); |
428 | return rc; | 437 | return rc; |
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index f0efd246962c..e61dc4d4741c 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -8,6 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/rtnetlink.h> | ||
11 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
12 | #include "efx.h" | 13 | #include "efx.h" |
13 | #include "mdio_10g.h" | 14 | #include "mdio_10g.h" |
@@ -157,14 +158,16 @@ | |||
157 | #define PCS_10GBASET_BLKLK_WIDTH 1 | 158 | #define PCS_10GBASET_BLKLK_WIDTH 1 |
158 | 159 | ||
159 | /* Boot status register */ | 160 | /* Boot status register */ |
160 | #define PCS_BOOT_STATUS_REG 53248 | 161 | #define PCS_BOOT_STATUS_REG 53248 |
161 | #define PCS_BOOT_FATAL_ERR_LBN (0) | 162 | #define PCS_BOOT_FATAL_ERROR_LBN 0 |
162 | #define PCS_BOOT_PROGRESS_LBN (1) | 163 | #define PCS_BOOT_PROGRESS_LBN 1 |
163 | #define PCS_BOOT_PROGRESS_WIDTH (2) | 164 | #define PCS_BOOT_PROGRESS_WIDTH 2 |
164 | #define PCS_BOOT_COMPLETE_LBN (3) | 165 | #define PCS_BOOT_PROGRESS_INIT 0 |
165 | 166 | #define PCS_BOOT_PROGRESS_WAIT_MDIO 1 | |
166 | #define PCS_BOOT_MAX_DELAY (100) | 167 | #define PCS_BOOT_PROGRESS_CHECKSUM 2 |
167 | #define PCS_BOOT_POLL_DELAY (10) | 168 | #define PCS_BOOT_PROGRESS_JUMP 3 |
169 | #define PCS_BOOT_DOWNLOAD_WAIT_LBN 3 | ||
170 | #define PCS_BOOT_CODE_STARTED_LBN 4 | ||
168 | 171 | ||
169 | /* 100M/1G PHY registers */ | 172 | /* 100M/1G PHY registers */ |
170 | #define GPHY_XCONTROL_REG 49152 | 173 | #define GPHY_XCONTROL_REG 49152 |
@@ -229,40 +232,62 @@ static ssize_t set_phy_short_reach(struct device *dev, | |||
229 | static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach, | 232 | static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach, |
230 | set_phy_short_reach); | 233 | set_phy_short_reach); |
231 | 234 | ||
232 | /* Check that the C166 has booted successfully */ | 235 | int sft9001_wait_boot(struct efx_nic *efx) |
233 | static int tenxpress_phy_check(struct efx_nic *efx) | ||
234 | { | 236 | { |
235 | int phy_id = efx->mii.phy_id; | 237 | unsigned long timeout = jiffies + HZ + 1; |
236 | int count = PCS_BOOT_MAX_DELAY / PCS_BOOT_POLL_DELAY; | ||
237 | int boot_stat; | 238 | int boot_stat; |
238 | 239 | ||
239 | /* Wait for the boot to complete (or not) */ | 240 | for (;;) { |
240 | while (count) { | 241 | boot_stat = mdio_clause45_read(efx, efx->mii.phy_id, |
241 | boot_stat = mdio_clause45_read(efx, phy_id, | ||
242 | MDIO_MMD_PCS, | 242 | MDIO_MMD_PCS, |
243 | PCS_BOOT_STATUS_REG); | 243 | PCS_BOOT_STATUS_REG); |
244 | if (boot_stat & (1 << PCS_BOOT_COMPLETE_LBN)) | 244 | if (boot_stat >= 0) { |
245 | break; | 245 | EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat); |
246 | count--; | 246 | switch (boot_stat & |
247 | udelay(PCS_BOOT_POLL_DELAY); | 247 | ((1 << PCS_BOOT_FATAL_ERROR_LBN) | |
248 | } | 248 | (3 << PCS_BOOT_PROGRESS_LBN) | |
249 | (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) | | ||
250 | (1 << PCS_BOOT_CODE_STARTED_LBN))) { | ||
251 | case ((1 << PCS_BOOT_FATAL_ERROR_LBN) | | ||
252 | (PCS_BOOT_PROGRESS_CHECKSUM << | ||
253 | PCS_BOOT_PROGRESS_LBN)): | ||
254 | case ((1 << PCS_BOOT_FATAL_ERROR_LBN) | | ||
255 | (PCS_BOOT_PROGRESS_INIT << | ||
256 | PCS_BOOT_PROGRESS_LBN) | | ||
257 | (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)): | ||
258 | return -EINVAL; | ||
259 | case ((PCS_BOOT_PROGRESS_WAIT_MDIO << | ||
260 | PCS_BOOT_PROGRESS_LBN) | | ||
261 | (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)): | ||
262 | return (efx->phy_mode & PHY_MODE_SPECIAL) ? | ||
263 | 0 : -EIO; | ||
264 | case ((PCS_BOOT_PROGRESS_JUMP << | ||
265 | PCS_BOOT_PROGRESS_LBN) | | ||
266 | (1 << PCS_BOOT_CODE_STARTED_LBN)): | ||
267 | case ((PCS_BOOT_PROGRESS_JUMP << | ||
268 | PCS_BOOT_PROGRESS_LBN) | | ||
269 | (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) | | ||
270 | (1 << PCS_BOOT_CODE_STARTED_LBN)): | ||
271 | return (efx->phy_mode & PHY_MODE_SPECIAL) ? | ||
272 | -EIO : 0; | ||
273 | default: | ||
274 | if (boot_stat & (1 << PCS_BOOT_FATAL_ERROR_LBN)) | ||
275 | return -EIO; | ||
276 | break; | ||
277 | } | ||
278 | } | ||
249 | 279 | ||
250 | if (!count) { | 280 | if (time_after_eq(jiffies, timeout)) |
251 | EFX_ERR(efx, "%s: PHY boot timed out. Last status " | 281 | return -ETIMEDOUT; |
252 | "%x\n", __func__, | ||
253 | (boot_stat >> PCS_BOOT_PROGRESS_LBN) & | ||
254 | ((1 << PCS_BOOT_PROGRESS_WIDTH) - 1)); | ||
255 | return -ETIMEDOUT; | ||
256 | } | ||
257 | 282 | ||
258 | return 0; | 283 | msleep(50); |
284 | } | ||
259 | } | 285 | } |
260 | 286 | ||
261 | static int tenxpress_init(struct efx_nic *efx) | 287 | static int tenxpress_init(struct efx_nic *efx) |
262 | { | 288 | { |
263 | int phy_id = efx->mii.phy_id; | 289 | int phy_id = efx->mii.phy_id; |
264 | int reg; | 290 | int reg; |
265 | int rc; | ||
266 | 291 | ||
267 | if (efx->phy_type == PHY_TYPE_SFX7101) { | 292 | if (efx->phy_type == PHY_TYPE_SFX7101) { |
268 | /* Enable 312.5 MHz clock */ | 293 | /* Enable 312.5 MHz clock */ |
@@ -285,10 +310,6 @@ static int tenxpress_init(struct efx_nic *efx) | |||
285 | false); | 310 | false); |
286 | } | 311 | } |
287 | 312 | ||
288 | rc = tenxpress_phy_check(efx); | ||
289 | if (rc < 0) | ||
290 | return rc; | ||
291 | |||
292 | /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ | 313 | /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ |
293 | if (efx->phy_type == PHY_TYPE_SFX7101) { | 314 | if (efx->phy_type == PHY_TYPE_SFX7101) { |
294 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD, | 315 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD, |
@@ -299,7 +320,7 @@ static int tenxpress_init(struct efx_nic *efx) | |||
299 | PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT); | 320 | PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT); |
300 | } | 321 | } |
301 | 322 | ||
302 | return rc; | 323 | return 0; |
303 | } | 324 | } |
304 | 325 | ||
305 | static int tenxpress_phy_init(struct efx_nic *efx) | 326 | static int tenxpress_phy_init(struct efx_nic *efx) |
@@ -571,15 +592,14 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) | |||
571 | static void tenxpress_phy_poll(struct efx_nic *efx) | 592 | static void tenxpress_phy_poll(struct efx_nic *efx) |
572 | { | 593 | { |
573 | struct tenxpress_phy_data *phy_data = efx->phy_data; | 594 | struct tenxpress_phy_data *phy_data = efx->phy_data; |
574 | bool change = false, link_ok; | 595 | bool change = false; |
575 | unsigned link_fc; | ||
576 | 596 | ||
577 | if (efx->phy_type == PHY_TYPE_SFX7101) { | 597 | if (efx->phy_type == PHY_TYPE_SFX7101) { |
578 | link_ok = sfx7101_link_ok(efx); | 598 | bool link_ok = sfx7101_link_ok(efx); |
579 | if (link_ok != efx->link_up) { | 599 | if (link_ok != efx->link_up) { |
580 | change = true; | 600 | change = true; |
581 | } else { | 601 | } else { |
582 | link_fc = mdio_clause45_get_pause(efx); | 602 | unsigned int link_fc = mdio_clause45_get_pause(efx); |
583 | if (link_fc != efx->link_fc) | 603 | if (link_fc != efx->link_fc) |
584 | change = true; | 604 | change = true; |
585 | } | 605 | } |
@@ -679,12 +699,10 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) | |||
679 | { | 699 | { |
680 | struct ethtool_cmd ecmd; | 700 | struct ethtool_cmd ecmd; |
681 | int phy_id = efx->mii.phy_id; | 701 | int phy_id = efx->mii.phy_id; |
682 | int rc = 0, rc2, i, res_reg; | 702 | int rc = 0, rc2, i, ctrl_reg, res_reg; |
683 | |||
684 | if (!(flags & ETH_TEST_FL_OFFLINE)) | ||
685 | return 0; | ||
686 | 703 | ||
687 | efx->phy_op->get_settings(efx, &ecmd); | 704 | if (flags & ETH_TEST_FL_OFFLINE) |
705 | efx->phy_op->get_settings(efx, &ecmd); | ||
688 | 706 | ||
689 | /* Initialise cable diagnostic results to unknown failure */ | 707 | /* Initialise cable diagnostic results to unknown failure */ |
690 | for (i = 1; i < 9; ++i) | 708 | for (i = 1; i < 9; ++i) |
@@ -692,18 +710,22 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) | |||
692 | 710 | ||
693 | /* Run cable diagnostics; wait up to 5 seconds for them to complete. | 711 | /* Run cable diagnostics; wait up to 5 seconds for them to complete. |
694 | * A cable fault is not a self-test failure, but a timeout is. */ | 712 | * A cable fault is not a self-test failure, but a timeout is. */ |
713 | ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) | | ||
714 | (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN)); | ||
715 | if (flags & ETH_TEST_FL_OFFLINE) { | ||
716 | /* Break the link in order to run full diagnostics. We | ||
717 | * must reset the PHY to resume normal service. */ | ||
718 | ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN); | ||
719 | } | ||
695 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | 720 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, |
696 | PMA_PMD_CDIAG_CTRL_REG, | 721 | PMA_PMD_CDIAG_CTRL_REG, ctrl_reg); |
697 | (1 << CDIAG_CTRL_IMMED_LBN) | | ||
698 | (1 << CDIAG_CTRL_BRK_LINK_LBN) | | ||
699 | (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN)); | ||
700 | i = 0; | 722 | i = 0; |
701 | while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | 723 | while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, |
702 | PMA_PMD_CDIAG_CTRL_REG) & | 724 | PMA_PMD_CDIAG_CTRL_REG) & |
703 | (1 << CDIAG_CTRL_IN_PROG_LBN)) { | 725 | (1 << CDIAG_CTRL_IN_PROG_LBN)) { |
704 | if (++i == 50) { | 726 | if (++i == 50) { |
705 | rc = -ETIMEDOUT; | 727 | rc = -ETIMEDOUT; |
706 | goto reset; | 728 | goto out; |
707 | } | 729 | } |
708 | msleep(100); | 730 | msleep(100); |
709 | } | 731 | } |
@@ -728,17 +750,18 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) | |||
728 | results[5 + i] = len_reg; | 750 | results[5 + i] = len_reg; |
729 | } | 751 | } |
730 | 752 | ||
731 | /* We must reset to exit cable diagnostic mode. The BIST will | 753 | out: |
732 | * also run when we do this. */ | 754 | if (flags & ETH_TEST_FL_OFFLINE) { |
733 | reset: | 755 | /* Reset, running the BIST and then resuming normal service. */ |
734 | rc2 = tenxpress_special_reset(efx); | 756 | rc2 = tenxpress_special_reset(efx); |
735 | results[0] = rc2 ? -1 : 1; | 757 | results[0] = rc2 ? -1 : 1; |
736 | if (!rc) | 758 | if (!rc) |
737 | rc = rc2; | 759 | rc = rc2; |
738 | 760 | ||
739 | rc2 = efx->phy_op->set_settings(efx, &ecmd); | 761 | rc2 = efx->phy_op->set_settings(efx, &ecmd); |
740 | if (!rc) | 762 | if (!rc) |
741 | rc = rc2; | 763 | rc = rc2; |
764 | } | ||
742 | 765 | ||
743 | return rc; | 766 | return rc; |
744 | } | 767 | } |
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index da3e9ff339f5..d6681edb7014 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c | |||
@@ -162,6 +162,14 @@ static int efx_enqueue_skb(struct efx_tx_queue *tx_queue, | |||
162 | /* Get size of the initial fragment */ | 162 | /* Get size of the initial fragment */ |
163 | len = skb_headlen(skb); | 163 | len = skb_headlen(skb); |
164 | 164 | ||
165 | /* Pad if necessary */ | ||
166 | if (EFX_WORKAROUND_15592(efx) && skb->len <= 32) { | ||
167 | EFX_BUG_ON_PARANOID(skb->data_len); | ||
168 | len = 32 + 1; | ||
169 | if (skb_pad(skb, len - skb->len)) | ||
170 | return NETDEV_TX_OK; | ||
171 | } | ||
172 | |||
165 | fill_level = tx_queue->insert_count - tx_queue->old_read_count; | 173 | fill_level = tx_queue->insert_count - tx_queue->old_read_count; |
166 | q_space = efx->type->txd_ring_mask - 1 - fill_level; | 174 | q_space = efx->type->txd_ring_mask - 1 - fill_level; |
167 | 175 | ||
@@ -376,6 +384,9 @@ int efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev) | |||
376 | struct efx_nic *efx = netdev_priv(net_dev); | 384 | struct efx_nic *efx = netdev_priv(net_dev); |
377 | struct efx_tx_queue *tx_queue; | 385 | struct efx_tx_queue *tx_queue; |
378 | 386 | ||
387 | if (unlikely(efx->port_inhibited)) | ||
388 | return NETDEV_TX_BUSY; | ||
389 | |||
379 | if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) | 390 | if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) |
380 | tx_queue = &efx->tx_queue[EFX_TX_QUEUE_OFFLOAD_CSUM]; | 391 | tx_queue = &efx->tx_queue[EFX_TX_QUEUE_OFFLOAD_CSUM]; |
381 | else | 392 | else |
@@ -397,7 +408,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) | |||
397 | * separates the update of read_count from the test of | 408 | * separates the update of read_count from the test of |
398 | * stopped. */ | 409 | * stopped. */ |
399 | smp_mb(); | 410 | smp_mb(); |
400 | if (unlikely(tx_queue->stopped)) { | 411 | if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) { |
401 | fill_level = tx_queue->insert_count - tx_queue->read_count; | 412 | fill_level = tx_queue->insert_count - tx_queue->read_count; |
402 | if (fill_level < EFX_NETDEV_TX_THRESHOLD(tx_queue)) { | 413 | if (fill_level < EFX_NETDEV_TX_THRESHOLD(tx_queue)) { |
403 | EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); | 414 | EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); |
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index 78de68f4a95b..c821c15445a0 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h | |||
@@ -36,6 +36,8 @@ | |||
36 | #define EFX_WORKAROUND_11482 EFX_WORKAROUND_ALWAYS | 36 | #define EFX_WORKAROUND_11482 EFX_WORKAROUND_ALWAYS |
37 | /* Flush events can take a very long time to appear */ | 37 | /* Flush events can take a very long time to appear */ |
38 | #define EFX_WORKAROUND_11557 EFX_WORKAROUND_ALWAYS | 38 | #define EFX_WORKAROUND_11557 EFX_WORKAROUND_ALWAYS |
39 | /* Truncated IPv4 packets can confuse the TX packet parser */ | ||
40 | #define EFX_WORKAROUND_15592 EFX_WORKAROUND_ALWAYS | ||
39 | 41 | ||
40 | /* Spurious parity errors in TSORT buffers */ | 42 | /* Spurious parity errors in TSORT buffers */ |
41 | #define EFX_WORKAROUND_5129 EFX_WORKAROUND_FALCON_A | 43 | #define EFX_WORKAROUND_5129 EFX_WORKAROUND_FALCON_A |
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c index 2d50b6ecf5f9..bb1ef77d5f56 100644 --- a/drivers/net/sfc/xfp_phy.c +++ b/drivers/net/sfc/xfp_phy.c | |||
@@ -7,8 +7,8 @@ | |||
7 | * by the Free Software Foundation, incorporated herein by reference. | 7 | * by the Free Software Foundation, incorporated herein by reference. |
8 | */ | 8 | */ |
9 | /* | 9 | /* |
10 | * Driver for XFP optical PHYs (plus some support specific to the Quake 2022/32) | 10 | * Driver for SFP+ and XFP optical PHYs plus some support specific to the |
11 | * See www.amcc.com for details (search for qt2032) | 11 | * AMCC QT20xx adapters; see www.amcc.com for details |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/timer.h> | 14 | #include <linux/timer.h> |
@@ -31,6 +31,21 @@ | |||
31 | /* Quake-specific MDIO registers */ | 31 | /* Quake-specific MDIO registers */ |
32 | #define MDIO_QUAKE_LED0_REG (0xD006) | 32 | #define MDIO_QUAKE_LED0_REG (0xD006) |
33 | 33 | ||
34 | /* QT2025C only */ | ||
35 | #define PCS_FW_HEARTBEAT_REG 0xd7ee | ||
36 | #define PCS_FW_HEARTB_LBN 0 | ||
37 | #define PCS_FW_HEARTB_WIDTH 8 | ||
38 | #define PCS_UC8051_STATUS_REG 0xd7fd | ||
39 | #define PCS_UC_STATUS_LBN 0 | ||
40 | #define PCS_UC_STATUS_WIDTH 8 | ||
41 | #define PCS_UC_STATUS_FW_SAVE 0x20 | ||
42 | #define PMA_PMD_FTX_CTRL2_REG 0xc309 | ||
43 | #define PMA_PMD_FTX_STATIC_LBN 13 | ||
44 | #define PMA_PMD_VEND1_REG 0xc001 | ||
45 | #define PMA_PMD_VEND1_LBTXD_LBN 15 | ||
46 | #define PCS_VEND1_REG 0xc000 | ||
47 | #define PCS_VEND1_LBTXD_LBN 5 | ||
48 | |||
34 | void xfp_set_led(struct efx_nic *p, int led, int mode) | 49 | void xfp_set_led(struct efx_nic *p, int led, int mode) |
35 | { | 50 | { |
36 | int addr = MDIO_QUAKE_LED0_REG + led; | 51 | int addr = MDIO_QUAKE_LED0_REG + led; |
@@ -45,7 +60,49 @@ struct xfp_phy_data { | |||
45 | #define XFP_MAX_RESET_TIME 500 | 60 | #define XFP_MAX_RESET_TIME 500 |
46 | #define XFP_RESET_WAIT 10 | 61 | #define XFP_RESET_WAIT 10 |
47 | 62 | ||
48 | /* Reset the PHYXS MMD. This is documented (for the Quake PHY) as doing | 63 | static int qt2025c_wait_reset(struct efx_nic *efx) |
64 | { | ||
65 | unsigned long timeout = jiffies + 10 * HZ; | ||
66 | int phy_id = efx->mii.phy_id; | ||
67 | int reg, old_counter = 0; | ||
68 | |||
69 | /* Wait for firmware heartbeat to start */ | ||
70 | for (;;) { | ||
71 | int counter; | ||
72 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS, | ||
73 | PCS_FW_HEARTBEAT_REG); | ||
74 | if (reg < 0) | ||
75 | return reg; | ||
76 | counter = ((reg >> PCS_FW_HEARTB_LBN) & | ||
77 | ((1 << PCS_FW_HEARTB_WIDTH) - 1)); | ||
78 | if (old_counter == 0) | ||
79 | old_counter = counter; | ||
80 | else if (counter != old_counter) | ||
81 | break; | ||
82 | if (time_after(jiffies, timeout)) | ||
83 | return -ETIMEDOUT; | ||
84 | msleep(10); | ||
85 | } | ||
86 | |||
87 | /* Wait for firmware status to look good */ | ||
88 | for (;;) { | ||
89 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS, | ||
90 | PCS_UC8051_STATUS_REG); | ||
91 | if (reg < 0) | ||
92 | return reg; | ||
93 | if ((reg & | ||
94 | ((1 << PCS_UC_STATUS_WIDTH) - 1) << PCS_UC_STATUS_LBN) >= | ||
95 | PCS_UC_STATUS_FW_SAVE) | ||
96 | break; | ||
97 | if (time_after(jiffies, timeout)) | ||
98 | return -ETIMEDOUT; | ||
99 | msleep(100); | ||
100 | } | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | /* Reset the PHYXS MMD. This is documented (for the Quake PHYs) as doing | ||
49 | * a complete soft reset. | 106 | * a complete soft reset. |
50 | */ | 107 | */ |
51 | static int xfp_reset_phy(struct efx_nic *efx) | 108 | static int xfp_reset_phy(struct efx_nic *efx) |
@@ -58,6 +115,12 @@ static int xfp_reset_phy(struct efx_nic *efx) | |||
58 | if (rc < 0) | 115 | if (rc < 0) |
59 | goto fail; | 116 | goto fail; |
60 | 117 | ||
118 | if (efx->phy_type == PHY_TYPE_QT2025C) { | ||
119 | rc = qt2025c_wait_reset(efx); | ||
120 | if (rc < 0) | ||
121 | goto fail; | ||
122 | } | ||
123 | |||
61 | /* Wait 250ms for the PHY to complete bootup */ | 124 | /* Wait 250ms for the PHY to complete bootup */ |
62 | msleep(250); | 125 | msleep(250); |
63 | 126 | ||
@@ -73,7 +136,7 @@ static int xfp_reset_phy(struct efx_nic *efx) | |||
73 | return rc; | 136 | return rc; |
74 | 137 | ||
75 | fail: | 138 | fail: |
76 | EFX_ERR(efx, "XFP: reset timed out!\n"); | 139 | EFX_ERR(efx, "PHY reset timed out\n"); |
77 | return rc; | 140 | return rc; |
78 | } | 141 | } |
79 | 142 | ||
@@ -88,15 +151,15 @@ static int xfp_phy_init(struct efx_nic *efx) | |||
88 | return -ENOMEM; | 151 | return -ENOMEM; |
89 | efx->phy_data = phy_data; | 152 | efx->phy_data = phy_data; |
90 | 153 | ||
91 | EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision" | 154 | EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n", |
92 | " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid), | 155 | devid, mdio_id_oui(devid), mdio_id_model(devid), |
93 | MDIO_ID_REV(devid)); | 156 | mdio_id_rev(devid)); |
94 | 157 | ||
95 | phy_data->phy_mode = efx->phy_mode; | 158 | phy_data->phy_mode = efx->phy_mode; |
96 | 159 | ||
97 | rc = xfp_reset_phy(efx); | 160 | rc = xfp_reset_phy(efx); |
98 | 161 | ||
99 | EFX_INFO(efx, "XFP: PHY init %s.\n", | 162 | EFX_INFO(efx, "PHY init %s.\n", |
100 | rc ? "failed" : "successful"); | 163 | rc ? "failed" : "successful"); |
101 | if (rc < 0) | 164 | if (rc < 0) |
102 | goto fail; | 165 | goto fail; |
@@ -131,12 +194,28 @@ static void xfp_phy_reconfigure(struct efx_nic *efx) | |||
131 | { | 194 | { |
132 | struct xfp_phy_data *phy_data = efx->phy_data; | 195 | struct xfp_phy_data *phy_data = efx->phy_data; |
133 | 196 | ||
134 | /* Reset the PHY when moving from tx off to tx on */ | 197 | if (efx->phy_type == PHY_TYPE_QT2025C) { |
135 | if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) && | 198 | /* There are several different register bits which can |
136 | (phy_data->phy_mode & PHY_MODE_TX_DISABLED)) | 199 | * disable TX (and save power) on direct-attach cables |
137 | xfp_reset_phy(efx); | 200 | * or optical transceivers, varying somewhat between |
201 | * firmware versions. Only 'static mode' appears to | ||
202 | * cover everything. */ | ||
203 | mdio_clause45_set_flag( | ||
204 | efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | ||
205 | PMA_PMD_FTX_CTRL2_REG, PMA_PMD_FTX_STATIC_LBN, | ||
206 | efx->phy_mode & PHY_MODE_TX_DISABLED || | ||
207 | efx->phy_mode & PHY_MODE_LOW_POWER || | ||
208 | efx->loopback_mode == LOOPBACK_PCS || | ||
209 | efx->loopback_mode == LOOPBACK_PMAPMD); | ||
210 | } else { | ||
211 | /* Reset the PHY when moving from tx off to tx on */ | ||
212 | if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) && | ||
213 | (phy_data->phy_mode & PHY_MODE_TX_DISABLED)) | ||
214 | xfp_reset_phy(efx); | ||
215 | |||
216 | mdio_clause45_transmit_disable(efx); | ||
217 | } | ||
138 | 218 | ||
139 | mdio_clause45_transmit_disable(efx); | ||
140 | mdio_clause45_phy_reconfigure(efx); | 219 | mdio_clause45_phy_reconfigure(efx); |
141 | 220 | ||
142 | phy_data->phy_mode = efx->phy_mode; | 221 | phy_data->phy_mode = efx->phy_mode; |