Commit | Line | Data |
---|---|---|
8b230ed8 RM |
1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify it | |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | |
6 | * published by the Free Software Foundation | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, but | |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
11 | * General Public License for more details. | |
12 | */ | |
13 | /* | |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | |
15 | * All rights reserved | |
16 | * www.brocade.com | |
17 | */ | |
18 | ||
19 | #include "bfa_defs_cna.h" | |
20 | #include "cna.h" | |
21 | #include "bfa_cee.h" | |
22 | #include "bfi_cna.h" | |
23 | #include "bfa_ioc.h" | |
24 | ||
25 | #define bfa_ioc_portid(__ioc) ((__ioc)->port_id) | |
26 | #define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc) | |
27 | ||
28 | static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg); | |
29 | static void bfa_cee_format_cee_cfg(void *buffer); | |
30 | ||
31 | static void | |
32 | bfa_cee_format_cee_cfg(void *buffer) | |
33 | { | |
34 | struct bfa_cee_attr *cee_cfg = buffer; | |
35 | bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote); | |
36 | } | |
37 | ||
38 | static void | |
39 | bfa_cee_stats_swap(struct bfa_cee_stats *stats) | |
40 | { | |
41 | u32 *buffer = (u32 *)stats; | |
42 | int i; | |
43 | ||
44 | for (i = 0; i < (sizeof(struct bfa_cee_stats) / sizeof(u32)); | |
45 | i++) { | |
46 | buffer[i] = ntohl(buffer[i]); | |
47 | } | |
48 | } | |
49 | ||
50 | static void | |
51 | bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg) | |
52 | { | |
53 | lldp_cfg->time_to_live = | |
54 | ntohs(lldp_cfg->time_to_live); | |
55 | lldp_cfg->enabled_system_cap = | |
56 | ntohs(lldp_cfg->enabled_system_cap); | |
57 | } | |
58 | ||
59 | /** | |
60 | * bfa_cee_attr_meminfo() | |
61 | * | |
62 | * @brief Returns the size of the DMA memory needed by CEE attributes | |
63 | * | |
64 | * @param[in] void | |
65 | * | |
66 | * @return Size of DMA region | |
67 | */ | |
68 | static u32 | |
69 | bfa_cee_attr_meminfo(void) | |
70 | { | |
71 | return roundup(sizeof(struct bfa_cee_attr), BFA_DMA_ALIGN_SZ); | |
72 | } | |
73 | /** | |
74 | * bfa_cee_stats_meminfo() | |
75 | * | |
76 | * @brief Returns the size of the DMA memory needed by CEE stats | |
77 | * | |
78 | * @param[in] void | |
79 | * | |
80 | * @return Size of DMA region | |
81 | */ | |
82 | static u32 | |
83 | bfa_cee_stats_meminfo(void) | |
84 | { | |
85 | return roundup(sizeof(struct bfa_cee_stats), BFA_DMA_ALIGN_SZ); | |
86 | } | |
87 | ||
88 | /** | |
89 | * bfa_cee_get_attr_isr() | |
90 | * | |
91 | * @brief CEE ISR for get-attributes responses from f/w | |
92 | * | |
93 | * @param[in] cee - Pointer to the CEE module | |
94 | * status - Return status from the f/w | |
95 | * | |
96 | * @return void | |
97 | */ | |
98 | static void | |
99 | bfa_cee_get_attr_isr(struct bfa_cee *cee, enum bfa_status status) | |
100 | { | |
101 | cee->get_attr_status = status; | |
102 | if (status == BFA_STATUS_OK) { | |
103 | memcpy(cee->attr, cee->attr_dma.kva, | |
104 | sizeof(struct bfa_cee_attr)); | |
105 | bfa_cee_format_cee_cfg(cee->attr); | |
106 | } | |
107 | cee->get_attr_pending = false; | |
108 | if (cee->cbfn.get_attr_cbfn) | |
109 | cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status); | |
110 | } | |
111 | ||
112 | /** | |
113 | * bfa_cee_get_attr_isr() | |
114 | * | |
115 | * @brief CEE ISR for get-stats responses from f/w | |
116 | * | |
117 | * @param[in] cee - Pointer to the CEE module | |
118 | * status - Return status from the f/w | |
119 | * | |
120 | * @return void | |
121 | */ | |
122 | static void | |
123 | bfa_cee_get_stats_isr(struct bfa_cee *cee, enum bfa_status status) | |
124 | { | |
125 | cee->get_stats_status = status; | |
126 | if (status == BFA_STATUS_OK) { | |
127 | memcpy(cee->stats, cee->stats_dma.kva, | |
128 | sizeof(struct bfa_cee_stats)); | |
129 | bfa_cee_stats_swap(cee->stats); | |
130 | } | |
131 | cee->get_stats_pending = false; | |
132 | if (cee->cbfn.get_stats_cbfn) | |
133 | cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status); | |
134 | } | |
135 | ||
136 | /** | |
137 | * bfa_cee_get_attr_isr() | |
138 | * | |
139 | * @brief CEE ISR for reset-stats responses from f/w | |
140 | * | |
141 | * @param[in] cee - Pointer to the CEE module | |
142 | * status - Return status from the f/w | |
143 | * | |
144 | * @return void | |
145 | */ | |
146 | static void | |
147 | bfa_cee_reset_stats_isr(struct bfa_cee *cee, enum bfa_status status) | |
148 | { | |
149 | cee->reset_stats_status = status; | |
150 | cee->reset_stats_pending = false; | |
151 | if (cee->cbfn.reset_stats_cbfn) | |
152 | cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status); | |
153 | } | |
154 | /** | |
8a891429 | 155 | * bfa_nw_cee_meminfo() |
8b230ed8 RM |
156 | * |
157 | * @brief Returns the size of the DMA memory needed by CEE module | |
158 | * | |
159 | * @param[in] void | |
160 | * | |
161 | * @return Size of DMA region | |
162 | */ | |
163 | u32 | |
8a891429 | 164 | bfa_nw_cee_meminfo(void) |
8b230ed8 RM |
165 | { |
166 | return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo(); | |
167 | } | |
168 | ||
169 | /** | |
8a891429 | 170 | * bfa_nw_cee_mem_claim() |
8b230ed8 RM |
171 | * |
172 | * @brief Initialized CEE DMA Memory | |
173 | * | |
174 | * @param[in] cee CEE module pointer | |
175 | * dma_kva Kernel Virtual Address of CEE DMA Memory | |
176 | * dma_pa Physical Address of CEE DMA Memory | |
177 | * | |
178 | * @return void | |
179 | */ | |
180 | void | |
8a891429 | 181 | bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa) |
8b230ed8 RM |
182 | { |
183 | cee->attr_dma.kva = dma_kva; | |
184 | cee->attr_dma.pa = dma_pa; | |
185 | cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo(); | |
186 | cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo(); | |
187 | cee->attr = (struct bfa_cee_attr *) dma_kva; | |
188 | cee->stats = (struct bfa_cee_stats *) | |
189 | (dma_kva + bfa_cee_attr_meminfo()); | |
190 | } | |
191 | ||
8b230ed8 RM |
192 | /** |
193 | * bfa_cee_isrs() | |
194 | * | |
195 | * @brief Handles Mail-box interrupts for CEE module. | |
196 | * | |
197 | * @param[in] Pointer to the CEE module data structure. | |
198 | * | |
199 | * @return void | |
200 | */ | |
201 | ||
8a891429 | 202 | static void |
8b230ed8 RM |
203 | bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m) |
204 | { | |
205 | union bfi_cee_i2h_msg_u *msg; | |
206 | struct bfi_cee_get_rsp *get_rsp; | |
207 | struct bfa_cee *cee = (struct bfa_cee *) cbarg; | |
208 | msg = (union bfi_cee_i2h_msg_u *) m; | |
209 | get_rsp = (struct bfi_cee_get_rsp *) m; | |
210 | switch (msg->mh.msg_id) { | |
211 | case BFI_CEE_I2H_GET_CFG_RSP: | |
212 | bfa_cee_get_attr_isr(cee, get_rsp->cmd_status); | |
213 | break; | |
214 | case BFI_CEE_I2H_GET_STATS_RSP: | |
215 | bfa_cee_get_stats_isr(cee, get_rsp->cmd_status); | |
216 | break; | |
217 | case BFI_CEE_I2H_RESET_STATS_RSP: | |
218 | bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status); | |
219 | break; | |
220 | default: | |
221 | BUG_ON(1); | |
222 | } | |
223 | } | |
224 | ||
225 | /** | |
bd5a92e9 | 226 | * bfa_cee_notify() |
8b230ed8 RM |
227 | * |
228 | * @brief CEE module heart-beat failure handler. | |
bd5a92e9 | 229 | * @brief CEE module IOC event handler. |
8b230ed8 | 230 | * |
bd5a92e9 | 231 | * @param[in] IOC event type |
8b230ed8 RM |
232 | * |
233 | * @return void | |
234 | */ | |
235 | ||
8a891429 | 236 | static void |
bd5a92e9 | 237 | bfa_cee_notify(void *arg, enum bfa_ioc_event event) |
8b230ed8 RM |
238 | { |
239 | struct bfa_cee *cee; | |
bd5a92e9 | 240 | cee = (struct bfa_cee *) arg; |
8b230ed8 | 241 | |
bd5a92e9 RM |
242 | switch (event) { |
243 | case BFA_IOC_E_DISABLED: | |
244 | case BFA_IOC_E_FAILED: | |
245 | if (cee->get_attr_pending == true) { | |
246 | cee->get_attr_status = BFA_STATUS_FAILED; | |
247 | cee->get_attr_pending = false; | |
248 | if (cee->cbfn.get_attr_cbfn) { | |
249 | cee->cbfn.get_attr_cbfn( | |
250 | cee->cbfn.get_attr_cbarg, | |
251 | BFA_STATUS_FAILED); | |
252 | } | |
8b230ed8 | 253 | } |
bd5a92e9 RM |
254 | if (cee->get_stats_pending == true) { |
255 | cee->get_stats_status = BFA_STATUS_FAILED; | |
256 | cee->get_stats_pending = false; | |
257 | if (cee->cbfn.get_stats_cbfn) { | |
258 | cee->cbfn.get_stats_cbfn( | |
259 | cee->cbfn.get_stats_cbarg, | |
260 | BFA_STATUS_FAILED); | |
261 | } | |
8b230ed8 | 262 | } |
bd5a92e9 RM |
263 | if (cee->reset_stats_pending == true) { |
264 | cee->reset_stats_status = BFA_STATUS_FAILED; | |
265 | cee->reset_stats_pending = false; | |
266 | if (cee->cbfn.reset_stats_cbfn) { | |
267 | cee->cbfn.reset_stats_cbfn( | |
268 | cee->cbfn.reset_stats_cbarg, | |
269 | BFA_STATUS_FAILED); | |
270 | } | |
8b230ed8 | 271 | } |
bd5a92e9 RM |
272 | break; |
273 | ||
274 | default: | |
275 | break; | |
8b230ed8 RM |
276 | } |
277 | } | |
278 | ||
279 | /** | |
8a891429 | 280 | * bfa_nw_cee_attach() |
8b230ed8 RM |
281 | * |
282 | * @brief CEE module-attach API | |
283 | * | |
284 | * @param[in] cee - Pointer to the CEE module data structure | |
285 | * ioc - Pointer to the ioc module data structure | |
286 | * dev - Pointer to the device driver module data structure | |
287 | * The device driver specific mbox ISR functions have | |
288 | * this pointer as one of the parameters. | |
289 | * | |
290 | * @return void | |
291 | */ | |
292 | void | |
8a891429 | 293 | bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, |
8b230ed8 RM |
294 | void *dev) |
295 | { | |
296 | BUG_ON(!(cee != NULL)); | |
297 | cee->dev = dev; | |
298 | cee->ioc = ioc; | |
299 | ||
8a891429 | 300 | bfa_nw_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee); |
bd5a92e9 RM |
301 | bfa_q_qe_init(&cee->ioc_notify); |
302 | bfa_ioc_notify_init(&cee->ioc_notify, bfa_cee_notify, cee); | |
303 | bfa_nw_ioc_notify_register(cee->ioc, &cee->ioc_notify); | |
8b230ed8 | 304 | } |