162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
362306a36Sopenharmony_ci * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
462306a36Sopenharmony_ci * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This software is available to you under a choice of one of two
762306a36Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
862306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
962306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the
1062306a36Sopenharmony_ci * OpenIB.org BSD license below:
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
1362306a36Sopenharmony_ci *     without modification, are permitted provided that the following
1462306a36Sopenharmony_ci *     conditions are met:
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci *      - Redistributions of source code must retain the above
1762306a36Sopenharmony_ci *        copyright notice, this list of conditions and the following
1862306a36Sopenharmony_ci *        disclaimer.
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
2162306a36Sopenharmony_ci *        copyright notice, this list of conditions and the following
2262306a36Sopenharmony_ci *        disclaimer in the documentation and/or other materials
2362306a36Sopenharmony_ci *        provided with the distribution.
2462306a36Sopenharmony_ci *
2562306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2662306a36Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2762306a36Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2862306a36Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2962306a36Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3062306a36Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3162306a36Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3262306a36Sopenharmony_ci * SOFTWARE.
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#ifndef _IPOIB_H
3662306a36Sopenharmony_ci#define _IPOIB_H
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#include <linux/list.h>
3962306a36Sopenharmony_ci#include <linux/skbuff.h>
4062306a36Sopenharmony_ci#include <linux/netdevice.h>
4162306a36Sopenharmony_ci#include <linux/workqueue.h>
4262306a36Sopenharmony_ci#include <linux/kref.h>
4362306a36Sopenharmony_ci#include <linux/if_infiniband.h>
4462306a36Sopenharmony_ci#include <linux/mutex.h>
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci#include <net/neighbour.h>
4762306a36Sopenharmony_ci#include <net/sch_generic.h>
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci#include <linux/atomic.h>
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#include <rdma/ib_verbs.h>
5262306a36Sopenharmony_ci#include <rdma/ib_pack.h>
5362306a36Sopenharmony_ci#include <rdma/ib_sa.h>
5462306a36Sopenharmony_ci#include <linux/sched.h>
5562306a36Sopenharmony_ci/* constants */
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_cienum ipoib_flush_level {
5862306a36Sopenharmony_ci	IPOIB_FLUSH_LIGHT,
5962306a36Sopenharmony_ci	IPOIB_FLUSH_NORMAL,
6062306a36Sopenharmony_ci	IPOIB_FLUSH_HEAVY
6162306a36Sopenharmony_ci};
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cienum {
6462306a36Sopenharmony_ci	IPOIB_ENCAP_LEN		  = 4,
6562306a36Sopenharmony_ci	IPOIB_PSEUDO_LEN	  = 20,
6662306a36Sopenharmony_ci	IPOIB_HARD_LEN		  = IPOIB_ENCAP_LEN + IPOIB_PSEUDO_LEN,
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	IPOIB_UD_HEAD_SIZE	  = IB_GRH_BYTES + IPOIB_ENCAP_LEN,
6962306a36Sopenharmony_ci	IPOIB_UD_RX_SG		  = 2, /* max buffer needed for 4K mtu */
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	IPOIB_CM_MTU		  = 0x10000 - 0x10, /* padding to align header to 16 */
7262306a36Sopenharmony_ci	IPOIB_CM_BUF_SIZE	  = IPOIB_CM_MTU  + IPOIB_ENCAP_LEN,
7362306a36Sopenharmony_ci	IPOIB_CM_HEAD_SIZE	  = IPOIB_CM_BUF_SIZE % PAGE_SIZE,
7462306a36Sopenharmony_ci	IPOIB_CM_RX_SG		  = ALIGN(IPOIB_CM_BUF_SIZE, PAGE_SIZE) / PAGE_SIZE,
7562306a36Sopenharmony_ci	IPOIB_RX_RING_SIZE	  = 256,
7662306a36Sopenharmony_ci	IPOIB_TX_RING_SIZE	  = 128,
7762306a36Sopenharmony_ci	IPOIB_MAX_QUEUE_SIZE	  = 8192,
7862306a36Sopenharmony_ci	IPOIB_MIN_QUEUE_SIZE	  = 2,
7962306a36Sopenharmony_ci	IPOIB_CM_MAX_CONN_QP	  = 4096,
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	IPOIB_NUM_WC		  = 4,
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	IPOIB_MAX_PATH_REC_QUEUE  = 3,
8462306a36Sopenharmony_ci	IPOIB_MAX_MCAST_QUEUE	  = 64,
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	IPOIB_FLAG_OPER_UP	  = 0,
8762306a36Sopenharmony_ci	IPOIB_FLAG_INITIALIZED	  = 1,
8862306a36Sopenharmony_ci	IPOIB_FLAG_ADMIN_UP	  = 2,
8962306a36Sopenharmony_ci	IPOIB_PKEY_ASSIGNED	  = 3,
9062306a36Sopenharmony_ci	IPOIB_FLAG_SUBINTERFACE	  = 5,
9162306a36Sopenharmony_ci	IPOIB_STOP_REAPER	  = 7,
9262306a36Sopenharmony_ci	IPOIB_FLAG_ADMIN_CM	  = 9,
9362306a36Sopenharmony_ci	IPOIB_FLAG_UMCAST	  = 10,
9462306a36Sopenharmony_ci	IPOIB_NEIGH_TBL_FLUSH	  = 12,
9562306a36Sopenharmony_ci	IPOIB_FLAG_DEV_ADDR_SET	  = 13,
9662306a36Sopenharmony_ci	IPOIB_FLAG_DEV_ADDR_CTRL  = 14,
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	IPOIB_MAX_BACKOFF_SECONDS = 16,
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	IPOIB_MCAST_FLAG_FOUND	  = 0,	/* used in set_multicast_list */
10162306a36Sopenharmony_ci	IPOIB_MCAST_FLAG_SENDONLY = 1,
10262306a36Sopenharmony_ci	/*
10362306a36Sopenharmony_ci	 * For IPOIB_MCAST_FLAG_BUSY
10462306a36Sopenharmony_ci	 * When set, in flight join and mcast->mc is unreliable
10562306a36Sopenharmony_ci	 * When clear and mcast->mc IS_ERR_OR_NULL, need to restart or
10662306a36Sopenharmony_ci	 *   haven't started yet
10762306a36Sopenharmony_ci	 * When clear and mcast->mc is valid pointer, join was successful
10862306a36Sopenharmony_ci	 */
10962306a36Sopenharmony_ci	IPOIB_MCAST_FLAG_BUSY	  = 2,
11062306a36Sopenharmony_ci	IPOIB_MCAST_FLAG_ATTACHED = 3,
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	MAX_SEND_CQE		  = 64,
11362306a36Sopenharmony_ci	IPOIB_CM_COPYBREAK	  = 256,
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	IPOIB_NON_CHILD		  = 0,
11662306a36Sopenharmony_ci	IPOIB_LEGACY_CHILD	  = 1,
11762306a36Sopenharmony_ci	IPOIB_RTNL_CHILD	  = 2,
11862306a36Sopenharmony_ci};
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci#define	IPOIB_OP_RECV   (1ul << 31)
12162306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_IPOIB_CM
12262306a36Sopenharmony_ci#define	IPOIB_OP_CM     (1ul << 30)
12362306a36Sopenharmony_ci#else
12462306a36Sopenharmony_ci#define	IPOIB_OP_CM     (0)
12562306a36Sopenharmony_ci#endif
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci#define IPOIB_QPN_MASK ((__force u32) cpu_to_be32(0xFFFFFF))
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci/* structs */
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_cistruct ipoib_header {
13262306a36Sopenharmony_ci	__be16	proto;
13362306a36Sopenharmony_ci	u16	reserved;
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistruct ipoib_pseudo_header {
13762306a36Sopenharmony_ci	u8	hwaddr[INFINIBAND_ALEN];
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistatic inline void skb_add_pseudo_hdr(struct sk_buff *skb)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	char *data = skb_push(skb, IPOIB_PSEUDO_LEN);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	/*
14562306a36Sopenharmony_ci	 * only the ipoib header is present now, make room for a dummy
14662306a36Sopenharmony_ci	 * pseudo header and set skb field accordingly
14762306a36Sopenharmony_ci	 */
14862306a36Sopenharmony_ci	memset(data, 0, IPOIB_PSEUDO_LEN);
14962306a36Sopenharmony_ci	skb_reset_mac_header(skb);
15062306a36Sopenharmony_ci	skb_pull(skb, IPOIB_HARD_LEN);
15162306a36Sopenharmony_ci}
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_cistatic inline struct ipoib_dev_priv *ipoib_priv(const struct net_device *dev)
15462306a36Sopenharmony_ci{
15562306a36Sopenharmony_ci	struct rdma_netdev *rn = netdev_priv(dev);
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	return rn->clnt_priv;
15862306a36Sopenharmony_ci}
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci/* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
16162306a36Sopenharmony_cistruct ipoib_mcast {
16262306a36Sopenharmony_ci	struct ib_sa_mcmember_rec mcmember;
16362306a36Sopenharmony_ci	struct ib_sa_multicast	 *mc;
16462306a36Sopenharmony_ci	struct ipoib_ah		 *ah;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	struct rb_node    rb_node;
16762306a36Sopenharmony_ci	struct list_head  list;
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	unsigned long created;
17062306a36Sopenharmony_ci	unsigned long backoff;
17162306a36Sopenharmony_ci	unsigned long delay_until;
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	unsigned long flags;
17462306a36Sopenharmony_ci	unsigned char logcount;
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	struct list_head  neigh_list;
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci	struct sk_buff_head pkt_queue;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	struct net_device *dev;
18162306a36Sopenharmony_ci	struct completion done;
18262306a36Sopenharmony_ci};
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_cistruct ipoib_rx_buf {
18562306a36Sopenharmony_ci	struct sk_buff *skb;
18662306a36Sopenharmony_ci	u64		mapping[IPOIB_UD_RX_SG];
18762306a36Sopenharmony_ci};
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_cistruct ipoib_tx_buf {
19062306a36Sopenharmony_ci	struct sk_buff *skb;
19162306a36Sopenharmony_ci	u64		mapping[MAX_SKB_FRAGS + 1];
19262306a36Sopenharmony_ci};
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_cistruct ib_cm_id;
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_cistruct ipoib_cm_data {
19762306a36Sopenharmony_ci	__be32 qpn; /* High byte MUST be ignored on receive */
19862306a36Sopenharmony_ci	__be32 mtu;
19962306a36Sopenharmony_ci};
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci/*
20262306a36Sopenharmony_ci * Quoting 10.3.1 Queue Pair and EE Context States:
20362306a36Sopenharmony_ci *
20462306a36Sopenharmony_ci * Note, for QPs that are associated with an SRQ, the Consumer should take the
20562306a36Sopenharmony_ci * QP through the Error State before invoking a Destroy QP or a Modify QP to the
20662306a36Sopenharmony_ci * Reset State.  The Consumer may invoke the Destroy QP without first performing
20762306a36Sopenharmony_ci * a Modify QP to the Error State and waiting for the Affiliated Asynchronous
20862306a36Sopenharmony_ci * Last WQE Reached Event. However, if the Consumer does not wait for the
20962306a36Sopenharmony_ci * Affiliated Asynchronous Last WQE Reached Event, then WQE and Data Segment
21062306a36Sopenharmony_ci * leakage may occur. Therefore, it is good programming practice to tear down a
21162306a36Sopenharmony_ci * QP that is associated with an SRQ by using the following process:
21262306a36Sopenharmony_ci *
21362306a36Sopenharmony_ci * - Put the QP in the Error State
21462306a36Sopenharmony_ci * - Wait for the Affiliated Asynchronous Last WQE Reached Event;
21562306a36Sopenharmony_ci * - either:
21662306a36Sopenharmony_ci *       drain the CQ by invoking the Poll CQ verb and either wait for CQ
21762306a36Sopenharmony_ci *       to be empty or the number of Poll CQ operations has exceeded
21862306a36Sopenharmony_ci *       CQ capacity size;
21962306a36Sopenharmony_ci * - or
22062306a36Sopenharmony_ci *       post another WR that completes on the same CQ and wait for this
22162306a36Sopenharmony_ci *       WR to return as a WC;
22262306a36Sopenharmony_ci * - and then invoke a Destroy QP or Reset QP.
22362306a36Sopenharmony_ci *
22462306a36Sopenharmony_ci * We use the second option and wait for a completion on the
22562306a36Sopenharmony_ci * same CQ before destroying QPs attached to our SRQ.
22662306a36Sopenharmony_ci */
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_cienum ipoib_cm_state {
22962306a36Sopenharmony_ci	IPOIB_CM_RX_LIVE,
23062306a36Sopenharmony_ci	IPOIB_CM_RX_ERROR, /* Ignored by stale task */
23162306a36Sopenharmony_ci	IPOIB_CM_RX_FLUSH  /* Last WQE Reached event observed */
23262306a36Sopenharmony_ci};
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_cistruct ipoib_cm_rx {
23562306a36Sopenharmony_ci	struct ib_cm_id	       *id;
23662306a36Sopenharmony_ci	struct ib_qp	       *qp;
23762306a36Sopenharmony_ci	struct ipoib_cm_rx_buf *rx_ring;
23862306a36Sopenharmony_ci	struct list_head	list;
23962306a36Sopenharmony_ci	struct net_device      *dev;
24062306a36Sopenharmony_ci	unsigned long		jiffies;
24162306a36Sopenharmony_ci	enum ipoib_cm_state	state;
24262306a36Sopenharmony_ci	int			recv_count;
24362306a36Sopenharmony_ci};
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_cistruct ipoib_cm_tx {
24662306a36Sopenharmony_ci	struct ib_cm_id	    *id;
24762306a36Sopenharmony_ci	struct ib_qp	    *qp;
24862306a36Sopenharmony_ci	struct list_head     list;
24962306a36Sopenharmony_ci	struct net_device   *dev;
25062306a36Sopenharmony_ci	struct ipoib_neigh  *neigh;
25162306a36Sopenharmony_ci	struct ipoib_tx_buf *tx_ring;
25262306a36Sopenharmony_ci	unsigned int	     tx_head;
25362306a36Sopenharmony_ci	unsigned int	     tx_tail;
25462306a36Sopenharmony_ci	unsigned long	     flags;
25562306a36Sopenharmony_ci	u32		     mtu;
25662306a36Sopenharmony_ci	unsigned int         max_send_sge;
25762306a36Sopenharmony_ci};
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_cistruct ipoib_cm_rx_buf {
26062306a36Sopenharmony_ci	struct sk_buff *skb;
26162306a36Sopenharmony_ci	u64 mapping[IPOIB_CM_RX_SG];
26262306a36Sopenharmony_ci};
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_cistruct ipoib_cm_dev_priv {
26562306a36Sopenharmony_ci	struct ib_srq	       *srq;
26662306a36Sopenharmony_ci	struct ipoib_cm_rx_buf *srq_ring;
26762306a36Sopenharmony_ci	struct ib_cm_id	       *id;
26862306a36Sopenharmony_ci	struct list_head	passive_ids;   /* state: LIVE */
26962306a36Sopenharmony_ci	struct list_head	rx_error_list; /* state: ERROR */
27062306a36Sopenharmony_ci	struct list_head	rx_flush_list; /* state: FLUSH, drain not started */
27162306a36Sopenharmony_ci	struct list_head	rx_drain_list; /* state: FLUSH, drain started */
27262306a36Sopenharmony_ci	struct list_head	rx_reap_list;  /* state: FLUSH, drain done */
27362306a36Sopenharmony_ci	struct work_struct      start_task;
27462306a36Sopenharmony_ci	struct work_struct      reap_task;
27562306a36Sopenharmony_ci	struct work_struct      skb_task;
27662306a36Sopenharmony_ci	struct work_struct      rx_reap_task;
27762306a36Sopenharmony_ci	struct delayed_work     stale_task;
27862306a36Sopenharmony_ci	struct sk_buff_head     skb_queue;
27962306a36Sopenharmony_ci	struct list_head	start_list;
28062306a36Sopenharmony_ci	struct list_head	reap_list;
28162306a36Sopenharmony_ci	struct ib_wc		ibwc[IPOIB_NUM_WC];
28262306a36Sopenharmony_ci	struct ib_sge		rx_sge[IPOIB_CM_RX_SG];
28362306a36Sopenharmony_ci	struct ib_recv_wr       rx_wr;
28462306a36Sopenharmony_ci	int			nonsrq_conn_qp;
28562306a36Sopenharmony_ci	int			max_cm_mtu;
28662306a36Sopenharmony_ci	int			num_frags;
28762306a36Sopenharmony_ci};
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_cistruct ipoib_ethtool_st {
29062306a36Sopenharmony_ci	u16     coalesce_usecs;
29162306a36Sopenharmony_ci	u16     max_coalesced_frames;
29262306a36Sopenharmony_ci};
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_cistruct ipoib_neigh_table;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_cistruct ipoib_neigh_hash {
29762306a36Sopenharmony_ci	struct ipoib_neigh_table       *ntbl;
29862306a36Sopenharmony_ci	struct ipoib_neigh __rcu      **buckets;
29962306a36Sopenharmony_ci	struct rcu_head			rcu;
30062306a36Sopenharmony_ci	u32				mask;
30162306a36Sopenharmony_ci	u32				size;
30262306a36Sopenharmony_ci};
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_cistruct ipoib_neigh_table {
30562306a36Sopenharmony_ci	struct ipoib_neigh_hash __rcu  *htbl;
30662306a36Sopenharmony_ci	atomic_t			entries;
30762306a36Sopenharmony_ci	struct completion		flushed;
30862306a36Sopenharmony_ci	struct completion		deleted;
30962306a36Sopenharmony_ci};
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_cistruct ipoib_qp_state_validate {
31262306a36Sopenharmony_ci	struct work_struct work;
31362306a36Sopenharmony_ci	struct ipoib_dev_priv   *priv;
31462306a36Sopenharmony_ci};
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci/*
31762306a36Sopenharmony_ci * Device private locking: network stack tx_lock protects members used
31862306a36Sopenharmony_ci * in TX fast path, lock protects everything else.  lock nests inside
31962306a36Sopenharmony_ci * of tx_lock (ie tx_lock must be acquired first if needed).
32062306a36Sopenharmony_ci */
32162306a36Sopenharmony_cistruct ipoib_dev_priv {
32262306a36Sopenharmony_ci	spinlock_t lock;
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	struct net_device *dev;
32562306a36Sopenharmony_ci	void (*next_priv_destructor)(struct net_device *dev);
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	struct napi_struct send_napi;
32862306a36Sopenharmony_ci	struct napi_struct recv_napi;
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci	unsigned long flags;
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	/*
33362306a36Sopenharmony_ci	 * This protects access to the child_intfs list.
33462306a36Sopenharmony_ci	 * To READ from child_intfs the RTNL or vlan_rwsem read side must be
33562306a36Sopenharmony_ci	 * held.  To WRITE RTNL and the vlan_rwsem write side must be held (in
33662306a36Sopenharmony_ci	 * that order) This lock exists because we have a few contexts where
33762306a36Sopenharmony_ci	 * we need the child_intfs, but do not want to grab the RTNL.
33862306a36Sopenharmony_ci	 */
33962306a36Sopenharmony_ci	struct rw_semaphore vlan_rwsem;
34062306a36Sopenharmony_ci	struct mutex mcast_mutex;
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	struct rb_root  path_tree;
34362306a36Sopenharmony_ci	struct list_head path_list;
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	struct ipoib_neigh_table ntbl;
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	struct ipoib_mcast *broadcast;
34862306a36Sopenharmony_ci	struct list_head multicast_list;
34962306a36Sopenharmony_ci	struct rb_root multicast_tree;
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci	struct workqueue_struct *wq;
35262306a36Sopenharmony_ci	struct delayed_work mcast_task;
35362306a36Sopenharmony_ci	struct work_struct carrier_on_task;
35462306a36Sopenharmony_ci	struct work_struct flush_light;
35562306a36Sopenharmony_ci	struct work_struct flush_normal;
35662306a36Sopenharmony_ci	struct work_struct flush_heavy;
35762306a36Sopenharmony_ci	struct work_struct restart_task;
35862306a36Sopenharmony_ci	struct delayed_work ah_reap_task;
35962306a36Sopenharmony_ci	struct delayed_work neigh_reap_task;
36062306a36Sopenharmony_ci	struct ib_device *ca;
36162306a36Sopenharmony_ci	u8		  port;
36262306a36Sopenharmony_ci	u16		  pkey;
36362306a36Sopenharmony_ci	u16		  pkey_index;
36462306a36Sopenharmony_ci	struct ib_pd	 *pd;
36562306a36Sopenharmony_ci	struct ib_cq	 *recv_cq;
36662306a36Sopenharmony_ci	struct ib_cq	 *send_cq;
36762306a36Sopenharmony_ci	struct ib_qp	 *qp;
36862306a36Sopenharmony_ci	u32		  qkey;
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	union ib_gid local_gid;
37162306a36Sopenharmony_ci	u32	     local_lid;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	unsigned int admin_mtu;
37462306a36Sopenharmony_ci	unsigned int mcast_mtu;
37562306a36Sopenharmony_ci	unsigned int max_ib_mtu;
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	struct ipoib_rx_buf *rx_ring;
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci	struct ipoib_tx_buf *tx_ring;
38062306a36Sopenharmony_ci	/* cyclic ring variables for managing tx_ring, for UD only */
38162306a36Sopenharmony_ci	unsigned int	     tx_head;
38262306a36Sopenharmony_ci	unsigned int	     tx_tail;
38362306a36Sopenharmony_ci	/* cyclic ring variables for counting overall outstanding send WRs */
38462306a36Sopenharmony_ci	unsigned int	     global_tx_head;
38562306a36Sopenharmony_ci	unsigned int	     global_tx_tail;
38662306a36Sopenharmony_ci	struct ib_sge	     tx_sge[MAX_SKB_FRAGS + 1];
38762306a36Sopenharmony_ci	struct ib_ud_wr      tx_wr;
38862306a36Sopenharmony_ci	struct ib_wc	     send_wc[MAX_SEND_CQE];
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	struct ib_recv_wr    rx_wr;
39162306a36Sopenharmony_ci	struct ib_sge	     rx_sge[IPOIB_UD_RX_SG];
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	struct ib_wc ibwc[IPOIB_NUM_WC];
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	struct list_head dead_ahs;
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	struct ib_event_handler event_handler;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci	struct net_device *parent;
40062306a36Sopenharmony_ci	struct list_head child_intfs;
40162306a36Sopenharmony_ci	struct list_head list;
40262306a36Sopenharmony_ci	int    child_type;
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_IPOIB_CM
40562306a36Sopenharmony_ci	struct ipoib_cm_dev_priv cm;
40662306a36Sopenharmony_ci#endif
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
40962306a36Sopenharmony_ci	struct list_head fs_list;
41062306a36Sopenharmony_ci	struct dentry *mcg_dentry;
41162306a36Sopenharmony_ci	struct dentry *path_dentry;
41262306a36Sopenharmony_ci#endif
41362306a36Sopenharmony_ci	u64	hca_caps;
41462306a36Sopenharmony_ci	u64	kernel_caps;
41562306a36Sopenharmony_ci	struct ipoib_ethtool_st ethtool;
41662306a36Sopenharmony_ci	unsigned int max_send_sge;
41762306a36Sopenharmony_ci	const struct net_device_ops	*rn_ops;
41862306a36Sopenharmony_ci};
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_cistruct ipoib_ah {
42162306a36Sopenharmony_ci	struct net_device *dev;
42262306a36Sopenharmony_ci	struct ib_ah	  *ah;
42362306a36Sopenharmony_ci	struct list_head   list;
42462306a36Sopenharmony_ci	struct kref	   ref;
42562306a36Sopenharmony_ci	unsigned int	   last_send;
42662306a36Sopenharmony_ci	int  		   valid;
42762306a36Sopenharmony_ci};
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_cistruct ipoib_path {
43062306a36Sopenharmony_ci	struct net_device    *dev;
43162306a36Sopenharmony_ci	struct sa_path_rec pathrec;
43262306a36Sopenharmony_ci	struct ipoib_ah      *ah;
43362306a36Sopenharmony_ci	struct sk_buff_head   queue;
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci	struct list_head      neigh_list;
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci	int		      query_id;
43862306a36Sopenharmony_ci	struct ib_sa_query   *query;
43962306a36Sopenharmony_ci	struct completion     done;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	struct rb_node	      rb_node;
44262306a36Sopenharmony_ci	struct list_head      list;
44362306a36Sopenharmony_ci};
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_cistruct ipoib_neigh {
44662306a36Sopenharmony_ci	struct ipoib_ah    *ah;
44762306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_IPOIB_CM
44862306a36Sopenharmony_ci	struct ipoib_cm_tx *cm;
44962306a36Sopenharmony_ci#endif
45062306a36Sopenharmony_ci	u8     daddr[INFINIBAND_ALEN];
45162306a36Sopenharmony_ci	struct sk_buff_head queue;
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci	struct net_device *dev;
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	struct list_head    list;
45662306a36Sopenharmony_ci	struct ipoib_neigh __rcu *hnext;
45762306a36Sopenharmony_ci	struct rcu_head     rcu;
45862306a36Sopenharmony_ci	refcount_t	    refcnt;
45962306a36Sopenharmony_ci	unsigned long       alive;
46062306a36Sopenharmony_ci};
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci#define IPOIB_UD_MTU(ib_mtu)		(ib_mtu - IPOIB_ENCAP_LEN)
46362306a36Sopenharmony_ci#define IPOIB_UD_BUF_SIZE(ib_mtu)	(ib_mtu + IB_GRH_BYTES)
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_civoid ipoib_neigh_dtor(struct ipoib_neigh *neigh);
46662306a36Sopenharmony_cistatic inline void ipoib_neigh_put(struct ipoib_neigh *neigh)
46762306a36Sopenharmony_ci{
46862306a36Sopenharmony_ci	if (refcount_dec_and_test(&neigh->refcnt))
46962306a36Sopenharmony_ci		ipoib_neigh_dtor(neigh);
47062306a36Sopenharmony_ci}
47162306a36Sopenharmony_cistruct ipoib_neigh *ipoib_neigh_get(struct net_device *dev, u8 *daddr);
47262306a36Sopenharmony_cistruct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr,
47362306a36Sopenharmony_ci				      struct net_device *dev);
47462306a36Sopenharmony_civoid ipoib_neigh_free(struct ipoib_neigh *neigh);
47562306a36Sopenharmony_civoid ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid);
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ciextern struct workqueue_struct *ipoib_workqueue;
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci/* functions */
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ciint ipoib_rx_poll(struct napi_struct *napi, int budget);
48262306a36Sopenharmony_ciint ipoib_tx_poll(struct napi_struct *napi, int budget);
48362306a36Sopenharmony_civoid ipoib_ib_rx_completion(struct ib_cq *cq, void *ctx_ptr);
48462306a36Sopenharmony_civoid ipoib_ib_tx_completion(struct ib_cq *cq, void *ctx_ptr);
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_cistruct ipoib_ah *ipoib_create_ah(struct net_device *dev,
48762306a36Sopenharmony_ci				 struct ib_pd *pd, struct rdma_ah_attr *attr);
48862306a36Sopenharmony_civoid ipoib_free_ah(struct kref *kref);
48962306a36Sopenharmony_cistatic inline void ipoib_put_ah(struct ipoib_ah *ah)
49062306a36Sopenharmony_ci{
49162306a36Sopenharmony_ci	kref_put(&ah->ref, ipoib_free_ah);
49262306a36Sopenharmony_ci}
49362306a36Sopenharmony_ciint ipoib_open(struct net_device *dev);
49462306a36Sopenharmony_civoid ipoib_intf_free(struct net_device *dev);
49562306a36Sopenharmony_ciint ipoib_add_pkey_attr(struct net_device *dev);
49662306a36Sopenharmony_ciint ipoib_add_umcast_attr(struct net_device *dev);
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ciint ipoib_send(struct net_device *dev, struct sk_buff *skb,
49962306a36Sopenharmony_ci	       struct ib_ah *address, u32 dqpn);
50062306a36Sopenharmony_civoid ipoib_reap_ah(struct work_struct *work);
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_cistruct ipoib_path *__path_find(struct net_device *dev, void *gid);
50362306a36Sopenharmony_civoid ipoib_mark_paths_invalid(struct net_device *dev);
50462306a36Sopenharmony_civoid ipoib_flush_paths(struct net_device *dev);
50562306a36Sopenharmony_cistruct net_device *ipoib_intf_alloc(struct ib_device *hca, u32 port,
50662306a36Sopenharmony_ci				    const char *format);
50762306a36Sopenharmony_ciint ipoib_intf_init(struct ib_device *hca, u32 port, const char *format,
50862306a36Sopenharmony_ci		    struct net_device *dev);
50962306a36Sopenharmony_civoid ipoib_ib_tx_timer_func(struct timer_list *t);
51062306a36Sopenharmony_civoid ipoib_ib_dev_flush_light(struct work_struct *work);
51162306a36Sopenharmony_civoid ipoib_ib_dev_flush_normal(struct work_struct *work);
51262306a36Sopenharmony_civoid ipoib_ib_dev_flush_heavy(struct work_struct *work);
51362306a36Sopenharmony_civoid ipoib_pkey_event(struct work_struct *work);
51462306a36Sopenharmony_civoid ipoib_ib_dev_cleanup(struct net_device *dev);
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ciint ipoib_ib_dev_open_default(struct net_device *dev);
51762306a36Sopenharmony_ciint ipoib_ib_dev_open(struct net_device *dev);
51862306a36Sopenharmony_civoid ipoib_ib_dev_stop(struct net_device *dev);
51962306a36Sopenharmony_civoid ipoib_ib_dev_up(struct net_device *dev);
52062306a36Sopenharmony_civoid ipoib_ib_dev_down(struct net_device *dev);
52162306a36Sopenharmony_ciint ipoib_ib_dev_stop_default(struct net_device *dev);
52262306a36Sopenharmony_civoid ipoib_pkey_dev_check_presence(struct net_device *dev);
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_civoid ipoib_mcast_join_task(struct work_struct *work);
52562306a36Sopenharmony_civoid ipoib_mcast_carrier_on_task(struct work_struct *work);
52662306a36Sopenharmony_civoid ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb);
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_civoid ipoib_mcast_restart_task(struct work_struct *work);
52962306a36Sopenharmony_civoid ipoib_mcast_start_thread(struct net_device *dev);
53062306a36Sopenharmony_civoid ipoib_mcast_stop_thread(struct net_device *dev);
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_civoid ipoib_mcast_dev_down(struct net_device *dev);
53362306a36Sopenharmony_civoid ipoib_mcast_dev_flush(struct net_device *dev);
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ciint ipoib_dma_map_tx(struct ib_device *ca, struct ipoib_tx_buf *tx_req);
53662306a36Sopenharmony_civoid ipoib_dma_unmap_tx(struct ipoib_dev_priv *priv,
53762306a36Sopenharmony_ci			struct ipoib_tx_buf *tx_req);
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_cistruct rtnl_link_ops *ipoib_get_link_ops(void);
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_cistatic inline void ipoib_build_sge(struct ipoib_dev_priv *priv,
54262306a36Sopenharmony_ci				   struct ipoib_tx_buf *tx_req)
54362306a36Sopenharmony_ci{
54462306a36Sopenharmony_ci	int i, off;
54562306a36Sopenharmony_ci	struct sk_buff *skb = tx_req->skb;
54662306a36Sopenharmony_ci	skb_frag_t *frags = skb_shinfo(skb)->frags;
54762306a36Sopenharmony_ci	int nr_frags = skb_shinfo(skb)->nr_frags;
54862306a36Sopenharmony_ci	u64 *mapping = tx_req->mapping;
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci	if (skb_headlen(skb)) {
55162306a36Sopenharmony_ci		priv->tx_sge[0].addr         = mapping[0];
55262306a36Sopenharmony_ci		priv->tx_sge[0].length       = skb_headlen(skb);
55362306a36Sopenharmony_ci		off = 1;
55462306a36Sopenharmony_ci	} else
55562306a36Sopenharmony_ci		off = 0;
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	for (i = 0; i < nr_frags; ++i) {
55862306a36Sopenharmony_ci		priv->tx_sge[i + off].addr = mapping[i + off];
55962306a36Sopenharmony_ci		priv->tx_sge[i + off].length = skb_frag_size(&frags[i]);
56062306a36Sopenharmony_ci	}
56162306a36Sopenharmony_ci	priv->tx_wr.wr.num_sge	     = nr_frags + off;
56262306a36Sopenharmony_ci}
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
56562306a36Sopenharmony_cistruct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
56662306a36Sopenharmony_ciint ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
56762306a36Sopenharmony_civoid ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
56862306a36Sopenharmony_ci				  union ib_gid *gid,
56962306a36Sopenharmony_ci				  unsigned long *created,
57062306a36Sopenharmony_ci				  unsigned int *queuelen,
57162306a36Sopenharmony_ci				  unsigned int *complete,
57262306a36Sopenharmony_ci				  unsigned int *send_only);
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_cistruct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev);
57562306a36Sopenharmony_ciint ipoib_path_iter_next(struct ipoib_path_iter *iter);
57662306a36Sopenharmony_civoid ipoib_path_iter_read(struct ipoib_path_iter *iter,
57762306a36Sopenharmony_ci			  struct ipoib_path *path);
57862306a36Sopenharmony_ci#endif
57962306a36Sopenharmony_ci
58062306a36Sopenharmony_ciint ipoib_mcast_attach(struct net_device *dev, struct ib_device *hca,
58162306a36Sopenharmony_ci		       union ib_gid *mgid, u16 mlid, int set_qkey, u32 qkey);
58262306a36Sopenharmony_ciint ipoib_mcast_detach(struct net_device *dev, struct ib_device *hca,
58362306a36Sopenharmony_ci		       union ib_gid *mgid, u16 mlid);
58462306a36Sopenharmony_civoid ipoib_mcast_remove_list(struct list_head *remove_list);
58562306a36Sopenharmony_civoid ipoib_check_and_add_mcast_sendonly(struct ipoib_dev_priv *priv, u8 *mgid,
58662306a36Sopenharmony_ci				struct list_head *remove_list);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ciint ipoib_init_qp(struct net_device *dev);
58962306a36Sopenharmony_ciint ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca);
59062306a36Sopenharmony_civoid ipoib_transport_dev_cleanup(struct net_device *dev);
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_civoid ipoib_event(struct ib_event_handler *handler,
59362306a36Sopenharmony_ci		 struct ib_event *record);
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ciint ipoib_vlan_add(struct net_device *pdev, unsigned short pkey);
59662306a36Sopenharmony_ciint ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey);
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ciint __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
59962306a36Sopenharmony_ci		     u16 pkey, int child_type);
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ciint  __init ipoib_netlink_init(void);
60262306a36Sopenharmony_civoid __exit ipoib_netlink_fini(void);
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_civoid ipoib_set_umcast(struct net_device *ndev, int umcast_val);
60562306a36Sopenharmony_ciint  ipoib_set_mode(struct net_device *dev, const char *buf);
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_civoid ipoib_setup_common(struct net_device *dev);
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_civoid ipoib_pkey_open(struct ipoib_dev_priv *priv);
61062306a36Sopenharmony_civoid ipoib_drain_cq(struct net_device *dev);
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_civoid ipoib_set_ethtool_ops(struct net_device *dev);
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci#define IPOIB_FLAGS_RC		0x80
61562306a36Sopenharmony_ci#define IPOIB_FLAGS_UC		0x40
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci/* We don't support UC connections at the moment */
61862306a36Sopenharmony_ci#define IPOIB_CM_SUPPORTED(ha)   (ha[0] & (IPOIB_FLAGS_RC))
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_IPOIB_CM
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ciextern int ipoib_max_conn_qp;
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_cistatic inline int ipoib_cm_admin_enabled(struct net_device *dev)
62562306a36Sopenharmony_ci{
62662306a36Sopenharmony_ci	struct ipoib_dev_priv *priv = ipoib_priv(dev);
62762306a36Sopenharmony_ci	return IPOIB_CM_SUPPORTED(dev->dev_addr) &&
62862306a36Sopenharmony_ci		test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
62962306a36Sopenharmony_ci}
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_cistatic inline int ipoib_cm_enabled(struct net_device *dev, u8 *hwaddr)
63262306a36Sopenharmony_ci{
63362306a36Sopenharmony_ci	struct ipoib_dev_priv *priv = ipoib_priv(dev);
63462306a36Sopenharmony_ci	return IPOIB_CM_SUPPORTED(hwaddr) &&
63562306a36Sopenharmony_ci		test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
63662306a36Sopenharmony_ci}
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_cistatic inline int ipoib_cm_up(struct ipoib_neigh *neigh)
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci{
64162306a36Sopenharmony_ci	return test_bit(IPOIB_FLAG_OPER_UP, &neigh->cm->flags);
64262306a36Sopenharmony_ci}
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_cistatic inline struct ipoib_cm_tx *ipoib_cm_get(struct ipoib_neigh *neigh)
64562306a36Sopenharmony_ci{
64662306a36Sopenharmony_ci	return neigh->cm;
64762306a36Sopenharmony_ci}
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_cistatic inline void ipoib_cm_set(struct ipoib_neigh *neigh, struct ipoib_cm_tx *tx)
65062306a36Sopenharmony_ci{
65162306a36Sopenharmony_ci	neigh->cm = tx;
65262306a36Sopenharmony_ci}
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_cistatic inline int ipoib_cm_has_srq(struct net_device *dev)
65562306a36Sopenharmony_ci{
65662306a36Sopenharmony_ci	struct ipoib_dev_priv *priv = ipoib_priv(dev);
65762306a36Sopenharmony_ci	return !!priv->cm.srq;
65862306a36Sopenharmony_ci}
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_cistatic inline unsigned int ipoib_cm_max_mtu(struct net_device *dev)
66162306a36Sopenharmony_ci{
66262306a36Sopenharmony_ci	struct ipoib_dev_priv *priv = ipoib_priv(dev);
66362306a36Sopenharmony_ci	return priv->cm.max_cm_mtu;
66462306a36Sopenharmony_ci}
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_civoid ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx);
66762306a36Sopenharmony_ciint ipoib_cm_dev_open(struct net_device *dev);
66862306a36Sopenharmony_civoid ipoib_cm_dev_stop(struct net_device *dev);
66962306a36Sopenharmony_ciint ipoib_cm_dev_init(struct net_device *dev);
67062306a36Sopenharmony_ciint ipoib_cm_add_mode_attr(struct net_device *dev);
67162306a36Sopenharmony_civoid ipoib_cm_dev_cleanup(struct net_device *dev);
67262306a36Sopenharmony_cistruct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
67362306a36Sopenharmony_ci				    struct ipoib_neigh *neigh);
67462306a36Sopenharmony_civoid ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx);
67562306a36Sopenharmony_civoid ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
67662306a36Sopenharmony_ci			   unsigned int mtu);
67762306a36Sopenharmony_civoid ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc);
67862306a36Sopenharmony_civoid ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc);
67962306a36Sopenharmony_ci#else
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_ci#define ipoib_max_conn_qp 0
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_cistatic inline int ipoib_cm_admin_enabled(struct net_device *dev)
68462306a36Sopenharmony_ci{
68562306a36Sopenharmony_ci	return 0;
68662306a36Sopenharmony_ci}
68762306a36Sopenharmony_cistatic inline int ipoib_cm_enabled(struct net_device *dev, u8 *hwaddr)
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_ci{
69062306a36Sopenharmony_ci	return 0;
69162306a36Sopenharmony_ci}
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_cistatic inline int ipoib_cm_up(struct ipoib_neigh *neigh)
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci{
69662306a36Sopenharmony_ci	return 0;
69762306a36Sopenharmony_ci}
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_cistatic inline struct ipoib_cm_tx *ipoib_cm_get(struct ipoib_neigh *neigh)
70062306a36Sopenharmony_ci{
70162306a36Sopenharmony_ci	return NULL;
70262306a36Sopenharmony_ci}
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_cistatic inline void ipoib_cm_set(struct ipoib_neigh *neigh, struct ipoib_cm_tx *tx)
70562306a36Sopenharmony_ci{
70662306a36Sopenharmony_ci}
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_cistatic inline int ipoib_cm_has_srq(struct net_device *dev)
70962306a36Sopenharmony_ci{
71062306a36Sopenharmony_ci	return 0;
71162306a36Sopenharmony_ci}
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_cistatic inline unsigned int ipoib_cm_max_mtu(struct net_device *dev)
71462306a36Sopenharmony_ci{
71562306a36Sopenharmony_ci	return 0;
71662306a36Sopenharmony_ci}
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_cistatic inline
71962306a36Sopenharmony_civoid ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx)
72062306a36Sopenharmony_ci{
72162306a36Sopenharmony_ci	return;
72262306a36Sopenharmony_ci}
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_cistatic inline
72562306a36Sopenharmony_ciint ipoib_cm_dev_open(struct net_device *dev)
72662306a36Sopenharmony_ci{
72762306a36Sopenharmony_ci	return 0;
72862306a36Sopenharmony_ci}
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_cistatic inline
73162306a36Sopenharmony_civoid ipoib_cm_dev_stop(struct net_device *dev)
73262306a36Sopenharmony_ci{
73362306a36Sopenharmony_ci	return;
73462306a36Sopenharmony_ci}
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_cistatic inline
73762306a36Sopenharmony_ciint ipoib_cm_dev_init(struct net_device *dev)
73862306a36Sopenharmony_ci{
73962306a36Sopenharmony_ci	return -EOPNOTSUPP;
74062306a36Sopenharmony_ci}
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_cistatic inline
74362306a36Sopenharmony_civoid ipoib_cm_dev_cleanup(struct net_device *dev)
74462306a36Sopenharmony_ci{
74562306a36Sopenharmony_ci	return;
74662306a36Sopenharmony_ci}
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_cistatic inline
74962306a36Sopenharmony_cistruct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
75062306a36Sopenharmony_ci				    struct ipoib_neigh *neigh)
75162306a36Sopenharmony_ci{
75262306a36Sopenharmony_ci	return NULL;
75362306a36Sopenharmony_ci}
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_cistatic inline
75662306a36Sopenharmony_civoid ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx)
75762306a36Sopenharmony_ci{
75862306a36Sopenharmony_ci	return;
75962306a36Sopenharmony_ci}
76062306a36Sopenharmony_ci
76162306a36Sopenharmony_cistatic inline
76262306a36Sopenharmony_ciint ipoib_cm_add_mode_attr(struct net_device *dev)
76362306a36Sopenharmony_ci{
76462306a36Sopenharmony_ci	return 0;
76562306a36Sopenharmony_ci}
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_cistatic inline void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
76862306a36Sopenharmony_ci					 unsigned int mtu)
76962306a36Sopenharmony_ci{
77062306a36Sopenharmony_ci	dev_kfree_skb_any(skb);
77162306a36Sopenharmony_ci}
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_cistatic inline void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
77462306a36Sopenharmony_ci{
77562306a36Sopenharmony_ci}
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_cistatic inline void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
77862306a36Sopenharmony_ci{
77962306a36Sopenharmony_ci}
78062306a36Sopenharmony_ci#endif
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
78362306a36Sopenharmony_civoid ipoib_create_debug_files(struct net_device *dev);
78462306a36Sopenharmony_civoid ipoib_delete_debug_files(struct net_device *dev);
78562306a36Sopenharmony_civoid ipoib_register_debugfs(void);
78662306a36Sopenharmony_civoid ipoib_unregister_debugfs(void);
78762306a36Sopenharmony_ci#else
78862306a36Sopenharmony_cistatic inline void ipoib_create_debug_files(struct net_device *dev) { }
78962306a36Sopenharmony_cistatic inline void ipoib_delete_debug_files(struct net_device *dev) { }
79062306a36Sopenharmony_cistatic inline void ipoib_register_debugfs(void) { }
79162306a36Sopenharmony_cistatic inline void ipoib_unregister_debugfs(void) { }
79262306a36Sopenharmony_ci#endif
79362306a36Sopenharmony_ci
79462306a36Sopenharmony_ci#define ipoib_printk(level, priv, format, arg...)	\
79562306a36Sopenharmony_ci	printk(level "%s: " format, ((struct ipoib_dev_priv *) priv)->dev->name , ## arg)
79662306a36Sopenharmony_ci#define ipoib_warn(priv, format, arg...)		\
79762306a36Sopenharmony_cido {							\
79862306a36Sopenharmony_ci	static DEFINE_RATELIMIT_STATE(_rs,		\
79962306a36Sopenharmony_ci		10 * HZ /*10 seconds */,		\
80062306a36Sopenharmony_ci		100);		\
80162306a36Sopenharmony_ci	if (__ratelimit(&_rs))				\
80262306a36Sopenharmony_ci		ipoib_printk(KERN_WARNING, priv, format , ## arg);\
80362306a36Sopenharmony_ci} while (0)
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ciextern int ipoib_sendq_size;
80662306a36Sopenharmony_ciextern int ipoib_recvq_size;
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_ciextern struct ib_sa_client ipoib_sa_client;
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
81162306a36Sopenharmony_ciextern int ipoib_debug_level;
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_ci#define ipoib_dbg(priv, format, arg...)			\
81462306a36Sopenharmony_ci	do {						\
81562306a36Sopenharmony_ci		if (ipoib_debug_level > 0)			\
81662306a36Sopenharmony_ci			ipoib_printk(KERN_DEBUG, priv, format , ## arg); \
81762306a36Sopenharmony_ci	} while (0)
81862306a36Sopenharmony_ci#define ipoib_dbg_mcast(priv, format, arg...)		\
81962306a36Sopenharmony_ci	do {						\
82062306a36Sopenharmony_ci		if (mcast_debug_level > 0)		\
82162306a36Sopenharmony_ci			ipoib_printk(KERN_DEBUG, priv, format , ## arg); \
82262306a36Sopenharmony_ci	} while (0)
82362306a36Sopenharmony_ci#else /* CONFIG_INFINIBAND_IPOIB_DEBUG */
82462306a36Sopenharmony_ci#define ipoib_dbg(priv, format, arg...)			\
82562306a36Sopenharmony_ci	do { (void) (priv); } while (0)
82662306a36Sopenharmony_ci#define ipoib_dbg_mcast(priv, format, arg...)		\
82762306a36Sopenharmony_ci	do { (void) (priv); } while (0)
82862306a36Sopenharmony_ci#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA
83162306a36Sopenharmony_ci#define ipoib_dbg_data(priv, format, arg...)		\
83262306a36Sopenharmony_ci	do {						\
83362306a36Sopenharmony_ci		if (data_debug_level > 0)		\
83462306a36Sopenharmony_ci			ipoib_printk(KERN_DEBUG, priv, format , ## arg); \
83562306a36Sopenharmony_ci	} while (0)
83662306a36Sopenharmony_ci#else /* CONFIG_INFINIBAND_IPOIB_DEBUG_DATA */
83762306a36Sopenharmony_ci#define ipoib_dbg_data(priv, format, arg...)		\
83862306a36Sopenharmony_ci	do { (void) (priv); } while (0)
83962306a36Sopenharmony_ci#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG_DATA */
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci#define IPOIB_QPN(ha) (be32_to_cpup((__be32 *) ha) & 0xffffff)
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_ci#endif /* _IPOIB_H */
844