[linux-yocto] [PATCH 43/89] drivers/net: Check for the PHY link setting and set as appropriate.
Paul Butler
butler.paul at gmail.com
Sun Oct 27 12:33:08 PDT 2013
From: John Jacques <john.jacques at lsi.com>
Signed-off-by: John Jacques <john.jacques at lsi.com>
---
drivers/net/ethernet/lsi/lsi_acp_net.c | 109 +++++++++++++++++++++++++++++----
1 file changed, 96 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/lsi/lsi_acp_net.c b/drivers/net/ethernet/lsi/lsi_acp_net.c
index 6069aa7..0a067d6 100644
--- a/drivers/net/ethernet/lsi/lsi_acp_net.c
+++ b/drivers/net/ethernet/lsi/lsi_acp_net.c
@@ -53,6 +53,9 @@
#include <linux/io.h>
#include <asm/dma.h>
+#undef AMARILLO_WAS
+#define AMARILLO_WAS
+
/*#include <asm/acp3400-version.h>*/
extern int acp_mdio_read(unsigned long,
@@ -594,6 +597,9 @@ typedef struct {
unsigned long mdio_clock;
unsigned long phy_address;
unsigned long ad_value;
+ unsigned long phy_link_auto;
+ unsigned long phy_link_speed;
+ unsigned long phy_link_duplex;
unsigned char mac_addr[6];
#ifdef LSINET_NAPI
@@ -1727,17 +1733,13 @@ static int enable_(struct net_device *device)
unsigned long rx_configuration_;
unsigned long tx_configuration_ = 0;
phy_status_t phy_status_;
+ phy_control_t phy_control_;
appnic_device_t *apnd = netdev_priv(device);
+ unsigned short value;
- rx_configuration_ =
- APPNIC_RX_CONF_STRIPCRC;
+ rx_configuration_ = APPNIC_RX_CONF_STRIPCRC;
+ /*rx_configuration_ |= 0x4;*/
-#if 0
- rx_configuration_ =
- (APPNIC_RX_CONF_STRIPCRC |
- APPNIC_RX_CONF_RXFCE |
- APPNIC_RX_CONF_TXFCE);
-#endif
tx_configuration_ =
(APPNIC_TX_CONF_ENABLE_SWAP_SA |
APPNIC_TX_CONF_APP_CRC_ENABLE |
@@ -1752,6 +1754,7 @@ static int enable_(struct net_device *device)
* status to set speed/duplex and check the link status).
*/
+ if (0 != apnd->phy_link_auto) {
if ((0 == phy_read_(apnd->phy_address, PHY_STATUS, &phy_status_.raw)) &&
(0 == phy_read_(apnd->phy_address, PHY_STATUS, &phy_status_.raw))) {
@@ -1799,6 +1802,57 @@ static int enable_(struct net_device *device)
} else {
ERROR_PRINT("phy_read_() failed!\n");
}
+ } else {
+ /*
+ Don't autonegotiate for now...
+ */
+
+ phy_read_(apnd->phy_address, 0x1f, &value);
+ value |= 0x80;
+ phy_write_(apnd->phy_address, 0x1f, value);
+
+ phy_write_(apnd->phy_address, 0x1d, 0x7);
+
+ phy_read_(apnd->phy_address, 0x1f, &value);
+ value &= ~0x80;
+ phy_write_(apnd->phy_address, 0x1f, value);
+
+ phy_read_(apnd->phy_address, PHY_CONTROL, &phy_control_.raw);
+ phy_control_.bits.autoneg_enable = 0;
+ phy_control_.bits.force100 = apnd->phy_link_speed;
+ phy_control_.bits.full_duplex = apnd->phy_link_duplex;
+ phy_write_(apnd->phy_address, PHY_CONTROL, phy_control_.raw);
+
+ if (0 == phy_read_(apnd->phy_address, PHY_STATUS, &phy_status_.raw)) {
+ if (1 == phy_status_.bits.link_status) {
+ if (1 == phy_speed_(apnd->phy_address)) {
+ rx_configuration_ |= APPNIC_RX_CONF_SPEED;
+ tx_configuration_ |= APPNIC_TX_CONF_SPEED;
+ }
+
+ if (1 == phy_duplex_(apnd->phy_address)) {
+ rx_configuration_ |= APPNIC_RX_CONF_DUPLEX;
+ tx_configuration_ |= APPNIC_TX_CONF_DUPLEX;
+ }
+
+ rx_configuration_ |=
+ (APPNIC_RX_CONF_ENABLE |
+ APPNIC_RX_CONF_LINK);
+ tx_configuration_ |=
+ (APPNIC_TX_CONF_LINK |
+ APPNIC_TX_CONF_ENABLE);
+ return_code_ = 0;
+ carrier_state_ = 1;
+ } else {
+ netif_carrier_off(device);
+ }
+ }
+
+#ifdef AMARILLO_WAS
+ rx_configuration_ &= ~0x1000;
+ tx_configuration_ &= ~0x1000;
+#endif
+ }
if (rx_configuration_ != read_mac_(APPNIC_RX_CONF)) {
PHY_DEBUG_PRINT("Writing APPNIC_RX_CONF: rx_config: 0x%x\n",
@@ -2103,7 +2157,7 @@ static int phy_enable_(struct net_device *device)
phy_id_low_t phy_id_low_;
unsigned char phyaddr_string_[40];
- printk("%d - apnd->phy_address=0x%x\n", __LINE__, apnd->phy_address);
+ apnd->phy_address = 0x1e;
if (0 == phy_read_(apnd->phy_address, PHY_ID_HIGH, &phy_id_high_.raw)) {
PHY_DEBUG_PRINT("Read PHY_ID_HIGH as 0x%x on mdio addr 0x%x.\n",
@@ -2128,7 +2182,6 @@ static int phy_enable_(struct net_device *device)
rc |= phy_write_(0, PHY_CONTROL, phy_control.raw);
rc |= phy_read_(0x1e, 0x18, &value);
- printk("%s:%d - rc=%d value=0x%x\n", __FILE__, __LINE__, rc, value);
}
{
@@ -2142,6 +2195,12 @@ static int phy_enable_(struct net_device *device)
/* Set RX FIFO size to 0x7 */
rc |= phy_write_(0x1e, PHY_AUXILIARY_MODE3, 0x7);
+
+ rc = phy_read_(0x1e, PHY_BCM_TEST_REG, &value);
+ /* Access Shadow reg 0x1d */
+ value = value & ~0x80;
+ rc |= phy_write_(0x1e, PHY_BCM_TEST_REG, value);
+
if (rc != 0) {
return rc;
}
@@ -3273,9 +3332,6 @@ appnic_init(struct net_device *device)
adapter->rx_tail = (appnic_queue_pointer_t *) dma_offset_;
adapter->rx_tail_dma = (int) adapter->rx_tail -
(int) adapter->dma_alloc_offset;
- printk("%s:%d - rx_tail=0x%08x rx_tail_dma=0x%08x\n",
- __FILE__, __LINE__,
- adapter->rx_tail, adapter->rx_tail_dma); /* ZZZ */
dma_offset_ += sizeof(appnic_queue_pointer_t);
memset((void *) adapter->rx_tail, 0,
sizeof(appnic_queue_pointer_t));
@@ -3650,6 +3706,7 @@ lsinet_init(void)
struct net_device *device;
struct device_node *np = NULL;
const u32 *field;
+ const char *macspeed;
appnic_device_t *appnic_device;
u64 value64;
u64 dt_size;
@@ -3740,6 +3797,32 @@ lsinet_init(void)
goto device_tree_failed;
appnic_device->phy_address = field[0];
+ macspeed = of_get_property(np, "phy-link", NULL);
+
+ if (macspeed) {
+ if (0 == strncmp(macspeed, "auto", strlen("auto"))) {
+ appnic_device->phy_link_auto = 1;
+ } else if (0 == strncmp(macspeed, "100MF", strlen("100MF"))) {
+ appnic_device->phy_link_auto = 0;
+ appnic_device->phy_link_speed = 1;
+ appnic_device->phy_link_duplex = 1;
+ } else if (0 == strncmp(macspeed, "100MH", strlen("100MH"))) {
+ appnic_device->phy_link_auto = 0;
+ appnic_device->phy_link_speed = 1;
+ appnic_device->phy_link_duplex = 0;
+ } else if (0 == strncmp(macspeed, "10MF", strlen("10MF"))) {
+ appnic_device->phy_link_auto = 0;
+ appnic_device->phy_link_speed = 0;
+ appnic_device->phy_link_duplex = 1;
+ } else if (0 == strncmp(macspeed, "10MH", strlen("10MH"))) {
+ appnic_device->phy_link_auto = 0;
+ appnic_device->phy_link_speed = 0;
+ appnic_device->phy_link_duplex = 0;
+ }
+ } else {
+ /* Auto is the default. */
+ appnic_device->phy_link_auto = 1;
+ }
field = of_get_property(np, "ad-value", NULL);
--
1.8.3.4
More information about the linux-yocto
mailing list