+static void release_bounce_buffer(struct ibmvnic_adapter *adapter)
+{
+ struct device *dev = &adapter->vdev->dev;
+
+ if (!adapter->bounce_buffer)
+ return;
+
+ if (!dma_mapping_error(dev, adapter->bounce_buffer_dma)) {
+ dma_unmap_single(dev, adapter->bounce_buffer_dma,
+ adapter->bounce_buffer_size,
+ DMA_BIDIRECTIONAL);
+ adapter->bounce_buffer_dma = DMA_ERROR_CODE;
+ }
+
+ kfree(adapter->bounce_buffer);
+ adapter->bounce_buffer = NULL;
+}
+
+static int init_bounce_buffer(struct net_device *netdev)
+{
+ struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+ struct device *dev = &adapter->vdev->dev;
+ char *buf;
+ int buf_sz;
+ dma_addr_t map_addr;
+
+ buf_sz = (netdev->mtu + ETH_HLEN - 1) / PAGE_SIZE + 1;
+ buf = kmalloc(adapter->bounce_buffer_size, GFP_KERNEL);
+ if (!buf)
+ return -1;
+
+ map_addr = dma_map_single(dev, buf, buf_sz, DMA_TO_DEVICE);
+ if (dma_mapping_error(dev, map_addr)) {
+ dev_err(dev, "Couldn't map bounce buffer\n");
+ kfree(buf);
+ return -1;
+ }
+
+ adapter->bounce_buffer = buf;
+ adapter->bounce_buffer_size = buf_sz;
+ adapter->bounce_buffer_dma = map_addr;
+ return 0;
+}
+