aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/tenxpress.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/tenxpress.c')
-rw-r--r--drivers/net/sfc/tenxpress.c213
1 files changed, 77 insertions, 136 deletions
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index f1365097b4fd..ac9eeab79f20 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -68,6 +68,8 @@
68#define PMA_PMD_EXT_CLK312_WIDTH 1 68#define PMA_PMD_EXT_CLK312_WIDTH 1
69#define PMA_PMD_EXT_LPOWER_LBN 12 69#define PMA_PMD_EXT_LPOWER_LBN 12
70#define PMA_PMD_EXT_LPOWER_WIDTH 1 70#define PMA_PMD_EXT_LPOWER_WIDTH 1
71#define PMA_PMD_EXT_ROBUST_LBN 14
72#define PMA_PMD_EXT_ROBUST_WIDTH 1
71#define PMA_PMD_EXT_SSR_LBN 15 73#define PMA_PMD_EXT_SSR_LBN 15
72#define PMA_PMD_EXT_SSR_WIDTH 1 74#define PMA_PMD_EXT_SSR_WIDTH 1
73 75
@@ -178,35 +180,24 @@
178#define C22EXT_STATUS_LINK_LBN 2 180#define C22EXT_STATUS_LINK_LBN 2
179#define C22EXT_STATUS_LINK_WIDTH 1 181#define C22EXT_STATUS_LINK_WIDTH 1
180 182
181#define C22EXT_MSTSLV_REG 49162 183#define C22EXT_MSTSLV_CTRL 49161
182#define C22EXT_MSTSLV_1000_HD_LBN 10 184#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8
183#define C22EXT_MSTSLV_1000_HD_WIDTH 1 185#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9
184#define C22EXT_MSTSLV_1000_FD_LBN 11 186
185#define C22EXT_MSTSLV_1000_FD_WIDTH 1 187#define C22EXT_MSTSLV_STATUS 49162
188#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10
189#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11
186 190
187/* Time to wait between powering down the LNPGA and turning off the power 191/* Time to wait between powering down the LNPGA and turning off the power
188 * rails */ 192 * rails */
189#define LNPGA_PDOWN_WAIT (HZ / 5) 193#define LNPGA_PDOWN_WAIT (HZ / 5)
190 194
191static int crc_error_reset_threshold = 100;
192module_param(crc_error_reset_threshold, int, 0644);
193MODULE_PARM_DESC(crc_error_reset_threshold,
194 "Max number of CRC errors before XAUI reset");
195
196struct tenxpress_phy_data { 195struct tenxpress_phy_data {
197 enum efx_loopback_mode loopback_mode; 196 enum efx_loopback_mode loopback_mode;
198 atomic_t bad_crc_count;
199 enum efx_phy_mode phy_mode; 197 enum efx_phy_mode phy_mode;
200 int bad_lp_tries; 198 int bad_lp_tries;
201}; 199};
202 200
203void tenxpress_crc_err(struct efx_nic *efx)
204{
205 struct tenxpress_phy_data *phy_data = efx->phy_data;
206 if (phy_data != NULL)
207 atomic_inc(&phy_data->bad_crc_count);
208}
209
210static ssize_t show_phy_short_reach(struct device *dev, 201static ssize_t show_phy_short_reach(struct device *dev,
211 struct device_attribute *attr, char *buf) 202 struct device_attribute *attr, char *buf)
212{ 203{
@@ -285,7 +276,9 @@ static int tenxpress_init(struct efx_nic *efx)
285 PMA_PMD_XCONTROL_REG); 276 PMA_PMD_XCONTROL_REG);
286 reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) | 277 reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
287 (1 << PMA_PMD_EXT_CLK_OUT_LBN) | 278 (1 << PMA_PMD_EXT_CLK_OUT_LBN) |
288 (1 << PMA_PMD_EXT_CLK312_LBN)); 279 (1 << PMA_PMD_EXT_CLK312_LBN) |
280 (1 << PMA_PMD_EXT_ROBUST_LBN));
281
289 mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, 282 mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
290 PMA_PMD_XCONTROL_REG, reg); 283 PMA_PMD_XCONTROL_REG, reg);
291 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, 284 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
@@ -347,6 +340,7 @@ static int tenxpress_phy_init(struct efx_nic *efx)
347 rc = tenxpress_init(efx); 340 rc = tenxpress_init(efx);
348 if (rc < 0) 341 if (rc < 0)
349 goto fail; 342 goto fail;
343 mdio_clause45_set_pause(efx);
350 344
351 if (efx->phy_type == PHY_TYPE_SFT9001B) { 345 if (efx->phy_type == PHY_TYPE_SFT9001B) {
352 rc = device_create_file(&efx->pci_dev->dev, 346 rc = device_create_file(&efx->pci_dev->dev,
@@ -377,8 +371,8 @@ static int tenxpress_special_reset(struct efx_nic *efx)
377 371
378 /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so 372 /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
379 * a special software reset can glitch the XGMAC sufficiently for stats 373 * a special software reset can glitch the XGMAC sufficiently for stats
380 * requests to fail. Since we don't often special_reset, just lock. */ 374 * requests to fail. */
381 spin_lock(&efx->stats_lock); 375 efx_stats_disable(efx);
382 376
383 /* Initiate reset */ 377 /* Initiate reset */
384 reg = mdio_clause45_read(efx, efx->mii.phy_id, 378 reg = mdio_clause45_read(efx, efx->mii.phy_id,
@@ -393,17 +387,17 @@ static int tenxpress_special_reset(struct efx_nic *efx)
393 rc = mdio_clause45_wait_reset_mmds(efx, 387 rc = mdio_clause45_wait_reset_mmds(efx,
394 TENXPRESS_REQUIRED_DEVS); 388 TENXPRESS_REQUIRED_DEVS);
395 if (rc < 0) 389 if (rc < 0)
396 goto unlock; 390 goto out;
397 391
398 /* Try and reconfigure the device */ 392 /* Try and reconfigure the device */
399 rc = tenxpress_init(efx); 393 rc = tenxpress_init(efx);
400 if (rc < 0) 394 if (rc < 0)
401 goto unlock; 395 goto out;
402 396
403 /* Wait for the XGXS state machine to churn */ 397 /* Wait for the XGXS state machine to churn */
404 mdelay(10); 398 mdelay(10);
405unlock: 399out:
406 spin_unlock(&efx->stats_lock); 400 efx_stats_enable(efx);
407 return rc; 401 return rc;
408} 402}
409 403
@@ -521,7 +515,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
521{ 515{
522 struct tenxpress_phy_data *phy_data = efx->phy_data; 516 struct tenxpress_phy_data *phy_data = efx->phy_data;
523 struct ethtool_cmd ecmd; 517 struct ethtool_cmd ecmd;
524 bool phy_mode_change, loop_reset, loop_toggle, loopback; 518 bool phy_mode_change, loop_reset;
525 519
526 if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { 520 if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
527 phy_data->phy_mode = efx->phy_mode; 521 phy_data->phy_mode = efx->phy_mode;
@@ -532,12 +526,10 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
532 526
533 phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && 527 phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
534 phy_data->phy_mode != PHY_MODE_NORMAL); 528 phy_data->phy_mode != PHY_MODE_NORMAL);
535 loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks;
536 loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks);
537 loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || 529 loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) ||
538 LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); 530 LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
539 531
540 if (loop_reset || loop_toggle || loopback || phy_mode_change) { 532 if (loop_reset || phy_mode_change) {
541 int rc; 533 int rc;
542 534
543 efx->phy_op->get_settings(efx, &ecmd); 535 efx->phy_op->get_settings(efx, &ecmd);
@@ -552,20 +544,6 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
552 falcon_reset_xaui(efx); 544 falcon_reset_xaui(efx);
553 } 545 }
554 546
555 if (efx->phy_type != PHY_TYPE_SFX7101) {
556 /* Only change autoneg once, on coming out or
557 * going into loopback */
558 if (loop_toggle)
559 ecmd.autoneg = !loopback;
560 if (loopback) {
561 ecmd.duplex = DUPLEX_FULL;
562 if (efx->loopback_mode == LOOPBACK_GPHY)
563 ecmd.speed = SPEED_1000;
564 else
565 ecmd.speed = SPEED_10000;
566 }
567 }
568
569 rc = efx->phy_op->set_settings(efx, &ecmd); 547 rc = efx->phy_op->set_settings(efx, &ecmd);
570 WARN_ON(rc); 548 WARN_ON(rc);
571 } 549 }
@@ -624,13 +602,6 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
624 602
625 if (phy_data->phy_mode != PHY_MODE_NORMAL) 603 if (phy_data->phy_mode != PHY_MODE_NORMAL)
626 return; 604 return;
627
628 if (EFX_WORKAROUND_10750(efx) &&
629 atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) {
630 EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n");
631 falcon_reset_xaui(efx);
632 atomic_set(&phy_data->bad_crc_count, 0);
633 }
634} 605}
635 606
636static void tenxpress_phy_fini(struct efx_nic *efx) 607static void tenxpress_phy_fini(struct efx_nic *efx)
@@ -773,107 +744,76 @@ reset:
773 return rc; 744 return rc;
774} 745}
775 746
776static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx) 747static void
748tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
777{ 749{
778 int phy = efx->mii.phy_id; 750 int phy_id = efx->mii.phy_id;
779 u32 lpa = 0; 751 u32 adv = 0, lpa = 0;
780 int reg; 752 int reg;
781 753
782 if (efx->phy_type != PHY_TYPE_SFX7101) { 754 if (efx->phy_type != PHY_TYPE_SFX7101) {
783 reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT, 755 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
784 C22EXT_MSTSLV_REG); 756 C22EXT_MSTSLV_CTRL);
785 if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN)) 757 if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
758 adv |= ADVERTISED_1000baseT_Full;
759 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
760 C22EXT_MSTSLV_STATUS);
761 if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
786 lpa |= ADVERTISED_1000baseT_Half; 762 lpa |= ADVERTISED_1000baseT_Half;
787 if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN)) 763 if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
788 lpa |= ADVERTISED_1000baseT_Full; 764 lpa |= ADVERTISED_1000baseT_Full;
789 } 765 }
790 reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS); 766 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
767 MDIO_AN_10GBT_CTRL);
768 if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
769 adv |= ADVERTISED_10000baseT_Full;
770 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
771 MDIO_AN_10GBT_STATUS);
791 if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) 772 if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
792 lpa |= ADVERTISED_10000baseT_Full; 773 lpa |= ADVERTISED_10000baseT_Full;
793 return lpa;
794}
795 774
796static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 775 mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
797{ 776
798 mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full, 777 if (efx->phy_type != PHY_TYPE_SFX7101)
799 tenxpress_get_xnp_lpa(efx)); 778 ecmd->supported |= (SUPPORTED_100baseT_Full |
800 ecmd->supported |= SUPPORTED_10000baseT_Full; 779 SUPPORTED_1000baseT_Full);
801 ecmd->advertising |= ADVERTISED_10000baseT_Full; 780
781 /* In loopback, the PHY automatically brings up the correct interface,
782 * but doesn't advertise the correct speed. So override it */
783 if (efx->loopback_mode == LOOPBACK_GPHY)
784 ecmd->speed = SPEED_1000;
785 else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
786 ecmd->speed = SPEED_10000;
802} 787}
803 788
804static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 789static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
805{ 790{
806 int phy_id = efx->mii.phy_id; 791 if (!ecmd->autoneg)
807 u32 xnp_adv = 0; 792 return -EINVAL;
808 int reg;
809
810 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
811 PMA_PMD_SPEED_ENABLE_REG);
812 if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN)))
813 xnp_adv |= ADVERTISED_100baseT_Full;
814 if (reg & (1 << PMA_PMD_1000T_ADV_LBN))
815 xnp_adv |= ADVERTISED_1000baseT_Full;
816 if (reg & (1 << PMA_PMD_10000T_ADV_LBN))
817 xnp_adv |= ADVERTISED_10000baseT_Full;
818
819 mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv,
820 tenxpress_get_xnp_lpa(efx));
821
822 ecmd->supported |= (SUPPORTED_100baseT_Half |
823 SUPPORTED_100baseT_Full |
824 SUPPORTED_1000baseT_Full);
825 793
826 /* Use the vendor defined C22ext register for duplex settings */ 794 return mdio_clause45_set_settings(efx, ecmd);
827 if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) {
828 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
829 GPHY_XCONTROL_REG);
830 ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
831 DUPLEX_FULL : DUPLEX_HALF);
832 }
833} 795}
834 796
835static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 797static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
836{ 798{
837 int phy_id = efx->mii.phy_id; 799 mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
838 int rc; 800 MDIO_AN_10GBT_CTRL,
839 801 MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
840 rc = mdio_clause45_set_settings(efx, ecmd); 802 advertising & ADVERTISED_10000baseT_Full);
841 if (rc)
842 return rc;
843
844 if (ecmd->speed != SPEED_10000 && !ecmd->autoneg)
845 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
846 GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN,
847 ecmd->duplex == DUPLEX_FULL);
848
849 return rc;
850} 803}
851 804
852static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising) 805static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
853{ 806{
854 int phy = efx->mii.phy_id; 807 int phy_id = efx->mii.phy_id;
855 int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD, 808
856 PMA_PMD_SPEED_ENABLE_REG); 809 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
857 bool enabled; 810 C22EXT_MSTSLV_CTRL,
858 811 C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
859 reg &= ~((1 << 2) | (1 << 3)); 812 advertising & ADVERTISED_1000baseT_Full);
860 if (EFX_WORKAROUND_13204(efx) && 813 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
861 (advertising & ADVERTISED_100baseT_Full)) 814 MDIO_AN_10GBT_CTRL,
862 reg |= 1 << PMA_PMD_100TX_ADV_LBN; 815 MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
863 if (advertising & ADVERTISED_1000baseT_Full) 816 advertising & ADVERTISED_10000baseT_Full);
864 reg |= 1 << PMA_PMD_1000T_ADV_LBN;
865 if (advertising & ADVERTISED_10000baseT_Full)
866 reg |= 1 << PMA_PMD_10000T_ADV_LBN;
867 mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD,
868 PMA_PMD_SPEED_ENABLE_REG, reg);
869
870 enabled = (advertising &
871 (ADVERTISED_1000baseT_Half |
872 ADVERTISED_1000baseT_Full |
873 ADVERTISED_10000baseT_Full));
874 if (EFX_WORKAROUND_13204(efx))
875 enabled |= (advertising & ADVERTISED_100baseT_Full);
876 return enabled;
877} 817}
878 818
879struct efx_phy_operations falcon_sfx7101_phy_ops = { 819struct efx_phy_operations falcon_sfx7101_phy_ops = {
@@ -883,8 +823,9 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
883 .poll = tenxpress_phy_poll, 823 .poll = tenxpress_phy_poll,
884 .fini = tenxpress_phy_fini, 824 .fini = tenxpress_phy_fini,
885 .clear_interrupt = efx_port_dummy_op_void, 825 .clear_interrupt = efx_port_dummy_op_void,
886 .get_settings = sfx7101_get_settings, 826 .get_settings = tenxpress_get_settings,
887 .set_settings = mdio_clause45_set_settings, 827 .set_settings = tenxpress_set_settings,
828 .set_npage_adv = sfx7101_set_npage_adv,
888 .num_tests = ARRAY_SIZE(sfx7101_test_names), 829 .num_tests = ARRAY_SIZE(sfx7101_test_names),
889 .test_names = sfx7101_test_names, 830 .test_names = sfx7101_test_names,
890 .run_tests = sfx7101_run_tests, 831 .run_tests = sfx7101_run_tests,
@@ -899,9 +840,9 @@ struct efx_phy_operations falcon_sft9001_phy_ops = {
899 .poll = tenxpress_phy_poll, 840 .poll = tenxpress_phy_poll,
900 .fini = tenxpress_phy_fini, 841 .fini = tenxpress_phy_fini,
901 .clear_interrupt = efx_port_dummy_op_void, 842 .clear_interrupt = efx_port_dummy_op_void,
902 .get_settings = sft9001_get_settings, 843 .get_settings = tenxpress_get_settings,
903 .set_settings = sft9001_set_settings, 844 .set_settings = tenxpress_set_settings,
904 .set_xnp_advertise = sft9001_set_xnp_advertise, 845 .set_npage_adv = sft9001_set_npage_adv,
905 .num_tests = ARRAY_SIZE(sft9001_test_names), 846 .num_tests = ARRAY_SIZE(sft9001_test_names),
906 .test_names = sft9001_test_names, 847 .test_names = sft9001_test_names,
907 .run_tests = sft9001_run_tests, 848 .run_tests = sft9001_run_tests,