diff options
-rw-r--r-- | drivers/net/niu.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 2541321bad82..9fb59d3f9c92 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -4489,6 +4489,9 @@ static int niu_alloc_channels(struct niu *np) | |||
4489 | { | 4489 | { |
4490 | struct niu_parent *parent = np->parent; | 4490 | struct niu_parent *parent = np->parent; |
4491 | int first_rx_channel, first_tx_channel; | 4491 | int first_rx_channel, first_tx_channel; |
4492 | int num_rx_rings, num_tx_rings; | ||
4493 | struct rx_ring_info *rx_rings; | ||
4494 | struct tx_ring_info *tx_rings; | ||
4492 | int i, port, err; | 4495 | int i, port, err; |
4493 | 4496 | ||
4494 | port = np->port; | 4497 | port = np->port; |
@@ -4498,18 +4501,21 @@ static int niu_alloc_channels(struct niu *np) | |||
4498 | first_tx_channel += parent->txchan_per_port[i]; | 4501 | first_tx_channel += parent->txchan_per_port[i]; |
4499 | } | 4502 | } |
4500 | 4503 | ||
4501 | np->num_rx_rings = parent->rxchan_per_port[port]; | 4504 | num_rx_rings = parent->rxchan_per_port[port]; |
4502 | np->num_tx_rings = parent->txchan_per_port[port]; | 4505 | num_tx_rings = parent->txchan_per_port[port]; |
4503 | 4506 | ||
4504 | netif_set_real_num_rx_queues(np->dev, np->num_rx_rings); | 4507 | rx_rings = kcalloc(num_rx_rings, sizeof(struct rx_ring_info), |
4505 | netif_set_real_num_tx_queues(np->dev, np->num_tx_rings); | 4508 | GFP_KERNEL); |
4506 | |||
4507 | np->rx_rings = kcalloc(np->num_rx_rings, sizeof(struct rx_ring_info), | ||
4508 | GFP_KERNEL); | ||
4509 | err = -ENOMEM; | 4509 | err = -ENOMEM; |
4510 | if (!np->rx_rings) | 4510 | if (!rx_rings) |
4511 | goto out_err; | 4511 | goto out_err; |
4512 | 4512 | ||
4513 | np->num_rx_rings = num_rx_rings; | ||
4514 | smp_wmb(); | ||
4515 | np->rx_rings = rx_rings; | ||
4516 | |||
4517 | netif_set_real_num_rx_queues(np->dev, num_rx_rings); | ||
4518 | |||
4513 | for (i = 0; i < np->num_rx_rings; i++) { | 4519 | for (i = 0; i < np->num_rx_rings; i++) { |
4514 | struct rx_ring_info *rp = &np->rx_rings[i]; | 4520 | struct rx_ring_info *rp = &np->rx_rings[i]; |
4515 | 4521 | ||
@@ -4538,12 +4544,18 @@ static int niu_alloc_channels(struct niu *np) | |||
4538 | return err; | 4544 | return err; |
4539 | } | 4545 | } |
4540 | 4546 | ||
4541 | np->tx_rings = kcalloc(np->num_tx_rings, sizeof(struct tx_ring_info), | 4547 | tx_rings = kcalloc(num_tx_rings, sizeof(struct tx_ring_info), |
4542 | GFP_KERNEL); | 4548 | GFP_KERNEL); |
4543 | err = -ENOMEM; | 4549 | err = -ENOMEM; |
4544 | if (!np->tx_rings) | 4550 | if (!tx_rings) |
4545 | goto out_err; | 4551 | goto out_err; |
4546 | 4552 | ||
4553 | np->num_tx_rings = num_tx_rings; | ||
4554 | smp_wmb(); | ||
4555 | np->tx_rings = tx_rings; | ||
4556 | |||
4557 | netif_set_real_num_tx_queues(np->dev, num_tx_rings); | ||
4558 | |||
4547 | for (i = 0; i < np->num_tx_rings; i++) { | 4559 | for (i = 0; i < np->num_tx_rings; i++) { |
4548 | struct tx_ring_info *rp = &np->tx_rings[i]; | 4560 | struct tx_ring_info *rp = &np->tx_rings[i]; |
4549 | 4561 | ||
@@ -6246,11 +6258,17 @@ static void niu_sync_mac_stats(struct niu *np) | |||
6246 | static void niu_get_rx_stats(struct niu *np) | 6258 | static void niu_get_rx_stats(struct niu *np) |
6247 | { | 6259 | { |
6248 | unsigned long pkts, dropped, errors, bytes; | 6260 | unsigned long pkts, dropped, errors, bytes; |
6261 | struct rx_ring_info *rx_rings; | ||
6249 | int i; | 6262 | int i; |
6250 | 6263 | ||
6251 | pkts = dropped = errors = bytes = 0; | 6264 | pkts = dropped = errors = bytes = 0; |
6265 | |||
6266 | rx_rings = ACCESS_ONCE(np->rx_rings); | ||
6267 | if (!rx_rings) | ||
6268 | goto no_rings; | ||
6269 | |||
6252 | for (i = 0; i < np->num_rx_rings; i++) { | 6270 | for (i = 0; i < np->num_rx_rings; i++) { |
6253 | struct rx_ring_info *rp = &np->rx_rings[i]; | 6271 | struct rx_ring_info *rp = &rx_rings[i]; |
6254 | 6272 | ||
6255 | niu_sync_rx_discard_stats(np, rp, 0); | 6273 | niu_sync_rx_discard_stats(np, rp, 0); |
6256 | 6274 | ||
@@ -6259,6 +6277,8 @@ static void niu_get_rx_stats(struct niu *np) | |||
6259 | dropped += rp->rx_dropped; | 6277 | dropped += rp->rx_dropped; |
6260 | errors += rp->rx_errors; | 6278 | errors += rp->rx_errors; |
6261 | } | 6279 | } |
6280 | |||
6281 | no_rings: | ||
6262 | np->dev->stats.rx_packets = pkts; | 6282 | np->dev->stats.rx_packets = pkts; |
6263 | np->dev->stats.rx_bytes = bytes; | 6283 | np->dev->stats.rx_bytes = bytes; |
6264 | np->dev->stats.rx_dropped = dropped; | 6284 | np->dev->stats.rx_dropped = dropped; |
@@ -6268,16 +6288,24 @@ static void niu_get_rx_stats(struct niu *np) | |||
6268 | static void niu_get_tx_stats(struct niu *np) | 6288 | static void niu_get_tx_stats(struct niu *np) |
6269 | { | 6289 | { |
6270 | unsigned long pkts, errors, bytes; | 6290 | unsigned long pkts, errors, bytes; |
6291 | struct tx_ring_info *tx_rings; | ||
6271 | int i; | 6292 | int i; |
6272 | 6293 | ||
6273 | pkts = errors = bytes = 0; | 6294 | pkts = errors = bytes = 0; |
6295 | |||
6296 | tx_rings = ACCESS_ONCE(np->tx_rings); | ||
6297 | if (!tx_rings) | ||
6298 | goto no_rings; | ||
6299 | |||
6274 | for (i = 0; i < np->num_tx_rings; i++) { | 6300 | for (i = 0; i < np->num_tx_rings; i++) { |
6275 | struct tx_ring_info *rp = &np->tx_rings[i]; | 6301 | struct tx_ring_info *rp = &tx_rings[i]; |
6276 | 6302 | ||
6277 | pkts += rp->tx_packets; | 6303 | pkts += rp->tx_packets; |
6278 | bytes += rp->tx_bytes; | 6304 | bytes += rp->tx_bytes; |
6279 | errors += rp->tx_errors; | 6305 | errors += rp->tx_errors; |
6280 | } | 6306 | } |
6307 | |||
6308 | no_rings: | ||
6281 | np->dev->stats.tx_packets = pkts; | 6309 | np->dev->stats.tx_packets = pkts; |
6282 | np->dev->stats.tx_bytes = bytes; | 6310 | np->dev->stats.tx_bytes = bytes; |
6283 | np->dev->stats.tx_errors = errors; | 6311 | np->dev->stats.tx_errors = errors; |
@@ -6287,9 +6315,10 @@ static struct net_device_stats *niu_get_stats(struct net_device *dev) | |||
6287 | { | 6315 | { |
6288 | struct niu *np = netdev_priv(dev); | 6316 | struct niu *np = netdev_priv(dev); |
6289 | 6317 | ||
6290 | niu_get_rx_stats(np); | 6318 | if (netif_running(dev)) { |
6291 | niu_get_tx_stats(np); | 6319 | niu_get_rx_stats(np); |
6292 | 6320 | niu_get_tx_stats(np); | |
6321 | } | ||
6293 | return &dev->stats; | 6322 | return &dev->stats; |
6294 | } | 6323 | } |
6295 | 6324 | ||