hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
....@@ -3,6 +3,7 @@
33
44 #include <linux/pci.h>
55 #include <linux/delay.h>
6
+#include <linux/iopoll.h>
67 #include <linux/sched.h>
78
89 #include "ixgbe.h"
....@@ -658,6 +659,303 @@
658659 return status;
659660 }
660661
662
+#define IXGBE_HW_READ_REG(addr) IXGBE_READ_REG(hw, addr)
663
+
664
+/**
665
+ * ixgbe_msca_cmd - Write the command register and poll for completion/timeout
666
+ * @hw: pointer to hardware structure
667
+ * @cmd: command register value to write
668
+ **/
669
+static s32 ixgbe_msca_cmd(struct ixgbe_hw *hw, u32 cmd)
670
+{
671
+ IXGBE_WRITE_REG(hw, IXGBE_MSCA, cmd);
672
+
673
+ return readx_poll_timeout(IXGBE_HW_READ_REG, IXGBE_MSCA, cmd,
674
+ !(cmd & IXGBE_MSCA_MDI_COMMAND), 10,
675
+ 10 * IXGBE_MDIO_COMMAND_TIMEOUT);
676
+}
677
+
678
+/**
679
+ * ixgbe_mii_bus_read_generic - Read a clause 22/45 register with gssr flags
680
+ * @hw: pointer to hardware structure
681
+ * @addr: address
682
+ * @regnum: register number
683
+ * @gssr: semaphore flags to acquire
684
+ **/
685
+static s32 ixgbe_mii_bus_read_generic(struct ixgbe_hw *hw, int addr,
686
+ int regnum, u32 gssr)
687
+{
688
+ u32 hwaddr, cmd;
689
+ s32 data;
690
+
691
+ if (hw->mac.ops.acquire_swfw_sync(hw, gssr))
692
+ return -EBUSY;
693
+
694
+ hwaddr = addr << IXGBE_MSCA_PHY_ADDR_SHIFT;
695
+ if (regnum & MII_ADDR_C45) {
696
+ hwaddr |= regnum & GENMASK(21, 0);
697
+ cmd = hwaddr | IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND;
698
+ } else {
699
+ hwaddr |= (regnum & GENMASK(5, 0)) << IXGBE_MSCA_DEV_TYPE_SHIFT;
700
+ cmd = hwaddr | IXGBE_MSCA_OLD_PROTOCOL |
701
+ IXGBE_MSCA_READ_AUTOINC | IXGBE_MSCA_MDI_COMMAND;
702
+ }
703
+
704
+ data = ixgbe_msca_cmd(hw, cmd);
705
+ if (data < 0)
706
+ goto mii_bus_read_done;
707
+
708
+ /* For a clause 45 access the address cycle just completed, we still
709
+ * need to do the read command, otherwise just get the data
710
+ */
711
+ if (!(regnum & MII_ADDR_C45))
712
+ goto do_mii_bus_read;
713
+
714
+ cmd = hwaddr | IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND;
715
+ data = ixgbe_msca_cmd(hw, cmd);
716
+ if (data < 0)
717
+ goto mii_bus_read_done;
718
+
719
+do_mii_bus_read:
720
+ data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
721
+ data = (data >> IXGBE_MSRWD_READ_DATA_SHIFT) & GENMASK(16, 0);
722
+
723
+mii_bus_read_done:
724
+ hw->mac.ops.release_swfw_sync(hw, gssr);
725
+ return data;
726
+}
727
+
728
+/**
729
+ * ixgbe_mii_bus_write_generic - Write a clause 22/45 register with gssr flags
730
+ * @hw: pointer to hardware structure
731
+ * @addr: address
732
+ * @regnum: register number
733
+ * @val: value to write
734
+ * @gssr: semaphore flags to acquire
735
+ **/
736
+static s32 ixgbe_mii_bus_write_generic(struct ixgbe_hw *hw, int addr,
737
+ int regnum, u16 val, u32 gssr)
738
+{
739
+ u32 hwaddr, cmd;
740
+ s32 err;
741
+
742
+ if (hw->mac.ops.acquire_swfw_sync(hw, gssr))
743
+ return -EBUSY;
744
+
745
+ IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)val);
746
+
747
+ hwaddr = addr << IXGBE_MSCA_PHY_ADDR_SHIFT;
748
+ if (regnum & MII_ADDR_C45) {
749
+ hwaddr |= regnum & GENMASK(21, 0);
750
+ cmd = hwaddr | IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND;
751
+ } else {
752
+ hwaddr |= (regnum & GENMASK(5, 0)) << IXGBE_MSCA_DEV_TYPE_SHIFT;
753
+ cmd = hwaddr | IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_WRITE |
754
+ IXGBE_MSCA_MDI_COMMAND;
755
+ }
756
+
757
+ /* For clause 45 this is an address cycle, for clause 22 this is the
758
+ * entire transaction
759
+ */
760
+ err = ixgbe_msca_cmd(hw, cmd);
761
+ if (err < 0 || !(regnum & MII_ADDR_C45))
762
+ goto mii_bus_write_done;
763
+
764
+ cmd = hwaddr | IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND;
765
+ err = ixgbe_msca_cmd(hw, cmd);
766
+
767
+mii_bus_write_done:
768
+ hw->mac.ops.release_swfw_sync(hw, gssr);
769
+ return err;
770
+}
771
+
772
+/**
773
+ * ixgbe_mii_bus_read - Read a clause 22/45 register
774
+ * @bus: pointer to mii_bus structure which points to our driver private
775
+ * @addr: address
776
+ * @regnum: register number
777
+ **/
778
+static s32 ixgbe_mii_bus_read(struct mii_bus *bus, int addr, int regnum)
779
+{
780
+ struct ixgbe_adapter *adapter = bus->priv;
781
+ struct ixgbe_hw *hw = &adapter->hw;
782
+ u32 gssr = hw->phy.phy_semaphore_mask;
783
+
784
+ return ixgbe_mii_bus_read_generic(hw, addr, regnum, gssr);
785
+}
786
+
787
+/**
788
+ * ixgbe_mii_bus_write - Write a clause 22/45 register
789
+ * @bus: pointer to mii_bus structure which points to our driver private
790
+ * @addr: address
791
+ * @regnum: register number
792
+ * @val: value to write
793
+ **/
794
+static s32 ixgbe_mii_bus_write(struct mii_bus *bus, int addr, int regnum,
795
+ u16 val)
796
+{
797
+ struct ixgbe_adapter *adapter = bus->priv;
798
+ struct ixgbe_hw *hw = &adapter->hw;
799
+ u32 gssr = hw->phy.phy_semaphore_mask;
800
+
801
+ return ixgbe_mii_bus_write_generic(hw, addr, regnum, val, gssr);
802
+}
803
+
804
+/**
805
+ * ixgbe_x550em_a_mii_bus_read - Read a clause 22/45 register on x550em_a
806
+ * @bus: pointer to mii_bus structure which points to our driver private
807
+ * @addr: address
808
+ * @regnum: register number
809
+ **/
810
+static s32 ixgbe_x550em_a_mii_bus_read(struct mii_bus *bus, int addr,
811
+ int regnum)
812
+{
813
+ struct ixgbe_adapter *adapter = bus->priv;
814
+ struct ixgbe_hw *hw = &adapter->hw;
815
+ u32 gssr = hw->phy.phy_semaphore_mask;
816
+
817
+ gssr |= IXGBE_GSSR_TOKEN_SM | IXGBE_GSSR_PHY0_SM;
818
+ return ixgbe_mii_bus_read_generic(hw, addr, regnum, gssr);
819
+}
820
+
821
+/**
822
+ * ixgbe_x550em_a_mii_bus_write - Write a clause 22/45 register on x550em_a
823
+ * @bus: pointer to mii_bus structure which points to our driver private
824
+ * @addr: address
825
+ * @regnum: register number
826
+ * @val: value to write
827
+ **/
828
+static s32 ixgbe_x550em_a_mii_bus_write(struct mii_bus *bus, int addr,
829
+ int regnum, u16 val)
830
+{
831
+ struct ixgbe_adapter *adapter = bus->priv;
832
+ struct ixgbe_hw *hw = &adapter->hw;
833
+ u32 gssr = hw->phy.phy_semaphore_mask;
834
+
835
+ gssr |= IXGBE_GSSR_TOKEN_SM | IXGBE_GSSR_PHY0_SM;
836
+ return ixgbe_mii_bus_write_generic(hw, addr, regnum, val, gssr);
837
+}
838
+
839
+/**
840
+ * ixgbe_get_first_secondary_devfn - get first device downstream of root port
841
+ * @devfn: PCI_DEVFN of root port on domain 0, bus 0
842
+ *
843
+ * Returns pci_dev pointer to PCI_DEVFN(0, 0) on subordinate side of root
844
+ * on domain 0, bus 0, devfn = 'devfn'
845
+ **/
846
+static struct pci_dev *ixgbe_get_first_secondary_devfn(unsigned int devfn)
847
+{
848
+ struct pci_dev *rp_pdev;
849
+ int bus;
850
+
851
+ rp_pdev = pci_get_domain_bus_and_slot(0, 0, devfn);
852
+ if (rp_pdev && rp_pdev->subordinate) {
853
+ bus = rp_pdev->subordinate->number;
854
+ return pci_get_domain_bus_and_slot(0, bus, 0);
855
+ }
856
+
857
+ return NULL;
858
+}
859
+
860
+/**
861
+ * ixgbe_x550em_a_has_mii - is this the first ixgbe x550em_a PCI function?
862
+ * @hw: pointer to hardware structure
863
+ *
864
+ * Returns true if hw points to lowest numbered PCI B:D.F x550_em_a device in
865
+ * the SoC. There are up to 4 MACs sharing a single MDIO bus on the x550em_a,
866
+ * but we only want to register one MDIO bus.
867
+ **/
868
+static bool ixgbe_x550em_a_has_mii(struct ixgbe_hw *hw)
869
+{
870
+ struct ixgbe_adapter *adapter = hw->back;
871
+ struct pci_dev *pdev = adapter->pdev;
872
+ struct pci_dev *func0_pdev;
873
+
874
+ /* For the C3000 family of SoCs (x550em_a) the internal ixgbe devices
875
+ * are always downstream of root ports @ 0000:00:16.0 & 0000:00:17.0
876
+ * It's not valid for function 0 to be disabled and function 1 is up,
877
+ * so the lowest numbered ixgbe dev will be device 0 function 0 on one
878
+ * of those two root ports
879
+ */
880
+ func0_pdev = ixgbe_get_first_secondary_devfn(PCI_DEVFN(0x16, 0));
881
+ if (func0_pdev) {
882
+ if (func0_pdev == pdev)
883
+ return true;
884
+ else
885
+ return false;
886
+ }
887
+ func0_pdev = ixgbe_get_first_secondary_devfn(PCI_DEVFN(0x17, 0));
888
+ if (func0_pdev == pdev)
889
+ return true;
890
+
891
+ return false;
892
+}
893
+
894
+/**
895
+ * ixgbe_mii_bus_init - mii_bus structure setup
896
+ * @hw: pointer to hardware structure
897
+ *
898
+ * Returns 0 on success, negative on failure
899
+ *
900
+ * ixgbe_mii_bus_init initializes a mii_bus structure in adapter
901
+ **/
902
+s32 ixgbe_mii_bus_init(struct ixgbe_hw *hw)
903
+{
904
+ s32 (*write)(struct mii_bus *bus, int addr, int regnum, u16 val);
905
+ s32 (*read)(struct mii_bus *bus, int addr, int regnum);
906
+ struct ixgbe_adapter *adapter = hw->back;
907
+ struct pci_dev *pdev = adapter->pdev;
908
+ struct device *dev = &adapter->netdev->dev;
909
+ struct mii_bus *bus;
910
+
911
+ switch (hw->device_id) {
912
+ /* C3000 SoCs */
913
+ case IXGBE_DEV_ID_X550EM_A_KR:
914
+ case IXGBE_DEV_ID_X550EM_A_KR_L:
915
+ case IXGBE_DEV_ID_X550EM_A_SFP_N:
916
+ case IXGBE_DEV_ID_X550EM_A_SGMII:
917
+ case IXGBE_DEV_ID_X550EM_A_SGMII_L:
918
+ case IXGBE_DEV_ID_X550EM_A_10G_T:
919
+ case IXGBE_DEV_ID_X550EM_A_SFP:
920
+ case IXGBE_DEV_ID_X550EM_A_1G_T:
921
+ case IXGBE_DEV_ID_X550EM_A_1G_T_L:
922
+ if (!ixgbe_x550em_a_has_mii(hw))
923
+ return 0;
924
+ read = &ixgbe_x550em_a_mii_bus_read;
925
+ write = &ixgbe_x550em_a_mii_bus_write;
926
+ break;
927
+ default:
928
+ read = &ixgbe_mii_bus_read;
929
+ write = &ixgbe_mii_bus_write;
930
+ break;
931
+ }
932
+
933
+ bus = devm_mdiobus_alloc(dev);
934
+ if (!bus)
935
+ return -ENOMEM;
936
+
937
+ bus->read = read;
938
+ bus->write = write;
939
+
940
+ /* Use the position of the device in the PCI hierarchy as the id */
941
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mdio-%s", ixgbe_driver_name,
942
+ pci_name(pdev));
943
+
944
+ bus->name = "ixgbe-mdio";
945
+ bus->priv = adapter;
946
+ bus->parent = dev;
947
+ bus->phy_mask = GENMASK(31, 0);
948
+
949
+ /* Support clause 22/45 natively. ixgbe_probe() sets MDIO_EMULATE_C22
950
+ * unfortunately that causes some clause 22 frames to be sent with
951
+ * clause 45 addressing. We don't want that.
952
+ */
953
+ hw->phy.mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22;
954
+
955
+ adapter->mii_bus = bus;
956
+ return mdiobus_register(bus);
957
+}
958
+
661959 /**
662960 * ixgbe_setup_phy_link_generic - Set and restart autoneg
663961 * @hw: pointer to hardware structure