aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbevf/ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbevf/ethtool.c')
-rw-r--r--drivers/net/ixgbevf/ethtool.c183
1 files changed, 97 insertions, 86 deletions
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c
index 4680b069b84f..deee3754b1f7 100644
--- a/drivers/net/ixgbevf/ethtool.c
+++ b/drivers/net/ixgbevf/ethtool.c
@@ -104,11 +104,13 @@ static int ixgbevf_get_settings(struct net_device *netdev,
104 hw->mac.ops.check_link(hw, &link_speed, &link_up, false); 104 hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
105 105
106 if (link_up) { 106 if (link_up) {
107 ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? 107 ethtool_cmd_speed_set(
108 SPEED_10000 : SPEED_1000; 108 ecmd,
109 (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
110 SPEED_10000 : SPEED_1000);
109 ecmd->duplex = DUPLEX_FULL; 111 ecmd->duplex = DUPLEX_FULL;
110 } else { 112 } else {
111 ecmd->speed = -1; 113 ethtool_cmd_speed_set(ecmd, -1);
112 ecmd->duplex = -1; 114 ecmd->duplex = -1;
113 } 115 }
114 116
@@ -172,7 +174,7 @@ static char *ixgbevf_reg_names[] = {
172 "IXGBE_VFSTATUS", 174 "IXGBE_VFSTATUS",
173 "IXGBE_VFLINKS", 175 "IXGBE_VFLINKS",
174 "IXGBE_VFRXMEMWRAP", 176 "IXGBE_VFRXMEMWRAP",
175 "IXGBE_VFRTIMER", 177 "IXGBE_VFFRTIMER",
176 "IXGBE_VTEICR", 178 "IXGBE_VTEICR",
177 "IXGBE_VTEICS", 179 "IXGBE_VTEICS",
178 "IXGBE_VTEIMS", 180 "IXGBE_VTEIMS",
@@ -240,7 +242,7 @@ static void ixgbevf_get_regs(struct net_device *netdev,
240 regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_VFSTATUS); 242 regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_VFSTATUS);
241 regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_VFLINKS); 243 regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
242 regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_VFRXMEMWRAP); 244 regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_VFRXMEMWRAP);
243 regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFRTIMER); 245 regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFFRTIMER);
244 246
245 /* Interrupt */ 247 /* Interrupt */
246 /* don't read EICR because it can clear interrupt causes, instead 248 /* don't read EICR because it can clear interrupt causes, instead
@@ -330,10 +332,8 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
330{ 332{
331 struct ixgbevf_adapter *adapter = netdev_priv(netdev); 333 struct ixgbevf_adapter *adapter = netdev_priv(netdev);
332 struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL; 334 struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL;
333 int i, err; 335 int i, err = 0;
334 u32 new_rx_count, new_tx_count; 336 u32 new_rx_count, new_tx_count;
335 bool need_tx_update = false;
336 bool need_rx_update = false;
337 337
338 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 338 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
339 return -EINVAL; 339 return -EINVAL;
@@ -355,89 +355,96 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
355 while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state)) 355 while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state))
356 msleep(1); 356 msleep(1);
357 357
358 if (new_tx_count != adapter->tx_ring_count) { 358 /*
359 tx_ring = kcalloc(adapter->num_tx_queues, 359 * If the adapter isn't up and running then just set the
360 sizeof(struct ixgbevf_ring), GFP_KERNEL); 360 * new parameters and scurry for the exits.
361 if (!tx_ring) { 361 */
362 err = -ENOMEM; 362 if (!netif_running(adapter->netdev)) {
363 goto err_setup; 363 for (i = 0; i < adapter->num_tx_queues; i++)
364 } 364 adapter->tx_ring[i].count = new_tx_count;
365 memcpy(tx_ring, adapter->tx_ring, 365 for (i = 0; i < adapter->num_rx_queues; i++)
366 adapter->num_tx_queues * sizeof(struct ixgbevf_ring)); 366 adapter->rx_ring[i].count = new_rx_count;
367 for (i = 0; i < adapter->num_tx_queues; i++) { 367 adapter->tx_ring_count = new_tx_count;
368 tx_ring[i].count = new_tx_count; 368 adapter->rx_ring_count = new_rx_count;
369 err = ixgbevf_setup_tx_resources(adapter, 369 goto clear_reset;
370 &tx_ring[i]);
371 if (err) {
372 while (i) {
373 i--;
374 ixgbevf_free_tx_resources(adapter,
375 &tx_ring[i]);
376 }
377 kfree(tx_ring);
378 goto err_setup;
379 }
380 tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
381 }
382 need_tx_update = true;
383 } 370 }
384 371
385 if (new_rx_count != adapter->rx_ring_count) { 372 tx_ring = kcalloc(adapter->num_tx_queues,
386 rx_ring = kcalloc(adapter->num_rx_queues, 373 sizeof(struct ixgbevf_ring), GFP_KERNEL);
387 sizeof(struct ixgbevf_ring), GFP_KERNEL); 374 if (!tx_ring) {
388 if ((!rx_ring) && (need_tx_update)) { 375 err = -ENOMEM;
389 err = -ENOMEM; 376 goto clear_reset;
390 goto err_rx_setup;
391 }
392 memcpy(rx_ring, adapter->rx_ring,
393 adapter->num_rx_queues * sizeof(struct ixgbevf_ring));
394 for (i = 0; i < adapter->num_rx_queues; i++) {
395 rx_ring[i].count = new_rx_count;
396 err = ixgbevf_setup_rx_resources(adapter,
397 &rx_ring[i]);
398 if (err) {
399 while (i) {
400 i--;
401 ixgbevf_free_rx_resources(adapter,
402 &rx_ring[i]);
403 }
404 kfree(rx_ring);
405 goto err_rx_setup;
406 }
407 rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
408 }
409 need_rx_update = true;
410 } 377 }
411 378
412err_rx_setup: 379 rx_ring = kcalloc(adapter->num_rx_queues,
413 /* if rings need to be updated, here's the place to do it in one shot */ 380 sizeof(struct ixgbevf_ring), GFP_KERNEL);
414 if (need_tx_update || need_rx_update) { 381 if (!rx_ring) {
415 if (netif_running(netdev)) 382 err = -ENOMEM;
416 ixgbevf_down(adapter); 383 goto err_rx_setup;
417 } 384 }
418 385
419 /* tx */ 386 ixgbevf_down(adapter);
420 if (need_tx_update) { 387
421 kfree(adapter->tx_ring); 388 memcpy(tx_ring, adapter->tx_ring,
422 adapter->tx_ring = tx_ring; 389 adapter->num_tx_queues * sizeof(struct ixgbevf_ring));
423 tx_ring = NULL; 390 for (i = 0; i < adapter->num_tx_queues; i++) {
424 adapter->tx_ring_count = new_tx_count; 391 tx_ring[i].count = new_tx_count;
392 err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]);
393 if (err) {
394 while (i) {
395 i--;
396 ixgbevf_free_tx_resources(adapter,
397 &tx_ring[i]);
398 }
399 goto err_tx_ring_setup;
400 }
401 tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
425 } 402 }
426 403
427 /* rx */ 404 memcpy(rx_ring, adapter->rx_ring,
428 if (need_rx_update) { 405 adapter->num_rx_queues * sizeof(struct ixgbevf_ring));
429 kfree(adapter->rx_ring); 406 for (i = 0; i < adapter->num_rx_queues; i++) {
430 adapter->rx_ring = rx_ring; 407 rx_ring[i].count = new_rx_count;
431 rx_ring = NULL; 408 err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]);
432 adapter->rx_ring_count = new_rx_count; 409 if (err) {
410 while (i) {
411 i--;
412 ixgbevf_free_rx_resources(adapter,
413 &rx_ring[i]);
414 }
415 goto err_rx_ring_setup;
416 }
417 rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
433 } 418 }
434 419
420 /*
421 * Only switch to new rings if all the prior allocations
422 * and ring setups have succeeded.
423 */
424 kfree(adapter->tx_ring);
425 adapter->tx_ring = tx_ring;
426 adapter->tx_ring_count = new_tx_count;
427
428 kfree(adapter->rx_ring);
429 adapter->rx_ring = rx_ring;
430 adapter->rx_ring_count = new_rx_count;
431
435 /* success! */ 432 /* success! */
436 err = 0; 433 ixgbevf_up(adapter);
437 if (netif_running(netdev))
438 ixgbevf_up(adapter);
439 434
440err_setup: 435 goto clear_reset;
436
437err_rx_ring_setup:
438 for(i = 0; i < adapter->num_tx_queues; i++)
439 ixgbevf_free_tx_resources(adapter, &tx_ring[i]);
440
441err_tx_ring_setup:
442 kfree(rx_ring);
443
444err_rx_setup:
445 kfree(tx_ring);
446
447clear_reset:
441 clear_bit(__IXGBEVF_RESETTING, &adapter->state); 448 clear_bit(__IXGBEVF_RESETTING, &adapter->state);
442 return err; 449 return err;
443} 450}
@@ -539,7 +546,7 @@ struct ixgbevf_reg_test {
539#define TABLE64_TEST_HI 6 546#define TABLE64_TEST_HI 6
540 547
541/* default VF register test */ 548/* default VF register test */
542static struct ixgbevf_reg_test reg_test_vf[] = { 549static const struct ixgbevf_reg_test reg_test_vf[] = {
543 { IXGBE_VFRDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 }, 550 { IXGBE_VFRDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
544 { IXGBE_VFRDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 551 { IXGBE_VFRDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
545 { IXGBE_VFRDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, 552 { IXGBE_VFRDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
@@ -552,19 +559,23 @@ static struct ixgbevf_reg_test reg_test_vf[] = {
552 { 0, 0, 0, 0 } 559 { 0, 0, 0, 0 }
553}; 560};
554 561
562static const u32 register_test_patterns[] = {
563 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
564};
565
555#define REG_PATTERN_TEST(R, M, W) \ 566#define REG_PATTERN_TEST(R, M, W) \
556{ \ 567{ \
557 u32 pat, val, before; \ 568 u32 pat, val, before; \
558 const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ 569 for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { \
559 for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { \
560 before = readl(adapter->hw.hw_addr + R); \ 570 before = readl(adapter->hw.hw_addr + R); \
561 writel((_test[pat] & W), (adapter->hw.hw_addr + R)); \ 571 writel((register_test_patterns[pat] & W), \
572 (adapter->hw.hw_addr + R)); \
562 val = readl(adapter->hw.hw_addr + R); \ 573 val = readl(adapter->hw.hw_addr + R); \
563 if (val != (_test[pat] & W & M)) { \ 574 if (val != (register_test_patterns[pat] & W & M)) { \
564 hw_dbg(&adapter->hw, \ 575 hw_dbg(&adapter->hw, \
565 "pattern test reg %04X failed: got " \ 576 "pattern test reg %04X failed: got " \
566 "0x%08X expected 0x%08X\n", \ 577 "0x%08X expected 0x%08X\n", \
567 R, val, (_test[pat] & W & M)); \ 578 R, val, (register_test_patterns[pat] & W & M)); \
568 *data = R; \ 579 *data = R; \
569 writel(before, adapter->hw.hw_addr + R); \ 580 writel(before, adapter->hw.hw_addr + R); \
570 return 1; \ 581 return 1; \
@@ -591,7 +602,7 @@ static struct ixgbevf_reg_test reg_test_vf[] = {
591 602
592static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data) 603static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data)
593{ 604{
594 struct ixgbevf_reg_test *test; 605 const struct ixgbevf_reg_test *test;
595 u32 i; 606 u32 i;
596 607
597 test = reg_test_vf; 608 test = reg_test_vf;