diff options
Diffstat (limited to 'drivers/net/niu.c')
| -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 | ||
