diff options
author | Sathya Perla <sathyap@serverengines.com> | 2009-06-17 20:02:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-19 03:18:39 -0400 |
commit | 5fb379ee67a7ec55ff65b467b472f3d69b60ba16 (patch) | |
tree | 23d8c00fd535abb6f9d56e98ade838b8ed253e99 /drivers/net/benet/be.h | |
parent | e3453f6342110d60edb37be92c4a4f668ca8b0c4 (diff) |
be2net: Add MCC queue mechanism for BE cmds
Currenlty all cmds use the blocking MCC mbox to post cmds. An mbox cmd is protected
via a spin_lock(cmd_lock) and not spin_lock_bh() as it is undesirable
to disable BHs while a blocking mbox cmd is in progress (and take long to finish.)
This can lockup a cmd in progress in process context. Instead cmds that may be
called in BH context must use the MCC queue to post cmds. The cmd completions
are rcvd in a separate completion queue and the events are placed in the tx-event
queue.
Signed-off-by: Sathya Perla <sathyap@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet/be.h')
-rw-r--r-- | drivers/net/benet/be.h | 95 |
1 files changed, 64 insertions, 31 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index b4bb06fdf30..ef5be133ce6 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -65,7 +65,7 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
65 | #define TX_CQ_LEN 1024 | 65 | #define TX_CQ_LEN 1024 |
66 | #define RX_Q_LEN 1024 /* Does not support any other value */ | 66 | #define RX_Q_LEN 1024 /* Does not support any other value */ |
67 | #define RX_CQ_LEN 1024 | 67 | #define RX_CQ_LEN 1024 |
68 | #define MCC_Q_LEN 64 /* total size not to exceed 8 pages */ | 68 | #define MCC_Q_LEN 128 /* total size not to exceed 8 pages */ |
69 | #define MCC_CQ_LEN 256 | 69 | #define MCC_CQ_LEN 256 |
70 | 70 | ||
71 | #define BE_NAPI_WEIGHT 64 | 71 | #define BE_NAPI_WEIGHT 64 |
@@ -91,6 +91,61 @@ struct be_queue_info { | |||
91 | atomic_t used; /* Number of valid elements in the queue */ | 91 | atomic_t used; /* Number of valid elements in the queue */ |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static inline u32 MODULO(u16 val, u16 limit) | ||
95 | { | ||
96 | BUG_ON(limit & (limit - 1)); | ||
97 | return val & (limit - 1); | ||
98 | } | ||
99 | |||
100 | static inline void index_adv(u16 *index, u16 val, u16 limit) | ||
101 | { | ||
102 | *index = MODULO((*index + val), limit); | ||
103 | } | ||
104 | |||
105 | static inline void index_inc(u16 *index, u16 limit) | ||
106 | { | ||
107 | *index = MODULO((*index + 1), limit); | ||
108 | } | ||
109 | |||
110 | static inline void *queue_head_node(struct be_queue_info *q) | ||
111 | { | ||
112 | return q->dma_mem.va + q->head * q->entry_size; | ||
113 | } | ||
114 | |||
115 | static inline void *queue_tail_node(struct be_queue_info *q) | ||
116 | { | ||
117 | return q->dma_mem.va + q->tail * q->entry_size; | ||
118 | } | ||
119 | |||
120 | static inline void queue_head_inc(struct be_queue_info *q) | ||
121 | { | ||
122 | index_inc(&q->head, q->len); | ||
123 | } | ||
124 | |||
125 | static inline void queue_tail_inc(struct be_queue_info *q) | ||
126 | { | ||
127 | index_inc(&q->tail, q->len); | ||
128 | } | ||
129 | |||
130 | |||
131 | struct be_eq_obj { | ||
132 | struct be_queue_info q; | ||
133 | char desc[32]; | ||
134 | |||
135 | /* Adaptive interrupt coalescing (AIC) info */ | ||
136 | bool enable_aic; | ||
137 | u16 min_eqd; /* in usecs */ | ||
138 | u16 max_eqd; /* in usecs */ | ||
139 | u16 cur_eqd; /* in usecs */ | ||
140 | |||
141 | struct napi_struct napi; | ||
142 | }; | ||
143 | |||
144 | struct be_mcc_obj { | ||
145 | struct be_queue_info q; | ||
146 | struct be_queue_info cq; | ||
147 | }; | ||
148 | |||
94 | struct be_ctrl_info { | 149 | struct be_ctrl_info { |
95 | u8 __iomem *csr; | 150 | u8 __iomem *csr; |
96 | u8 __iomem *db; /* Door Bell */ | 151 | u8 __iomem *db; /* Door Bell */ |
@@ -98,11 +153,16 @@ struct be_ctrl_info { | |||
98 | int pci_func; | 153 | int pci_func; |
99 | 154 | ||
100 | /* Mbox used for cmd request/response */ | 155 | /* Mbox used for cmd request/response */ |
101 | spinlock_t cmd_lock; /* For serializing cmds to BE card */ | 156 | spinlock_t mbox_lock; /* For serializing mbox cmds to BE card */ |
102 | struct be_dma_mem mbox_mem; | 157 | struct be_dma_mem mbox_mem; |
103 | /* Mbox mem is adjusted to align to 16 bytes. The allocated addr | 158 | /* Mbox mem is adjusted to align to 16 bytes. The allocated addr |
104 | * is stored for freeing purpose */ | 159 | * is stored for freeing purpose */ |
105 | struct be_dma_mem mbox_mem_alloced; | 160 | struct be_dma_mem mbox_mem_alloced; |
161 | |||
162 | /* MCC Rings */ | ||
163 | struct be_mcc_obj mcc_obj; | ||
164 | spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ | ||
165 | spinlock_t mcc_cq_lock; | ||
106 | }; | 166 | }; |
107 | 167 | ||
108 | #include "be_cmds.h" | 168 | #include "be_cmds.h" |
@@ -150,19 +210,6 @@ struct be_stats_obj { | |||
150 | struct be_dma_mem cmd; | 210 | struct be_dma_mem cmd; |
151 | }; | 211 | }; |
152 | 212 | ||
153 | struct be_eq_obj { | ||
154 | struct be_queue_info q; | ||
155 | char desc[32]; | ||
156 | |||
157 | /* Adaptive interrupt coalescing (AIC) info */ | ||
158 | bool enable_aic; | ||
159 | u16 min_eqd; /* in usecs */ | ||
160 | u16 max_eqd; /* in usecs */ | ||
161 | u16 cur_eqd; /* in usecs */ | ||
162 | |||
163 | struct napi_struct napi; | ||
164 | }; | ||
165 | |||
166 | struct be_tx_obj { | 213 | struct be_tx_obj { |
167 | struct be_queue_info q; | 214 | struct be_queue_info q; |
168 | struct be_queue_info cq; | 215 | struct be_queue_info cq; |
@@ -235,22 +282,6 @@ extern struct ethtool_ops be_ethtool_ops; | |||
235 | 282 | ||
236 | #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) | 283 | #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) |
237 | 284 | ||
238 | static inline u32 MODULO(u16 val, u16 limit) | ||
239 | { | ||
240 | BUG_ON(limit & (limit - 1)); | ||
241 | return val & (limit - 1); | ||
242 | } | ||
243 | |||
244 | static inline void index_adv(u16 *index, u16 val, u16 limit) | ||
245 | { | ||
246 | *index = MODULO((*index + val), limit); | ||
247 | } | ||
248 | |||
249 | static inline void index_inc(u16 *index, u16 limit) | ||
250 | { | ||
251 | *index = MODULO((*index + 1), limit); | ||
252 | } | ||
253 | |||
254 | #define PAGE_SHIFT_4K 12 | 285 | #define PAGE_SHIFT_4K 12 |
255 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) | 286 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) |
256 | 287 | ||
@@ -339,4 +370,6 @@ static inline u8 is_udp_pkt(struct sk_buff *skb) | |||
339 | return val; | 370 | return val; |
340 | } | 371 | } |
341 | 372 | ||
373 | extern void be_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm, | ||
374 | u16 num_popped); | ||
342 | #endif /* BE_H */ | 375 | #endif /* BE_H */ |