diff options
author | Tom Herbert <therbert@google.com> | 2011-02-16 05:27:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-17 15:49:45 -0500 |
commit | ab532cf32b4055028ad095d3c1fee9eec28ed25e (patch) | |
tree | 03c537583ce9d9dfa87d96e83ec4f467695ed3e4 /drivers/net/bnx2x | |
parent | f878b995b0f746f5726af9e66940f3bf373dae91 (diff) |
bnx2x: Support for managing RX indirection table
Support fetching and retrieving RX indirection table via ethtool.
Signed-off-by: Tom Herbert <therbert@google.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x')
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 2 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_ethtool.c | 56 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 22 |
3 files changed, 75 insertions, 5 deletions
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 236d79a80624..c0dd30d870ae 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -1076,6 +1076,7 @@ struct bnx2x { | |||
1076 | int num_queues; | 1076 | int num_queues; |
1077 | int disable_tpa; | 1077 | int disable_tpa; |
1078 | int int_mode; | 1078 | int int_mode; |
1079 | u32 *rx_indir_table; | ||
1079 | 1080 | ||
1080 | struct tstorm_eth_mac_filter_config mac_filters; | 1081 | struct tstorm_eth_mac_filter_config mac_filters; |
1081 | #define BNX2X_ACCEPT_NONE 0x0000 | 1082 | #define BNX2X_ACCEPT_NONE 0x0000 |
@@ -1799,5 +1800,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, | |||
1799 | BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ | 1800 | BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ |
1800 | 1801 | ||
1801 | extern void bnx2x_set_ethtool_ops(struct net_device *netdev); | 1802 | extern void bnx2x_set_ethtool_ops(struct net_device *netdev); |
1803 | void bnx2x_push_indir_table(struct bnx2x *bp); | ||
1802 | 1804 | ||
1803 | #endif /* bnx2x.h */ | 1805 | #endif /* bnx2x.h */ |
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 816fef6d3844..8d19d127f796 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c | |||
@@ -2134,6 +2134,59 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data) | |||
2134 | return 0; | 2134 | return 0; |
2135 | } | 2135 | } |
2136 | 2136 | ||
2137 | static int bnx2x_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, | ||
2138 | void *rules __always_unused) | ||
2139 | { | ||
2140 | struct bnx2x *bp = netdev_priv(dev); | ||
2141 | |||
2142 | switch (info->cmd) { | ||
2143 | case ETHTOOL_GRXRINGS: | ||
2144 | info->data = BNX2X_NUM_ETH_QUEUES(bp); | ||
2145 | return 0; | ||
2146 | |||
2147 | default: | ||
2148 | return -EOPNOTSUPP; | ||
2149 | } | ||
2150 | } | ||
2151 | |||
2152 | static int bnx2x_get_rxfh_indir(struct net_device *dev, | ||
2153 | struct ethtool_rxfh_indir *indir) | ||
2154 | { | ||
2155 | struct bnx2x *bp = netdev_priv(dev); | ||
2156 | size_t copy_size = | ||
2157 | min_t(size_t, indir->size, TSTORM_INDIRECTION_TABLE_SIZE); | ||
2158 | |||
2159 | if (bp->multi_mode == ETH_RSS_MODE_DISABLED) | ||
2160 | return -EOPNOTSUPP; | ||
2161 | |||
2162 | indir->size = TSTORM_INDIRECTION_TABLE_SIZE; | ||
2163 | memcpy(indir->ring_index, bp->rx_indir_table, | ||
2164 | copy_size * sizeof(bp->rx_indir_table[0])); | ||
2165 | return 0; | ||
2166 | } | ||
2167 | |||
2168 | static int bnx2x_set_rxfh_indir(struct net_device *dev, | ||
2169 | const struct ethtool_rxfh_indir *indir) | ||
2170 | { | ||
2171 | struct bnx2x *bp = netdev_priv(dev); | ||
2172 | size_t i; | ||
2173 | |||
2174 | if (bp->multi_mode == ETH_RSS_MODE_DISABLED) | ||
2175 | return -EOPNOTSUPP; | ||
2176 | |||
2177 | /* Validate size and indices */ | ||
2178 | if (indir->size != TSTORM_INDIRECTION_TABLE_SIZE) | ||
2179 | return -EINVAL; | ||
2180 | for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) | ||
2181 | if (indir->ring_index[i] >= BNX2X_NUM_ETH_QUEUES(bp)) | ||
2182 | return -EINVAL; | ||
2183 | |||
2184 | memcpy(bp->rx_indir_table, indir->ring_index, | ||
2185 | indir->size * sizeof(bp->rx_indir_table[0])); | ||
2186 | bnx2x_push_indir_table(bp); | ||
2187 | return 0; | ||
2188 | } | ||
2189 | |||
2137 | static const struct ethtool_ops bnx2x_ethtool_ops = { | 2190 | static const struct ethtool_ops bnx2x_ethtool_ops = { |
2138 | .get_settings = bnx2x_get_settings, | 2191 | .get_settings = bnx2x_get_settings, |
2139 | .set_settings = bnx2x_set_settings, | 2192 | .set_settings = bnx2x_set_settings, |
@@ -2170,6 +2223,9 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { | |||
2170 | .get_strings = bnx2x_get_strings, | 2223 | .get_strings = bnx2x_get_strings, |
2171 | .phys_id = bnx2x_phys_id, | 2224 | .phys_id = bnx2x_phys_id, |
2172 | .get_ethtool_stats = bnx2x_get_ethtool_stats, | 2225 | .get_ethtool_stats = bnx2x_get_ethtool_stats, |
2226 | .get_rxnfc = bnx2x_get_rxnfc, | ||
2227 | .get_rxfh_indir = bnx2x_get_rxfh_indir, | ||
2228 | .set_rxfh_indir = bnx2x_set_rxfh_indir, | ||
2173 | }; | 2229 | }; |
2174 | 2230 | ||
2175 | void bnx2x_set_ethtool_ops(struct net_device *netdev) | 2231 | void bnx2x_set_ethtool_ops(struct net_device *netdev) |
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index c238c4d65d13..6c7745eee00d 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
@@ -4254,7 +4254,7 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp) | |||
4254 | min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1); | 4254 | min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1); |
4255 | } | 4255 | } |
4256 | 4256 | ||
4257 | static void bnx2x_init_ind_table(struct bnx2x *bp) | 4257 | void bnx2x_push_indir_table(struct bnx2x *bp) |
4258 | { | 4258 | { |
4259 | int func = BP_FUNC(bp); | 4259 | int func = BP_FUNC(bp); |
4260 | int i; | 4260 | int i; |
@@ -4262,13 +4262,20 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) | |||
4262 | if (bp->multi_mode == ETH_RSS_MODE_DISABLED) | 4262 | if (bp->multi_mode == ETH_RSS_MODE_DISABLED) |
4263 | return; | 4263 | return; |
4264 | 4264 | ||
4265 | DP(NETIF_MSG_IFUP, | ||
4266 | "Initializing indirection table multi_mode %d\n", bp->multi_mode); | ||
4267 | for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) | 4265 | for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) |
4268 | REG_WR8(bp, BAR_TSTRORM_INTMEM + | 4266 | REG_WR8(bp, BAR_TSTRORM_INTMEM + |
4269 | TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, | 4267 | TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, |
4270 | bp->fp->cl_id + (i % (bp->num_queues - | 4268 | bp->fp->cl_id + bp->rx_indir_table[i]); |
4271 | NONE_ETH_CONTEXT_USE))); | 4269 | } |
4270 | |||
4271 | static void bnx2x_init_ind_table(struct bnx2x *bp) | ||
4272 | { | ||
4273 | int i; | ||
4274 | |||
4275 | for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) | ||
4276 | bp->rx_indir_table[i] = i % BNX2X_NUM_ETH_QUEUES(bp); | ||
4277 | |||
4278 | bnx2x_push_indir_table(bp); | ||
4272 | } | 4279 | } |
4273 | 4280 | ||
4274 | void bnx2x_set_storm_rx_mode(struct bnx2x *bp) | 4281 | void bnx2x_set_storm_rx_mode(struct bnx2x *bp) |
@@ -6016,6 +6023,8 @@ void bnx2x_free_mem(struct bnx2x *bp) | |||
6016 | BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, | 6023 | BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, |
6017 | BCM_PAGE_SIZE * NUM_EQ_PAGES); | 6024 | BCM_PAGE_SIZE * NUM_EQ_PAGES); |
6018 | 6025 | ||
6026 | BNX2X_FREE(bp->rx_indir_table); | ||
6027 | |||
6019 | #undef BNX2X_PCI_FREE | 6028 | #undef BNX2X_PCI_FREE |
6020 | #undef BNX2X_KFREE | 6029 | #undef BNX2X_KFREE |
6021 | } | 6030 | } |
@@ -6146,6 +6155,9 @@ int bnx2x_alloc_mem(struct bnx2x *bp) | |||
6146 | /* EQ */ | 6155 | /* EQ */ |
6147 | BNX2X_PCI_ALLOC(bp->eq_ring, &bp->eq_mapping, | 6156 | BNX2X_PCI_ALLOC(bp->eq_ring, &bp->eq_mapping, |
6148 | BCM_PAGE_SIZE * NUM_EQ_PAGES); | 6157 | BCM_PAGE_SIZE * NUM_EQ_PAGES); |
6158 | |||
6159 | BNX2X_ALLOC(bp->rx_indir_table, sizeof(bp->rx_indir_table[0]) * | ||
6160 | TSTORM_INDIRECTION_TABLE_SIZE); | ||
6149 | return 0; | 6161 | return 0; |
6150 | 6162 | ||
6151 | alloc_mem_err: | 6163 | alloc_mem_err: |