aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Herbert <therbert@google.com>2011-02-16 05:27:02 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-17 15:49:45 -0500
commitab532cf32b4055028ad095d3c1fee9eec28ed25e (patch)
tree03c537583ce9d9dfa87d96e83ec4f467695ed3e4
parentf878b995b0f746f5726af9e66940f3bf373dae91 (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>
-rw-r--r--drivers/net/bnx2x/bnx2x.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c56
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c22
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,
1799BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ 1800BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */
1800 1801
1801extern void bnx2x_set_ethtool_ops(struct net_device *netdev); 1802extern void bnx2x_set_ethtool_ops(struct net_device *netdev);
1803void 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
2137static 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
2152static 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
2168static 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
2137static const struct ethtool_ops bnx2x_ethtool_ops = { 2190static 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
2175void bnx2x_set_ethtool_ops(struct net_device *netdev) 2231void 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
4257static void bnx2x_init_ind_table(struct bnx2x *bp) 4257void 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
4271static 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
4274void bnx2x_set_storm_rx_mode(struct bnx2x *bp) 4281void 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
6151alloc_mem_err: 6163alloc_mem_err: