aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ibmveth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ibmveth.c')
-rw-r--r--drivers/net/ibmveth.c64
1 files changed, 54 insertions, 10 deletions
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 4bac3cd8f235..44c9f993dcc4 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -212,7 +212,8 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
212 break; 212 break;
213 } 213 }
214 214
215 free_index = pool->consumer_index++ % pool->size; 215 free_index = pool->consumer_index;
216 pool->consumer_index = (pool->consumer_index + 1) % pool->size;
216 index = pool->free_map[free_index]; 217 index = pool->free_map[free_index];
217 218
218 ibmveth_assert(index != IBM_VETH_INVALID_MAP); 219 ibmveth_assert(index != IBM_VETH_INVALID_MAP);
@@ -238,7 +239,10 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
238 if(lpar_rc != H_SUCCESS) { 239 if(lpar_rc != H_SUCCESS) {
239 pool->free_map[free_index] = index; 240 pool->free_map[free_index] = index;
240 pool->skbuff[index] = NULL; 241 pool->skbuff[index] = NULL;
241 pool->consumer_index--; 242 if (pool->consumer_index == 0)
243 pool->consumer_index = pool->size - 1;
244 else
245 pool->consumer_index--;
242 dma_unmap_single(&adapter->vdev->dev, 246 dma_unmap_single(&adapter->vdev->dev,
243 pool->dma_addr[index], pool->buff_size, 247 pool->dma_addr[index], pool->buff_size,
244 DMA_FROM_DEVICE); 248 DMA_FROM_DEVICE);
@@ -325,7 +329,10 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64
325 adapter->rx_buff_pool[pool].buff_size, 329 adapter->rx_buff_pool[pool].buff_size,
326 DMA_FROM_DEVICE); 330 DMA_FROM_DEVICE);
327 331
328 free_index = adapter->rx_buff_pool[pool].producer_index++ % adapter->rx_buff_pool[pool].size; 332 free_index = adapter->rx_buff_pool[pool].producer_index;
333 adapter->rx_buff_pool[pool].producer_index
334 = (adapter->rx_buff_pool[pool].producer_index + 1)
335 % adapter->rx_buff_pool[pool].size;
329 adapter->rx_buff_pool[pool].free_map[free_index] = index; 336 adapter->rx_buff_pool[pool].free_map[free_index] = index;
330 337
331 mb(); 338 mb();
@@ -437,6 +444,31 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
437 &adapter->rx_buff_pool[i]); 444 &adapter->rx_buff_pool[i]);
438} 445}
439 446
447static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter,
448 union ibmveth_buf_desc rxq_desc, u64 mac_address)
449{
450 int rc, try_again = 1;
451
452 /* After a kexec the adapter will still be open, so our attempt to
453 * open it will fail. So if we get a failure we free the adapter and
454 * try again, but only once. */
455retry:
456 rc = h_register_logical_lan(adapter->vdev->unit_address,
457 adapter->buffer_list_dma, rxq_desc.desc,
458 adapter->filter_list_dma, mac_address);
459
460 if (rc != H_SUCCESS && try_again) {
461 do {
462 rc = h_free_logical_lan(adapter->vdev->unit_address);
463 } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY));
464
465 try_again = 0;
466 goto retry;
467 }
468
469 return rc;
470}
471
440static int ibmveth_open(struct net_device *netdev) 472static int ibmveth_open(struct net_device *netdev)
441{ 473{
442 struct ibmveth_adapter *adapter = netdev->priv; 474 struct ibmveth_adapter *adapter = netdev->priv;
@@ -502,12 +534,9 @@ static int ibmveth_open(struct net_device *netdev)
502 ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr); 534 ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr);
503 ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr); 535 ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr);
504 536
537 h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE);
505 538
506 lpar_rc = h_register_logical_lan(adapter->vdev->unit_address, 539 lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address);
507 adapter->buffer_list_dma,
508 rxq_desc.desc,
509 adapter->filter_list_dma,
510 mac_address);
511 540
512 if(lpar_rc != H_SUCCESS) { 541 if(lpar_rc != H_SUCCESS) {
513 ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); 542 ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc);
@@ -905,6 +934,14 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
905 return -EINVAL; 934 return -EINVAL;
906} 935}
907 936
937#ifdef CONFIG_NET_POLL_CONTROLLER
938static void ibmveth_poll_controller(struct net_device *dev)
939{
940 ibmveth_replenish_task(dev->priv);
941 ibmveth_interrupt(dev->irq, dev);
942}
943#endif
944
908static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) 945static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
909{ 946{
910 int rc, i; 947 int rc, i;
@@ -977,6 +1014,9 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
977 netdev->ethtool_ops = &netdev_ethtool_ops; 1014 netdev->ethtool_ops = &netdev_ethtool_ops;
978 netdev->change_mtu = ibmveth_change_mtu; 1015 netdev->change_mtu = ibmveth_change_mtu;
979 SET_NETDEV_DEV(netdev, &dev->dev); 1016 SET_NETDEV_DEV(netdev, &dev->dev);
1017#ifdef CONFIG_NET_POLL_CONTROLLER
1018 netdev->poll_controller = ibmveth_poll_controller;
1019#endif
980 netdev->features |= NETIF_F_LLTX; 1020 netdev->features |= NETIF_F_LLTX;
981 spin_lock_init(&adapter->stats_lock); 1021 spin_lock_init(&adapter->stats_lock);
982 1022
@@ -1132,7 +1172,9 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter)
1132{ 1172{
1133 struct proc_dir_entry *entry; 1173 struct proc_dir_entry *entry;
1134 if (ibmveth_proc_dir) { 1174 if (ibmveth_proc_dir) {
1135 entry = create_proc_entry(adapter->netdev->name, S_IFREG, ibmveth_proc_dir); 1175 char u_addr[10];
1176 sprintf(u_addr, "%x", adapter->vdev->unit_address);
1177 entry = create_proc_entry(u_addr, S_IFREG, ibmveth_proc_dir);
1136 if (!entry) { 1178 if (!entry) {
1137 ibmveth_error_printk("Cannot create adapter proc entry"); 1179 ibmveth_error_printk("Cannot create adapter proc entry");
1138 } else { 1180 } else {
@@ -1147,7 +1189,9 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter)
1147static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter) 1189static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter)
1148{ 1190{
1149 if (ibmveth_proc_dir) { 1191 if (ibmveth_proc_dir) {
1150 remove_proc_entry(adapter->netdev->name, ibmveth_proc_dir); 1192 char u_addr[10];
1193 sprintf(u_addr, "%x", adapter->vdev->unit_address);
1194 remove_proc_entry(u_addr, ibmveth_proc_dir);
1151 } 1195 }
1152} 1196}
1153 1197