diff options
author | Michael Chan <mchan@broadcom.com> | 2012-02-05 10:24:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-02-05 22:42:00 -0500 |
commit | b033281f618fa40ee1b24a60cd8043b4979bfee4 (patch) | |
tree | 78458117b284cd7989b14c6e821645282a56f6bc /drivers/net/ethernet/broadcom | |
parent | b9d6d2dbf45b038a94c63295203525101a9fbbb7 (diff) |
bnx2: Add support for ethtool --show-channels|--set-channels
Allow the user to override the default number of RSS/TSS rings.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2.c | 99 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2.h | 3 |
2 files changed, 93 insertions, 9 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 0a4c5405dcf4..2ab31daef80f 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c | |||
@@ -6246,7 +6246,16 @@ static int | |||
6246 | bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) | 6246 | bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) |
6247 | { | 6247 | { |
6248 | int cpus = num_online_cpus(); | 6248 | int cpus = num_online_cpus(); |
6249 | int msix_vecs = min(cpus + 1, RX_MAX_RINGS); | 6249 | int msix_vecs; |
6250 | |||
6251 | if (!bp->num_req_rx_rings) | ||
6252 | msix_vecs = max(cpus + 1, bp->num_req_tx_rings); | ||
6253 | else if (!bp->num_req_tx_rings) | ||
6254 | msix_vecs = max(cpus, bp->num_req_rx_rings); | ||
6255 | else | ||
6256 | msix_vecs = max(bp->num_req_rx_rings, bp->num_req_tx_rings); | ||
6257 | |||
6258 | msix_vecs = min(msix_vecs, RX_MAX_RINGS); | ||
6250 | 6259 | ||
6251 | bp->irq_tbl[0].handler = bnx2_interrupt; | 6260 | bp->irq_tbl[0].handler = bnx2_interrupt; |
6252 | strcpy(bp->irq_tbl[0].name, bp->dev->name); | 6261 | strcpy(bp->irq_tbl[0].name, bp->dev->name); |
@@ -6270,10 +6279,18 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) | |||
6270 | } | 6279 | } |
6271 | } | 6280 | } |
6272 | 6281 | ||
6273 | bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs); | 6282 | if (!bp->num_req_tx_rings) |
6283 | bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs); | ||
6284 | else | ||
6285 | bp->num_tx_rings = min(bp->irq_nvecs, bp->num_req_tx_rings); | ||
6286 | |||
6287 | if (!bp->num_req_rx_rings) | ||
6288 | bp->num_rx_rings = bp->irq_nvecs; | ||
6289 | else | ||
6290 | bp->num_rx_rings = min(bp->irq_nvecs, bp->num_req_rx_rings); | ||
6291 | |||
6274 | netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings); | 6292 | netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings); |
6275 | 6293 | ||
6276 | bp->num_rx_rings = bp->irq_nvecs; | ||
6277 | return netif_set_real_num_rx_queues(bp->dev, bp->num_rx_rings); | 6294 | return netif_set_real_num_rx_queues(bp->dev, bp->num_rx_rings); |
6278 | } | 6295 | } |
6279 | 6296 | ||
@@ -7162,7 +7179,7 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) | |||
7162 | } | 7179 | } |
7163 | 7180 | ||
7164 | static int | 7181 | static int |
7165 | bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) | 7182 | bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx, bool reset_irq) |
7166 | { | 7183 | { |
7167 | if (netif_running(bp->dev)) { | 7184 | if (netif_running(bp->dev)) { |
7168 | /* Reset will erase chipset stats; save them */ | 7185 | /* Reset will erase chipset stats; save them */ |
@@ -7170,7 +7187,12 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) | |||
7170 | 7187 | ||
7171 | bnx2_netif_stop(bp, true); | 7188 | bnx2_netif_stop(bp, true); |
7172 | bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); | 7189 | bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); |
7173 | __bnx2_free_irq(bp); | 7190 | if (reset_irq) { |
7191 | bnx2_free_irq(bp); | ||
7192 | bnx2_del_napi(bp); | ||
7193 | } else { | ||
7194 | __bnx2_free_irq(bp); | ||
7195 | } | ||
7174 | bnx2_free_skbs(bp); | 7196 | bnx2_free_skbs(bp); |
7175 | bnx2_free_mem(bp); | 7197 | bnx2_free_mem(bp); |
7176 | } | 7198 | } |
@@ -7179,9 +7201,16 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) | |||
7179 | bp->tx_ring_size = tx; | 7201 | bp->tx_ring_size = tx; |
7180 | 7202 | ||
7181 | if (netif_running(bp->dev)) { | 7203 | if (netif_running(bp->dev)) { |
7182 | int rc; | 7204 | int rc = 0; |
7205 | |||
7206 | if (reset_irq) { | ||
7207 | rc = bnx2_setup_int_mode(bp, disable_msi); | ||
7208 | bnx2_init_napi(bp); | ||
7209 | } | ||
7210 | |||
7211 | if (!rc) | ||
7212 | rc = bnx2_alloc_mem(bp); | ||
7183 | 7213 | ||
7184 | rc = bnx2_alloc_mem(bp); | ||
7185 | if (!rc) | 7214 | if (!rc) |
7186 | rc = bnx2_request_irq(bp); | 7215 | rc = bnx2_request_irq(bp); |
7187 | 7216 | ||
@@ -7217,7 +7246,8 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) | |||
7217 | 7246 | ||
7218 | return -EINVAL; | 7247 | return -EINVAL; |
7219 | } | 7248 | } |
7220 | rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending); | 7249 | rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending, |
7250 | false); | ||
7221 | return rc; | 7251 | return rc; |
7222 | } | 7252 | } |
7223 | 7253 | ||
@@ -7605,6 +7635,54 @@ bnx2_set_features(struct net_device *dev, netdev_features_t features) | |||
7605 | return 0; | 7635 | return 0; |
7606 | } | 7636 | } |
7607 | 7637 | ||
7638 | static void bnx2_get_channels(struct net_device *dev, | ||
7639 | struct ethtool_channels *channels) | ||
7640 | { | ||
7641 | struct bnx2 *bp = netdev_priv(dev); | ||
7642 | u32 max_rx_rings = 1; | ||
7643 | u32 max_tx_rings = 1; | ||
7644 | |||
7645 | if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !disable_msi) { | ||
7646 | max_rx_rings = RX_MAX_RINGS; | ||
7647 | max_tx_rings = TX_MAX_RINGS; | ||
7648 | } | ||
7649 | |||
7650 | channels->max_rx = max_rx_rings; | ||
7651 | channels->max_tx = max_tx_rings; | ||
7652 | channels->max_other = 0; | ||
7653 | channels->max_combined = 0; | ||
7654 | channels->rx_count = bp->num_rx_rings; | ||
7655 | channels->tx_count = bp->num_tx_rings; | ||
7656 | channels->other_count = 0; | ||
7657 | channels->combined_count = 0; | ||
7658 | } | ||
7659 | |||
7660 | static int bnx2_set_channels(struct net_device *dev, | ||
7661 | struct ethtool_channels *channels) | ||
7662 | { | ||
7663 | struct bnx2 *bp = netdev_priv(dev); | ||
7664 | u32 max_rx_rings = 1; | ||
7665 | u32 max_tx_rings = 1; | ||
7666 | int rc = 0; | ||
7667 | |||
7668 | if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !disable_msi) { | ||
7669 | max_rx_rings = RX_MAX_RINGS; | ||
7670 | max_tx_rings = TX_MAX_RINGS; | ||
7671 | } | ||
7672 | if (channels->rx_count > max_rx_rings || | ||
7673 | channels->tx_count > max_tx_rings) | ||
7674 | return -EINVAL; | ||
7675 | |||
7676 | bp->num_req_rx_rings = channels->rx_count; | ||
7677 | bp->num_req_tx_rings = channels->tx_count; | ||
7678 | |||
7679 | if (netif_running(dev)) | ||
7680 | rc = bnx2_change_ring_size(bp, bp->rx_ring_size, | ||
7681 | bp->tx_ring_size, true); | ||
7682 | |||
7683 | return rc; | ||
7684 | } | ||
7685 | |||
7608 | static const struct ethtool_ops bnx2_ethtool_ops = { | 7686 | static const struct ethtool_ops bnx2_ethtool_ops = { |
7609 | .get_settings = bnx2_get_settings, | 7687 | .get_settings = bnx2_get_settings, |
7610 | .set_settings = bnx2_set_settings, | 7688 | .set_settings = bnx2_set_settings, |
@@ -7629,6 +7707,8 @@ static const struct ethtool_ops bnx2_ethtool_ops = { | |||
7629 | .set_phys_id = bnx2_set_phys_id, | 7707 | .set_phys_id = bnx2_set_phys_id, |
7630 | .get_ethtool_stats = bnx2_get_ethtool_stats, | 7708 | .get_ethtool_stats = bnx2_get_ethtool_stats, |
7631 | .get_sset_count = bnx2_get_sset_count, | 7709 | .get_sset_count = bnx2_get_sset_count, |
7710 | .get_channels = bnx2_get_channels, | ||
7711 | .set_channels = bnx2_set_channels, | ||
7632 | }; | 7712 | }; |
7633 | 7713 | ||
7634 | /* Called with rtnl_lock */ | 7714 | /* Called with rtnl_lock */ |
@@ -7710,7 +7790,8 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu) | |||
7710 | return -EINVAL; | 7790 | return -EINVAL; |
7711 | 7791 | ||
7712 | dev->mtu = new_mtu; | 7792 | dev->mtu = new_mtu; |
7713 | return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size); | 7793 | return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size, |
7794 | false); | ||
7714 | } | 7795 | } |
7715 | 7796 | ||
7716 | #ifdef CONFIG_NET_POLL_CONTROLLER | 7797 | #ifdef CONFIG_NET_POLL_CONTROLLER |
diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h index 1db2d51ba3f1..dc06bda73be7 100644 --- a/drivers/net/ethernet/broadcom/bnx2.h +++ b/drivers/net/ethernet/broadcom/bnx2.h | |||
@@ -6933,6 +6933,9 @@ struct bnx2 { | |||
6933 | u8 num_tx_rings; | 6933 | u8 num_tx_rings; |
6934 | u8 num_rx_rings; | 6934 | u8 num_rx_rings; |
6935 | 6935 | ||
6936 | int num_req_tx_rings; | ||
6937 | int num_req_rx_rings; | ||
6938 | |||
6936 | u32 leds_save; | 6939 | u32 leds_save; |
6937 | u32 idle_chk_status_idx; | 6940 | u32 idle_chk_status_idx; |
6938 | 6941 | ||