1eb1e7c3eSFabien Chouteau /*
2eb1e7c3eSFabien Chouteau * QEMU Freescale eTSEC Emulator
3eb1e7c3eSFabien Chouteau *
4eb1e7c3eSFabien Chouteau * Copyright (c) 2011-2013 AdaCore
5eb1e7c3eSFabien Chouteau *
6eb1e7c3eSFabien Chouteau * Permission is hereby granted, free of charge, to any person obtaining a copy
7eb1e7c3eSFabien Chouteau * of this software and associated documentation files (the "Software"), to deal
8eb1e7c3eSFabien Chouteau * in the Software without restriction, including without limitation the rights
9eb1e7c3eSFabien Chouteau * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10eb1e7c3eSFabien Chouteau * copies of the Software, and to permit persons to whom the Software is
11eb1e7c3eSFabien Chouteau * furnished to do so, subject to the following conditions:
12eb1e7c3eSFabien Chouteau *
13eb1e7c3eSFabien Chouteau * The above copyright notice and this permission notice shall be included in
14eb1e7c3eSFabien Chouteau * all copies or substantial portions of the Software.
15eb1e7c3eSFabien Chouteau *
16eb1e7c3eSFabien Chouteau * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17eb1e7c3eSFabien Chouteau * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18eb1e7c3eSFabien Chouteau * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19eb1e7c3eSFabien Chouteau * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20eb1e7c3eSFabien Chouteau * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21eb1e7c3eSFabien Chouteau * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22eb1e7c3eSFabien Chouteau * THE SOFTWARE.
23eb1e7c3eSFabien Chouteau */
24eb1e7c3eSFabien Chouteau
25e8d40465SPeter Maydell #include "qemu/osdep.h"
266684bef1SAkihiko Odaki #include "hw/net/mii.h"
27eb1e7c3eSFabien Chouteau #include "etsec.h"
28eb1e7c3eSFabien Chouteau #include "registers.h"
29eb1e7c3eSFabien Chouteau
30eb1e7c3eSFabien Chouteau /* #define DEBUG_MIIM */
31eb1e7c3eSFabien Chouteau
miim_read_cycle(eTSEC * etsec)32eb1e7c3eSFabien Chouteau static void miim_read_cycle(eTSEC *etsec)
33eb1e7c3eSFabien Chouteau {
34eb1e7c3eSFabien Chouteau uint8_t phy;
35eb1e7c3eSFabien Chouteau uint8_t addr;
36eb1e7c3eSFabien Chouteau uint16_t value;
37eb1e7c3eSFabien Chouteau
38eb1e7c3eSFabien Chouteau phy = (etsec->regs[MIIMADD].value >> 8) & 0x1F;
39eb1e7c3eSFabien Chouteau (void)phy; /* Unreferenced */
40eb1e7c3eSFabien Chouteau addr = etsec->regs[MIIMADD].value & 0x1F;
41eb1e7c3eSFabien Chouteau
42eb1e7c3eSFabien Chouteau switch (addr) {
43*65a12bb5SBernhard Beschow case MII_BMCR:
44eb1e7c3eSFabien Chouteau value = etsec->phy_control;
45eb1e7c3eSFabien Chouteau break;
46*65a12bb5SBernhard Beschow case MII_BMSR:
47eb1e7c3eSFabien Chouteau value = etsec->phy_status;
48eb1e7c3eSFabien Chouteau break;
49*65a12bb5SBernhard Beschow case MII_STAT1000:
50*65a12bb5SBernhard Beschow value = MII_STAT1000_LOK | MII_STAT1000_ROK;
51eb1e7c3eSFabien Chouteau break;
52eb1e7c3eSFabien Chouteau default:
53eb1e7c3eSFabien Chouteau value = 0x0;
54eb1e7c3eSFabien Chouteau break;
55eb1e7c3eSFabien Chouteau };
56eb1e7c3eSFabien Chouteau
57eb1e7c3eSFabien Chouteau #ifdef DEBUG_MIIM
58eb1e7c3eSFabien Chouteau qemu_log("%s phy:%d addr:0x%x value:0x%x\n", __func__, phy, addr, value);
59eb1e7c3eSFabien Chouteau #endif
60eb1e7c3eSFabien Chouteau
61eb1e7c3eSFabien Chouteau etsec->regs[MIIMSTAT].value = value;
62eb1e7c3eSFabien Chouteau }
63eb1e7c3eSFabien Chouteau
miim_write_cycle(eTSEC * etsec)64eb1e7c3eSFabien Chouteau static void miim_write_cycle(eTSEC *etsec)
65eb1e7c3eSFabien Chouteau {
66eb1e7c3eSFabien Chouteau uint8_t phy;
67eb1e7c3eSFabien Chouteau uint8_t addr;
68eb1e7c3eSFabien Chouteau uint16_t value;
69eb1e7c3eSFabien Chouteau
70eb1e7c3eSFabien Chouteau phy = (etsec->regs[MIIMADD].value >> 8) & 0x1F;
71eb1e7c3eSFabien Chouteau (void)phy; /* Unreferenced */
72eb1e7c3eSFabien Chouteau addr = etsec->regs[MIIMADD].value & 0x1F;
73eb1e7c3eSFabien Chouteau value = etsec->regs[MIIMCON].value & 0xffff;
74eb1e7c3eSFabien Chouteau
75eb1e7c3eSFabien Chouteau #ifdef DEBUG_MIIM
76eb1e7c3eSFabien Chouteau qemu_log("%s phy:%d addr:0x%x value:0x%x\n", __func__, phy, addr, value);
77eb1e7c3eSFabien Chouteau #endif
78eb1e7c3eSFabien Chouteau
79eb1e7c3eSFabien Chouteau switch (addr) {
80*65a12bb5SBernhard Beschow case MII_BMCR:
81*65a12bb5SBernhard Beschow etsec->phy_control = value & ~(MII_BMCR_RESET | MII_BMCR_FD);
82eb1e7c3eSFabien Chouteau break;
83eb1e7c3eSFabien Chouteau default:
84eb1e7c3eSFabien Chouteau break;
85eb1e7c3eSFabien Chouteau };
86eb1e7c3eSFabien Chouteau }
87eb1e7c3eSFabien Chouteau
etsec_write_miim(eTSEC * etsec,eTSEC_Register * reg,uint32_t reg_index,uint32_t value)88eb1e7c3eSFabien Chouteau void etsec_write_miim(eTSEC *etsec,
89eb1e7c3eSFabien Chouteau eTSEC_Register *reg,
90eb1e7c3eSFabien Chouteau uint32_t reg_index,
91eb1e7c3eSFabien Chouteau uint32_t value)
92eb1e7c3eSFabien Chouteau {
93eb1e7c3eSFabien Chouteau
94eb1e7c3eSFabien Chouteau switch (reg_index) {
95eb1e7c3eSFabien Chouteau
96eb1e7c3eSFabien Chouteau case MIIMCOM:
97eb1e7c3eSFabien Chouteau /* Read and scan cycle */
98eb1e7c3eSFabien Chouteau
99eb1e7c3eSFabien Chouteau if ((!(reg->value & MIIMCOM_READ)) && (value & MIIMCOM_READ)) {
100eb1e7c3eSFabien Chouteau /* Read */
101eb1e7c3eSFabien Chouteau miim_read_cycle(etsec);
102eb1e7c3eSFabien Chouteau }
103eb1e7c3eSFabien Chouteau reg->value = value;
104eb1e7c3eSFabien Chouteau break;
105eb1e7c3eSFabien Chouteau
106eb1e7c3eSFabien Chouteau case MIIMCON:
107eb1e7c3eSFabien Chouteau reg->value = value & 0xffff;
108eb1e7c3eSFabien Chouteau miim_write_cycle(etsec);
109eb1e7c3eSFabien Chouteau break;
110eb1e7c3eSFabien Chouteau
111eb1e7c3eSFabien Chouteau default:
112eb1e7c3eSFabien Chouteau /* Default handling */
113eb1e7c3eSFabien Chouteau switch (reg->access) {
114eb1e7c3eSFabien Chouteau
115eb1e7c3eSFabien Chouteau case ACC_RW:
116eb1e7c3eSFabien Chouteau case ACC_WO:
117eb1e7c3eSFabien Chouteau reg->value = value;
118eb1e7c3eSFabien Chouteau break;
119eb1e7c3eSFabien Chouteau
120eb1e7c3eSFabien Chouteau case ACC_W1C:
121eb1e7c3eSFabien Chouteau reg->value &= ~value;
122eb1e7c3eSFabien Chouteau break;
123eb1e7c3eSFabien Chouteau
124eb1e7c3eSFabien Chouteau case ACC_RO:
125eb1e7c3eSFabien Chouteau default:
126eb1e7c3eSFabien Chouteau /* Read Only or Unknown register */
127eb1e7c3eSFabien Chouteau break;
128eb1e7c3eSFabien Chouteau }
129eb1e7c3eSFabien Chouteau }
130eb1e7c3eSFabien Chouteau
131eb1e7c3eSFabien Chouteau }
132eb1e7c3eSFabien Chouteau
etsec_miim_link_status(eTSEC * etsec,NetClientState * nc)133eb1e7c3eSFabien Chouteau void etsec_miim_link_status(eTSEC *etsec, NetClientState *nc)
134eb1e7c3eSFabien Chouteau {
135eb1e7c3eSFabien Chouteau /* Set link status */
136eb1e7c3eSFabien Chouteau if (nc->link_down) {
1376684bef1SAkihiko Odaki etsec->phy_status &= ~MII_BMSR_LINK_ST;
138eb1e7c3eSFabien Chouteau } else {
1396684bef1SAkihiko Odaki etsec->phy_status |= MII_BMSR_LINK_ST;
140eb1e7c3eSFabien Chouteau }
141eb1e7c3eSFabien Chouteau }
142