Skip to content

Commit 1d3018a

Browse files
JBarberUkartben
authored andcommitted
driver: mdio: mdio_nxp_enet: Implement c45 read/write
This change refactors the mdio_read / mdio_write functions into an mdio_wransfer, and utilizes it to implement mdio_{read,write,read_c45,write_c45}. Heavily inspired by the implementation in drivers/mdio/mdio_sam.c Signed-off-by: John Barbero Unenge <[email protected]>
1 parent db16853 commit 1d3018a

File tree

1 file changed

+46
-51
lines changed

1 file changed

+46
-51
lines changed

drivers/mdio/mdio_nxp_enet.c

+46-51
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,8 @@ static int nxp_enet_mdio_wait_xfer(const struct device *dev)
5959
return 0;
6060
}
6161

62-
/* MDIO Read API implementation */
63-
static int nxp_enet_mdio_read(const struct device *dev,
64-
uint8_t prtad, uint8_t regad, uint16_t *read_data)
62+
static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t regad,
63+
enum mdio_opcode op, bool c45, uint16_t data_in, uint16_t *data_out)
6564
{
6665
struct nxp_enet_mdio_data *data = dev->data;
6766
int ret;
@@ -71,25 +70,27 @@ static int nxp_enet_mdio_read(const struct device *dev,
7170

7271
/*
7372
* Clear the bit (W1C) that indicates MDIO transfer is ready to
74-
* prepare to wait for it to be set once this read is done
73+
* prepare to wait for it to be set once this transfer is done
7574
*/
7675
data->base->EIR = ENET_EIR_MII_MASK;
7776

7877
/*
7978
* Write MDIO frame to MII management register which will
80-
* send the read command and data out to the MDIO bus as this frame:
81-
* ST = start, 1 means start
82-
* OP = operation, 2 means read
79+
* send the command and data out to the MDIO bus as this frame:
80+
* ST = start, C22: 1 means start
81+
* C45: 0 means start
82+
* OP = operation, see mdio_opcode for specifics on what the values are
8383
* PA = PHY/Port address
8484
* RA = Register/Device Address
8585
* TA = Turnaround, must be 2 to be valid
8686
* data = data to be written to the PHY register
8787
*/
88-
data->base->MMFR = ENET_MMFR_ST(0x1U) |
89-
ENET_MMFR_OP(MDIO_OP_C22_READ) |
90-
ENET_MMFR_PA(prtad) |
91-
ENET_MMFR_RA(regad) |
92-
ENET_MMFR_TA(0x2U);
88+
data->base->MMFR = ENET_MMFR_ST(c45 ? 0x0U : 0x1U)
89+
| ENET_MMFR_OP(op)
90+
| ENET_MMFR_PA(prtad)
91+
| ENET_MMFR_RA(regad)
92+
| ENET_MMFR_TA(0x2U)
93+
| data_in;
9394

9495
ret = nxp_enet_mdio_wait_xfer(dev);
9596
if (ret) {
@@ -98,7 +99,9 @@ static int nxp_enet_mdio_read(const struct device *dev,
9899
}
99100

100101
/* The data is received in the same register that we wrote the command to */
101-
*read_data = (data->base->MMFR & ENET_MMFR_DATA_MASK) >> ENET_MMFR_DATA_SHIFT;
102+
if (data_out != NULL) {
103+
*data_out = (data->base->MMFR & ENET_MMFR_DATA_MASK) >> ENET_MMFR_DATA_SHIFT;
104+
}
102105

103106
/* Clear the same bit as before because the event has been handled */
104107
data->base->EIR = ENET_EIR_MII_MASK;
@@ -109,57 +112,49 @@ static int nxp_enet_mdio_read(const struct device *dev,
109112
return ret;
110113
}
111114

112-
/* MDIO Write API implementation */
113-
static int nxp_enet_mdio_write(const struct device *dev,
114-
uint8_t prtad, uint8_t regad, uint16_t write_data)
115+
static int nxp_enet_mdio_read(const struct device *dev, uint8_t prtad, uint8_t regad,
116+
uint16_t *read_data)
115117
{
116-
struct nxp_enet_mdio_data *data = dev->data;
117-
int ret;
118-
119-
/* Only one MDIO bus operation attempt at a time */
120-
(void)k_mutex_lock(&data->mdio_mutex, K_FOREVER);
118+
return mdio_transfer(dev, prtad, regad, MDIO_OP_C22_READ, false, 0, read_data);
119+
}
121120

122-
/*
123-
* Clear the bit (W1C) that indicates MDIO transfer is ready to
124-
* prepare to wait for it to be set once this write is done
125-
*/
126-
data->base->EIR = ENET_EIR_MII_MASK;
121+
static int nxp_enet_mdio_write(const struct device *dev, uint8_t prtad, uint8_t regad,
122+
uint16_t write_data)
123+
{
124+
return mdio_transfer(dev, prtad, regad, MDIO_OP_C22_WRITE, false, write_data, NULL);
125+
}
127126

128-
/*
129-
* Write MDIO frame to MII management register which will
130-
* send the write command and data out to the MDIO bus as this frame:
131-
* ST = start, 1 means start
132-
* OP = operation, 1 means write
133-
* PA = PHY/Port address
134-
* RA = Register/Device Address
135-
* TA = Turnaround, must be 2 to be valid
136-
* data = data to be written to the PHY register
137-
*/
138-
data->base->MMFR = ENET_MMFR_ST(0x1U) |
139-
ENET_MMFR_OP(MDIO_OP_C22_WRITE) |
140-
ENET_MMFR_PA(prtad) |
141-
ENET_MMFR_RA(regad) |
142-
ENET_MMFR_TA(0x2U) |
143-
write_data;
127+
static int nxp_enet_mdio_read_c45(const struct device *dev, uint8_t prtad, uint8_t devad,
128+
uint16_t regad, uint16_t *data)
129+
{
130+
int err;
144131

145-
ret = nxp_enet_mdio_wait_xfer(dev);
146-
if (ret) {
147-
(void)k_mutex_unlock(&data->mdio_mutex);
148-
return ret;
132+
err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_ADDRESS, true, regad, NULL);
133+
if (!err) {
134+
err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_READ, true, 0, data);
149135
}
150136

151-
/* Clear the same bit as before because the event has been handled */
152-
data->base->EIR = ENET_EIR_MII_MASK;
137+
return err;
138+
}
153139

154-
/* This MDIO interaction is finished */
155-
(void)k_mutex_unlock(&data->mdio_mutex);
140+
int nxp_enet_mdio_write_c45(const struct device *dev, uint8_t prtad, uint8_t devad, uint16_t regad,
141+
uint16_t data)
142+
{
143+
int err;
156144

157-
return ret;
145+
err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_ADDRESS, true, regad, NULL);
146+
if (!err) {
147+
err = mdio_transfer(dev, prtad, devad, MDIO_OP_C45_WRITE, true, data, NULL);
148+
}
149+
150+
return err;
158151
}
159152

160153
static DEVICE_API(mdio, nxp_enet_mdio_api) = {
161154
.read = nxp_enet_mdio_read,
162155
.write = nxp_enet_mdio_write,
156+
.read_c45 = nxp_enet_mdio_read_c45,
157+
.write_c45 = nxp_enet_mdio_write_c45
163158
};
164159

165160
static void nxp_enet_mdio_isr_cb(const struct device *dev)

0 commit comments

Comments
 (0)