/*
 * QEMU Freescale eTSEC Emulator
 *
 * Copyright (c) 2011-2013 AdaCore
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "etsec.h"
#include "registers.h"

/* #define DEBUG_MIIM */

#define MIIM_CONTROL    0
#define MIIM_STATUS     1
#define MIIM_PHY_ID_1   2
#define MIIM_PHY_ID_2   3
#define MIIM_T2_STATUS  10
#define MIIM_EXT_STATUS 15

static void miim_read_cycle(eTSEC *etsec)
{
    uint8_t  phy;
    uint8_t  addr;
    uint16_t value;

    phy  = (etsec->regs[MIIMADD].value >> 8) & 0x1F;
    (void)phy; /* Unreferenced */
    addr = etsec->regs[MIIMADD].value & 0x1F;

    switch (addr) {
    case MIIM_CONTROL:
        value = etsec->phy_control;
        break;
    case MIIM_STATUS:
        value = etsec->phy_status;
        break;
    case MIIM_T2_STATUS:
        value = 0x1800;           /* Local and remote receivers OK */
        break;
    default:
        value = 0x0;
        break;
    };

#ifdef DEBUG_MIIM
    qemu_log("%s phy:%d addr:0x%x value:0x%x\n", __func__, phy, addr, value);
#endif

    etsec->regs[MIIMSTAT].value = value;
}

static void miim_write_cycle(eTSEC *etsec)
{
    uint8_t  phy;
    uint8_t  addr;
    uint16_t value;

    phy   = (etsec->regs[MIIMADD].value >> 8) & 0x1F;
    (void)phy; /* Unreferenced */
    addr  = etsec->regs[MIIMADD].value & 0x1F;
    value = etsec->regs[MIIMCON].value & 0xffff;

#ifdef DEBUG_MIIM
    qemu_log("%s phy:%d addr:0x%x value:0x%x\n", __func__, phy, addr, value);
#endif

    switch (addr) {
    case MIIM_CONTROL:
        etsec->phy_control = value & ~(0x8100);
        break;
    default:
        break;
    };
}

void etsec_write_miim(eTSEC          *etsec,
                      eTSEC_Register *reg,
                      uint32_t        reg_index,
                      uint32_t        value)
{

    switch (reg_index) {

    case MIIMCOM:
        /* Read and scan cycle */

        if ((!(reg->value & MIIMCOM_READ)) && (value & MIIMCOM_READ)) {
            /* Read */
            miim_read_cycle(etsec);
        }
        reg->value = value;
        break;

    case MIIMCON:
        reg->value = value & 0xffff;
        miim_write_cycle(etsec);
        break;

    default:
        /* Default handling */
        switch (reg->access) {

        case ACC_RW:
        case ACC_WO:
            reg->value = value;
            break;

        case ACC_W1C:
            reg->value &= ~value;
            break;

        case ACC_RO:
        default:
            /* Read Only or Unknown register */
            break;
        }
    }

}

void etsec_miim_link_status(eTSEC *etsec, NetClientState *nc)
{
    /* Set link status */
    if (nc->link_down) {
        etsec->phy_status &= ~MII_SR_LINK_STATUS;
    } else {
        etsec->phy_status |= MII_SR_LINK_STATUS;
    }
}
