aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/niu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/niu.c')
-rw-r--r--drivers/net/niu.c264
1 files changed, 230 insertions, 34 deletions
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index abfc61c3a38c..5f6beabf2d17 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -33,8 +33,8 @@
33 33
34#define DRV_MODULE_NAME "niu" 34#define DRV_MODULE_NAME "niu"
35#define PFX DRV_MODULE_NAME ": " 35#define PFX DRV_MODULE_NAME ": "
36#define DRV_MODULE_VERSION "0.5" 36#define DRV_MODULE_VERSION "0.6"
37#define DRV_MODULE_RELDATE "October 5, 2007" 37#define DRV_MODULE_RELDATE "January 5, 2008"
38 38
39static char version[] __devinitdata = 39static char version[] __devinitdata =
40 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; 40 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
@@ -801,22 +801,90 @@ static int bcm8704_init_user_dev3(struct niu *np)
801 return 0; 801 return 0;
802} 802}
803 803
804static int xcvr_init_10g(struct niu *np) 804static int mrvl88x2011_act_led(struct niu *np, int val)
805{
806 int err;
807
808 err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
809 MRVL88X2011_LED_8_TO_11_CTL);
810 if (err < 0)
811 return err;
812
813 err &= ~MRVL88X2011_LED(MRVL88X2011_LED_ACT,MRVL88X2011_LED_CTL_MASK);
814 err |= MRVL88X2011_LED(MRVL88X2011_LED_ACT,val);
815
816 return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
817 MRVL88X2011_LED_8_TO_11_CTL, err);
818}
819
820static int mrvl88x2011_led_blink_rate(struct niu *np, int rate)
821{
822 int err;
823
824 err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
825 MRVL88X2011_LED_BLINK_CTL);
826 if (err >= 0) {
827 err &= ~MRVL88X2011_LED_BLKRATE_MASK;
828 err |= (rate << 4);
829
830 err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
831 MRVL88X2011_LED_BLINK_CTL, err);
832 }
833
834 return err;
835}
836
837static int xcvr_init_10g_mrvl88x2011(struct niu *np)
838{
839 int err;
840
841 /* Set LED functions */
842 err = mrvl88x2011_led_blink_rate(np, MRVL88X2011_LED_BLKRATE_134MS);
843 if (err)
844 return err;
845
846 /* led activity */
847 err = mrvl88x2011_act_led(np, MRVL88X2011_LED_CTL_OFF);
848 if (err)
849 return err;
850
851 err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
852 MRVL88X2011_GENERAL_CTL);
853 if (err < 0)
854 return err;
855
856 err |= MRVL88X2011_ENA_XFPREFCLK;
857
858 err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
859 MRVL88X2011_GENERAL_CTL, err);
860 if (err < 0)
861 return err;
862
863 err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
864 MRVL88X2011_PMA_PMD_CTL_1);
865 if (err < 0)
866 return err;
867
868 if (np->link_config.loopback_mode == LOOPBACK_MAC)
869 err |= MRVL88X2011_LOOPBACK;
870 else
871 err &= ~MRVL88X2011_LOOPBACK;
872
873 err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
874 MRVL88X2011_PMA_PMD_CTL_1, err);
875 if (err < 0)
876 return err;
877
878 /* Enable PMD */
879 return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
880 MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX);
881}
882
883static int xcvr_init_10g_bcm8704(struct niu *np)
805{ 884{
806 struct niu_link_config *lp = &np->link_config; 885 struct niu_link_config *lp = &np->link_config;
807 u16 analog_stat0, tx_alarm_status; 886 u16 analog_stat0, tx_alarm_status;
808 int err; 887 int err;
809 u64 val;
810
811 val = nr64_mac(XMAC_CONFIG);
812 val &= ~XMAC_CONFIG_LED_POLARITY;
813 val |= XMAC_CONFIG_FORCE_LED_ON;
814 nw64_mac(XMAC_CONFIG, val);
815
816 /* XXX shared resource, lock parent XXX */
817 val = nr64(MIF_CONFIG);
818 val |= MIF_CONFIG_INDIRECT_MODE;
819 nw64(MIF_CONFIG, val);
820 888
821 err = bcm8704_reset(np); 889 err = bcm8704_reset(np);
822 if (err) 890 if (err)
@@ -896,6 +964,38 @@ static int xcvr_init_10g(struct niu *np)
896 return 0; 964 return 0;
897} 965}
898 966
967static int xcvr_init_10g(struct niu *np)
968{
969 int phy_id, err;
970 u64 val;
971
972 val = nr64_mac(XMAC_CONFIG);
973 val &= ~XMAC_CONFIG_LED_POLARITY;
974 val |= XMAC_CONFIG_FORCE_LED_ON;
975 nw64_mac(XMAC_CONFIG, val);
976
977 /* XXX shared resource, lock parent XXX */
978 val = nr64(MIF_CONFIG);
979 val |= MIF_CONFIG_INDIRECT_MODE;
980 nw64(MIF_CONFIG, val);
981
982 phy_id = phy_decode(np->parent->port_phy, np->port);
983 phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
984
985 /* handle different phy types */
986 switch (phy_id & NIU_PHY_ID_MASK) {
987 case NIU_PHY_ID_MRVL88X2011:
988 err = xcvr_init_10g_mrvl88x2011(np);
989 break;
990
991 default: /* bcom 8704 */
992 err = xcvr_init_10g_bcm8704(np);
993 break;
994 }
995
996 return 0;
997}
998
899static int mii_reset(struct niu *np) 999static int mii_reset(struct niu *np)
900{ 1000{
901 int limit, err; 1001 int limit, err;
@@ -1082,19 +1182,68 @@ static int niu_link_status_common(struct niu *np, int link_up)
1082 return 0; 1182 return 0;
1083} 1183}
1084 1184
1085static int link_status_10g(struct niu *np, int *link_up_p) 1185static int link_status_10g_mrvl(struct niu *np, int *link_up_p)
1086{ 1186{
1087 unsigned long flags; 1187 int err, link_up, pma_status, pcs_status;
1088 int err, link_up;
1089 1188
1090 link_up = 0; 1189 link_up = 0;
1091 1190
1092 spin_lock_irqsave(&np->lock, flags); 1191 err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
1192 MRVL88X2011_10G_PMD_STATUS_2);
1193 if (err < 0)
1194 goto out;
1093 1195
1094 err = -EINVAL; 1196 /* Check PMA/PMD Register: 1.0001.2 == 1 */
1095 if (np->link_config.loopback_mode != LOOPBACK_DISABLED) 1197 err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
1198 MRVL88X2011_PMA_PMD_STATUS_1);
1199 if (err < 0)
1200 goto out;
1201
1202 pma_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0);
1203
1204 /* Check PMC Register : 3.0001.2 == 1: read twice */
1205 err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
1206 MRVL88X2011_PMA_PMD_STATUS_1);
1207 if (err < 0)
1208 goto out;
1209
1210 err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
1211 MRVL88X2011_PMA_PMD_STATUS_1);
1212 if (err < 0)
1096 goto out; 1213 goto out;
1097 1214
1215 pcs_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0);
1216
1217 /* Check XGXS Register : 4.0018.[0-3,12] */
1218 err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV4_ADDR,
1219 MRVL88X2011_10G_XGXS_LANE_STAT);
1220 if (err < 0)
1221 goto out;
1222
1223 if (err == (PHYXS_XGXS_LANE_STAT_ALINGED | PHYXS_XGXS_LANE_STAT_LANE3 |
1224 PHYXS_XGXS_LANE_STAT_LANE2 | PHYXS_XGXS_LANE_STAT_LANE1 |
1225 PHYXS_XGXS_LANE_STAT_LANE0 | PHYXS_XGXS_LANE_STAT_MAGIC |
1226 0x800))
1227 link_up = (pma_status && pcs_status) ? 1 : 0;
1228
1229 np->link_config.active_speed = SPEED_10000;
1230 np->link_config.active_duplex = DUPLEX_FULL;
1231 err = 0;
1232out:
1233 mrvl88x2011_act_led(np, (link_up ?
1234 MRVL88X2011_LED_CTL_PCS_ACT :
1235 MRVL88X2011_LED_CTL_OFF));
1236
1237 *link_up_p = link_up;
1238 return err;
1239}
1240
1241static int link_status_10g_bcom(struct niu *np, int *link_up_p)
1242{
1243 int err, link_up;
1244
1245 link_up = 0;
1246
1098 err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR, 1247 err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR,
1099 BCM8704_PMD_RCV_SIGDET); 1248 BCM8704_PMD_RCV_SIGDET);
1100 if (err < 0) 1249 if (err < 0)
@@ -1134,14 +1283,43 @@ static int link_status_10g(struct niu *np, int *link_up_p)
1134 err = 0; 1283 err = 0;
1135 1284
1136out: 1285out:
1286 *link_up_p = link_up;
1287 return err;
1288}
1289
1290static int link_status_10g(struct niu *np, int *link_up_p)
1291{
1292 unsigned long flags;
1293 int err = -EINVAL;
1294
1295 spin_lock_irqsave(&np->lock, flags);
1296
1297 if (np->link_config.loopback_mode == LOOPBACK_DISABLED) {
1298 int phy_id;
1299
1300 phy_id = phy_decode(np->parent->port_phy, np->port);
1301 phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
1302
1303 /* handle different phy types */
1304 switch (phy_id & NIU_PHY_ID_MASK) {
1305 case NIU_PHY_ID_MRVL88X2011:
1306 err = link_status_10g_mrvl(np, link_up_p);
1307 break;
1308
1309 default: /* bcom 8704 */
1310 err = link_status_10g_bcom(np, link_up_p);
1311 break;
1312 }
1313 }
1314
1137 spin_unlock_irqrestore(&np->lock, flags); 1315 spin_unlock_irqrestore(&np->lock, flags);
1138 1316
1139 *link_up_p = link_up;
1140 return err; 1317 return err;
1141} 1318}
1142 1319
1143static int link_status_1g(struct niu *np, int *link_up_p) 1320static int link_status_1g(struct niu *np, int *link_up_p)
1144{ 1321{
1322 struct niu_link_config *lp = &np->link_config;
1145 u16 current_speed, bmsr; 1323 u16 current_speed, bmsr;
1146 unsigned long flags; 1324 unsigned long flags;
1147 u8 current_duplex; 1325 u8 current_duplex;
@@ -1209,6 +1387,8 @@ static int link_status_1g(struct niu *np, int *link_up_p)
1209 link_up = 0; 1387 link_up = 0;
1210 } 1388 }
1211 } 1389 }
1390 lp->active_speed = current_speed;
1391 lp->active_duplex = current_duplex;
1212 err = 0; 1392 err = 0;
1213 1393
1214out: 1394out:
@@ -2241,6 +2421,8 @@ static int niu_process_rx_pkt(struct niu *np, struct rx_ring_info *rp)
2241 skb->protocol = eth_type_trans(skb, np->dev); 2421 skb->protocol = eth_type_trans(skb, np->dev);
2242 netif_receive_skb(skb); 2422 netif_receive_skb(skb);
2243 2423
2424 np->dev->last_rx = jiffies;
2425
2244 return num_rcr; 2426 return num_rcr;
2245} 2427}
2246 2428
@@ -2508,15 +2690,19 @@ static int niu_rx_error(struct niu *np, struct rx_ring_info *rp)
2508 u64 stat = nr64(RX_DMA_CTL_STAT(rp->rx_channel)); 2690 u64 stat = nr64(RX_DMA_CTL_STAT(rp->rx_channel));
2509 int err = 0; 2691 int err = 0;
2510 2692
2511 dev_err(np->device, PFX "%s: RX channel %u error, stat[%llx]\n",
2512 np->dev->name, rp->rx_channel, (unsigned long long) stat);
2513
2514 niu_log_rxchan_errors(np, rp, stat);
2515 2693
2516 if (stat & (RX_DMA_CTL_STAT_CHAN_FATAL | 2694 if (stat & (RX_DMA_CTL_STAT_CHAN_FATAL |
2517 RX_DMA_CTL_STAT_PORT_FATAL)) 2695 RX_DMA_CTL_STAT_PORT_FATAL))
2518 err = -EINVAL; 2696 err = -EINVAL;
2519 2697
2698 if (err) {
2699 dev_err(np->device, PFX "%s: RX channel %u error, stat[%llx]\n",
2700 np->dev->name, rp->rx_channel,
2701 (unsigned long long) stat);
2702
2703 niu_log_rxchan_errors(np, rp, stat);
2704 }
2705
2520 nw64(RX_DMA_CTL_STAT(rp->rx_channel), 2706 nw64(RX_DMA_CTL_STAT(rp->rx_channel),
2521 stat & RX_DMA_CTL_WRITE_CLEAR_ERRS); 2707 stat & RX_DMA_CTL_WRITE_CLEAR_ERRS);
2522 2708
@@ -2749,13 +2935,16 @@ static int niu_device_error(struct niu *np)
2749 return -ENODEV; 2935 return -ENODEV;
2750} 2936}
2751 2937
2752static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp) 2938static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp,
2939 u64 v0, u64 v1, u64 v2)
2753{ 2940{
2754 u64 v0 = lp->v0; 2941
2755 u64 v1 = lp->v1;
2756 u64 v2 = lp->v2;
2757 int i, err = 0; 2942 int i, err = 0;
2758 2943
2944 lp->v0 = v0;
2945 lp->v1 = v1;
2946 lp->v2 = v2;
2947
2759 if (v1 & 0x00000000ffffffffULL) { 2948 if (v1 & 0x00000000ffffffffULL) {
2760 u32 rx_vec = (v1 & 0xffffffff); 2949 u32 rx_vec = (v1 & 0xffffffff);
2761 2950
@@ -2764,8 +2953,13 @@ static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp)
2764 2953
2765 if (rx_vec & (1 << rp->rx_channel)) { 2954 if (rx_vec & (1 << rp->rx_channel)) {
2766 int r = niu_rx_error(np, rp); 2955 int r = niu_rx_error(np, rp);
2767 if (r) 2956 if (r) {
2768 err = r; 2957 err = r;
2958 } else {
2959 if (!v0)
2960 nw64(RX_DMA_CTL_STAT(rp->rx_channel),
2961 RX_DMA_CTL_STAT_MEX);
2962 }
2769 } 2963 }
2770 } 2964 }
2771 } 2965 }
@@ -2803,7 +2997,7 @@ static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp)
2803 if (err) 2997 if (err)
2804 niu_enable_interrupts(np, 0); 2998 niu_enable_interrupts(np, 0);
2805 2999
2806 return -EINVAL; 3000 return err;
2807} 3001}
2808 3002
2809static void niu_rxchan_intr(struct niu *np, struct rx_ring_info *rp, 3003static void niu_rxchan_intr(struct niu *np, struct rx_ring_info *rp,
@@ -2905,7 +3099,7 @@ static irqreturn_t niu_interrupt(int irq, void *dev_id)
2905 } 3099 }
2906 3100
2907 if (unlikely((v0 & ((u64)1 << LDN_MIF)) || v1 || v2)) { 3101 if (unlikely((v0 & ((u64)1 << LDN_MIF)) || v1 || v2)) {
2908 int err = niu_slowpath_interrupt(np, lp); 3102 int err = niu_slowpath_interrupt(np, lp, v0, v1, v2);
2909 if (err) 3103 if (err)
2910 goto out; 3104 goto out;
2911 } 3105 }
@@ -5194,7 +5388,8 @@ static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev)
5194 } 5388 }
5195 kfree_skb(skb); 5389 kfree_skb(skb);
5196 skb = skb_new; 5390 skb = skb_new;
5197 } 5391 } else
5392 skb_orphan(skb);
5198 5393
5199 align = ((unsigned long) skb->data & (16 - 1)); 5394 align = ((unsigned long) skb->data & (16 - 1));
5200 headroom = align + sizeof(struct tx_pkt_hdr); 5395 headroom = align + sizeof(struct tx_pkt_hdr);
@@ -6282,7 +6477,8 @@ static int __devinit phy_record(struct niu_parent *parent,
6282 if (dev_id_1 < 0 || dev_id_2 < 0) 6477 if (dev_id_1 < 0 || dev_id_2 < 0)
6283 return 0; 6478 return 0;
6284 if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) { 6479 if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) {
6285 if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) 6480 if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) &&
6481 ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011))
6286 return 0; 6482 return 0;
6287 } else { 6483 } else {
6288 if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R) 6484 if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R)