ifup() is partially complete
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3103 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
451bfc3f93
commit
e5e5d8f404
@ -107,20 +107,83 @@
|
|||||||
/* Select PHY-specific values. Add more PHYs as needed. */
|
/* Select PHY-specific values. Add more PHYs as needed. */
|
||||||
|
|
||||||
#ifdef CONFIG_PHY_KS8721
|
#ifdef CONFIG_PHY_KS8721
|
||||||
# define LPC17_PHYNAME "KS8721"
|
# define LPC17_PHYNAME "KS8721"
|
||||||
# define LPC17_PHYID1 MII_PHYID1_KS8721
|
# define LPC17_PHYID1 MII_PHYID1_KS8721
|
||||||
# define LPC17_PHYID2 MII_PHYID2_KS8721
|
# define LPC17_PHYID2 MII_PHYID2_KS8721
|
||||||
# define LPC17_HAVE_PHY 1
|
# define LPC17_HAVE_PHY 1
|
||||||
#else
|
#else
|
||||||
# warning "No PHY specified!"
|
# warning "No PHY specified!"
|
||||||
# undef LPC17_HAVE_PHY
|
# undef LPC17_HAVE_PHY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MII_BIG_TIMEOUT 666666
|
#define MII_BIG_TIMEOUT 666666
|
||||||
|
|
||||||
|
/* These definitions are used to remember the speed/duplex settings */
|
||||||
|
|
||||||
|
#define LPC17_SPEED_MASK 0x01
|
||||||
|
#define LPC17_SPEED_100 0x01
|
||||||
|
#define LPC17_SPEED_10 0x00
|
||||||
|
|
||||||
|
#define LPC17_DUPLEX_MASK 0x02
|
||||||
|
#define LPC17_DUPLEX_FULL 0x02
|
||||||
|
#define LPC17_DUPLEX_HALF 0x00
|
||||||
|
|
||||||
|
#define LPC17_10BASET_HD (LPC17_SPEED_10 | LPC17_DUPLEX_HALF)
|
||||||
|
#define LPC17_10BASET_FD (LPC17_SPEED_10 | LPC17_DUPLEX_FULL)
|
||||||
|
#define LPC17_100BASET_HD (LPC17_SPEED_100 | LPC17_DUPLEX_HALF)
|
||||||
|
#define LPC17_100BASET_FD (LPC17_SPEED_100 | LPC17_DUPLEX_FULL)
|
||||||
|
|
||||||
|
#ifdef CONFIG_PHY_SPEED100
|
||||||
|
# ifdef CONFIG_PHY_FDUPLEX
|
||||||
|
# define LPC17_MODE_DEFLT LPC17_100BASET_FD
|
||||||
|
# else
|
||||||
|
# define LPC17_MODE_DEFLT LPC17_100BASET_HD
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifdef CONFIG_PHY_FDUPLEX
|
||||||
|
# define LPC17_MODE_DEFLT LPC17_10BASET_FD
|
||||||
|
# else
|
||||||
|
# define LPC17_MODE_DEFLT LPC17_10BASET_HD
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This is the number of ethernet GPIO pins that must be configured */
|
/* This is the number of ethernet GPIO pins that must be configured */
|
||||||
|
|
||||||
#define GPIO_NENET_PINS 10
|
#define GPIO_NENET_PINS 10
|
||||||
|
|
||||||
|
/* EMAC DMA RAM and descriptor definitions.
|
||||||
|
*
|
||||||
|
* All of AHB SRAM, Bank 0 is set aside for EMAC Tx and Rx descriptors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LPC17_BANK0_SIZE 0x00004000
|
||||||
|
#warning "Need to exclude bank0 from the heap"
|
||||||
|
|
||||||
|
/* Numbers of descriptors and sizes of descriptor and status regions */
|
||||||
|
|
||||||
|
#ifdef CONFIG_ETH_NTXDESC
|
||||||
|
# define CONFIG_ETH_NTXDESC 16
|
||||||
|
#endif
|
||||||
|
#define LPC17_TXDESC_SIZE (8*CONFIG_ETH_NTXDESC)
|
||||||
|
#define LPC17_TXSTAT_SIZE (4*CONFIG_ETH_NTXDESC)
|
||||||
|
|
||||||
|
#ifdef CONFIG_ETH_NRXDESC
|
||||||
|
# define CONFIG_ETH_NRXDESC 16
|
||||||
|
#endif
|
||||||
|
#define LPC17_RXDESC_SIZE (8*CONFIG_ETH_NRXDESC)
|
||||||
|
#define LPC17_RXSTAT_SIZE (8*CONFIG_ETH_NRXDESC)
|
||||||
|
|
||||||
|
/* Descriptor Memory Organization. Descriptors are packed
|
||||||
|
* at the end of AHB SRAM, Bank 0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LPC17_DESC_SIZE (LPC17_TXDESC_SIZE+LPC17_RXDESC_SIZE+LPC17_TXSTAT_SIZE+LPC17_RXSTAT_SIZE)
|
||||||
|
#define LPC17_DESC_BASE (LPC17_SRAM_BANK0+LPC17_BANK0_SIZE-LPC17_DESC_SIZE)
|
||||||
|
|
||||||
|
#define LPC17_TXDESC_BASE LPC17_DESC_BASE
|
||||||
|
#define LPC17_TXSTAT_BASE (LPC17_TXDESC_BASE+LPC17_TXDESC_SIZE)
|
||||||
|
#define LPC17_RXDESC_BASE (LPC17_TXSTAT_BASE+LPC17_TXSTAT_SIZE)
|
||||||
|
#define LPC17_RXSTAT_BASE (LPC17_RXDESC_BASE + LPC17_RXDESC_SIZE)
|
||||||
|
|
||||||
/* Register debug */
|
/* Register debug */
|
||||||
|
|
||||||
@ -148,8 +211,7 @@ struct lpc17_driver_s
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool lp_ifup; /* true:ifup false:ifdown */
|
bool lp_ifup; /* true:ifup false:ifdown */
|
||||||
bool lp_speed100; /* true:100Mbps false:10Mbps */
|
bool lp_mode; /* speed/duplex */
|
||||||
bool lp_fullduplex; /* true:full duplex false:half duplex */
|
|
||||||
#ifdef LPC17_HAVE_PHY
|
#ifdef LPC17_HAVE_PHY
|
||||||
uint8_t lp_phyaddr; /* PHY device address */
|
uint8_t lp_phyaddr; /* PHY device address */
|
||||||
#endif
|
#endif
|
||||||
@ -248,15 +310,15 @@ static inline int lpc17_phyreset(uint8_t phyaddr);
|
|||||||
# ifdef CONFIG_PHY_AUTONEG
|
# ifdef CONFIG_PHY_AUTONEG
|
||||||
static inline int lpc17_phyautoneg(uint8_t phyaddr);
|
static inline int lpc17_phyautoneg(uint8_t phyaddr);
|
||||||
# endif
|
# endif
|
||||||
static int lpc17_phyfixed(uint8_t phyaddr, bool speed100, bool fullduplex);
|
static int lpc17_phymode(uint8_t phyaddr, uint8_t mode);
|
||||||
static void lpc17_phyduplex(uint8_t phyaddr, bool fullduplex);
|
|
||||||
static inline int lpc17_phyinit(struct lpc17_driver_s *priv);
|
static inline int lpc17_phyinit(struct lpc17_driver_s *priv);
|
||||||
#else
|
#else
|
||||||
# define lpc17_phyinit()
|
# define lpc17_phyinit(priv)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* EMAC Initialization functions */
|
/* EMAC Initialization functions */
|
||||||
|
|
||||||
|
static void lpc17_macmode(uint8_t mode);
|
||||||
static void lpc17_ethreset(struct lpc17_driver_s *priv);
|
static void lpc17_ethreset(struct lpc17_driver_s *priv);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -274,7 +336,7 @@ static void lpc17_ethreset(struct lpc17_driver_s *priv);
|
|||||||
#ifdef CONFIG_LPC17_ENET_REGDEBUG
|
#ifdef CONFIG_LPC17_ENET_REGDEBUG
|
||||||
static void lpc17_printreg(uint32_t addr, uint32_t val, bool iswrite)
|
static void lpc17_printreg(uint32_t addr, uint32_t val, bool iswrite)
|
||||||
{
|
{
|
||||||
lldbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val);
|
dbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -324,7 +386,7 @@ static void lpc17_checkreg(uint32_t addr, uint32_t val, bool iswrite)
|
|||||||
{
|
{
|
||||||
/* No.. More than one. */
|
/* No.. More than one. */
|
||||||
|
|
||||||
lldbg("[repeats %d more times]\n", count);
|
dbg("[repeats %d more times]\n", count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,12 +757,24 @@ static int lpc17_ifup(struct uip_driver_s *dev)
|
|||||||
{
|
{
|
||||||
FAR struct lpc17_driver_s *priv = (FAR struct lpc17_driver_s *)dev->d_private;
|
FAR struct lpc17_driver_s *priv = (FAR struct lpc17_driver_s *)dev->d_private;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
int ret;
|
||||||
|
|
||||||
ndbg("Bringing up: %d.%d.%d.%d\n",
|
ndbg("Bringing up: %d.%d.%d.%d\n",
|
||||||
dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
|
dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
|
||||||
(dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
|
(dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
|
||||||
|
|
||||||
/* Initilize Ethernet interface */
|
/* Reset the Ethernet controller (again) */
|
||||||
|
|
||||||
|
lpc17_ethreset(priv);
|
||||||
|
|
||||||
|
/* Initialize the PHY and wait for the link to be established */
|
||||||
|
|
||||||
|
ret = lpc17_phyinit(priv);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
ndbg("lpc17_phyinit failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure the MAC station address */
|
/* Configure the MAC station address */
|
||||||
|
|
||||||
@ -716,6 +790,16 @@ static int lpc17_ifup(struct uip_driver_s *dev)
|
|||||||
(uint32_t)priv->lp_dev.d_mac.ether_addr_octet[4];
|
(uint32_t)priv->lp_dev.d_mac.ether_addr_octet[4];
|
||||||
lpc17_putreg(regval, LPC17_ETH_SA2);
|
lpc17_putreg(regval, LPC17_ETH_SA2);
|
||||||
|
|
||||||
|
/* Initialize Ethernet interface for the PHY setup */
|
||||||
|
|
||||||
|
lpc17_macmode(priv->lp_mode);
|
||||||
|
|
||||||
|
/* Initialize EMAC DMA memory */
|
||||||
|
|
||||||
|
/* Set up RX filter and configure to accept broadcast address and perfect
|
||||||
|
* station address matches.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Set and activate a timer process */
|
/* Set and activate a timer process */
|
||||||
|
|
||||||
(void)wd_start(priv->lp_txpoll, LPC17_WDDELAY, lpc17_polltimer, 1, (uint32_t)priv);
|
(void)wd_start(priv->lp_txpoll, LPC17_WDDELAY, lpc17_polltimer, 1, (uint32_t)priv);
|
||||||
@ -760,6 +844,7 @@ static int lpc17_ifdown(struct uip_driver_s *dev)
|
|||||||
|
|
||||||
/* Reset the device */
|
/* Reset the device */
|
||||||
|
|
||||||
|
lpc17_ethreset(priv);
|
||||||
priv->lp_ifup = false;
|
priv->lp_ifup = false;
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
return OK;
|
return OK;
|
||||||
@ -908,14 +993,14 @@ static void lpc17_showpins(void)
|
|||||||
#if defined(CONFIG_LPC17_ENET_REGDEBUG) && defined(LPC17_HAVE_PHY)
|
#if defined(CONFIG_LPC17_ENET_REGDEBUG) && defined(LPC17_HAVE_PHY)
|
||||||
static void lpc17_showmii(uint8_t phyaddr, const char *msg)
|
static void lpc17_showmii(uint8_t phyaddr, const char *msg)
|
||||||
{
|
{
|
||||||
lldbg("PHY " LPC17_PHYNAME ": %s\n", msg);
|
dbg("PHY " LPC17_PHYNAME ": %s\n", msg);
|
||||||
lldbg(" MCR: %04x\n", lpc17_getreg(MII_MCR));
|
dbg(" MCR: %04x\n", lpc17_getreg(MII_MCR));
|
||||||
lldbg(" MSR: %04x\n", lpc17_getreg(MII_MSR));
|
dbg(" MSR: %04x\n", lpc17_getreg(MII_MSR));
|
||||||
lldbg(" ADVERTISE: %04x\n", lpc17_getreg(MII_ADVERTISE));
|
dbg(" ADVERTISE: %04x\n", lpc17_getreg(MII_ADVERTISE));
|
||||||
lldbg(" LPA: %04x\n", lpc17_getreg(MII_LPA));
|
dbg(" LPA: %04x\n", lpc17_getreg(MII_LPA));
|
||||||
lldbg(" EXPANSION: %04x\n", lpc17_getreg(MII_EXPANSION));
|
dbg(" EXPANSION: %04x\n", lpc17_getreg(MII_EXPANSION));
|
||||||
#ifdef CONFIG_PHY_KS8721
|
#ifdef CONFIG_PHY_KS8721
|
||||||
lldbg(" 10BTCR: %04x\n", lpc17_getreg(MII_KS8721_10BTCR));
|
dbg(" 10BTCR: %04x\n", lpc17_getreg(MII_KS8721_10BTCR));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1051,7 +1136,7 @@ static inline int lpc17_phyreset(uint8_t phyaddr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nlldbg("Reset failed. MCR: %04x\n", phyreg);
|
ndbg("Reset failed. MCR: %04x\n", phyreg);
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1099,19 +1184,20 @@ static inline int lpc17_phyautoneg(uint8_t phyaddr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nlldbg("Auto-negotiation failed. MSR: %04x\n", phyreg);
|
ndbg("Auto-negotiation failed. MSR: %04x\n", phyreg);
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: lpc17_phyfixed
|
* Function: lpc17_phymode
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Set fixed PHY configuration.
|
* Set the PHY to operate at a selected speed/duplex mode.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* phyaddr - The device address where the PHY was discovered
|
* phyaddr - The device address where the PHY was discovered
|
||||||
|
* mode - speed/duplex mode
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@ -1121,7 +1207,7 @@ static inline int lpc17_phyautoneg(uint8_t phyaddr)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef LPC17_HAVE_PHY
|
#ifdef LPC17_HAVE_PHY
|
||||||
static int lpc17_phyfixed(uint8_t phyaddr, bool speed100, bool fullduplex)
|
static int lpc17_phymode(uint8_t phyaddr, uint8_t mode)
|
||||||
{
|
{
|
||||||
int32_t timeout;
|
int32_t timeout;
|
||||||
uint16_t phyreg;
|
uint16_t phyreg;
|
||||||
@ -1129,12 +1215,12 @@ static int lpc17_phyfixed(uint8_t phyaddr, bool speed100, bool fullduplex)
|
|||||||
/* Disable auto-negotiation and set fixed Speed and Duplex settings */
|
/* Disable auto-negotiation and set fixed Speed and Duplex settings */
|
||||||
|
|
||||||
phyreg = 0;
|
phyreg = 0;
|
||||||
if (speed100)
|
if ((mode & LPC17_SPEED_MASK) == LPC17_SPEED_100)
|
||||||
{
|
{
|
||||||
phyreg = MII_MCR_SPEED100;
|
phyreg = MII_MCR_SPEED100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullduplex)
|
if ((mode & LPC17_DUPLEX_MASK) == LPC17_DUPLEX_FULL)
|
||||||
{
|
{
|
||||||
phyreg |= MII_MCR_FULLDPLX;
|
phyreg |= MII_MCR_FULLDPLX;
|
||||||
}
|
}
|
||||||
@ -1154,72 +1240,11 @@ static int lpc17_phyfixed(uint8_t phyaddr, bool speed100, bool fullduplex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nlldbg("Link failed. MSR: %04x\n", phyreg);
|
ndbg("Link failed. MSR: %04x\n", phyreg);
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Function: lpc17_phyfulldplex
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Tweak a few things for full/half duplex.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* phyaddr - The device address where the PHY was discovered
|
|
||||||
* fullduplex - TRUE: full duplex
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef LPC17_HAVE_PHY
|
|
||||||
static void lpc17_phyduplex(uint8_t phyaddr, bool fullduplex)
|
|
||||||
{
|
|
||||||
uint32_t regval;
|
|
||||||
|
|
||||||
if (fullduplex)
|
|
||||||
{
|
|
||||||
/* Set the inter-packet gap */
|
|
||||||
|
|
||||||
lpc17_putreg(21, LPC17_ETH_IPGT);
|
|
||||||
|
|
||||||
/* Set MAC to operate in full duplex mode */
|
|
||||||
|
|
||||||
regval = lpc17_getreg(LPC17_ETH_MAC2);
|
|
||||||
regval |= ETH_MAC2_FD;
|
|
||||||
lpc17_putreg(regval, LPC17_ETH_MAC2);
|
|
||||||
|
|
||||||
/* Select full duplex operation for ethernet controller */
|
|
||||||
|
|
||||||
regval = lpc17_getreg(LPC17_ETH_CMD);
|
|
||||||
regval |= ETH_CMD_FD;
|
|
||||||
lpc17_putreg(regval, LPC17_ETH_CMD);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set the inter-packet gap */
|
|
||||||
|
|
||||||
lpc17_putreg(18, LPC17_ETH_IPGT);
|
|
||||||
|
|
||||||
/* Set MAC to operate in half duplex mode */
|
|
||||||
|
|
||||||
regval = lpc17_getreg(LPC17_ETH_MAC2);
|
|
||||||
regval &= ~ETH_MAC2_FD;
|
|
||||||
lpc17_putreg(regval, LPC17_ETH_MAC2);
|
|
||||||
|
|
||||||
/* Select half duplex operation for ethernet controller */
|
|
||||||
|
|
||||||
regval = lpc17_getreg(LPC17_ETH_CMD);
|
|
||||||
regval &= ~ETH_CMD_FD;
|
|
||||||
lpc17_putreg(regval, LPC17_ETH_CMD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: lpc17_phyinit
|
* Function: lpc17_phyinit
|
||||||
*
|
*
|
||||||
@ -1230,7 +1255,9 @@ static void lpc17_phyduplex(uint8_t phyaddr, bool fullduplex)
|
|||||||
* priv - Pointer to EMAC device driver structure
|
* priv - Pointer to EMAC device driver structure
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None directory.
|
||||||
|
* As a side-effect, it will initialize priv->lp_phyaddr and
|
||||||
|
* priv->lp_phymode.
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
*
|
*
|
||||||
@ -1277,7 +1304,7 @@ static inline int lpc17_phyinit(struct lpc17_driver_s *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nlldbg("phyaddr: %d\n", phyaddr);
|
nvdbg("phyaddr: %d\n", phyaddr);
|
||||||
|
|
||||||
/* Check if the PHY device address was found */
|
/* Check if the PHY device address was found */
|
||||||
|
|
||||||
@ -1333,19 +1360,7 @@ static inline int lpc17_phyinit(struct lpc17_driver_s *priv)
|
|||||||
#else
|
#else
|
||||||
/* Set up the fixed PHY configuration */
|
/* Set up the fixed PHY configuration */
|
||||||
|
|
||||||
#ifdef CONFIG_PHY_SPEED100
|
ret = lpc17_phymode(phyaddr, LPC17_MODE_DEFLT);
|
||||||
priv->lp_speed100 = true;
|
|
||||||
#else
|
|
||||||
priv->lp_speed100 = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_PHY_FDUPLEX
|
|
||||||
priv->lp_fullduplex = true;
|
|
||||||
#else
|
|
||||||
priv->lp_fullduplex = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = lpc17_phyfixed(phyaddr, priv->lp_speed100, priv->lp_fullduplex);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
return ret;
|
return ret;
|
||||||
@ -1364,42 +1379,119 @@ static inline int lpc17_phyinit(struct lpc17_driver_s *priv)
|
|||||||
switch (phyreg & KS8721_10BTCR_MODE_MASK)
|
switch (phyreg & KS8721_10BTCR_MODE_MASK)
|
||||||
{
|
{
|
||||||
case KS8721_10BTCR_MODE_10BTHD: /* 10BASE-T half duplex */
|
case KS8721_10BTCR_MODE_10BTHD: /* 10BASE-T half duplex */
|
||||||
priv->lp_fullduplex = false;
|
priv->lp_mode = LPC17_10BASET_HD;
|
||||||
priv->lp_speed100 = false;
|
|
||||||
lpc17_putreg(0, LPC17_ETH_SUPP);
|
lpc17_putreg(0, LPC17_ETH_SUPP);
|
||||||
break;
|
break;
|
||||||
case KS8721_10BTCR_MODE_100BTHD: /* 100BASE-T half duplex */
|
case KS8721_10BTCR_MODE_100BTHD: /* 100BASE-T half duplex */
|
||||||
priv->lp_fullduplex = false;
|
priv->lp_mode = LPC17_100BASET_HD;
|
||||||
priv->lp_speed100 = true;
|
|
||||||
break;
|
break;
|
||||||
case KS8721_10BTCR_MODE_10BTFD: /* 10BASE-T full duplex */
|
case KS8721_10BTCR_MODE_10BTFD: /* 10BASE-T full duplex */
|
||||||
priv->lp_fullduplex = true;
|
priv->lp_mode = LPC17_10BASET_FD;
|
||||||
priv->lp_speed100 = false;
|
|
||||||
lpc17_putreg(0, LPC17_ETH_SUPP);
|
lpc17_putreg(0, LPC17_ETH_SUPP);
|
||||||
break;
|
break;
|
||||||
case KS8721_10BTCR_MODE_100BTFD: /* 100BASE-T full duplex */
|
case KS8721_10BTCR_MODE_100BTFD: /* 100BASE-T full duplex */
|
||||||
priv->lp_fullduplex = true;
|
priv->lp_mode = LPC17_100BASET_FD;
|
||||||
priv->lp_speed100 = true;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
lldbg("Unrecognized mode: %04x\n", phyreg);
|
dbg("Unrecognized mode: %04x\n", phyreg);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# warning "PHY Unknown: speed and duplex are bogus"
|
# warning "PHY Unknown: speed and duplex are bogus"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nlldbg("%dBase-T %s duplex\n",
|
ndbg("%dBase-T %s duplex\n",
|
||||||
priv->lp_speed100 ? 10 : 100,
|
priv->lp_mode & LPC17_SPEED_MASK == LPC17_SPEED_100 ? 100 : 10,
|
||||||
priv->lp_fullduplex ? "full" : "half");
|
priv->lp_mode & LPC17_DUPLEX_MASK == LPC17_DUPLEX_FULL ?"full" : "half");
|
||||||
|
|
||||||
/* Configure the MAC for this speed */
|
/* Disable auto-configuration. Set the fixed speed/duplex mode.
|
||||||
|
* (probably more than little redundant).
|
||||||
|
*/
|
||||||
|
|
||||||
lpc17_phyduplex(phyaddr, priv->lp_fullduplex);
|
ret = lpc17_phymode(phyaddr, LPC17_MODE_DEFLT);
|
||||||
lpc17_phyfixed(phyaddr, priv->lp_speed100, priv->lp_fullduplex);
|
lpc17_showmii(phyaddr, "After final configuration");
|
||||||
lpc17_showmii(phyaddr, "At completion");
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return OK;
|
/****************************************************************************
|
||||||
|
* Function: lpc17_macmode
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set the MAC to operate at a selected speed/duplex mode.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* mode - speed/duplex mode
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef LPC17_HAVE_PHY
|
||||||
|
static void lpc17_macmode(uint8_t mode)
|
||||||
|
{
|
||||||
|
uint32_t regval;
|
||||||
|
|
||||||
|
/* Set up for full or half duplex operation */
|
||||||
|
|
||||||
|
if ((mode & LPC17_DUPLEX_MASK) == LPC17_DUPLEX_FULL)
|
||||||
|
{
|
||||||
|
/* Set the back-to-back inter-packet gap */
|
||||||
|
|
||||||
|
lpc17_putreg(21, LPC17_ETH_IPGT);
|
||||||
|
|
||||||
|
/* Set MAC to operate in full duplex mode with CRC and Pad enabled */
|
||||||
|
|
||||||
|
regval = lpc17_getreg(LPC17_ETH_MAC2);
|
||||||
|
regval |= (ETH_MAC2_FD | ETH_MAC2_CRCEN | ETH_MAC2_PADCRCEN);
|
||||||
|
lpc17_putreg(regval, LPC17_ETH_MAC2);
|
||||||
|
|
||||||
|
/* Select full duplex operation for ethernet controller */
|
||||||
|
|
||||||
|
regval = lpc17_getreg(LPC17_ETH_CMD);
|
||||||
|
regval |= (ETH_CMD_FD | ETH_CMD_RMII | ETH_CMD_PRFRAME);
|
||||||
|
lpc17_putreg(regval, LPC17_ETH_CMD);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Set the back-to-back inter-packet gap */
|
||||||
|
|
||||||
|
lpc17_putreg(18, LPC17_ETH_IPGT);
|
||||||
|
|
||||||
|
/* Set MAC to operate in half duplex mode with CRC and Pad enabled */
|
||||||
|
|
||||||
|
regval = lpc17_getreg(LPC17_ETH_MAC2);
|
||||||
|
regval &= ~ETH_MAC2_FD;
|
||||||
|
regval |= (ETH_MAC2_CRCEN | ETH_MAC2_PADCRCEN);
|
||||||
|
lpc17_putreg(regval, LPC17_ETH_MAC2);
|
||||||
|
|
||||||
|
/* Select half duplex operation for ethernet controller */
|
||||||
|
|
||||||
|
regval = lpc17_getreg(LPC17_ETH_CMD);
|
||||||
|
regval &= ~ETH_CMD_FD;
|
||||||
|
regval |= (ETH_CMD_RMII | ETH_CMD_PRFRAME);
|
||||||
|
lpc17_putreg(regval, LPC17_ETH_CMD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is currently done in lpc17_phyinit(). That doesn't
|
||||||
|
* seem like the right place. It should be done here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
regval = lpc17_getreg(LPC17_ETH_SUPP);
|
||||||
|
if ((mode & LPC17_SPEED_MASK) == LPC17_SPEED_100)
|
||||||
|
{
|
||||||
|
regval |= ETH_SUPP_SPEED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regval &= ~ETH_SUPP_SPEED;
|
||||||
|
}
|
||||||
|
lpc17_putreg(regval, LPC17_ETH_SUPP);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1422,28 +1514,51 @@ static inline int lpc17_phyinit(struct lpc17_driver_s *priv)
|
|||||||
static void lpc17_ethreset(struct lpc17_driver_s *priv)
|
static void lpc17_ethreset(struct lpc17_driver_s *priv)
|
||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
uint32_t regval;
|
|
||||||
|
|
||||||
#if LPC17_NETHCONTROLLERS > 1
|
/* Reset the MAC */
|
||||||
# error "If multiple interfaces are supported, this function would have to be redesigned"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Make sure that clocking is enabled for the Ethernet (and PHY) peripherals */
|
flags = irqsave();
|
||||||
|
|
||||||
flags = irqsave();
|
/* Put the MAC into the reset state */
|
||||||
|
|
||||||
/* Put the Ethernet controller into the reset state */
|
lpc17_putreg((ETH_MAC1_TXRST | ETH_MAC1_MCSTXRST |ETH_MAC1_RXRST |
|
||||||
|
ETH_MAC1_MCSRXRST | ETH_MAC1_SIMRST | ETH_MAC1_SOFTRST),
|
||||||
|
LPC17_ETH_MAC1);
|
||||||
|
|
||||||
/* Wait just a bit. This is a much longer delay than necessary */
|
/* Disable RX/RX, clear modes, reset all control registers */
|
||||||
|
|
||||||
up_mdelay(2);
|
lpc17_putreg((ETH_CMD_REGRST | ETH_CMD_TXRST | ETH_CMD_RXRST),
|
||||||
|
LPC17_ETH_CMD);
|
||||||
|
|
||||||
/* Then take the Ethernet controller out of the reset state */
|
/* Take the MAC out of the reset state */
|
||||||
|
|
||||||
|
up_udelay(50);
|
||||||
|
lpc17_putreg(0, LPC17_ETH_MAC1);
|
||||||
|
|
||||||
|
/* The RMII bit must be set on initialization (I'm not sure
|
||||||
|
* this needs to be done here but... oh well.
|
||||||
|
*/
|
||||||
|
|
||||||
|
lpc17_putreg(ETH_CMD_RMII, LPC17_ETH_CMD);
|
||||||
|
|
||||||
|
/* Set other misc configuration-related registers to default values */
|
||||||
|
|
||||||
|
lpc17_putreg(0, LPC17_ETH_MAC2);
|
||||||
|
lpc17_putreg(0, LPC17_ETH_SUPP);
|
||||||
|
lpc17_putreg(0, LPC17_ETH_TEST);
|
||||||
|
|
||||||
|
lpc17_putreg(18, LPC17_ETH_IPGR);
|
||||||
|
lpc17_putreg(((15 << ETH_CLRT_RMAX_SHIFT) | (55 << ETH_CLRT_COLWIN_SHIFT)),
|
||||||
|
LPC17_ETH_CLRT);
|
||||||
|
lpc17_putreg(0x0600, LPC17_ETH_MAXF);
|
||||||
|
|
||||||
/* Disable all Ethernet controller interrupts */
|
/* Disable all Ethernet controller interrupts */
|
||||||
|
|
||||||
|
lpc17_putreg(0, LPC17_ETH_INTEN);
|
||||||
|
|
||||||
/* Clear any pending interrupts (shouldn't be any) */
|
/* Clear any pending interrupts (shouldn't be any) */
|
||||||
|
|
||||||
|
lpc17_putreg(0xffffffff, LPC17_ETH_INTCLR);
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1518,12 +1633,11 @@ static inline int lpc17_ethinitialize(int intf)
|
|||||||
priv->lp_txpoll = wd_create(); /* Create periodic poll timer */
|
priv->lp_txpoll = wd_create(); /* Create periodic poll timer */
|
||||||
priv->lp_txtimeout = wd_create(); /* Create TX timeout timer */
|
priv->lp_txtimeout = wd_create(); /* Create TX timeout timer */
|
||||||
|
|
||||||
/* Perform minimal, one-time initialization -- just reset the controller and
|
/* Reset the Ethernet controller and leave in the ifdown statue. The
|
||||||
* leave it disabled. The Ethernet controller will be reset and properly
|
* Ethernet controller will be properly re-initialized each time
|
||||||
* re-initialized each time lpc17_ifup() is called.
|
* lpc17_ifup() is called.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
lpc17_ethreset(priv);
|
|
||||||
lpc17_ifdown(&priv->lp_dev);
|
lpc17_ifdown(&priv->lp_dev);
|
||||||
|
|
||||||
/* Attach the IRQ to the driver */
|
/* Attach the IRQ to the driver */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user