aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3
diff options
context:
space:
mode:
authorKaren Xie <kxie@chelsio.com>2009-10-08 05:11:05 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-13 06:44:06 -0400
commitf14d42f314cb45a080bf84ecadf8b9b1eebbe9fd (patch)
treefb89056f265802233d87db2a41d3d35646665878 /drivers/net/cxgb3
parentbcd5149ded6b2edbf3732fa1483600a716b1cba6 (diff)
cxgb3: Added private MAC address and provisioning packet handler for iSCSI
This patch added support of private MAC address per port and provisioning packet handler for iSCSI traffic only. The above changes are isolated to the cxgb3 driver, independent of any scsi or iscsi driver changes. Acked-by: Karen Xie <kxie@chelsio.com> Acked-by: Divy Le Ray <divy@chelsio.com> Signed-off-by: Rakesh Ranjan <rakesh@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cxgb3')
-rw-r--r--drivers/net/cxgb3/adapter.h16
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c22
-rw-r--r--drivers/net/cxgb3/sge.c28
3 files changed, 53 insertions, 13 deletions
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 2b1aea6aa558..3e8618b4efbc 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -48,12 +48,27 @@
48struct vlan_group; 48struct vlan_group;
49struct adapter; 49struct adapter;
50struct sge_qset; 50struct sge_qset;
51struct port_info;
51 52
52enum { /* rx_offload flags */ 53enum { /* rx_offload flags */
53 T3_RX_CSUM = 1 << 0, 54 T3_RX_CSUM = 1 << 0,
54 T3_LRO = 1 << 1, 55 T3_LRO = 1 << 1,
55}; 56};
56 57
58enum mac_idx_types {
59 LAN_MAC_IDX = 0,
60 SAN_MAC_IDX,
61
62 MAX_MAC_IDX
63};
64
65struct iscsi_config {
66 __u8 mac_addr[ETH_ALEN];
67 __u32 flags;
68 int (*send)(struct port_info *pi, struct sk_buff **skb);
69 int (*recv)(struct port_info *pi, struct sk_buff *skb);
70};
71
57struct port_info { 72struct port_info {
58 struct adapter *adapter; 73 struct adapter *adapter;
59 struct vlan_group *vlan_grp; 74 struct vlan_group *vlan_grp;
@@ -68,6 +83,7 @@ struct port_info {
68 struct net_device_stats netstats; 83 struct net_device_stats netstats;
69 int activity; 84 int activity;
70 __be32 iscsi_ipv4addr; 85 __be32 iscsi_ipv4addr;
86 struct iscsi_config iscsic;
71 87
72 int link_fault; /* link fault was detected */ 88 int link_fault; /* link fault was detected */
73}; 89};
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 34e776c5f06b..c9113d3297ee 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -344,8 +344,10 @@ static void link_start(struct net_device *dev)
344 344
345 init_rx_mode(&rm, dev, dev->mc_list); 345 init_rx_mode(&rm, dev, dev->mc_list);
346 t3_mac_reset(mac); 346 t3_mac_reset(mac);
347 t3_mac_set_num_ucast(mac, MAX_MAC_IDX);
347 t3_mac_set_mtu(mac, dev->mtu); 348 t3_mac_set_mtu(mac, dev->mtu);
348 t3_mac_set_address(mac, 0, dev->dev_addr); 349 t3_mac_set_address(mac, LAN_MAC_IDX, dev->dev_addr);
350 t3_mac_set_address(mac, SAN_MAC_IDX, pi->iscsic.mac_addr);
349 t3_mac_set_rx_mode(mac, &rm); 351 t3_mac_set_rx_mode(mac, &rm);
350 t3_link_start(&pi->phy, mac, &pi->link_config); 352 t3_link_start(&pi->phy, mac, &pi->link_config);
351 t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); 353 t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
@@ -903,6 +905,7 @@ static inline int offload_tx(struct t3cdev *tdev, struct sk_buff *skb)
903static int write_smt_entry(struct adapter *adapter, int idx) 905static int write_smt_entry(struct adapter *adapter, int idx)
904{ 906{
905 struct cpl_smt_write_req *req; 907 struct cpl_smt_write_req *req;
908 struct port_info *pi = netdev_priv(adapter->port[idx]);
906 struct sk_buff *skb = alloc_skb(sizeof(*req), GFP_KERNEL); 909 struct sk_buff *skb = alloc_skb(sizeof(*req), GFP_KERNEL);
907 910
908 if (!skb) 911 if (!skb)
@@ -913,8 +916,8 @@ static int write_smt_entry(struct adapter *adapter, int idx)
913 OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, idx)); 916 OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, idx));
914 req->mtu_idx = NMTUS - 1; /* should be 0 but there's a T3 bug */ 917 req->mtu_idx = NMTUS - 1; /* should be 0 but there's a T3 bug */
915 req->iff = idx; 918 req->iff = idx;
916 memset(req->src_mac1, 0, sizeof(req->src_mac1));
917 memcpy(req->src_mac0, adapter->port[idx]->dev_addr, ETH_ALEN); 919 memcpy(req->src_mac0, adapter->port[idx]->dev_addr, ETH_ALEN);
920 memcpy(req->src_mac1, pi->iscsic.mac_addr, ETH_ALEN);
918 skb->priority = 1; 921 skb->priority = 1;
919 offload_tx(&adapter->tdev, skb); 922 offload_tx(&adapter->tdev, skb);
920 return 0; 923 return 0;
@@ -2516,7 +2519,7 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p)
2516 return -EINVAL; 2519 return -EINVAL;
2517 2520
2518 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 2521 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
2519 t3_mac_set_address(&pi->mac, 0, dev->dev_addr); 2522 t3_mac_set_address(&pi->mac, LAN_MAC_IDX, dev->dev_addr);
2520 if (offload_running(adapter)) 2523 if (offload_running(adapter))
2521 write_smt_entry(adapter, pi->port_id); 2524 write_smt_entry(adapter, pi->port_id);
2522 return 0; 2525 return 0;
@@ -2654,7 +2657,7 @@ static void check_t3b2_mac(struct adapter *adapter)
2654 struct cmac *mac = &p->mac; 2657 struct cmac *mac = &p->mac;
2655 2658
2656 t3_mac_set_mtu(mac, dev->mtu); 2659 t3_mac_set_mtu(mac, dev->mtu);
2657 t3_mac_set_address(mac, 0, dev->dev_addr); 2660 t3_mac_set_address(mac, LAN_MAC_IDX, dev->dev_addr);
2658 cxgb_set_rxmode(dev); 2661 cxgb_set_rxmode(dev);
2659 t3_link_start(&p->phy, mac, &p->link_config); 2662 t3_link_start(&p->phy, mac, &p->link_config);
2660 t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); 2663 t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
@@ -3112,6 +3115,14 @@ static const struct net_device_ops cxgb_netdev_ops = {
3112#endif 3115#endif
3113}; 3116};
3114 3117
3118static void __devinit cxgb3_init_iscsi_mac(struct net_device *dev)
3119{
3120 struct port_info *pi = netdev_priv(dev);
3121
3122 memcpy(pi->iscsic.mac_addr, dev->dev_addr, ETH_ALEN);
3123 pi->iscsic.mac_addr[3] |= 0x80;
3124}
3125
3115static int __devinit init_one(struct pci_dev *pdev, 3126static int __devinit init_one(struct pci_dev *pdev,
3116 const struct pci_device_id *ent) 3127 const struct pci_device_id *ent)
3117{ 3128{
@@ -3270,6 +3281,9 @@ static int __devinit init_one(struct pci_dev *pdev,
3270 goto out_free_dev; 3281 goto out_free_dev;
3271 } 3282 }
3272 3283
3284 for_each_port(adapter, i)
3285 cxgb3_init_iscsi_mac(adapter->port[i]);
3286
3273 /* Driver's ready. Reflect it on LEDs */ 3287 /* Driver's ready. Reflect it on LEDs */
3274 t3_led_ready(adapter); 3288 t3_led_ready(adapter);
3275 3289
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index f86612857a73..b7f4ee40879c 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1946,10 +1946,9 @@ static void restart_tx(struct sge_qset *qs)
1946 * Check if the ARP request is probing the private IP address 1946 * Check if the ARP request is probing the private IP address
1947 * dedicated to iSCSI, generate an ARP reply if so. 1947 * dedicated to iSCSI, generate an ARP reply if so.
1948 */ 1948 */
1949static void cxgb3_arp_process(struct adapter *adapter, struct sk_buff *skb) 1949static void cxgb3_arp_process(struct port_info *pi, struct sk_buff *skb)
1950{ 1950{
1951 struct net_device *dev = skb->dev; 1951 struct net_device *dev = skb->dev;
1952 struct port_info *pi;
1953 struct arphdr *arp; 1952 struct arphdr *arp;
1954 unsigned char *arp_ptr; 1953 unsigned char *arp_ptr;
1955 unsigned char *sha; 1954 unsigned char *sha;
@@ -1972,12 +1971,11 @@ static void cxgb3_arp_process(struct adapter *adapter, struct sk_buff *skb)
1972 arp_ptr += dev->addr_len; 1971 arp_ptr += dev->addr_len;
1973 memcpy(&tip, arp_ptr, sizeof(tip)); 1972 memcpy(&tip, arp_ptr, sizeof(tip));
1974 1973
1975 pi = netdev_priv(dev);
1976 if (tip != pi->iscsi_ipv4addr) 1974 if (tip != pi->iscsi_ipv4addr)
1977 return; 1975 return;
1978 1976
1979 arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha, 1977 arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
1980 dev->dev_addr, sha); 1978 pi->iscsic.mac_addr, sha);
1981 1979
1982} 1980}
1983 1981
@@ -1986,6 +1984,19 @@ static inline int is_arp(struct sk_buff *skb)
1986 return skb->protocol == htons(ETH_P_ARP); 1984 return skb->protocol == htons(ETH_P_ARP);
1987} 1985}
1988 1986
1987static void cxgb3_process_iscsi_prov_pack(struct port_info *pi,
1988 struct sk_buff *skb)
1989{
1990 if (is_arp(skb)) {
1991 cxgb3_arp_process(pi, skb);
1992 return;
1993 }
1994
1995 if (pi->iscsic.recv)
1996 pi->iscsic.recv(pi, skb);
1997
1998}
1999
1989/** 2000/**
1990 * rx_eth - process an ingress ethernet packet 2001 * rx_eth - process an ingress ethernet packet
1991 * @adap: the adapter 2002 * @adap: the adapter
@@ -2024,13 +2035,12 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
2024 vlan_gro_receive(&qs->napi, grp, 2035 vlan_gro_receive(&qs->napi, grp,
2025 ntohs(p->vlan), skb); 2036 ntohs(p->vlan), skb);
2026 else { 2037 else {
2027 if (unlikely(pi->iscsi_ipv4addr && 2038 if (unlikely(pi->iscsic.flags)) {
2028 is_arp(skb))) {
2029 unsigned short vtag = ntohs(p->vlan) & 2039 unsigned short vtag = ntohs(p->vlan) &
2030 VLAN_VID_MASK; 2040 VLAN_VID_MASK;
2031 skb->dev = vlan_group_get_device(grp, 2041 skb->dev = vlan_group_get_device(grp,
2032 vtag); 2042 vtag);
2033 cxgb3_arp_process(adap, skb); 2043 cxgb3_process_iscsi_prov_pack(pi, skb);
2034 } 2044 }
2035 __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan), 2045 __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
2036 rq->polling); 2046 rq->polling);
@@ -2041,8 +2051,8 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
2041 if (lro) 2051 if (lro)
2042 napi_gro_receive(&qs->napi, skb); 2052 napi_gro_receive(&qs->napi, skb);
2043 else { 2053 else {
2044 if (unlikely(pi->iscsi_ipv4addr && is_arp(skb))) 2054 if (unlikely(pi->iscsic.flags))
2045 cxgb3_arp_process(adap, skb); 2055 cxgb3_process_iscsi_prov_pack(pi, skb);
2046 netif_receive_skb(skb); 2056 netif_receive_skb(skb);
2047 } 2057 }
2048 } else 2058 } else