diff options
author | Scott Feldman <scofeldm@cisco.com> | 2009-09-03 13:02:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-03 23:19:19 -0400 |
commit | 6ba9cdc09678d6925c205ef0b0bd374e31589ecf (patch) | |
tree | cff6128e997b6945d77ad47dab3a23bc8de8a56a /drivers/net/enic | |
parent | 350991e12ac1ac407850169a0d65f522a7fd029e (diff) |
enic: provision for multiple Rx/Tx queues; prepare for RSS support
Provision for multiple Rx/Tx queues. Max of 8 WQs and 8 RQs. Max for
completion queue is 8+8=16 and max for interrupt resources is 8+8+2.
Add driver/firmware interface for setting up RSS secret key and indirection
table.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/enic')
-rw-r--r-- | drivers/net/enic/enic.h | 16 | ||||
-rw-r--r-- | drivers/net/enic/enic_main.c | 6 | ||||
-rw-r--r-- | drivers/net/enic/enic_res.c | 33 | ||||
-rw-r--r-- | drivers/net/enic/enic_res.h | 2 | ||||
-rw-r--r-- | drivers/net/enic/vnic_nic.h | 7 |
5 files changed, 50 insertions, 14 deletions
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index f7c5b334bc79..e1c2076228ba 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "vnic_cq.h" | 29 | #include "vnic_cq.h" |
30 | #include "vnic_intr.h" | 30 | #include "vnic_intr.h" |
31 | #include "vnic_stats.h" | 31 | #include "vnic_stats.h" |
32 | #include "vnic_nic.h" | ||
32 | #include "vnic_rss.h" | 33 | #include "vnic_rss.h" |
33 | 34 | ||
34 | #define DRV_NAME "enic" | 35 | #define DRV_NAME "enic" |
@@ -42,17 +43,20 @@ | |||
42 | 43 | ||
43 | #define ENIC_BARS_MAX 6 | 44 | #define ENIC_BARS_MAX 6 |
44 | 45 | ||
46 | #define ENIC_WQ_MAX 8 | ||
47 | #define ENIC_RQ_MAX 8 | ||
48 | #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) | ||
49 | #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) | ||
50 | |||
45 | enum enic_cq_index { | 51 | enum enic_cq_index { |
46 | ENIC_CQ_RQ, | 52 | ENIC_CQ_RQ, |
47 | ENIC_CQ_WQ, | 53 | ENIC_CQ_WQ, |
48 | ENIC_CQ_MAX, | ||
49 | }; | 54 | }; |
50 | 55 | ||
51 | enum enic_intx_intr_index { | 56 | enum enic_intx_intr_index { |
52 | ENIC_INTX_WQ_RQ, | 57 | ENIC_INTX_WQ_RQ, |
53 | ENIC_INTX_ERR, | 58 | ENIC_INTX_ERR, |
54 | ENIC_INTX_NOTIFY, | 59 | ENIC_INTX_NOTIFY, |
55 | ENIC_INTX_MAX, | ||
56 | }; | 60 | }; |
57 | 61 | ||
58 | enum enic_msix_intr_index { | 62 | enum enic_msix_intr_index { |
@@ -90,13 +94,13 @@ struct enic { | |||
90 | u32 port_mtu; | 94 | u32 port_mtu; |
91 | 95 | ||
92 | /* work queue cache line section */ | 96 | /* work queue cache line section */ |
93 | ____cacheline_aligned struct vnic_wq wq[1]; | 97 | ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX]; |
94 | spinlock_t wq_lock[1]; | 98 | spinlock_t wq_lock[ENIC_WQ_MAX]; |
95 | unsigned int wq_count; | 99 | unsigned int wq_count; |
96 | struct vlan_group *vlan_group; | 100 | struct vlan_group *vlan_group; |
97 | 101 | ||
98 | /* receive queue cache line section */ | 102 | /* receive queue cache line section */ |
99 | ____cacheline_aligned struct vnic_rq rq[1]; | 103 | ____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX]; |
100 | unsigned int rq_count; | 104 | unsigned int rq_count; |
101 | int (*rq_alloc_buf)(struct vnic_rq *rq); | 105 | int (*rq_alloc_buf)(struct vnic_rq *rq); |
102 | u64 rq_truncated_pkts; | 106 | u64 rq_truncated_pkts; |
@@ -106,7 +110,7 @@ struct enic { | |||
106 | struct net_lro_desc lro_desc[ENIC_LRO_MAX_DESC]; | 110 | struct net_lro_desc lro_desc[ENIC_LRO_MAX_DESC]; |
107 | 111 | ||
108 | /* interrupt resource cache line section */ | 112 | /* interrupt resource cache line section */ |
109 | ____cacheline_aligned struct vnic_intr intr[ENIC_MSIX_MAX]; | 113 | ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; |
110 | unsigned int intr_count; | 114 | unsigned int intr_count; |
111 | u32 __iomem *legacy_pba; /* memory-mapped */ | 115 | u32 __iomem *legacy_pba; /* memory-mapped */ |
112 | 116 | ||
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index b265b103c210..e01067e727b2 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
@@ -1586,7 +1586,7 @@ static int enic_set_niccfg(struct enic *enic) | |||
1586 | const u8 ig_vlan_strip_en = 1; | 1586 | const u8 ig_vlan_strip_en = 1; |
1587 | 1587 | ||
1588 | /* Enable VLAN tag stripping. RSS not enabled (yet). | 1588 | /* Enable VLAN tag stripping. RSS not enabled (yet). |
1589 | */ | 1589 | */ |
1590 | 1590 | ||
1591 | return enic_set_nic_cfg(enic, | 1591 | return enic_set_nic_cfg(enic, |
1592 | rss_default_cpu, rss_hash_type, | 1592 | rss_default_cpu, rss_hash_type, |
@@ -1621,8 +1621,8 @@ static void enic_reset(struct work_struct *work) | |||
1621 | 1621 | ||
1622 | static int enic_set_intr_mode(struct enic *enic) | 1622 | static int enic_set_intr_mode(struct enic *enic) |
1623 | { | 1623 | { |
1624 | unsigned int n = ARRAY_SIZE(enic->rq); | 1624 | unsigned int n = 1; |
1625 | unsigned int m = ARRAY_SIZE(enic->wq); | 1625 | unsigned int m = 1; |
1626 | unsigned int i; | 1626 | unsigned int i; |
1627 | 1627 | ||
1628 | /* Set interrupt mode (INTx, MSI, MSI-X) depending | 1628 | /* Set interrupt mode (INTx, MSI, MSI-X) depending |
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index e5fc9384f8f5..32111144efc9 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c | |||
@@ -156,6 +156,22 @@ int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, | |||
156 | return vnic_dev_cmd(enic->vdev, CMD_NIC_CFG, &a0, &a1, wait); | 156 | return vnic_dev_cmd(enic->vdev, CMD_NIC_CFG, &a0, &a1, wait); |
157 | } | 157 | } |
158 | 158 | ||
159 | int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len) | ||
160 | { | ||
161 | u64 a0 = (u64)key_pa, a1 = len; | ||
162 | int wait = 1000; | ||
163 | |||
164 | return vnic_dev_cmd(enic->vdev, CMD_RSS_KEY, &a0, &a1, wait); | ||
165 | } | ||
166 | |||
167 | int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len) | ||
168 | { | ||
169 | u64 a0 = (u64)cpu_pa, a1 = len; | ||
170 | int wait = 1000; | ||
171 | |||
172 | return vnic_dev_cmd(enic->vdev, CMD_RSS_CPU, &a0, &a1, wait); | ||
173 | } | ||
174 | |||
159 | void enic_free_vnic_resources(struct enic *enic) | 175 | void enic_free_vnic_resources(struct enic *enic) |
160 | { | 176 | { |
161 | unsigned int i; | 177 | unsigned int i; |
@@ -172,11 +188,18 @@ void enic_free_vnic_resources(struct enic *enic) | |||
172 | 188 | ||
173 | void enic_get_res_counts(struct enic *enic) | 189 | void enic_get_res_counts(struct enic *enic) |
174 | { | 190 | { |
175 | enic->wq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ); | 191 | enic->wq_count = min_t(int, |
176 | enic->rq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ); | 192 | vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ), |
177 | enic->cq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ); | 193 | ENIC_WQ_MAX); |
178 | enic->intr_count = vnic_dev_get_res_count(enic->vdev, | 194 | enic->rq_count = min_t(int, |
179 | RES_TYPE_INTR_CTRL); | 195 | vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ), |
196 | ENIC_RQ_MAX); | ||
197 | enic->cq_count = min_t(int, | ||
198 | vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ), | ||
199 | ENIC_CQ_MAX); | ||
200 | enic->intr_count = min_t(int, | ||
201 | vnic_dev_get_res_count(enic->vdev, RES_TYPE_INTR_CTRL), | ||
202 | ENIC_INTR_MAX); | ||
180 | 203 | ||
181 | printk(KERN_INFO PFX "vNIC resources avail: " | 204 | printk(KERN_INFO PFX "vNIC resources avail: " |
182 | "wq %d rq %d cq %d intr %d\n", | 205 | "wq %d rq %d cq %d intr %d\n", |
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h index 7bf272fa859b..abc19741ab02 100644 --- a/drivers/net/enic/enic_res.h +++ b/drivers/net/enic/enic_res.h | |||
@@ -139,6 +139,8 @@ void enic_del_vlan(struct enic *enic, u16 vlanid); | |||
139 | int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, | 139 | int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, |
140 | u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en, | 140 | u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en, |
141 | u8 ig_vlan_strip_en); | 141 | u8 ig_vlan_strip_en); |
142 | int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len); | ||
143 | int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len); | ||
142 | void enic_get_res_counts(struct enic *enic); | 144 | void enic_get_res_counts(struct enic *enic); |
143 | void enic_init_vnic_resources(struct enic *enic); | 145 | void enic_init_vnic_resources(struct enic *enic); |
144 | int enic_alloc_vnic_resources(struct enic *); | 146 | int enic_alloc_vnic_resources(struct enic *); |
diff --git a/drivers/net/enic/vnic_nic.h b/drivers/net/enic/vnic_nic.h index dadf26fae69a..eeaf329945d8 100644 --- a/drivers/net/enic/vnic_nic.h +++ b/drivers/net/enic/vnic_nic.h | |||
@@ -41,6 +41,13 @@ | |||
41 | #define NIC_CFG_IG_VLAN_STRIP_EN_MASK_FIELD 1UL | 41 | #define NIC_CFG_IG_VLAN_STRIP_EN_MASK_FIELD 1UL |
42 | #define NIC_CFG_IG_VLAN_STRIP_EN_SHIFT 24 | 42 | #define NIC_CFG_IG_VLAN_STRIP_EN_SHIFT 24 |
43 | 43 | ||
44 | #define NIC_CFG_RSS_HASH_TYPE_IPV4 (1 << 0) | ||
45 | #define NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 (1 << 1) | ||
46 | #define NIC_CFG_RSS_HASH_TYPE_IPV6 (1 << 2) | ||
47 | #define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6 (1 << 3) | ||
48 | #define NIC_CFG_RSS_HASH_TYPE_IPV6_EX (1 << 4) | ||
49 | #define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX (1 << 5) | ||
50 | |||
44 | static inline void vnic_set_nic_cfg(u32 *nic_cfg, | 51 | static inline void vnic_set_nic_cfg(u32 *nic_cfg, |
45 | u8 rss_default_cpu, u8 rss_hash_type, | 52 | u8 rss_default_cpu, u8 rss_hash_type, |
46 | u8 rss_hash_bits, u8 rss_base_cpu, | 53 | u8 rss_hash_bits, u8 rss_base_cpu, |