forked from Minki/linux
Staging: sxg: Add Checksum Offload support for Sahara SXG driver
* This patch adds support for offloading checksum to hardware. IP checksum have been tested for IPv4 and IPv6. Signed-off-by: LinSysSoft Sahara Team <saharaproj@linsyssoft.com> Signed-off-by: Mithlesh Thukral <mithlesh@linsyssoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
c1f46a001f
commit
9914f0536f
@ -1078,6 +1078,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
|
|||||||
netdev->get_stats = sxg_get_stats;
|
netdev->get_stats = sxg_get_stats;
|
||||||
netdev->set_multicast_list = sxg_mcast_set_list;
|
netdev->set_multicast_list = sxg_mcast_set_list;
|
||||||
SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops);
|
SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops);
|
||||||
|
netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
|
||||||
err = sxg_set_interrupt_capability(adapter);
|
err = sxg_set_interrupt_capability(adapter);
|
||||||
if (err != STATUS_SUCCESS)
|
if (err != STATUS_SUCCESS)
|
||||||
DBG_ERROR("Cannot enable MSI-X capability\n");
|
DBG_ERROR("Cannot enable MSI-X capability\n");
|
||||||
@ -1432,6 +1433,31 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
|
|||||||
return (NewIsr);
|
return (NewIsr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sxg_rcv_checksum - Set the checksum for received packet
|
||||||
|
*
|
||||||
|
* Arguements:
|
||||||
|
* @skb - Packet which is receieved
|
||||||
|
* @Event - Event read from hardware
|
||||||
|
*/
|
||||||
|
|
||||||
|
void sxg_rcv_checksum(struct sk_buff *skb, struct sxg_event *Event)
|
||||||
|
{
|
||||||
|
skb->ip_summed = CHECKSUM_NONE;
|
||||||
|
if(Event->Status & EVENT_STATUS_TCPIP) {
|
||||||
|
if(!(Event->Status & EVENT_STATUS_TCPBAD)) {
|
||||||
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
|
}
|
||||||
|
if(!(Event->Status & EVENT_STATUS_IPBAD)) {
|
||||||
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
|
}
|
||||||
|
} else if(Event->Status & EVENT_STATUS_IPONLY) {
|
||||||
|
if(!(Event->Status & EVENT_STATUS_IPBAD)) {
|
||||||
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sxg_process_event_queue - Process our event queue
|
* sxg_process_event_queue - Process our event queue
|
||||||
*
|
*
|
||||||
@ -1506,9 +1532,7 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId,
|
|||||||
rx_bytes = Event->Length;
|
rx_bytes = Event->Length;
|
||||||
adapter->stats.rx_packets++;
|
adapter->stats.rx_packets++;
|
||||||
adapter->stats.rx_bytes += rx_bytes;
|
adapter->stats.rx_bytes += rx_bytes;
|
||||||
#if SXG_OFFLOAD_IP_CHECKSUM
|
sxg_rcv_checksum(skb, Event);
|
||||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
||||||
#endif
|
|
||||||
skb->dev = adapter->netdev;
|
skb->dev = adapter->netdev;
|
||||||
netif_receive_skb(skb);
|
netif_receive_skb(skb);
|
||||||
#endif
|
#endif
|
||||||
@ -2555,7 +2579,7 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
|||||||
SXG_LARGE_SEND_QUEUE_MASK));
|
SXG_LARGE_SEND_QUEUE_MASK));
|
||||||
}
|
}
|
||||||
} else if (skb->protocol == htons(ETH_P_IPV6)) {
|
} else if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||||
if ( (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) && (DataLength >=
|
if ((ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) && (DataLength >=
|
||||||
sizeof(struct tcphdr)) ) {
|
sizeof(struct tcphdr)) ) {
|
||||||
queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ?
|
queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ?
|
||||||
(ntohs (tcp_hdr(skb)->source) &
|
(ntohs (tcp_hdr(skb)->source) &
|
||||||
@ -2629,6 +2653,20 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
|
|||||||
XmtCmd->Buffer.TotalLength = DataLength;
|
XmtCmd->Buffer.TotalLength = DataLength;
|
||||||
XmtCmd->SgEntries = 1;
|
XmtCmd->SgEntries = 1;
|
||||||
XmtCmd->Flags = 0;
|
XmtCmd->Flags = 0;
|
||||||
|
|
||||||
|
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||||
|
/*
|
||||||
|
* We need to set the Checkum in IP header to 0. This is
|
||||||
|
* required by hardware.
|
||||||
|
*/
|
||||||
|
ip_hdr(skb)->check = 0x0;
|
||||||
|
XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP;
|
||||||
|
XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP;
|
||||||
|
/* Dont know if length will require a change in case of VLAN */
|
||||||
|
XmtCmd->CsumFlags.MacLen = ETH_HLEN;
|
||||||
|
XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >>
|
||||||
|
SXG_NW_HDR_LEN_SHIFT;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Advance transmit cmd descripter by 1.
|
* Advance transmit cmd descripter by 1.
|
||||||
* NOTE - See comments in SxgTcpOutput where we write
|
* NOTE - See comments in SxgTcpOutput where we write
|
||||||
@ -4064,6 +4102,8 @@ static int sxg_initialize_adapter(struct adapter_t *adapter)
|
|||||||
WRITE_REG(adapter->UcodeRegs[0].ReceiveChecksum,
|
WRITE_REG(adapter->UcodeRegs[0].ReceiveChecksum,
|
||||||
SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED, TRUE);
|
SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED, TRUE);
|
||||||
|
|
||||||
|
adapter->flags |= (SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED );
|
||||||
|
|
||||||
/* Initialize the MAC, XAUI */
|
/* Initialize the MAC, XAUI */
|
||||||
DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __func__);
|
DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __func__);
|
||||||
status = sxg_initialize_link(adapter);
|
status = sxg_initialize_link(adapter);
|
||||||
|
@ -1004,4 +1004,8 @@ struct sxg_ucode_stats {
|
|||||||
u32 XNoBufs; /* Xmt drop due to no DRAM Xmit buffer or PxyBuf */
|
u32 XNoBufs; /* Xmt drop due to no DRAM Xmit buffer or PxyBuf */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macros for handling the Offload engine values
|
||||||
|
*/
|
||||||
|
/* Number of positions to shift Network Header Length before passing to card */
|
||||||
|
#define SXG_NW_HDR_LEN_SHIFT 2
|
||||||
|
Loading…
Reference in New Issue
Block a user