qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

miim.c (3818B)


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