aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/dp83640.c4
-rw-r--r--drivers/net/phy/marvell.c19
-rw-r--r--drivers/net/phy/phy.c36
3 files changed, 45 insertions, 14 deletions
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 2954052706e8..e22e602beef3 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -791,7 +791,7 @@ static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts)
791 791
792 switch (type & PTP_CLASS_PMASK) { 792 switch (type & PTP_CLASS_PMASK) {
793 case PTP_CLASS_IPV4: 793 case PTP_CLASS_IPV4:
794 offset += ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; 794 offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN;
795 break; 795 break;
796 case PTP_CLASS_IPV6: 796 case PTP_CLASS_IPV6:
797 offset += ETH_HLEN + IP6_HLEN + UDP_HLEN; 797 offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
@@ -934,7 +934,7 @@ static int is_sync(struct sk_buff *skb, int type)
934 934
935 switch (type & PTP_CLASS_PMASK) { 935 switch (type & PTP_CLASS_PMASK) {
936 case PTP_CLASS_IPV4: 936 case PTP_CLASS_IPV4:
937 offset += ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; 937 offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN;
938 break; 938 break;
939 case PTP_CLASS_IPV6: 939 case PTP_CLASS_IPV6:
940 offset += ETH_HLEN + IP6_HLEN + UDP_HLEN; 940 offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index bd37e45c89c0..225c033b08f3 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -50,10 +50,15 @@
50#define MII_M1011_PHY_SCR 0x10 50#define MII_M1011_PHY_SCR 0x10
51#define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060 51#define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060
52 52
53#define MII_M1145_PHY_EXT_SR 0x1b
53#define MII_M1145_PHY_EXT_CR 0x14 54#define MII_M1145_PHY_EXT_CR 0x14
54#define MII_M1145_RGMII_RX_DELAY 0x0080 55#define MII_M1145_RGMII_RX_DELAY 0x0080
55#define MII_M1145_RGMII_TX_DELAY 0x0002 56#define MII_M1145_RGMII_TX_DELAY 0x0002
56 57
58#define MII_M1145_HWCFG_MODE_SGMII_NO_CLK 0x4
59#define MII_M1145_HWCFG_MODE_MASK 0xf
60#define MII_M1145_HWCFG_FIBER_COPPER_AUTO 0x8000
61
57#define MII_M1111_PHY_LED_CONTROL 0x18 62#define MII_M1111_PHY_LED_CONTROL 0x18
58#define MII_M1111_PHY_LED_DIRECT 0x4100 63#define MII_M1111_PHY_LED_DIRECT 0x4100
59#define MII_M1111_PHY_LED_COMBINE 0x411c 64#define MII_M1111_PHY_LED_COMBINE 0x411c
@@ -676,6 +681,20 @@ static int m88e1145_config_init(struct phy_device *phydev)
676 } 681 }
677 } 682 }
678 683
684 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
685 int temp = phy_read(phydev, MII_M1145_PHY_EXT_SR);
686 if (temp < 0)
687 return temp;
688
689 temp &= ~MII_M1145_HWCFG_MODE_MASK;
690 temp |= MII_M1145_HWCFG_MODE_SGMII_NO_CLK;
691 temp |= MII_M1145_HWCFG_FIBER_COPPER_AUTO;
692
693 err = phy_write(phydev, MII_M1145_PHY_EXT_SR, temp);
694 if (err < 0)
695 return err;
696 }
697
679 err = marvell_of_reg_init(phydev); 698 err = marvell_of_reg_init(phydev);
680 if (err < 0) 699 if (err < 0)
681 return err; 700 return err;
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 1dfffdc9dfc3..767cd110f496 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -352,6 +352,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
352{ 352{
353 struct mii_ioctl_data *mii_data = if_mii(ifr); 353 struct mii_ioctl_data *mii_data = if_mii(ifr);
354 u16 val = mii_data->val_in; 354 u16 val = mii_data->val_in;
355 bool change_autoneg = false;
355 356
356 switch (cmd) { 357 switch (cmd) {
357 case SIOCGMIIPHY: 358 case SIOCGMIIPHY:
@@ -367,22 +368,29 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
367 if (mii_data->phy_id == phydev->addr) { 368 if (mii_data->phy_id == phydev->addr) {
368 switch (mii_data->reg_num) { 369 switch (mii_data->reg_num) {
369 case MII_BMCR: 370 case MII_BMCR:
370 if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) 371 if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) {
372 if (phydev->autoneg == AUTONEG_ENABLE)
373 change_autoneg = true;
371 phydev->autoneg = AUTONEG_DISABLE; 374 phydev->autoneg = AUTONEG_DISABLE;
372 else 375 if (val & BMCR_FULLDPLX)
376 phydev->duplex = DUPLEX_FULL;
377 else
378 phydev->duplex = DUPLEX_HALF;
379 if (val & BMCR_SPEED1000)
380 phydev->speed = SPEED_1000;
381 else if (val & BMCR_SPEED100)
382 phydev->speed = SPEED_100;
383 else phydev->speed = SPEED_10;
384 }
385 else {
386 if (phydev->autoneg == AUTONEG_DISABLE)
387 change_autoneg = true;
373 phydev->autoneg = AUTONEG_ENABLE; 388 phydev->autoneg = AUTONEG_ENABLE;
374 if (!phydev->autoneg && (val & BMCR_FULLDPLX)) 389 }
375 phydev->duplex = DUPLEX_FULL;
376 else
377 phydev->duplex = DUPLEX_HALF;
378 if (!phydev->autoneg && (val & BMCR_SPEED1000))
379 phydev->speed = SPEED_1000;
380 else if (!phydev->autoneg &&
381 (val & BMCR_SPEED100))
382 phydev->speed = SPEED_100;
383 break; 390 break;
384 case MII_ADVERTISE: 391 case MII_ADVERTISE:
385 phydev->advertising = val; 392 phydev->advertising = mii_adv_to_ethtool_adv_t(val);
393 change_autoneg = true;
386 break; 394 break;
387 default: 395 default:
388 /* do nothing */ 396 /* do nothing */
@@ -396,6 +404,10 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
396 if (mii_data->reg_num == MII_BMCR && 404 if (mii_data->reg_num == MII_BMCR &&
397 val & BMCR_RESET) 405 val & BMCR_RESET)
398 return phy_init_hw(phydev); 406 return phy_init_hw(phydev);
407
408 if (change_autoneg)
409 return phy_start_aneg(phydev);
410
399 return 0; 411 return 0;
400 412
401 case SIOCSHWTSTAMP: 413 case SIOCSHWTSTAMP: