aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3/sge.c
diff options
context:
space:
mode:
authorKaren Xie <kxie@chelsio.com>2008-12-19 01:56:20 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-19 01:56:20 -0500
commita109a5b916bc180e14fad0d1e9c37a08c85652c0 (patch)
tree03bf2fffff72aeb2dc881091bb728c83251598c8 /drivers/net/cxgb3/sge.c
parent221b3d60cbb2740ec7d46a4f1ea6d3318a112e51 (diff)
cxgb3: manage private iSCSI IP address
The accelerated iSCSI traffic could use a private IP address unknown to the OS: - The IP address is required in both drivers to manage ARP requests and connection set up. - Added an control call to retrieve the ip address. - Reply to ARP requests dedicated to the private IP address. Signed-off-by: Divy Le Ray <divy@chelsio.com> Signed-off-by: Karen Xie <kxie@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cxgb3/sge.c')
-rw-r--r--drivers/net/cxgb3/sge.c67
1 files changed, 64 insertions, 3 deletions
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 63eb97473c8b..6c641a889471 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -36,6 +36,7 @@
36#include <linux/ip.h> 36#include <linux/ip.h>
37#include <linux/tcp.h> 37#include <linux/tcp.h>
38#include <linux/dma-mapping.h> 38#include <linux/dma-mapping.h>
39#include <net/arp.h>
39#include "common.h" 40#include "common.h"
40#include "regs.h" 41#include "regs.h"
41#include "sge_defs.h" 42#include "sge_defs.h"
@@ -1863,6 +1864,54 @@ static void restart_tx(struct sge_qset *qs)
1863} 1864}
1864 1865
1865/** 1866/**
1867 * cxgb3_arp_process - process an ARP request probing a private IP address
1868 * @adapter: the adapter
1869 * @skb: the skbuff containing the ARP request
1870 *
1871 * Check if the ARP request is probing the private IP address
1872 * dedicated to iSCSI, generate an ARP reply if so.
1873 */
1874static void cxgb3_arp_process(struct adapter *adapter, struct sk_buff *skb)
1875{
1876 struct net_device *dev = skb->dev;
1877 struct port_info *pi;
1878 struct arphdr *arp;
1879 unsigned char *arp_ptr;
1880 unsigned char *sha;
1881 __be32 sip, tip;
1882
1883 if (!dev)
1884 return;
1885
1886 skb_reset_network_header(skb);
1887 arp = arp_hdr(skb);
1888
1889 if (arp->ar_op != htons(ARPOP_REQUEST))
1890 return;
1891
1892 arp_ptr = (unsigned char *)(arp + 1);
1893 sha = arp_ptr;
1894 arp_ptr += dev->addr_len;
1895 memcpy(&sip, arp_ptr, sizeof(sip));
1896 arp_ptr += sizeof(sip);
1897 arp_ptr += dev->addr_len;
1898 memcpy(&tip, arp_ptr, sizeof(tip));
1899
1900 pi = netdev_priv(dev);
1901 if (tip != pi->iscsi_ipv4addr)
1902 return;
1903
1904 arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
1905 dev->dev_addr, sha);
1906
1907}
1908
1909static inline int is_arp(struct sk_buff *skb)
1910{
1911 return skb->protocol == htons(ETH_P_ARP);
1912}
1913
1914/**
1866 * rx_eth - process an ingress ethernet packet 1915 * rx_eth - process an ingress ethernet packet
1867 * @adap: the adapter 1916 * @adap: the adapter
1868 * @rq: the response queue that received the packet 1917 * @rq: the response queue that received the packet
@@ -1885,7 +1934,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
1885 pi = netdev_priv(skb->dev); 1934 pi = netdev_priv(skb->dev);
1886 if (pi->rx_csum_offload && p->csum_valid && p->csum == htons(0xffff) && 1935 if (pi->rx_csum_offload && p->csum_valid && p->csum == htons(0xffff) &&
1887 !p->fragment) { 1936 !p->fragment) {
1888 rspq_to_qset(rq)->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; 1937 qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
1889 skb->ip_summed = CHECKSUM_UNNECESSARY; 1938 skb->ip_summed = CHECKSUM_UNNECESSARY;
1890 } else 1939 } else
1891 skb->ip_summed = CHECKSUM_NONE; 1940 skb->ip_summed = CHECKSUM_NONE;
@@ -1900,16 +1949,28 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
1900 grp, 1949 grp,
1901 ntohs(p->vlan), 1950 ntohs(p->vlan),
1902 p); 1951 p);
1903 else 1952 else {
1953 if (unlikely(pi->iscsi_ipv4addr &&
1954 is_arp(skb))) {
1955 unsigned short vtag = ntohs(p->vlan) &
1956 VLAN_VID_MASK;
1957 skb->dev = vlan_group_get_device(grp,
1958 vtag);
1959 cxgb3_arp_process(adap, skb);
1960 }
1904 __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan), 1961 __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
1905 rq->polling); 1962 rq->polling);
1963 }
1906 else 1964 else
1907 dev_kfree_skb_any(skb); 1965 dev_kfree_skb_any(skb);
1908 } else if (rq->polling) { 1966 } else if (rq->polling) {
1909 if (lro) 1967 if (lro)
1910 lro_receive_skb(&qs->lro_mgr, skb, p); 1968 lro_receive_skb(&qs->lro_mgr, skb, p);
1911 else 1969 else {
1970 if (unlikely(pi->iscsi_ipv4addr && is_arp(skb)))
1971 cxgb3_arp_process(adap, skb);
1912 netif_receive_skb(skb); 1972 netif_receive_skb(skb);
1973 }
1913 } else 1974 } else
1914 netif_rx(skb); 1975 netif_rx(skb);
1915} 1976}