static int ibmveth_send(struct ibmveth_adapter *adapter, union ibmveth_buf_desc *descs) { unsigned long correlator; unsigned int retry_count; unsigned long ret; /* * The retry count sets a maximum for the number of broadcast and * multicast destinations within the system. */ retry_count = 1024; correlator = 0; do { ret = h_send_logical_lan(adapter->vdev->unit_address, descs[0].desc, descs[1].desc, descs[2].desc, descs[3].desc, descs[4].desc, descs[5].desc, correlator, &correlator); } while ((ret == H_BUSY) && (retry_count--)); if (ret != H_SUCCESS && ret != H_DROPPED) { netdev_err(adapter->netdev, "tx: h_send_logical_lan failed " "with rc=%ld\n", ret); return 1; } return 0; }
static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) { struct ibmveth_adapter *adapter = netdev_priv(netdev); union ibmveth_buf_desc desc; unsigned long lpar_rc; unsigned long correlator; unsigned long flags; unsigned int retry_count; unsigned int tx_dropped = 0; unsigned int tx_bytes = 0; unsigned int tx_packets = 0; unsigned int tx_send_failed = 0; unsigned int tx_map_failed = 0; int used_bounce = 0; unsigned long data_dma_addr; desc.fields.flags_len = IBMVETH_BUF_VALID | skb->len; if (skb->ip_summed == CHECKSUM_PARTIAL && ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) { ibmveth_error_printk("tx: failed to checksum packet\n"); tx_dropped++; goto out; } if (skb->ip_summed == CHECKSUM_PARTIAL) { unsigned char *buf = skb_transport_header(skb) + skb->csum_offset; desc.fields.flags_len |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD); buf[0] = 0; buf[1] = 0; } data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, skb->len, DMA_TO_DEVICE); if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) { if (!firmware_has_feature(FW_FEATURE_CMO)) ibmveth_error_printk("tx: unable to map xmit buffer\n"); skb_copy_from_linear_data(skb, adapter->bounce_buffer, skb->len); desc.fields.address = adapter->bounce_buffer_dma; tx_map_failed++; used_bounce = 1; wmb(); } else desc.fields.address = data_dma_addr; correlator = 0; retry_count = 1024; do { lpar_rc = h_send_logical_lan(adapter->vdev->unit_address, desc.desc, 0, 0, 0, 0, 0, correlator, &correlator); } while ((lpar_rc == H_BUSY) && (retry_count--)); if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) { ibmveth_error_printk("tx: h_send_logical_lan failed with rc=%ld\n", lpar_rc); ibmveth_error_printk("tx: valid=%d, len=%d, address=0x%08x\n", (desc.fields.flags_len & IBMVETH_BUF_VALID) ? 1 : 0, skb->len, desc.fields.address); tx_send_failed++; tx_dropped++; } else { tx_packets++; tx_bytes += skb->len; netdev->trans_start = jiffies; } if (!used_bounce) dma_unmap_single(&adapter->vdev->dev, data_dma_addr, skb->len, DMA_TO_DEVICE); out: spin_lock_irqsave(&adapter->stats_lock, flags); netdev->stats.tx_dropped += tx_dropped; netdev->stats.tx_bytes += tx_bytes; netdev->stats.tx_packets += tx_packets; adapter->tx_send_failed += tx_send_failed; adapter->tx_map_failed += tx_map_failed; spin_unlock_irqrestore(&adapter->stats_lock, flags); dev_kfree_skb(skb); return NETDEV_TX_OK; }
static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) { struct ibmveth_adapter *adapter = netdev->priv; union ibmveth_buf_desc desc; unsigned long lpar_rc; unsigned long correlator; unsigned long flags; unsigned int retry_count; unsigned int tx_dropped = 0; unsigned int tx_bytes = 0; unsigned int tx_packets = 0; unsigned int tx_send_failed = 0; unsigned int tx_map_failed = 0; desc.fields.flags_len = IBMVETH_BUF_VALID | skb->len; desc.fields.address = dma_map_single(&adapter->vdev->dev, skb->data, skb->len, DMA_TO_DEVICE); if (skb->ip_summed == CHECKSUM_PARTIAL && ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) { ibmveth_error_printk("tx: failed to checksum packet\n"); tx_dropped++; goto out; } if (skb->ip_summed == CHECKSUM_PARTIAL) { unsigned char *buf = skb_transport_header(skb) + skb->csum_offset; desc.fields.flags_len |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD); /* Need to zero out the checksum */ buf[0] = 0; buf[1] = 0; } if (dma_mapping_error(desc.fields.address)) { ibmveth_error_printk("tx: unable to map xmit buffer\n"); tx_map_failed++; tx_dropped++; goto out; } /* send the frame. Arbitrarily set retrycount to 1024 */ correlator = 0; retry_count = 1024; do { lpar_rc = h_send_logical_lan(adapter->vdev->unit_address, desc.desc, 0, 0, 0, 0, 0, correlator, &correlator); } while ((lpar_rc == H_BUSY) && (retry_count--)); if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) { ibmveth_error_printk("tx: h_send_logical_lan failed with rc=%ld\n", lpar_rc); ibmveth_error_printk("tx: valid=%d, len=%d, address=0x%08x\n", (desc.fields.flags_len & IBMVETH_BUF_VALID) ? 1 : 0, skb->len, desc.fields.address); tx_send_failed++; tx_dropped++; } else { tx_packets++; tx_bytes += skb->len; netdev->trans_start = jiffies; } dma_unmap_single(&adapter->vdev->dev, desc.fields.address, skb->len, DMA_TO_DEVICE); out: spin_lock_irqsave(&adapter->stats_lock, flags); netdev->stats.tx_dropped += tx_dropped; netdev->stats.tx_bytes += tx_bytes; netdev->stats.tx_packets += tx_packets; adapter->tx_send_failed += tx_send_failed; adapter->tx_map_failed += tx_map_failed; spin_unlock_irqrestore(&adapter->stats_lock, flags); dev_kfree_skb(skb); return 0; }