diff options
author | Claudiu Manoil <claudiu.manoil@freescale.com> | 2014-02-17 05:53:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-02-18 15:03:01 -0500 |
commit | 208627883ecfaa182c266eb67178bb71d392af54 (patch) | |
tree | 92514547385e7083c09cd05c247a59a29662a614 | |
parent | c85fde8336ec6c062d65a5c1bca2ca78028111ae (diff) |
gianfar: Cleanup/Fix gfar_probe and the hw init code
Factor out gfar_hw_init() to contain all the controller hw
initialization steps for a better control of register writes,
and to significantly simplify the tangled code from gfar_probe().
This results in code size and stack usage reduction (besides
code readability).
Fix memory leak on device removal, by freeing the rx_/tx_queue
structures.
Replace custom bit swapping function with a library one (bitrev8).
Move allocation of rx_/tx_queue struct arrays before the group
structure init, because in order to assign Rx/Tx queues
to groups we need to have the queues first. This also allows
earlier bail out of gfar_probe(), in case the memory allocation
fails.
The flow control checks for maccfg1 were removed from gfar_probe(),
since flow control is disabled at probe time (priv->rx_/tx_pause_en
are 0). Redundant initializations (by 0) also removed.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 331 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.h | 34 |
2 files changed, 188 insertions, 177 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index ad5a5aadc7e1..ab915b060d4c 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * Maintainer: Kumar Gala | 9 | * Maintainer: Kumar Gala |
10 | * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com> | 10 | * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com> |
11 | * | 11 | * |
12 | * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc. | 12 | * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc. |
13 | * Copyright 2007 MontaVista Software, Inc. | 13 | * Copyright 2007 MontaVista Software, Inc. |
14 | * | 14 | * |
15 | * This program is free software; you can redistribute it and/or modify it | 15 | * This program is free software; you can redistribute it and/or modify it |
@@ -511,7 +511,43 @@ void unlock_tx_qs(struct gfar_private *priv) | |||
511 | spin_unlock(&priv->tx_queue[i]->txlock); | 511 | spin_unlock(&priv->tx_queue[i]->txlock); |
512 | } | 512 | } |
513 | 513 | ||
514 | static void free_tx_pointers(struct gfar_private *priv) | 514 | static int gfar_alloc_tx_queues(struct gfar_private *priv) |
515 | { | ||
516 | int i; | ||
517 | |||
518 | for (i = 0; i < priv->num_tx_queues; i++) { | ||
519 | priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q), | ||
520 | GFP_KERNEL); | ||
521 | if (!priv->tx_queue[i]) | ||
522 | return -ENOMEM; | ||
523 | |||
524 | priv->tx_queue[i]->tx_skbuff = NULL; | ||
525 | priv->tx_queue[i]->qindex = i; | ||
526 | priv->tx_queue[i]->dev = priv->ndev; | ||
527 | spin_lock_init(&(priv->tx_queue[i]->txlock)); | ||
528 | } | ||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static int gfar_alloc_rx_queues(struct gfar_private *priv) | ||
533 | { | ||
534 | int i; | ||
535 | |||
536 | for (i = 0; i < priv->num_rx_queues; i++) { | ||
537 | priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q), | ||
538 | GFP_KERNEL); | ||
539 | if (!priv->rx_queue[i]) | ||
540 | return -ENOMEM; | ||
541 | |||
542 | priv->rx_queue[i]->rx_skbuff = NULL; | ||
543 | priv->rx_queue[i]->qindex = i; | ||
544 | priv->rx_queue[i]->dev = priv->ndev; | ||
545 | spin_lock_init(&(priv->rx_queue[i]->rxlock)); | ||
546 | } | ||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | static void gfar_free_tx_queues(struct gfar_private *priv) | ||
515 | { | 551 | { |
516 | int i; | 552 | int i; |
517 | 553 | ||
@@ -519,7 +555,7 @@ static void free_tx_pointers(struct gfar_private *priv) | |||
519 | kfree(priv->tx_queue[i]); | 555 | kfree(priv->tx_queue[i]); |
520 | } | 556 | } |
521 | 557 | ||
522 | static void free_rx_pointers(struct gfar_private *priv) | 558 | static void gfar_free_rx_queues(struct gfar_private *priv) |
523 | { | 559 | { |
524 | int i; | 560 | int i; |
525 | 561 | ||
@@ -608,6 +644,30 @@ static int gfar_parse_group(struct device_node *np, | |||
608 | grp->rx_bit_map = 0xFF; | 644 | grp->rx_bit_map = 0xFF; |
609 | grp->tx_bit_map = 0xFF; | 645 | grp->tx_bit_map = 0xFF; |
610 | } | 646 | } |
647 | |||
648 | /* bit_map's MSB is q0 (from q0 to q7) but, for_each_set_bit parses | ||
649 | * right to left, so we need to revert the 8 bits to get the q index | ||
650 | */ | ||
651 | grp->rx_bit_map = bitrev8(grp->rx_bit_map); | ||
652 | grp->tx_bit_map = bitrev8(grp->tx_bit_map); | ||
653 | |||
654 | /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values, | ||
655 | * also assign queues to groups | ||
656 | */ | ||
657 | for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) { | ||
658 | grp->num_rx_queues++; | ||
659 | grp->rstat |= (RSTAT_CLEAR_RHALT >> i); | ||
660 | priv->rqueue |= ((RQUEUE_EN0 | RQUEUE_EX0) >> i); | ||
661 | priv->rx_queue[i]->grp = grp; | ||
662 | } | ||
663 | |||
664 | for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) { | ||
665 | grp->num_tx_queues++; | ||
666 | grp->tstat |= (TSTAT_CLEAR_THALT >> i); | ||
667 | priv->tqueue |= (TQUEUE_EN0 >> i); | ||
668 | priv->tx_queue[i]->grp = grp; | ||
669 | } | ||
670 | |||
611 | priv->num_grps++; | 671 | priv->num_grps++; |
612 | 672 | ||
613 | return 0; | 673 | return 0; |
@@ -664,7 +724,14 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
664 | priv->num_tx_queues = num_tx_qs; | 724 | priv->num_tx_queues = num_tx_qs; |
665 | netif_set_real_num_rx_queues(dev, num_rx_qs); | 725 | netif_set_real_num_rx_queues(dev, num_rx_qs); |
666 | priv->num_rx_queues = num_rx_qs; | 726 | priv->num_rx_queues = num_rx_qs; |
667 | priv->num_grps = 0x0; | 727 | |
728 | err = gfar_alloc_tx_queues(priv); | ||
729 | if (err) | ||
730 | goto tx_alloc_failed; | ||
731 | |||
732 | err = gfar_alloc_rx_queues(priv); | ||
733 | if (err) | ||
734 | goto rx_alloc_failed; | ||
668 | 735 | ||
669 | /* Init Rx queue filer rule set linked list */ | 736 | /* Init Rx queue filer rule set linked list */ |
670 | INIT_LIST_HEAD(&priv->rx_list.list); | 737 | INIT_LIST_HEAD(&priv->rx_list.list); |
@@ -691,38 +758,6 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
691 | goto err_grp_init; | 758 | goto err_grp_init; |
692 | } | 759 | } |
693 | 760 | ||
694 | for (i = 0; i < priv->num_tx_queues; i++) | ||
695 | priv->tx_queue[i] = NULL; | ||
696 | for (i = 0; i < priv->num_rx_queues; i++) | ||
697 | priv->rx_queue[i] = NULL; | ||
698 | |||
699 | for (i = 0; i < priv->num_tx_queues; i++) { | ||
700 | priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q), | ||
701 | GFP_KERNEL); | ||
702 | if (!priv->tx_queue[i]) { | ||
703 | err = -ENOMEM; | ||
704 | goto tx_alloc_failed; | ||
705 | } | ||
706 | priv->tx_queue[i]->tx_skbuff = NULL; | ||
707 | priv->tx_queue[i]->qindex = i; | ||
708 | priv->tx_queue[i]->dev = dev; | ||
709 | spin_lock_init(&(priv->tx_queue[i]->txlock)); | ||
710 | } | ||
711 | |||
712 | for (i = 0; i < priv->num_rx_queues; i++) { | ||
713 | priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q), | ||
714 | GFP_KERNEL); | ||
715 | if (!priv->rx_queue[i]) { | ||
716 | err = -ENOMEM; | ||
717 | goto rx_alloc_failed; | ||
718 | } | ||
719 | priv->rx_queue[i]->rx_skbuff = NULL; | ||
720 | priv->rx_queue[i]->qindex = i; | ||
721 | priv->rx_queue[i]->dev = dev; | ||
722 | spin_lock_init(&(priv->rx_queue[i]->rxlock)); | ||
723 | } | ||
724 | |||
725 | |||
726 | stash = of_get_property(np, "bd-stash", NULL); | 761 | stash = of_get_property(np, "bd-stash", NULL); |
727 | 762 | ||
728 | if (stash) { | 763 | if (stash) { |
@@ -784,12 +819,12 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
784 | 819 | ||
785 | return 0; | 820 | return 0; |
786 | 821 | ||
787 | rx_alloc_failed: | ||
788 | free_rx_pointers(priv); | ||
789 | tx_alloc_failed: | ||
790 | free_tx_pointers(priv); | ||
791 | err_grp_init: | 822 | err_grp_init: |
792 | unmap_group_regs(priv); | 823 | unmap_group_regs(priv); |
824 | rx_alloc_failed: | ||
825 | gfar_free_rx_queues(priv); | ||
826 | tx_alloc_failed: | ||
827 | gfar_free_tx_queues(priv); | ||
793 | free_gfar_dev(priv); | 828 | free_gfar_dev(priv); |
794 | return err; | 829 | return err; |
795 | } | 830 | } |
@@ -875,19 +910,6 @@ static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
875 | return phy_mii_ioctl(priv->phydev, rq, cmd); | 910 | return phy_mii_ioctl(priv->phydev, rq, cmd); |
876 | } | 911 | } |
877 | 912 | ||
878 | static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs) | ||
879 | { | ||
880 | unsigned int new_bit_map = 0x0; | ||
881 | int mask = 0x1 << (max_qs - 1), i; | ||
882 | |||
883 | for (i = 0; i < max_qs; i++) { | ||
884 | if (bit_map & mask) | ||
885 | new_bit_map = new_bit_map + (1 << i); | ||
886 | mask = mask >> 0x1; | ||
887 | } | ||
888 | return new_bit_map; | ||
889 | } | ||
890 | |||
891 | static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar, | 913 | static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar, |
892 | u32 class) | 914 | u32 class) |
893 | { | 915 | { |
@@ -1005,19 +1027,88 @@ static void gfar_detect_errata(struct gfar_private *priv) | |||
1005 | priv->errata); | 1027 | priv->errata); |
1006 | } | 1028 | } |
1007 | 1029 | ||
1030 | static void gfar_hw_init(struct gfar_private *priv) | ||
1031 | { | ||
1032 | struct gfar __iomem *regs = priv->gfargrp[0].regs; | ||
1033 | u32 tempval; | ||
1034 | |||
1035 | /* Reset MAC layer */ | ||
1036 | gfar_write(®s->maccfg1, MACCFG1_SOFT_RESET); | ||
1037 | |||
1038 | /* We need to delay at least 3 TX clocks */ | ||
1039 | udelay(2); | ||
1040 | |||
1041 | /* the soft reset bit is not self-resetting, so we need to | ||
1042 | * clear it before resuming normal operation | ||
1043 | */ | ||
1044 | gfar_write(®s->maccfg1, 0); | ||
1045 | |||
1046 | /* Initialize MACCFG2. */ | ||
1047 | tempval = MACCFG2_INIT_SETTINGS; | ||
1048 | if (gfar_has_errata(priv, GFAR_ERRATA_74)) | ||
1049 | tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK; | ||
1050 | gfar_write(®s->maccfg2, tempval); | ||
1051 | |||
1052 | /* Initialize ECNTRL */ | ||
1053 | gfar_write(®s->ecntrl, ECNTRL_INIT_SETTINGS); | ||
1054 | |||
1055 | /* Program the interrupt steering regs, only for MG devices */ | ||
1056 | if (priv->num_grps > 1) | ||
1057 | gfar_write_isrg(priv); | ||
1058 | |||
1059 | /* Enable all Rx/Tx queues after MAC reset */ | ||
1060 | gfar_write(®s->rqueue, priv->rqueue); | ||
1061 | gfar_write(®s->tqueue, priv->tqueue); | ||
1062 | } | ||
1063 | |||
1064 | static void __init gfar_init_addr_hash_table(struct gfar_private *priv) | ||
1065 | { | ||
1066 | struct gfar __iomem *regs = priv->gfargrp[0].regs; | ||
1067 | |||
1068 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { | ||
1069 | priv->extended_hash = 1; | ||
1070 | priv->hash_width = 9; | ||
1071 | |||
1072 | priv->hash_regs[0] = ®s->igaddr0; | ||
1073 | priv->hash_regs[1] = ®s->igaddr1; | ||
1074 | priv->hash_regs[2] = ®s->igaddr2; | ||
1075 | priv->hash_regs[3] = ®s->igaddr3; | ||
1076 | priv->hash_regs[4] = ®s->igaddr4; | ||
1077 | priv->hash_regs[5] = ®s->igaddr5; | ||
1078 | priv->hash_regs[6] = ®s->igaddr6; | ||
1079 | priv->hash_regs[7] = ®s->igaddr7; | ||
1080 | priv->hash_regs[8] = ®s->gaddr0; | ||
1081 | priv->hash_regs[9] = ®s->gaddr1; | ||
1082 | priv->hash_regs[10] = ®s->gaddr2; | ||
1083 | priv->hash_regs[11] = ®s->gaddr3; | ||
1084 | priv->hash_regs[12] = ®s->gaddr4; | ||
1085 | priv->hash_regs[13] = ®s->gaddr5; | ||
1086 | priv->hash_regs[14] = ®s->gaddr6; | ||
1087 | priv->hash_regs[15] = ®s->gaddr7; | ||
1088 | |||
1089 | } else { | ||
1090 | priv->extended_hash = 0; | ||
1091 | priv->hash_width = 8; | ||
1092 | |||
1093 | priv->hash_regs[0] = ®s->gaddr0; | ||
1094 | priv->hash_regs[1] = ®s->gaddr1; | ||
1095 | priv->hash_regs[2] = ®s->gaddr2; | ||
1096 | priv->hash_regs[3] = ®s->gaddr3; | ||
1097 | priv->hash_regs[4] = ®s->gaddr4; | ||
1098 | priv->hash_regs[5] = ®s->gaddr5; | ||
1099 | priv->hash_regs[6] = ®s->gaddr6; | ||
1100 | priv->hash_regs[7] = ®s->gaddr7; | ||
1101 | } | ||
1102 | } | ||
1103 | |||
1008 | /* Set up the ethernet device structure, private data, | 1104 | /* Set up the ethernet device structure, private data, |
1009 | * and anything else we need before we start | 1105 | * and anything else we need before we start |
1010 | */ | 1106 | */ |
1011 | static int gfar_probe(struct platform_device *ofdev) | 1107 | static int gfar_probe(struct platform_device *ofdev) |
1012 | { | 1108 | { |
1013 | u32 tempval; | ||
1014 | struct net_device *dev = NULL; | 1109 | struct net_device *dev = NULL; |
1015 | struct gfar_private *priv = NULL; | 1110 | struct gfar_private *priv = NULL; |
1016 | struct gfar __iomem *regs = NULL; | 1111 | int err = 0, i; |
1017 | int err = 0, i, grp_idx = 0; | ||
1018 | u32 rstat = 0, tstat = 0, rqueue = 0, tqueue = 0; | ||
1019 | u32 isrg = 0; | ||
1020 | u32 __iomem *baddr; | ||
1021 | 1112 | ||
1022 | err = gfar_of_init(ofdev, &dev); | 1113 | err = gfar_of_init(ofdev, &dev); |
1023 | 1114 | ||
@@ -1034,7 +1125,6 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1034 | INIT_WORK(&priv->reset_task, gfar_reset_task); | 1125 | INIT_WORK(&priv->reset_task, gfar_reset_task); |
1035 | 1126 | ||
1036 | platform_set_drvdata(ofdev, priv); | 1127 | platform_set_drvdata(ofdev, priv); |
1037 | regs = priv->gfargrp[0].regs; | ||
1038 | 1128 | ||
1039 | gfar_detect_errata(priv); | 1129 | gfar_detect_errata(priv); |
1040 | 1130 | ||
@@ -1043,33 +1133,10 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1043 | */ | 1133 | */ |
1044 | gfar_halt(dev); | 1134 | gfar_halt(dev); |
1045 | 1135 | ||
1046 | /* Reset MAC layer */ | 1136 | gfar_hw_init(priv); |
1047 | gfar_write(®s->maccfg1, MACCFG1_SOFT_RESET); | ||
1048 | |||
1049 | /* We need to delay at least 3 TX clocks */ | ||
1050 | udelay(2); | ||
1051 | |||
1052 | tempval = 0; | ||
1053 | if (!priv->pause_aneg_en && priv->tx_pause_en) | ||
1054 | tempval |= MACCFG1_TX_FLOW; | ||
1055 | if (!priv->pause_aneg_en && priv->rx_pause_en) | ||
1056 | tempval |= MACCFG1_RX_FLOW; | ||
1057 | /* the soft reset bit is not self-resetting, so we need to | ||
1058 | * clear it before resuming normal operation | ||
1059 | */ | ||
1060 | gfar_write(®s->maccfg1, tempval); | ||
1061 | |||
1062 | /* Initialize MACCFG2. */ | ||
1063 | tempval = MACCFG2_INIT_SETTINGS; | ||
1064 | if (gfar_has_errata(priv, GFAR_ERRATA_74)) | ||
1065 | tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK; | ||
1066 | gfar_write(®s->maccfg2, tempval); | ||
1067 | |||
1068 | /* Initialize ECNTRL */ | ||
1069 | gfar_write(®s->ecntrl, ECNTRL_INIT_SETTINGS); | ||
1070 | 1137 | ||
1071 | /* Set the dev->base_addr to the gfar reg region */ | 1138 | /* Set the dev->base_addr to the gfar reg region */ |
1072 | dev->base_addr = (unsigned long) regs; | 1139 | dev->base_addr = (unsigned long) priv->gfargrp[0].regs; |
1073 | 1140 | ||
1074 | /* Fill in the dev structure */ | 1141 | /* Fill in the dev structure */ |
1075 | dev->watchdog_timeo = TX_TIMEOUT; | 1142 | dev->watchdog_timeo = TX_TIMEOUT; |
@@ -1099,40 +1166,7 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1099 | dev->features |= NETIF_F_HW_VLAN_CTAG_RX; | 1166 | dev->features |= NETIF_F_HW_VLAN_CTAG_RX; |
1100 | } | 1167 | } |
1101 | 1168 | ||
1102 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { | 1169 | gfar_init_addr_hash_table(priv); |
1103 | priv->extended_hash = 1; | ||
1104 | priv->hash_width = 9; | ||
1105 | |||
1106 | priv->hash_regs[0] = ®s->igaddr0; | ||
1107 | priv->hash_regs[1] = ®s->igaddr1; | ||
1108 | priv->hash_regs[2] = ®s->igaddr2; | ||
1109 | priv->hash_regs[3] = ®s->igaddr3; | ||
1110 | priv->hash_regs[4] = ®s->igaddr4; | ||
1111 | priv->hash_regs[5] = ®s->igaddr5; | ||
1112 | priv->hash_regs[6] = ®s->igaddr6; | ||
1113 | priv->hash_regs[7] = ®s->igaddr7; | ||
1114 | priv->hash_regs[8] = ®s->gaddr0; | ||
1115 | priv->hash_regs[9] = ®s->gaddr1; | ||
1116 | priv->hash_regs[10] = ®s->gaddr2; | ||
1117 | priv->hash_regs[11] = ®s->gaddr3; | ||
1118 | priv->hash_regs[12] = ®s->gaddr4; | ||
1119 | priv->hash_regs[13] = ®s->gaddr5; | ||
1120 | priv->hash_regs[14] = ®s->gaddr6; | ||
1121 | priv->hash_regs[15] = ®s->gaddr7; | ||
1122 | |||
1123 | } else { | ||
1124 | priv->extended_hash = 0; | ||
1125 | priv->hash_width = 8; | ||
1126 | |||
1127 | priv->hash_regs[0] = ®s->gaddr0; | ||
1128 | priv->hash_regs[1] = ®s->gaddr1; | ||
1129 | priv->hash_regs[2] = ®s->gaddr2; | ||
1130 | priv->hash_regs[3] = ®s->gaddr3; | ||
1131 | priv->hash_regs[4] = ®s->gaddr4; | ||
1132 | priv->hash_regs[5] = ®s->gaddr5; | ||
1133 | priv->hash_regs[6] = ®s->gaddr6; | ||
1134 | priv->hash_regs[7] = ®s->gaddr7; | ||
1135 | } | ||
1136 | 1170 | ||
1137 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_PADDING) | 1171 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_PADDING) |
1138 | priv->padding = DEFAULT_PADDING; | 1172 | priv->padding = DEFAULT_PADDING; |
@@ -1143,59 +1177,6 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1143 | priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) | 1177 | priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) |
1144 | dev->needed_headroom = GMAC_FCB_LEN; | 1178 | dev->needed_headroom = GMAC_FCB_LEN; |
1145 | 1179 | ||
1146 | /* Program the isrg regs only if number of grps > 1 */ | ||
1147 | if (priv->num_grps > 1) { | ||
1148 | baddr = ®s->isrg0; | ||
1149 | for (i = 0; i < priv->num_grps; i++) { | ||
1150 | isrg |= (priv->gfargrp[i].rx_bit_map << ISRG_SHIFT_RX); | ||
1151 | isrg |= (priv->gfargrp[i].tx_bit_map << ISRG_SHIFT_TX); | ||
1152 | gfar_write(baddr, isrg); | ||
1153 | baddr++; | ||
1154 | isrg = 0x0; | ||
1155 | } | ||
1156 | } | ||
1157 | |||
1158 | /* Need to reverse the bit maps as bit_map's MSB is q0 | ||
1159 | * but, for_each_set_bit parses from right to left, which | ||
1160 | * basically reverses the queue numbers | ||
1161 | */ | ||
1162 | for (i = 0; i< priv->num_grps; i++) { | ||
1163 | priv->gfargrp[i].tx_bit_map = | ||
1164 | reverse_bitmap(priv->gfargrp[i].tx_bit_map, MAX_TX_QS); | ||
1165 | priv->gfargrp[i].rx_bit_map = | ||
1166 | reverse_bitmap(priv->gfargrp[i].rx_bit_map, MAX_RX_QS); | ||
1167 | } | ||
1168 | |||
1169 | /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values, | ||
1170 | * also assign queues to groups | ||
1171 | */ | ||
1172 | for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) { | ||
1173 | priv->gfargrp[grp_idx].num_rx_queues = 0x0; | ||
1174 | |||
1175 | for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map, | ||
1176 | priv->num_rx_queues) { | ||
1177 | priv->gfargrp[grp_idx].num_rx_queues++; | ||
1178 | priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx]; | ||
1179 | rstat = rstat | (RSTAT_CLEAR_RHALT >> i); | ||
1180 | rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i); | ||
1181 | } | ||
1182 | priv->gfargrp[grp_idx].num_tx_queues = 0x0; | ||
1183 | |||
1184 | for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map, | ||
1185 | priv->num_tx_queues) { | ||
1186 | priv->gfargrp[grp_idx].num_tx_queues++; | ||
1187 | priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx]; | ||
1188 | tstat = tstat | (TSTAT_CLEAR_THALT >> i); | ||
1189 | tqueue = tqueue | (TQUEUE_EN0 >> i); | ||
1190 | } | ||
1191 | priv->gfargrp[grp_idx].rstat = rstat; | ||
1192 | priv->gfargrp[grp_idx].tstat = tstat; | ||
1193 | rstat = tstat =0; | ||
1194 | } | ||
1195 | |||
1196 | gfar_write(®s->rqueue, rqueue); | ||
1197 | gfar_write(®s->tqueue, tqueue); | ||
1198 | |||
1199 | priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE; | 1180 | priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE; |
1200 | 1181 | ||
1201 | /* Initializing some of the rx/tx queue level parameters */ | 1182 | /* Initializing some of the rx/tx queue level parameters */ |
@@ -1272,8 +1253,8 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1272 | 1253 | ||
1273 | register_fail: | 1254 | register_fail: |
1274 | unmap_group_regs(priv); | 1255 | unmap_group_regs(priv); |
1275 | free_tx_pointers(priv); | 1256 | gfar_free_rx_queues(priv); |
1276 | free_rx_pointers(priv); | 1257 | gfar_free_tx_queues(priv); |
1277 | if (priv->phy_node) | 1258 | if (priv->phy_node) |
1278 | of_node_put(priv->phy_node); | 1259 | of_node_put(priv->phy_node); |
1279 | if (priv->tbi_node) | 1260 | if (priv->tbi_node) |
@@ -1293,6 +1274,8 @@ static int gfar_remove(struct platform_device *ofdev) | |||
1293 | 1274 | ||
1294 | unregister_netdev(priv->ndev); | 1275 | unregister_netdev(priv->ndev); |
1295 | unmap_group_regs(priv); | 1276 | unmap_group_regs(priv); |
1277 | gfar_free_rx_queues(priv); | ||
1278 | gfar_free_tx_queues(priv); | ||
1296 | free_gfar_dev(priv); | 1279 | free_gfar_dev(priv); |
1297 | 1280 | ||
1298 | return 0; | 1281 | return 0; |
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 52bb2b0195cc..63c830c3181b 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h | |||
@@ -9,7 +9,7 @@ | |||
9 | * Maintainer: Kumar Gala | 9 | * Maintainer: Kumar Gala |
10 | * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com> | 10 | * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com> |
11 | * | 11 | * |
12 | * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc. | 12 | * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc. |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify it | 14 | * This program is free software; you can redistribute it and/or modify it |
15 | * under the terms of the GNU General Public License as published by the | 15 | * under the terms of the GNU General Public License as published by the |
@@ -892,8 +892,8 @@ struct gfar { | |||
892 | #define DEFAULT_MAPPING 0xFF | 892 | #define DEFAULT_MAPPING 0xFF |
893 | #endif | 893 | #endif |
894 | 894 | ||
895 | #define ISRG_SHIFT_TX 0x10 | 895 | #define ISRG_RR0 0x80000000 |
896 | #define ISRG_SHIFT_RX 0x18 | 896 | #define ISRG_TR0 0x00800000 |
897 | 897 | ||
898 | /* The same driver can operate in two modes */ | 898 | /* The same driver can operate in two modes */ |
899 | /* SQ_SG_MODE: Single Queue Single Group Mode | 899 | /* SQ_SG_MODE: Single Queue Single Group Mode |
@@ -1113,6 +1113,9 @@ struct gfar_private { | |||
1113 | unsigned int total_tx_ring_size; | 1113 | unsigned int total_tx_ring_size; |
1114 | unsigned int total_rx_ring_size; | 1114 | unsigned int total_rx_ring_size; |
1115 | 1115 | ||
1116 | u32 rqueue; | ||
1117 | u32 tqueue; | ||
1118 | |||
1116 | /* RX per device parameters */ | 1119 | /* RX per device parameters */ |
1117 | unsigned int rx_stash_size; | 1120 | unsigned int rx_stash_size; |
1118 | unsigned int rx_stash_index; | 1121 | unsigned int rx_stash_index; |
@@ -1176,6 +1179,31 @@ static inline void gfar_read_filer(struct gfar_private *priv, | |||
1176 | *fpr = gfar_read(®s->rqfpr); | 1179 | *fpr = gfar_read(®s->rqfpr); |
1177 | } | 1180 | } |
1178 | 1181 | ||
1182 | static inline void gfar_write_isrg(struct gfar_private *priv) | ||
1183 | { | ||
1184 | struct gfar __iomem *regs = priv->gfargrp[0].regs; | ||
1185 | u32 __iomem *baddr = ®s->isrg0; | ||
1186 | u32 isrg = 0; | ||
1187 | int grp_idx, i; | ||
1188 | |||
1189 | for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) { | ||
1190 | struct gfar_priv_grp *grp = &priv->gfargrp[grp_idx]; | ||
1191 | |||
1192 | for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) { | ||
1193 | isrg |= (ISRG_RR0 >> i); | ||
1194 | } | ||
1195 | |||
1196 | for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) { | ||
1197 | isrg |= (ISRG_TR0 >> i); | ||
1198 | } | ||
1199 | |||
1200 | gfar_write(baddr, isrg); | ||
1201 | |||
1202 | baddr++; | ||
1203 | isrg = 0; | ||
1204 | } | ||
1205 | } | ||
1206 | |||
1179 | void lock_rx_qs(struct gfar_private *priv); | 1207 | void lock_rx_qs(struct gfar_private *priv); |
1180 | void lock_tx_qs(struct gfar_private *priv); | 1208 | void lock_tx_qs(struct gfar_private *priv); |
1181 | void unlock_rx_qs(struct gfar_private *priv); | 1209 | void unlock_rx_qs(struct gfar_private *priv); |