aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLendacky, Thomas <Thomas.Lendacky@amd.com>2014-11-04 17:06:26 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-05 21:50:11 -0500
commit4780b7cae60cf10af4ae75bc5d6643f41d4c2969 (patch)
tree1feb576159fdb1cbde6067336b83377f2ec8f93d
parent25de4668d094f00e44a8f2428dd3c1a4ecfa0053 (diff)
amd-xgbe: Move ring allocation to device open
Move the channel and ring tracking structures allocation to device open. This will allow for future support to vary the number of Tx/Rx queues without unloading the module. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-drv.c93
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c8
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-main.c62
3 files changed, 93 insertions, 70 deletions
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 2349ea970255..07b00bdcd9f9 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -129,6 +129,80 @@
129static int xgbe_poll(struct napi_struct *, int); 129static int xgbe_poll(struct napi_struct *, int);
130static void xgbe_set_rx_mode(struct net_device *); 130static void xgbe_set_rx_mode(struct net_device *);
131 131
132static int xgbe_alloc_channels(struct xgbe_prv_data *pdata)
133{
134 struct xgbe_channel *channel_mem, *channel;
135 struct xgbe_ring *tx_ring, *rx_ring;
136 unsigned int count, i;
137
138 count = max_t(unsigned int, pdata->tx_ring_count, pdata->rx_ring_count);
139
140 channel_mem = kcalloc(count, sizeof(struct xgbe_channel), GFP_KERNEL);
141 if (!channel_mem)
142 goto err_channel;
143
144 tx_ring = kcalloc(pdata->tx_ring_count, sizeof(struct xgbe_ring),
145 GFP_KERNEL);
146 if (!tx_ring)
147 goto err_tx_ring;
148
149 rx_ring = kcalloc(pdata->rx_ring_count, sizeof(struct xgbe_ring),
150 GFP_KERNEL);
151 if (!rx_ring)
152 goto err_rx_ring;
153
154 for (i = 0, channel = channel_mem; i < count; i++, channel++) {
155 snprintf(channel->name, sizeof(channel->name), "channel-%d", i);
156 channel->pdata = pdata;
157 channel->queue_index = i;
158 channel->dma_regs = pdata->xgmac_regs + DMA_CH_BASE +
159 (DMA_CH_INC * i);
160
161 if (i < pdata->tx_ring_count) {
162 spin_lock_init(&tx_ring->lock);
163 channel->tx_ring = tx_ring++;
164 }
165
166 if (i < pdata->rx_ring_count) {
167 spin_lock_init(&rx_ring->lock);
168 channel->rx_ring = rx_ring++;
169 }
170
171 DBGPR(" %s - queue_index=%u, dma_regs=%p, tx=%p, rx=%p\n",
172 channel->name, channel->queue_index, channel->dma_regs,
173 channel->tx_ring, channel->rx_ring);
174 }
175
176 pdata->channel = channel_mem;
177 pdata->channel_count = count;
178
179 return 0;
180
181err_rx_ring:
182 kfree(tx_ring);
183
184err_tx_ring:
185 kfree(channel_mem);
186
187err_channel:
188 netdev_err(pdata->netdev, "channel allocation failed\n");
189
190 return -ENOMEM;
191}
192
193static void xgbe_free_channels(struct xgbe_prv_data *pdata)
194{
195 if (!pdata->channel)
196 return;
197
198 kfree(pdata->channel->rx_ring);
199 kfree(pdata->channel->tx_ring);
200 kfree(pdata->channel);
201
202 pdata->channel = NULL;
203 pdata->channel_count = 0;
204}
205
132static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring) 206static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring)
133{ 207{
134 return (ring->rdesc_count - (ring->cur - ring->dirty)); 208 return (ring->rdesc_count - (ring->cur - ring->dirty));
@@ -1119,10 +1193,15 @@ static int xgbe_open(struct net_device *netdev)
1119 goto err_ptpclk; 1193 goto err_ptpclk;
1120 pdata->rx_buf_size = ret; 1194 pdata->rx_buf_size = ret;
1121 1195
1196 /* Allocate the channel and ring structures */
1197 ret = xgbe_alloc_channels(pdata);
1198 if (ret)
1199 goto err_ptpclk;
1200
1122 /* Allocate the ring descriptors and buffers */ 1201 /* Allocate the ring descriptors and buffers */
1123 ret = desc_if->alloc_ring_resources(pdata); 1202 ret = desc_if->alloc_ring_resources(pdata);
1124 if (ret) 1203 if (ret)
1125 goto err_ptpclk; 1204 goto err_channels;
1126 1205
1127 /* Initialize the device restart and Tx timestamp work struct */ 1206 /* Initialize the device restart and Tx timestamp work struct */
1128 INIT_WORK(&pdata->restart_work, xgbe_restart); 1207 INIT_WORK(&pdata->restart_work, xgbe_restart);
@@ -1134,7 +1213,7 @@ static int xgbe_open(struct net_device *netdev)
1134 if (ret) { 1213 if (ret) {
1135 netdev_alert(netdev, "error requesting irq %d\n", 1214 netdev_alert(netdev, "error requesting irq %d\n",
1136 pdata->irq_number); 1215 pdata->irq_number);
1137 goto err_irq; 1216 goto err_rings;
1138 } 1217 }
1139 pdata->irq_number = netdev->irq; 1218 pdata->irq_number = netdev->irq;
1140 1219
@@ -1152,9 +1231,12 @@ err_start:
1152 devm_free_irq(pdata->dev, pdata->irq_number, pdata); 1231 devm_free_irq(pdata->dev, pdata->irq_number, pdata);
1153 pdata->irq_number = 0; 1232 pdata->irq_number = 0;
1154 1233
1155err_irq: 1234err_rings:
1156 desc_if->free_ring_resources(pdata); 1235 desc_if->free_ring_resources(pdata);
1157 1236
1237err_channels:
1238 xgbe_free_channels(pdata);
1239
1158err_ptpclk: 1240err_ptpclk:
1159 clk_disable_unprepare(pdata->ptpclk); 1241 clk_disable_unprepare(pdata->ptpclk);
1160 1242
@@ -1181,9 +1263,12 @@ static int xgbe_close(struct net_device *netdev)
1181 /* Issue software reset to device */ 1263 /* Issue software reset to device */
1182 hw_if->exit(pdata); 1264 hw_if->exit(pdata);
1183 1265
1184 /* Free all the ring data */ 1266 /* Free the ring descriptors and buffers */
1185 desc_if->free_ring_resources(pdata); 1267 desc_if->free_ring_resources(pdata);
1186 1268
1269 /* Free the channel and ring structures */
1270 xgbe_free_channels(pdata);
1271
1187 /* Release the interrupt */ 1272 /* Release the interrupt */
1188 if (pdata->irq_number != 0) { 1273 if (pdata->irq_number != 0) {
1189 devm_free_irq(pdata->dev, pdata->irq_number, pdata); 1274 devm_free_irq(pdata->dev, pdata->irq_number, pdata);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
index 49508ec98b72..47022fb00b79 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
@@ -452,9 +452,9 @@ static int xgbe_set_coalesce(struct net_device *netdev,
452 rx_usecs); 452 rx_usecs);
453 return -EINVAL; 453 return -EINVAL;
454 } 454 }
455 if (rx_frames > pdata->channel->rx_ring->rdesc_count) { 455 if (rx_frames > pdata->rx_desc_count) {
456 netdev_alert(netdev, "rx-frames is limited to %d frames\n", 456 netdev_alert(netdev, "rx-frames is limited to %d frames\n",
457 pdata->channel->rx_ring->rdesc_count); 457 pdata->rx_desc_count);
458 return -EINVAL; 458 return -EINVAL;
459 } 459 }
460 460
@@ -462,9 +462,9 @@ static int xgbe_set_coalesce(struct net_device *netdev,
462 tx_frames = ec->tx_max_coalesced_frames; 462 tx_frames = ec->tx_max_coalesced_frames;
463 463
464 /* Check the bounds of values for Tx */ 464 /* Check the bounds of values for Tx */
465 if (tx_frames > pdata->channel->tx_ring->rdesc_count) { 465 if (tx_frames > pdata->tx_desc_count) {
466 netdev_alert(netdev, "tx-frames is limited to %d frames\n", 466 netdev_alert(netdev, "tx-frames is limited to %d frames\n",
467 pdata->channel->tx_ring->rdesc_count); 467 pdata->tx_desc_count);
468 return -EINVAL; 468 return -EINVAL;
469 } 469 }
470 470
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index f5a8fa03921a..e5077fd5b012 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -133,60 +133,6 @@ MODULE_LICENSE("Dual BSD/GPL");
133MODULE_VERSION(XGBE_DRV_VERSION); 133MODULE_VERSION(XGBE_DRV_VERSION);
134MODULE_DESCRIPTION(XGBE_DRV_DESC); 134MODULE_DESCRIPTION(XGBE_DRV_DESC);
135 135
136static struct xgbe_channel *xgbe_alloc_rings(struct xgbe_prv_data *pdata)
137{
138 struct xgbe_channel *channel_mem, *channel;
139 struct xgbe_ring *tx_ring, *rx_ring;
140 unsigned int count, i;
141
142 DBGPR("-->xgbe_alloc_rings\n");
143
144 count = max_t(unsigned int, pdata->tx_ring_count, pdata->rx_ring_count);
145
146 channel_mem = devm_kcalloc(pdata->dev, count,
147 sizeof(struct xgbe_channel), GFP_KERNEL);
148 if (!channel_mem)
149 return NULL;
150
151 tx_ring = devm_kcalloc(pdata->dev, pdata->tx_ring_count,
152 sizeof(struct xgbe_ring), GFP_KERNEL);
153 if (!tx_ring)
154 return NULL;
155
156 rx_ring = devm_kcalloc(pdata->dev, pdata->rx_ring_count,
157 sizeof(struct xgbe_ring), GFP_KERNEL);
158 if (!rx_ring)
159 return NULL;
160
161 for (i = 0, channel = channel_mem; i < count; i++, channel++) {
162 snprintf(channel->name, sizeof(channel->name), "channel-%d", i);
163 channel->pdata = pdata;
164 channel->queue_index = i;
165 channel->dma_regs = pdata->xgmac_regs + DMA_CH_BASE +
166 (DMA_CH_INC * i);
167
168 if (i < pdata->tx_ring_count) {
169 spin_lock_init(&tx_ring->lock);
170 channel->tx_ring = tx_ring++;
171 }
172
173 if (i < pdata->rx_ring_count) {
174 spin_lock_init(&rx_ring->lock);
175 channel->rx_ring = rx_ring++;
176 }
177
178 DBGPR(" %s - queue_index=%u, dma_regs=%p, tx=%p, rx=%p\n",
179 channel->name, channel->queue_index, channel->dma_regs,
180 channel->tx_ring, channel->rx_ring);
181 }
182
183 pdata->channel_count = count;
184
185 DBGPR("<--xgbe_alloc_rings\n");
186
187 return channel_mem;
188}
189
190static void xgbe_default_config(struct xgbe_prv_data *pdata) 136static void xgbe_default_config(struct xgbe_prv_data *pdata)
191{ 137{
192 DBGPR("-->xgbe_default_config\n"); 138 DBGPR("-->xgbe_default_config\n");
@@ -383,14 +329,6 @@ static int xgbe_probe(struct platform_device *pdev)
383 goto err_io; 329 goto err_io;
384 } 330 }
385 331
386 /* Allocate the rings for the DMA channels */
387 pdata->channel = xgbe_alloc_rings(pdata);
388 if (!pdata->channel) {
389 dev_err(dev, "ring allocation failed\n");
390 ret = -ENOMEM;
391 goto err_io;
392 }
393
394 /* Prepare to regsiter with MDIO */ 332 /* Prepare to regsiter with MDIO */
395 pdata->mii_bus_id = kasprintf(GFP_KERNEL, "%s", pdev->name); 333 pdata->mii_bus_id = kasprintf(GFP_KERNEL, "%s", pdev->name);
396 if (!pdata->mii_bus_id) { 334 if (!pdata->mii_bus_id) {