diff options
author | David S. Miller <davem@davemloft.net> | 2013-08-16 18:37:26 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-16 18:37:26 -0400 |
commit | 2ff1cf12c9fe70e75e600404e6a4274b19d293ed (patch) | |
tree | beafddac0a8098e3f07d2ec60e44a2a7d006e605 /drivers/net/ethernet/stmicro/stmmac | |
parent | 16b304f3404f8e0243d5ee2b70b68767b7b59b2b (diff) | |
parent | 0f7dd1aa8f959216f1faa71513b9d3c1a9065e5a (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 111 |
2 files changed, 103 insertions, 21 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index c9d942a5c335..1ef9d8a555aa 100644 --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c | |||
@@ -33,10 +33,15 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | |||
33 | struct stmmac_priv *priv = (struct stmmac_priv *)p; | 33 | struct stmmac_priv *priv = (struct stmmac_priv *)p; |
34 | unsigned int txsize = priv->dma_tx_size; | 34 | unsigned int txsize = priv->dma_tx_size; |
35 | unsigned int entry = priv->cur_tx % txsize; | 35 | unsigned int entry = priv->cur_tx % txsize; |
36 | struct dma_desc *desc = priv->dma_tx + entry; | 36 | struct dma_desc *desc; |
37 | unsigned int nopaged_len = skb_headlen(skb); | 37 | unsigned int nopaged_len = skb_headlen(skb); |
38 | unsigned int bmax, len; | 38 | unsigned int bmax, len; |
39 | 39 | ||
40 | if (priv->extend_desc) | ||
41 | desc = (struct dma_desc *)(priv->dma_etx + entry); | ||
42 | else | ||
43 | desc = priv->dma_tx + entry; | ||
44 | |||
40 | if (priv->plat->enh_desc) | 45 | if (priv->plat->enh_desc) |
41 | bmax = BUF_SIZE_8KiB; | 46 | bmax = BUF_SIZE_8KiB; |
42 | else | 47 | else |
@@ -54,7 +59,11 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | |||
54 | STMMAC_RING_MODE); | 59 | STMMAC_RING_MODE); |
55 | wmb(); | 60 | wmb(); |
56 | entry = (++priv->cur_tx) % txsize; | 61 | entry = (++priv->cur_tx) % txsize; |
57 | desc = priv->dma_tx + entry; | 62 | |
63 | if (priv->extend_desc) | ||
64 | desc = (struct dma_desc *)(priv->dma_etx + entry); | ||
65 | else | ||
66 | desc = priv->dma_tx + entry; | ||
58 | 67 | ||
59 | desc->des2 = dma_map_single(priv->device, skb->data + bmax, | 68 | desc->des2 = dma_map_single(priv->device, skb->data + bmax, |
60 | len, DMA_TO_DEVICE); | 69 | len, DMA_TO_DEVICE); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index f2ccb36e8685..0a9bb9d30c3f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -939,15 +939,20 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, | |||
939 | 939 | ||
940 | skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN, | 940 | skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN, |
941 | GFP_KERNEL); | 941 | GFP_KERNEL); |
942 | if (unlikely(skb == NULL)) { | 942 | if (!skb) { |
943 | pr_err("%s: Rx init fails; skb is NULL\n", __func__); | 943 | pr_err("%s: Rx init fails; skb is NULL\n", __func__); |
944 | return 1; | 944 | return -ENOMEM; |
945 | } | 945 | } |
946 | skb_reserve(skb, NET_IP_ALIGN); | 946 | skb_reserve(skb, NET_IP_ALIGN); |
947 | priv->rx_skbuff[i] = skb; | 947 | priv->rx_skbuff[i] = skb; |
948 | priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data, | 948 | priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data, |
949 | priv->dma_buf_sz, | 949 | priv->dma_buf_sz, |
950 | DMA_FROM_DEVICE); | 950 | DMA_FROM_DEVICE); |
951 | if (dma_mapping_error(priv->device, priv->rx_skbuff_dma[i])) { | ||
952 | pr_err("%s: DMA mapping error\n", __func__); | ||
953 | dev_kfree_skb_any(skb); | ||
954 | return -EINVAL; | ||
955 | } | ||
951 | 956 | ||
952 | p->des2 = priv->rx_skbuff_dma[i]; | 957 | p->des2 = priv->rx_skbuff_dma[i]; |
953 | 958 | ||
@@ -958,6 +963,16 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, | |||
958 | return 0; | 963 | return 0; |
959 | } | 964 | } |
960 | 965 | ||
966 | static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i) | ||
967 | { | ||
968 | if (priv->rx_skbuff[i]) { | ||
969 | dma_unmap_single(priv->device, priv->rx_skbuff_dma[i], | ||
970 | priv->dma_buf_sz, DMA_FROM_DEVICE); | ||
971 | dev_kfree_skb_any(priv->rx_skbuff[i]); | ||
972 | } | ||
973 | priv->rx_skbuff[i] = NULL; | ||
974 | } | ||
975 | |||
961 | /** | 976 | /** |
962 | * init_dma_desc_rings - init the RX/TX descriptor rings | 977 | * init_dma_desc_rings - init the RX/TX descriptor rings |
963 | * @dev: net device structure | 978 | * @dev: net device structure |
@@ -965,13 +980,14 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, | |||
965 | * and allocates the socket buffers. It suppors the chained and ring | 980 | * and allocates the socket buffers. It suppors the chained and ring |
966 | * modes. | 981 | * modes. |
967 | */ | 982 | */ |
968 | static void init_dma_desc_rings(struct net_device *dev) | 983 | static int init_dma_desc_rings(struct net_device *dev) |
969 | { | 984 | { |
970 | int i; | 985 | int i; |
971 | struct stmmac_priv *priv = netdev_priv(dev); | 986 | struct stmmac_priv *priv = netdev_priv(dev); |
972 | unsigned int txsize = priv->dma_tx_size; | 987 | unsigned int txsize = priv->dma_tx_size; |
973 | unsigned int rxsize = priv->dma_rx_size; | 988 | unsigned int rxsize = priv->dma_rx_size; |
974 | unsigned int bfsize = 0; | 989 | unsigned int bfsize = 0; |
990 | int ret = -ENOMEM; | ||
975 | 991 | ||
976 | /* Set the max buffer size according to the DESC mode | 992 | /* Set the max buffer size according to the DESC mode |
977 | * and the MTU. Note that RING mode allows 16KiB bsize. | 993 | * and the MTU. Note that RING mode allows 16KiB bsize. |
@@ -992,34 +1008,60 @@ static void init_dma_desc_rings(struct net_device *dev) | |||
992 | dma_extended_desc), | 1008 | dma_extended_desc), |
993 | &priv->dma_rx_phy, | 1009 | &priv->dma_rx_phy, |
994 | GFP_KERNEL); | 1010 | GFP_KERNEL); |
1011 | if (!priv->dma_erx) | ||
1012 | goto err_dma; | ||
1013 | |||
995 | priv->dma_etx = dma_alloc_coherent(priv->device, txsize * | 1014 | priv->dma_etx = dma_alloc_coherent(priv->device, txsize * |
996 | sizeof(struct | 1015 | sizeof(struct |
997 | dma_extended_desc), | 1016 | dma_extended_desc), |
998 | &priv->dma_tx_phy, | 1017 | &priv->dma_tx_phy, |
999 | GFP_KERNEL); | 1018 | GFP_KERNEL); |
1000 | if ((!priv->dma_erx) || (!priv->dma_etx)) | 1019 | if (!priv->dma_etx) { |
1001 | return; | 1020 | dma_free_coherent(priv->device, priv->dma_rx_size * |
1021 | sizeof(struct dma_extended_desc), | ||
1022 | priv->dma_erx, priv->dma_rx_phy); | ||
1023 | goto err_dma; | ||
1024 | } | ||
1002 | } else { | 1025 | } else { |
1003 | priv->dma_rx = dma_alloc_coherent(priv->device, rxsize * | 1026 | priv->dma_rx = dma_alloc_coherent(priv->device, rxsize * |
1004 | sizeof(struct dma_desc), | 1027 | sizeof(struct dma_desc), |
1005 | &priv->dma_rx_phy, | 1028 | &priv->dma_rx_phy, |
1006 | GFP_KERNEL); | 1029 | GFP_KERNEL); |
1030 | if (!priv->dma_rx) | ||
1031 | goto err_dma; | ||
1032 | |||
1007 | priv->dma_tx = dma_alloc_coherent(priv->device, txsize * | 1033 | priv->dma_tx = dma_alloc_coherent(priv->device, txsize * |
1008 | sizeof(struct dma_desc), | 1034 | sizeof(struct dma_desc), |
1009 | &priv->dma_tx_phy, | 1035 | &priv->dma_tx_phy, |
1010 | GFP_KERNEL); | 1036 | GFP_KERNEL); |
1011 | if ((!priv->dma_rx) || (!priv->dma_tx)) | 1037 | if (!priv->dma_tx) { |
1012 | return; | 1038 | dma_free_coherent(priv->device, priv->dma_rx_size * |
1039 | sizeof(struct dma_desc), | ||
1040 | priv->dma_rx, priv->dma_rx_phy); | ||
1041 | goto err_dma; | ||
1042 | } | ||
1013 | } | 1043 | } |
1014 | 1044 | ||
1015 | priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t), | 1045 | priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t), |
1016 | GFP_KERNEL); | 1046 | GFP_KERNEL); |
1047 | if (!priv->rx_skbuff_dma) | ||
1048 | goto err_rx_skbuff_dma; | ||
1049 | |||
1017 | priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *), | 1050 | priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *), |
1018 | GFP_KERNEL); | 1051 | GFP_KERNEL); |
1052 | if (!priv->rx_skbuff) | ||
1053 | goto err_rx_skbuff; | ||
1054 | |||
1019 | priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t), | 1055 | priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t), |
1020 | GFP_KERNEL); | 1056 | GFP_KERNEL); |
1057 | if (!priv->tx_skbuff_dma) | ||
1058 | goto err_tx_skbuff_dma; | ||
1059 | |||
1021 | priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *), | 1060 | priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *), |
1022 | GFP_KERNEL); | 1061 | GFP_KERNEL); |
1062 | if (!priv->tx_skbuff) | ||
1063 | goto err_tx_skbuff; | ||
1064 | |||
1023 | if (netif_msg_probe(priv)) { | 1065 | if (netif_msg_probe(priv)) { |
1024 | pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__, | 1066 | pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__, |
1025 | (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy); | 1067 | (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy); |
@@ -1034,8 +1076,9 @@ static void init_dma_desc_rings(struct net_device *dev) | |||
1034 | else | 1076 | else |
1035 | p = priv->dma_rx + i; | 1077 | p = priv->dma_rx + i; |
1036 | 1078 | ||
1037 | if (stmmac_init_rx_buffers(priv, p, i)) | 1079 | ret = stmmac_init_rx_buffers(priv, p, i); |
1038 | break; | 1080 | if (ret) |
1081 | goto err_init_rx_buffers; | ||
1039 | 1082 | ||
1040 | if (netif_msg_probe(priv)) | 1083 | if (netif_msg_probe(priv)) |
1041 | pr_debug("[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i], | 1084 | pr_debug("[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i], |
@@ -1081,20 +1124,44 @@ static void init_dma_desc_rings(struct net_device *dev) | |||
1081 | 1124 | ||
1082 | if (netif_msg_hw(priv)) | 1125 | if (netif_msg_hw(priv)) |
1083 | stmmac_display_rings(priv); | 1126 | stmmac_display_rings(priv); |
1127 | |||
1128 | return 0; | ||
1129 | err_init_rx_buffers: | ||
1130 | while (--i >= 0) | ||
1131 | stmmac_free_rx_buffers(priv, i); | ||
1132 | kfree(priv->tx_skbuff); | ||
1133 | err_tx_skbuff: | ||
1134 | kfree(priv->tx_skbuff_dma); | ||
1135 | err_tx_skbuff_dma: | ||
1136 | kfree(priv->rx_skbuff); | ||
1137 | err_rx_skbuff: | ||
1138 | kfree(priv->rx_skbuff_dma); | ||
1139 | err_rx_skbuff_dma: | ||
1140 | if (priv->extend_desc) { | ||
1141 | dma_free_coherent(priv->device, priv->dma_tx_size * | ||
1142 | sizeof(struct dma_extended_desc), | ||
1143 | priv->dma_etx, priv->dma_tx_phy); | ||
1144 | dma_free_coherent(priv->device, priv->dma_rx_size * | ||
1145 | sizeof(struct dma_extended_desc), | ||
1146 | priv->dma_erx, priv->dma_rx_phy); | ||
1147 | } else { | ||
1148 | dma_free_coherent(priv->device, | ||
1149 | priv->dma_tx_size * sizeof(struct dma_desc), | ||
1150 | priv->dma_tx, priv->dma_tx_phy); | ||
1151 | dma_free_coherent(priv->device, | ||
1152 | priv->dma_rx_size * sizeof(struct dma_desc), | ||
1153 | priv->dma_rx, priv->dma_rx_phy); | ||
1154 | } | ||
1155 | err_dma: | ||
1156 | return ret; | ||
1084 | } | 1157 | } |
1085 | 1158 | ||
1086 | static void dma_free_rx_skbufs(struct stmmac_priv *priv) | 1159 | static void dma_free_rx_skbufs(struct stmmac_priv *priv) |
1087 | { | 1160 | { |
1088 | int i; | 1161 | int i; |
1089 | 1162 | ||
1090 | for (i = 0; i < priv->dma_rx_size; i++) { | 1163 | for (i = 0; i < priv->dma_rx_size; i++) |
1091 | if (priv->rx_skbuff[i]) { | 1164 | stmmac_free_rx_buffers(priv, i); |
1092 | dma_unmap_single(priv->device, priv->rx_skbuff_dma[i], | ||
1093 | priv->dma_buf_sz, DMA_FROM_DEVICE); | ||
1094 | dev_kfree_skb_any(priv->rx_skbuff[i]); | ||
1095 | } | ||
1096 | priv->rx_skbuff[i] = NULL; | ||
1097 | } | ||
1098 | } | 1165 | } |
1099 | 1166 | ||
1100 | static void dma_free_tx_skbufs(struct stmmac_priv *priv) | 1167 | static void dma_free_tx_skbufs(struct stmmac_priv *priv) |
@@ -1560,12 +1627,17 @@ static int stmmac_open(struct net_device *dev) | |||
1560 | priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); | 1627 | priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); |
1561 | priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); | 1628 | priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); |
1562 | priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); | 1629 | priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); |
1563 | init_dma_desc_rings(dev); | 1630 | |
1631 | ret = init_dma_desc_rings(dev); | ||
1632 | if (ret < 0) { | ||
1633 | pr_err("%s: DMA descriptors initialization failed\n", __func__); | ||
1634 | goto dma_desc_error; | ||
1635 | } | ||
1564 | 1636 | ||
1565 | /* DMA initialization and SW reset */ | 1637 | /* DMA initialization and SW reset */ |
1566 | ret = stmmac_init_dma_engine(priv); | 1638 | ret = stmmac_init_dma_engine(priv); |
1567 | if (ret < 0) { | 1639 | if (ret < 0) { |
1568 | pr_err("%s: DMA initialization failed\n", __func__); | 1640 | pr_err("%s: DMA engine initialization failed\n", __func__); |
1569 | goto init_error; | 1641 | goto init_error; |
1570 | } | 1642 | } |
1571 | 1643 | ||
@@ -1672,6 +1744,7 @@ wolirq_error: | |||
1672 | 1744 | ||
1673 | init_error: | 1745 | init_error: |
1674 | free_dma_desc_resources(priv); | 1746 | free_dma_desc_resources(priv); |
1747 | dma_desc_error: | ||
1675 | if (priv->phydev) | 1748 | if (priv->phydev) |
1676 | phy_disconnect(priv->phydev); | 1749 | phy_disconnect(priv->phydev); |
1677 | phy_error: | 1750 | phy_error: |