diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2015-09-25 12:09:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-09-29 14:51:40 -0400 |
commit | d893665728f3cc79f7719df50c4345d200bb293c (patch) | |
tree | d4f4ae7f1ffe229d91e59425f1bace1963818218 | |
parent | 12bb03b436dad56692e9a103ed26156156bef5d2 (diff) |
net: mvneta: Allow different queues
The mvneta driver allows to change the default RX queue trough the rxq_def
kernel parameter.
However, the current code doesn't allow to have any value but 0. It is
actively checked for in the driver's probe because the drivers makes a
number of assumption and takes a number of shortcuts in order to just use
that RX queue.
Remove these limitations in order to be able to specify any available
queue.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/marvell/mvneta.c | 80 |
1 files changed, 11 insertions, 69 deletions
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index d0b710afffd6..0702beb60031 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c | |||
@@ -478,7 +478,7 @@ struct mvneta_rx_queue { | |||
478 | /* The hardware supports eight (8) rx queues, but we are only allowing | 478 | /* The hardware supports eight (8) rx queues, but we are only allowing |
479 | * the first one to be used. Therefore, let's just allocate one queue. | 479 | * the first one to be used. Therefore, let's just allocate one queue. |
480 | */ | 480 | */ |
481 | static int rxq_number = 1; | 481 | static int rxq_number = 8; |
482 | static int txq_number = 8; | 482 | static int txq_number = 8; |
483 | 483 | ||
484 | static int rxq_def; | 484 | static int rxq_def; |
@@ -766,14 +766,7 @@ static void mvneta_port_up(struct mvneta_port *pp) | |||
766 | mvreg_write(pp, MVNETA_TXQ_CMD, q_map); | 766 | mvreg_write(pp, MVNETA_TXQ_CMD, q_map); |
767 | 767 | ||
768 | /* Enable all initialized RXQs. */ | 768 | /* Enable all initialized RXQs. */ |
769 | q_map = 0; | 769 | mvreg_write(pp, MVNETA_RXQ_CMD, BIT(rxq_def)); |
770 | for (queue = 0; queue < rxq_number; queue++) { | ||
771 | struct mvneta_rx_queue *rxq = &pp->rxqs[queue]; | ||
772 | if (rxq->descs != NULL) | ||
773 | q_map |= (1 << queue); | ||
774 | } | ||
775 | |||
776 | mvreg_write(pp, MVNETA_RXQ_CMD, q_map); | ||
777 | } | 770 | } |
778 | 771 | ||
779 | /* Stop the Ethernet port activity */ | 772 | /* Stop the Ethernet port activity */ |
@@ -1436,17 +1429,6 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb) | |||
1436 | return MVNETA_TX_L4_CSUM_NOT; | 1429 | return MVNETA_TX_L4_CSUM_NOT; |
1437 | } | 1430 | } |
1438 | 1431 | ||
1439 | /* Returns rx queue pointer (find last set bit) according to causeRxTx | ||
1440 | * value | ||
1441 | */ | ||
1442 | static struct mvneta_rx_queue *mvneta_rx_policy(struct mvneta_port *pp, | ||
1443 | u32 cause) | ||
1444 | { | ||
1445 | int queue = fls(cause >> 8) - 1; | ||
1446 | |||
1447 | return (queue < 0 || queue >= rxq_number) ? NULL : &pp->rxqs[queue]; | ||
1448 | } | ||
1449 | |||
1450 | /* Drop packets received by the RXQ and free buffers */ | 1432 | /* Drop packets received by the RXQ and free buffers */ |
1451 | static void mvneta_rxq_drop_pkts(struct mvneta_port *pp, | 1433 | static void mvneta_rxq_drop_pkts(struct mvneta_port *pp, |
1452 | struct mvneta_rx_queue *rxq) | 1434 | struct mvneta_rx_queue *rxq) |
@@ -2146,33 +2128,8 @@ static int mvneta_poll(struct napi_struct *napi, int budget) | |||
2146 | * RX packets | 2128 | * RX packets |
2147 | */ | 2129 | */ |
2148 | cause_rx_tx |= port->cause_rx_tx; | 2130 | cause_rx_tx |= port->cause_rx_tx; |
2149 | if (rxq_number > 1) { | 2131 | rx_done = mvneta_rx(pp, budget, &pp->rxqs[rxq_def]); |
2150 | while ((cause_rx_tx & MVNETA_RX_INTR_MASK_ALL) && (budget > 0)) { | 2132 | budget -= rx_done; |
2151 | int count; | ||
2152 | struct mvneta_rx_queue *rxq; | ||
2153 | /* get rx queue number from cause_rx_tx */ | ||
2154 | rxq = mvneta_rx_policy(pp, cause_rx_tx); | ||
2155 | if (!rxq) | ||
2156 | break; | ||
2157 | |||
2158 | /* process the packet in that rx queue */ | ||
2159 | count = mvneta_rx(pp, budget, rxq); | ||
2160 | rx_done += count; | ||
2161 | budget -= count; | ||
2162 | if (budget > 0) { | ||
2163 | /* set off the rx bit of the | ||
2164 | * corresponding bit in the cause rx | ||
2165 | * tx register, so that next iteration | ||
2166 | * will find the next rx queue where | ||
2167 | * packets are received on | ||
2168 | */ | ||
2169 | cause_rx_tx &= ~((1 << rxq->id) << 8); | ||
2170 | } | ||
2171 | } | ||
2172 | } else { | ||
2173 | rx_done = mvneta_rx(pp, budget, &pp->rxqs[rxq_def]); | ||
2174 | budget -= rx_done; | ||
2175 | } | ||
2176 | 2133 | ||
2177 | if (budget > 0) { | 2134 | if (budget > 0) { |
2178 | cause_rx_tx = 0; | 2135 | cause_rx_tx = 0; |
@@ -2384,26 +2341,19 @@ static void mvneta_cleanup_txqs(struct mvneta_port *pp) | |||
2384 | /* Cleanup all Rx queues */ | 2341 | /* Cleanup all Rx queues */ |
2385 | static void mvneta_cleanup_rxqs(struct mvneta_port *pp) | 2342 | static void mvneta_cleanup_rxqs(struct mvneta_port *pp) |
2386 | { | 2343 | { |
2387 | int queue; | 2344 | mvneta_rxq_deinit(pp, &pp->rxqs[rxq_def]); |
2388 | |||
2389 | for (queue = 0; queue < rxq_number; queue++) | ||
2390 | mvneta_rxq_deinit(pp, &pp->rxqs[queue]); | ||
2391 | } | 2345 | } |
2392 | 2346 | ||
2393 | 2347 | ||
2394 | /* Init all Rx queues */ | 2348 | /* Init all Rx queues */ |
2395 | static int mvneta_setup_rxqs(struct mvneta_port *pp) | 2349 | static int mvneta_setup_rxqs(struct mvneta_port *pp) |
2396 | { | 2350 | { |
2397 | int queue; | 2351 | int err = mvneta_rxq_init(pp, &pp->rxqs[rxq_def]); |
2398 | 2352 | if (err) { | |
2399 | for (queue = 0; queue < rxq_number; queue++) { | 2353 | netdev_err(pp->dev, "%s: can't create rxq=%d\n", |
2400 | int err = mvneta_rxq_init(pp, &pp->rxqs[queue]); | 2354 | __func__, rxq_def); |
2401 | if (err) { | 2355 | mvneta_cleanup_rxqs(pp); |
2402 | netdev_err(pp->dev, "%s: can't create rxq=%d\n", | 2356 | return err; |
2403 | __func__, queue); | ||
2404 | mvneta_cleanup_rxqs(pp); | ||
2405 | return err; | ||
2406 | } | ||
2407 | } | 2357 | } |
2408 | 2358 | ||
2409 | return 0; | 2359 | return 0; |
@@ -3051,14 +3001,6 @@ static int mvneta_probe(struct platform_device *pdev) | |||
3051 | int err; | 3001 | int err; |
3052 | int cpu; | 3002 | int cpu; |
3053 | 3003 | ||
3054 | /* Our multiqueue support is not complete, so for now, only | ||
3055 | * allow the usage of the first RX queue | ||
3056 | */ | ||
3057 | if (rxq_def != 0) { | ||
3058 | dev_err(&pdev->dev, "Invalid rxq_def argument: %d\n", rxq_def); | ||
3059 | return -EINVAL; | ||
3060 | } | ||
3061 | |||
3062 | dev = alloc_etherdev_mqs(sizeof(struct mvneta_port), txq_number, rxq_number); | 3004 | dev = alloc_etherdev_mqs(sizeof(struct mvneta_port), txq_number, rxq_number); |
3063 | if (!dev) | 3005 | if (!dev) |
3064 | return -ENOMEM; | 3006 | return -ENOMEM; |