diff options
Diffstat (limited to 'drivers/net/mlx4')
-rw-r--r-- | drivers/net/mlx4/en_netdev.c | 53 | ||||
-rw-r--r-- | drivers/net/mlx4/mlx4_en.h | 3 |
2 files changed, 24 insertions, 32 deletions
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 73c3d20c6453..96180c0ec206 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c | |||
@@ -161,39 +161,29 @@ static void mlx4_en_do_set_mac(struct work_struct *work) | |||
161 | static void mlx4_en_clear_list(struct net_device *dev) | 161 | static void mlx4_en_clear_list(struct net_device *dev) |
162 | { | 162 | { |
163 | struct mlx4_en_priv *priv = netdev_priv(dev); | 163 | struct mlx4_en_priv *priv = netdev_priv(dev); |
164 | struct dev_mc_list *plist = priv->mc_list; | ||
165 | struct dev_mc_list *next; | ||
166 | 164 | ||
167 | while (plist) { | 165 | kfree(priv->mc_addrs); |
168 | next = plist->next; | 166 | priv->mc_addrs_cnt = 0; |
169 | kfree(plist); | ||
170 | plist = next; | ||
171 | } | ||
172 | priv->mc_list = NULL; | ||
173 | } | 167 | } |
174 | 168 | ||
175 | static void mlx4_en_cache_mclist(struct net_device *dev) | 169 | static void mlx4_en_cache_mclist(struct net_device *dev) |
176 | { | 170 | { |
177 | struct mlx4_en_priv *priv = netdev_priv(dev); | 171 | struct mlx4_en_priv *priv = netdev_priv(dev); |
178 | struct dev_mc_list *mclist; | 172 | struct netdev_hw_addr *ha; |
179 | struct dev_mc_list *tmp; | 173 | char *mc_addrs; |
180 | struct dev_mc_list *plist = NULL; | 174 | int mc_addrs_cnt = netdev_mc_count(dev); |
181 | 175 | int i; | |
182 | for (mclist = dev->mc_list; mclist; mclist = mclist->next) { | 176 | |
183 | tmp = kmalloc(sizeof(struct dev_mc_list), GFP_ATOMIC); | 177 | mc_addrs = kmalloc(mc_addrs_cnt * ETH_ALEN, GFP_ATOMIC); |
184 | if (!tmp) { | 178 | if (!mc_addrs) { |
185 | en_err(priv, "failed to allocate multicast list\n"); | 179 | en_err(priv, "failed to allocate multicast list\n"); |
186 | mlx4_en_clear_list(dev); | 180 | return; |
187 | return; | ||
188 | } | ||
189 | memcpy(tmp, mclist, sizeof(struct dev_mc_list)); | ||
190 | tmp->next = NULL; | ||
191 | if (plist) | ||
192 | plist->next = tmp; | ||
193 | else | ||
194 | priv->mc_list = tmp; | ||
195 | plist = tmp; | ||
196 | } | 181 | } |
182 | i = 0; | ||
183 | netdev_for_each_mc_addr(ha, dev) | ||
184 | memcpy(mc_addrs + i++ * ETH_ALEN, ha->addr, ETH_ALEN); | ||
185 | priv->mc_addrs = mc_addrs; | ||
186 | priv->mc_addrs_cnt = mc_addrs_cnt; | ||
197 | } | 187 | } |
198 | 188 | ||
199 | 189 | ||
@@ -213,7 +203,6 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
213 | mcast_task); | 203 | mcast_task); |
214 | struct mlx4_en_dev *mdev = priv->mdev; | 204 | struct mlx4_en_dev *mdev = priv->mdev; |
215 | struct net_device *dev = priv->dev; | 205 | struct net_device *dev = priv->dev; |
216 | struct dev_mc_list *mclist; | ||
217 | u64 mcast_addr = 0; | 206 | u64 mcast_addr = 0; |
218 | int err; | 207 | int err; |
219 | 208 | ||
@@ -289,6 +278,8 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
289 | if (err) | 278 | if (err) |
290 | en_err(priv, "Failed disabling multicast filter\n"); | 279 | en_err(priv, "Failed disabling multicast filter\n"); |
291 | } else { | 280 | } else { |
281 | int i; | ||
282 | |||
292 | err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, | 283 | err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, |
293 | 0, MLX4_MCAST_DISABLE); | 284 | 0, MLX4_MCAST_DISABLE); |
294 | if (err) | 285 | if (err) |
@@ -303,8 +294,9 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
303 | netif_tx_lock_bh(dev); | 294 | netif_tx_lock_bh(dev); |
304 | mlx4_en_cache_mclist(dev); | 295 | mlx4_en_cache_mclist(dev); |
305 | netif_tx_unlock_bh(dev); | 296 | netif_tx_unlock_bh(dev); |
306 | for (mclist = priv->mc_list; mclist; mclist = mclist->next) { | 297 | for (i = 0; i < priv->mc_addrs_cnt; i++) { |
307 | mcast_addr = mlx4_en_mac_to_u64(mclist->dmi_addr); | 298 | mcast_addr = |
299 | mlx4_en_mac_to_u64(priv->mc_addrs + i * ETH_ALEN); | ||
308 | mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, | 300 | mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, |
309 | mcast_addr, 0, MLX4_MCAST_CONFIG); | 301 | mcast_addr, 0, MLX4_MCAST_CONFIG); |
310 | } | 302 | } |
@@ -512,7 +504,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work) | |||
512 | 504 | ||
513 | err = mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 0); | 505 | err = mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 0); |
514 | if (err) | 506 | if (err) |
515 | en_dbg(HW, priv, "Could not update stats \n"); | 507 | en_dbg(HW, priv, "Could not update stats\n"); |
516 | 508 | ||
517 | mutex_lock(&mdev->state_lock); | 509 | mutex_lock(&mdev->state_lock); |
518 | if (mdev->device_up) { | 510 | if (mdev->device_up) { |
@@ -985,7 +977,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
985 | priv->flags = prof->flags; | 977 | priv->flags = prof->flags; |
986 | priv->tx_ring_num = prof->tx_ring_num; | 978 | priv->tx_ring_num = prof->tx_ring_num; |
987 | priv->rx_ring_num = prof->rx_ring_num; | 979 | priv->rx_ring_num = prof->rx_ring_num; |
988 | priv->mc_list = NULL; | ||
989 | priv->mac_index = -1; | 980 | priv->mac_index = -1; |
990 | priv->msg_enable = MLX4_EN_MSG_LEVEL; | 981 | priv->msg_enable = MLX4_EN_MSG_LEVEL; |
991 | spin_lock_init(&priv->stats_lock); | 982 | spin_lock_init(&priv->stats_lock); |
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 82c3ebc584e3..b55e46c8b682 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h | |||
@@ -492,7 +492,8 @@ struct mlx4_en_priv { | |||
492 | struct mlx4_en_perf_stats pstats; | 492 | struct mlx4_en_perf_stats pstats; |
493 | struct mlx4_en_pkt_stats pkstats; | 493 | struct mlx4_en_pkt_stats pkstats; |
494 | struct mlx4_en_port_stats port_stats; | 494 | struct mlx4_en_port_stats port_stats; |
495 | struct dev_mc_list *mc_list; | 495 | char *mc_addrs; |
496 | int mc_addrs_cnt; | ||
496 | struct mlx4_en_stat_out_mbox hw_stats; | 497 | struct mlx4_en_stat_out_mbox hw_stats; |
497 | }; | 498 | }; |
498 | 499 | ||