Deprecated fork of old network stack source from github. Please use official library instead: https://mbed.org/users/mbed_official/code/EthernetInterface/

Committer:
AdamGreen
Date:
Sat Oct 26 08:51:36 2013 +0000
Revision:
1:eadc868c2acf
Parent:
0:3b00827bb0b7
Fix TCP checksum bug and stranded large TCP segments.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AdamGreen 0:3b00827bb0b7 1 /**********************************************************************
AdamGreen 0:3b00827bb0b7 2 * $Id$ lpc_phy_dp83848.c 2011-11-20
AdamGreen 0:3b00827bb0b7 3 *//**
AdamGreen 0:3b00827bb0b7 4 * @file lpc_phy_dp83848.c
AdamGreen 0:3b00827bb0b7 5 * @brief DP83848C PHY status and control.
AdamGreen 0:3b00827bb0b7 6 * @version 1.0
AdamGreen 0:3b00827bb0b7 7 * @date 20 Nov. 2011
AdamGreen 0:3b00827bb0b7 8 * @author NXP MCU SW Application Team
AdamGreen 0:3b00827bb0b7 9 *
AdamGreen 0:3b00827bb0b7 10 * Copyright(C) 2011, NXP Semiconductor
AdamGreen 0:3b00827bb0b7 11 * All rights reserved.
AdamGreen 0:3b00827bb0b7 12 *
AdamGreen 0:3b00827bb0b7 13 ***********************************************************************
AdamGreen 0:3b00827bb0b7 14 * Software that is described herein is for illustrative purposes only
AdamGreen 0:3b00827bb0b7 15 * which provides customers with programming information regarding the
AdamGreen 0:3b00827bb0b7 16 * products. This software is supplied "AS IS" without any warranties.
AdamGreen 0:3b00827bb0b7 17 * NXP Semiconductors assumes no responsibility or liability for the
AdamGreen 0:3b00827bb0b7 18 * use of the software, conveys no license or title under any patent,
AdamGreen 0:3b00827bb0b7 19 * copyright, or mask work right to the product. NXP Semiconductors
AdamGreen 0:3b00827bb0b7 20 * reserves the right to make changes in the software without
AdamGreen 0:3b00827bb0b7 21 * notification. NXP Semiconductors also make no representation or
AdamGreen 0:3b00827bb0b7 22 * warranty that such application will be suitable for the specified
AdamGreen 0:3b00827bb0b7 23 * use without further testing or modification.
AdamGreen 0:3b00827bb0b7 24 **********************************************************************/
AdamGreen 0:3b00827bb0b7 25
AdamGreen 0:3b00827bb0b7 26 #include "lwip/opt.h"
AdamGreen 0:3b00827bb0b7 27 #include "lwip/err.h"
AdamGreen 0:3b00827bb0b7 28 #include "lwip/tcpip.h"
AdamGreen 0:3b00827bb0b7 29 #include "lwip/snmp.h"
AdamGreen 0:3b00827bb0b7 30 #include "lpc_emac_config.h"
AdamGreen 0:3b00827bb0b7 31 #include "lpc_phy.h"
AdamGreen 0:3b00827bb0b7 32
AdamGreen 0:3b00827bb0b7 33 /** @defgroup dp83848_phy PHY status and control for the DP83848.
AdamGreen 0:3b00827bb0b7 34 * @ingroup lwip_phy
AdamGreen 0:3b00827bb0b7 35 *
AdamGreen 0:3b00827bb0b7 36 * Various functions for controlling and monitoring the status of the
AdamGreen 0:3b00827bb0b7 37 * DP83848 PHY. In polled (standalone) systems, the PHY state must be
AdamGreen 0:3b00827bb0b7 38 * monitored as part of the application. In a threaded (RTOS) system,
AdamGreen 0:3b00827bb0b7 39 * the PHY state is monitored by the PHY handler thread. The MAC
AdamGreen 0:3b00827bb0b7 40 * driver will not transmit unless the PHY link is active.
AdamGreen 0:3b00827bb0b7 41 * @{
AdamGreen 0:3b00827bb0b7 42 */
AdamGreen 0:3b00827bb0b7 43
AdamGreen 0:3b00827bb0b7 44 /** \brief DP83848 PHY register offsets */
AdamGreen 0:3b00827bb0b7 45 #define DP8_BMCR_REG 0x0 /**< Basic Mode Control Register */
AdamGreen 0:3b00827bb0b7 46 #define DP8_BMSR_REG 0x1 /**< Basic Mode Status Reg */
AdamGreen 0:3b00827bb0b7 47 #define DP8_IDR1_REG 0x2 /**< Basic Mode Status Reg */
AdamGreen 0:3b00827bb0b7 48 #define DP8_IDR2_REG 0x3 /**< Basic Mode Status Reg */
AdamGreen 0:3b00827bb0b7 49 #define DP8_ANADV_REG 0x4 /**< Auto_Neg Advt Reg */
AdamGreen 0:3b00827bb0b7 50 #define DP8_ANLPA_REG 0x5 /**< Auto_neg Link Partner Ability Reg */
AdamGreen 0:3b00827bb0b7 51 #define DP8_ANEEXP_REG 0x6 /**< Auto-neg Expansion Reg */
AdamGreen 0:3b00827bb0b7 52 #define DP8_PHY_STAT_REG 0x10 /**< PHY Status Register */
AdamGreen 0:3b00827bb0b7 53 #define DP8_PHY_INT_CTL_REG 0x11 /**< PHY Interrupt Control Register */
AdamGreen 0:3b00827bb0b7 54 #define DP8_PHY_RBR_REG 0x17 /**< PHY RMII and Bypass Register */
AdamGreen 0:3b00827bb0b7 55 #define DP8_PHY_STS_REG 0x19 /**< PHY Status Register */
AdamGreen 0:3b00827bb0b7 56
AdamGreen 0:3b00827bb0b7 57 #define DP8_PHY_SCSR_REG 0x1f /**< PHY Special Control/Status Register (LAN8720) */
AdamGreen 0:3b00827bb0b7 58
AdamGreen 0:3b00827bb0b7 59 /** \brief DP83848 Control register definitions */
AdamGreen 0:3b00827bb0b7 60 #define DP8_RESET (1 << 15) /**< 1= S/W Reset */
AdamGreen 0:3b00827bb0b7 61 #define DP8_LOOPBACK (1 << 14) /**< 1=loopback Enabled */
AdamGreen 0:3b00827bb0b7 62 #define DP8_SPEED_SELECT (1 << 13) /**< 1=Select 100MBps */
AdamGreen 0:3b00827bb0b7 63 #define DP8_AUTONEG (1 << 12) /**< 1=Enable auto-negotiation */
AdamGreen 0:3b00827bb0b7 64 #define DP8_POWER_DOWN (1 << 11) /**< 1=Power down PHY */
AdamGreen 0:3b00827bb0b7 65 #define DP8_ISOLATE (1 << 10) /**< 1=Isolate PHY */
AdamGreen 0:3b00827bb0b7 66 #define DP8_RESTART_AUTONEG (1 << 9) /**< 1=Restart auto-negoatiation */
AdamGreen 0:3b00827bb0b7 67 #define DP8_DUPLEX_MODE (1 << 8) /**< 1=Full duplex mode */
AdamGreen 0:3b00827bb0b7 68 #define DP8_COLLISION_TEST (1 << 7) /**< 1=Perform collsion test */
AdamGreen 0:3b00827bb0b7 69
AdamGreen 0:3b00827bb0b7 70 /** \brief DP83848 Status register definitions */
AdamGreen 0:3b00827bb0b7 71 #define DP8_100BASE_T4 (1 << 15) /**< T4 mode */
AdamGreen 0:3b00827bb0b7 72 #define DP8_100BASE_TX_FD (1 << 14) /**< 100MBps full duplex */
AdamGreen 0:3b00827bb0b7 73 #define DP8_100BASE_TX_HD (1 << 13) /**< 100MBps half duplex */
AdamGreen 0:3b00827bb0b7 74 #define DP8_10BASE_T_FD (1 << 12) /**< 100Bps full duplex */
AdamGreen 0:3b00827bb0b7 75 #define DP8_10BASE_T_HD (1 << 11) /**< 10MBps half duplex */
AdamGreen 0:3b00827bb0b7 76 #define DP8_MF_PREAMB_SUPPR (1 << 6) /**< Preamble suppress */
AdamGreen 0:3b00827bb0b7 77 #define DP8_AUTONEG_COMP (1 << 5) /**< Auto-negotation complete */
AdamGreen 0:3b00827bb0b7 78 #define DP8_RMT_FAULT (1 << 4) /**< Fault */
AdamGreen 0:3b00827bb0b7 79 #define DP8_AUTONEG_ABILITY (1 << 3) /**< Auto-negotation supported */
AdamGreen 0:3b00827bb0b7 80 #define DP8_LINK_STATUS (1 << 2) /**< 1=Link active */
AdamGreen 0:3b00827bb0b7 81 #define DP8_JABBER_DETECT (1 << 1) /**< Jabber detect */
AdamGreen 0:3b00827bb0b7 82 #define DP8_EXTEND_CAPAB (1 << 0) /**< Supports extended capabilities */
AdamGreen 0:3b00827bb0b7 83
AdamGreen 0:3b00827bb0b7 84 /** \brief DP83848 PHY RBR MII dode definitions */
AdamGreen 0:3b00827bb0b7 85 #define DP8_RBR_RMII_MODE (1 << 5) /**< Use RMII mode */
AdamGreen 0:3b00827bb0b7 86
AdamGreen 0:3b00827bb0b7 87 /** \brief DP83848 PHY status definitions */
AdamGreen 0:3b00827bb0b7 88 #define DP8_REMOTEFAULT (1 << 6) /**< Remote fault */
AdamGreen 0:3b00827bb0b7 89 #define DP8_FULLDUPLEX (1 << 2) /**< 1=full duplex */
AdamGreen 0:3b00827bb0b7 90 #define DP8_SPEED10MBPS (1 << 1) /**< 1=10MBps speed */
AdamGreen 0:3b00827bb0b7 91 #define DP8_VALID_LINK (1 << 0) /**< 1=Link active */
AdamGreen 0:3b00827bb0b7 92
AdamGreen 0:3b00827bb0b7 93 /** \brief DP83848 PHY ID register definitions */
AdamGreen 0:3b00827bb0b7 94 #define DP8_PHYID1_OUI 0x2000 /**< Expected PHY ID1 */
AdamGreen 0:3b00827bb0b7 95 #define DP8_PHYID2_OUI 0x5c90 /**< Expected PHY ID2 */
AdamGreen 0:3b00827bb0b7 96
AdamGreen 0:3b00827bb0b7 97 /** \brief LAN8720 PHY Special Control/Status Register */
AdamGreen 0:3b00827bb0b7 98 #define PHY_SCSR_100MBIT 0x0008 /**< Speed: 1=100 MBit, 0=10Mbit */
AdamGreen 0:3b00827bb0b7 99 #define PHY_SCSR_DUPLEX 0x0010 /**< PHY Duplex Mask */
AdamGreen 0:3b00827bb0b7 100
AdamGreen 0:3b00827bb0b7 101 /** \brief Link status bits */
AdamGreen 0:3b00827bb0b7 102 #define LNK_STAT_VALID 0x01
AdamGreen 0:3b00827bb0b7 103 #define LNK_STAT_FULLDUPLEX 0x02
AdamGreen 0:3b00827bb0b7 104 #define LNK_STAT_SPEED10MPS 0x04
AdamGreen 0:3b00827bb0b7 105
AdamGreen 0:3b00827bb0b7 106 /** \brief PHY ID definitions */
AdamGreen 0:3b00827bb0b7 107 #define DP83848C_ID 0x20005C90 /**< PHY Identifier - DP83848C */
AdamGreen 0:3b00827bb0b7 108 #define LAN8720_ID 0x0007C0F0 /**< PHY Identifier - LAN8720 */
AdamGreen 0:3b00827bb0b7 109
AdamGreen 0:3b00827bb0b7 110 /** \brief PHY status structure used to indicate current status of PHY.
AdamGreen 0:3b00827bb0b7 111 */
AdamGreen 0:3b00827bb0b7 112 typedef struct {
AdamGreen 0:3b00827bb0b7 113 u32_t phy_speed_100mbs:1; /**< 10/100 MBS connection speed flag. */
AdamGreen 0:3b00827bb0b7 114 u32_t phy_full_duplex:1; /**< Half/full duplex connection speed flag. */
AdamGreen 0:3b00827bb0b7 115 u32_t phy_link_active:1; /**< Phy link active flag. */
AdamGreen 0:3b00827bb0b7 116 } PHY_STATUS_TYPE;
AdamGreen 0:3b00827bb0b7 117
AdamGreen 0:3b00827bb0b7 118 /** \brief PHY update flags */
AdamGreen 0:3b00827bb0b7 119 static PHY_STATUS_TYPE physts;
AdamGreen 0:3b00827bb0b7 120
AdamGreen 0:3b00827bb0b7 121 /** \brief Last PHY update flags, used for determing if something has changed */
AdamGreen 0:3b00827bb0b7 122 static PHY_STATUS_TYPE olddphysts;
AdamGreen 0:3b00827bb0b7 123
AdamGreen 0:3b00827bb0b7 124 /** \brief PHY update counter for state machine */
AdamGreen 0:3b00827bb0b7 125 static s32_t phyustate;
AdamGreen 0:3b00827bb0b7 126
AdamGreen 0:3b00827bb0b7 127 /** \brief Holds the PHY ID */
AdamGreen 0:3b00827bb0b7 128 static u32_t phy_id;
AdamGreen 0:3b00827bb0b7 129
AdamGreen 0:3b00827bb0b7 130 /** \brief Temporary holder of link status for LAN7420 */
AdamGreen 0:3b00827bb0b7 131 static u32_t phy_lan7420_sts_tmp;
AdamGreen 0:3b00827bb0b7 132
AdamGreen 0:3b00827bb0b7 133 /** \brief Update PHY status from passed value
AdamGreen 0:3b00827bb0b7 134 *
AdamGreen 0:3b00827bb0b7 135 * This function updates the current PHY status based on the
AdamGreen 0:3b00827bb0b7 136 * passed PHY status word. The PHY status indicate if the link
AdamGreen 0:3b00827bb0b7 137 * is active, the connection speed, and duplex.
AdamGreen 0:3b00827bb0b7 138 *
AdamGreen 0:3b00827bb0b7 139 * \param[in] netif NETIF structure
AdamGreen 0:3b00827bb0b7 140 * \param[in] linksts Status word from PHY
AdamGreen 0:3b00827bb0b7 141 * \return 1 if the status has changed, otherwise 0
AdamGreen 0:3b00827bb0b7 142 */
AdamGreen 0:3b00827bb0b7 143 static s32_t lpc_update_phy_sts(struct netif *netif, u32_t linksts)
AdamGreen 0:3b00827bb0b7 144 {
AdamGreen 0:3b00827bb0b7 145 s32_t changed = 0;
AdamGreen 0:3b00827bb0b7 146
AdamGreen 0:3b00827bb0b7 147 /* Update link active status */
AdamGreen 0:3b00827bb0b7 148 if (linksts & LNK_STAT_VALID)
AdamGreen 0:3b00827bb0b7 149 physts.phy_link_active = 1;
AdamGreen 0:3b00827bb0b7 150 else
AdamGreen 0:3b00827bb0b7 151 physts.phy_link_active = 0;
AdamGreen 0:3b00827bb0b7 152
AdamGreen 0:3b00827bb0b7 153 /* Full or half duplex */
AdamGreen 0:3b00827bb0b7 154 if (linksts & LNK_STAT_FULLDUPLEX)
AdamGreen 0:3b00827bb0b7 155 physts.phy_full_duplex = 1;
AdamGreen 0:3b00827bb0b7 156 else
AdamGreen 0:3b00827bb0b7 157 physts.phy_full_duplex = 0;
AdamGreen 0:3b00827bb0b7 158
AdamGreen 0:3b00827bb0b7 159 /* Configure 100MBit/10MBit mode. */
AdamGreen 0:3b00827bb0b7 160 if (linksts & LNK_STAT_SPEED10MPS)
AdamGreen 0:3b00827bb0b7 161 physts.phy_speed_100mbs = 0;
AdamGreen 0:3b00827bb0b7 162 else
AdamGreen 0:3b00827bb0b7 163 physts.phy_speed_100mbs = 1;
AdamGreen 0:3b00827bb0b7 164
AdamGreen 0:3b00827bb0b7 165 if (physts.phy_speed_100mbs != olddphysts.phy_speed_100mbs) {
AdamGreen 0:3b00827bb0b7 166 changed = 1;
AdamGreen 0:3b00827bb0b7 167 if (physts.phy_speed_100mbs) {
AdamGreen 0:3b00827bb0b7 168 /* 100MBit mode. */
AdamGreen 0:3b00827bb0b7 169 lpc_emac_set_speed(1);
AdamGreen 0:3b00827bb0b7 170
AdamGreen 0:3b00827bb0b7 171 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);
AdamGreen 0:3b00827bb0b7 172 }
AdamGreen 0:3b00827bb0b7 173 else {
AdamGreen 0:3b00827bb0b7 174 /* 10MBit mode. */
AdamGreen 0:3b00827bb0b7 175 lpc_emac_set_speed(0);
AdamGreen 0:3b00827bb0b7 176
AdamGreen 0:3b00827bb0b7 177 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
AdamGreen 0:3b00827bb0b7 178 }
AdamGreen 0:3b00827bb0b7 179
AdamGreen 0:3b00827bb0b7 180 olddphysts.phy_speed_100mbs = physts.phy_speed_100mbs;
AdamGreen 0:3b00827bb0b7 181 }
AdamGreen 0:3b00827bb0b7 182
AdamGreen 0:3b00827bb0b7 183 if (physts.phy_full_duplex != olddphysts.phy_full_duplex) {
AdamGreen 0:3b00827bb0b7 184 changed = 1;
AdamGreen 0:3b00827bb0b7 185 if (physts.phy_full_duplex)
AdamGreen 0:3b00827bb0b7 186 lpc_emac_set_duplex(1);
AdamGreen 0:3b00827bb0b7 187 else
AdamGreen 0:3b00827bb0b7 188 lpc_emac_set_duplex(0);
AdamGreen 0:3b00827bb0b7 189
AdamGreen 0:3b00827bb0b7 190 olddphysts.phy_full_duplex = physts.phy_full_duplex;
AdamGreen 0:3b00827bb0b7 191 }
AdamGreen 0:3b00827bb0b7 192
AdamGreen 0:3b00827bb0b7 193 if (physts.phy_link_active != olddphysts.phy_link_active) {
AdamGreen 0:3b00827bb0b7 194 changed = 1;
AdamGreen 0:3b00827bb0b7 195 #if NO_SYS == 1
AdamGreen 0:3b00827bb0b7 196 if (physts.phy_link_active)
AdamGreen 0:3b00827bb0b7 197 netif_set_link_up(netif);
AdamGreen 0:3b00827bb0b7 198 else
AdamGreen 0:3b00827bb0b7 199 netif_set_link_down(netif);
AdamGreen 0:3b00827bb0b7 200 #else
AdamGreen 0:3b00827bb0b7 201 if (physts.phy_link_active)
AdamGreen 0:3b00827bb0b7 202 tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up,
AdamGreen 0:3b00827bb0b7 203 (void*) netif, 1);
AdamGreen 0:3b00827bb0b7 204 else
AdamGreen 0:3b00827bb0b7 205 tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down,
AdamGreen 0:3b00827bb0b7 206 (void*) netif, 1);
AdamGreen 0:3b00827bb0b7 207 #endif
AdamGreen 0:3b00827bb0b7 208
AdamGreen 0:3b00827bb0b7 209 olddphysts.phy_link_active = physts.phy_link_active;
AdamGreen 0:3b00827bb0b7 210 }
AdamGreen 0:3b00827bb0b7 211
AdamGreen 0:3b00827bb0b7 212 return changed;
AdamGreen 0:3b00827bb0b7 213 }
AdamGreen 0:3b00827bb0b7 214
AdamGreen 0:3b00827bb0b7 215 /** \brief Initialize the DP83848 PHY.
AdamGreen 0:3b00827bb0b7 216 *
AdamGreen 0:3b00827bb0b7 217 * This function initializes the DP83848 PHY. It will block until
AdamGreen 0:3b00827bb0b7 218 * complete. This function is called as part of the EMAC driver
AdamGreen 0:3b00827bb0b7 219 * initialization. Configuration of the PHY at startup is
AdamGreen 0:3b00827bb0b7 220 * controlled by setting up configuration defines in lpc_phy.h.
AdamGreen 0:3b00827bb0b7 221 *
AdamGreen 0:3b00827bb0b7 222 * \param[in] netif NETIF structure
AdamGreen 0:3b00827bb0b7 223 * \param[in] rmii If set, configures the PHY for RMII mode
AdamGreen 0:3b00827bb0b7 224 * \return ERR_OK if the setup was successful, otherwise ERR_TIMEOUT
AdamGreen 0:3b00827bb0b7 225 */
AdamGreen 0:3b00827bb0b7 226 err_t lpc_phy_init(struct netif *netif, int rmii)
AdamGreen 0:3b00827bb0b7 227 {
AdamGreen 0:3b00827bb0b7 228 u32_t tmp;
AdamGreen 0:3b00827bb0b7 229 s32_t i;
AdamGreen 0:3b00827bb0b7 230
AdamGreen 0:3b00827bb0b7 231 physts.phy_speed_100mbs = olddphysts.phy_speed_100mbs = 0;
AdamGreen 0:3b00827bb0b7 232 physts.phy_full_duplex = olddphysts.phy_full_duplex = 0;
AdamGreen 0:3b00827bb0b7 233 physts.phy_link_active = olddphysts.phy_link_active = 0;
AdamGreen 0:3b00827bb0b7 234 phyustate = 0;
AdamGreen 0:3b00827bb0b7 235
AdamGreen 0:3b00827bb0b7 236 /* Only first read and write are checked for failure */
AdamGreen 0:3b00827bb0b7 237 /* Put the DP83848C in reset mode and wait for completion */
AdamGreen 0:3b00827bb0b7 238 if (lpc_mii_write(DP8_BMCR_REG, DP8_RESET) != 0)
AdamGreen 0:3b00827bb0b7 239 return ERR_TIMEOUT;
AdamGreen 0:3b00827bb0b7 240 i = 400;
AdamGreen 0:3b00827bb0b7 241 while (i > 0) {
AdamGreen 0:3b00827bb0b7 242 osDelay(1); /* 1 ms */
AdamGreen 0:3b00827bb0b7 243 if (lpc_mii_read(DP8_BMCR_REG, &tmp) != 0)
AdamGreen 0:3b00827bb0b7 244 return ERR_TIMEOUT;
AdamGreen 0:3b00827bb0b7 245
AdamGreen 0:3b00827bb0b7 246 if (!(tmp & (DP8_RESET | DP8_POWER_DOWN)))
AdamGreen 0:3b00827bb0b7 247 i = -1;
AdamGreen 0:3b00827bb0b7 248 else
AdamGreen 0:3b00827bb0b7 249 i--;
AdamGreen 0:3b00827bb0b7 250 }
AdamGreen 0:3b00827bb0b7 251 /* Timeout? */
AdamGreen 0:3b00827bb0b7 252 if (i == 0)
AdamGreen 0:3b00827bb0b7 253 return ERR_TIMEOUT;
AdamGreen 0:3b00827bb0b7 254
AdamGreen 0:3b00827bb0b7 255 // read PHY ID
AdamGreen 0:3b00827bb0b7 256 lpc_mii_read(DP8_IDR1_REG, &tmp);
AdamGreen 0:3b00827bb0b7 257 phy_id = (tmp << 16);
AdamGreen 0:3b00827bb0b7 258 lpc_mii_read(DP8_IDR2_REG, &tmp);
AdamGreen 0:3b00827bb0b7 259 phy_id |= (tmp & 0XFFF0);
AdamGreen 0:3b00827bb0b7 260
AdamGreen 0:3b00827bb0b7 261 /* Setup link based on configuration options */
AdamGreen 0:3b00827bb0b7 262 #if PHY_USE_AUTONEG==1
AdamGreen 0:3b00827bb0b7 263 tmp = DP8_AUTONEG;
AdamGreen 0:3b00827bb0b7 264 #else
AdamGreen 0:3b00827bb0b7 265 tmp = 0;
AdamGreen 0:3b00827bb0b7 266 #endif
AdamGreen 0:3b00827bb0b7 267 #if PHY_USE_100MBS==1
AdamGreen 0:3b00827bb0b7 268 tmp |= DP8_SPEED_SELECT;
AdamGreen 0:3b00827bb0b7 269 #endif
AdamGreen 0:3b00827bb0b7 270 #if PHY_USE_FULL_DUPLEX==1
AdamGreen 0:3b00827bb0b7 271 tmp |= DP8_DUPLEX_MODE;
AdamGreen 0:3b00827bb0b7 272 #endif
AdamGreen 0:3b00827bb0b7 273 lpc_mii_write(DP8_BMCR_REG, tmp);
AdamGreen 0:3b00827bb0b7 274
AdamGreen 0:3b00827bb0b7 275 /* Enable RMII mode for PHY */
AdamGreen 0:3b00827bb0b7 276 if (rmii)
AdamGreen 0:3b00827bb0b7 277 lpc_mii_write(DP8_PHY_RBR_REG, DP8_RBR_RMII_MODE);
AdamGreen 0:3b00827bb0b7 278
AdamGreen 0:3b00827bb0b7 279 /* The link is not set active at this point, but will be detected
AdamGreen 0:3b00827bb0b7 280 later */
AdamGreen 0:3b00827bb0b7 281
AdamGreen 0:3b00827bb0b7 282 return ERR_OK;
AdamGreen 0:3b00827bb0b7 283 }
AdamGreen 0:3b00827bb0b7 284
AdamGreen 0:3b00827bb0b7 285 /* Phy status update state machine */
AdamGreen 0:3b00827bb0b7 286 s32_t lpc_phy_sts_sm(struct netif *netif)
AdamGreen 0:3b00827bb0b7 287 {
AdamGreen 0:3b00827bb0b7 288 s32_t changed = 0;
AdamGreen 0:3b00827bb0b7 289 u32_t data = 0;
AdamGreen 0:3b00827bb0b7 290 u32_t tmp;
AdamGreen 0:3b00827bb0b7 291
AdamGreen 0:3b00827bb0b7 292 switch (phyustate) {
AdamGreen 0:3b00827bb0b7 293 default:
AdamGreen 0:3b00827bb0b7 294 case 0:
AdamGreen 0:3b00827bb0b7 295 if (phy_id == DP83848C_ID) {
AdamGreen 0:3b00827bb0b7 296 lpc_mii_read_noblock(DP8_PHY_STAT_REG);
AdamGreen 0:3b00827bb0b7 297 phyustate = 2;
AdamGreen 0:3b00827bb0b7 298 }
AdamGreen 0:3b00827bb0b7 299 else if (phy_id == LAN8720_ID) {
AdamGreen 0:3b00827bb0b7 300 lpc_mii_read_noblock(DP8_PHY_SCSR_REG);
AdamGreen 0:3b00827bb0b7 301 phyustate = 1;
AdamGreen 0:3b00827bb0b7 302 }
AdamGreen 0:3b00827bb0b7 303 break;
AdamGreen 0:3b00827bb0b7 304
AdamGreen 0:3b00827bb0b7 305 case 1:
AdamGreen 0:3b00827bb0b7 306 if (phy_id == LAN8720_ID) {
AdamGreen 0:3b00827bb0b7 307 tmp = lpc_mii_read_data();
AdamGreen 0:3b00827bb0b7 308 // we get speed and duplex here.
AdamGreen 0:3b00827bb0b7 309 phy_lan7420_sts_tmp = (tmp & PHY_SCSR_DUPLEX) ? LNK_STAT_FULLDUPLEX : 0;
AdamGreen 0:3b00827bb0b7 310 phy_lan7420_sts_tmp |= (tmp & PHY_SCSR_100MBIT) ? 0 : LNK_STAT_SPEED10MPS;
AdamGreen 0:3b00827bb0b7 311
AdamGreen 0:3b00827bb0b7 312 //read the status register to get link status
AdamGreen 0:3b00827bb0b7 313 lpc_mii_read_noblock(DP8_BMSR_REG);
AdamGreen 0:3b00827bb0b7 314 phyustate = 2;
AdamGreen 0:3b00827bb0b7 315 }
AdamGreen 0:3b00827bb0b7 316 break;
AdamGreen 0:3b00827bb0b7 317
AdamGreen 0:3b00827bb0b7 318 case 2:
AdamGreen 0:3b00827bb0b7 319 /* Wait for read status state */
AdamGreen 0:3b00827bb0b7 320 if (!lpc_mii_is_busy()) {
AdamGreen 0:3b00827bb0b7 321 /* Update PHY status */
AdamGreen 0:3b00827bb0b7 322 tmp = lpc_mii_read_data();
AdamGreen 0:3b00827bb0b7 323
AdamGreen 0:3b00827bb0b7 324 if (phy_id == DP83848C_ID) {
AdamGreen 0:3b00827bb0b7 325 // STS register contains all needed status bits
AdamGreen 0:3b00827bb0b7 326 data = (tmp & DP8_VALID_LINK) ? LNK_STAT_VALID : 0;
AdamGreen 0:3b00827bb0b7 327 data |= (tmp & DP8_FULLDUPLEX) ? LNK_STAT_FULLDUPLEX : 0;
AdamGreen 0:3b00827bb0b7 328 data |= (tmp & DP8_SPEED10MBPS) ? LNK_STAT_SPEED10MPS : 0;
AdamGreen 0:3b00827bb0b7 329 }
AdamGreen 0:3b00827bb0b7 330 else if (phy_id == LAN8720_ID) {
AdamGreen 0:3b00827bb0b7 331 // we only get the link status here.
AdamGreen 0:3b00827bb0b7 332 phy_lan7420_sts_tmp |= (tmp & DP8_LINK_STATUS) ? LNK_STAT_VALID : 0;
AdamGreen 0:3b00827bb0b7 333 data = phy_lan7420_sts_tmp;
AdamGreen 0:3b00827bb0b7 334 }
AdamGreen 0:3b00827bb0b7 335
AdamGreen 0:3b00827bb0b7 336 changed = lpc_update_phy_sts(netif, data);
AdamGreen 0:3b00827bb0b7 337 phyustate = 0;
AdamGreen 0:3b00827bb0b7 338 }
AdamGreen 0:3b00827bb0b7 339 break;
AdamGreen 0:3b00827bb0b7 340 }
AdamGreen 0:3b00827bb0b7 341
AdamGreen 0:3b00827bb0b7 342 return changed;
AdamGreen 0:3b00827bb0b7 343 }
AdamGreen 0:3b00827bb0b7 344
AdamGreen 0:3b00827bb0b7 345 /**
AdamGreen 0:3b00827bb0b7 346 * @}
AdamGreen 0:3b00827bb0b7 347 */
AdamGreen 0:3b00827bb0b7 348
AdamGreen 0:3b00827bb0b7 349 /* --------------------------------- End Of File ------------------------------ */