mdio-cavium.c (8be98d2f2a0a262f8bf8a0bc1fdf522b3c7aab17) | mdio-cavium.c (93641ecbaa1f2602c455842ad0b0fe066f5f1344) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2009-2016 Cavium, Inc. 4 */ 5 6#include <linux/delay.h> 7#include <linux/io.h> 8#include <linux/module.h> --- 12 unchanged lines hidden (view full) --- 21 smi_clk.u64 = oct_mdio_readq(p->register_base + SMI_CLK); 22 smi_clk.s.mode = (m == C45) ? 1 : 0; 23 smi_clk.s.preamble = 1; 24 oct_mdio_writeq(smi_clk.u64, p->register_base + SMI_CLK); 25 p->mode = m; 26} 27 28static int cavium_mdiobus_c45_addr(struct cavium_mdiobus *p, | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2009-2016 Cavium, Inc. 4 */ 5 6#include <linux/delay.h> 7#include <linux/io.h> 8#include <linux/module.h> --- 12 unchanged lines hidden (view full) --- 21 smi_clk.u64 = oct_mdio_readq(p->register_base + SMI_CLK); 22 smi_clk.s.mode = (m == C45) ? 1 : 0; 23 smi_clk.s.preamble = 1; 24 oct_mdio_writeq(smi_clk.u64, p->register_base + SMI_CLK); 25 p->mode = m; 26} 27 28static int cavium_mdiobus_c45_addr(struct cavium_mdiobus *p, |
29 int phy_id, int regnum) | 29 int phy_id, int devad, int regnum) |
30{ 31 union cvmx_smix_cmd smi_cmd; 32 union cvmx_smix_wr_dat smi_wr; 33 int timeout = 1000; 34 35 cavium_mdiobus_set_mode(p, C45); 36 37 smi_wr.u64 = 0; 38 smi_wr.s.dat = regnum & 0xffff; 39 oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT); 40 | 30{ 31 union cvmx_smix_cmd smi_cmd; 32 union cvmx_smix_wr_dat smi_wr; 33 int timeout = 1000; 34 35 cavium_mdiobus_set_mode(p, C45); 36 37 smi_wr.u64 = 0; 38 smi_wr.s.dat = regnum & 0xffff; 39 oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT); 40 |
41 regnum = (regnum >> 16) & 0x1f; 42 | |
43 smi_cmd.u64 = 0; 44 smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_45_ADDRESS */ 45 smi_cmd.s.phy_adr = phy_id; | 41 smi_cmd.u64 = 0; 42 smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_45_ADDRESS */ 43 smi_cmd.s.phy_adr = phy_id; |
46 smi_cmd.s.reg_adr = regnum; | 44 smi_cmd.s.reg_adr = devad; |
47 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD); 48 49 do { 50 /* Wait 1000 clocks so we don't saturate the RSL bus 51 * doing reads. 52 */ 53 __delay(1000); 54 smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT); 55 } while (smi_wr.s.pending && --timeout); 56 57 if (timeout <= 0) 58 return -EIO; 59 return 0; 60} 61 | 45 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD); 46 47 do { 48 /* Wait 1000 clocks so we don't saturate the RSL bus 49 * doing reads. 50 */ 51 __delay(1000); 52 smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT); 53 } while (smi_wr.s.pending && --timeout); 54 55 if (timeout <= 0) 56 return -EIO; 57 return 0; 58} 59 |
62int cavium_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) | 60int cavium_mdiobus_read_c22(struct mii_bus *bus, int phy_id, int regnum) |
63{ 64 struct cavium_mdiobus *p = bus->priv; 65 union cvmx_smix_cmd smi_cmd; 66 union cvmx_smix_rd_dat smi_rd; | 61{ 62 struct cavium_mdiobus *p = bus->priv; 63 union cvmx_smix_cmd smi_cmd; 64 union cvmx_smix_rd_dat smi_rd; |
67 unsigned int op = 1; /* MDIO_CLAUSE_22_READ */ | |
68 int timeout = 1000; 69 | 65 int timeout = 1000; 66 |
70 if (regnum & MII_ADDR_C45) { 71 int r = cavium_mdiobus_c45_addr(p, phy_id, regnum); | 67 cavium_mdiobus_set_mode(p, C22); |
72 | 68 |
73 if (r < 0) 74 return r; | 69 smi_cmd.u64 = 0; 70 smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_22_READ */; 71 smi_cmd.s.phy_adr = phy_id; 72 smi_cmd.s.reg_adr = regnum; 73 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD); |
75 | 74 |
76 regnum = (regnum >> 16) & 0x1f; 77 op = 3; /* MDIO_CLAUSE_45_READ */ 78 } else { 79 cavium_mdiobus_set_mode(p, C22); 80 } | 75 do { 76 /* Wait 1000 clocks so we don't saturate the RSL bus 77 * doing reads. 78 */ 79 __delay(1000); 80 smi_rd.u64 = oct_mdio_readq(p->register_base + SMI_RD_DAT); 81 } while (smi_rd.s.pending && --timeout); |
81 | 82 |
83 if (smi_rd.s.val) 84 return smi_rd.s.dat; 85 else 86 return -EIO; 87} 88EXPORT_SYMBOL(cavium_mdiobus_read_c22); 89 90int cavium_mdiobus_read_c45(struct mii_bus *bus, int phy_id, int devad, 91 int regnum) 92{ 93 struct cavium_mdiobus *p = bus->priv; 94 union cvmx_smix_cmd smi_cmd; 95 union cvmx_smix_rd_dat smi_rd; 96 int timeout = 1000; 97 int r; 98 99 r = cavium_mdiobus_c45_addr(p, phy_id, devad, regnum); 100 if (r < 0) 101 return r; 102 |
|
82 smi_cmd.u64 = 0; | 103 smi_cmd.u64 = 0; |
83 smi_cmd.s.phy_op = op; | 104 smi_cmd.s.phy_op = 3; /* MDIO_CLAUSE_45_READ */ |
84 smi_cmd.s.phy_adr = phy_id; 85 smi_cmd.s.reg_adr = regnum; 86 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD); 87 88 do { 89 /* Wait 1000 clocks so we don't saturate the RSL bus 90 * doing reads. 91 */ 92 __delay(1000); 93 smi_rd.u64 = oct_mdio_readq(p->register_base + SMI_RD_DAT); 94 } while (smi_rd.s.pending && --timeout); 95 96 if (smi_rd.s.val) 97 return smi_rd.s.dat; 98 else 99 return -EIO; 100} | 105 smi_cmd.s.phy_adr = phy_id; 106 smi_cmd.s.reg_adr = regnum; 107 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD); 108 109 do { 110 /* Wait 1000 clocks so we don't saturate the RSL bus 111 * doing reads. 112 */ 113 __delay(1000); 114 smi_rd.u64 = oct_mdio_readq(p->register_base + SMI_RD_DAT); 115 } while (smi_rd.s.pending && --timeout); 116 117 if (smi_rd.s.val) 118 return smi_rd.s.dat; 119 else 120 return -EIO; 121} |
101EXPORT_SYMBOL(cavium_mdiobus_read); | 122EXPORT_SYMBOL(cavium_mdiobus_read_c45); |
102 | 123 |
103int cavium_mdiobus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val) | 124int cavium_mdiobus_write_c22(struct mii_bus *bus, int phy_id, int regnum, 125 u16 val) |
104{ 105 struct cavium_mdiobus *p = bus->priv; 106 union cvmx_smix_cmd smi_cmd; 107 union cvmx_smix_wr_dat smi_wr; | 126{ 127 struct cavium_mdiobus *p = bus->priv; 128 union cvmx_smix_cmd smi_cmd; 129 union cvmx_smix_wr_dat smi_wr; |
108 unsigned int op = 0; /* MDIO_CLAUSE_22_WRITE */ | |
109 int timeout = 1000; 110 | 130 int timeout = 1000; 131 |
111 if (regnum & MII_ADDR_C45) { 112 int r = cavium_mdiobus_c45_addr(p, phy_id, regnum); | 132 cavium_mdiobus_set_mode(p, C22); |
113 | 133 |
114 if (r < 0) 115 return r; | 134 smi_wr.u64 = 0; 135 smi_wr.s.dat = val; 136 oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT); |
116 | 137 |
117 regnum = (regnum >> 16) & 0x1f; 118 op = 1; /* MDIO_CLAUSE_45_WRITE */ 119 } else { 120 cavium_mdiobus_set_mode(p, C22); 121 } | 138 smi_cmd.u64 = 0; 139 smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_22_WRITE */; 140 smi_cmd.s.phy_adr = phy_id; 141 smi_cmd.s.reg_adr = regnum; 142 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD); |
122 | 143 |
144 do { 145 /* Wait 1000 clocks so we don't saturate the RSL bus 146 * doing reads. 147 */ 148 __delay(1000); 149 smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT); 150 } while (smi_wr.s.pending && --timeout); 151 152 if (timeout <= 0) 153 return -EIO; 154 155 return 0; 156} 157EXPORT_SYMBOL(cavium_mdiobus_write_c22); 158 159int cavium_mdiobus_write_c45(struct mii_bus *bus, int phy_id, int devad, 160 int regnum, u16 val) 161{ 162 struct cavium_mdiobus *p = bus->priv; 163 union cvmx_smix_cmd smi_cmd; 164 union cvmx_smix_wr_dat smi_wr; 165 int timeout = 1000; 166 int r; 167 168 r = cavium_mdiobus_c45_addr(p, phy_id, devad, regnum); 169 if (r < 0) 170 return r; 171 |
|
123 smi_wr.u64 = 0; 124 smi_wr.s.dat = val; 125 oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT); 126 127 smi_cmd.u64 = 0; | 172 smi_wr.u64 = 0; 173 smi_wr.s.dat = val; 174 oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT); 175 176 smi_cmd.u64 = 0; |
128 smi_cmd.s.phy_op = op; | 177 smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_45_WRITE */ |
129 smi_cmd.s.phy_adr = phy_id; | 178 smi_cmd.s.phy_adr = phy_id; |
130 smi_cmd.s.reg_adr = regnum; | 179 smi_cmd.s.reg_adr = devad; |
131 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD); 132 133 do { 134 /* Wait 1000 clocks so we don't saturate the RSL bus 135 * doing reads. 136 */ 137 __delay(1000); 138 smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT); 139 } while (smi_wr.s.pending && --timeout); 140 141 if (timeout <= 0) 142 return -EIO; 143 144 return 0; 145} | 180 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD); 181 182 do { 183 /* Wait 1000 clocks so we don't saturate the RSL bus 184 * doing reads. 185 */ 186 __delay(1000); 187 smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT); 188 } while (smi_wr.s.pending && --timeout); 189 190 if (timeout <= 0) 191 return -EIO; 192 193 return 0; 194} |
146EXPORT_SYMBOL(cavium_mdiobus_write); | 195EXPORT_SYMBOL(cavium_mdiobus_write_c45); |
147 148MODULE_DESCRIPTION("Common code for OCTEON and Thunder MDIO bus drivers"); 149MODULE_AUTHOR("David Daney"); 150MODULE_LICENSE("GPL v2"); | 196 197MODULE_DESCRIPTION("Common code for OCTEON and Thunder MDIO bus drivers"); 198MODULE_AUTHOR("David Daney"); 199MODULE_LICENSE("GPL v2"); |