summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/nand/nand_base.c10
-rw-r--r--drivers/pci_auto.c7
-rw-r--r--drivers/smc91111.c8
-rw-r--r--drivers/tsec.c99
-rw-r--r--drivers/tsec.h3
5 files changed, 115 insertions, 12 deletions
diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c
index 8495829..c6fee18 100644
--- a/drivers/nand/nand_base.c
+++ b/drivers/nand/nand_base.c
@@ -427,8 +427,9 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
struct nand_chip *this = mtd->priv;
u16 bad;
+ page = (int)(ofs >> this->page_shift) & this->pagemask;
+
if (getchip) {
- page = (int)(ofs >> this->page_shift);
chipnr = (int)(ofs >> this->chip_shift);
/* Grab the lock and see if the device is available */
@@ -436,18 +437,17 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
/* Select the NAND device */
this->select_chip(mtd, chipnr);
- } else
- page = (int) ofs;
+ }
if (this->options & NAND_BUSWIDTH_16) {
- this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
+ this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page);
bad = cpu_to_le16(this->read_word(mtd));
if (this->badblockpos & 0x1)
bad >>= 1;
if ((bad & 0xFF) != 0xff)
res = 1;
} else {
- this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask);
+ this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page);
if (this->read_byte(mtd) != 0xff)
res = 1;
}
diff --git a/drivers/pci_auto.c b/drivers/pci_auto.c
index 9691675..f170c2d 100644
--- a/drivers/pci_auto.c
+++ b/drivers/pci_auto.c
@@ -34,7 +34,12 @@
void pciauto_region_init(struct pci_region* res)
{
- res->bus_lower = res->bus_start;
+ /*
+ * Avoid allocating PCI resources from address 0 -- this is illegal
+ * according to PCI 2.1 and moreover, this is known to cause Linux IDE
+ * drivers to fail. Use a reasonable starting value of 0x1000 instead.
+ */
+ res->bus_lower = res->bus_start ? res->bus_start : 0x1000;
}
void pciauto_region_align(struct pci_region *res, unsigned long size)
diff --git a/drivers/smc91111.c b/drivers/smc91111.c
index f91e4b9..8061f12 100644
--- a/drivers/smc91111.c
+++ b/drivers/smc91111.c
@@ -1538,9 +1538,9 @@ int eth_send(volatile void *packet, int length) {
int smc_get_ethaddr (bd_t * bd)
{
int env_size, rom_valid, env_present = 0, reg;
- char *s = NULL, *e, *v_mac, es[] = "11:22:33:44:55:66";
+ char *s = NULL, *e, es[] = "11:22:33:44:55:66";
char s_env_mac[64];
- uchar v_env_mac[6], v_rom_mac[6];
+ uchar v_env_mac[6], v_rom_mac[6], *v_mac;
env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac));
if ((env_size > 0) && (env_size < sizeof (es))) { /* exit if env is bad */
@@ -1563,7 +1563,7 @@ int smc_get_ethaddr (bd_t * bd)
if (!env_present) { /* if NO env */
if (rom_valid) { /* but ROM is valid */
- v_mac = (char *)v_rom_mac;
+ v_mac = v_rom_mac;
sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X",
v_mac[0], v_mac[1], v_mac[2], v_mac[3],
v_mac[4], v_mac[5]);
@@ -1573,7 +1573,7 @@ int smc_get_ethaddr (bd_t * bd)
return (-1);
}
} else { /* good env, don't care ROM */
- v_mac = (char *)v_env_mac; /* always use a good env over a ROM */
+ v_mac = v_env_mac; /* always use a good env over a ROM */
}
if (env_present && rom_valid) { /* if both env and ROM are good */
diff --git a/drivers/tsec.c b/drivers/tsec.c
index 3f11eb0..b418773 100644
--- a/drivers/tsec.c
+++ b/drivers/tsec.c
@@ -5,7 +5,7 @@
* terms of the GNU Public License, Version 2, incorporated
* herein by reference.
*
- * Copyright 2004 Freescale Semiconductor.
+ * Copyright 2004, 2007 Freescale Semiconductor, Inc.
* (C) Copyright 2003, Motorola, Inc.
* author Andy Fleming
*
@@ -66,7 +66,11 @@ struct tsec_info_struct {
*/
static struct tsec_info_struct tsec_info[] = {
#if defined(CONFIG_MPC85XX_TSEC1) || defined(CONFIG_MPC83XX_TSEC1)
+#if defined(CONFIG_MPC8544DS)
+ {TSEC1_PHY_ADDR, TSEC_GIGABIT | TSEC_REDUCED, TSEC1_PHYIDX},
+#else
{TSEC1_PHY_ADDR, TSEC_GIGABIT, TSEC1_PHYIDX},
+#endif
#elif defined(CONFIG_MPC86XX_TSEC1)
{TSEC1_PHY_ADDR, TSEC_GIGABIT | TSEC_REDUCED, TSEC1_PHYIDX},
#else
@@ -381,6 +385,76 @@ uint mii_parse_sr(uint mii_reg, struct tsec_private * priv)
return 0;
}
+/* Generic function which updates the speed and duplex. If
+ * autonegotiation is enabled, it uses the AND of the link
+ * partner's advertised capabilities and our advertised
+ * capabilities. If autonegotiation is disabled, we use the
+ * appropriate bits in the control register.
+ *
+ * Stolen from Linux's mii.c and phy_device.c
+ */
+uint mii_parse_link(uint mii_reg, struct tsec_private *priv)
+{
+ /* We're using autonegotiation */
+ if (mii_reg & PHY_BMSR_AUTN_ABLE) {
+ uint lpa = 0;
+ uint gblpa = 0;
+
+ /* Check for gigabit capability */
+ if (mii_reg & PHY_BMSR_EXT) {
+ /* We want a list of states supported by
+ * both PHYs in the link
+ */
+ gblpa = read_phy_reg(priv, PHY_1000BTSR);
+ gblpa &= read_phy_reg(priv, PHY_1000BTCR) << 2;
+ }
+
+ /* Set the baseline so we only have to set them
+ * if they're different
+ */
+ priv->speed = 10;
+ priv->duplexity = 0;
+
+ /* Check the gigabit fields */
+ if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
+ priv->speed = 1000;
+
+ if (gblpa & PHY_1000BTSR_1000FD)
+ priv->duplexity = 1;
+
+ /* We're done! */
+ return 0;
+ }
+
+ lpa = read_phy_reg(priv, PHY_ANAR);
+ lpa &= read_phy_reg(priv, PHY_ANLPAR);
+
+ if (lpa & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) {
+ priv->speed = 100;
+
+ if (lpa & PHY_ANLPAR_TXFD)
+ priv->duplexity = 1;
+
+ } else if (lpa & PHY_ANLPAR_10FD)
+ priv->duplexity = 1;
+ } else {
+ uint bmcr = read_phy_reg(priv, PHY_BMCR);
+
+ priv->speed = 10;
+ priv->duplexity = 0;
+
+ if (bmcr & PHY_BMCR_DPLX)
+ priv->duplexity = 1;
+
+ if (bmcr & PHY_BMCR_1000_MBPS)
+ priv->speed = 1000;
+ else if (bmcr & PHY_BMCR_100_MBPS)
+ priv->speed = 100;
+ }
+
+ return 0;
+}
+
/*
* Parse the BCM54xx status register for speed and duplex information.
* The linux sungem_phy has this information, but in a table format.
@@ -718,6 +792,7 @@ static void startup_tsec(struct eth_device *dev)
/* Start up the PHY */
if(priv->phyinfo)
phy_run_commands(priv, priv->phyinfo->startup);
+
adjust_link(dev);
/* Enable Transmit and Receive */
@@ -1088,6 +1163,27 @@ struct phy_info phy_info_dm9161 = {
{miim_end,}
},
};
+/* a generic flavor. */
+struct phy_info phy_info_generic = {
+ 0,
+ "Unknown/Generic PHY",
+ 32,
+ (struct phy_cmd[]) { /* config */
+ {PHY_BMCR, PHY_BMCR_RESET, NULL},
+ {PHY_BMCR, PHY_BMCR_AUTON|PHY_BMCR_RST_NEG, NULL},
+ {miim_end,}
+ },
+ (struct phy_cmd[]) { /* startup */
+ {PHY_BMSR, miim_read, NULL},
+ {PHY_BMSR, miim_read, &mii_parse_sr},
+ {PHY_BMSR, miim_read, &mii_parse_link},
+ {miim_end,}
+ },
+ (struct phy_cmd[]) { /* shutdown */
+ {miim_end,}
+ }
+};
+
uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv)
{
@@ -1203,6 +1299,7 @@ struct phy_info *phy_info[] = {
&phy_info_lxt971,
&phy_info_VSC8244,
&phy_info_dp83865,
+ &phy_info_generic,
NULL
};
diff --git a/drivers/tsec.h b/drivers/tsec.h
index 422bc66..7bf3dee 100644
--- a/drivers/tsec.h
+++ b/drivers/tsec.h
@@ -7,7 +7,7 @@
* terms of the GNU Public License, Version 2, incorporated
* herein by reference.
*
- * Copyright 2004 Freescale Semiconductor.
+ * Copyright 2004, 2007 Freescale Semiconductor, Inc.
* (C) Copyright 2003, Motorola, Inc.
* maintained by Xianghua Xiao (x.xiao@motorola.com)
* author Andy Fleming
@@ -65,6 +65,7 @@
#define ECNTRL_INIT_SETTINGS 0x00001000
#define ECNTRL_TBI_MODE 0x00000020
#define ECNTRL_R100 0x00000008
+#define ECNTRL_SGMII_MODE 0x00000002
#define miim_end -2
#define miim_read -1