/*
 * Copyright (C) 2013 Realtek Semiconductor Corp.
 * All Rights Reserved.
 *
 * This program is the proprietary software of Realtek Semiconductor
 * Corporation and/or its licensors, and only be used, duplicated,
 * modified or distributed under the authorized license from Realtek.
 *
 * ANY USE OF THE SOFTWARE OTHER THAN AS AUTHORIZED UNDER
 * THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
 *
 * $Revision$
 * $Date$
 *
 * Purpose : RTK switch high-level API for RTL8367/RTL8367C
 * Feature : Here is a list of all functions and variables in Port module.
 *
 */

#include <rtk_switch.h>
#include <rtk_error.h>
#include <dal/rtl8367c/dal_rtl8367c_port.h>
#include <string.h>

#include <rtl8367c_asicdrv.h>
#include <rtl8367c_asicdrv_port.h>
#include <rtl8367c_asicdrv_misc.h>
#include <rtl8367c_asicdrv_portIsolation.h>

#define FIBER_INIT_SIZE 1817
CONST_T rtk_uint8 Fiber[FIBER_INIT_SIZE] = {
0x02,0x05,0x5C,0xE4,0xF5,0xA8,
0xD2,0xAF,0x22,0x00,0x00,0x02,0x06,0x87,
0xE4,0x90,0x06,0x2A,0xF0,0x90,0x06,0x2D,
0xF0,0xFD,0x7C,0x01,0x7F,0x3F,0x7E,0x1D,
0x12,0x06,0xE5,0x7D,0x40,0x12,0x03,0x55,
0x80,0x08,0x12,0x06,0x5B,0x50,0x08,0x12,
0x06,0x48,0x12,0x06,0x6C,0x80,0xF3,0xE4,
0xF5,0xA8,0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,
0x49,0x7E,0x13,0x12,0x06,0xE5,0x12,0x07,
0x0C,0x7D,0xFE,0x7C,0x00,0x7F,0xAA,0x7E,
0x12,0x12,0x06,0xE5,0x7D,0xD7,0x12,0x03,
0x20,0x7D,0x80,0x12,0x02,0xBC,0x7D,0x94,
0x7C,0xF9,0x12,0x03,0x4D,0x7D,0x81,0x12,
0x02,0xBC,0x7D,0xA2,0x7C,0x31,0x12,0x03,
0x4D,0x7D,0x82,0x12,0x02,0xD1,0x7D,0x60,
0x7C,0x69,0x12,0x03,0x63,0x7D,0x83,0x12,
0x02,0xD1,0x7D,0x28,0x7C,0x97,0x12,0x03,
0x63,0x7D,0x84,0x12,0x02,0xE6,0x7D,0x85,
0x7C,0x9D,0x12,0x03,0x7C,0x7D,0x23,0x12,
0x02,0xE6,0x7D,0x10,0x7C,0xD8,0x12,0x03,
0x7C,0x7D,0x24,0x7C,0x04,0x12,0x03,0x3A,
0x7D,0x00,0x12,0x03,0x20,0x7D,0x2F,0x12,
0x02,0xFB,0x7D,0x20,0x7C,0x0F,0x7F,0x02,
0x7E,0x66,0x12,0x06,0xE5,0x7D,0x01,0x12,
0x02,0xFB,0x7D,0x04,0x7C,0x00,0x7F,0x01,
0x7E,0x66,0x12,0x06,0xE5,0x7D,0x80,0x7C,
0x00,0x7F,0x00,0x7E,0x66,0x12,0x06,0xE5,
0x7F,0x02,0x7E,0x66,0x12,0x06,0xC1,0x12,
0x06,0x73,0x44,0x02,0xFF,0x12,0x06,0x73,
0x44,0x04,0x12,0x06,0x7C,0xFD,0x7F,0x02,
0x7E,0x66,0x12,0x06,0xE5,0x7D,0x04,0x7C,
0x00,0x12,0x03,0x3A,0x7D,0xB9,0x7C,0x15,
0x7F,0xEB,0x7E,0x13,0x12,0x06,0xE5,0x7D,
0x07,0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12,
0x06,0xE5,0x7D,0x40,0x7C,0x11,0x7F,0x00,
0x7E,0x62,0x12,0x06,0xE5,0x12,0x04,0x9D,
0x7D,0x41,0x12,0x03,0x55,0x80,0x08,0x12,
0x06,0x5B,0x50,0x08,0x12,0x06,0x48,0x12,
0x06,0x6C,0x80,0xF3,0xC2,0x00,0xC2,0x01,
0xD2,0xA9,0xD2,0x8C,0x12,0x03,0x2A,0xEE,
0x44,0x18,0x12,0x03,0x6B,0xE4,0xFF,0xFE,
0xFD,0x80,0x0C,0x7F,0xD0,0x7E,0x07,0x12,
0x06,0x5F,0x50,0x08,0x12,0x06,0x48,0x12,
0x06,0x6C,0x80,0xEF,0x7F,0x04,0x7E,0x62,
0x12,0x06,0xC1,0x12,0x06,0x73,0xEE,0x44,
0x01,0xFE,0xEF,0x44,0x80,0x12,0x06,0x7C,
0xFD,0x7F,0x04,0x7E,0x62,0x12,0x06,0xE5,
0xE4,0xFF,0xFE,0xFD,0x80,0x08,0x12,0x06,
0x5B,0x50,0x08,0x12,0x06,0x48,0x12,0x06,
0x6C,0x80,0xF3,0x12,0x03,0x2A,0xEE,0x54,
0xE7,0x12,0x03,0x6B,0x12,0x03,0x10,0x12,
0x03,0x10,0x30,0xE2,0x71,0x90,0x06,0x2D,
0xE0,0x64,0x01,0x70,0x62,0x7F,0xEA,0x7E,
0x13,0x12,0x06,0xC1,0x90,0x06,0x2B,0xEE,
0xF0,0xA3,0xEF,0xF0,0x54,0xEF,0xFF,0x90,
0x06,0x2B,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE,
0x44,0x10,0x90,0x06,0x2B,0xF0,0xFC,0xA3,
0xEF,0xF0,0xFD,0x7F,0x16,0x7E,0x13,0x12,
0x06,0xE5,0xE4,0xFF,0xFE,0xFD,0x80,0x0D,
0xE4,0x7F,0xFF,0x7E,0x6F,0x12,0x06,0x60,
0x50,0x08,0x12,0x06,0x48,0x12,0x06,0x6C,
0x80,0xEE,0x90,0x06,0x2B,0xE0,0x54,0xEF,
0xFE,0xA3,0xE0,0x90,0x06,0x2B,0x12,0x06,
0x7F,0xAD,0x07,0x7F,0x16,0x7E,0x13,0x12,
0x06,0xE5,0xE4,0x90,0x06,0x2D,0xF0,0xE4,
0x90,0x06,0x2A,0xF0,0x80,0x86,0x90,0x06,
0x2A,0xE0,0x70,0x13,0x12,0x02,0x47,0x90,
0x06,0x2A,0x74,0x01,0xF0,0xE4,0x90,0x06,
0x30,0xF0,0xA3,0xF0,0x02,0x01,0x92,0xC3,
0x90,0x06,0x31,0xE0,0x94,0x64,0x90,0x06,
0x30,0xE0,0x94,0x00,0x50,0x03,0x02,0x01,
0x92,0xE4,0xF0,0xA3,0xF0,0x12,0x02,0x47,
0x90,0x06,0x2A,0x74,0x01,0xF0,0x02,0x01,
0x92,0x7F,0x56,0x7E,0x13,0x12,0x06,0xC1,
0x90,0x06,0x2B,0xEE,0xF0,0xA3,0xEF,0xF0,
0x54,0xEF,0xFF,0x90,0x06,0x2B,0xEE,0xF0,
0xA3,0xEF,0xF0,0xEE,0x44,0x10,0x90,0x06,
0x2B,0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,0x7F,
0x16,0x7E,0x13,0x12,0x06,0xE5,0x90,0x06,
0x2D,0x74,0x01,0xF0,0x7D,0x04,0x7C,0x00,
0x7F,0x02,0x7E,0x66,0x12,0x06,0xE5,0x7D,
0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,
0x06,0xE5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,
0x7E,0x66,0x12,0x06,0xE5,0xE4,0xFD,0xFC,
0x7F,0x02,0x7E,0x66,0x12,0x06,0xE5,0x7D,
0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,
0x06,0xE5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,
0x7E,0x66,0x12,0x06,0xE5,0x22,0x7C,0x04,
0x7F,0x01,0x7E,0x66,0x12,0x06,0xE5,0x7D,
0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,
0x06,0xE5,0x22,0x7C,0x04,0x7F,0x01,0x7E,
0x66,0x12,0x06,0xE5,0x7D,0xC0,0x7C,0x00,
0x7F,0x00,0x7E,0x66,0x12,0x06,0xE5,0x22,
0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x06,
0xE5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,
0x66,0x12,0x06,0xE5,0x22,0x7C,0x00,0x7F,
0x01,0x7E,0x66,0x12,0x06,0xE5,0x7D,0xC0,
0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x06,
0xE5,0x22,0x7F,0x01,0x7E,0x62,0x12,0x06,
0xC1,0x90,0x06,0x28,0xEE,0xF0,0xA3,0xEF,
0xF0,0x22,0x7C,0x04,0x7F,0x02,0x7E,0x66,
0x12,0x06,0xE5,0x22,0x7F,0xE7,0x7E,0x13,
0x12,0x06,0xC1,0x90,0x06,0x28,0xEE,0xF0,
0xA3,0xEF,0xF0,0x22,0x7F,0x01,0x7E,0x66,
0x12,0x06,0xE5,0x7D,0xC0,0x7C,0x00,0x7F,
0x00,0x7E,0x66,0x12,0x06,0xE5,0x22,0x7F,
0x02,0x7E,0x66,0x12,0x06,0xE5,0x22,0x7C,
0x00,0x7F,0x36,0x7E,0x13,0x12,0x06,0xE5,
0xE4,0xFF,0xFE,0xFD,0x22,0x7F,0x02,0x7E,
0x66,0x12,0x06,0xE5,0x22,0x90,0x06,0x28,
0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,0x7F,0xE7,
0x7E,0x13,0x12,0x06,0xE5,0x22,0x7F,0x02,
0x7E,0x66,0x12,0x06,0xE5,0x22,0xC5,0xF0,
0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8,
0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83,
0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75,
0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE,
0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82,
0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99,
0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE,
0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC,
0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4,
0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22,
0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00,
0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD,
0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF,
0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD,
0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7,
0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F,
0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18,
0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,
0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10,
0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC,
0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0,
0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75,
0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE,
0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33,
0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8,
0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A,
0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA,
0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8,
0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E,
0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C,
0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD,
0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0,
0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3,
0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0,
0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x12,
0x05,0x13,0x12,0x05,0x35,0x44,0x40,0x12,
0x05,0x2A,0x7D,0x03,0x7C,0x00,0x12,0x05,
0x3E,0x12,0x06,0xE5,0x12,0x05,0x13,0x12,
0x05,0x35,0x54,0xBF,0x12,0x05,0x2A,0x7D,
0x03,0x7C,0x00,0x12,0x04,0xEB,0x7F,0x02,
0x7E,0x66,0x12,0x06,0xC1,0xEF,0x54,0xFD,
0x54,0xFE,0x12,0x05,0x4E,0x12,0x04,0xEB,
0x7F,0x02,0x7E,0x66,0x12,0x06,0xC1,0xEF,
0x44,0x02,0x44,0x01,0x12,0x05,0x4E,0x12,
0x05,0x3E,0x02,0x06,0xE5,0x7F,0x01,0x7E,
0x66,0x12,0x06,0xE5,0x7D,0xC0,0x7C,0x00,
0x7F,0x00,0x7E,0x66,0x12,0x06,0xE5,0xE4,
0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x06,
0xE5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E,
0x66,0x12,0x06,0xE5,0x22,0x7D,0x03,0x7C,
0x00,0x7F,0x01,0x7E,0x66,0x12,0x06,0xE5,
0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E,0x66,
0x12,0x06,0xE5,0x22,0xFD,0xAC,0x06,0x7F,
0x02,0x7E,0x66,0x12,0x06,0xE5,0x22,0x7F,
0x02,0x7E,0x66,0x12,0x06,0xC1,0xEF,0x22,
0x7F,0x01,0x7E,0x66,0x12,0x06,0xE5,0x7D,
0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x22,
0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,
0x06,0xE5,0xE4,0xFD,0xFC,0x22,0x78,0x7F,
0xE4,0xF6,0xD8,0xFD,0x75,0x81,0x3C,0x02,
0x05,0xA3,0x02,0x00,0x0E,0xE4,0x93,0xA3,
0xF8,0xE4,0x93,0xA3,0x40,0x03,0xF6,0x80,
0x01,0xF2,0x08,0xDF,0xF4,0x80,0x29,0xE4,
0x93,0xA3,0xF8,0x54,0x07,0x24,0x0C,0xC8,
0xC3,0x33,0xC4,0x54,0x0F,0x44,0x20,0xC8,
0x83,0x40,0x04,0xF4,0x56,0x80,0x01,0x46,
0xF6,0xDF,0xE4,0x80,0x0B,0x01,0x02,0x04,
0x08,0x10,0x20,0x40,0x80,0x90,0x07,0x01,
0xE4,0x7E,0x01,0x93,0x60,0xBC,0xA3,0xFF,
0x54,0x3F,0x30,0xE5,0x09,0x54,0x1F,0xFE,
0xE4,0x93,0xA3,0x60,0x01,0x0E,0xCF,0x54,
0xC0,0x25,0xE0,0x60,0xA8,0x40,0xB8,0xE4,
0x93,0xA3,0xFA,0xE4,0x93,0xA3,0xF8,0xE4,
0x93,0xA3,0xC8,0xC5,0x82,0xC8,0xCA,0xC5,
0x83,0xCA,0xF0,0xA3,0xC8,0xC5,0x82,0xC8,
0xCA,0xC5,0x83,0xCA,0xDF,0xE9,0xDE,0xE7,
0x80,0xBE,0x75,0x0F,0x80,0x75,0x0E,0x7E,
0x75,0x0D,0xAA,0x75,0x0C,0x83,0xE4,0xF5,
0x10,0x75,0x0B,0xA0,0x75,0x0A,0xAC,0x75,
0x09,0xB9,0x75,0x08,0x03,0x75,0x89,0x11,
0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF,0x0B,
0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12,0x03,
0xD6,0xAD,0x07,0xAC,0x06,0xC3,0xE4,0x9D,
0xFD,0xE4,0x9C,0xFC,0x78,0x17,0xF6,0xAF,
0x05,0xEF,0x08,0xF6,0x18,0xE6,0xF5,0x8C,
0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2D,0xFD,
0xE4,0x3C,0x18,0xF6,0xAF,0x05,0xEF,0x08,
0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7,0xD2,
0xA9,0x22,0x90,0x06,0x24,0x12,0x04,0x79,
0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4,
0x3D,0xFD,0xE4,0x3C,0x22,0x7F,0x20,0x7E,
0x4E,0xE4,0xFD,0xFC,0x90,0x06,0x24,0x12,
0x04,0x85,0xC3,0x02,0x04,0x68,0xFC,0x90,
0x06,0x24,0x02,0x04,0x91,0x90,0x06,0x28,
0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x90,0x06,
0x28,0xFF,0xEE,0xF0,0xFC,0xA3,0xEF,0xF0,
0x22,0xC0,0xE0,0xC0,0xF0,0xC0,0x83,0xC0,
0x82,0xC0,0xD0,0x75,0xD0,0x00,0xC0,0x00,
0x78,0x17,0xE6,0xF5,0x8C,0x78,0x18,0xE6,
0xF5,0x8A,0x90,0x06,0x2E,0xE4,0x75,0xF0,
0x01,0x12,0x03,0x84,0x90,0x06,0x30,0xE4,
0x75,0xF0,0x01,0x12,0x03,0x84,0xD0,0x00,
0xD0,0xD0,0xD0,0x82,0xD0,0x83,0xD0,0xF0,
0xD0,0xE0,0x32,0xC2,0xAF,0xAD,0x07,0xAC,
0x06,0x8C,0xA2,0x8D,0xA3,0x75,0xA0,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xAE,0xA1,0xBE,0x00,0xF0,
0xAE,0xA6,0xAF,0xA7,0xD2,0xAF,0x22,0xC2,
0xAF,0xAB,0x07,0xAA,0x06,0x8A,0xA2,0x8B,
0xA3,0x8C,0xA4,0x8D,0xA5,0x75,0xA0,0x03,
0x00,0x00,0x00,0xAA,0xA1,0xBA,0x00,0xF8,
0xD2,0xAF,0x22,0x42,0x06,0x30,0x00,0x00,
0x42,0x06,0x2E,0x00,0x00,0x00,0x12,0x07,
0x15,0x12,0x05,0xE8,0x02,0x00,0x03,0xE4,
0xF5,0x8E,0x22};

#define FIBER_AUTO_INIT_SIZE 1937
CONST_T rtk_uint8 Fiber_auto[FIBER_AUTO_INIT_SIZE] = {
0x02,0x05,0x7E,0xE4,0xF5,0xA8,
0xD2,0xAF,0x22,0x00,0x00,0x02,0x06,0xFF,
0xE4,0x90,0x06,0x2A,0xF0,0x90,0x06,0x2D,
0xF0,0xA3,0xF0,0xA3,0xF0,0xFD,0x7C,0x01,
0x7F,0x3F,0x7E,0x1D,0x12,0x07,0x5D,0x7D,
0x40,0x12,0x03,0x77,0x80,0x08,0x12,0x06,
0xD3,0x50,0x08,0x12,0x06,0xC0,0x12,0x06,
0xE4,0x80,0xF3,0xE4,0xF5,0xA8,0xD2,0xAF,
0x7D,0x1F,0xFC,0x7F,0x49,0x7E,0x13,0x12,
0x07,0x5D,0x12,0x07,0x84,0x7D,0xFE,0x7C,
0x00,0x7F,0xAA,0x7E,0x12,0x12,0x07,0x5D,
0x7D,0xD7,0x12,0x03,0x42,0x7D,0x80,0x12,
0x02,0xDE,0x7D,0x94,0x7C,0xF9,0x12,0x03,
0x6F,0x7D,0x81,0x12,0x02,0xDE,0x7D,0xA2,
0x7C,0x31,0x12,0x03,0x6F,0x7D,0x82,0x12,
0x02,0xF3,0x7D,0x60,0x7C,0x69,0x12,0x03,
0x85,0x7D,0x83,0x12,0x02,0xF3,0x7D,0x28,
0x7C,0x97,0x12,0x03,0x85,0x7D,0x84,0x12,
0x03,0x08,0x7D,0x85,0x7C,0x9D,0x12,0x03,
0x9E,0x7D,0x23,0x12,0x03,0x08,0x7D,0x10,
0x7C,0xD8,0x12,0x03,0x9E,0x7D,0x24,0x7C,
0x04,0x12,0x03,0x5C,0x7D,0x00,0x12,0x03,
0x42,0x7D,0x2F,0x12,0x03,0x1D,0x7D,0x20,
0x7C,0x0F,0x7F,0x02,0x7E,0x66,0x12,0x07,
0x5D,0x7D,0x01,0x12,0x03,0x1D,0x7D,0x04,
0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12,0x07,
0x5D,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E,
0x66,0x12,0x07,0x5D,0x7F,0x02,0x7E,0x66,
0x12,0x07,0x39,0x12,0x06,0xEB,0x44,0x02,
0xFF,0x12,0x06,0xEB,0x44,0x04,0x12,0x06,
0xF4,0xFD,0x7F,0x02,0x7E,0x66,0x12,0x07,
0x5D,0x7D,0x04,0x7C,0x00,0x12,0x03,0x5C,
0x7D,0xB8,0x7C,0x15,0x7F,0xEB,0x7E,0x13,
0x12,0x07,0x5D,0x7D,0x07,0x7C,0x00,0x7F,
0xE7,0x7E,0x13,0x12,0x07,0x5D,0x7D,0x40,
0x7C,0x11,0x7F,0x00,0x7E,0x62,0x12,0x07,
0x5D,0x12,0x04,0xBF,0x7D,0x41,0x12,0x03,
0x77,0x80,0x08,0x12,0x06,0xD3,0x50,0x08,
0x12,0x06,0xC0,0x12,0x06,0xE4,0x80,0xF3,
0xC2,0x00,0xC2,0x01,0xD2,0xA9,0xD2,0x8C,
0x12,0x03,0x4C,0xEE,0x44,0x18,0x12,0x03,
0x8D,0xE4,0xFF,0xFE,0xFD,0x80,0x0C,0x7F,
0xD0,0x7E,0x07,0x12,0x06,0xD7,0x50,0x08,
0x12,0x06,0xC0,0x12,0x06,0xE4,0x80,0xEF,
0x7F,0x04,0x7E,0x62,0x12,0x07,0x39,0x12,
0x06,0xEB,0xEE,0x44,0x01,0xFE,0xEF,0x44,
0x80,0x12,0x06,0xF4,0xFD,0x7F,0x04,0x7E,
0x62,0x12,0x07,0x5D,0xE4,0xFF,0xFE,0xFD,
0x80,0x08,0x12,0x06,0xD3,0x50,0x08,0x12,
0x06,0xC0,0x12,0x06,0xE4,0x80,0xF3,0x12,
0x03,0x4C,0xEE,0x54,0xE7,0x12,0x03,0x8D,
0x7D,0x80,0x7C,0x67,0x7F,0x40,0x7E,0x13,
0x12,0x07,0x5D,0x7F,0x43,0x7E,0x13,0x12,
0x07,0x39,0x90,0x06,0x2E,0xEE,0xF0,0xA3,
0xEF,0xF0,0x30,0xE3,0xE3,0x12,0x03,0x32,
0x12,0x03,0x32,0x30,0xE2,0x72,0x90,0x06,
0x2D,0xE0,0x64,0x01,0x70,0x62,0x7F,0xEA,
0x7E,0x13,0x12,0x07,0x39,0x90,0x06,0x2B,
0xEE,0xF0,0xA3,0xEF,0xF0,0x54,0xEF,0xFF,
0x90,0x06,0x2B,0xEE,0xF0,0xA3,0xEF,0xF0,
0xEE,0x44,0x10,0x90,0x06,0x2B,0xF0,0xFC,
0xA3,0xEF,0xF0,0xFD,0x7F,0x16,0x7E,0x13,
0x12,0x07,0x5D,0xE4,0xFF,0xFE,0xFD,0x80,
0x0D,0xE4,0x7F,0xFF,0x7E,0x6F,0x12,0x06,
0xD8,0x50,0x08,0x12,0x06,0xC0,0x12,0x06,
0xE4,0x80,0xEE,0x90,0x06,0x2B,0xE0,0x54,
0xEF,0xFE,0xA3,0xE0,0x90,0x06,0x2B,0x12,
0x06,0xF7,0xAD,0x07,0x7F,0x16,0x7E,0x13,
0x12,0x07,0x5D,0xE4,0x90,0x06,0x2D,0xF0,
0xE4,0x90,0x06,0x2A,0xF0,0x02,0x01,0x96,
0x90,0x06,0x2A,0xE0,0x70,0x13,0x12,0x02,
0x69,0x90,0x06,0x2A,0x74,0x01,0xF0,0xE4,
0x90,0x06,0x32,0xF0,0xA3,0xF0,0x02,0x01,
0x96,0xC3,0x90,0x06,0x33,0xE0,0x94,0x64,
0x90,0x06,0x32,0xE0,0x94,0x00,0x50,0x03,
0x02,0x01,0x96,0xE4,0xF0,0xA3,0xF0,0x12,
0x02,0x69,0x90,0x06,0x2A,0x74,0x01,0xF0,
0x02,0x01,0x96,0x7F,0x56,0x7E,0x13,0x12,
0x07,0x39,0x90,0x06,0x2B,0xEE,0xF0,0xA3,
0xEF,0xF0,0x54,0xEF,0xFF,0x90,0x06,0x2B,
0xEE,0xF0,0xA3,0xEF,0xF0,0xEE,0x44,0x10,
0x90,0x06,0x2B,0xF0,0xFC,0xA3,0xEF,0xF0,
0xFD,0x7F,0x16,0x7E,0x13,0x12,0x07,0x5D,
0x90,0x06,0x2D,0x74,0x01,0xF0,0x7D,0x04,
0x7C,0x00,0x7F,0x02,0x7E,0x66,0x12,0x07,
0x5D,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E,
0x66,0x12,0x07,0x5D,0x7D,0xC0,0x7C,0x00,
0x7F,0x00,0x7E,0x66,0x12,0x07,0x5D,0xE4,
0xFD,0xFC,0x7F,0x02,0x7E,0x66,0x12,0x07,
0x5D,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E,
0x66,0x12,0x07,0x5D,0x7D,0xC0,0x7C,0x00,
0x7F,0x00,0x7E,0x66,0x12,0x07,0x5D,0x22,
0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,
0x5D,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,
0x66,0x12,0x07,0x5D,0x22,0x7C,0x04,0x7F,
0x01,0x7E,0x66,0x12,0x07,0x5D,0x7D,0xC0,
0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,
0x5D,0x22,0x7C,0x04,0x7F,0x01,0x7E,0x66,
0x12,0x07,0x5D,0x7D,0xC0,0x7C,0x00,0x7F,
0x00,0x7E,0x66,0x12,0x07,0x5D,0x22,0x7C,
0x00,0x7F,0x01,0x7E,0x66,0x12,0x07,0x5D,
0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,
0x12,0x07,0x5D,0x22,0x7F,0x01,0x7E,0x62,
0x12,0x07,0x39,0x90,0x06,0x28,0xEE,0xF0,
0xA3,0xEF,0xF0,0x22,0x7C,0x04,0x7F,0x02,
0x7E,0x66,0x12,0x07,0x5D,0x22,0x7F,0xE7,
0x7E,0x13,0x12,0x07,0x39,0x90,0x06,0x28,
0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7F,0x01,
0x7E,0x66,0x12,0x07,0x5D,0x7D,0xC0,0x7C,
0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0x5D,
0x22,0x7F,0x02,0x7E,0x66,0x12,0x07,0x5D,
0x22,0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,
0x07,0x5D,0xE4,0xFF,0xFE,0xFD,0x22,0x7F,
0x02,0x7E,0x66,0x12,0x07,0x5D,0x22,0x90,
0x06,0x28,0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,
0x7F,0xE7,0x7E,0x13,0x12,0x07,0x5D,0x22,
0x7F,0x02,0x7E,0x66,0x12,0x07,0x5D,0x22,
0xC5,0xF0,0xF8,0xA3,0xE0,0x28,0xF0,0xC5,
0xF0,0xF8,0xE5,0x82,0x15,0x82,0x70,0x02,
0x15,0x83,0xE0,0x38,0xF0,0x22,0x75,0xF0,
0x08,0x75,0x82,0x00,0xEF,0x2F,0xFF,0xEE,
0x33,0xFE,0xCD,0x33,0xCD,0xCC,0x33,0xCC,
0xC5,0x82,0x33,0xC5,0x82,0x9B,0xED,0x9A,
0xEC,0x99,0xE5,0x82,0x98,0x40,0x0C,0xF5,
0x82,0xEE,0x9B,0xFE,0xED,0x9A,0xFD,0xEC,
0x99,0xFC,0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,
0xFB,0xE4,0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,
0x82,0x22,0xB8,0x00,0xC1,0xB9,0x00,0x59,
0xBA,0x00,0x2D,0xEC,0x8B,0xF0,0x84,0xCF,
0xCE,0xCD,0xFC,0xE5,0xF0,0xCB,0xF9,0x78,
0x18,0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,
0x33,0xFD,0xEC,0x33,0xFC,0xEB,0x33,0xFB,
0x10,0xD7,0x03,0x99,0x40,0x04,0xEB,0x99,
0xFB,0x0F,0xD8,0xE5,0xE4,0xF9,0xFA,0x22,
0x78,0x18,0xEF,0x2F,0xFF,0xEE,0x33,0xFE,
0xED,0x33,0xFD,0xEC,0x33,0xFC,0xC9,0x33,
0xC9,0x10,0xD7,0x05,0x9B,0xE9,0x9A,0x40,
0x07,0xEC,0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,
0xD8,0xE0,0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,
0x22,0x75,0xF0,0x10,0xEF,0x2F,0xFF,0xEE,
0x33,0xFE,0xED,0x33,0xFD,0xCC,0x33,0xCC,
0xC8,0x33,0xC8,0x10,0xD7,0x07,0x9B,0xEC,
0x9A,0xE8,0x99,0x40,0x0A,0xED,0x9B,0xFD,
0xEC,0x9A,0xFC,0xE8,0x99,0xF8,0x0F,0xD5,
0xF0,0xDA,0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,
0xE4,0xC8,0xF9,0x22,0xEB,0x9F,0xF5,0xF0,
0xEA,0x9E,0x42,0xF0,0xE9,0x9D,0x42,0xF0,
0xE8,0x9C,0x45,0xF0,0x22,0xE0,0xFC,0xA3,
0xE0,0xFD,0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,
0x22,0xE0,0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,
0xFA,0xA3,0xE0,0xFB,0x22,0xEC,0xF0,0xA3,
0xED,0xF0,0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,
0x22,0x12,0x05,0x35,0x12,0x05,0x57,0x44,
0x40,0x12,0x05,0x4C,0x7D,0x03,0x7C,0x00,
0x12,0x05,0x60,0x12,0x07,0x5D,0x12,0x05,
0x35,0x12,0x05,0x57,0x54,0xBF,0x12,0x05,
0x4C,0x7D,0x03,0x7C,0x00,0x12,0x05,0x0D,
0x7F,0x02,0x7E,0x66,0x12,0x07,0x39,0xEF,
0x54,0xFD,0x54,0xFE,0x12,0x05,0x70,0x12,
0x05,0x0D,0x7F,0x02,0x7E,0x66,0x12,0x07,
0x39,0xEF,0x44,0x02,0x44,0x01,0x12,0x05,
0x70,0x12,0x05,0x60,0x02,0x07,0x5D,0x7F,
0x01,0x7E,0x66,0x12,0x07,0x5D,0x7D,0xC0,
0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,
0x5D,0xE4,0xFD,0xFC,0x7F,0x01,0x7E,0x66,
0x12,0x07,0x5D,0x7D,0x80,0x7C,0x00,0x7F,
0x00,0x7E,0x66,0x12,0x07,0x5D,0x22,0x7D,
0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12,
0x07,0x5D,0x7D,0x80,0x7C,0x00,0x7F,0x00,
0x7E,0x66,0x12,0x07,0x5D,0x22,0xFD,0xAC,
0x06,0x7F,0x02,0x7E,0x66,0x12,0x07,0x5D,
0x22,0x7F,0x02,0x7E,0x66,0x12,0x07,0x39,
0xEF,0x22,0x7F,0x01,0x7E,0x66,0x12,0x07,
0x5D,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,
0x66,0x22,0xFD,0xAC,0x06,0x7F,0x02,0x7E,
0x66,0x12,0x07,0x5D,0xE4,0xFD,0xFC,0x22,
0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75,0x81,
0x3C,0x02,0x05,0xC5,0x02,0x00,0x0E,0xE4,
0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40,0x03,
0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4,0x80,
0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07,0x24,
0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F,0x44,
0x20,0xC8,0x83,0x40,0x04,0xF4,0x56,0x80,
0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B,0x01,
0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,
0x07,0x79,0xE4,0x7E,0x01,0x93,0x60,0xBC,
0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09,0x54,
0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01,0x0E,
0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8,0x40,
0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93,0xA3,
0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82,0xC8,
0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8,0xC5,
0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF,0xE9,
0xDE,0xE7,0x80,0xBE,0x75,0x0F,0x80,0x75,
0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C,0x83,
0xE4,0xF5,0x10,0x75,0x0B,0xA0,0x75,0x0A,
0xAC,0x75,0x09,0xB9,0x75,0x08,0x03,0x75,
0x89,0x11,0x7B,0x60,0x7A,0x09,0xF9,0xF8,
0xAF,0x0B,0xAE,0x0A,0xAD,0x09,0xAC,0x08,
0x12,0x03,0xF8,0xAD,0x07,0xAC,0x06,0xC3,
0xE4,0x9D,0xFD,0xE4,0x9C,0xFC,0x78,0x17,
0xF6,0xAF,0x05,0xEF,0x08,0xF6,0x18,0xE6,
0xF5,0x8C,0x08,0xE6,0xF5,0x8A,0x74,0x0D,
0x2D,0xFD,0xE4,0x3C,0x18,0xF6,0xAF,0x05,
0xEF,0x08,0xF6,0x75,0x88,0x10,0x53,0x8E,
0xC7,0xD2,0xA9,0x22,0x7D,0x69,0x7C,0x0A,
0x7F,0x15,0x7E,0x1D,0x12,0x07,0x5D,0x7F,
0x00,0x12,0x06,0x98,0x74,0x20,0xFF,0xFE,
0x12,0x06,0xB1,0x7F,0x40,0x12,0x06,0x98,
0x7F,0x60,0x7E,0x20,0x12,0x06,0xB1,0x7D,
0x40,0x7C,0x13,0x7F,0x80,0x7E,0x20,0x02,
0x07,0x5D,0x7D,0x40,0x7C,0x13,0x7E,0x20,
0x12,0x07,0x5D,0x7D,0x69,0x7C,0x0A,0x7F,
0x15,0x7E,0x1D,0x12,0x07,0x5D,0x7D,0x40,
0x7C,0x13,0x22,0x12,0x07,0x5D,0x7D,0x69,
0x7C,0x0A,0x7F,0x15,0x7E,0x1D,0x12,0x07,
0x5D,0x22,0x90,0x06,0x24,0x12,0x04,0x9B,
0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4,
0x3D,0xFD,0xE4,0x3C,0x22,0x7F,0x20,0x7E,
0x4E,0xE4,0xFD,0xFC,0x90,0x06,0x24,0x12,
0x04,0xA7,0xC3,0x02,0x04,0x8A,0xFC,0x90,
0x06,0x24,0x02,0x04,0xB3,0x90,0x06,0x28,
0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x90,0x06,
0x28,0xFF,0xEE,0xF0,0xFC,0xA3,0xEF,0xF0,
0x22,0xC0,0xE0,0xC0,0xF0,0xC0,0x83,0xC0,
0x82,0xC0,0xD0,0x75,0xD0,0x00,0xC0,0x00,
0x78,0x17,0xE6,0xF5,0x8C,0x78,0x18,0xE6,
0xF5,0x8A,0x90,0x06,0x30,0xE4,0x75,0xF0,
0x01,0x12,0x03,0xA6,0x90,0x06,0x32,0xE4,
0x75,0xF0,0x01,0x12,0x03,0xA6,0xD0,0x00,
0xD0,0xD0,0xD0,0x82,0xD0,0x83,0xD0,0xF0,
0xD0,0xE0,0x32,0xC2,0xAF,0xAD,0x07,0xAC,
0x06,0x8C,0xA2,0x8D,0xA3,0x75,0xA0,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xAE,0xA1,0xBE,0x00,0xF0,
0xAE,0xA6,0xAF,0xA7,0xD2,0xAF,0x22,0xC2,
0xAF,0xAB,0x07,0xAA,0x06,0x8A,0xA2,0x8B,
0xA3,0x8C,0xA4,0x8D,0xA5,0x75,0xA0,0x03,
0x00,0x00,0x00,0xAA,0xA1,0xBA,0x00,0xF8,
0xD2,0xAF,0x22,0x42,0x06,0x32,0x00,0x00,
0x42,0x06,0x30,0x00,0x00,0x00,0x12,0x07,
0x8D,0x12,0x06,0x0A,0x02,0x00,0x03,0xE4,
0xF5,0x8E,0x22};


static rtk_api_ret_t _dal_rtl8367c_port_FiberModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility)
{
    rtk_api_ret_t   retVal;
    rtk_uint32      regData;

    /* Check Combo port or not */
    RTK_CHK_PORT_IS_COMBO(port);

    /* Flow Control */
    if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_FIB0_CFG04, &regData)) != RT_ERR_OK)
        return retVal;

    if (pAbility->AsyFC == 1)
        regData |= (0x0001 << 8);
    else
        regData &= ~(0x0001 << 8);

    if (pAbility->FC == 1)
        regData |= (0x0001 << 7);
    else
        regData &= ~(0x0001 << 7);

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG04, regData)) != RT_ERR_OK)
        return retVal;

    /* Speed ability */
    if( (pAbility->Full_1000 == 1) && (pAbility->Full_100 == 1) && (pAbility->AutoNegotiation == 1) )
    {
        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 0)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 7)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x1140)) != RT_ERR_OK)
            return retVal;
    }
    else if(pAbility->Full_1000 == 1)
    {
        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 1)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 4)) != RT_ERR_OK)
            return retVal;

        if(pAbility->AutoNegotiation == 1)
        {
            if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x1140)) != RT_ERR_OK)
                return retVal;
        }
        else
        {
            if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x0140)) != RT_ERR_OK)
                return retVal;
        }
    }
    else if(pAbility->Full_100 == 1)
    {
        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 1)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 5)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x2100)) != RT_ERR_OK)
            return retVal;
    }

    /* Digital software reset */
    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, &regData)) != RT_ERR_OK)
        return retVal;

    regData |= (0x0001 << 6);

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, regData)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK)
        return retVal;

    regData &= ~(0x0001 << 6);

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, regData)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK)
        return retVal;

    /* CDR reset */
    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x1401))!=RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0000))!=RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0))!=RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x1403))!=RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0000))!=RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0))!=RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

static rtk_api_ret_t _dal_rtl8367c_port_FiberModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility)
{
    rtk_api_ret_t   retVal;
    rtk_uint32      data, regData;

    /* Check Combo port or not */
    RTK_CHK_PORT_IS_COMBO(port);

    memset(pAbility, 0x00, sizeof(rtk_port_phy_ability_t));

    /* Flow Control */
    if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_REG4_OFFSET, 1)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_REG4_FIB100_OFFSET, 0)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0044)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, &regData)) != RT_ERR_OK)
        return retVal;

    if(regData & (0x0001 << 8))
        pAbility->AsyFC = 1;

    if(regData & (0x0001 << 7))
        pAbility->FC = 1;

    /* Speed ability */
    if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, &data)) != RT_ERR_OK)
            return retVal;

    if(data == 0)
    {
        pAbility->AutoNegotiation = 1;
        pAbility->Full_1000 = 1;
        pAbility->Full_100 = 1;
    }
    else
    {
        if ((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, &data)) != RT_ERR_OK)
            return retVal;

        if(data == 4)
        {
            pAbility->Full_1000 = 1;

            if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_FIB0_CFG00, &data)) != RT_ERR_OK)
                return retVal;

            if(data & 0x1000)
                pAbility->AutoNegotiation = 1;
            else
                pAbility->AutoNegotiation = 0;
        }
        else if(data == 5)
            pAbility->Full_100 = 1;
        else
            return RT_ERR_FAILED;
    }

    return RT_ERR_OK;
}

static rtk_api_ret_t _dal_rtl8367c_port_phyComboPortMedia_get(rtk_port_t port, rtk_port_media_t *pMedia)
{
    rtk_api_ret_t   retVal;
    rtk_uint32      regData;
    rtk_uint32      data;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    /* Check Combo Port ID */
    RTK_CHK_PORT_IS_COMBO(port);

    if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK)
        return retVal;

    if((retVal = rtl8367c_getAsicReg(0x1300, &regData)) != RT_ERR_OK)
        return retVal;

    if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK)
        return retVal;

    if(regData != 0x6367)
    {
        *pMedia = PORT_MEDIA_COPPER;
    }
    else
    {
        if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIB_DISAUTODET_OFFSET, &data))!=RT_ERR_OK)
                return retVal;
        if(data == 0)
        {
            *pMedia = PORT_MEDIA_AUTO;
        }
        else
        {
            if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, &data))!=RT_ERR_OK)
                    return retVal;

            if(data == 1)
                *pMedia = PORT_MEDIA_COPPER;
            else
                *pMedia = PORT_MEDIA_FIBER;
        }
    }

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyAutoNegoAbility_set
 * Description:
 *      Set ethernet PHY auto-negotiation desired ability.
 * Input:
 *      port        - port id.
 *      pAbility    - Ability structure
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_ID          - Invalid port number.
 *      RT_ERR_PHY_REG_ID       - Invalid PHY address
 *      RT_ERR_INPUT            - Invalid input parameters.
 *      RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
 * Note:
 *      If Full_1000 bit is set to 1, the AutoNegotiation will be automatic set to 1. While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will
 *      be set as following 100F > 100H > 10F > 10H priority sequence.
 */
rtk_api_ret_t dal_rtl8367c_port_phyAutoNegoAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility)
{
    rtk_api_ret_t       retVal;
    rtk_uint32          phyData;
    rtk_uint32          phyEnMsk0;
    rtk_uint32          phyEnMsk4;
    rtk_uint32          phyEnMsk9;
    rtk_port_media_t    media_type;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if(NULL == pAbility)
        return RT_ERR_NULL_POINTER;

    if (pAbility->Half_10 >= RTK_ENABLE_END || pAbility->Full_10 >= RTK_ENABLE_END ||
       pAbility->Half_100 >= RTK_ENABLE_END || pAbility->Full_100 >= RTK_ENABLE_END ||
       pAbility->Full_1000 >= RTK_ENABLE_END || pAbility->AutoNegotiation >= RTK_ENABLE_END ||
       pAbility->AsyFC >= RTK_ENABLE_END || pAbility->FC >= RTK_ENABLE_END)
        return RT_ERR_INPUT;

    if (rtk_switch_isComboPort(port) == RT_ERR_OK)
    {
        if ((retVal = _dal_rtl8367c_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK)
            return retVal;

        if(media_type == PORT_MEDIA_FIBER)
        {
            return _dal_rtl8367c_port_FiberModeAbility_set(port, pAbility);
        }
    }

    /*for PHY auto mode setup*/
    pAbility->AutoNegotiation = 1;

    phyEnMsk0 = 0;
    phyEnMsk4 = 0;
    phyEnMsk9 = 0;

    if (1 == pAbility->Half_10)
    {
        /*10BASE-TX half duplex capable in reg 4.5*/
        phyEnMsk4 = phyEnMsk4 | (1 << 5);

        /*Speed selection [1:0] */
        /* 11=Reserved*/
        /* 10= 1000Mpbs*/
        /* 01= 100Mpbs*/
        /* 00= 10Mpbs*/
        phyEnMsk0 = phyEnMsk0 & (~(1 << 6));
        phyEnMsk0 = phyEnMsk0 & (~(1 << 13));
    }

    if (1 == pAbility->Full_10)
    {
        /*10BASE-TX full duplex capable in reg 4.6*/
        phyEnMsk4 = phyEnMsk4 | (1 << 6);
        /*Speed selection [1:0] */
        /* 11=Reserved*/
        /* 10= 1000Mpbs*/
        /* 01= 100Mpbs*/
        /* 00= 10Mpbs*/
        phyEnMsk0 = phyEnMsk0 & (~(1 << 6));
        phyEnMsk0 = phyEnMsk0 & (~(1 << 13));

        /*Full duplex mode in reg 0.8*/
        phyEnMsk0 = phyEnMsk0 | (1 << 8);

    }

    if (1 == pAbility->Half_100)
    {
        /*100BASE-TX half duplex capable in reg 4.7*/
        phyEnMsk4 = phyEnMsk4 | (1 << 7);
        /*Speed selection [1:0] */
        /* 11=Reserved*/
        /* 10= 1000Mpbs*/
        /* 01= 100Mpbs*/
        /* 00= 10Mpbs*/
        phyEnMsk0 = phyEnMsk0 & (~(1 << 6));
        phyEnMsk0 = phyEnMsk0 | (1 << 13);
    }


    if (1 == pAbility->Full_100)
    {
        /*100BASE-TX full duplex capable in reg 4.8*/
        phyEnMsk4 = phyEnMsk4 | (1 << 8);
        /*Speed selection [1:0] */
        /* 11=Reserved*/
        /* 10= 1000Mpbs*/
        /* 01= 100Mpbs*/
        /* 00= 10Mpbs*/
        phyEnMsk0 = phyEnMsk0 & (~(1 << 6));
        phyEnMsk0 = phyEnMsk0 | (1 << 13);
        /*Full duplex mode in reg 0.8*/
        phyEnMsk0 = phyEnMsk0 | (1 << 8);
    }


    if (1 == pAbility->Full_1000)
    {
        /*1000 BASE-T FULL duplex capable setting in reg 9.9*/
        phyEnMsk9 = phyEnMsk9 | (1 << 9);

        /*Speed selection [1:0] */
        /* 11=Reserved*/
        /* 10= 1000Mpbs*/
        /* 01= 100Mpbs*/
        /* 00= 10Mpbs*/
        phyEnMsk0 = phyEnMsk0 | (1 << 6);
        phyEnMsk0 = phyEnMsk0 & (~(1 << 13));


        /*Auto-Negotiation setting in reg 0.12*/
        phyEnMsk0 = phyEnMsk0 | (1 << 12);

     }

    if (1 == pAbility->AutoNegotiation)
    {
        /*Auto-Negotiation setting in reg 0.12*/
        phyEnMsk0 = phyEnMsk0 | (1 << 12);
    }

    if (1 == pAbility->AsyFC)
    {
        /*Asymetric flow control in reg 4.11*/
        phyEnMsk4 = phyEnMsk4 | (1 << 11);
    }
    if (1 == pAbility->FC)
    {
        /*Flow control in reg 4.10*/
        phyEnMsk4 = phyEnMsk4 | (1 << 10);
    }

    /*1000 BASE-T control register setting*/
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData)) != RT_ERR_OK)
        return retVal;

    phyData = (phyData & (~0x0200)) | phyEnMsk9 ;

    if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, phyData)) != RT_ERR_OK)
        return retVal;

    /*Auto-Negotiation control register setting*/
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData)) != RT_ERR_OK)
        return retVal;

    phyData = (phyData & (~0x0DE0)) | phyEnMsk4;
    if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, phyData)) != RT_ERR_OK)
        return retVal;

    /*Control register setting and restart auto*/
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData)) != RT_ERR_OK)
        return retVal;

    phyData = (phyData & (~0x3140)) | phyEnMsk0;
    /*If have auto-negotiation capable, then restart auto negotiation*/
    if (1 == pAbility->AutoNegotiation)
    {
        phyData = phyData | (1 << 9);
    }

    if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyAutoNegoAbility_get
 * Description:
 *      Get PHY ability through PHY registers.
 * Input:
 *      port - Port id.
 * Output:
 *      pAbility - Ability structure
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_ID          - Invalid port number.
 *      RT_ERR_PHY_REG_ID       - Invalid PHY address
 *      RT_ERR_INPUT            - Invalid input parameters.
 *      RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
 * Note:
 *      Get the capablity of specified PHY.
 */
rtk_api_ret_t dal_rtl8367c_port_phyAutoNegoAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility)
{
    rtk_api_ret_t       retVal;
    rtk_uint32          phyData0;
    rtk_uint32          phyData4;
    rtk_uint32          phyData9;
    rtk_port_media_t    media_type;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if(NULL == pAbility)
        return RT_ERR_NULL_POINTER;

    if (rtk_switch_isComboPort(port) == RT_ERR_OK)
    {
        if ((retVal = _dal_rtl8367c_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK)
            return retVal;

        if(media_type == PORT_MEDIA_FIBER)
        {
            return _dal_rtl8367c_port_FiberModeAbility_get(port, pAbility);
        }
    }

    /*Control register setting and restart auto*/
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData0)) != RT_ERR_OK)
        return retVal;

    /*Auto-Negotiation control register setting*/
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData4)) != RT_ERR_OK)
        return retVal;

    /*1000 BASE-T control register setting*/
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData9)) != RT_ERR_OK)
        return retVal;

    if (phyData9 & (1 << 9))
        pAbility->Full_1000 = 1;
    else
        pAbility->Full_1000 = 0;

    if (phyData4 & (1 << 11))
        pAbility->AsyFC = 1;
    else
        pAbility->AsyFC = 0;

    if (phyData4 & (1 << 10))
        pAbility->FC = 1;
    else
        pAbility->FC = 0;


    if (phyData4 & (1 << 8))
        pAbility->Full_100 = 1;
    else
        pAbility->Full_100 = 0;

    if (phyData4 & (1 << 7))
        pAbility->Half_100 = 1;
    else
        pAbility->Half_100 = 0;

    if (phyData4 & (1 << 6))
        pAbility->Full_10 = 1;
    else
        pAbility->Full_10 = 0;

    if (phyData4 & (1 << 5))
        pAbility->Half_10 = 1;
    else
        pAbility->Half_10 = 0;


    if (phyData0 & (1 << 12))
        pAbility->AutoNegotiation = 1;
    else
        pAbility->AutoNegotiation = 0;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyForceModeAbility_set
 * Description:
 *      Set the port speed/duplex mode/pause/asy_pause in the PHY force mode.
 * Input:
 *      port        - port id.
 *      pAbility    - Ability structure
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_ID          - Invalid port number.
 *      RT_ERR_PHY_REG_ID       - Invalid PHY address
 *      RT_ERR_INPUT            - Invalid input parameters.
 *      RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
 * Note:
 *      While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will
 *      be set as following 100F > 100H > 10F > 10H priority sequence.
 *      This API can be used to configure combo port in fiber mode.
 *      The possible parameters in fiber mode are Full_1000 and Full 100.
 *      All the other fields in rtk_port_phy_ability_t will be ignored in fiber port.
 */
rtk_api_ret_t dal_rtl8367c_port_phyForceModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility)
{
     rtk_api_ret_t      retVal;
     rtk_uint32         phyData;
     rtk_uint32         phyEnMsk0;
     rtk_uint32         phyEnMsk4;
     rtk_uint32         phyEnMsk9;
     rtk_port_media_t   media_type;

     /* Check initialization state */
     RTK_CHK_INIT_STATE();

     /* Check Port Valid */
     RTK_CHK_PORT_IS_UTP(port);

     if(NULL == pAbility)
        return RT_ERR_NULL_POINTER;

     if (pAbility->Half_10 >= RTK_ENABLE_END || pAbility->Full_10 >= RTK_ENABLE_END ||
        pAbility->Half_100 >= RTK_ENABLE_END || pAbility->Full_100 >= RTK_ENABLE_END ||
        pAbility->Full_1000 >= RTK_ENABLE_END || pAbility->AutoNegotiation >= RTK_ENABLE_END ||
        pAbility->AsyFC >= RTK_ENABLE_END || pAbility->FC >= RTK_ENABLE_END)
         return RT_ERR_INPUT;

     if (rtk_switch_isComboPort(port) == RT_ERR_OK)
     {
         if ((retVal = _dal_rtl8367c_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK)
             return retVal;

         if(media_type == PORT_MEDIA_FIBER)
         {
             return _dal_rtl8367c_port_FiberModeAbility_set(port, pAbility);
         }
     }

     if (1 == pAbility->Full_1000)
         return RT_ERR_INPUT;

     /*for PHY force mode setup*/
     pAbility->AutoNegotiation = 0;

     phyEnMsk0 = 0;
     phyEnMsk4 = 0;
     phyEnMsk9 = 0;

     if (1 == pAbility->Half_10)
     {
         /*10BASE-TX half duplex capable in reg 4.5*/
         phyEnMsk4 = phyEnMsk4 | (1 << 5);

         /*Speed selection [1:0] */
         /* 11=Reserved*/
         /* 10= 1000Mpbs*/
         /* 01= 100Mpbs*/
         /* 00= 10Mpbs*/
         phyEnMsk0 = phyEnMsk0 & (~(1 << 6));
         phyEnMsk0 = phyEnMsk0 & (~(1 << 13));
     }

     if (1 == pAbility->Full_10)
     {
         /*10BASE-TX full duplex capable in reg 4.6*/
         phyEnMsk4 = phyEnMsk4 | (1 << 6);
         /*Speed selection [1:0] */
         /* 11=Reserved*/
         /* 10= 1000Mpbs*/
         /* 01= 100Mpbs*/
         /* 00= 10Mpbs*/
         phyEnMsk0 = phyEnMsk0 & (~(1 << 6));
         phyEnMsk0 = phyEnMsk0 & (~(1 << 13));

         /*Full duplex mode in reg 0.8*/
         phyEnMsk0 = phyEnMsk0 | (1 << 8);

     }

     if (1 == pAbility->Half_100)
     {
         /*100BASE-TX half duplex capable in reg 4.7*/
         phyEnMsk4 = phyEnMsk4 | (1 << 7);
         /*Speed selection [1:0] */
         /* 11=Reserved*/
         /* 10= 1000Mpbs*/
         /* 01= 100Mpbs*/
         /* 00= 10Mpbs*/
         phyEnMsk0 = phyEnMsk0 & (~(1 << 6));
         phyEnMsk0 = phyEnMsk0 | (1 << 13);
     }


     if (1 == pAbility->Full_100)
     {
         /*100BASE-TX full duplex capable in reg 4.8*/
         phyEnMsk4 = phyEnMsk4 | (1 << 8);
         /*Speed selection [1:0] */
         /* 11=Reserved*/
         /* 10= 1000Mpbs*/
         /* 01= 100Mpbs*/
         /* 00= 10Mpbs*/
         phyEnMsk0 = phyEnMsk0 & (~(1 << 6));
         phyEnMsk0 = phyEnMsk0 | (1 << 13);
         /*Full duplex mode in reg 0.8*/
         phyEnMsk0 = phyEnMsk0 | (1 << 8);
     }

     if (1 == pAbility->AsyFC)
     {
         /*Asymetric flow control in reg 4.11*/
         phyEnMsk4 = phyEnMsk4 | (1 << 11);
     }
     if (1 == pAbility->FC)
     {
         /*Flow control in reg 4.10*/
         phyEnMsk4 = phyEnMsk4 | ((1 << 10));
     }

     /*1000 BASE-T control register setting*/
     if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData)) != RT_ERR_OK)
         return retVal;

     phyData = (phyData & (~0x0200)) | phyEnMsk9 ;

     if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, phyData)) != RT_ERR_OK)
         return retVal;

     /*Auto-Negotiation control register setting*/
     if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData)) != RT_ERR_OK)
         return retVal;

     phyData = (phyData & (~0x0DE0)) | phyEnMsk4;
     if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, phyData)) != RT_ERR_OK)
         return retVal;

     /*Control register setting and power off/on*/
     phyData = phyEnMsk0 & (~(1 << 12));
     phyData |= (1 << 11);   /* power down PHY, bit 11 should be set to 1 */
     if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK)
         return retVal;

     phyData = phyData & (~(1 << 11));   /* power on PHY, bit 11 should be set to 0*/
     if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK)
         return retVal;

     return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyForceModeAbility_get
 * Description:
 *      Get PHY ability through PHY registers.
 * Input:
 *      port - Port id.
 * Output:
 *      pAbility - Ability structure
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_ID          - Invalid port number.
 *      RT_ERR_PHY_REG_ID       - Invalid PHY address
 *      RT_ERR_INPUT            - Invalid input parameters.
 *      RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
 * Note:
 *      Get the capablity of specified PHY.
 */
rtk_api_ret_t dal_rtl8367c_port_phyForceModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility)
{
    rtk_api_ret_t       retVal;
    rtk_uint32          phyData0;
    rtk_uint32          phyData4;
    rtk_uint32          phyData9;
    rtk_port_media_t    media_type;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
     RTK_CHK_PORT_IS_UTP(port);

     if(NULL == pAbility)
        return RT_ERR_NULL_POINTER;

     if (rtk_switch_isComboPort(port) == RT_ERR_OK)
     {
         if ((retVal = _dal_rtl8367c_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK)
             return retVal;

         if(media_type == PORT_MEDIA_FIBER)
         {
             return _dal_rtl8367c_port_FiberModeAbility_get(port, pAbility);
         }
     }

    /*Control register setting and restart auto*/
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData0)) != RT_ERR_OK)
        return retVal;

    /*Auto-Negotiation control register setting*/
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData4)) != RT_ERR_OK)
        return retVal;

    /*1000 BASE-T control register setting*/
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData9)) != RT_ERR_OK)
        return retVal;

    if (phyData9 & (1 << 9))
        pAbility->Full_1000 = 1;
    else
        pAbility->Full_1000 = 0;

    if (phyData4 & (1 << 11))
        pAbility->AsyFC = 1;
    else
        pAbility->AsyFC = 0;

    if (phyData4 & ((1 << 10)))
        pAbility->FC = 1;
    else
        pAbility->FC = 0;


    if (phyData4 & (1 << 8))
        pAbility->Full_100 = 1;
    else
        pAbility->Full_100 = 0;

    if (phyData4 & (1 << 7))
        pAbility->Half_100 = 1;
    else
        pAbility->Half_100 = 0;

    if (phyData4 & (1 << 6))
        pAbility->Full_10 = 1;
    else
        pAbility->Full_10 = 0;

    if (phyData4 & (1 << 5))
        pAbility->Half_10 = 1;
    else
        pAbility->Half_10 = 0;


    if (phyData0 & (1 << 12))
        pAbility->AutoNegotiation = 1;
    else
        pAbility->AutoNegotiation = 0;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyStatus_get
 * Description:
 *      Get ethernet PHY linking status
 * Input:
 *      port - Port id.
 * Output:
 *      linkStatus  - PHY link status
 *      speed       - PHY link speed
 *      duplex      - PHY duplex mode
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_ID          - Invalid port number.
 *      RT_ERR_PHY_REG_ID       - Invalid PHY address
 *      RT_ERR_INPUT            - Invalid input parameters.
 *      RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
 * Note:
 *      API will return auto negotiation status of phy.
 */
rtk_api_ret_t dal_rtl8367c_port_phyStatus_get(rtk_port_t port, rtk_port_linkStatus_t *pLinkStatus, rtk_port_speed_t *pSpeed, rtk_port_duplex_t *pDuplex)
{
    rtk_api_ret_t retVal;
    rtk_uint32 phyData;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if( (NULL == pLinkStatus) || (NULL == pSpeed) || (NULL == pDuplex) )
        return RT_ERR_NULL_POINTER;

    /*Get PHY resolved register*/
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_RESOLVED_REG, &phyData)) != RT_ERR_OK)
        return retVal;

    /*check link status*/
    if (phyData & (1<<2))
    {
        *pLinkStatus = 1;

        /*check link speed*/
        *pSpeed = (phyData&0x0030) >> 4;

        /*check link duplex*/
        *pDuplex = (phyData&0x0008) >> 3;
    }
    else
    {
        *pLinkStatus = 0;
        *pSpeed = 0;
        *pDuplex = 0;
    }

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_macForceLink_set
 * Description:
 *      Set port force linking configuration.
 * Input:
 *      port            - port id.
 *      pPortability    - port ability configuration
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 * Note:
 *      This API can set Port/MAC force mode properties.
 */
rtk_api_ret_t dal_rtl8367c_port_macForceLink_set(rtk_port_t port, rtk_port_mac_ability_t *pPortability)
{
    rtk_api_ret_t retVal;
    rtl8367c_port_ability_t ability;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if(NULL == pPortability)
        return RT_ERR_NULL_POINTER;

    if (pPortability->forcemode >1|| pPortability->speed > 2 || pPortability->duplex > 1 ||
       pPortability->link > 1 || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1)
        return RT_ERR_INPUT;

    if ((retVal = rtl8367c_getAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK)
        return retVal;

    ability.forcemode = pPortability->forcemode;
    ability.speed     = pPortability->speed;
    ability.duplex    = pPortability->duplex;
    ability.link      = pPortability->link;
    ability.nway      = pPortability->nway;
    ability.txpause   = pPortability->txpause;
    ability.rxpause   = pPortability->rxpause;

    if ((retVal = rtl8367c_setAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_macForceLink_get
 * Description:
 *      Get port force linking configuration.
 * Input:
 *      port - Port id.
 * Output:
 *      pPortability - port ability configuration
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 *      RT_ERR_INPUT        - Invalid input parameters.
 * Note:
 *      This API can get Port/MAC force mode properties.
 */
rtk_api_ret_t dal_rtl8367c_port_macForceLink_get(rtk_port_t port, rtk_port_mac_ability_t *pPortability)
{
    rtk_api_ret_t retVal;
    rtl8367c_port_ability_t ability;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if(NULL == pPortability)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK)
        return retVal;

    pPortability->forcemode = ability.forcemode;
    pPortability->speed     = ability.speed;
    pPortability->duplex    = ability.duplex;
    pPortability->link      = ability.link;
    pPortability->nway      = ability.nway;
    pPortability->txpause   = ability.txpause;
    pPortability->rxpause   = ability.rxpause;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_macForceLinkExt_set
 * Description:
 *      Set external interface force linking configuration.
 * Input:
 *      port            - external port ID
 *      mode            - external interface mode
 *      pPortability    - port ability configuration
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_INPUT        - Invalid input parameters.
 * Note:
 *      This API can set external interface force mode properties.
 *      The external interface can be set to:
 *      - MODE_EXT_DISABLE,
 *      - MODE_EXT_RGMII,
 *      - MODE_EXT_MII_MAC,
 *      - MODE_EXT_MII_PHY,
 *      - MODE_EXT_TMII_MAC,
 *      - MODE_EXT_TMII_PHY,
 *      - MODE_EXT_GMII,
 *      - MODE_EXT_RMII_MAC,
 *      - MODE_EXT_RMII_PHY,
 *      - MODE_EXT_SGMII,
 *      - MODE_EXT_HSGMII,
 *      - MODE_EXT_1000X_100FX,
 *      - MODE_EXT_1000X,
 *      - MODE_EXT_100FX,
 */
rtk_api_ret_t dal_rtl8367c_port_macForceLinkExt_set(rtk_port_t port, rtk_mode_ext_t mode, rtk_port_mac_ability_t *pPortability)
{
    rtk_api_ret_t retVal;
    rtl8367c_port_ability_t ability;
    rtk_uint32 ext_id;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_EXT(port);

    if(NULL == pPortability)
        return RT_ERR_NULL_POINTER;

    if (mode >= MODE_EXT_END)
        return RT_ERR_INPUT;

    if (mode == MODE_EXT_FIBER_2P5G)
        return RT_ERR_CHIP_NOT_SUPPORTED;

    if(mode == MODE_EXT_HSGMII)
    {
        if (pPortability->forcemode > 1 || pPortability->speed != PORT_SPEED_2500M || pPortability->duplex != PORT_FULL_DUPLEX ||
           pPortability->link >= PORT_LINKSTATUS_END || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1)
            return RT_ERR_INPUT;

        if(rtk_switch_isHsgPort(port) != RT_ERR_OK)
            return RT_ERR_PORT_ID;
    }
    else if (mode != MODE_EXT_DISABLE)
    {
        if (pPortability->forcemode > 1 || pPortability->speed > PORT_SPEED_1000M || pPortability->duplex >= PORT_DUPLEX_END ||
           pPortability->link >= PORT_LINKSTATUS_END || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1)
            return RT_ERR_INPUT;
    }

    ext_id = port - 15;

    if(mode == MODE_EXT_DISABLE)
    {
        memset(&ability, 0x00, sizeof(rtl8367c_port_ability_t));
        if ((retVal = rtl8367c_setAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicPortExtMode(ext_id, mode)) != RT_ERR_OK)
            return retVal;
    }
    else
    {
        if ((retVal = rtl8367c_setAsicPortExtMode(ext_id, mode)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_getAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK)
            return retVal;

        ability.forcemode = pPortability->forcemode;
        ability.speed     = (mode == MODE_EXT_HSGMII) ? PORT_SPEED_1000M : pPortability->speed;
        ability.duplex    = pPortability->duplex;
        ability.link      = pPortability->link;
        ability.nway      = pPortability->nway;
        ability.txpause   = pPortability->txpause;
        ability.rxpause   = pPortability->rxpause;

        if ((retVal = rtl8367c_setAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK)
            return retVal;
    }

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_macForceLinkExt_get
 * Description:
 *      Set external interface force linking configuration.
 * Input:
 *      port            - external port ID
 * Output:
 *      pMode           - external interface mode
 *      pPortability    - port ability configuration
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_INPUT        - Invalid input parameters.
 * Note:
 *      This API can get external interface force mode properties.
 */
rtk_api_ret_t dal_rtl8367c_port_macForceLinkExt_get(rtk_port_t port, rtk_mode_ext_t *pMode, rtk_port_mac_ability_t *pPortability)
{
    rtk_api_ret_t retVal;
    rtl8367c_port_ability_t ability;
    rtk_uint32 ext_id;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_EXT(port);

    if(NULL == pMode)
        return RT_ERR_NULL_POINTER;

    if(NULL == pPortability)
        return RT_ERR_NULL_POINTER;

    ext_id = port - 15;

    if ((retVal = rtl8367c_getAsicPortExtMode(ext_id, (rtk_uint32 *)pMode)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_getAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK)
        return retVal;

    pPortability->forcemode = ability.forcemode;
    pPortability->speed     = (*pMode == MODE_EXT_HSGMII) ? PORT_SPEED_2500M : ability.speed;
    pPortability->duplex    = ability.duplex;
    pPortability->link      = ability.link;
    pPortability->nway      = ability.nway;
    pPortability->txpause   = ability.txpause;
    pPortability->rxpause   = ability.rxpause;

    return RT_ERR_OK;

}

/* Function Name:
 *      dal_rtl8367c_port_macStatus_get
 * Description:
 *      Get port link status.
 * Input:
 *      port - Port id.
 * Output:
 *      pPortstatus - port ability configuration
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 * Note:
 *      This API can get Port/PHY properties.
 */
rtk_api_ret_t dal_rtl8367c_port_macStatus_get(rtk_port_t port, rtk_port_mac_ability_t *pPortstatus)
{
    rtk_api_ret_t retVal;
    rtl8367c_port_status_t status;
    rtk_uint32 hsgsel;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_VALID(port);

    if(NULL == pPortstatus)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicPortStatus(rtk_switch_port_L2P_get(port), &status)) != RT_ERR_OK)
        return retVal;


    pPortstatus->duplex    = status.duplex;
    pPortstatus->link      = status.link;
    pPortstatus->nway      = status.nway;
    pPortstatus->txpause   = status.txpause;
    pPortstatus->rxpause   = status.rxpause;

    if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, &hsgsel)) != RT_ERR_OK)
            return retVal;

    if( (rtk_switch_isHsgPort(port) == RT_ERR_OK) && (hsgsel == 1) )
        pPortstatus->speed = PORT_SPEED_2500M;
    else
        pPortstatus->speed = status.speed;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_macLocalLoopbackEnable_set
 * Description:
 *      Set Port Local Loopback. (Redirect TX to RX.)
 * Input:
 *      port    - Port id.
 *      enable  - Loopback state, 0:disable, 1:enable
 * Output:
 *      None.
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 * Note:
 *      This API can enable/disable Local loopback in MAC.
 *      For UTP port, This API will also enable the digital
 *      loopback bit in PHY register for sync of speed between
 *      PHY and MAC. For EXT port, users need to force the
 *      link state by themself.
 */
rtk_api_ret_t dal_rtl8367c_port_macLocalLoopbackEnable_set(rtk_port_t port, rtk_enable_t enable)
{
    rtk_api_ret_t   retVal;
    rtk_uint32      data;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_VALID(port);

    if(enable >= RTK_ENABLE_END)
        return RT_ERR_INPUT;

    if ((retVal = rtl8367c_setAsicPortLoopback(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK)
        return retVal;

    if(rtk_switch_isUtpPort(port) == RT_ERR_OK)
    {
        if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &data)) != RT_ERR_OK)
            return retVal;

        if(enable == ENABLED)
            data |= (0x0001 << 14);
        else
            data &= ~(0x0001 << 14);

        if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, data)) != RT_ERR_OK)
            return retVal;
    }

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_macLocalLoopbackEnable_get
 * Description:
 *      Get Port Local Loopback. (Redirect TX to RX.)
 * Input:
 *      port    - Port id.
 * Output:
 *      pEnable  - Loopback state, 0:disable, 1:enable
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 * Note:
 *      None.
 */
rtk_api_ret_t dal_rtl8367c_port_macLocalLoopbackEnable_get(rtk_port_t port, rtk_enable_t *pEnable)
{
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_VALID(port);

    if(NULL == pEnable)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicPortLoopback(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyReg_set
 * Description:
 *      Set PHY register data of the specific port.
 * Input:
 *      port    - port id.
 *      reg     - Register id
 *      regData - Register data
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_ID          - Invalid port number.
 *      RT_ERR_PHY_REG_ID       - Invalid PHY address
 *      RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
 * Note:
 *      This API can set PHY register data of the specific port.
 */
rtk_api_ret_t dal_rtl8367c_port_phyReg_set(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t regData)
{
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), reg, regData)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyReg_get
 * Description:
 *      Get PHY register data of the specific port.
 * Input:
 *      port    - Port id.
 *      reg     - Register id
 * Output:
 *      pData   - Register data
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_ID          - Invalid port number.
 *      RT_ERR_PHY_REG_ID       - Invalid PHY address
 *      RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
 * Note:
 *      This API can get PHY register data of the specific port.
 */
rtk_api_ret_t dal_rtl8367c_port_phyReg_get(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t *pData)
{
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), reg, pData)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyOCPReg_set
 * Description:
 *      Set PHY OCP register
 * Input:
 *      port        - PHY ID
 *      ocpAddr     - OCP register address
 *      ocpData     - OCP Data.
 * Output:
 *      None.
 * Return:
 *      RT_ERR_OK                               - OK
 *      RT_ERR_FAILED                           - Failed
 *      RT_ERR_BUSYWAIT_TIMEOUT                 - Timeout
 * Note:
 *      None.
 */
rtk_api_ret_t dal_rtl8367c_port_phyOCPReg_set(rtk_port_t port, rtk_uint32 ocpAddr, rtk_uint32 ocpData )
{
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), ocpAddr, ocpData)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyOCPReg_get
 * Description:
 *      Set PHY OCP register
 * Input:
 *      phyNo       - PHY ID
 *      ocpAddr     - OCP register address
 * Output:
 *      pRegData    - OCP data.
 * Return:
 *      RT_ERR_OK                               - OK
 *      RT_ERR_FAILED                           - Failed
 *      RT_ERR_NULL_POINTER                     - Null pointer
 * Note:
 *      None.
 */
rtk_api_ret_t dal_rtl8367c_port_phyOCPReg_get(rtk_port_t port, rtk_uint32 ocpAddr, rtk_uint32 *pRegData )
{
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if (pRegData == NULL)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicPHYOCPReg(rtk_switch_port_L2P_get(port), ocpAddr, pRegData)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_backpressureEnable_set
 * Description:
 *      Set the half duplex backpressure enable status of the specific port.
 * Input:
 *      port    - port id.
 *      enable  - Back pressure status.
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 *      RT_ERR_ENABLE       - Invalid enable input.
 * Note:
 *      This API can set the half duplex backpressure enable status of the specific port.
 *      The half duplex backpressure enable status of the port is as following:
 *      - DISABLE(Defer)
 *      - ENABLE (Backpressure)
 */
rtk_api_ret_t dal_rtl8367c_port_backpressureEnable_set(rtk_port_t port, rtk_enable_t enable)
{
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    if (port != RTK_WHOLE_SYSTEM)
        return RT_ERR_PORT_ID;

    if (enable >= RTK_ENABLE_END)
        return RT_ERR_INPUT;

    if ((retVal = rtl8367c_setAsicPortJamMode(!enable)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_backpressureEnable_get
 * Description:
 *      Get the half duplex backpressure enable status of the specific port.
 * Input:
 *      port - Port id.
 * Output:
 *      pEnable - Back pressure status.
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 * Note:
 *      This API can get the half duplex backpressure enable status of the specific port.
 *      The half duplex backpressure enable status of the port is as following:
 *      - DISABLE(Defer)
 *      - ENABLE (Backpressure)
 */
rtk_api_ret_t dal_rtl8367c_port_backpressureEnable_get(rtk_port_t port, rtk_enable_t *pEnable)
{
    rtk_api_ret_t retVal;
    rtk_uint32 regData;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    if (port != RTK_WHOLE_SYSTEM)
        return RT_ERR_PORT_ID;

    if(NULL == pEnable)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicPortJamMode(&regData)) != RT_ERR_OK)
        return retVal;

    *pEnable = !regData;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_adminEnable_set
 * Description:
 *      Set port admin configuration of the specific port.
 * Input:
 *      port    - port id.
 *      enable  - Back pressure status.
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 *      RT_ERR_ENABLE       - Invalid enable input.
 * Note:
 *      This API can set port admin configuration of the specific port.
 *      The port admin configuration of the port is as following:
 *      - DISABLE
 *      - ENABLE
 */
rtk_api_ret_t dal_rtl8367c_port_adminEnable_set(rtk_port_t port, rtk_enable_t enable)
{
    rtk_api_ret_t retVal;
    rtk_uint32      data;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if (enable >= RTK_ENABLE_END)
        return RT_ERR_INPUT;

    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &data)) != RT_ERR_OK)
        return retVal;

    if (ENABLED == enable)
    {
        data &= 0xF7FF;
        data |= 0x0200;
    }
    else if (DISABLED == enable)
    {
        data |= 0x0800;
    }

    if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, data)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_adminEnable_get
 * Description:
 *      Get port admin configurationof the specific port.
 * Input:
 *      port - Port id.
 * Output:
 *      pEnable - Back pressure status.
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 * Note:
 *      This API can get port admin configuration of the specific port.
 *      The port admin configuration of the port is as following:
 *      - DISABLE
 *      - ENABLE
 */
rtk_api_ret_t dal_rtl8367c_port_adminEnable_get(rtk_port_t port, rtk_enable_t *pEnable)
{
    rtk_api_ret_t retVal;
    rtk_uint32      data;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    if(NULL == pEnable)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicPHYReg(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK)
        return retVal;

    if ( (data & 0x0800) == 0x0800)
    {
        *pEnable = DISABLED;
    }
    else
    {
        *pEnable = ENABLED;
    }

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_isolation_set
 * Description:
 *      Set permitted port isolation portmask
 * Input:
 *      port         - port id.
 *      pPortmask    - Permit port mask
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 *      RT_ERR_PORT_MASK    - Invalid portmask.
 * Note:
 *      This API set the port mask that a port can trasmit packet to of each port
 *      A port can only transmit packet to ports included in permitted portmask
 */
rtk_api_ret_t dal_rtl8367c_port_isolation_set(rtk_port_t port, rtk_portmask_t *pPortmask)
{
    rtk_api_ret_t retVal;
    rtk_uint32 pmask;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_VALID(port);

    if(NULL == pPortmask)
        return RT_ERR_NULL_POINTER;

    /* check port mask */
    RTK_CHK_PORTMASK_VALID(pPortmask);

    if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_switch_port_L2P_get(port), pmask)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_isolation_get
 * Description:
 *      Get permitted port isolation portmask
 * Input:
 *      port - Port id.
 * Output:
 *      pPortmask - Permit port mask
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_PORT_ID      - Invalid port number.
 * Note:
 *      This API get the port mask that a port can trasmit packet to of each port
 *      A port can only transmit packet to ports included in permitted portmask
 */
rtk_api_ret_t dal_rtl8367c_port_isolation_get(rtk_port_t port, rtk_portmask_t *pPortmask)
{
    rtk_api_ret_t retVal;
    rtk_uint32 pmask;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_VALID(port);

    if(NULL == pPortmask)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_switch_port_L2P_get(port), &pmask)) != RT_ERR_OK)
        return retVal;

    if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_rgmiiDelayExt_set
 * Description:
 *      Set RGMII interface delay value for TX and RX.
 * Input:
 *      txDelay - TX delay value, 1 for delay 2ns and 0 for no-delay
 *      rxDelay - RX delay value, 0~7 for delay setup.
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_INPUT        - Invalid input parameters.
 * Note:
 *      This API can set external interface 2 RGMII delay.
 *      In TX delay, there are 2 selection: no-delay and 2ns delay.
 *      In RX dekay, there are 8 steps for delay tunning. 0 for no-delay, and 7 for maximum delay.
 *      Note. This API should be called before rtk_port_macForceLinkExt_set().
 */
rtk_api_ret_t dal_rtl8367c_port_rgmiiDelayExt_set(rtk_port_t port, rtk_data_t txDelay, rtk_data_t rxDelay)
{
    rtk_api_ret_t retVal;
    rtk_uint32 regAddr, regData;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_EXT(port);

    if ((txDelay > 1) || (rxDelay > 7))
        return RT_ERR_INPUT;

    if(port == EXT_PORT0)
        regAddr = RTL8367C_REG_EXT1_RGMXF;
    else if(port == EXT_PORT1)
        regAddr = RTL8367C_REG_EXT2_RGMXF;
    else
        return RT_ERR_INPUT;

    if ((retVal = rtl8367c_getAsicReg(regAddr, &regData)) != RT_ERR_OK)
        return retVal;

    regData = (regData & 0xFFF0) | ((txDelay << 3) & 0x0008) | (rxDelay & 0x0007);

    if ((retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_rgmiiDelayExt_get
 * Description:
 *      Get RGMII interface delay value for TX and RX.
 * Input:
 *      None
 * Output:
 *      pTxDelay - TX delay value
 *      pRxDelay - RX delay value
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_INPUT        - Invalid input parameters.
 * Note:
 *      This API can set external interface 2 RGMII delay.
 *      In TX delay, there are 2 selection: no-delay and 2ns delay.
 *      In RX dekay, there are 8 steps for delay tunning. 0 for n0-delay, and 7 for maximum delay.
 */
rtk_api_ret_t dal_rtl8367c_port_rgmiiDelayExt_get(rtk_port_t port, rtk_data_t *pTxDelay, rtk_data_t *pRxDelay)
{
    rtk_api_ret_t retVal;
    rtk_uint32 regAddr, regData;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_EXT(port);

    if( (NULL == pTxDelay) || (NULL == pRxDelay) )
        return RT_ERR_NULL_POINTER;

    if(port == EXT_PORT0)
        regAddr = RTL8367C_REG_EXT1_RGMXF;
    else if(port == EXT_PORT1)
        regAddr = RTL8367C_REG_EXT2_RGMXF;
    else
        return RT_ERR_INPUT;

    if ((retVal = rtl8367c_getAsicReg(regAddr, &regData)) != RT_ERR_OK)
        return retVal;

    *pTxDelay = (regData & 0x0008) >> 3;
    *pRxDelay = regData & 0x0007;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyEnableAll_set
 * Description:
 *      Set all PHY enable status.
 * Input:
 *      enable - PHY Enable State.
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 *      RT_ERR_ENABLE       - Invalid enable input.
 * Note:
 *      This API can set all PHY status.
 *      The configuration of all PHY is as following:
 *      - DISABLE
 *      - ENABLE
 */
rtk_api_ret_t dal_rtl8367c_port_phyEnableAll_set(rtk_enable_t enable)
{
    rtk_api_ret_t retVal;
    rtk_uint32 data;
    rtk_uint32 port;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    if (enable >= RTK_ENABLE_END)
        return RT_ERR_ENABLE;

    if ((retVal = rtl8367c_setAsicPortEnableAll(enable)) != RT_ERR_OK)
        return retVal;

    RTK_SCAN_ALL_LOG_PORT(port)
    {
        if(rtk_switch_isUtpPort(port) == RT_ERR_OK)
        {
            if ((retVal = dal_rtl8367c_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK)
                return retVal;

            if (ENABLED == enable)
            {
                data &= 0xF7FF;
                data |= 0x0200;
            }
            else
            {
                data |= 0x0800;
            }

            if ((retVal = dal_rtl8367c_port_phyReg_set(port, PHY_CONTROL_REG, data)) != RT_ERR_OK)
                return retVal;
        }
    }

    return RT_ERR_OK;

}

/* Function Name:
 *      dal_rtl8367c_port_phyEnableAll_get
 * Description:
 *      Get all PHY enable status.
 * Input:
 *      None
 * Output:
 *      pEnable - PHY Enable State.
 * Return:
 *      RT_ERR_OK           - OK
 *      RT_ERR_FAILED       - Failed
 *      RT_ERR_SMI          - SMI access error
 * Note:
 *      This API can set all PHY status.
 *      The configuration of all PHY is as following:
 *      - DISABLE
 *      - ENABLE
 */
rtk_api_ret_t dal_rtl8367c_port_phyEnableAll_get(rtk_enable_t *pEnable)
{
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    if(NULL == pEnable)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicPortEnableAll(pEnable)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_efid_set
 * Description:
 *      Set port-based enhanced filtering database
 * Input:
 *      port - Port id.
 *      efid - Specified enhanced filtering database.
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK              - OK
 *      RT_ERR_FAILED          - Failed
 *      RT_ERR_SMI             - SMI access error
 *      RT_ERR_L2_FID - Invalid fid.
 *      RT_ERR_INPUT - Invalid input parameter.
 *      RT_ERR_PORT_ID - Invalid port ID.
 * Note:
 *      The API can set port-based enhanced filtering database.
 */
rtk_api_ret_t dal_rtl8367c_port_efid_set(rtk_port_t port, rtk_data_t efid)
{
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_VALID(port);

    /* efid must be 0~7 */
    if (efid > RTK_EFID_MAX)
        return RT_ERR_INPUT;

    if ((retVal = rtl8367c_setAsicPortIsolationEfid(rtk_switch_port_L2P_get(port), efid))!=RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_efid_get
 * Description:
 *      Get port-based enhanced filtering database
 * Input:
 *      port - Port id.
 * Output:
 *      pEfid - Specified enhanced filtering database.
 * Return:
 *      RT_ERR_OK              - OK
 *      RT_ERR_FAILED          - Failed
 *      RT_ERR_SMI             - SMI access error
 *      RT_ERR_INPUT - Invalid input parameters.
 *      RT_ERR_PORT_ID - Invalid port ID.
 * Note:
 *      The API can get port-based enhanced filtering database status.
 */
rtk_api_ret_t dal_rtl8367c_port_efid_get(rtk_port_t port, rtk_data_t *pEfid)
{
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_VALID(port);

    if(NULL == pEfid)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicPortIsolationEfid(rtk_switch_port_L2P_get(port), pEfid))!=RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyComboPortMedia_set
 * Description:
 *      Set Combo port media type
 * Input:
 *      port    - Port id.
 *      media   - Media (COPPER or FIBER or AUTO)
 * Output:
 *      None.
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_INPUT            - Invalid input parameters.
 *      RT_ERR_PORT_ID          - Invalid port ID.
 * Note:
 *      The API can Set Combo port media type.
 */
rtk_api_ret_t dal_rtl8367c_port_phyComboPortMedia_set(rtk_port_t port, rtk_port_media_t media)
{
    rtk_api_ret_t retVal;
    rtk_uint32 regData;
    rtk_uint32 idx;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    /* Check Combo Port ID */
    RTK_CHK_PORT_IS_COMBO(port);

    if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK)
        return retVal;

    if((retVal = rtl8367c_getAsicReg(0x1300, &regData)) != RT_ERR_OK)
        return retVal;

    if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK)
        return retVal;

    if(regData != 0x6367)
        return RT_ERR_CHIP_NOT_SUPPORTED;

    if(media == PORT_MEDIA_FIBER)
    {
        /* software init */
        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK)
            return retVal;

        for(idx = 0; idx < FIBER_INIT_SIZE; idx++)
        {
            if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber[idx])) != RT_ERR_OK)
                return retVal;
        }

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK)
            return retVal;
    }
    else if(media == PORT_MEDIA_AUTO)
    {
        /* software init */
        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK)
            return retVal;

        for(idx = 0; idx < FIBER_AUTO_INIT_SIZE; idx++)
        {
            if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber_auto[idx])) != RT_ERR_OK)
                return retVal;
        }

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK)
            return retVal;
    }
    else if(media == PORT_MEDIA_COPPER)
    {
        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, 1))!=RT_ERR_OK)
            return retVal;

        if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_DW8051_READY_OFFSET, 0)) != RT_ERR_OK)
            return retVal;
    }
    else
        return RT_ERR_INPUT;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyComboPortMedia_get
 * Description:
 *      Get Combo port media type
 * Input:
 *      port    - Port id.
 * Output:
 *      pMedia  - Media (COPPER or FIBER or AUTO)
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_INPUT            - Invalid input parameters.
 *      RT_ERR_PORT_ID          - Invalid port ID.
 * Note:
 *      The API can Set Combo port media type.
 */
rtk_api_ret_t dal_rtl8367c_port_phyComboPortMedia_get(rtk_port_t port, rtk_port_media_t *pMedia)
{
    rtk_api_ret_t   retVal;
    rtk_uint32      regData;
    rtk_uint32      data;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    /* Check Combo Port ID */
    RTK_CHK_PORT_IS_COMBO(port);

    if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK)
        return retVal;

    if((retVal = rtl8367c_getAsicReg(0x1300, &regData)) != RT_ERR_OK)
        return retVal;

    if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK)
        return retVal;

    if(regData != 0x6367)
    {
        *pMedia = PORT_MEDIA_COPPER;
    }
    else
    {
        if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIB_DISAUTODET_OFFSET, &data))!=RT_ERR_OK)
                return retVal;
        if(data == 0)
        {
            *pMedia = PORT_MEDIA_AUTO;
        }
        else
        {
            if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, &data))!=RT_ERR_OK)
                    return retVal;

            if(data == 1)
                *pMedia = PORT_MEDIA_COPPER;
            else
                *pMedia = PORT_MEDIA_FIBER;
        }
    }

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_rtctEnable_set
 * Description:
 *      Enable RTCT test
 * Input:
 *      pPortmask    - Port mask of RTCT enabled port
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_MASK        - Invalid port mask.
 * Note:
 *      The API can enable RTCT Test
 */
rtk_api_ret_t dal_rtl8367c_port_rtctEnable_set(rtk_portmask_t *pPortmask)
{
    rtk_api_ret_t   retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Mask Valid */
    RTK_CHK_PORTMASK_VALID_ONLY_UTP(pPortmask);

    if ((retVal = rtl8367c_setAsicPortRTCTEnable(pPortmask->bits[0]))!=RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_rtctDisable_set
 * Description:
 *      Disable RTCT test
 * Input:
 *      pPortmask    - Port mask of RTCT disabled port
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_MASK        - Invalid port mask.
 * Note:
 *      The API can disable RTCT Test
 */
rtk_api_ret_t dal_rtl8367c_port_rtctDisable_set(rtk_portmask_t *pPortmask)
{
    rtk_api_ret_t   retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Mask Valid */
    RTK_CHK_PORTMASK_VALID_ONLY_UTP(pPortmask);

    if ((retVal = rtl8367c_setAsicPortRTCTDisable(pPortmask->bits[0]))!=RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_rtctResult_get
 * Description:
 *      Get the result of RTCT test
 * Input:
 *      port        - Port ID
 * Output:
 *      pRtctResult - The result of RTCT result
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 *      RT_ERR_PORT_ID              - Invalid port ID.
 *      RT_ERR_PHY_RTCT_NOT_FINISH  - Testing does not finish.
 * Note:
 *      The API can get RTCT test result.
 *      RTCT test may takes 4.8 seconds to finish its test at most.
 *      Thus, if this API return RT_ERR_PHY_RTCT_NOT_FINISH or
 *      other error code, the result can not be referenced and
 *      user should call this API again until this API returns
 *      a RT_ERR_OK.
 *      The result is stored at pRtctResult->ge_result
 *      pRtctResult->linkType is unused.
 *      The unit of channel length is 2.5cm. Ex. 300 means 300 * 2.5 = 750cm = 7.5M
 */
rtk_api_ret_t dal_rtl8367c_port_rtctResult_get(rtk_port_t port, rtk_rtctResult_t *pRtctResult)
{
    rtk_api_ret_t               retVal;
    rtl8367c_port_rtct_result_t result;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    memset(pRtctResult, 0x00, sizeof(rtk_rtctResult_t));
    if ((retVal = rtl8367c_getAsicPortRTCTResult(port, &result))!=RT_ERR_OK)
        return retVal;

    pRtctResult->result.ge_result.channelALen = result.channelALen;
    pRtctResult->result.ge_result.channelBLen = result.channelBLen;
    pRtctResult->result.ge_result.channelCLen = result.channelCLen;
    pRtctResult->result.ge_result.channelDLen = result.channelDLen;

    pRtctResult->result.ge_result.channelALinedriver = result.channelALinedriver;
    pRtctResult->result.ge_result.channelBLinedriver = result.channelBLinedriver;
    pRtctResult->result.ge_result.channelCLinedriver = result.channelCLinedriver;
    pRtctResult->result.ge_result.channelDLinedriver = result.channelDLinedriver;

    pRtctResult->result.ge_result.channelAMismatch = result.channelAMismatch;
    pRtctResult->result.ge_result.channelBMismatch = result.channelBMismatch;
    pRtctResult->result.ge_result.channelCMismatch = result.channelCMismatch;
    pRtctResult->result.ge_result.channelDMismatch = result.channelDMismatch;

    pRtctResult->result.ge_result.channelAOpen = result.channelAOpen;
    pRtctResult->result.ge_result.channelBOpen = result.channelBOpen;
    pRtctResult->result.ge_result.channelCOpen = result.channelCOpen;
    pRtctResult->result.ge_result.channelDOpen = result.channelDOpen;

    pRtctResult->result.ge_result.channelAShort = result.channelAShort;
    pRtctResult->result.ge_result.channelBShort = result.channelBShort;
    pRtctResult->result.ge_result.channelCShort = result.channelCShort;
    pRtctResult->result.ge_result.channelDShort = result.channelDShort;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_sds_reset
 * Description:
 *      Reset Serdes
 * Input:
 *      port        - Port ID
 * Output:
 *      None.
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 *      RT_ERR_PORT_ID              - Invalid port ID.
 * Note:
 *      The API can reset Serdes
 */
rtk_api_ret_t dal_rtl8367c_port_sds_reset(rtk_port_t port)
{
    rtk_uint32 ext_id;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK)
        return RT_ERR_PORT_ID;

    ext_id = port - 15;
    return rtl8367c_sdsReset(ext_id);
}

/* Function Name:
 *      dal_rtl8367c_port_sgmiiLinkStatus_get
 * Description:
 *      Get SGMII status
 * Input:
 *      port        - Port ID
 * Output:
 *      pSignalDetect   - Signal detect
 *      pSync           - Sync
 *      pLink           - Link
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 *      RT_ERR_PORT_ID              - Invalid port ID.
 * Note:
 *      The API can reset Serdes
 */
rtk_api_ret_t dal_rtl8367c_port_sgmiiLinkStatus_get(rtk_port_t port, rtk_data_t *pSignalDetect, rtk_data_t *pSync, rtk_port_linkStatus_t *pLink)
{
    rtk_uint32 ext_id;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK)
        return RT_ERR_PORT_ID;

    if(NULL == pSignalDetect)
        return RT_ERR_NULL_POINTER;

    if(NULL == pSync)
        return RT_ERR_NULL_POINTER;

    if(NULL == pLink)
        return RT_ERR_NULL_POINTER;

    ext_id = port - 15;
    return rtl8367c_getSdsLinkStatus(ext_id, (rtk_uint32 *)pSignalDetect, (rtk_uint32 *)pSync, (rtk_uint32 *)pLink);
}

/* Function Name:
 *      dal_rtl8367c_port_sgmiiNway_set
 * Description:
 *      Configure SGMII/HSGMII port Nway state
 * Input:
 *      port        - Port ID
 *      state       - Nway state
 * Output:
 *      None.
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 *      RT_ERR_PORT_ID              - Invalid port ID.
 * Note:
 *      The API configure SGMII/HSGMII port Nway state
 */
rtk_api_ret_t dal_rtl8367c_port_sgmiiNway_set(rtk_port_t port, rtk_enable_t state)
{
    rtk_uint32 ext_id;

     /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK)
        return RT_ERR_PORT_ID;

    if(state >= RTK_ENABLE_END)
        return RT_ERR_INPUT;

    ext_id = port - 15;
    return rtl8367c_setSgmiiNway(ext_id, (rtk_uint32)state);
}

/* Function Name:
 *      dal_rtl8367c_port_sgmiiNway_get
 * Description:
 *      Get SGMII/HSGMII port Nway state
 * Input:
 *      port        - Port ID
 * Output:
 *      pState      - Nway state
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 *      RT_ERR_PORT_ID              - Invalid port ID.
 * Note:
 *      The API can get SGMII/HSGMII port Nway state
 */
rtk_api_ret_t dal_rtl8367c_port_sgmiiNway_get(rtk_port_t port, rtk_enable_t *pState)
{
    rtk_uint32 ext_id;

     /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK)
        return RT_ERR_PORT_ID;

    if(NULL == pState)
        return RT_ERR_NULL_POINTER;

    ext_id = port - 15;
    return rtl8367c_getSgmiiNway(ext_id, (rtk_uint32 *)pState);
}


/* Function Name:
 *      dal_rtl8367c_port_fiberAbilityExt_set
 * Description:
 *      Get SGMII/HSGMII port Nway state
 * Input:
 *      port        - Port ID
 *      pause      -pause state
 *      asypause -asypause state
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 *      RT_ERR_PORT_ID              - Invalid port ID.
 * Note:
 *      The API can get SGMII/HSGMII port Nway state
 */
rtk_api_ret_t dal_rtl8367c_port_fiberAbilityExt_set(rtk_port_t port, rtk_uint32 pause, rtk_uint32 asypause)
{
    rtk_uint32 ext_id;

    ext_id = port - 15;

    return rtl8367c_setFiberAbilityExt(ext_id, pause, asypause);

}

/* Function Name:
 *      dal_rtl8367c_port_fiberAbilityExt_get
 * Description:
 *      Get SGMII/HSGMII port Nway state
 * Input:
 *      port        - Port ID
 * Output:
 *      pPause      -pause state
 *      pAsypause -asypause state
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 *      RT_ERR_PORT_ID              - Invalid port ID.
 * Note:
 *      The API can get SGMII/HSGMII port Nway state
 */
rtk_api_ret_t dal_rtl8367c_port_fiberAbilityExt_get(rtk_port_t port, rtk_uint32* pPause, rtk_uint32* pAsypause)
{
    rtk_uint32 ext_id;

    ext_id = port - 15;

    return rtl8367c_getFiberAbilityExt(ext_id, pPause, pAsypause);

}

/* Function Name:
 *      dal_rtl8367c_port_autoDos_set
 * Description:
 *      Set Auto Dos state
 * Input:
 *      type        - Auto DoS type
 *      state       - 1: Eanble(Drop), 0: Disable(Forward)
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 * Note:
 *      The API can set Auto Dos state
 */
rtk_api_ret_t dal_rtl8367c_port_autoDos_set(rtk_port_autoDosType_t type, rtk_enable_t state)
{
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    if (type >= AUTODOS_END)
        return RT_ERR_INPUT;

    if (state >= RTK_ENABLE_END)
        return RT_ERR_INPUT;

    if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DOS_CFG, RTL8367C_DROP_DAEQSA_OFFSET + type, (state == ENABLED) ? 1 : 0)) != RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_autoDos_get
 * Description:
 *      Get Auto Dos state
 * Input:
 *      type        - Auto DoS type
 * Output:
 *      pState      - 1: Eanble(Drop), 0: Disable(Forward)
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 *      RT_ERR_NULL_POINTER         - Null Pointer
 * Note:
 *      The API can get Auto Dos state
 */
rtk_api_ret_t dal_rtl8367c_port_autoDos_get(rtk_port_autoDosType_t type, rtk_enable_t *pState)
{
    rtk_api_ret_t retVal;
    rtk_uint32 regData;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    if (type >= AUTODOS_END)
        return RT_ERR_INPUT;

    if (pState == NULL)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_DOS_CFG, RTL8367C_DROP_DAEQSA_OFFSET + type, &regData)) != RT_ERR_OK)
        return retVal;

    *pState = (regData == 1) ? ENABLED : DISABLED;
    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyMdx_set
 * Description:
 *      Set PHY MDI/MDIX state
 * Input:
 *      port        - port ID
 *      mode        - PHY MDI/MDIX mode
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 * Note:
 *      The API can set PHY MDI/MDIX state
 */
rtk_api_ret_t dal_rtl8367c_port_phyMdx_set(rtk_port_t port, rtk_port_phy_mdix_mode_t mode)
{
    rtk_uint32 regData;
    rtk_api_ret_t retVal;

    /* Check initialization state */
    RTK_CHK_INIT_STATE();

    /* Check Port Valid */
    RTK_CHK_PORT_IS_UTP(port);

    switch (mode)
    {
        case PHY_AUTO_CROSSOVER_MODE:
            if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 24, &regData))!=RT_ERR_OK)
                return retVal;

            regData &= ~(0x0001 << 9);

            if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), 24, regData))!=RT_ERR_OK)
                return retVal;
            break;
        case PHY_FORCE_MDI_MODE:
            if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 24, &regData))!=RT_ERR_OK)
                return retVal;

            regData |= (0x0001 << 9);
            regData |= (0x0001 << 8);

            if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), 24, regData))!=RT_ERR_OK)
                return retVal;
            break;
        case PHY_FORCE_MDIX_MODE:
            if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 24, &regData))!=RT_ERR_OK)
                return retVal;

            regData |= (0x0001 << 9);
            regData &= ~(0x0001 << 8);

            if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), 24, regData))!=RT_ERR_OK)
                return retVal;
            break;
        default:
            return RT_ERR_INPUT;
            break;
    }

    /* Restart N-way */
    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 0, &regData))!=RT_ERR_OK)
        return retVal;

    regData |= (0x0001 << 9);

    if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), 0, regData))!=RT_ERR_OK)
        return retVal;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyMdx_get
 * Description:
 *      Get PHY MDI/MDIX state
 * Input:
 *      port        - port ID
 * Output:
 *      pMode       - PHY MDI/MDIX mode
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 * Note:
 *      The API can get PHY MDI/MDIX state
 */
rtk_api_ret_t dal_rtl8367c_port_phyMdx_get(rtk_port_t port, rtk_port_phy_mdix_mode_t *pMode)
{
    rtk_uint32 regData;
    rtk_api_ret_t retVal;

    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 24, &regData))!=RT_ERR_OK)
        return retVal;

    if(regData & (0x0001 << 9))
    {
        if(regData & (0x0001 << 8))
            *pMode = PHY_FORCE_MDI_MODE;
        else
            *pMode = PHY_FORCE_MDIX_MODE;
    }
    else
        *pMode = PHY_AUTO_CROSSOVER_MODE;

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyMdxStatus_get
 * Description:
 *      Get PHY MDI/MDIX status
 * Input:
 *      port        - port ID
 * Output:
 *      pStatus     - PHY MDI/MDIX status
 * Return:
 *      RT_ERR_OK                   - OK
 *      RT_ERR_FAILED               - Failed
 *      RT_ERR_SMI                  - SMI access error
 * Note:
 *      The API can get PHY MDI/MDIX status
 */
rtk_api_ret_t dal_rtl8367c_port_phyMdxStatus_get(rtk_port_t port, rtk_port_phy_mdix_status_t *pStatus)
{
    rtk_uint32 regData;
    rtk_api_ret_t retVal;

    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 24, &regData))!=RT_ERR_OK)
        return retVal;

    if (regData & (0x0001 << 9))
    {
        if (regData & (0x0001 << 8))
            *pStatus = PHY_STATUS_FORCE_MDI_MODE;
        else
            *pStatus = PHY_STATUS_FORCE_MDIX_MODE;
    }
    else
    {
        if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 26, &regData))!=RT_ERR_OK)
            return retVal;

        if (regData & (0x0001 << 1))
            *pStatus = PHY_STATUS_AUTO_MDI_MODE;
        else
            *pStatus = PHY_STATUS_AUTO_MDIX_MODE;
    }

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyTestMode_set
 * Description:
 *      Set PHY in test mode.
 * Input:
 *      port    - port id.
 *      mode    - PHY test mode 0:normal 1:test mode 1 2:test mode 2 3: test mode 3 4:test mode 4 5~7:reserved
 * Output:
 *      None
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_ID          - Invalid port number.
 *      RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
 *      RT_ERR_NOT_ALLOWED      - The Setting is not allowed, caused by set more than 1 port in Test mode.
 * Note:
 *      Set PHY in test mode and only one PHY can be in test mode at the same time.
 *      It means API will return FAILED if other PHY is in test mode.
 *      This API only provide test mode 1 & 4 setup.
 */
rtk_api_ret_t dal_rtl8367c_port_phyTestMode_set(rtk_port_t port, rtk_port_phy_test_mode_t mode)
{
    rtk_uint32          data, regData, i;
    rtk_api_ret_t       retVal;

    RTK_CHK_PORT_IS_UTP(port);

    if(mode >= PHY_TEST_MODE_END)
        return RT_ERR_INPUT;

    if( (mode == PHY_TEST_MODE_2) || (mode == PHY_TEST_MODE_3) )
        return RT_ERR_INPUT;

    if (PHY_TEST_MODE_NORMAL != mode)
    {
        /* Other port should be Normal mode */
        RTK_SCAN_ALL_LOG_PORT(i)
        {
            if(rtk_switch_isUtpPort(i) == RT_ERR_OK)
            {
                if(i != port)
                {
                    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(i), 9, &data)) != RT_ERR_OK)
                        return retVal;

                    if((data & 0xE000) != 0)
                        return RT_ERR_NOT_ALLOWED;
                }
            }
        }
    }

    if (PHY_TEST_MODE_4 == mode)
    {
        if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK)
            return retVal;

        if((retVal = rtl8367c_getAsicReg(0x1300, &regData)) != RT_ERR_OK)
            return retVal;

        if(regData == 0x6511)
        {
            if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa436, 0x8081)) != RT_ERR_OK)
                return retVal;

            if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa438, 0x7e00)) != RT_ERR_OK)
                return retVal;
        }
    }

    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 9, &data)) != RT_ERR_OK)
        return retVal;

    data &= ~0xE000;
    data |= (mode << 13);
    if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), 9, data)) != RT_ERR_OK)
        return retVal;

    if (PHY_TEST_MODE_4 == mode)
    {
        if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK)
            return retVal;

        if((retVal = rtl8367c_getAsicReg(0x1300, &regData)) != RT_ERR_OK)
            return retVal;

        if( (regData == 0x0276) || (regData == 0x0597) )
        {
            if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xbcc2, 0xF4F4)) != RT_ERR_OK)
                return retVal;
        }

        if( (regData == 0x6367) )
        {
            if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa436, 0x80c1)) != RT_ERR_OK)
                return retVal;

            if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa438, 0xfe00)) != RT_ERR_OK)
                return retVal;
        }
    }

    return RT_ERR_OK;
}

/* Function Name:
 *      dal_rtl8367c_port_phyTestMode_get
 * Description:
 *      Get PHY in which test mode.
 * Input:
 *      port - Port id.
 * Output:
 *      mode - PHY test mode 0:normal 1:test mode 1 2:test mode 2 3: test mode 3 4:test mode 4 5~7:reserved
 * Return:
 *      RT_ERR_OK               - OK
 *      RT_ERR_FAILED           - Failed
 *      RT_ERR_SMI              - SMI access error
 *      RT_ERR_PORT_ID          - Invalid port number.
 *      RT_ERR_INPUT            - Invalid input parameters.
 *      RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy
 * Note:
 *      Get test mode of PHY from register setting 9.15 to 9.13.
 */
rtk_api_ret_t dal_rtl8367c_port_phyTestMode_get(rtk_port_t port, rtk_port_phy_test_mode_t *pMode)
{
    rtk_uint32      data;
    rtk_api_ret_t   retVal;

    RTK_CHK_PORT_IS_UTP(port);

    if (pMode == NULL)
        return RT_ERR_NULL_POINTER;

    if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 9, &data)) != RT_ERR_OK)
        return retVal;

    *pMode = (data & 0xE000) >> 13;

    return RT_ERR_OK;
}
