Newer
Older
regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
/* Tell the DMA it is clear to go */
regs->dmactrl |= DMACTRL_INIT_SETTINGS;
regs->tstat = TSTAT_CLEAR_THALT;
regs->rstat = RSTAT_CLEAR_RHALT;
regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
}
/* This returns the status bits of the device. The return value
* is never checked, and this is what the 8260 driver did, so we
* do the same. Presumably, this would be zero if there were no
* errors
*/
static int tsec_send(struct eth_device *dev, volatile void *packet, int length)
{
int i;
int result = 0;
struct tsec_private *priv = (struct tsec_private *)dev->priv;
volatile tsec_t *regs = priv->regs;
/* Find an empty buffer descriptor */
for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
debug("%s: tsec: tx buffers full\n", dev->name);
return result;
}
}
rtx.txbd[txIdx].bufPtr = (uint) packet;
rtx.txbd[txIdx].length = length;
rtx.txbd[txIdx].status |=
(TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
/* Tell the DMA to go */
regs->tstat = TSTAT_CLEAR_THALT;
/* Wait for buffer to be transmitted */
for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
debug("%s: tsec: tx error\n", dev->name);
return result;
}
}
txIdx = (txIdx + 1) % TX_BUF_CNT;
result = rtx.txbd[txIdx].status & TXBD_STATS;
return result;
}
static int tsec_recv(struct eth_device *dev)
struct tsec_private *priv = (struct tsec_private *)dev->priv;
volatile tsec_t *regs = priv->regs;
while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
length = rtx.rxbd[rxIdx].length;
/* Send the packet up if there were no errors */
if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) {
NetReceive(NetRxPackets[rxIdx], length - 4);
} else {
printf("Got error %x\n",
(rtx.rxbd[rxIdx].status & RXBD_STATS));
}
rtx.rxbd[rxIdx].length = 0;
/* Set the wrap bit if this is the last element in the list */
rtx.rxbd[rxIdx].status =
RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0);
rxIdx = (rxIdx + 1) % PKTBUFSRX;
}
if (regs->ievent & IEVENT_BSY) {
regs->ievent = IEVENT_BSY;
regs->rstat = RSTAT_CLEAR_RHALT;
}
return -1;
}
static void tsec_halt(struct eth_device *dev)
struct tsec_private *priv = (struct tsec_private *)dev->priv;
volatile tsec_t *regs = priv->regs;
regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
while ((regs->ievent & (IEVENT_GRSC | IEVENT_GTSC))
!= (IEVENT_GRSC | IEVENT_GTSC)) ;
regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
/* Shut down the PHY, as needed */
if(priv->phyinfo)
phy_run_commands(priv, priv->phyinfo->shutdown);
static struct phy_info phy_info_M88E1149S = {
0x1410ca,
"Marvell 88E1149S",
4,
/* Reset and configure the PHY */
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{0x1d, 0x1f, NULL},
{0x1e, 0x200c, NULL},
{0x1d, 0x5, NULL},
{0x1e, 0x0, NULL},
{0x1e, 0x100, NULL},
{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr},
/* The 5411 id is 0x206070, the 5421 is 0x2060e0 */
static struct phy_info phy_info_BCM5461S = {
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
0x02060c1, /* 5461 ID */
"Broadcom BCM5461S",
0, /* not clear to me what minor revisions we can shift away */
(struct phy_cmd[]) { /* config */
/* Reset and configure the PHY */
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
};
static struct phy_info phy_info_BCM5464S = {
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
0x02060b1, /* 5464 ID */
"Broadcom BCM5464S",
0, /* not clear to me what minor revisions we can shift away */
(struct phy_cmd[]) { /* config */
/* Reset and configure the PHY */
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
};
static struct phy_info phy_info_BCM5482S = {
0x0143bcb,
"Broadcom BCM5482S",
4,
(struct phy_cmd[]) { /* config */
/* Reset and configure the PHY */
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
/* Setup read from auxilary control shadow register 7 */
{MIIM_BCM54xx_AUXCNTL, MIIM_BCM54xx_AUXCNTL_ENCODE(7), NULL},
/* Read Misc Control register and or in Ethernet@Wirespeed */
{MIIM_BCM54xx_AUXCNTL, 0, &mii_BCM54xx_wirespeed},
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
/* Initial config/enable of secondary SerDes interface */
{MIIM_BCM54XX_SHD, MIIM_BCM54XX_SHD_WR_ENCODE(0x14, 0xf), NULL},
/* Write intial value to secondary SerDes Contol */
{MIIM_BCM54XX_EXP_SEL, MIIM_BCM54XX_EXP_SEL_SSD | 0, NULL},
{MIIM_BCM54XX_EXP_DATA, MIIM_CONTROL_RESTART, NULL},
/* Enable copper/fiber auto-detect */
{MIIM_BCM54XX_SHD, MIIM_BCM54XX_SHD_WR_ENCODE(0x1e, 0x201)},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Determine copper/fiber, auto-negotiate, and read the result */
{MIIM_STATUS, miim_read, &mii_parse_BCM5482_sr},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
};
static struct phy_info phy_info_M88E1011S = {
0x01410c6,
"Marvell 88E1011S",
4,
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
(struct phy_cmd[]) { /* config */
/* Reset and configure the PHY */
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{0x1d, 0x1f, NULL},
{0x1e, 0x200c, NULL},
{0x1d, 0x5, NULL},
{0x1e, 0x0, NULL},
{0x1e, 0x100, NULL},
{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
static struct phy_info phy_info_M88E1111S = {
0x01410cc,
"Marvell 88E1111S",
4,
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
(struct phy_cmd[]) { /* config */
/* Reset and configure the PHY */
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{0x1b, 0x848f, &mii_m88e1111s_setmode},
{0x14, 0x0cd2, NULL}, /* Delay RGMII TX and RX */
{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
static struct phy_info phy_info_M88E1118 = {
0x01410e1,
"Marvell 88E1118",
4,
/* Reset and configure the PHY */
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{0x16, 0x0002, NULL}, /* Change Page Number */
{0x15, 0x1070, NULL}, /* Delay RGMII TX and RX */
{0x16, 0x0003, NULL}, /* Change Page Number */
{0x10, 0x021e, NULL}, /* Adjust LED control */
{0x16, 0x0000, NULL}, /* Change Page Number */
{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
{0x16, 0x0000, NULL}, /* Change Page Number */
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
/* Read the status */
{MIIM_88E1011_PHY_STATUS, miim_read,
&mii_parse_88E1011_psr},
{miim_end,}
/*
* Since to access LED register we need do switch the page, we
* do LED configuring in the miim_read-like function as follows
*/
static uint mii_88E1121_set_led (uint mii_reg, struct tsec_private *priv)
{
uint pg;
/* Switch the page to access the led register */
pg = read_phy_reg(priv, MIIM_88E1121_PHY_PAGE);
write_phy_reg(priv, MIIM_88E1121_PHY_PAGE, MIIM_88E1121_PHY_LED_PAGE);
/* Configure leds */
write_phy_reg(priv, MIIM_88E1121_PHY_LED_CTRL,
MIIM_88E1121_PHY_LED_DEF);
/* Restore the page pointer */
write_phy_reg(priv, MIIM_88E1121_PHY_PAGE, pg);
return 0;
}
static struct phy_info phy_info_M88E1121R = {
0x01410cb,
"Marvell 88E1121R",
4,
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
(struct phy_cmd[]) { /* config */
/* Reset and configure the PHY */
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
/* Configure leds */
{MIIM_88E1121_PHY_LED_CTRL, miim_read, &mii_88E1121_set_led},
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
/* Disable IRQs and de-assert interrupt */
{MIIM_88E1121_PHY_IRQ_EN, 0, NULL},
{MIIM_88E1121_PHY_IRQ_STATUS, miim_read, NULL},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
{MIIM_STATUS, miim_read, &mii_parse_sr},
{MIIM_STATUS, miim_read, &mii_parse_link},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
static unsigned int m88e1145_setmode(uint mii_reg, struct tsec_private *priv)
{
uint mii_data = read_phy_reg(priv, mii_reg);
/* Setting MIIM_88E1145_PHY_EXT_CR */
if (priv->flags & TSEC_REDUCED)
return mii_data |
MIIM_M88E1145_RGMII_RX_DELAY | MIIM_M88E1145_RGMII_TX_DELAY;
else
return mii_data;
}
static struct phy_info phy_info_M88E1145 = {
0x01410cd,
"Marvell 88E1145",
4,
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
(struct phy_cmd[]) { /* config */
/* Reset the PHY */
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
/* Errata E0, E1 */
{29, 0x001b, NULL},
{30, 0x418f, NULL},
{29, 0x0016, NULL},
{30, 0xa2da, NULL},
/* Configure the PHY */
{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
{MIIM_88E1011_PHY_SCR, MIIM_88E1011_PHY_MDI_X_AUTO, NULL},
{MIIM_88E1145_PHY_EXT_CR, 0, &m88e1145_setmode},
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_CONTROL, MIIM_CONTROL_INIT, NULL},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
{MIIM_88E1111_PHY_LED_CONTROL, MIIM_88E1111_PHY_LED_DIRECT, NULL},
/* Read the Status */
{MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
static struct phy_info phy_info_cis8204 = {
0x3f11,
"Cicada Cis8204",
6,
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
(struct phy_cmd[]) { /* config */
/* Override PHY config settings */
{MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
/* Configure some basic stuff */
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT,
&mii_cis8204_fixled},
{MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT,
&mii_cis8204_setmode},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Read the Status (2x to make sure link is right) */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
};
/* Cicada 8201 */
static struct phy_info phy_info_cis8201 = {
0xfc41,
"CIS8201",
4,
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
(struct phy_cmd[]) { /* config */
/* Override PHY config settings */
{MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
/* Set up the interface mode */
{MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL},
/* Configure some basic stuff */
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Read the Status (2x to make sure link is right) */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
static struct phy_info phy_info_VSC8211 = {
0xfc4b,
"Vitesse VSC8211",
4,
(struct phy_cmd[]) { /* config */
/* Override PHY config settings */
{MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
/* Set up the interface mode */
{MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL},
/* Configure some basic stuff */
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Read the Status (2x to make sure link is right) */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
static struct phy_info phy_info_VSC8244 = {
0x3f1b,
"Vitesse VSC8244",
6,
(struct phy_cmd[]) { /* config */
/* Override PHY config settings */
/* Configure some basic stuff */
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Read the Status (2x to make sure link is right) */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
static struct phy_info phy_info_VSC8641 = {
0x7043,
"Vitesse VSC8641",
4,
(struct phy_cmd[]) { /* config */
/* Configure some basic stuff */
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Read the Status (2x to make sure link is right) */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
};
static struct phy_info phy_info_VSC8221 = {
0xfc55,
"Vitesse VSC8221",
4,
(struct phy_cmd[]) { /* config */
/* Configure some basic stuff */
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Read the Status (2x to make sure link is right) */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
};
static struct phy_info phy_info_VSC8601 = {
0x00007042,
"Vitesse VSC8601",
4,
(struct phy_cmd[]) { /* config */
/* Override PHY config settings */
/* Configure some basic stuff */
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
#ifdef CONFIG_SYS_VSC8601_SKEWFIX
{MIIM_VSC8601_EPHY_CON,MIIM_VSC8601_EPHY_CON_INIT_SKEW,NULL},
#if defined(CONFIG_SYS_VSC8601_SKEW_TX) && defined(CONFIG_SYS_VSC8601_SKEW_RX)
{MIIM_EXT_PAGE_ACCESS,1,NULL},
#define VSC8101_SKEW \
(CONFIG_SYS_VSC8601_SKEW_TX << 14) | (CONFIG_SYS_VSC8601_SKEW_RX << 12)
{MIIM_VSC8601_SKEW_CTRL,VSC8101_SKEW,NULL},
{MIIM_EXT_PAGE_ACCESS,0,NULL},
{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
{MIIM_CONTROL, MIIM_CONTROL_RESTART, &mii_cr_init},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Read the Status (2x to make sure link is right) */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
static struct phy_info phy_info_dm9161 = {
0x0181b88,
"Davicom DM9161E",
4,
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
(struct phy_cmd[]) { /* config */
{MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL},
/* Do not bypass the scrambler/descrambler */
{MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL},
/* Clear 10BTCSR to default */
{MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT, NULL},
/* Configure some basic stuff */
{MIIM_CONTROL, MIIM_CR_INIT, NULL},
/* Restart Auto Negotiation */
{MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_DM9161_SCSR, miim_read, &mii_parse_dm9161_scsr},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
/* micrel KSZ804 */
static struct phy_info phy_info_ksz804 = {
0x0022151,
"Micrel KSZ804 PHY",
4,
(struct phy_cmd[]) { /* config */
{MII_BMCR, BMCR_RESET, NULL},
{MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART, NULL},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
{MII_BMSR, miim_read, NULL},
{MII_BMSR, miim_read, &mii_parse_sr},
{MII_BMSR, miim_read, &mii_parse_link},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
}
};
/* a generic flavor. */
static struct phy_info phy_info_generic = {
0,
"Unknown/Generic PHY",
32,
(struct phy_cmd[]) { /* config */
{MII_BMCR, BMCR_RESET, NULL},
{MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART, NULL},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
{MII_BMSR, miim_read, NULL},
{MII_BMSR, miim_read, &mii_parse_sr},
{MII_BMSR, miim_read, &mii_parse_link},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
}
};
static uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv)
unsigned int speed;
if (priv->link) {
speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK;
switch (speed) {
case MIIM_LXT971_SR2_10HDX:
priv->speed = 10;
priv->duplexity = 0;
break;
case MIIM_LXT971_SR2_10FDX:
priv->speed = 10;
priv->duplexity = 1;
break;
case MIIM_LXT971_SR2_100HDX:
priv->speed = 100;
priv->duplexity = 0;
default:
priv->speed = 100;
priv->duplexity = 1;
}
} else {
priv->speed = 0;
priv->duplexity = 0;
}
return 0;
static struct phy_info phy_info_lxt971 = {
0x0001378e,
"LXT971",
4,
(struct phy_cmd[]) { /* config */
{MIIM_CR, MIIM_CR_INIT, mii_cr_init}, /* autonegotiate */
{miim_end,}
},
(struct phy_cmd[]) { /* startup - enable interrupts */
/* { 0x12, 0x00f2, NULL }, */
{MIIM_STATUS, miim_read, NULL},
{MIIM_STATUS, miim_read, &mii_parse_sr},
{MIIM_LXT971_SR2, miim_read, &mii_parse_lxt971_sr2},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown - disable interrupts */
{miim_end,}
},
/* Parse the DP83865's link and auto-neg status register for speed and duplex
static uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv)
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
{
switch (mii_reg & MIIM_DP83865_SPD_MASK) {
case MIIM_DP83865_SPD_1000:
priv->speed = 1000;
break;
case MIIM_DP83865_SPD_100:
priv->speed = 100;
break;
default:
priv->speed = 10;
break;
}
if (mii_reg & MIIM_DP83865_DPX_FULL)
priv->duplexity = 1;
else
priv->duplexity = 0;
return 0;
}
static struct phy_info phy_info_dp83865 = {
0x20005c7,
"NatSemi DP83865",
4,
(struct phy_cmd[]) { /* config */
{MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the link and auto-neg status */
{MIIM_DP83865_LANR, miim_read, &mii_parse_dp83865_lanr},
{miim_end,}
},
(struct phy_cmd[]) { /* shutdown */
{miim_end,}
},
static struct phy_info phy_info_rtl8211b = {
0x001cc91,
"RealTek RTL8211B",
4,
/* Reset and configure the PHY */
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{miim_end,}
},
/* Status is read once to clear old link state */
{MIIM_STATUS, miim_read, NULL},
/* Auto-negotiate */
{MIIM_STATUS, miim_read, &mii_parse_sr},
/* Read the status */
{MIIM_RTL8211B_PHY_STATUS, miim_read, &mii_parse_RTL8211B_sr},
{miim_end,}
},
{miim_end,}
},
};
static struct phy_info *phy_info[] = {
&phy_info_M88E1121R,
&phy_info_VSC8641,
&phy_info_VSC8221,
&phy_info_dp83865,
&phy_info_generic, /* must be last; has ID 0 and 32 bit mask */
NULL
};
/* Grab the identifier of the device's PHY, and search through
* all of the known PHYs to see if one matches. If so, return
* it, if not, return NULL
*/
static struct phy_info *get_phy_info(struct eth_device *dev)
{
struct tsec_private *priv = (struct tsec_private *)dev->priv;
uint phy_reg, phy_ID;
int i;
struct phy_info *theInfo = NULL;
/* Grab the bits from PHYIR1, and put them in the upper half */
phy_reg = read_phy_reg(priv, MIIM_PHYIR1);
phy_ID = (phy_reg & 0xffff) << 16;
/* Grab the bits from PHYIR2, and put them in the lower half */
phy_reg = read_phy_reg(priv, MIIM_PHYIR2);
phy_ID |= (phy_reg & 0xffff);
/* loop through all the known PHY types, and find one that */
/* matches the ID we read from the PHY. */
for (i = 0; phy_info[i]; i++) {
if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) {
if (theInfo == &phy_info_generic) {
printf("%s: No support for PHY id %x; assuming generic\n",
dev->name, phy_ID);
debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID);
}
return theInfo;
/* Execute the given series of commands on the given device's
* PHY, running functions as necessary
*/
static void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd)
{
int i;
uint result;
volatile tsec_mdio_t *phyregs = priv->phyregs;
phyregs->miimcfg = MIIMCFG_RESET;
phyregs->miimcfg = MIIMCFG_INIT_VALUE;
while (phyregs->miimind & MIIMIND_BUSY) ;
for (i = 0; cmd->mii_reg != miim_end; i++) {
if (cmd->mii_data == miim_read) {
result = read_phy_reg(priv, cmd->mii_reg);
if (cmd->funct != NULL)
(*(cmd->funct)) (result, priv);
if (cmd->funct != NULL)
result = (*(cmd->funct)) (cmd->mii_reg, priv);
else
result = cmd->mii_data;
write_phy_reg(priv, cmd->mii_reg, result);
}
cmd++;
}
}
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
/*
* Read a MII PHY register.
*
* Returns:
static int tsec_miiphy_read(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value)
michael.firth@bt.com
committed
struct tsec_private *priv = privlist[0];
printf("Can't read PHY at address %d\n", addr);
return -1;
}
ret = (unsigned short)tsec_local_mdio_read(priv->phyregs, addr, reg);
return 0;
}
/*
* Write a MII PHY register.
*
* Returns:
static int tsec_miiphy_write(const char *devname, unsigned char addr,
unsigned char reg, unsigned short value)
michael.firth@bt.com
committed
struct tsec_private *priv = privlist[0];
printf("Can't write PHY at address %d\n", addr);
return -1;
}
tsec_local_mdio_write(priv->phyregs, addr, reg, value);
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
#ifdef CONFIG_MCAST_TFTP
/* CREDITS: linux gianfar driver, slightly adjusted... thanx. */
/* Set the appropriate hash bit for the given addr */
/* The algorithm works like so:
* 1) Take the Destination Address (ie the multicast address), and
* do a CRC on it (little endian), and reverse the bits of the
* result.
* 2) Use the 8 most significant bits as a hash into a 256-entry
* table. The table is controlled through 8 32-bit registers:
* gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is
* gaddr7. This means that the 3 most significant bits in the
* hash index which gaddr register to use, and the 5 other bits
* indicate which bit (assuming an IBM numbering scheme, which
* for PowerPC (tm) is usually the case) in the tregister holds
* the entry. */
static int
tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set)
{
struct tsec_private *priv = privlist[1];
volatile tsec_t *regs = priv->regs;
volatile u32 *reg_array, value;
u8 result, whichbit, whichreg;
result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) >> 24) & 0xff);
whichbit = result & 0x1f; /* the 5 LSB = which bit to set */
whichreg = result >> 5; /* the 3 MSB = which reg to set it in */
value = (1 << (31-whichbit));
reg_array = &(regs->hash.gaddr0);
if (set) {
reg_array[whichreg] |= value;
} else {
reg_array[whichreg] &= ~value;
}
return 0;
}