aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRon Mercer <ron.mercer@qlogic.com>2007-03-26 15:43:52 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 11:01:02 -0400
commit3efedf2e5b814f3edd99e4f4ca47a604871ebe0e (patch)
tree2cc59d55ca90b1ca4bcff89e227529584a6b35fd
parentec8263839aa8bc6eeee608a045e8f51738d7e436 (diff)
qla3xxx: Adding support for the Agere PHY (ET1011C)
This PHY support patch was written by Benjamin Li. Signed-off-by: Benjamin Li <benjamin.li@qlogic.com> Signed-off-by: Ron Mercer <ron.mercer@qlogic.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rwxr-xr-xdrivers/net/qla3xxx.c347
-rwxr-xr-xdrivers/net/qla3xxx.h33
2 files changed, 335 insertions, 45 deletions
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index c2eb2c93803b..4061f7de48af 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -72,6 +72,30 @@ static struct pci_device_id ql3xxx_pci_tbl[] __devinitdata = {
72MODULE_DEVICE_TABLE(pci, ql3xxx_pci_tbl); 72MODULE_DEVICE_TABLE(pci, ql3xxx_pci_tbl);
73 73
74/* 74/*
75 * These are the known PHY's which are used
76 */
77typedef enum {
78 PHY_TYPE_UNKNOWN = 0,
79 PHY_VITESSE_VSC8211,
80 PHY_AGERE_ET1011C,
81 MAX_PHY_DEV_TYPES
82} PHY_DEVICE_et;
83
84typedef struct {
85 PHY_DEVICE_et phyDevice;
86 u32 phyIdOUI;
87 u16 phyIdModel;
88 char *name;
89} PHY_DEVICE_INFO_t;
90
91const PHY_DEVICE_INFO_t PHY_DEVICES[] =
92 {{PHY_TYPE_UNKNOWN, 0x000000, 0x0, "PHY_TYPE_UNKNOWN"},
93 {PHY_VITESSE_VSC8211, 0x0003f1, 0xb, "PHY_VITESSE_VSC8211"},
94 {PHY_AGERE_ET1011C, 0x00a0bc, 0x1, "PHY_AGERE_ET1011C"},
95};
96
97
98/*
75 * Caller must take hw_lock. 99 * Caller must take hw_lock.
76 */ 100 */
77static int ql_sem_spinlock(struct ql3_adapter *qdev, 101static int ql_sem_spinlock(struct ql3_adapter *qdev,
@@ -662,7 +686,7 @@ static u8 ql_mii_disable_scan_mode(struct ql3_adapter *qdev)
662} 686}
663 687
664static int ql_mii_write_reg_ex(struct ql3_adapter *qdev, 688static int ql_mii_write_reg_ex(struct ql3_adapter *qdev,
665 u16 regAddr, u16 value, u32 mac_index) 689 u16 regAddr, u16 value, u32 phyAddr)
666{ 690{
667 struct ql3xxx_port_registers __iomem *port_regs = 691 struct ql3xxx_port_registers __iomem *port_regs =
668 qdev->mem_map_registers; 692 qdev->mem_map_registers;
@@ -680,7 +704,7 @@ static int ql_mii_write_reg_ex(struct ql3_adapter *qdev,
680 } 704 }
681 705
682 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg, 706 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg,
683 PHYAddr[mac_index] | regAddr); 707 phyAddr | regAddr);
684 708
685 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtDataReg, value); 709 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtDataReg, value);
686 710
@@ -701,7 +725,7 @@ static int ql_mii_write_reg_ex(struct ql3_adapter *qdev,
701} 725}
702 726
703static int ql_mii_read_reg_ex(struct ql3_adapter *qdev, u16 regAddr, 727static int ql_mii_read_reg_ex(struct ql3_adapter *qdev, u16 regAddr,
704 u16 * value, u32 mac_index) 728 u16 * value, u32 phyAddr)
705{ 729{
706 struct ql3xxx_port_registers __iomem *port_regs = 730 struct ql3xxx_port_registers __iomem *port_regs =
707 qdev->mem_map_registers; 731 qdev->mem_map_registers;
@@ -720,7 +744,7 @@ static int ql_mii_read_reg_ex(struct ql3_adapter *qdev, u16 regAddr,
720 } 744 }
721 745
722 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg, 746 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg,
723 PHYAddr[mac_index] | regAddr); 747 phyAddr | regAddr);
724 748
725 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg, 749 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg,
726 (MAC_MII_CONTROL_RC << 16)); 750 (MAC_MII_CONTROL_RC << 16));
@@ -850,28 +874,31 @@ static void ql_petbi_start_neg(struct ql3_adapter *qdev)
850 874
851} 875}
852 876
853static void ql_petbi_reset_ex(struct ql3_adapter *qdev, u32 mac_index) 877static void ql_petbi_reset_ex(struct ql3_adapter *qdev)
854{ 878{
855 ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG, PETBI_CTRL_SOFT_RESET, 879 ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG, PETBI_CTRL_SOFT_RESET,
856 mac_index); 880 PHYAddr[qdev->mac_index]);
857} 881}
858 882
859static void ql_petbi_start_neg_ex(struct ql3_adapter *qdev, u32 mac_index) 883static void ql_petbi_start_neg_ex(struct ql3_adapter *qdev)
860{ 884{
861 u16 reg; 885 u16 reg;
862 886
863 /* Enable Auto-negotiation sense */ 887 /* Enable Auto-negotiation sense */
864 ql_mii_read_reg_ex(qdev, PETBI_TBI_CTRL, &reg, mac_index); 888 ql_mii_read_reg_ex(qdev, PETBI_TBI_CTRL, &reg,
889 PHYAddr[qdev->mac_index]);
865 reg |= PETBI_TBI_AUTO_SENSE; 890 reg |= PETBI_TBI_AUTO_SENSE;
866 ql_mii_write_reg_ex(qdev, PETBI_TBI_CTRL, reg, mac_index); 891 ql_mii_write_reg_ex(qdev, PETBI_TBI_CTRL, reg,
892 PHYAddr[qdev->mac_index]);
867 893
868 ql_mii_write_reg_ex(qdev, PETBI_NEG_ADVER, 894 ql_mii_write_reg_ex(qdev, PETBI_NEG_ADVER,
869 PETBI_NEG_PAUSE | PETBI_NEG_DUPLEX, mac_index); 895 PETBI_NEG_PAUSE | PETBI_NEG_DUPLEX,
896 PHYAddr[qdev->mac_index]);
870 897
871 ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG, 898 ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG,
872 PETBI_CTRL_AUTO_NEG | PETBI_CTRL_RESTART_NEG | 899 PETBI_CTRL_AUTO_NEG | PETBI_CTRL_RESTART_NEG |
873 PETBI_CTRL_FULL_DUPLEX | PETBI_CTRL_SPEED_1000, 900 PETBI_CTRL_FULL_DUPLEX | PETBI_CTRL_SPEED_1000,
874 mac_index); 901 PHYAddr[qdev->mac_index]);
875} 902}
876 903
877static void ql_petbi_init(struct ql3_adapter *qdev) 904static void ql_petbi_init(struct ql3_adapter *qdev)
@@ -880,10 +907,10 @@ static void ql_petbi_init(struct ql3_adapter *qdev)
880 ql_petbi_start_neg(qdev); 907 ql_petbi_start_neg(qdev);
881} 908}
882 909
883static void ql_petbi_init_ex(struct ql3_adapter *qdev, u32 mac_index) 910static void ql_petbi_init_ex(struct ql3_adapter *qdev)
884{ 911{
885 ql_petbi_reset_ex(qdev, mac_index); 912 ql_petbi_reset_ex(qdev);
886 ql_petbi_start_neg_ex(qdev, mac_index); 913 ql_petbi_start_neg_ex(qdev);
887} 914}
888 915
889static int ql_is_petbi_neg_pause(struct ql3_adapter *qdev) 916static int ql_is_petbi_neg_pause(struct ql3_adapter *qdev)
@@ -896,33 +923,128 @@ static int ql_is_petbi_neg_pause(struct ql3_adapter *qdev)
896 return (reg & PETBI_NEG_PAUSE_MASK) == PETBI_NEG_PAUSE; 923 return (reg & PETBI_NEG_PAUSE_MASK) == PETBI_NEG_PAUSE;
897} 924}
898 925
926static void phyAgereSpecificInit(struct ql3_adapter *qdev, u32 miiAddr)
927{
928 printk(KERN_INFO "%s: enabling Agere specific PHY\n", qdev->ndev->name);
929 /* power down device bit 11 = 1 */
930 ql_mii_write_reg_ex(qdev, 0x00, 0x1940, miiAddr);
931 /* enable diagnostic mode bit 2 = 1 */
932 ql_mii_write_reg_ex(qdev, 0x12, 0x840e, miiAddr);
933 /* 1000MB amplitude adjust (see Agere errata) */
934 ql_mii_write_reg_ex(qdev, 0x10, 0x8805, miiAddr);
935 /* 1000MB amplitude adjust (see Agere errata) */
936 ql_mii_write_reg_ex(qdev, 0x11, 0xf03e, miiAddr);
937 /* 100MB amplitude adjust (see Agere errata) */
938 ql_mii_write_reg_ex(qdev, 0x10, 0x8806, miiAddr);
939 /* 100MB amplitude adjust (see Agere errata) */
940 ql_mii_write_reg_ex(qdev, 0x11, 0x003e, miiAddr);
941 /* 10MB amplitude adjust (see Agere errata) */
942 ql_mii_write_reg_ex(qdev, 0x10, 0x8807, miiAddr);
943 /* 10MB amplitude adjust (see Agere errata) */
944 ql_mii_write_reg_ex(qdev, 0x11, 0x1f00, miiAddr);
945 /* point to hidden reg 0x2806 */
946 ql_mii_write_reg_ex(qdev, 0x10, 0x2806, miiAddr);
947 /* Write new PHYAD w/bit 5 set */
948 ql_mii_write_reg_ex(qdev, 0x11, 0x0020 | (PHYAddr[qdev->mac_index] >> 8), miiAddr);
949 /*
950 * Disable diagnostic mode bit 2 = 0
951 * Power up device bit 11 = 0
952 * Link up (on) and activity (blink)
953 */
954 ql_mii_write_reg(qdev, 0x12, 0x840a);
955 ql_mii_write_reg(qdev, 0x00, 0x1140);
956 ql_mii_write_reg(qdev, 0x1c, 0xfaf0);
957}
958
959static PHY_DEVICE_et getPhyType (struct ql3_adapter *qdev,
960 u16 phyIdReg0, u16 phyIdReg1)
961{
962 PHY_DEVICE_et result = PHY_TYPE_UNKNOWN;
963 u32 oui;
964 u16 model;
965 int i;
966
967 if (phyIdReg0 == 0xffff) {
968 return result;
969 }
970
971 if (phyIdReg1 == 0xffff) {
972 return result;
973 }
974
975 /* oui is split between two registers */
976 oui = (phyIdReg0 << 6) | ((phyIdReg1 & PHY_OUI_1_MASK) >> 10);
977
978 model = (phyIdReg1 & PHY_MODEL_MASK) >> 4;
979
980 /* Scan table for this PHY */
981 for(i = 0; i < MAX_PHY_DEV_TYPES; i++) {
982 if ((oui == PHY_DEVICES[i].phyIdOUI) && (model == PHY_DEVICES[i].phyIdModel))
983 {
984 result = PHY_DEVICES[i].phyDevice;
985
986 printk(KERN_INFO "%s: Phy: %s\n",
987 qdev->ndev->name, PHY_DEVICES[i].name);
988
989 break;
990 }
991 }
992
993 return result;
994}
995
899static int ql_phy_get_speed(struct ql3_adapter *qdev) 996static int ql_phy_get_speed(struct ql3_adapter *qdev)
900{ 997{
901 u16 reg; 998 u16 reg;
902 999
1000 switch(qdev->phyType) {
1001 case PHY_AGERE_ET1011C:
1002 {
1003 if (ql_mii_read_reg(qdev, 0x1A, &reg) < 0)
1004 return 0;
1005
1006 reg = (reg >> 8) & 3;
1007 break;
1008 }
1009 default:
903 if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, &reg) < 0) 1010 if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, &reg) < 0)
904 return 0; 1011 return 0;
905 1012
906 reg = (((reg & 0x18) >> 3) & 3); 1013 reg = (((reg & 0x18) >> 3) & 3);
1014 }
907 1015
908 if (reg == 2) 1016 switch(reg) {
1017 case 2:
909 return SPEED_1000; 1018 return SPEED_1000;
910 else if (reg == 1) 1019 case 1:
911 return SPEED_100; 1020 return SPEED_100;
912 else if (reg == 0) 1021 case 0:
913 return SPEED_10; 1022 return SPEED_10;
914 else 1023 default:
915 return -1; 1024 return -1;
1025 }
916} 1026}
917 1027
918static int ql_is_full_dup(struct ql3_adapter *qdev) 1028static int ql_is_full_dup(struct ql3_adapter *qdev)
919{ 1029{
920 u16 reg; 1030 u16 reg;
921 1031
922 if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, &reg) < 0) 1032 switch(qdev->phyType) {
923 return 0; 1033 case PHY_AGERE_ET1011C:
924 1034 {
925 return (reg & PHY_AUX_DUPLEX_STAT) != 0; 1035 if (ql_mii_read_reg(qdev, 0x1A, &reg))
1036 return 0;
1037
1038 return ((reg & 0x0080) && (reg & 0x1000)) != 0;
1039 }
1040 case PHY_VITESSE_VSC8211:
1041 default:
1042 {
1043 if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, &reg) < 0)
1044 return 0;
1045 return (reg & PHY_AUX_DUPLEX_STAT) != 0;
1046 }
1047 }
926} 1048}
927 1049
928static int ql_is_phy_neg_pause(struct ql3_adapter *qdev) 1050static int ql_is_phy_neg_pause(struct ql3_adapter *qdev)
@@ -935,6 +1057,73 @@ static int ql_is_phy_neg_pause(struct ql3_adapter *qdev)
935 return (reg & PHY_NEG_PAUSE) != 0; 1057 return (reg & PHY_NEG_PAUSE) != 0;
936} 1058}
937 1059
1060static int PHY_Setup(struct ql3_adapter *qdev)
1061{
1062 u16 reg1;
1063 u16 reg2;
1064 bool agereAddrChangeNeeded = false;
1065 u32 miiAddr = 0;
1066 int err;
1067
1068 /* Determine the PHY we are using by reading the ID's */
1069 err = ql_mii_read_reg(qdev, PHY_ID_0_REG, &reg1);
1070 if(err != 0) {
1071 printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG\n",
1072 qdev->ndev->name);
1073 return err;
1074 }
1075
1076 err = ql_mii_read_reg(qdev, PHY_ID_1_REG, &reg2);
1077 if(err != 0) {
1078 printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG\n",
1079 qdev->ndev->name);
1080 return err;
1081 }
1082
1083 /* Check if we have a Agere PHY */
1084 if ((reg1 == 0xffff) || (reg2 == 0xffff)) {
1085
1086 /* Determine which MII address we should be using
1087 determined by the index of the card */
1088 if (qdev->mac_index == 0) {
1089 miiAddr = MII_AGERE_ADDR_1;
1090 } else {
1091 miiAddr = MII_AGERE_ADDR_2;
1092 }
1093
1094 err =ql_mii_read_reg_ex(qdev, PHY_ID_0_REG, &reg1, miiAddr);
1095 if(err != 0) {
1096 printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG after Agere detected\n",
1097 qdev->ndev->name);
1098 return err;
1099 }
1100
1101 err = ql_mii_read_reg_ex(qdev, PHY_ID_1_REG, &reg2, miiAddr);
1102 if(err != 0) {
1103 printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG after Agere detected\n",
1104 qdev->ndev->name);
1105 return err;
1106 }
1107
1108 /* We need to remember to initialize the Agere PHY */
1109 agereAddrChangeNeeded = true;
1110 }
1111
1112 /* Determine the particular PHY we have on board to apply
1113 PHY specific initializations */
1114 qdev->phyType = getPhyType(qdev, reg1, reg2);
1115
1116 if ((qdev->phyType == PHY_AGERE_ET1011C) && agereAddrChangeNeeded) {
1117 /* need this here so address gets changed */
1118 phyAgereSpecificInit(qdev, miiAddr);
1119 } else if (qdev->phyType == PHY_TYPE_UNKNOWN) {
1120 printk(KERN_ERR "%s: PHY is unknown\n", qdev->ndev->name);
1121 return -EIO;
1122 }
1123
1124 return 0;
1125}
1126
938/* 1127/*
939 * Caller holds hw_lock. 1128 * Caller holds hw_lock.
940 */ 1129 */
@@ -1205,15 +1394,14 @@ static int ql_link_down_detect_clear(struct ql3_adapter *qdev)
1205/* 1394/*
1206 * Caller holds hw_lock. 1395 * Caller holds hw_lock.
1207 */ 1396 */
1208static int ql_this_adapter_controls_port(struct ql3_adapter *qdev, 1397static int ql_this_adapter_controls_port(struct ql3_adapter *qdev)
1209 u32 mac_index)
1210{ 1398{
1211 struct ql3xxx_port_registers __iomem *port_regs = 1399 struct ql3xxx_port_registers __iomem *port_regs =
1212 qdev->mem_map_registers; 1400 qdev->mem_map_registers;
1213 u32 bitToCheck = 0; 1401 u32 bitToCheck = 0;
1214 u32 temp; 1402 u32 temp;
1215 1403
1216 switch (mac_index) { 1404 switch (qdev->mac_index) {
1217 case 0: 1405 case 0:
1218 bitToCheck = PORT_STATUS_F1_ENABLED; 1406 bitToCheck = PORT_STATUS_F1_ENABLED;
1219 break; 1407 break;
@@ -1238,27 +1426,96 @@ static int ql_this_adapter_controls_port(struct ql3_adapter *qdev,
1238 } 1426 }
1239} 1427}
1240 1428
1241static void ql_phy_reset_ex(struct ql3_adapter *qdev, u32 mac_index) 1429static void ql_phy_reset_ex(struct ql3_adapter *qdev)
1242{ 1430{
1243 ql_mii_write_reg_ex(qdev, CONTROL_REG, PHY_CTRL_SOFT_RESET, mac_index); 1431 ql_mii_write_reg_ex(qdev, CONTROL_REG, PHY_CTRL_SOFT_RESET,
1432 PHYAddr[qdev->mac_index]);
1244} 1433}
1245 1434
1246static void ql_phy_start_neg_ex(struct ql3_adapter *qdev, u32 mac_index) 1435static void ql_phy_start_neg_ex(struct ql3_adapter *qdev)
1247{ 1436{
1248 u16 reg; 1437 u16 reg;
1438 u16 portConfiguration;
1249 1439
1250 ql_mii_write_reg_ex(qdev, PHY_NEG_ADVER, 1440 if(qdev->phyType == PHY_AGERE_ET1011C) {
1251 PHY_NEG_PAUSE | PHY_NEG_ADV_SPEED | 1, mac_index); 1441 /* turn off external loopback */
1442 ql_mii_write_reg(qdev, 0x13, 0x0000);
1443 }
1444
1445 if(qdev->mac_index == 0)
1446 portConfiguration = qdev->nvram_data.macCfg_port0.portConfiguration;
1447 else
1448 portConfiguration = qdev->nvram_data.macCfg_port1.portConfiguration;
1449
1450 /* Some HBA's in the field are set to 0 and they need to
1451 be reinterpreted with a default value */
1452 if(portConfiguration == 0)
1453 portConfiguration = PORT_CONFIG_DEFAULT;
1454
1455 /* Set the 1000 advertisements */
1456 ql_mii_read_reg_ex(qdev, PHY_GIG_CONTROL, &reg,
1457 PHYAddr[qdev->mac_index]);
1458 reg &= ~PHY_GIG_ALL_PARAMS;
1459
1460 if(portConfiguration &
1461 PORT_CONFIG_FULL_DUPLEX_ENABLED &
1462 PORT_CONFIG_1000MB_SPEED) {
1463 reg |= PHY_GIG_ADV_1000F;
1464 }
1465
1466 if(portConfiguration &
1467 PORT_CONFIG_HALF_DUPLEX_ENABLED &
1468 PORT_CONFIG_1000MB_SPEED) {
1469 reg |= PHY_GIG_ADV_1000H;
1470 }
1471
1472 ql_mii_write_reg_ex(qdev, PHY_GIG_CONTROL, reg,
1473 PHYAddr[qdev->mac_index]);
1474
1475 /* Set the 10/100 & pause negotiation advertisements */
1476 ql_mii_read_reg_ex(qdev, PHY_NEG_ADVER, &reg,
1477 PHYAddr[qdev->mac_index]);
1478 reg &= ~PHY_NEG_ALL_PARAMS;
1479
1480 if(portConfiguration & PORT_CONFIG_SYM_PAUSE_ENABLED)
1481 reg |= PHY_NEG_ASY_PAUSE | PHY_NEG_SYM_PAUSE;
1482
1483 if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED) {
1484 if(portConfiguration & PORT_CONFIG_100MB_SPEED)
1485 reg |= PHY_NEG_ADV_100F;
1486
1487 if(portConfiguration & PORT_CONFIG_10MB_SPEED)
1488 reg |= PHY_NEG_ADV_10F;
1489 }
1252 1490
1253 ql_mii_read_reg_ex(qdev, CONTROL_REG, &reg, mac_index); 1491 if(portConfiguration & PORT_CONFIG_HALF_DUPLEX_ENABLED) {
1254 ql_mii_write_reg_ex(qdev, CONTROL_REG, reg | PHY_CTRL_RESTART_NEG, 1492 if(portConfiguration & PORT_CONFIG_100MB_SPEED)
1255 mac_index); 1493 reg |= PHY_NEG_ADV_100H;
1494
1495 if(portConfiguration & PORT_CONFIG_10MB_SPEED)
1496 reg |= PHY_NEG_ADV_10H;
1497 }
1498
1499 if(portConfiguration &
1500 PORT_CONFIG_1000MB_SPEED) {
1501 reg |= 1;
1502 }
1503
1504 ql_mii_write_reg_ex(qdev, PHY_NEG_ADVER, reg,
1505 PHYAddr[qdev->mac_index]);
1506
1507 ql_mii_read_reg_ex(qdev, CONTROL_REG, &reg, PHYAddr[qdev->mac_index]);
1508
1509 ql_mii_write_reg_ex(qdev, CONTROL_REG,
1510 reg | PHY_CTRL_RESTART_NEG | PHY_CTRL_AUTO_NEG,
1511 PHYAddr[qdev->mac_index]);
1256} 1512}
1257 1513
1258static void ql_phy_init_ex(struct ql3_adapter *qdev, u32 mac_index) 1514static void ql_phy_init_ex(struct ql3_adapter *qdev)
1259{ 1515{
1260 ql_phy_reset_ex(qdev, mac_index); 1516 ql_phy_reset_ex(qdev);
1261 ql_phy_start_neg_ex(qdev, mac_index); 1517 PHY_Setup(qdev);
1518 ql_phy_start_neg_ex(qdev);
1262} 1519}
1263 1520
1264/* 1521/*
@@ -1295,14 +1552,17 @@ static int ql_port_start(struct ql3_adapter *qdev)
1295{ 1552{
1296 if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, 1553 if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK,
1297 (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * 1554 (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) *
1298 2) << 7)) 1555 2) << 7)) {
1556 printk(KERN_ERR "%s: Could not get hw lock for GIO\n",
1557 qdev->ndev->name);
1299 return -1; 1558 return -1;
1559 }
1300 1560
1301 if (ql_is_fiber(qdev)) { 1561 if (ql_is_fiber(qdev)) {
1302 ql_petbi_init(qdev); 1562 ql_petbi_init(qdev);
1303 } else { 1563 } else {
1304 /* Copper port */ 1564 /* Copper port */
1305 ql_phy_init_ex(qdev, qdev->mac_index); 1565 ql_phy_init_ex(qdev);
1306 } 1566 }
1307 1567
1308 ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); 1568 ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK);
@@ -1453,7 +1713,7 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
1453 */ 1713 */
1454static void ql_get_phy_owner(struct ql3_adapter *qdev) 1714static void ql_get_phy_owner(struct ql3_adapter *qdev)
1455{ 1715{
1456 if (ql_this_adapter_controls_port(qdev, qdev->mac_index)) 1716 if (ql_this_adapter_controls_port(qdev))
1457 set_bit(QL_LINK_MASTER,&qdev->flags); 1717 set_bit(QL_LINK_MASTER,&qdev->flags);
1458 else 1718 else
1459 clear_bit(QL_LINK_MASTER,&qdev->flags); 1719 clear_bit(QL_LINK_MASTER,&qdev->flags);
@@ -1467,11 +1727,11 @@ static void ql_init_scan_mode(struct ql3_adapter *qdev)
1467 ql_mii_enable_scan_mode(qdev); 1727 ql_mii_enable_scan_mode(qdev);
1468 1728
1469 if (test_bit(QL_LINK_OPTICAL,&qdev->flags)) { 1729 if (test_bit(QL_LINK_OPTICAL,&qdev->flags)) {
1470 if (ql_this_adapter_controls_port(qdev, qdev->mac_index)) 1730 if (ql_this_adapter_controls_port(qdev))
1471 ql_petbi_init_ex(qdev, qdev->mac_index); 1731 ql_petbi_init_ex(qdev);
1472 } else { 1732 } else {
1473 if (ql_this_adapter_controls_port(qdev, qdev->mac_index)) 1733 if (ql_this_adapter_controls_port(qdev))
1474 ql_phy_init_ex(qdev, qdev->mac_index); 1734 ql_phy_init_ex(qdev);
1475 } 1735 }
1476} 1736}
1477 1737
@@ -3092,6 +3352,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev)
3092 goto out; 3352 goto out;
3093 } 3353 }
3094 3354
3355 PHY_Setup(qdev);
3095 ql_init_scan_mode(qdev); 3356 ql_init_scan_mode(qdev);
3096 ql_get_phy_owner(qdev); 3357 ql_get_phy_owner(qdev);
3097 3358
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
index 0203f88f0544..4a832c46c274 100755
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -293,6 +293,16 @@ struct net_rsp_iocb {
293 293
294#define MII_SCAN_REGISTER 0x00000001 294#define MII_SCAN_REGISTER 0x00000001
295 295
296#define PHY_ID_0_REG 2
297#define PHY_ID_1_REG 3
298
299#define PHY_OUI_1_MASK 0xfc00
300#define PHY_MODEL_MASK 0x03f0
301
302/* Address for the Agere Phy */
303#define MII_AGERE_ADDR_1 0x00001000
304#define MII_AGERE_ADDR_2 0x00001100
305
296/* 32-bit ispControlStatus */ 306/* 32-bit ispControlStatus */
297enum { 307enum {
298 ISP_CONTROL_NP_MASK = 0x0003, 308 ISP_CONTROL_NP_MASK = 0x0003,
@@ -789,6 +799,7 @@ enum {
789 PHY_CTRL_LOOPBACK = 0x4000, 799 PHY_CTRL_LOOPBACK = 0x4000,
790 800
791 PETBI_CONTROL_REG = 0x00, 801 PETBI_CONTROL_REG = 0x00,
802 PETBI_CTRL_ALL_PARAMS = 0x7140,
792 PETBI_CTRL_SOFT_RESET = 0x8000, 803 PETBI_CTRL_SOFT_RESET = 0x8000,
793 PETBI_CTRL_AUTO_NEG = 0x1000, 804 PETBI_CTRL_AUTO_NEG = 0x1000,
794 PETBI_CTRL_RESTART_NEG = 0x0200, 805 PETBI_CTRL_RESTART_NEG = 0x0200,
@@ -811,6 +822,23 @@ enum {
811 PETBI_EXPANSION_REG = 0x06, 822 PETBI_EXPANSION_REG = 0x06,
812 PETBI_EXP_PAGE_RX = 0x0002, 823 PETBI_EXP_PAGE_RX = 0x0002,
813 824
825 PHY_GIG_CONTROL = 9,
826 PHY_GIG_ENABLE_MAN = 0x1000, /* Enable Master/Slave Manual Config*/
827 PHY_GIG_SET_MASTER = 0x0800, /* Set Master (slave if clear)*/
828 PHY_GIG_ALL_PARAMS = 0x0300,
829 PHY_GIG_ADV_1000F = 0x0200,
830 PHY_GIG_ADV_1000H = 0x0100,
831
832 PHY_NEG_ADVER = 4,
833 PHY_NEG_ALL_PARAMS = 0x0fe0,
834 PHY_NEG_ASY_PAUSE = 0x0800,
835 PHY_NEG_SYM_PAUSE = 0x0400,
836 PHY_NEG_ADV_SPEED = 0x01e0,
837 PHY_NEG_ADV_100F = 0x0100,
838 PHY_NEG_ADV_100H = 0x0080,
839 PHY_NEG_ADV_10F = 0x0040,
840 PHY_NEG_ADV_10H = 0x0020,
841
814 PETBI_TBI_CTRL = 0x11, 842 PETBI_TBI_CTRL = 0x11,
815 PETBI_TBI_RESET = 0x8000, 843 PETBI_TBI_RESET = 0x8000,
816 PETBI_TBI_AUTO_SENSE = 0x0100, 844 PETBI_TBI_AUTO_SENSE = 0x0100,
@@ -826,8 +854,7 @@ enum {
826 PHY_AUX_RESET_STICK = 0x0002, 854 PHY_AUX_RESET_STICK = 0x0002,
827 PHY_NEG_PAUSE = 0x0400, 855 PHY_NEG_PAUSE = 0x0400,
828 PHY_CTRL_SOFT_RESET = 0x8000, 856 PHY_CTRL_SOFT_RESET = 0x8000,
829 PHY_NEG_ADVER = 4, 857 PHY_CTRL_AUTO_NEG = 0x1000,
830 PHY_NEG_ADV_SPEED = 0x01e0,
831 PHY_CTRL_RESTART_NEG = 0x0200, 858 PHY_CTRL_RESTART_NEG = 0x0200,
832}; 859};
833enum { 860enum {
@@ -892,6 +919,7 @@ enum {EEPROM_SIZE = FM93C86A_SIZE_16,
892 u16 pauseThreshold_mac; 919 u16 pauseThreshold_mac;
893 u16 resumeThreshold_mac; 920 u16 resumeThreshold_mac;
894 u16 portConfiguration; 921 u16 portConfiguration;
922#define PORT_CONFIG_DEFAULT 0xf700
895#define PORT_CONFIG_AUTO_NEG_ENABLED 0x8000 923#define PORT_CONFIG_AUTO_NEG_ENABLED 0x8000
896#define PORT_CONFIG_SYM_PAUSE_ENABLED 0x4000 924#define PORT_CONFIG_SYM_PAUSE_ENABLED 0x4000
897#define PORT_CONFIG_FULL_DUPLEX_ENABLED 0x2000 925#define PORT_CONFIG_FULL_DUPLEX_ENABLED 0x2000
@@ -1259,6 +1287,7 @@ struct ql3_adapter {
1259 struct delayed_work tx_timeout_work; 1287 struct delayed_work tx_timeout_work;
1260 u32 max_frame_size; 1288 u32 max_frame_size;
1261 u32 device_id; 1289 u32 device_id;
1290 u16 phyType;
1262}; 1291};
1263 1292
1264#endif /* _QLA3XXX_H_ */ 1293#endif /* _QLA3XXX_H_ */