aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorLendacky, Thomas <Thomas.Lendacky@amd.com>2015-01-16 13:47:00 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-16 22:24:20 -0500
commitc3152d4728ca5f87688b1d9bf3e61de43235cbb0 (patch)
tree1e01fad3b329fb800d20f9f8f998664f42eae46c /drivers/net/phy
parenta83ef427b7d97314df30d6e25abc7aa3a80ffcfd (diff)
amd-xgbe-phy: Change auto-negotiation logic
The auto negotiation logic was geared to being the initiator of the auto negotiation. This presented problems when auto negotiation was initiated by the remote end. Change the auto negotiation logic to make use of the auto negotiation event interrupt thus allowing the auto negotiation state machine to function properly in either scenario. This also removes the polling during auto-negotiation. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/amd-xgbe-phy.c627
1 files changed, 361 insertions, 266 deletions
diff --git a/drivers/net/phy/amd-xgbe-phy.c b/drivers/net/phy/amd-xgbe-phy.c
index 5ce42e324eb7..7fde5088c797 100644
--- a/drivers/net/phy/amd-xgbe-phy.c
+++ b/drivers/net/phy/amd-xgbe-phy.c
@@ -60,6 +60,7 @@
60#include <linux/interrupt.h> 60#include <linux/interrupt.h>
61#include <linux/init.h> 61#include <linux/init.h>
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <linux/workqueue.h>
63#include <linux/netdevice.h> 64#include <linux/netdevice.h>
64#include <linux/etherdevice.h> 65#include <linux/etherdevice.h>
65#include <linux/skbuff.h> 66#include <linux/skbuff.h>
@@ -89,6 +90,7 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
89#define XGBE_AN_INT_CMPLT 0x01 90#define XGBE_AN_INT_CMPLT 0x01
90#define XGBE_AN_INC_LINK 0x02 91#define XGBE_AN_INC_LINK 0x02
91#define XGBE_AN_PG_RCV 0x04 92#define XGBE_AN_PG_RCV 0x04
93#define XGBE_AN_INT_MASK 0x07
92 94
93#define XNP_MCF_NULL_MESSAGE 0x001 95#define XNP_MCF_NULL_MESSAGE 0x001
94#define XNP_ACK_PROCESSED BIT(12) 96#define XNP_ACK_PROCESSED BIT(12)
@@ -117,18 +119,10 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
117#define MDIO_AN_INT 0x8002 119#define MDIO_AN_INT 0x8002
118#endif 120#endif
119 121
120#ifndef MDIO_AN_KR_CTRL
121#define MDIO_AN_KR_CTRL 0x8003
122#endif
123
124#ifndef MDIO_CTRL1_SPEED1G 122#ifndef MDIO_CTRL1_SPEED1G
125#define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100) 123#define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100)
126#endif 124#endif
127 125
128#ifndef MDIO_KR_CTRL_PDETECT
129#define MDIO_KR_CTRL_PDETECT 0x01
130#endif
131
132/* SerDes integration register offsets */ 126/* SerDes integration register offsets */
133#define SIR0_KR_RT_1 0x002c 127#define SIR0_KR_RT_1 0x002c
134#define SIR0_STATUS 0x0040 128#define SIR0_STATUS 0x0040
@@ -294,21 +288,18 @@ do { \
294 288
295enum amd_xgbe_phy_an { 289enum amd_xgbe_phy_an {
296 AMD_XGBE_AN_READY = 0, 290 AMD_XGBE_AN_READY = 0,
297 AMD_XGBE_AN_START,
298 AMD_XGBE_AN_EVENT,
299 AMD_XGBE_AN_PAGE_RECEIVED, 291 AMD_XGBE_AN_PAGE_RECEIVED,
300 AMD_XGBE_AN_INCOMPAT_LINK, 292 AMD_XGBE_AN_INCOMPAT_LINK,
301 AMD_XGBE_AN_COMPLETE, 293 AMD_XGBE_AN_COMPLETE,
302 AMD_XGBE_AN_NO_LINK, 294 AMD_XGBE_AN_NO_LINK,
303 AMD_XGBE_AN_EXIT,
304 AMD_XGBE_AN_ERROR, 295 AMD_XGBE_AN_ERROR,
305}; 296};
306 297
307enum amd_xgbe_phy_rx { 298enum amd_xgbe_phy_rx {
308 AMD_XGBE_RX_READY = 0, 299 AMD_XGBE_RX_BPA = 0,
309 AMD_XGBE_RX_BPA,
310 AMD_XGBE_RX_XNP, 300 AMD_XGBE_RX_XNP,
311 AMD_XGBE_RX_COMPLETE, 301 AMD_XGBE_RX_COMPLETE,
302 AMD_XGBE_RX_ERROR,
312}; 303};
313 304
314enum amd_xgbe_phy_mode { 305enum amd_xgbe_phy_mode {
@@ -337,8 +328,11 @@ struct amd_xgbe_phy_priv {
337 void __iomem *sir0_regs; /* SerDes integration registers (1/2) */ 328 void __iomem *sir0_regs; /* SerDes integration registers (1/2) */
338 void __iomem *sir1_regs; /* SerDes integration registers (2/2) */ 329 void __iomem *sir1_regs; /* SerDes integration registers (2/2) */
339 330
340 /* Maintain link status for re-starting auto-negotiation */ 331 int an_irq;
341 unsigned int link; 332 char an_irq_name[IFNAMSIZ + 32];
333 struct work_struct an_irq_work;
334 unsigned int an_irq_allocated;
335
342 unsigned int speed_set; 336 unsigned int speed_set;
343 337
344 /* Auto-negotiation state machine support */ 338 /* Auto-negotiation state machine support */
@@ -349,6 +343,7 @@ struct amd_xgbe_phy_priv {
349 enum amd_xgbe_phy_rx kx_state; 343 enum amd_xgbe_phy_rx kx_state;
350 struct work_struct an_work; 344 struct work_struct an_work;
351 struct workqueue_struct *an_workqueue; 345 struct workqueue_struct *an_workqueue;
346 unsigned int an_supported;
352 unsigned int parallel_detect; 347 unsigned int parallel_detect;
353 348
354 unsigned int lpm_ctrl; /* CTRL1 for resume */ 349 unsigned int lpm_ctrl; /* CTRL1 for resume */
@@ -638,6 +633,38 @@ static int amd_xgbe_phy_set_mode(struct phy_device *phydev,
638 return ret; 633 return ret;
639} 634}
640 635
636static int amd_xgbe_phy_set_an(struct phy_device *phydev, bool enable,
637 bool restart)
638{
639 int ret;
640
641 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
642 if (ret < 0)
643 return ret;
644
645 ret &= ~MDIO_AN_CTRL1_ENABLE;
646
647 if (enable)
648 ret |= MDIO_AN_CTRL1_ENABLE;
649
650 if (restart)
651 ret |= MDIO_AN_CTRL1_RESTART;
652
653 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, ret);
654
655 return 0;
656}
657
658static int amd_xgbe_phy_restart_an(struct phy_device *phydev)
659{
660 return amd_xgbe_phy_set_an(phydev, true, true);
661}
662
663static int amd_xgbe_phy_disable_an(struct phy_device *phydev)
664{
665 return amd_xgbe_phy_set_an(phydev, false, false);
666}
667
641static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev, 668static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
642 enum amd_xgbe_phy_rx *state) 669 enum amd_xgbe_phy_rx *state)
643{ 670{
@@ -648,7 +675,7 @@ static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
648 675
649 /* If we're not in KR mode then we're done */ 676 /* If we're not in KR mode then we're done */
650 if (!amd_xgbe_phy_in_kr_mode(phydev)) 677 if (!amd_xgbe_phy_in_kr_mode(phydev))
651 return AMD_XGBE_AN_EVENT; 678 return AMD_XGBE_AN_PAGE_RECEIVED;
652 679
653 /* Enable/Disable FEC */ 680 /* Enable/Disable FEC */
654 ad_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 681 ad_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
@@ -682,7 +709,7 @@ static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
682 709
683 XSIR0_IOWRITE_BITS(priv, SIR0_KR_RT_1, RESET, 0); 710 XSIR0_IOWRITE_BITS(priv, SIR0_KR_RT_1, RESET, 0);
684 711
685 return AMD_XGBE_AN_EVENT; 712 return AMD_XGBE_AN_PAGE_RECEIVED;
686} 713}
687 714
688static enum amd_xgbe_phy_an amd_xgbe_an_tx_xnp(struct phy_device *phydev, 715static enum amd_xgbe_phy_an amd_xgbe_an_tx_xnp(struct phy_device *phydev,
@@ -699,7 +726,7 @@ static enum amd_xgbe_phy_an amd_xgbe_an_tx_xnp(struct phy_device *phydev,
699 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0); 726 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0);
700 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_XNP, msg); 727 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_XNP, msg);
701 728
702 return AMD_XGBE_AN_EVENT; 729 return AMD_XGBE_AN_PAGE_RECEIVED;
703} 730}
704 731
705static enum amd_xgbe_phy_an amd_xgbe_an_rx_bpa(struct phy_device *phydev, 732static enum amd_xgbe_phy_an amd_xgbe_an_rx_bpa(struct phy_device *phydev,
@@ -751,226 +778,255 @@ static enum amd_xgbe_phy_an amd_xgbe_an_rx_xnp(struct phy_device *phydev,
751 amd_xgbe_an_tx_training(phydev, state); 778 amd_xgbe_an_tx_training(phydev, state);
752} 779}
753 780
754static enum amd_xgbe_phy_an amd_xgbe_an_start(struct phy_device *phydev) 781static enum amd_xgbe_phy_an amd_xgbe_an_page_received(struct phy_device *phydev)
782{
783 struct amd_xgbe_phy_priv *priv = phydev->priv;
784 enum amd_xgbe_phy_rx *state;
785 int ret;
786
787 state = amd_xgbe_phy_in_kr_mode(phydev) ? &priv->kr_state
788 : &priv->kx_state;
789
790 switch (*state) {
791 case AMD_XGBE_RX_BPA:
792 ret = amd_xgbe_an_rx_bpa(phydev, state);
793 break;
794
795 case AMD_XGBE_RX_XNP:
796 ret = amd_xgbe_an_rx_xnp(phydev, state);
797 break;
798
799 default:
800 ret = AMD_XGBE_AN_ERROR;
801 }
802
803 return ret;
804}
805
806static enum amd_xgbe_phy_an amd_xgbe_an_incompat_link(struct phy_device *phydev)
755{ 807{
756 struct amd_xgbe_phy_priv *priv = phydev->priv; 808 struct amd_xgbe_phy_priv *priv = phydev->priv;
757 int ret; 809 int ret;
758 810
759 /* Be sure we aren't looping trying to negotiate */ 811 /* Be sure we aren't looping trying to negotiate */
760 if (amd_xgbe_phy_in_kr_mode(phydev)) { 812 if (amd_xgbe_phy_in_kr_mode(phydev)) {
761 if (priv->kr_state != AMD_XGBE_RX_READY) 813 priv->kr_state = AMD_XGBE_RX_ERROR;
814
815 if (!(phydev->supported & SUPPORTED_1000baseKX_Full) &&
816 !(phydev->supported & SUPPORTED_2500baseX_Full))
817 return AMD_XGBE_AN_NO_LINK;
818
819 if (priv->kx_state != AMD_XGBE_RX_BPA)
762 return AMD_XGBE_AN_NO_LINK; 820 return AMD_XGBE_AN_NO_LINK;
763 priv->kr_state = AMD_XGBE_RX_BPA;
764 } else { 821 } else {
765 if (priv->kx_state != AMD_XGBE_RX_READY) 822 priv->kx_state = AMD_XGBE_RX_ERROR;
823
824 if (!(phydev->supported & SUPPORTED_10000baseKR_Full))
825 return AMD_XGBE_AN_NO_LINK;
826
827 if (priv->kr_state != AMD_XGBE_RX_BPA)
766 return AMD_XGBE_AN_NO_LINK; 828 return AMD_XGBE_AN_NO_LINK;
767 priv->kx_state = AMD_XGBE_RX_BPA;
768 } 829 }
769 830
770 /* Set up Advertisement register 3 first */ 831 ret = amd_xgbe_phy_disable_an(phydev);
771 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 832 if (ret)
772 if (ret < 0)
773 return AMD_XGBE_AN_ERROR; 833 return AMD_XGBE_AN_ERROR;
774 834
775 if (phydev->supported & SUPPORTED_10000baseR_FEC) 835 ret = amd_xgbe_phy_switch_mode(phydev);
776 ret |= 0xc000; 836 if (ret)
777 else
778 ret &= ~0xc000;
779
780 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, ret);
781
782 /* Set up Advertisement register 2 next */
783 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
784 if (ret < 0)
785 return AMD_XGBE_AN_ERROR; 837 return AMD_XGBE_AN_ERROR;
786 838
787 if (phydev->supported & SUPPORTED_10000baseKR_Full) 839 ret = amd_xgbe_phy_restart_an(phydev);
788 ret |= 0x80; 840 if (ret)
789 else
790 ret &= ~0x80;
791
792 if ((phydev->supported & SUPPORTED_1000baseKX_Full) ||
793 (phydev->supported & SUPPORTED_2500baseX_Full))
794 ret |= 0x20;
795 else
796 ret &= ~0x20;
797
798 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, ret);
799
800 /* Set up Advertisement register 1 last */
801 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
802 if (ret < 0)
803 return AMD_XGBE_AN_ERROR; 841 return AMD_XGBE_AN_ERROR;
804 842
805 if (phydev->supported & SUPPORTED_Pause) 843 return AMD_XGBE_AN_INCOMPAT_LINK;
806 ret |= 0x400; 844}
807 else
808 ret &= ~0x400;
809 845
810 if (phydev->supported & SUPPORTED_Asym_Pause) 846static irqreturn_t amd_xgbe_an_isr(int irq, void *data)
811 ret |= 0x800; 847{
812 else 848 struct amd_xgbe_phy_priv *priv = (struct amd_xgbe_phy_priv *)data;
813 ret &= ~0x800;
814 849
815 /* We don't intend to perform XNP */ 850 /* Interrupt reason must be read and cleared outside of IRQ context */
816 ret &= ~XNP_NP_EXCHANGE; 851 disable_irq_nosync(priv->an_irq);
817 852
818 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, ret); 853 queue_work(priv->an_workqueue, &priv->an_irq_work);
819 854
820 /* Enable and start auto-negotiation */ 855 return IRQ_HANDLED;
821 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0); 856}
822 857
823 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_KR_CTRL); 858static void amd_xgbe_an_irq_work(struct work_struct *work)
824 if (ret < 0) 859{
825 return AMD_XGBE_AN_ERROR; 860 struct amd_xgbe_phy_priv *priv = container_of(work,
861 struct amd_xgbe_phy_priv,
862 an_irq_work);
826 863
827 ret |= MDIO_KR_CTRL_PDETECT; 864 /* Avoid a race between enabling the IRQ and exiting the work by
828 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_KR_CTRL, ret); 865 * waiting for the work to finish and then queueing it
866 */
867 flush_work(&priv->an_work);
868 queue_work(priv->an_workqueue, &priv->an_work);
869}
829 870
830 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1); 871static void amd_xgbe_an_state_machine(struct work_struct *work)
831 if (ret < 0) 872{
832 return AMD_XGBE_AN_ERROR; 873 struct amd_xgbe_phy_priv *priv = container_of(work,
874 struct amd_xgbe_phy_priv,
875 an_work);
876 struct phy_device *phydev = priv->phydev;
877 enum amd_xgbe_phy_an cur_state = priv->an_state;
878 int int_reg, int_mask;
833 879
834 ret |= MDIO_AN_CTRL1_ENABLE; 880 mutex_lock(&priv->an_mutex);
835 ret |= MDIO_AN_CTRL1_RESTART;
836 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, ret);
837 881
838 return AMD_XGBE_AN_EVENT; 882 /* Read the interrupt */
839} 883 int_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT);
884 if (!int_reg)
885 goto out;
840 886
841static enum amd_xgbe_phy_an amd_xgbe_an_event(struct phy_device *phydev) 887next_int:
842{ 888 if (int_reg < 0) {
843 enum amd_xgbe_phy_an new_state; 889 priv->an_state = AMD_XGBE_AN_ERROR;
844 int ret; 890 int_mask = XGBE_AN_INT_MASK;
891 } else if (int_reg & XGBE_AN_PG_RCV) {
892 priv->an_state = AMD_XGBE_AN_PAGE_RECEIVED;
893 int_mask = XGBE_AN_PG_RCV;
894 } else if (int_reg & XGBE_AN_INC_LINK) {
895 priv->an_state = AMD_XGBE_AN_INCOMPAT_LINK;
896 int_mask = XGBE_AN_INC_LINK;
897 } else if (int_reg & XGBE_AN_INT_CMPLT) {
898 priv->an_state = AMD_XGBE_AN_COMPLETE;
899 int_mask = XGBE_AN_INT_CMPLT;
900 } else {
901 priv->an_state = AMD_XGBE_AN_ERROR;
902 int_mask = 0;
903 }
845 904
846 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT); 905 /* Clear the interrupt to be processed */
847 if (ret < 0) 906 int_reg &= ~int_mask;
848 return AMD_XGBE_AN_ERROR; 907 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, int_reg);
849 908
850 new_state = AMD_XGBE_AN_EVENT; 909 priv->an_result = priv->an_state;
851 if (ret & XGBE_AN_PG_RCV)
852 new_state = AMD_XGBE_AN_PAGE_RECEIVED;
853 else if (ret & XGBE_AN_INC_LINK)
854 new_state = AMD_XGBE_AN_INCOMPAT_LINK;
855 else if (ret & XGBE_AN_INT_CMPLT)
856 new_state = AMD_XGBE_AN_COMPLETE;
857 910
858 if (new_state != AMD_XGBE_AN_EVENT) 911again:
859 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0); 912 cur_state = priv->an_state;
860 913
861 return new_state; 914 switch (priv->an_state) {
862} 915 case AMD_XGBE_AN_READY:
916 priv->an_supported = 0;
917 break;
863 918
864static enum amd_xgbe_phy_an amd_xgbe_an_page_received(struct phy_device *phydev) 919 case AMD_XGBE_AN_PAGE_RECEIVED:
865{ 920 priv->an_state = amd_xgbe_an_page_received(phydev);
866 struct amd_xgbe_phy_priv *priv = phydev->priv; 921 priv->an_supported++;
867 enum amd_xgbe_phy_rx *state; 922 break;
868 int ret;
869 923
870 state = amd_xgbe_phy_in_kr_mode(phydev) ? &priv->kr_state 924 case AMD_XGBE_AN_INCOMPAT_LINK:
871 : &priv->kx_state; 925 priv->an_supported = 0;
926 priv->parallel_detect = 0;
927 priv->an_state = amd_xgbe_an_incompat_link(phydev);
928 break;
872 929
873 switch (*state) { 930 case AMD_XGBE_AN_COMPLETE:
874 case AMD_XGBE_RX_BPA: 931 priv->parallel_detect = priv->an_supported ? 0 : 1;
875 ret = amd_xgbe_an_rx_bpa(phydev, state); 932 netdev_dbg(phydev->attached_dev, "%s successful\n",
933 priv->an_supported ? "Auto negotiation"
934 : "Parallel detection");
876 break; 935 break;
877 936
878 case AMD_XGBE_RX_XNP: 937 case AMD_XGBE_AN_NO_LINK:
879 ret = amd_xgbe_an_rx_xnp(phydev, state);
880 break; 938 break;
881 939
882 default: 940 default:
883 ret = AMD_XGBE_AN_ERROR; 941 priv->an_state = AMD_XGBE_AN_ERROR;
884 } 942 }
885 943
886 return ret; 944 if (priv->an_state == AMD_XGBE_AN_NO_LINK) {
887} 945 int_reg = 0;
946 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
947 } else if (priv->an_state == AMD_XGBE_AN_ERROR) {
948 netdev_err(phydev->attached_dev,
949 "error during auto-negotiation, state=%u\n",
950 cur_state);
888 951
889static enum amd_xgbe_phy_an amd_xgbe_an_incompat_link(struct phy_device *phydev) 952 int_reg = 0;
890{ 953 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
891 int ret; 954 }
892 955
893 ret = amd_xgbe_phy_switch_mode(phydev); 956 if (priv->an_state >= AMD_XGBE_AN_COMPLETE) {
894 if (ret) 957 priv->an_result = priv->an_state;
895 return AMD_XGBE_AN_ERROR; 958 priv->an_state = AMD_XGBE_AN_READY;
959 priv->kr_state = AMD_XGBE_RX_BPA;
960 priv->kx_state = AMD_XGBE_RX_BPA;
961 }
896 962
897 return AMD_XGBE_AN_START; 963 if (cur_state != priv->an_state)
898} 964 goto again;
899 965
900static void amd_xgbe_an_state_machine(struct work_struct *work) 966 if (int_reg)
901{ 967 goto next_int;
902 struct amd_xgbe_phy_priv *priv = container_of(work,
903 struct amd_xgbe_phy_priv,
904 an_work);
905 struct phy_device *phydev = priv->phydev;
906 enum amd_xgbe_phy_an cur_state;
907 int sleep;
908 unsigned int an_supported = 0;
909 968
910 /* Start in KX mode */ 969out:
911 if (amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX)) 970 enable_irq(priv->an_irq);
912 priv->an_state = AMD_XGBE_AN_ERROR;
913 971
914 while (1) { 972 mutex_unlock(&priv->an_mutex);
915 mutex_lock(&priv->an_mutex); 973}
916 974
917 cur_state = priv->an_state; 975static int amd_xgbe_an_init(struct phy_device *phydev)
976{
977 int ret;
918 978
919 switch (priv->an_state) { 979 /* Set up Advertisement register 3 first */
920 case AMD_XGBE_AN_START: 980 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
921 an_supported = 0; 981 if (ret < 0)
922 priv->parallel_detect = 0; 982 return ret;
923 priv->an_state = amd_xgbe_an_start(phydev);
924 break;
925 983
926 case AMD_XGBE_AN_EVENT: 984 if (phydev->supported & SUPPORTED_10000baseR_FEC)
927 priv->an_state = amd_xgbe_an_event(phydev); 985 ret |= 0xc000;
928 break; 986 else
987 ret &= ~0xc000;
929 988
930 case AMD_XGBE_AN_PAGE_RECEIVED: 989 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, ret);
931 priv->an_state = amd_xgbe_an_page_received(phydev);
932 an_supported++;
933 break;
934 990
935 case AMD_XGBE_AN_INCOMPAT_LINK: 991 /* Set up Advertisement register 2 next */
936 priv->an_state = amd_xgbe_an_incompat_link(phydev); 992 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
937 break; 993 if (ret < 0)
994 return ret;
938 995
939 case AMD_XGBE_AN_COMPLETE: 996 if (phydev->supported & SUPPORTED_10000baseKR_Full)
940 priv->parallel_detect = an_supported ? 0 : 1; 997 ret |= 0x80;
941 netdev_info(phydev->attached_dev, "%s successful\n", 998 else
942 an_supported ? "Auto negotiation" 999 ret &= ~0x80;
943 : "Parallel detection");
944 /* fall through */
945 1000
946 case AMD_XGBE_AN_NO_LINK: 1001 if ((phydev->supported & SUPPORTED_1000baseKX_Full) ||
947 case AMD_XGBE_AN_EXIT: 1002 (phydev->supported & SUPPORTED_2500baseX_Full))
948 goto exit_unlock; 1003 ret |= 0x20;
1004 else
1005 ret &= ~0x20;
949 1006
950 default: 1007 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, ret);
951 priv->an_state = AMD_XGBE_AN_ERROR;
952 }
953 1008
954 if (priv->an_state == AMD_XGBE_AN_ERROR) { 1009 /* Set up Advertisement register 1 last */
955 netdev_err(phydev->attached_dev, 1010 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
956 "error during auto-negotiation, state=%u\n", 1011 if (ret < 0)
957 cur_state); 1012 return ret;
958 goto exit_unlock;
959 }
960 1013
961 sleep = (priv->an_state == AMD_XGBE_AN_EVENT) ? 1 : 0; 1014 if (phydev->supported & SUPPORTED_Pause)
1015 ret |= 0x400;
1016 else
1017 ret &= ~0x400;
962 1018
963 mutex_unlock(&priv->an_mutex); 1019 if (phydev->supported & SUPPORTED_Asym_Pause)
1020 ret |= 0x800;
1021 else
1022 ret &= ~0x800;
964 1023
965 if (sleep) 1024 /* We don't intend to perform XNP */
966 usleep_range(20, 50); 1025 ret &= ~XNP_NP_EXCHANGE;
967 }
968 1026
969exit_unlock: 1027 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, ret);
970 priv->an_result = priv->an_state;
971 priv->an_state = AMD_XGBE_AN_READY;
972 1028
973 mutex_unlock(&priv->an_mutex); 1029 return 0;
974} 1030}
975 1031
976static int amd_xgbe_phy_soft_reset(struct phy_device *phydev) 1032static int amd_xgbe_phy_soft_reset(struct phy_device *phydev)
@@ -995,13 +1051,46 @@ static int amd_xgbe_phy_soft_reset(struct phy_device *phydev)
995 if (ret & MDIO_CTRL1_RESET) 1051 if (ret & MDIO_CTRL1_RESET)
996 return -ETIMEDOUT; 1052 return -ETIMEDOUT;
997 1053
998 /* Make sure the XPCS and SerDes are in compatible states */ 1054 /* Disable auto-negotiation for now */
999 return amd_xgbe_phy_xgmii_mode(phydev); 1055 ret = amd_xgbe_phy_disable_an(phydev);
1056 if (ret < 0)
1057 return ret;
1058
1059 /* Clear auto-negotiation interrupts */
1060 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
1061
1062 return 0;
1000} 1063}
1001 1064
1002static int amd_xgbe_phy_config_init(struct phy_device *phydev) 1065static int amd_xgbe_phy_config_init(struct phy_device *phydev)
1003{ 1066{
1004 struct amd_xgbe_phy_priv *priv = phydev->priv; 1067 struct amd_xgbe_phy_priv *priv = phydev->priv;
1068 struct net_device *netdev = phydev->attached_dev;
1069 int ret;
1070
1071 if (!priv->an_irq_allocated) {
1072 /* Allocate the auto-negotiation workqueue and interrupt */
1073 snprintf(priv->an_irq_name, sizeof(priv->an_irq_name) - 1,
1074 "%s-pcs", netdev_name(netdev));
1075
1076 priv->an_workqueue =
1077 create_singlethread_workqueue(priv->an_irq_name);
1078 if (!priv->an_workqueue) {
1079 netdev_err(netdev, "phy workqueue creation failed\n");
1080 return -ENOMEM;
1081 }
1082
1083 ret = devm_request_irq(priv->dev, priv->an_irq,
1084 amd_xgbe_an_isr, 0, priv->an_irq_name,
1085 priv);
1086 if (ret) {
1087 netdev_err(netdev, "phy irq request failed\n");
1088 destroy_workqueue(priv->an_workqueue);
1089 return ret;
1090 }
1091
1092 priv->an_irq_allocated = 1;
1093 }
1005 1094
1006 /* Initialize supported features */ 1095 /* Initialize supported features */
1007 phydev->supported = SUPPORTED_Autoneg; 1096 phydev->supported = SUPPORTED_Autoneg;
@@ -1019,9 +1108,27 @@ static int amd_xgbe_phy_config_init(struct phy_device *phydev)
1019 } 1108 }
1020 phydev->advertising = phydev->supported; 1109 phydev->advertising = phydev->supported;
1021 1110
1022 /* Turn off and clear interrupts */ 1111 /* Set initial mode - call the mode setting routines
1023 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); 1112 * directly to insure we are properly configured
1024 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0); 1113 */
1114 if (phydev->supported & SUPPORTED_10000baseKR_Full)
1115 ret = amd_xgbe_phy_xgmii_mode(phydev);
1116 else if (phydev->supported & SUPPORTED_1000baseKX_Full)
1117 ret = amd_xgbe_phy_gmii_mode(phydev);
1118 else if (phydev->supported & SUPPORTED_2500baseX_Full)
1119 ret = amd_xgbe_phy_gmii_2500_mode(phydev);
1120 else
1121 ret = -EINVAL;
1122 if (ret < 0)
1123 return ret;
1124
1125 /* Set up advertisement registers based on current settings */
1126 ret = amd_xgbe_an_init(phydev);
1127 if (ret)
1128 return ret;
1129
1130 /* Enable auto-negotiation interrupts */
1131 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07);
1025 1132
1026 return 0; 1133 return 0;
1027} 1134}
@@ -1031,25 +1138,19 @@ static int amd_xgbe_phy_setup_forced(struct phy_device *phydev)
1031 int ret; 1138 int ret;
1032 1139
1033 /* Disable auto-negotiation */ 1140 /* Disable auto-negotiation */
1034 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1); 1141 ret = amd_xgbe_phy_disable_an(phydev);
1035 if (ret < 0) 1142 if (ret < 0)
1036 return ret; 1143 return ret;
1037 1144
1038 ret &= ~MDIO_AN_CTRL1_ENABLE;
1039 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, ret);
1040
1041 /* Validate/Set specified speed */ 1145 /* Validate/Set specified speed */
1042 switch (phydev->speed) { 1146 switch (phydev->speed) {
1043 case SPEED_10000: 1147 case SPEED_10000:
1044 ret = amd_xgbe_phy_xgmii_mode(phydev); 1148 ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KR);
1045 break; 1149 break;
1046 1150
1047 case SPEED_2500: 1151 case SPEED_2500:
1048 ret = amd_xgbe_phy_gmii_2500_mode(phydev);
1049 break;
1050
1051 case SPEED_1000: 1152 case SPEED_1000:
1052 ret = amd_xgbe_phy_gmii_mode(phydev); 1153 ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX);
1053 break; 1154 break;
1054 1155
1055 default: 1156 default:
@@ -1069,10 +1170,11 @@ static int amd_xgbe_phy_setup_forced(struct phy_device *phydev)
1069 return 0; 1170 return 0;
1070} 1171}
1071 1172
1072static int amd_xgbe_phy_config_aneg(struct phy_device *phydev) 1173static int __amd_xgbe_phy_config_aneg(struct phy_device *phydev)
1073{ 1174{
1074 struct amd_xgbe_phy_priv *priv = phydev->priv; 1175 struct amd_xgbe_phy_priv *priv = phydev->priv;
1075 u32 mmd_mask = phydev->c45_ids.devices_in_package; 1176 u32 mmd_mask = phydev->c45_ids.devices_in_package;
1177 int ret;
1076 1178
1077 if (phydev->autoneg != AUTONEG_ENABLE) 1179 if (phydev->autoneg != AUTONEG_ENABLE)
1078 return amd_xgbe_phy_setup_forced(phydev); 1180 return amd_xgbe_phy_setup_forced(phydev);
@@ -1081,56 +1183,79 @@ static int amd_xgbe_phy_config_aneg(struct phy_device *phydev)
1081 if (!(mmd_mask & MDIO_DEVS_AN)) 1183 if (!(mmd_mask & MDIO_DEVS_AN))
1082 return -EINVAL; 1184 return -EINVAL;
1083 1185
1084 /* Start/Restart the auto-negotiation state machine */ 1186 /* Disable auto-negotiation interrupt */
1085 mutex_lock(&priv->an_mutex); 1187 disable_irq(priv->an_irq);
1188
1189 /* Start auto-negotiation in a supported mode */
1190 if (phydev->supported & SUPPORTED_10000baseKR_Full)
1191 ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KR);
1192 else if ((phydev->supported & SUPPORTED_1000baseKX_Full) ||
1193 (phydev->supported & SUPPORTED_2500baseX_Full))
1194 ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX);
1195 else
1196 ret = -EINVAL;
1197 if (ret < 0) {
1198 enable_irq(priv->an_irq);
1199 return ret;
1200 }
1201
1202 /* Disable and stop any in progress auto-negotiation */
1203 ret = amd_xgbe_phy_disable_an(phydev);
1204 if (ret < 0)
1205 return ret;
1206
1207 /* Clear any auto-negotitation interrupts */
1208 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
1209
1086 priv->an_result = AMD_XGBE_AN_READY; 1210 priv->an_result = AMD_XGBE_AN_READY;
1087 priv->an_state = AMD_XGBE_AN_START; 1211 priv->an_state = AMD_XGBE_AN_READY;
1088 priv->kr_state = AMD_XGBE_RX_READY; 1212 priv->kr_state = AMD_XGBE_RX_BPA;
1089 priv->kx_state = AMD_XGBE_RX_READY; 1213 priv->kx_state = AMD_XGBE_RX_BPA;
1090 mutex_unlock(&priv->an_mutex);
1091 1214
1092 queue_work(priv->an_workqueue, &priv->an_work); 1215 /* Re-enable auto-negotiation interrupt */
1216 enable_irq(priv->an_irq);
1093 1217
1094 return 0; 1218 /* Set up advertisement registers based on current settings */
1219 ret = amd_xgbe_an_init(phydev);
1220 if (ret)
1221 return ret;
1222
1223 /* Enable and start auto-negotiation */
1224 return amd_xgbe_phy_restart_an(phydev);
1095} 1225}
1096 1226
1097static int amd_xgbe_phy_aneg_done(struct phy_device *phydev) 1227static int amd_xgbe_phy_config_aneg(struct phy_device *phydev)
1098{ 1228{
1099 struct amd_xgbe_phy_priv *priv = phydev->priv; 1229 struct amd_xgbe_phy_priv *priv = phydev->priv;
1100 enum amd_xgbe_phy_an state; 1230 int ret;
1101 1231
1102 mutex_lock(&priv->an_mutex); 1232 mutex_lock(&priv->an_mutex);
1103 state = priv->an_result; 1233
1234 ret = __amd_xgbe_phy_config_aneg(phydev);
1235
1104 mutex_unlock(&priv->an_mutex); 1236 mutex_unlock(&priv->an_mutex);
1105 1237
1106 return (state == AMD_XGBE_AN_COMPLETE); 1238 return ret;
1239}
1240
1241static int amd_xgbe_phy_aneg_done(struct phy_device *phydev)
1242{
1243 struct amd_xgbe_phy_priv *priv = phydev->priv;
1244
1245 return (priv->an_result == AMD_XGBE_AN_COMPLETE);
1107} 1246}
1108 1247
1109static int amd_xgbe_phy_update_link(struct phy_device *phydev) 1248static int amd_xgbe_phy_update_link(struct phy_device *phydev)
1110{ 1249{
1111 struct amd_xgbe_phy_priv *priv = phydev->priv; 1250 struct amd_xgbe_phy_priv *priv = phydev->priv;
1112 enum amd_xgbe_phy_an state;
1113 unsigned int check_again, autoneg;
1114 int ret; 1251 int ret;
1115 1252
1116 /* If we're doing auto-negotiation don't report link down */ 1253 /* If we're doing auto-negotiation don't report link down */
1117 mutex_lock(&priv->an_mutex); 1254 if (priv->an_state != AMD_XGBE_AN_READY) {
1118 state = priv->an_state;
1119 mutex_unlock(&priv->an_mutex);
1120
1121 if (state != AMD_XGBE_AN_READY) {
1122 phydev->link = 1; 1255 phydev->link = 1;
1123 return 0; 1256 return 0;
1124 } 1257 }
1125 1258
1126 /* Since the device can be in the wrong mode when a link is
1127 * (re-)established (cable connected after the interface is
1128 * up, etc.), the link status may report no link. If there
1129 * is no link, try switching modes and checking the status
1130 * again if auto negotiation is enabled.
1131 */
1132 check_again = (phydev->autoneg == AUTONEG_ENABLE) ? 1 : 0;
1133again:
1134 /* Link status is latched low, so read once to clear 1259 /* Link status is latched low, so read once to clear
1135 * and then read again to get current state 1260 * and then read again to get current state
1136 */ 1261 */
@@ -1144,25 +1269,6 @@ again:
1144 1269
1145 phydev->link = (ret & MDIO_STAT1_LSTATUS) ? 1 : 0; 1270 phydev->link = (ret & MDIO_STAT1_LSTATUS) ? 1 : 0;
1146 1271
1147 if (!phydev->link) {
1148 if (check_again) {
1149 ret = amd_xgbe_phy_switch_mode(phydev);
1150 if (ret < 0)
1151 return ret;
1152 check_again = 0;
1153 goto again;
1154 }
1155 }
1156
1157 autoneg = (phydev->link && !priv->link) ? 1 : 0;
1158 priv->link = phydev->link;
1159 if (autoneg) {
1160 /* Link is (back) up, re-start auto-negotiation */
1161 ret = amd_xgbe_phy_config_aneg(phydev);
1162 if (ret < 0)
1163 return ret;
1164 }
1165
1166 return 0; 1272 return 0;
1167} 1273}
1168 1274
@@ -1293,7 +1399,6 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
1293 struct amd_xgbe_phy_priv *priv; 1399 struct amd_xgbe_phy_priv *priv;
1294 struct platform_device *pdev; 1400 struct platform_device *pdev;
1295 struct device *dev; 1401 struct device *dev;
1296 char *wq_name;
1297 const __be32 *property; 1402 const __be32 *property;
1298 unsigned int speed_set; 1403 unsigned int speed_set;
1299 int ret; 1404 int ret;
@@ -1306,21 +1411,18 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
1306 return -EINVAL; 1411 return -EINVAL;
1307 dev = &pdev->dev; 1412 dev = &pdev->dev;
1308 1413
1309 wq_name = kasprintf(GFP_KERNEL, "%s-amd-xgbe-phy", phydev->bus->name);
1310 if (!wq_name) {
1311 ret = -ENOMEM;
1312 goto err_pdev;
1313 }
1314
1315 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 1414 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1316 if (!priv) { 1415 if (!priv) {
1317 ret = -ENOMEM; 1416 ret = -ENOMEM;
1318 goto err_name; 1417 goto err_pdev;
1319 } 1418 }
1320 1419
1321 priv->pdev = pdev; 1420 priv->pdev = pdev;
1322 priv->dev = dev; 1421 priv->dev = dev;
1323 priv->phydev = phydev; 1422 priv->phydev = phydev;
1423 mutex_init(&priv->an_mutex);
1424 INIT_WORK(&priv->an_irq_work, amd_xgbe_an_irq_work);
1425 INIT_WORK(&priv->an_work, amd_xgbe_an_state_machine);
1324 1426
1325 /* Get the device mmio areas */ 1427 /* Get the device mmio areas */
1326 priv->rxtx_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1428 priv->rxtx_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1347,6 +1449,14 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
1347 goto err_sir0; 1449 goto err_sir0;
1348 } 1450 }
1349 1451
1452 /* Get the auto-negotiation interrupt */
1453 ret = platform_get_irq(pdev, 0);
1454 if (ret < 0) {
1455 dev_err(dev, "platform_get_irq failed\n");
1456 goto err_sir1;
1457 }
1458 priv->an_irq = ret;
1459
1350 /* Get the device speed set property */ 1460 /* Get the device speed set property */
1351 speed_set = 0; 1461 speed_set = 0;
1352 property = of_get_property(dev->of_node, XGBE_PHY_SPEEDSET_PROPERTY, 1462 property = of_get_property(dev->of_node, XGBE_PHY_SPEEDSET_PROPERTY,
@@ -1367,19 +1477,8 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
1367 goto err_sir1; 1477 goto err_sir1;
1368 } 1478 }
1369 1479
1370 priv->link = 1;
1371
1372 mutex_init(&priv->an_mutex);
1373 INIT_WORK(&priv->an_work, amd_xgbe_an_state_machine);
1374 priv->an_workqueue = create_singlethread_workqueue(wq_name);
1375 if (!priv->an_workqueue) {
1376 ret = -ENOMEM;
1377 goto err_sir1;
1378 }
1379
1380 phydev->priv = priv; 1480 phydev->priv = priv;
1381 1481
1382 kfree(wq_name);
1383 of_dev_put(pdev); 1482 of_dev_put(pdev);
1384 1483
1385 return 0; 1484 return 0;
@@ -1402,9 +1501,6 @@ err_rxtx:
1402err_priv: 1501err_priv:
1403 devm_kfree(dev, priv); 1502 devm_kfree(dev, priv);
1404 1503
1405err_name:
1406 kfree(wq_name);
1407
1408err_pdev: 1504err_pdev:
1409 of_dev_put(pdev); 1505 of_dev_put(pdev);
1410 1506
@@ -1416,13 +1512,12 @@ static void amd_xgbe_phy_remove(struct phy_device *phydev)
1416 struct amd_xgbe_phy_priv *priv = phydev->priv; 1512 struct amd_xgbe_phy_priv *priv = phydev->priv;
1417 struct device *dev = priv->dev; 1513 struct device *dev = priv->dev;
1418 1514
1419 /* Stop any in process auto-negotiation */ 1515 if (priv->an_irq_allocated) {
1420 mutex_lock(&priv->an_mutex); 1516 devm_free_irq(dev, priv->an_irq, priv);
1421 priv->an_state = AMD_XGBE_AN_EXIT;
1422 mutex_unlock(&priv->an_mutex);
1423 1517
1424 flush_workqueue(priv->an_workqueue); 1518 flush_workqueue(priv->an_workqueue);
1425 destroy_workqueue(priv->an_workqueue); 1519 destroy_workqueue(priv->an_workqueue);
1520 }
1426 1521
1427 /* Release resources */ 1522 /* Release resources */
1428 devm_iounmap(dev, priv->sir1_regs); 1523 devm_iounmap(dev, priv->sir1_regs);