aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4/en_netdev.c
diff options
context:
space:
mode:
authorYevgeny Petrilin <yevgenyp@mellanox.co.il>2011-03-22 18:38:31 -0400
committerDavid S. Miller <davem@davemloft.net>2011-03-23 15:24:22 -0400
commit1679200f91da6a054b06954c9bd3eeed29b6731f (patch)
treea447268debe479a257cfff4c7e5e86151eef6583 /drivers/net/mlx4/en_netdev.c
parentb12d93d63c3217f0ec923ff938b12a744e242ffa (diff)
mlx4_en: Enabling new steering
The mlx4_en module now uses the new steering mechanism. The RX packets are now steered through the MCG table instead of Mac table for unicast, and default entry for multicast. The feature is enabled through INIT_HCA Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/mlx4/en_netdev.c')
-rw-r--r--drivers/net/mlx4/en_netdev.c133
1 files changed, 106 insertions, 27 deletions
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index f6ed315b4b89..08e680100db8 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -156,9 +156,8 @@ static void mlx4_en_do_set_mac(struct work_struct *work)
156 mutex_lock(&mdev->state_lock); 156 mutex_lock(&mdev->state_lock);
157 if (priv->port_up) { 157 if (priv->port_up) {
158 /* Remove old MAC and insert the new one */ 158 /* Remove old MAC and insert the new one */
159 mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index); 159 err = mlx4_replace_mac(mdev->dev, priv->port,
160 err = mlx4_register_mac(mdev->dev, priv->port, 160 priv->base_qpn, priv->mac, 0);
161 priv->mac, &priv->mac_index);
162 if (err) 161 if (err)
163 en_err(priv, "Failed changing HW MAC address\n"); 162 en_err(priv, "Failed changing HW MAC address\n");
164 } else 163 } else
@@ -214,6 +213,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
214 struct mlx4_en_dev *mdev = priv->mdev; 213 struct mlx4_en_dev *mdev = priv->mdev;
215 struct net_device *dev = priv->dev; 214 struct net_device *dev = priv->dev;
216 u64 mcast_addr = 0; 215 u64 mcast_addr = 0;
216 u8 mc_list[16] = {0};
217 int err; 217 int err;
218 218
219 mutex_lock(&mdev->state_lock); 219 mutex_lock(&mdev->state_lock);
@@ -239,8 +239,12 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
239 priv->flags |= MLX4_EN_FLAG_PROMISC; 239 priv->flags |= MLX4_EN_FLAG_PROMISC;
240 240
241 /* Enable promiscouos mode */ 241 /* Enable promiscouos mode */
242 err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, 242 if (!mdev->dev->caps.vep_uc_steering)
243 priv->base_qpn, 1); 243 err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
244 priv->base_qpn, 1);
245 else
246 err = mlx4_unicast_promisc_add(mdev->dev, priv->base_qpn,
247 priv->port);
244 if (err) 248 if (err)
245 en_err(priv, "Failed enabling " 249 en_err(priv, "Failed enabling "
246 "promiscous mode\n"); 250 "promiscous mode\n");
@@ -252,10 +256,21 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
252 en_err(priv, "Failed disabling " 256 en_err(priv, "Failed disabling "
253 "multicast filter\n"); 257 "multicast filter\n");
254 258
255 /* Disable port VLAN filter */ 259 /* Add the default qp number as multicast promisc */
256 err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL); 260 if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) {
257 if (err) 261 err = mlx4_multicast_promisc_add(mdev->dev, priv->base_qpn,
258 en_err(priv, "Failed disabling VLAN filter\n"); 262 priv->port);
263 if (err)
264 en_err(priv, "Failed entering multicast promisc mode\n");
265 priv->flags |= MLX4_EN_FLAG_MC_PROMISC;
266 }
267
268 if (priv->vlgrp) {
269 /* Disable port VLAN filter */
270 err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL);
271 if (err)
272 en_err(priv, "Failed disabling VLAN filter\n");
273 }
259 } 274 }
260 goto out; 275 goto out;
261 } 276 }
@@ -270,11 +285,24 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
270 priv->flags &= ~MLX4_EN_FLAG_PROMISC; 285 priv->flags &= ~MLX4_EN_FLAG_PROMISC;
271 286
272 /* Disable promiscouos mode */ 287 /* Disable promiscouos mode */
273 err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, 288 if (!mdev->dev->caps.vep_uc_steering)
274 priv->base_qpn, 0); 289 err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
290 priv->base_qpn, 0);
291 else
292 err = mlx4_unicast_promisc_remove(mdev->dev, priv->base_qpn,
293 priv->port);
275 if (err) 294 if (err)
276 en_err(priv, "Failed disabling promiscous mode\n"); 295 en_err(priv, "Failed disabling promiscous mode\n");
277 296
297 /* Disable Multicast promisc */
298 if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) {
299 err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn,
300 priv->port);
301 if (err)
302 en_err(priv, "Failed disabling multicast promiscous mode\n");
303 priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC;
304 }
305
278 /* Enable port VLAN filter */ 306 /* Enable port VLAN filter */
279 err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); 307 err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
280 if (err) 308 if (err)
@@ -287,14 +315,38 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
287 0, MLX4_MCAST_DISABLE); 315 0, MLX4_MCAST_DISABLE);
288 if (err) 316 if (err)
289 en_err(priv, "Failed disabling multicast filter\n"); 317 en_err(priv, "Failed disabling multicast filter\n");
318
319 /* Add the default qp number as multicast promisc */
320 if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) {
321 err = mlx4_multicast_promisc_add(mdev->dev, priv->base_qpn,
322 priv->port);
323 if (err)
324 en_err(priv, "Failed entering multicast promisc mode\n");
325 priv->flags |= MLX4_EN_FLAG_MC_PROMISC;
326 }
290 } else { 327 } else {
291 int i; 328 int i;
329 /* Disable Multicast promisc */
330 if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) {
331 err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn,
332 priv->port);
333 if (err)
334 en_err(priv, "Failed disabling multicast promiscous mode\n");
335 priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC;
336 }
292 337
293 err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 338 err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
294 0, MLX4_MCAST_DISABLE); 339 0, MLX4_MCAST_DISABLE);
295 if (err) 340 if (err)
296 en_err(priv, "Failed disabling multicast filter\n"); 341 en_err(priv, "Failed disabling multicast filter\n");
297 342
343 /* Detach our qp from all the multicast addresses */
344 for (i = 0; i < priv->mc_addrs_cnt; i++) {
345 memcpy(&mc_list[10], priv->mc_addrs + i * ETH_ALEN, ETH_ALEN);
346 mc_list[5] = priv->port;
347 mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp,
348 mc_list, MLX4_PROT_ETH);
349 }
298 /* Flush mcast filter and init it with broadcast address */ 350 /* Flush mcast filter and init it with broadcast address */
299 mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, ETH_BCAST, 351 mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, ETH_BCAST,
300 1, MLX4_MCAST_CONFIG); 352 1, MLX4_MCAST_CONFIG);
@@ -307,6 +359,10 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
307 for (i = 0; i < priv->mc_addrs_cnt; i++) { 359 for (i = 0; i < priv->mc_addrs_cnt; i++) {
308 mcast_addr = 360 mcast_addr =
309 mlx4_en_mac_to_u64(priv->mc_addrs + i * ETH_ALEN); 361 mlx4_en_mac_to_u64(priv->mc_addrs + i * ETH_ALEN);
362 memcpy(&mc_list[10], priv->mc_addrs + i * ETH_ALEN, ETH_ALEN);
363 mc_list[5] = priv->port;
364 mlx4_multicast_attach(mdev->dev, &priv->rss_map.indir_qp,
365 mc_list, 0, MLX4_PROT_ETH);
310 mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 366 mlx4_SET_MCAST_FLTR(mdev->dev, priv->port,
311 mcast_addr, 0, MLX4_MCAST_CONFIG); 367 mcast_addr, 0, MLX4_MCAST_CONFIG);
312 } 368 }
@@ -314,8 +370,6 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
314 0, MLX4_MCAST_ENABLE); 370 0, MLX4_MCAST_ENABLE);
315 if (err) 371 if (err)
316 en_err(priv, "Failed enabling multicast filter\n"); 372 en_err(priv, "Failed enabling multicast filter\n");
317
318 mlx4_en_clear_list(dev);
319 } 373 }
320out: 374out:
321 mutex_unlock(&mdev->state_lock); 375 mutex_unlock(&mdev->state_lock);
@@ -557,6 +611,7 @@ int mlx4_en_start_port(struct net_device *dev)
557 int err = 0; 611 int err = 0;
558 int i; 612 int i;
559 int j; 613 int j;
614 u8 mc_list[16] = {0};
560 char name[32]; 615 char name[32];
561 616
562 if (priv->port_up) { 617 if (priv->port_up) {
@@ -596,10 +651,20 @@ int mlx4_en_start_port(struct net_device *dev)
596 ++rx_index; 651 ++rx_index;
597 } 652 }
598 653
654 /* Set port mac number */
655 en_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
656 err = mlx4_register_mac(mdev->dev, priv->port,
657 priv->mac, &priv->base_qpn, 0);
658 if (err) {
659 en_err(priv, "Failed setting port mac\n");
660 goto cq_err;
661 }
662 mdev->mac_removed[priv->port] = 0;
663
599 err = mlx4_en_config_rss_steer(priv); 664 err = mlx4_en_config_rss_steer(priv);
600 if (err) { 665 if (err) {
601 en_err(priv, "Failed configuring rss steering\n"); 666 en_err(priv, "Failed configuring rss steering\n");
602 goto cq_err; 667 goto mac_err;
603 } 668 }
604 669
605 if (mdev->dev->caps.comp_pool && !priv->tx_vector) { 670 if (mdev->dev->caps.comp_pool && !priv->tx_vector) {
@@ -661,24 +726,22 @@ int mlx4_en_start_port(struct net_device *dev)
661 en_err(priv, "Failed setting default qp numbers\n"); 726 en_err(priv, "Failed setting default qp numbers\n");
662 goto tx_err; 727 goto tx_err;
663 } 728 }
664 /* Set port mac number */
665 en_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
666 err = mlx4_register_mac(mdev->dev, priv->port,
667 priv->mac, &priv->mac_index);
668 if (err) {
669 en_err(priv, "Failed setting port mac\n");
670 goto tx_err;
671 }
672 mdev->mac_removed[priv->port] = 0;
673 729
674 /* Init port */ 730 /* Init port */
675 en_dbg(HW, priv, "Initializing port\n"); 731 en_dbg(HW, priv, "Initializing port\n");
676 err = mlx4_INIT_PORT(mdev->dev, priv->port); 732 err = mlx4_INIT_PORT(mdev->dev, priv->port);
677 if (err) { 733 if (err) {
678 en_err(priv, "Failed Initializing port\n"); 734 en_err(priv, "Failed Initializing port\n");
679 goto mac_err; 735 goto tx_err;
680 } 736 }
681 737
738 /* Attach rx QP to bradcast address */
739 memset(&mc_list[10], 0xff, ETH_ALEN);
740 mc_list[5] = priv->port;
741 if (mlx4_multicast_attach(mdev->dev, &priv->rss_map.indir_qp, mc_list,
742 0, MLX4_PROT_ETH))
743 mlx4_warn(mdev, "Failed Attaching Broadcast\n");
744
682 /* Schedule multicast task to populate multicast list */ 745 /* Schedule multicast task to populate multicast list */
683 queue_work(mdev->workqueue, &priv->mcast_task); 746 queue_work(mdev->workqueue, &priv->mcast_task);
684 747
@@ -686,8 +749,6 @@ int mlx4_en_start_port(struct net_device *dev)
686 netif_tx_start_all_queues(dev); 749 netif_tx_start_all_queues(dev);
687 return 0; 750 return 0;
688 751
689mac_err:
690 mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
691tx_err: 752tx_err:
692 while (tx_index--) { 753 while (tx_index--) {
693 mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[tx_index]); 754 mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[tx_index]);
@@ -695,6 +756,8 @@ tx_err:
695 } 756 }
696 757
697 mlx4_en_release_rss_steer(priv); 758 mlx4_en_release_rss_steer(priv);
759mac_err:
760 mlx4_unregister_mac(mdev->dev, priv->port, priv->base_qpn);
698cq_err: 761cq_err:
699 while (rx_index--) 762 while (rx_index--)
700 mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]); 763 mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]);
@@ -710,6 +773,7 @@ void mlx4_en_stop_port(struct net_device *dev)
710 struct mlx4_en_priv *priv = netdev_priv(dev); 773 struct mlx4_en_priv *priv = netdev_priv(dev);
711 struct mlx4_en_dev *mdev = priv->mdev; 774 struct mlx4_en_dev *mdev = priv->mdev;
712 int i; 775 int i;
776 u8 mc_list[16] = {0};
713 777
714 if (!priv->port_up) { 778 if (!priv->port_up) {
715 en_dbg(DRV, priv, "stop port called while port already down\n"); 779 en_dbg(DRV, priv, "stop port called while port already down\n");
@@ -724,8 +788,23 @@ void mlx4_en_stop_port(struct net_device *dev)
724 /* Set port as not active */ 788 /* Set port as not active */
725 priv->port_up = false; 789 priv->port_up = false;
726 790
791 /* Detach All multicasts */
792 memset(&mc_list[10], 0xff, ETH_ALEN);
793 mc_list[5] = priv->port;
794 mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, mc_list,
795 MLX4_PROT_ETH);
796 for (i = 0; i < priv->mc_addrs_cnt; i++) {
797 memcpy(&mc_list[10], priv->mc_addrs + i * ETH_ALEN, ETH_ALEN);
798 mc_list[5] = priv->port;
799 mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp,
800 mc_list, MLX4_PROT_ETH);
801 }
802 mlx4_en_clear_list(dev);
803 /* Flush multicast filter */
804 mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG);
805
727 /* Unregister Mac address for the port */ 806 /* Unregister Mac address for the port */
728 mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index); 807 mlx4_unregister_mac(mdev->dev, priv->port, priv->base_qpn);
729 mdev->mac_removed[priv->port] = 1; 808 mdev->mac_removed[priv->port] = 1;
730 809
731 /* Free TX Rings */ 810 /* Free TX Rings */