===== drivers/net/ibmveth.c 1.17 vs edited ===== --- 1.17/drivers/net/ibmveth.c Mon Aug 23 03:14:44 2004 +++ edited/drivers/net/ibmveth.c Fri Aug 27 14:23:56 2004 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -104,7 +105,7 @@ static const char ibmveth_driver_name[] = "ibmveth"; static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet Driver"; -#define ibmveth_driver_version "1.02" +#define ibmveth_driver_version "1.03" MODULE_AUTHOR("Santiago Leon "); MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver"); @@ -132,6 +133,11 @@ return (adapter->rx_queue.queue_addr[adapter->rx_queue.index].length); } +static inline int ibmveth_rxq_frame_checksum_good(struct ibmveth_adapter *adapter) +{ + return (adapter->rx_queue.queue_addr[adapter->rx_queue.index].checksum_good); +} + /* setup the initial settings for a buffer pool */ static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool, u32 pool_index, u32 pool_size, u32 buff_size) { @@ -403,6 +409,11 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) { + unsigned long chkoff_result, dummy; + + h_illan_attributes(adapter->vdev->unit_address, CHECKSUM_OFFLOAD, 0, + chkoff_result, dummy); + if(adapter->buffer_list_addr != NULL) { if(!dma_mapping_error(adapter->buffer_list_dma)) { vio_unmap_single(adapter->vdev, adapter->buffer_list_dma, 4096, DMA_BIDIRECTIONAL); @@ -645,6 +656,12 @@ desc[0].fields.length, DMA_TO_DEVICE); desc[0].fields.valid = 1; + if (adapter->can_checksum_offload && skb->ip_summed == CHECKSUM_HW) { + desc[0].fields.no_checksum = 1; + desc[0].fields.checksum_good = 1; + skb->h.th->check = 0; + } + if(dma_mapping_error(desc[0].fields.address)) { ibmveth_error_printk("tx: unable to map initial fragment\n"); adapter->tx_map_failed++; @@ -743,6 +760,7 @@ } else { int length = ibmveth_rxq_frame_length(adapter); int offset = ibmveth_rxq_frame_offset(adapter); + int checksum_good = ibmveth_rxq_frame_checksum_good(adapter); skb = ibmveth_rxq_get_buffer(adapter); ibmveth_rxq_harvest_buffer(adapter); @@ -751,6 +769,11 @@ skb_put(skb, length); skb->dev = netdev; skb->protocol = eth_type_trans(skb, netdev); + + if (checksum_good) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; netif_receive_skb(skb); /* send it up */ @@ -878,7 +901,7 @@ unsigned char *mac_addr_p; unsigned int *mcastFilterSize_p; - + unsigned long chkoff_result, dummy; ibmveth_debug_printk_no_adapter("entering ibmveth_probe for UA 0x%x\n", dev->unit_address); @@ -926,6 +949,18 @@ adapter->liobn = dev->iommu_table->it_index; + rc = h_illan_attributes(dev->unit_address, 0, CHECKSUM_OFFLOAD, + chkoff_result, dummy); + + if (rc == H_Success) + adapter->can_checksum_offload = 1; + else + adapter->can_checksum_offload = 0; + + ibmveth_printk("Firmware %s checksum offload, result mask=%lu\n", + adapter->can_checksum_offload? "supports" : + "does not support", chkoff_result); + netdev->irq = dev->irq; netdev->open = ibmveth_open; netdev->poll = ibmveth_poll; @@ -937,6 +972,8 @@ netdev->do_ioctl = ibmveth_ioctl; netdev->ethtool_ops = &netdev_ethtool_ops; netdev->change_mtu = ibmveth_change_mtu; + if (adapter->can_checksum_offload) + netdev->features = NETIF_F_HW_CSUM; SET_NETDEV_DEV(netdev, &dev->dev); memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); ===== drivers/net/ibmveth.h 1.2 vs edited ===== --- 1.2/drivers/net/ibmveth.h Mon Aug 23 03:14:44 2004 +++ edited/drivers/net/ibmveth.h Fri Aug 27 14:21:15 2004 @@ -49,6 +49,7 @@ #define H_SEND_LOGICAL_LAN 0x120 #define H_MULTICAST_CTRL 0x130 #define H_CHANGE_LOGICAL_LAN_MAC 0x14C +#define H_ILLAN_ATTRIBUTES 0x244 /* hcall macros */ #define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \ @@ -69,6 +70,9 @@ #define h_change_logical_lan_mac(ua, mac) \ plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac) +#define h_illan_attributes(ua, reset_mask, set_mask, result, dummy) \ + plpar_hcall(H_ILLAN_ATTRIBUTES, ua, reset_mask, set_mask, 0, &result, &dummy, &dummy) + #define IbmVethNumBufferPools 3 #define IbmVethPool0DftSize (1024 * 2) #define IbmVethPool1DftSize (1024 * 4) @@ -79,6 +83,8 @@ #define IBM_VETH_INVALID_MAP ((u16)0xffff) +#define CHECKSUM_OFFLOAD 0x6 + struct ibmveth_buff_pool { u32 size; u32 index; @@ -115,6 +121,7 @@ struct ibmveth_buff_pool rx_buff_pool[IbmVethNumBufferPools]; struct ibmveth_rx_q rx_queue; atomic_t not_replenishing; + int can_checksum_offload; /* helper tasks */ struct work_struct replenish_task; @@ -136,7 +143,9 @@ struct ibmveth_buf_desc_fields { u32 valid : 1; u32 toggle : 1; - u32 reserved : 6; + u32 reserved : 4; + u32 no_checksum : 1; + u32 checksum_good :1; u32 length : 24; u32 address; }; @@ -149,7 +158,10 @@ struct ibmveth_rx_q_entry { u16 toggle : 1; u16 valid : 1; - u16 reserved : 14; + u16 reserved : 4; + u16 no_checksum : 1; + u16 checksum_good : 1; + u16 reserved2 : 8; u16 offset; u32 length; u64 correlator;