blob: 0e1628f2018e572a8b8300fe4ef0753bb95fc7dd [file] [log] [blame]
Sakthivel Kf5860992013-04-17 16:37:02 +05301/*
2 * PMC-Sierra SPCv/ve 8088/8089 SAS/SATA based host adapters driver
3 *
4 * Copyright (c) 2008-2009 PMC-Sierra, Inc.,
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * substantially similar to the "NO WARRANTY" disclaimer below
15 * ("Disclaimer") and any redistribution must be conditioned upon
16 * including a substantially similar Disclaimer requirement for further
17 * binary redistribution.
18 * 3. Neither the names of the above-listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * Alternatively, this software may be distributed under the terms of the
23 * GNU General Public License ("GPL") version 2 as published by the Free
24 * Software Foundation.
25 *
26 * NO WARRANTY
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGES.
38 *
39 */
40 #include <linux/slab.h>
41 #include "pm8001_sas.h"
42 #include "pm80xx_hwi.h"
43 #include "pm8001_chips.h"
44 #include "pm8001_ctl.h"
45
46#define SMP_DIRECT 1
47#define SMP_INDIRECT 2
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +053048
49
50int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shift_value)
51{
52 u32 reg_val;
53 unsigned long start;
54 pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER, shift_value);
55 /* confirm the setting is written */
56 start = jiffies + HZ; /* 1 sec */
57 do {
58 reg_val = pm8001_cr32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER);
59 } while ((reg_val != shift_value) && time_before(jiffies, start));
60 if (reg_val != shift_value) {
61 PM8001_FAIL_DBG(pm8001_ha,
62 pm8001_printk("TIMEOUT:MEMBASE_II_SHIFT_REGISTER"
63 " = 0x%x\n", reg_val));
64 return -1;
65 }
66 return 0;
67}
68
69void pm80xx_pci_mem_copy(struct pm8001_hba_info *pm8001_ha, u32 soffset,
70 const void *destination,
71 u32 dw_count, u32 bus_base_number)
72{
73 u32 index, value, offset;
74 u32 *destination1;
75 destination1 = (u32 *)destination;
76
77 for (index = 0; index < dw_count; index += 4, destination1++) {
78 offset = (soffset + index / 4);
79 if (offset < (64 * 1024)) {
80 value = pm8001_cr32(pm8001_ha, bus_base_number, offset);
81 *destination1 = cpu_to_le32(value);
82 }
83 }
84 return;
85}
86
87ssize_t pm80xx_get_fatal_dump(struct device *cdev,
88 struct device_attribute *attr, char *buf)
89{
90 struct Scsi_Host *shost = class_to_shost(cdev);
91 struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
92 struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
93 void __iomem *fatal_table_address = pm8001_ha->fatal_tbl_addr;
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +053094 u32 accum_len , reg_val, index, *temp;
95 unsigned long start;
96 u8 *direct_data;
97 char *fatal_error_data = buf;
98
99 pm8001_ha->forensic_info.data_buf.direct_data = buf;
100 if (pm8001_ha->chip_id == chip_8001) {
101 pm8001_ha->forensic_info.data_buf.direct_data +=
102 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
103 "Not supported for SPC controller");
104 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
105 (char *)buf;
106 }
107 if (pm8001_ha->forensic_info.data_buf.direct_offset == 0) {
108 PM8001_IO_DBG(pm8001_ha,
109 pm8001_printk("forensic_info TYPE_NON_FATAL..............\n"));
110 direct_data = (u8 *)fatal_error_data;
111 pm8001_ha->forensic_info.data_type = TYPE_NON_FATAL;
112 pm8001_ha->forensic_info.data_buf.direct_len = SYSFS_OFFSET;
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530113 pm8001_ha->forensic_info.data_buf.read_len = 0;
114
115 pm8001_ha->forensic_info.data_buf.direct_data = direct_data;
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530116
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530117 /* start to get data */
118 /* Program the MEMBASE II Shifting Register with 0x00.*/
119 pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
120 pm8001_ha->fatal_forensic_shift_offset);
121 pm8001_ha->forensic_last_offset = 0;
122 pm8001_ha->forensic_fatal_step = 0;
123 pm8001_ha->fatal_bar_loc = 0;
124 }
Viswas Gcf370062013-12-10 10:31:38 +0530125
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530126 /* Read until accum_len is retrived */
127 accum_len = pm8001_mr32(fatal_table_address,
128 MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
129 PM8001_IO_DBG(pm8001_ha, pm8001_printk("accum_len 0x%x\n",
130 accum_len));
131 if (accum_len == 0xFFFFFFFF) {
132 PM8001_IO_DBG(pm8001_ha,
133 pm8001_printk("Possible PCI issue 0x%x not expected\n",
134 accum_len));
Viswas Gcf370062013-12-10 10:31:38 +0530135 return -EIO;
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530136 }
137 if (accum_len == 0 || accum_len >= 0x100000) {
138 pm8001_ha->forensic_info.data_buf.direct_data +=
139 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
140 "%08x ", 0xFFFFFFFF);
141 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
142 (char *)buf;
143 }
144 temp = (u32 *)pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr;
145 if (pm8001_ha->forensic_fatal_step == 0) {
146moreData:
147 if (pm8001_ha->forensic_info.data_buf.direct_data) {
148 /* Data is in bar, copy to host memory */
149 pm80xx_pci_mem_copy(pm8001_ha, pm8001_ha->fatal_bar_loc,
150 pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr,
151 pm8001_ha->forensic_info.data_buf.direct_len ,
152 1);
153 }
154 pm8001_ha->fatal_bar_loc +=
155 pm8001_ha->forensic_info.data_buf.direct_len;
156 pm8001_ha->forensic_info.data_buf.direct_offset +=
157 pm8001_ha->forensic_info.data_buf.direct_len;
158 pm8001_ha->forensic_last_offset +=
159 pm8001_ha->forensic_info.data_buf.direct_len;
160 pm8001_ha->forensic_info.data_buf.read_len =
161 pm8001_ha->forensic_info.data_buf.direct_len;
162
163 if (pm8001_ha->forensic_last_offset >= accum_len) {
164 pm8001_ha->forensic_info.data_buf.direct_data +=
165 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
166 "%08x ", 3);
167 for (index = 0; index < (SYSFS_OFFSET / 4); index++) {
168 pm8001_ha->forensic_info.data_buf.direct_data +=
169 sprintf(pm8001_ha->
170 forensic_info.data_buf.direct_data,
171 "%08x ", *(temp + index));
172 }
173
174 pm8001_ha->fatal_bar_loc = 0;
175 pm8001_ha->forensic_fatal_step = 1;
176 pm8001_ha->fatal_forensic_shift_offset = 0;
177 pm8001_ha->forensic_last_offset = 0;
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530178 return (char *)pm8001_ha->
179 forensic_info.data_buf.direct_data -
180 (char *)buf;
181 }
182 if (pm8001_ha->fatal_bar_loc < (64 * 1024)) {
183 pm8001_ha->forensic_info.data_buf.direct_data +=
184 sprintf(pm8001_ha->
185 forensic_info.data_buf.direct_data,
186 "%08x ", 2);
187 for (index = 0; index < (SYSFS_OFFSET / 4); index++) {
188 pm8001_ha->forensic_info.data_buf.direct_data +=
189 sprintf(pm8001_ha->
190 forensic_info.data_buf.direct_data,
191 "%08x ", *(temp + index));
192 }
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530193 return (char *)pm8001_ha->
194 forensic_info.data_buf.direct_data -
195 (char *)buf;
196 }
197
198 /* Increment the MEMBASE II Shifting Register value by 0x100.*/
199 pm8001_ha->forensic_info.data_buf.direct_data +=
200 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
201 "%08x ", 2);
202 for (index = 0; index < 256; index++) {
203 pm8001_ha->forensic_info.data_buf.direct_data +=
204 sprintf(pm8001_ha->
205 forensic_info.data_buf.direct_data,
206 "%08x ", *(temp + index));
207 }
208 pm8001_ha->fatal_forensic_shift_offset += 0x100;
209 pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
210 pm8001_ha->fatal_forensic_shift_offset);
211 pm8001_ha->fatal_bar_loc = 0;
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530212 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
213 (char *)buf;
214 }
215 if (pm8001_ha->forensic_fatal_step == 1) {
216 pm8001_ha->fatal_forensic_shift_offset = 0;
217 /* Read 64K of the debug data. */
218 pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
219 pm8001_ha->fatal_forensic_shift_offset);
220 pm8001_mw32(fatal_table_address,
221 MPI_FATAL_EDUMP_TABLE_HANDSHAKE,
222 MPI_FATAL_EDUMP_HANDSHAKE_RDY);
223
224 /* Poll FDDHSHK until clear */
225 start = jiffies + (2 * HZ); /* 2 sec */
226
227 do {
228 reg_val = pm8001_mr32(fatal_table_address,
229 MPI_FATAL_EDUMP_TABLE_HANDSHAKE);
230 } while ((reg_val) && time_before(jiffies, start));
231
232 if (reg_val != 0) {
233 PM8001_FAIL_DBG(pm8001_ha,
234 pm8001_printk("TIMEOUT:MEMBASE_II_SHIFT_REGISTER"
235 " = 0x%x\n", reg_val));
Viswas Gcf370062013-12-10 10:31:38 +0530236 return -EIO;
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530237 }
238
239 /* Read the next 64K of the debug data. */
240 pm8001_ha->forensic_fatal_step = 0;
241 if (pm8001_mr32(fatal_table_address,
242 MPI_FATAL_EDUMP_TABLE_STATUS) !=
243 MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE) {
244 pm8001_mw32(fatal_table_address,
245 MPI_FATAL_EDUMP_TABLE_HANDSHAKE, 0);
246 goto moreData;
247 } else {
248 pm8001_ha->forensic_info.data_buf.direct_data +=
249 sprintf(pm8001_ha->
250 forensic_info.data_buf.direct_data,
251 "%08x ", 4);
252 pm8001_ha->forensic_info.data_buf.read_len = 0xFFFFFFFF;
253 pm8001_ha->forensic_info.data_buf.direct_len = 0;
254 pm8001_ha->forensic_info.data_buf.direct_offset = 0;
255 pm8001_ha->forensic_info.data_buf.read_len = 0;
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530256 }
257 }
258
259 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
260 (char *)buf;
261}
262
Sakthivel Kf5860992013-04-17 16:37:02 +0530263/**
264 * read_main_config_table - read the configure table and save it.
265 * @pm8001_ha: our hba card information
266 */
267static void read_main_config_table(struct pm8001_hba_info *pm8001_ha)
268{
269 void __iomem *address = pm8001_ha->main_cfg_tbl_addr;
270
271 pm8001_ha->main_cfg_tbl.pm80xx_tbl.signature =
272 pm8001_mr32(address, MAIN_SIGNATURE_OFFSET);
273 pm8001_ha->main_cfg_tbl.pm80xx_tbl.interface_rev =
274 pm8001_mr32(address, MAIN_INTERFACE_REVISION);
275 pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev =
276 pm8001_mr32(address, MAIN_FW_REVISION);
277 pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io =
278 pm8001_mr32(address, MAIN_MAX_OUTSTANDING_IO_OFFSET);
279 pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_sgl =
280 pm8001_mr32(address, MAIN_MAX_SGL_OFFSET);
281 pm8001_ha->main_cfg_tbl.pm80xx_tbl.ctrl_cap_flag =
282 pm8001_mr32(address, MAIN_CNTRL_CAP_OFFSET);
283 pm8001_ha->main_cfg_tbl.pm80xx_tbl.gst_offset =
284 pm8001_mr32(address, MAIN_GST_OFFSET);
285 pm8001_ha->main_cfg_tbl.pm80xx_tbl.inbound_queue_offset =
286 pm8001_mr32(address, MAIN_IBQ_OFFSET);
287 pm8001_ha->main_cfg_tbl.pm80xx_tbl.outbound_queue_offset =
288 pm8001_mr32(address, MAIN_OBQ_OFFSET);
289
290 /* read Error Dump Offset and Length */
291 pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_dump_offset0 =
292 pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_OFFSET);
293 pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_dump_length0 =
294 pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_LENGTH);
295 pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_dump_offset1 =
296 pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_OFFSET);
297 pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_dump_length1 =
298 pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_LENGTH);
299
300 /* read GPIO LED settings from the configuration table */
301 pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping =
302 pm8001_mr32(address, MAIN_GPIO_LED_FLAGS_OFFSET);
303
304 /* read analog Setting offset from the configuration table */
305 pm8001_ha->main_cfg_tbl.pm80xx_tbl.analog_setup_table_offset =
306 pm8001_mr32(address, MAIN_ANALOG_SETUP_OFFSET);
307
308 pm8001_ha->main_cfg_tbl.pm80xx_tbl.int_vec_table_offset =
309 pm8001_mr32(address, MAIN_INT_VECTOR_TABLE_OFFSET);
310 pm8001_ha->main_cfg_tbl.pm80xx_tbl.phy_attr_table_offset =
311 pm8001_mr32(address, MAIN_SAS_PHY_ATTR_TABLE_OFFSET);
Viswas G8414cd82015-08-11 15:06:30 +0530312 /* read port recover and reset timeout */
313 pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer =
314 pm8001_mr32(address, MAIN_PORT_RECOVERY_TIMER);
Sakthivel Kf5860992013-04-17 16:37:02 +0530315}
316
317/**
318 * read_general_status_table - read the general status table and save it.
319 * @pm8001_ha: our hba card information
320 */
321static void read_general_status_table(struct pm8001_hba_info *pm8001_ha)
322{
323 void __iomem *address = pm8001_ha->general_stat_tbl_addr;
324 pm8001_ha->gs_tbl.pm80xx_tbl.gst_len_mpistate =
325 pm8001_mr32(address, GST_GSTLEN_MPIS_OFFSET);
326 pm8001_ha->gs_tbl.pm80xx_tbl.iq_freeze_state0 =
327 pm8001_mr32(address, GST_IQ_FREEZE_STATE0_OFFSET);
328 pm8001_ha->gs_tbl.pm80xx_tbl.iq_freeze_state1 =
329 pm8001_mr32(address, GST_IQ_FREEZE_STATE1_OFFSET);
330 pm8001_ha->gs_tbl.pm80xx_tbl.msgu_tcnt =
331 pm8001_mr32(address, GST_MSGUTCNT_OFFSET);
332 pm8001_ha->gs_tbl.pm80xx_tbl.iop_tcnt =
333 pm8001_mr32(address, GST_IOPTCNT_OFFSET);
334 pm8001_ha->gs_tbl.pm80xx_tbl.gpio_input_val =
335 pm8001_mr32(address, GST_GPIO_INPUT_VAL);
336 pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[0] =
337 pm8001_mr32(address, GST_RERRINFO_OFFSET0);
338 pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[1] =
339 pm8001_mr32(address, GST_RERRINFO_OFFSET1);
340 pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[2] =
341 pm8001_mr32(address, GST_RERRINFO_OFFSET2);
342 pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[3] =
343 pm8001_mr32(address, GST_RERRINFO_OFFSET3);
344 pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[4] =
345 pm8001_mr32(address, GST_RERRINFO_OFFSET4);
346 pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[5] =
347 pm8001_mr32(address, GST_RERRINFO_OFFSET5);
348 pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[6] =
349 pm8001_mr32(address, GST_RERRINFO_OFFSET6);
350 pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[7] =
351 pm8001_mr32(address, GST_RERRINFO_OFFSET7);
352}
353/**
354 * read_phy_attr_table - read the phy attribute table and save it.
355 * @pm8001_ha: our hba card information
356 */
357static void read_phy_attr_table(struct pm8001_hba_info *pm8001_ha)
358{
359 void __iomem *address = pm8001_ha->pspa_q_tbl_addr;
360 pm8001_ha->phy_attr_table.phystart1_16[0] =
361 pm8001_mr32(address, PSPA_PHYSTATE0_OFFSET);
362 pm8001_ha->phy_attr_table.phystart1_16[1] =
363 pm8001_mr32(address, PSPA_PHYSTATE1_OFFSET);
364 pm8001_ha->phy_attr_table.phystart1_16[2] =
365 pm8001_mr32(address, PSPA_PHYSTATE2_OFFSET);
366 pm8001_ha->phy_attr_table.phystart1_16[3] =
367 pm8001_mr32(address, PSPA_PHYSTATE3_OFFSET);
368 pm8001_ha->phy_attr_table.phystart1_16[4] =
369 pm8001_mr32(address, PSPA_PHYSTATE4_OFFSET);
370 pm8001_ha->phy_attr_table.phystart1_16[5] =
371 pm8001_mr32(address, PSPA_PHYSTATE5_OFFSET);
372 pm8001_ha->phy_attr_table.phystart1_16[6] =
373 pm8001_mr32(address, PSPA_PHYSTATE6_OFFSET);
374 pm8001_ha->phy_attr_table.phystart1_16[7] =
375 pm8001_mr32(address, PSPA_PHYSTATE7_OFFSET);
376 pm8001_ha->phy_attr_table.phystart1_16[8] =
377 pm8001_mr32(address, PSPA_PHYSTATE8_OFFSET);
378 pm8001_ha->phy_attr_table.phystart1_16[9] =
379 pm8001_mr32(address, PSPA_PHYSTATE9_OFFSET);
380 pm8001_ha->phy_attr_table.phystart1_16[10] =
381 pm8001_mr32(address, PSPA_PHYSTATE10_OFFSET);
382 pm8001_ha->phy_attr_table.phystart1_16[11] =
383 pm8001_mr32(address, PSPA_PHYSTATE11_OFFSET);
384 pm8001_ha->phy_attr_table.phystart1_16[12] =
385 pm8001_mr32(address, PSPA_PHYSTATE12_OFFSET);
386 pm8001_ha->phy_attr_table.phystart1_16[13] =
387 pm8001_mr32(address, PSPA_PHYSTATE13_OFFSET);
388 pm8001_ha->phy_attr_table.phystart1_16[14] =
389 pm8001_mr32(address, PSPA_PHYSTATE14_OFFSET);
390 pm8001_ha->phy_attr_table.phystart1_16[15] =
391 pm8001_mr32(address, PSPA_PHYSTATE15_OFFSET);
392
393 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[0] =
394 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID0_OFFSET);
395 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[1] =
396 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID1_OFFSET);
397 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[2] =
398 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID2_OFFSET);
399 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[3] =
400 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID3_OFFSET);
401 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[4] =
402 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID4_OFFSET);
403 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[5] =
404 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID5_OFFSET);
405 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[6] =
406 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID6_OFFSET);
407 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[7] =
408 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID7_OFFSET);
409 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[8] =
410 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID8_OFFSET);
411 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[9] =
412 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID9_OFFSET);
413 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[10] =
414 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID10_OFFSET);
415 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[11] =
416 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID11_OFFSET);
417 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[12] =
418 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID12_OFFSET);
419 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[13] =
420 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID13_OFFSET);
421 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[14] =
422 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID14_OFFSET);
423 pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[15] =
424 pm8001_mr32(address, PSPA_OB_HW_EVENT_PID15_OFFSET);
425
426}
427
428/**
429 * read_inbnd_queue_table - read the inbound queue table and save it.
430 * @pm8001_ha: our hba card information
431 */
432static void read_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
433{
434 int i;
435 void __iomem *address = pm8001_ha->inbnd_q_tbl_addr;
436 for (i = 0; i < PM8001_MAX_SPCV_INB_NUM; i++) {
437 u32 offset = i * 0x20;
438 pm8001_ha->inbnd_q_tbl[i].pi_pci_bar =
439 get_pci_bar_index(pm8001_mr32(address,
440 (offset + IB_PIPCI_BAR)));
441 pm8001_ha->inbnd_q_tbl[i].pi_offset =
442 pm8001_mr32(address, (offset + IB_PIPCI_BAR_OFFSET));
443 }
444}
445
446/**
447 * read_outbnd_queue_table - read the outbound queue table and save it.
448 * @pm8001_ha: our hba card information
449 */
450static void read_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
451{
452 int i;
453 void __iomem *address = pm8001_ha->outbnd_q_tbl_addr;
454 for (i = 0; i < PM8001_MAX_SPCV_OUTB_NUM; i++) {
455 u32 offset = i * 0x24;
456 pm8001_ha->outbnd_q_tbl[i].ci_pci_bar =
457 get_pci_bar_index(pm8001_mr32(address,
458 (offset + OB_CIPCI_BAR)));
459 pm8001_ha->outbnd_q_tbl[i].ci_offset =
460 pm8001_mr32(address, (offset + OB_CIPCI_BAR_OFFSET));
461 }
462}
463
464/**
465 * init_default_table_values - init the default table.
466 * @pm8001_ha: our hba card information
467 */
468static void init_default_table_values(struct pm8001_hba_info *pm8001_ha)
469{
470 int i;
471 u32 offsetib, offsetob;
472 void __iomem *addressib = pm8001_ha->inbnd_q_tbl_addr;
473 void __iomem *addressob = pm8001_ha->outbnd_q_tbl_addr;
474
475 pm8001_ha->main_cfg_tbl.pm80xx_tbl.upper_event_log_addr =
476 pm8001_ha->memoryMap.region[AAP1].phys_addr_hi;
477 pm8001_ha->main_cfg_tbl.pm80xx_tbl.lower_event_log_addr =
478 pm8001_ha->memoryMap.region[AAP1].phys_addr_lo;
479 pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_size =
480 PM8001_EVENT_LOG_SIZE;
481 pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_severity = 0x01;
482 pm8001_ha->main_cfg_tbl.pm80xx_tbl.upper_pcs_event_log_addr =
483 pm8001_ha->memoryMap.region[IOP].phys_addr_hi;
484 pm8001_ha->main_cfg_tbl.pm80xx_tbl.lower_pcs_event_log_addr =
485 pm8001_ha->memoryMap.region[IOP].phys_addr_lo;
486 pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_size =
487 PM8001_EVENT_LOG_SIZE;
488 pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_severity = 0x01;
489 pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt = 0x01;
490
Sakthivel Kc6b9ef52013-03-19 18:08:08 +0530491 /* Disable end to end CRC checking */
492 pm8001_ha->main_cfg_tbl.pm80xx_tbl.crc_core_dump = (0x1 << 16);
493
Sakthivel Kf5860992013-04-17 16:37:02 +0530494 for (i = 0; i < PM8001_MAX_SPCV_INB_NUM; i++) {
495 pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt =
Hans Verkuil9504a922013-07-26 18:43:45 +0200496 PM8001_MPI_QUEUE | (pm8001_ha->iomb_size << 16) | (0x00<<30);
Sakthivel Kf5860992013-04-17 16:37:02 +0530497 pm8001_ha->inbnd_q_tbl[i].upper_base_addr =
498 pm8001_ha->memoryMap.region[IB + i].phys_addr_hi;
499 pm8001_ha->inbnd_q_tbl[i].lower_base_addr =
500 pm8001_ha->memoryMap.region[IB + i].phys_addr_lo;
501 pm8001_ha->inbnd_q_tbl[i].base_virt =
502 (u8 *)pm8001_ha->memoryMap.region[IB + i].virt_ptr;
503 pm8001_ha->inbnd_q_tbl[i].total_length =
504 pm8001_ha->memoryMap.region[IB + i].total_len;
505 pm8001_ha->inbnd_q_tbl[i].ci_upper_base_addr =
506 pm8001_ha->memoryMap.region[CI + i].phys_addr_hi;
507 pm8001_ha->inbnd_q_tbl[i].ci_lower_base_addr =
508 pm8001_ha->memoryMap.region[CI + i].phys_addr_lo;
509 pm8001_ha->inbnd_q_tbl[i].ci_virt =
510 pm8001_ha->memoryMap.region[CI + i].virt_ptr;
511 offsetib = i * 0x20;
512 pm8001_ha->inbnd_q_tbl[i].pi_pci_bar =
513 get_pci_bar_index(pm8001_mr32(addressib,
514 (offsetib + 0x14)));
515 pm8001_ha->inbnd_q_tbl[i].pi_offset =
516 pm8001_mr32(addressib, (offsetib + 0x18));
517 pm8001_ha->inbnd_q_tbl[i].producer_idx = 0;
518 pm8001_ha->inbnd_q_tbl[i].consumer_index = 0;
519 }
520 for (i = 0; i < PM8001_MAX_SPCV_OUTB_NUM; i++) {
521 pm8001_ha->outbnd_q_tbl[i].element_size_cnt =
Hans Verkuil9504a922013-07-26 18:43:45 +0200522 PM8001_MPI_QUEUE | (pm8001_ha->iomb_size << 16) | (0x01<<30);
Sakthivel Kf5860992013-04-17 16:37:02 +0530523 pm8001_ha->outbnd_q_tbl[i].upper_base_addr =
524 pm8001_ha->memoryMap.region[OB + i].phys_addr_hi;
525 pm8001_ha->outbnd_q_tbl[i].lower_base_addr =
526 pm8001_ha->memoryMap.region[OB + i].phys_addr_lo;
527 pm8001_ha->outbnd_q_tbl[i].base_virt =
528 (u8 *)pm8001_ha->memoryMap.region[OB + i].virt_ptr;
529 pm8001_ha->outbnd_q_tbl[i].total_length =
530 pm8001_ha->memoryMap.region[OB + i].total_len;
531 pm8001_ha->outbnd_q_tbl[i].pi_upper_base_addr =
532 pm8001_ha->memoryMap.region[PI + i].phys_addr_hi;
533 pm8001_ha->outbnd_q_tbl[i].pi_lower_base_addr =
534 pm8001_ha->memoryMap.region[PI + i].phys_addr_lo;
535 /* interrupt vector based on oq */
536 pm8001_ha->outbnd_q_tbl[i].interrup_vec_cnt_delay = (i << 24);
537 pm8001_ha->outbnd_q_tbl[i].pi_virt =
538 pm8001_ha->memoryMap.region[PI + i].virt_ptr;
539 offsetob = i * 0x24;
540 pm8001_ha->outbnd_q_tbl[i].ci_pci_bar =
541 get_pci_bar_index(pm8001_mr32(addressob,
542 offsetob + 0x14));
543 pm8001_ha->outbnd_q_tbl[i].ci_offset =
544 pm8001_mr32(addressob, (offsetob + 0x18));
545 pm8001_ha->outbnd_q_tbl[i].consumer_idx = 0;
546 pm8001_ha->outbnd_q_tbl[i].producer_index = 0;
547 }
548}
549
550/**
551 * update_main_config_table - update the main default table to the HBA.
552 * @pm8001_ha: our hba card information
553 */
554static void update_main_config_table(struct pm8001_hba_info *pm8001_ha)
555{
556 void __iomem *address = pm8001_ha->main_cfg_tbl_addr;
557 pm8001_mw32(address, MAIN_IQNPPD_HPPD_OFFSET,
558 pm8001_ha->main_cfg_tbl.pm80xx_tbl.inbound_q_nppd_hppd);
559 pm8001_mw32(address, MAIN_EVENT_LOG_ADDR_HI,
560 pm8001_ha->main_cfg_tbl.pm80xx_tbl.upper_event_log_addr);
561 pm8001_mw32(address, MAIN_EVENT_LOG_ADDR_LO,
562 pm8001_ha->main_cfg_tbl.pm80xx_tbl.lower_event_log_addr);
563 pm8001_mw32(address, MAIN_EVENT_LOG_BUFF_SIZE,
564 pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_size);
565 pm8001_mw32(address, MAIN_EVENT_LOG_OPTION,
566 pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_severity);
567 pm8001_mw32(address, MAIN_PCS_EVENT_LOG_ADDR_HI,
568 pm8001_ha->main_cfg_tbl.pm80xx_tbl.upper_pcs_event_log_addr);
569 pm8001_mw32(address, MAIN_PCS_EVENT_LOG_ADDR_LO,
570 pm8001_ha->main_cfg_tbl.pm80xx_tbl.lower_pcs_event_log_addr);
571 pm8001_mw32(address, MAIN_PCS_EVENT_LOG_BUFF_SIZE,
572 pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_size);
573 pm8001_mw32(address, MAIN_PCS_EVENT_LOG_OPTION,
574 pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_severity);
575 pm8001_mw32(address, MAIN_FATAL_ERROR_INTERRUPT,
576 pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt);
Sakthivel Kc6b9ef52013-03-19 18:08:08 +0530577 pm8001_mw32(address, MAIN_EVENT_CRC_CHECK,
578 pm8001_ha->main_cfg_tbl.pm80xx_tbl.crc_core_dump);
Sakthivel Kf5860992013-04-17 16:37:02 +0530579
580 /* SPCv specific */
581 pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping &= 0xCFFFFFFF;
582 /* Set GPIOLED to 0x2 for LED indicator */
583 pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping |= 0x20000000;
584 pm8001_mw32(address, MAIN_GPIO_LED_FLAGS_OFFSET,
585 pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping);
586
587 pm8001_mw32(address, MAIN_PORT_RECOVERY_TIMER,
588 pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer);
589 pm8001_mw32(address, MAIN_INT_REASSERTION_DELAY,
590 pm8001_ha->main_cfg_tbl.pm80xx_tbl.interrupt_reassertion_delay);
Viswas G8414cd82015-08-11 15:06:30 +0530591
592 pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer &= 0xffff0000;
593 pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer |=
594 PORT_RECOVERY_TIMEOUT;
595 pm8001_mw32(address, MAIN_PORT_RECOVERY_TIMER,
596 pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer);
Sakthivel Kf5860992013-04-17 16:37:02 +0530597}
598
599/**
600 * update_inbnd_queue_table - update the inbound queue table to the HBA.
601 * @pm8001_ha: our hba card information
602 */
603static void update_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha,
604 int number)
605{
606 void __iomem *address = pm8001_ha->inbnd_q_tbl_addr;
607 u16 offset = number * 0x20;
608 pm8001_mw32(address, offset + IB_PROPERITY_OFFSET,
609 pm8001_ha->inbnd_q_tbl[number].element_pri_size_cnt);
610 pm8001_mw32(address, offset + IB_BASE_ADDR_HI_OFFSET,
611 pm8001_ha->inbnd_q_tbl[number].upper_base_addr);
612 pm8001_mw32(address, offset + IB_BASE_ADDR_LO_OFFSET,
613 pm8001_ha->inbnd_q_tbl[number].lower_base_addr);
614 pm8001_mw32(address, offset + IB_CI_BASE_ADDR_HI_OFFSET,
615 pm8001_ha->inbnd_q_tbl[number].ci_upper_base_addr);
616 pm8001_mw32(address, offset + IB_CI_BASE_ADDR_LO_OFFSET,
617 pm8001_ha->inbnd_q_tbl[number].ci_lower_base_addr);
618}
619
620/**
621 * update_outbnd_queue_table - update the outbound queue table to the HBA.
622 * @pm8001_ha: our hba card information
623 */
624static void update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha,
625 int number)
626{
627 void __iomem *address = pm8001_ha->outbnd_q_tbl_addr;
628 u16 offset = number * 0x24;
629 pm8001_mw32(address, offset + OB_PROPERITY_OFFSET,
630 pm8001_ha->outbnd_q_tbl[number].element_size_cnt);
631 pm8001_mw32(address, offset + OB_BASE_ADDR_HI_OFFSET,
632 pm8001_ha->outbnd_q_tbl[number].upper_base_addr);
633 pm8001_mw32(address, offset + OB_BASE_ADDR_LO_OFFSET,
634 pm8001_ha->outbnd_q_tbl[number].lower_base_addr);
635 pm8001_mw32(address, offset + OB_PI_BASE_ADDR_HI_OFFSET,
636 pm8001_ha->outbnd_q_tbl[number].pi_upper_base_addr);
637 pm8001_mw32(address, offset + OB_PI_BASE_ADDR_LO_OFFSET,
638 pm8001_ha->outbnd_q_tbl[number].pi_lower_base_addr);
639 pm8001_mw32(address, offset + OB_INTERRUPT_COALES_OFFSET,
640 pm8001_ha->outbnd_q_tbl[number].interrup_vec_cnt_delay);
641}
642
643/**
644 * mpi_init_check - check firmware initialization status.
645 * @pm8001_ha: our hba card information
646 */
647static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)
648{
649 u32 max_wait_count;
650 u32 value;
651 u32 gst_len_mpistate;
652
653 /* Write bit0=1 to Inbound DoorBell Register to tell the SPC FW the
654 table is updated */
655 pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPCv_MSGU_CFG_TABLE_UPDATE);
656 /* wait until Inbound DoorBell Clear Register toggled */
Anand Kumar Santhanama9a923e2013-09-03 15:09:42 +0530657 if (IS_SPCV_12G(pm8001_ha->pdev)) {
658 max_wait_count = 4 * 1000 * 1000;/* 4 sec */
659 } else {
660 max_wait_count = 2 * 1000 * 1000;/* 2 sec */
661 }
Sakthivel Kf5860992013-04-17 16:37:02 +0530662 do {
663 udelay(1);
664 value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);
665 value &= SPCv_MSGU_CFG_TABLE_UPDATE;
666 } while ((value != 0) && (--max_wait_count));
667
668 if (!max_wait_count)
669 return -1;
670 /* check the MPI-State for initialization upto 100ms*/
671 max_wait_count = 100 * 1000;/* 100 msec */
672 do {
673 udelay(1);
674 gst_len_mpistate =
675 pm8001_mr32(pm8001_ha->general_stat_tbl_addr,
676 GST_GSTLEN_MPIS_OFFSET);
677 } while ((GST_MPI_STATE_INIT !=
678 (gst_len_mpistate & GST_MPI_STATE_MASK)) && (--max_wait_count));
679 if (!max_wait_count)
680 return -1;
681
682 /* check MPI Initialization error */
683 gst_len_mpistate = gst_len_mpistate >> 16;
684 if (0x0000 != gst_len_mpistate)
685 return -1;
686
687 return 0;
688}
689
690/**
691 * check_fw_ready - The LLDD check if the FW is ready, if not, return error.
692 * @pm8001_ha: our hba card information
693 */
694static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)
695{
696 u32 value;
697 u32 max_wait_count;
698 u32 max_wait_time;
699 int ret = 0;
700
701 /* reset / PCIe ready */
702 max_wait_time = max_wait_count = 100 * 1000; /* 100 milli sec */
703 do {
704 udelay(1);
705 value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
706 } while ((value == 0xFFFFFFFF) && (--max_wait_count));
707
708 /* check ila status */
709 max_wait_time = max_wait_count = 1000 * 1000; /* 1000 milli sec */
710 do {
711 udelay(1);
712 value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
713 } while (((value & SCRATCH_PAD_ILA_READY) !=
714 SCRATCH_PAD_ILA_READY) && (--max_wait_count));
715 if (!max_wait_count)
716 ret = -1;
717 else {
718 PM8001_MSG_DBG(pm8001_ha,
719 pm8001_printk(" ila ready status in %d millisec\n",
720 (max_wait_time - max_wait_count)));
721 }
722
723 /* check RAAE status */
724 max_wait_time = max_wait_count = 1800 * 1000; /* 1800 milli sec */
725 do {
726 udelay(1);
727 value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
728 } while (((value & SCRATCH_PAD_RAAE_READY) !=
729 SCRATCH_PAD_RAAE_READY) && (--max_wait_count));
730 if (!max_wait_count)
731 ret = -1;
732 else {
733 PM8001_MSG_DBG(pm8001_ha,
734 pm8001_printk(" raae ready status in %d millisec\n",
735 (max_wait_time - max_wait_count)));
736 }
737
738 /* check iop0 status */
739 max_wait_time = max_wait_count = 600 * 1000; /* 600 milli sec */
740 do {
741 udelay(1);
742 value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
743 } while (((value & SCRATCH_PAD_IOP0_READY) != SCRATCH_PAD_IOP0_READY) &&
744 (--max_wait_count));
745 if (!max_wait_count)
746 ret = -1;
747 else {
748 PM8001_MSG_DBG(pm8001_ha,
749 pm8001_printk(" iop0 ready status in %d millisec\n",
750 (max_wait_time - max_wait_count)));
751 }
752
753 /* check iop1 status only for 16 port controllers */
754 if ((pm8001_ha->chip_id != chip_8008) &&
755 (pm8001_ha->chip_id != chip_8009)) {
756 /* 200 milli sec */
757 max_wait_time = max_wait_count = 200 * 1000;
758 do {
759 udelay(1);
760 value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
761 } while (((value & SCRATCH_PAD_IOP1_READY) !=
762 SCRATCH_PAD_IOP1_READY) && (--max_wait_count));
763 if (!max_wait_count)
764 ret = -1;
765 else {
766 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
767 "iop1 ready status in %d millisec\n",
768 (max_wait_time - max_wait_count)));
769 }
770 }
771
772 return ret;
773}
774
775static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
776{
777 void __iomem *base_addr;
778 u32 value;
779 u32 offset;
780 u32 pcibar;
781 u32 pcilogic;
782
783 value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0);
784 offset = value & 0x03FFFFFF; /* scratch pad 0 TBL address */
785
786 PM8001_INIT_DBG(pm8001_ha,
787 pm8001_printk("Scratchpad 0 Offset: 0x%x value 0x%x\n",
788 offset, value));
789 pcilogic = (value & 0xFC000000) >> 26;
790 pcibar = get_pci_bar_index(pcilogic);
791 PM8001_INIT_DBG(pm8001_ha,
792 pm8001_printk("Scratchpad 0 PCI BAR: %d\n", pcibar));
793 pm8001_ha->main_cfg_tbl_addr = base_addr =
794 pm8001_ha->io_mem[pcibar].memvirtaddr + offset;
795 pm8001_ha->general_stat_tbl_addr =
796 base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x18) &
797 0xFFFFFF);
798 pm8001_ha->inbnd_q_tbl_addr =
799 base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x1C) &
800 0xFFFFFF);
801 pm8001_ha->outbnd_q_tbl_addr =
802 base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x20) &
803 0xFFFFFF);
804 pm8001_ha->ivt_tbl_addr =
805 base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x8C) &
806 0xFFFFFF);
807 pm8001_ha->pspa_q_tbl_addr =
808 base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x90) &
809 0xFFFFFF);
Anand Kumar Santhanamd078b512013-09-04 12:57:00 +0530810 pm8001_ha->fatal_tbl_addr =
811 base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0xA0) &
812 0xFFFFFF);
Sakthivel Kf5860992013-04-17 16:37:02 +0530813
814 PM8001_INIT_DBG(pm8001_ha,
815 pm8001_printk("GST OFFSET 0x%x\n",
816 pm8001_cr32(pm8001_ha, pcibar, offset + 0x18)));
817 PM8001_INIT_DBG(pm8001_ha,
818 pm8001_printk("INBND OFFSET 0x%x\n",
819 pm8001_cr32(pm8001_ha, pcibar, offset + 0x1C)));
820 PM8001_INIT_DBG(pm8001_ha,
821 pm8001_printk("OBND OFFSET 0x%x\n",
822 pm8001_cr32(pm8001_ha, pcibar, offset + 0x20)));
823 PM8001_INIT_DBG(pm8001_ha,
824 pm8001_printk("IVT OFFSET 0x%x\n",
825 pm8001_cr32(pm8001_ha, pcibar, offset + 0x8C)));
826 PM8001_INIT_DBG(pm8001_ha,
827 pm8001_printk("PSPA OFFSET 0x%x\n",
828 pm8001_cr32(pm8001_ha, pcibar, offset + 0x90)));
829 PM8001_INIT_DBG(pm8001_ha,
830 pm8001_printk("addr - main cfg %p general status %p\n",
831 pm8001_ha->main_cfg_tbl_addr,
832 pm8001_ha->general_stat_tbl_addr));
833 PM8001_INIT_DBG(pm8001_ha,
834 pm8001_printk("addr - inbnd %p obnd %p\n",
835 pm8001_ha->inbnd_q_tbl_addr,
836 pm8001_ha->outbnd_q_tbl_addr));
837 PM8001_INIT_DBG(pm8001_ha,
838 pm8001_printk("addr - pspa %p ivt %p\n",
839 pm8001_ha->pspa_q_tbl_addr,
840 pm8001_ha->ivt_tbl_addr));
841}
842
843/**
844 * pm80xx_set_thermal_config - support the thermal configuration
845 * @pm8001_ha: our hba card information.
846 */
Sakthivel Ka6cb3d02013-03-19 18:08:40 +0530847int
Sakthivel Kf5860992013-04-17 16:37:02 +0530848pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
849{
850 struct set_ctrl_cfg_req payload;
851 struct inbound_queue_table *circularQ;
852 int rc;
853 u32 tag;
854 u32 opc = OPC_INB_SET_CONTROLLER_CONFIG;
Viswas G842784e2015-08-11 15:06:27 +0530855 u32 page_code;
Sakthivel Kf5860992013-04-17 16:37:02 +0530856
857 memset(&payload, 0, sizeof(struct set_ctrl_cfg_req));
858 rc = pm8001_tag_alloc(pm8001_ha, &tag);
859 if (rc)
860 return -1;
861
862 circularQ = &pm8001_ha->inbnd_q_tbl[0];
863 payload.tag = cpu_to_le32(tag);
Viswas G842784e2015-08-11 15:06:27 +0530864
865 if (IS_SPCV_12G(pm8001_ha->pdev))
866 page_code = THERMAL_PAGE_CODE_7H;
867 else
868 page_code = THERMAL_PAGE_CODE_8H;
869
Sakthivel Kf5860992013-04-17 16:37:02 +0530870 payload.cfg_pg[0] = (THERMAL_LOG_ENABLE << 9) |
Viswas G842784e2015-08-11 15:06:27 +0530871 (THERMAL_ENABLE << 8) | page_code;
Sakthivel Kf5860992013-04-17 16:37:02 +0530872 payload.cfg_pg[1] = (LTEMPHIL << 24) | (RTEMPHIL << 8);
873
874 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
Tomas Henzl5533abc2014-07-09 17:20:49 +0530875 if (rc)
876 pm8001_tag_free(pm8001_ha, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +0530877 return rc;
878
879}
880
881/**
Sakthivel Ka6cb3d02013-03-19 18:08:40 +0530882* pm80xx_set_sas_protocol_timer_config - support the SAS Protocol
883* Timer configuration page
884* @pm8001_ha: our hba card information.
885*/
886static int
887pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
888{
889 struct set_ctrl_cfg_req payload;
890 struct inbound_queue_table *circularQ;
891 SASProtocolTimerConfig_t SASConfigPage;
892 int rc;
893 u32 tag;
894 u32 opc = OPC_INB_SET_CONTROLLER_CONFIG;
895
896 memset(&payload, 0, sizeof(struct set_ctrl_cfg_req));
897 memset(&SASConfigPage, 0, sizeof(SASProtocolTimerConfig_t));
898
899 rc = pm8001_tag_alloc(pm8001_ha, &tag);
900
901 if (rc)
902 return -1;
903
904 circularQ = &pm8001_ha->inbnd_q_tbl[0];
905 payload.tag = cpu_to_le32(tag);
906
907 SASConfigPage.pageCode = SAS_PROTOCOL_TIMER_CONFIG_PAGE;
908 SASConfigPage.MST_MSI = 3 << 15;
909 SASConfigPage.STP_SSP_MCT_TMO = (STP_MCT_TMO << 16) | SSP_MCT_TMO;
910 SASConfigPage.STP_FRM_TMO = (SAS_MAX_OPEN_TIME << 24) |
911 (SMP_MAX_CONN_TIMER << 16) | STP_FRM_TIMER;
912 SASConfigPage.STP_IDLE_TMO = STP_IDLE_TIME;
913
914 if (SASConfigPage.STP_IDLE_TMO > 0x3FFFFFF)
915 SASConfigPage.STP_IDLE_TMO = 0x3FFFFFF;
916
917
918 SASConfigPage.OPNRJT_RTRY_INTVL = (SAS_MFD << 16) |
919 SAS_OPNRJT_RTRY_INTVL;
920 SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO = (SAS_DOPNRJT_RTRY_TMO << 16)
921 | SAS_COPNRJT_RTRY_TMO;
922 SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR = (SAS_DOPNRJT_RTRY_THR << 16)
923 | SAS_COPNRJT_RTRY_THR;
924 SASConfigPage.MAX_AIP = SAS_MAX_AIP;
925
926 PM8001_INIT_DBG(pm8001_ha,
927 pm8001_printk("SASConfigPage.pageCode "
928 "0x%08x\n", SASConfigPage.pageCode));
929 PM8001_INIT_DBG(pm8001_ha,
930 pm8001_printk("SASConfigPage.MST_MSI "
931 " 0x%08x\n", SASConfigPage.MST_MSI));
932 PM8001_INIT_DBG(pm8001_ha,
933 pm8001_printk("SASConfigPage.STP_SSP_MCT_TMO "
934 " 0x%08x\n", SASConfigPage.STP_SSP_MCT_TMO));
935 PM8001_INIT_DBG(pm8001_ha,
936 pm8001_printk("SASConfigPage.STP_FRM_TMO "
937 " 0x%08x\n", SASConfigPage.STP_FRM_TMO));
938 PM8001_INIT_DBG(pm8001_ha,
939 pm8001_printk("SASConfigPage.STP_IDLE_TMO "
940 " 0x%08x\n", SASConfigPage.STP_IDLE_TMO));
941 PM8001_INIT_DBG(pm8001_ha,
942 pm8001_printk("SASConfigPage.OPNRJT_RTRY_INTVL "
943 " 0x%08x\n", SASConfigPage.OPNRJT_RTRY_INTVL));
944 PM8001_INIT_DBG(pm8001_ha,
945 pm8001_printk("SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO "
946 " 0x%08x\n", SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO));
947 PM8001_INIT_DBG(pm8001_ha,
948 pm8001_printk("SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR "
949 " 0x%08x\n", SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR));
950 PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.MAX_AIP "
951 " 0x%08x\n", SASConfigPage.MAX_AIP));
952
953 memcpy(&payload.cfg_pg, &SASConfigPage,
954 sizeof(SASProtocolTimerConfig_t));
955
956 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
Tomas Henzl5533abc2014-07-09 17:20:49 +0530957 if (rc)
958 pm8001_tag_free(pm8001_ha, tag);
Sakthivel Ka6cb3d02013-03-19 18:08:40 +0530959
960 return rc;
961}
962
963/**
Sakthivel Kf5860992013-04-17 16:37:02 +0530964 * pm80xx_get_encrypt_info - Check for encryption
965 * @pm8001_ha: our hba card information.
966 */
967static int
968pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha)
969{
970 u32 scratch3_value;
Rickard Strandqvistda225492014-07-09 17:20:10 +0530971 int ret = -1;
Sakthivel Kf5860992013-04-17 16:37:02 +0530972
973 /* Read encryption status from SCRATCH PAD 3 */
974 scratch3_value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3);
975
976 if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) ==
977 SCRATCH_PAD3_ENC_READY) {
978 if (scratch3_value & SCRATCH_PAD3_XTS_ENABLED)
979 pm8001_ha->encrypt_info.cipher_mode = CIPHER_MODE_XTS;
980 if ((scratch3_value & SCRATCH_PAD3_SM_MASK) ==
981 SCRATCH_PAD3_SMF_ENABLED)
982 pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMF;
983 if ((scratch3_value & SCRATCH_PAD3_SM_MASK) ==
984 SCRATCH_PAD3_SMA_ENABLED)
985 pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMA;
986 if ((scratch3_value & SCRATCH_PAD3_SM_MASK) ==
987 SCRATCH_PAD3_SMB_ENABLED)
988 pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB;
989 pm8001_ha->encrypt_info.status = 0;
990 PM8001_INIT_DBG(pm8001_ha, pm8001_printk(
991 "Encryption: SCRATCH_PAD3_ENC_READY 0x%08X."
992 "Cipher mode 0x%x Sec mode 0x%x status 0x%x\n",
993 scratch3_value, pm8001_ha->encrypt_info.cipher_mode,
994 pm8001_ha->encrypt_info.sec_mode,
995 pm8001_ha->encrypt_info.status));
996 ret = 0;
997 } else if ((scratch3_value & SCRATCH_PAD3_ENC_READY) ==
998 SCRATCH_PAD3_ENC_DISABLED) {
999 PM8001_INIT_DBG(pm8001_ha, pm8001_printk(
1000 "Encryption: SCRATCH_PAD3_ENC_DISABLED 0x%08X\n",
1001 scratch3_value));
1002 pm8001_ha->encrypt_info.status = 0xFFFFFFFF;
1003 pm8001_ha->encrypt_info.cipher_mode = 0;
1004 pm8001_ha->encrypt_info.sec_mode = 0;
Rickard Strandqvistda225492014-07-09 17:20:10 +05301005 ret = 0;
Sakthivel Kf5860992013-04-17 16:37:02 +05301006 } else if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) ==
1007 SCRATCH_PAD3_ENC_DIS_ERR) {
1008 pm8001_ha->encrypt_info.status =
1009 (scratch3_value & SCRATCH_PAD3_ERR_CODE) >> 16;
1010 if (scratch3_value & SCRATCH_PAD3_XTS_ENABLED)
1011 pm8001_ha->encrypt_info.cipher_mode = CIPHER_MODE_XTS;
1012 if ((scratch3_value & SCRATCH_PAD3_SM_MASK) ==
1013 SCRATCH_PAD3_SMF_ENABLED)
1014 pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMF;
1015 if ((scratch3_value & SCRATCH_PAD3_SM_MASK) ==
1016 SCRATCH_PAD3_SMA_ENABLED)
1017 pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMA;
1018 if ((scratch3_value & SCRATCH_PAD3_SM_MASK) ==
1019 SCRATCH_PAD3_SMB_ENABLED)
1020 pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB;
1021 PM8001_INIT_DBG(pm8001_ha, pm8001_printk(
1022 "Encryption: SCRATCH_PAD3_DIS_ERR 0x%08X."
1023 "Cipher mode 0x%x sec mode 0x%x status 0x%x\n",
1024 scratch3_value, pm8001_ha->encrypt_info.cipher_mode,
1025 pm8001_ha->encrypt_info.sec_mode,
1026 pm8001_ha->encrypt_info.status));
Sakthivel Kf5860992013-04-17 16:37:02 +05301027 } else if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) ==
1028 SCRATCH_PAD3_ENC_ENA_ERR) {
1029
1030 pm8001_ha->encrypt_info.status =
1031 (scratch3_value & SCRATCH_PAD3_ERR_CODE) >> 16;
1032 if (scratch3_value & SCRATCH_PAD3_XTS_ENABLED)
1033 pm8001_ha->encrypt_info.cipher_mode = CIPHER_MODE_XTS;
1034 if ((scratch3_value & SCRATCH_PAD3_SM_MASK) ==
1035 SCRATCH_PAD3_SMF_ENABLED)
1036 pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMF;
1037 if ((scratch3_value & SCRATCH_PAD3_SM_MASK) ==
1038 SCRATCH_PAD3_SMA_ENABLED)
1039 pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMA;
1040 if ((scratch3_value & SCRATCH_PAD3_SM_MASK) ==
1041 SCRATCH_PAD3_SMB_ENABLED)
1042 pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB;
1043
1044 PM8001_INIT_DBG(pm8001_ha, pm8001_printk(
1045 "Encryption: SCRATCH_PAD3_ENA_ERR 0x%08X."
1046 "Cipher mode 0x%x sec mode 0x%x status 0x%x\n",
1047 scratch3_value, pm8001_ha->encrypt_info.cipher_mode,
1048 pm8001_ha->encrypt_info.sec_mode,
1049 pm8001_ha->encrypt_info.status));
Sakthivel Kf5860992013-04-17 16:37:02 +05301050 }
1051 return ret;
1052}
1053
1054/**
1055 * pm80xx_encrypt_update - update flash with encryption informtion
1056 * @pm8001_ha: our hba card information.
1057 */
1058static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
1059{
1060 struct kek_mgmt_req payload;
1061 struct inbound_queue_table *circularQ;
1062 int rc;
1063 u32 tag;
1064 u32 opc = OPC_INB_KEK_MANAGEMENT;
1065
1066 memset(&payload, 0, sizeof(struct kek_mgmt_req));
1067 rc = pm8001_tag_alloc(pm8001_ha, &tag);
1068 if (rc)
1069 return -1;
1070
1071 circularQ = &pm8001_ha->inbnd_q_tbl[0];
1072 payload.tag = cpu_to_le32(tag);
1073 /* Currently only one key is used. New KEK index is 1.
1074 * Current KEK index is 1. Store KEK to NVRAM is 1.
1075 */
1076 payload.new_curidx_ksop = ((1 << 24) | (1 << 16) | (1 << 8) |
1077 KEK_MGMT_SUBOP_KEYCARDUPDATE);
1078
1079 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
Tomas Henzl5533abc2014-07-09 17:20:49 +05301080 if (rc)
1081 pm8001_tag_free(pm8001_ha, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +05301082
1083 return rc;
1084}
1085
1086/**
1087 * pm8001_chip_init - the main init function that initialize whole PM8001 chip.
1088 * @pm8001_ha: our hba card information
1089 */
1090static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha)
1091{
1092 int ret;
1093 u8 i = 0;
1094
1095 /* check the firmware status */
1096 if (-1 == check_fw_ready(pm8001_ha)) {
1097 PM8001_FAIL_DBG(pm8001_ha,
1098 pm8001_printk("Firmware is not ready!\n"));
1099 return -EBUSY;
1100 }
1101
1102 /* Initialize pci space address eg: mpi offset */
1103 init_pci_device_addresses(pm8001_ha);
1104 init_default_table_values(pm8001_ha);
1105 read_main_config_table(pm8001_ha);
1106 read_general_status_table(pm8001_ha);
1107 read_inbnd_queue_table(pm8001_ha);
1108 read_outbnd_queue_table(pm8001_ha);
1109 read_phy_attr_table(pm8001_ha);
1110
1111 /* update main config table ,inbound table and outbound table */
1112 update_main_config_table(pm8001_ha);
1113 for (i = 0; i < PM8001_MAX_SPCV_INB_NUM; i++)
1114 update_inbnd_queue_table(pm8001_ha, i);
1115 for (i = 0; i < PM8001_MAX_SPCV_OUTB_NUM; i++)
1116 update_outbnd_queue_table(pm8001_ha, i);
1117
1118 /* notify firmware update finished and check initialization status */
1119 if (0 == mpi_init_check(pm8001_ha)) {
1120 PM8001_INIT_DBG(pm8001_ha,
1121 pm8001_printk("MPI initialize successful!\n"));
1122 } else
1123 return -EBUSY;
1124
Sakthivel Ka6cb3d02013-03-19 18:08:40 +05301125 /* send SAS protocol timer configuration page to FW */
1126 ret = pm80xx_set_sas_protocol_timer_config(pm8001_ha);
Sakthivel Kf5860992013-04-17 16:37:02 +05301127
1128 /* Check for encryption */
1129 if (pm8001_ha->chip->encrypt) {
1130 PM8001_INIT_DBG(pm8001_ha,
1131 pm8001_printk("Checking for encryption\n"));
1132 ret = pm80xx_get_encrypt_info(pm8001_ha);
1133 if (ret == -1) {
1134 PM8001_INIT_DBG(pm8001_ha,
1135 pm8001_printk("Encryption error !!\n"));
1136 if (pm8001_ha->encrypt_info.status == 0x81) {
1137 PM8001_INIT_DBG(pm8001_ha, pm8001_printk(
1138 "Encryption enabled with error."
1139 "Saving encryption key to flash\n"));
1140 pm80xx_encrypt_update(pm8001_ha);
1141 }
1142 }
1143 }
1144 return 0;
1145}
1146
1147static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)
1148{
1149 u32 max_wait_count;
1150 u32 value;
1151 u32 gst_len_mpistate;
1152 init_pci_device_addresses(pm8001_ha);
1153 /* Write bit1=1 to Inbound DoorBell Register to tell the SPC FW the
1154 table is stop */
1155 pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPCv_MSGU_CFG_TABLE_RESET);
1156
1157 /* wait until Inbound DoorBell Clear Register toggled */
Anand Kumar Santhanama9a923e2013-09-03 15:09:42 +05301158 if (IS_SPCV_12G(pm8001_ha->pdev)) {
1159 max_wait_count = 4 * 1000 * 1000;/* 4 sec */
1160 } else {
1161 max_wait_count = 2 * 1000 * 1000;/* 2 sec */
1162 }
Sakthivel Kf5860992013-04-17 16:37:02 +05301163 do {
1164 udelay(1);
1165 value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);
1166 value &= SPCv_MSGU_CFG_TABLE_RESET;
1167 } while ((value != 0) && (--max_wait_count));
1168
1169 if (!max_wait_count) {
1170 PM8001_FAIL_DBG(pm8001_ha,
1171 pm8001_printk("TIMEOUT:IBDB value/=%x\n", value));
1172 return -1;
1173 }
1174
1175 /* check the MPI-State for termination in progress */
1176 /* wait until Inbound DoorBell Clear Register toggled */
1177 max_wait_count = 2 * 1000 * 1000; /* 2 sec for spcv/ve */
1178 do {
1179 udelay(1);
1180 gst_len_mpistate =
1181 pm8001_mr32(pm8001_ha->general_stat_tbl_addr,
1182 GST_GSTLEN_MPIS_OFFSET);
1183 if (GST_MPI_STATE_UNINIT ==
1184 (gst_len_mpistate & GST_MPI_STATE_MASK))
1185 break;
1186 } while (--max_wait_count);
1187 if (!max_wait_count) {
1188 PM8001_FAIL_DBG(pm8001_ha,
1189 pm8001_printk(" TIME OUT MPI State = 0x%x\n",
1190 gst_len_mpistate & GST_MPI_STATE_MASK));
1191 return -1;
1192 }
1193
1194 return 0;
1195}
1196
1197/**
1198 * pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all
1199 * the FW register status to the originated status.
1200 * @pm8001_ha: our hba card information
1201 */
1202
1203static int
1204pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha)
1205{
1206 u32 regval;
1207 u32 bootloader_state;
Anand Kumar Santhanam06f12f222013-09-17 14:32:20 +05301208 u32 ibutton0, ibutton1;
Sakthivel Kf5860992013-04-17 16:37:02 +05301209
1210 /* Check if MPI is in ready state to reset */
1211 if (mpi_uninit_check(pm8001_ha) != 0) {
1212 PM8001_FAIL_DBG(pm8001_ha,
1213 pm8001_printk("MPI state is not ready\n"));
1214 return -1;
1215 }
1216
1217 /* checked for reset register normal state; 0x0 */
1218 regval = pm8001_cr32(pm8001_ha, 0, SPC_REG_SOFT_RESET);
1219 PM8001_INIT_DBG(pm8001_ha,
1220 pm8001_printk("reset register before write : 0x%x\n", regval));
1221
1222 pm8001_cw32(pm8001_ha, 0, SPC_REG_SOFT_RESET, SPCv_NORMAL_RESET_VALUE);
1223 mdelay(500);
1224
1225 regval = pm8001_cr32(pm8001_ha, 0, SPC_REG_SOFT_RESET);
1226 PM8001_INIT_DBG(pm8001_ha,
1227 pm8001_printk("reset register after write 0x%x\n", regval));
1228
1229 if ((regval & SPCv_SOFT_RESET_READ_MASK) ==
1230 SPCv_SOFT_RESET_NORMAL_RESET_OCCURED) {
1231 PM8001_MSG_DBG(pm8001_ha,
1232 pm8001_printk(" soft reset successful [regval: 0x%x]\n",
1233 regval));
1234 } else {
1235 PM8001_MSG_DBG(pm8001_ha,
1236 pm8001_printk(" soft reset failed [regval: 0x%x]\n",
1237 regval));
1238
1239 /* check bootloader is successfully executed or in HDA mode */
1240 bootloader_state =
1241 pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1) &
1242 SCRATCH_PAD1_BOOTSTATE_MASK;
1243
1244 if (bootloader_state == SCRATCH_PAD1_BOOTSTATE_HDA_SEEPROM) {
1245 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
1246 "Bootloader state - HDA mode SEEPROM\n"));
1247 } else if (bootloader_state ==
1248 SCRATCH_PAD1_BOOTSTATE_HDA_BOOTSTRAP) {
1249 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
1250 "Bootloader state - HDA mode Bootstrap Pin\n"));
1251 } else if (bootloader_state ==
1252 SCRATCH_PAD1_BOOTSTATE_HDA_SOFTRESET) {
1253 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
1254 "Bootloader state - HDA mode soft reset\n"));
1255 } else if (bootloader_state ==
1256 SCRATCH_PAD1_BOOTSTATE_CRIT_ERROR) {
1257 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
1258 "Bootloader state-HDA mode critical error\n"));
1259 }
1260 return -EBUSY;
1261 }
1262
1263 /* check the firmware status after reset */
1264 if (-1 == check_fw_ready(pm8001_ha)) {
1265 PM8001_FAIL_DBG(pm8001_ha,
1266 pm8001_printk("Firmware is not ready!\n"));
Anand Kumar Santhanam06f12f222013-09-17 14:32:20 +05301267 /* check iButton feature support for motherboard controller */
1268 if (pm8001_ha->pdev->subsystem_vendor !=
1269 PCI_VENDOR_ID_ADAPTEC2 &&
1270 pm8001_ha->pdev->subsystem_vendor != 0) {
1271 ibutton0 = pm8001_cr32(pm8001_ha, 0,
1272 MSGU_HOST_SCRATCH_PAD_6);
1273 ibutton1 = pm8001_cr32(pm8001_ha, 0,
1274 MSGU_HOST_SCRATCH_PAD_7);
1275 if (!ibutton0 && !ibutton1) {
1276 PM8001_FAIL_DBG(pm8001_ha,
1277 pm8001_printk("iButton Feature is"
1278 " not Available!!!\n"));
1279 return -EBUSY;
1280 }
1281 if (ibutton0 == 0xdeadbeef && ibutton1 == 0xdeadbeef) {
1282 PM8001_FAIL_DBG(pm8001_ha,
1283 pm8001_printk("CRC Check for iButton"
1284 " Feature Failed!!!\n"));
1285 return -EBUSY;
1286 }
1287 }
Sakthivel Kf5860992013-04-17 16:37:02 +05301288 }
1289 PM8001_INIT_DBG(pm8001_ha,
1290 pm8001_printk("SPCv soft reset Complete\n"));
1291 return 0;
1292}
1293
1294static void pm80xx_hw_chip_rst(struct pm8001_hba_info *pm8001_ha)
1295{
1296 u32 i;
1297
1298 PM8001_INIT_DBG(pm8001_ha,
1299 pm8001_printk("chip reset start\n"));
1300
1301 /* do SPCv chip reset. */
1302 pm8001_cw32(pm8001_ha, 0, SPC_REG_SOFT_RESET, 0x11);
1303 PM8001_INIT_DBG(pm8001_ha,
1304 pm8001_printk("SPC soft reset Complete\n"));
1305
1306 /* Check this ..whether delay is required or no */
1307 /* delay 10 usec */
1308 udelay(10);
1309
1310 /* wait for 20 msec until the firmware gets reloaded */
1311 i = 20;
1312 do {
1313 mdelay(1);
1314 } while ((--i) != 0);
1315
1316 PM8001_INIT_DBG(pm8001_ha,
1317 pm8001_printk("chip reset finished\n"));
1318}
1319
1320/**
1321 * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt
1322 * @pm8001_ha: our hba card information
1323 */
1324static void
1325pm80xx_chip_intx_interrupt_enable(struct pm8001_hba_info *pm8001_ha)
1326{
1327 pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, ODMR_CLEAR_ALL);
1328 pm8001_cw32(pm8001_ha, 0, MSGU_ODCR, ODCR_CLEAR_ALL);
1329}
1330
1331/**
1332 * pm8001_chip_intx_interrupt_disable- disable PM8001 chip interrupt
1333 * @pm8001_ha: our hba card information
1334 */
1335static void
1336pm80xx_chip_intx_interrupt_disable(struct pm8001_hba_info *pm8001_ha)
1337{
1338 pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_CLR, ODMR_MASK_ALL);
1339}
1340
1341/**
1342 * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt
1343 * @pm8001_ha: our hba card information
1344 */
1345static void
1346pm80xx_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec)
1347{
1348#ifdef PM8001_USE_MSIX
1349 u32 mask;
1350 mask = (u32)(1 << vec);
1351
1352 pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_CLR, (u32)(mask & 0xFFFFFFFF));
1353 return;
1354#endif
1355 pm80xx_chip_intx_interrupt_enable(pm8001_ha);
1356
1357}
1358
1359/**
1360 * pm8001_chip_interrupt_disable- disable PM8001 chip interrupt
1361 * @pm8001_ha: our hba card information
1362 */
1363static void
1364pm80xx_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec)
1365{
1366#ifdef PM8001_USE_MSIX
1367 u32 mask;
1368 if (vec == 0xFF)
1369 mask = 0xFFFFFFFF;
1370 else
1371 mask = (u32)(1 << vec);
1372 pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, (u32)(mask & 0xFFFFFFFF));
1373 return;
1374#endif
1375 pm80xx_chip_intx_interrupt_disable(pm8001_ha);
1376}
1377
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301378static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
1379 struct pm8001_device *pm8001_ha_dev)
1380{
1381 int res;
1382 u32 ccb_tag;
1383 struct pm8001_ccb_info *ccb;
1384 struct sas_task *task = NULL;
1385 struct task_abort_req task_abort;
1386 struct inbound_queue_table *circularQ;
1387 u32 opc = OPC_INB_SATA_ABORT;
1388 int ret;
1389
1390 if (!pm8001_ha_dev) {
1391 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("dev is null\n"));
1392 return;
1393 }
1394
1395 task = sas_alloc_slow_task(GFP_ATOMIC);
1396
1397 if (!task) {
1398 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("cannot "
1399 "allocate task\n"));
1400 return;
1401 }
1402
1403 task->task_done = pm8001_task_done;
1404
1405 res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
Tomas Henzl5533abc2014-07-09 17:20:49 +05301406 if (res) {
1407 sas_free_task(task);
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301408 return;
Tomas Henzl5533abc2014-07-09 17:20:49 +05301409 }
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301410
1411 ccb = &pm8001_ha->ccb_info[ccb_tag];
1412 ccb->device = pm8001_ha_dev;
1413 ccb->ccb_tag = ccb_tag;
1414 ccb->task = task;
1415
1416 circularQ = &pm8001_ha->inbnd_q_tbl[0];
1417
1418 memset(&task_abort, 0, sizeof(task_abort));
1419 task_abort.abort_all = cpu_to_le32(1);
1420 task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
1421 task_abort.tag = cpu_to_le32(ccb_tag);
1422
1423 ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0);
Tomas Henzl5533abc2014-07-09 17:20:49 +05301424 if (ret) {
1425 sas_free_task(task);
1426 pm8001_tag_free(pm8001_ha, ccb_tag);
1427 }
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301428}
1429
1430static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
1431 struct pm8001_device *pm8001_ha_dev)
1432{
1433 struct sata_start_req sata_cmd;
1434 int res;
1435 u32 ccb_tag;
1436 struct pm8001_ccb_info *ccb;
1437 struct sas_task *task = NULL;
1438 struct host_to_dev_fis fis;
1439 struct domain_device *dev;
1440 struct inbound_queue_table *circularQ;
1441 u32 opc = OPC_INB_SATA_HOST_OPSTART;
1442
1443 task = sas_alloc_slow_task(GFP_ATOMIC);
1444
1445 if (!task) {
1446 PM8001_FAIL_DBG(pm8001_ha,
1447 pm8001_printk("cannot allocate task !!!\n"));
1448 return;
1449 }
1450 task->task_done = pm8001_task_done;
1451
1452 res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
1453 if (res) {
Tomas Henzl5533abc2014-07-09 17:20:49 +05301454 sas_free_task(task);
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301455 PM8001_FAIL_DBG(pm8001_ha,
1456 pm8001_printk("cannot allocate tag !!!\n"));
1457 return;
1458 }
1459
1460 /* allocate domain device by ourselves as libsas
1461 * is not going to provide any
1462 */
1463 dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
1464 if (!dev) {
Tomas Henzl5533abc2014-07-09 17:20:49 +05301465 sas_free_task(task);
1466 pm8001_tag_free(pm8001_ha, ccb_tag);
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301467 PM8001_FAIL_DBG(pm8001_ha,
1468 pm8001_printk("Domain device cannot be allocated\n"));
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301469 return;
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301470 }
1471
Tomas Henzl5533abc2014-07-09 17:20:49 +05301472 task->dev = dev;
1473 task->dev->lldd_dev = pm8001_ha_dev;
1474
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301475 ccb = &pm8001_ha->ccb_info[ccb_tag];
1476 ccb->device = pm8001_ha_dev;
1477 ccb->ccb_tag = ccb_tag;
1478 ccb->task = task;
1479 pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
1480 pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
1481
1482 memset(&sata_cmd, 0, sizeof(sata_cmd));
1483 circularQ = &pm8001_ha->inbnd_q_tbl[0];
1484
1485 /* construct read log FIS */
1486 memset(&fis, 0, sizeof(struct host_to_dev_fis));
1487 fis.fis_type = 0x27;
1488 fis.flags = 0x80;
1489 fis.command = ATA_CMD_READ_LOG_EXT;
1490 fis.lbal = 0x10;
1491 fis.sector_count = 0x1;
1492
1493 sata_cmd.tag = cpu_to_le32(ccb_tag);
1494 sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
1495 sata_cmd.ncqtag_atap_dir_m_dad |= ((0x1 << 7) | (0x5 << 9));
1496 memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
1497
1498 res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0);
Tomas Henzl5533abc2014-07-09 17:20:49 +05301499 if (res) {
1500 sas_free_task(task);
1501 pm8001_tag_free(pm8001_ha, ccb_tag);
1502 kfree(dev);
1503 }
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301504}
1505
Sakthivel Kf5860992013-04-17 16:37:02 +05301506/**
1507 * mpi_ssp_completion- process the event that FW response to the SSP request.
1508 * @pm8001_ha: our hba card information
1509 * @piomb: the message contents of this outbound message.
1510 *
1511 * When FW has completed a ssp request for example a IO request, after it has
1512 * filled the SG data with the data, it will trigger this event represent
1513 * that he has finished the job,please check the coresponding buffer.
1514 * So we will tell the caller who maybe waiting the result to tell upper layer
1515 * that the task has been finished.
1516 */
1517static void
1518mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
1519{
1520 struct sas_task *t;
1521 struct pm8001_ccb_info *ccb;
1522 unsigned long flags;
1523 u32 status;
1524 u32 param;
1525 u32 tag;
1526 struct ssp_completion_resp *psspPayload;
1527 struct task_status_struct *ts;
1528 struct ssp_response_iu *iu;
1529 struct pm8001_device *pm8001_dev;
1530 psspPayload = (struct ssp_completion_resp *)(piomb + 4);
1531 status = le32_to_cpu(psspPayload->status);
1532 tag = le32_to_cpu(psspPayload->tag);
1533 ccb = &pm8001_ha->ccb_info[tag];
1534 if ((status == IO_ABORTED) && ccb->open_retry) {
1535 /* Being completed by another */
1536 ccb->open_retry = 0;
1537 return;
1538 }
1539 pm8001_dev = ccb->device;
1540 param = le32_to_cpu(psspPayload->param);
1541 t = ccb->task;
1542
1543 if (status && status != IO_UNDERFLOW)
1544 PM8001_FAIL_DBG(pm8001_ha,
1545 pm8001_printk("sas IO status 0x%x\n", status));
1546 if (unlikely(!t || !t->lldd_task || !t->dev))
1547 return;
1548 ts = &t->task_status;
Anand Kumar Santhanamcb269c22013-09-17 16:47:21 +05301549 /* Print sas address of IO failed device */
1550 if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) &&
1551 (status != IO_UNDERFLOW))
1552 PM8001_FAIL_DBG(pm8001_ha,
1553 pm8001_printk("SAS Address of IO Failure Drive"
1554 ":%016llx", SAS_ADDR(t->dev->sas_addr)));
1555
Sakthivel Kf5860992013-04-17 16:37:02 +05301556 switch (status) {
1557 case IO_SUCCESS:
1558 PM8001_IO_DBG(pm8001_ha,
1559 pm8001_printk("IO_SUCCESS ,param = 0x%x\n",
1560 param));
1561 if (param == 0) {
1562 ts->resp = SAS_TASK_COMPLETE;
1563 ts->stat = SAM_STAT_GOOD;
1564 } else {
1565 ts->resp = SAS_TASK_COMPLETE;
1566 ts->stat = SAS_PROTO_RESPONSE;
1567 ts->residual = param;
1568 iu = &psspPayload->ssp_resp_iu;
1569 sas_ssp_task_response(pm8001_ha->dev, t, iu);
1570 }
1571 if (pm8001_dev)
1572 pm8001_dev->running_req--;
1573 break;
1574 case IO_ABORTED:
1575 PM8001_IO_DBG(pm8001_ha,
1576 pm8001_printk("IO_ABORTED IOMB Tag\n"));
1577 ts->resp = SAS_TASK_COMPLETE;
1578 ts->stat = SAS_ABORTED_TASK;
1579 break;
1580 case IO_UNDERFLOW:
1581 /* SSP Completion with error */
1582 PM8001_IO_DBG(pm8001_ha,
1583 pm8001_printk("IO_UNDERFLOW ,param = 0x%x\n",
1584 param));
1585 ts->resp = SAS_TASK_COMPLETE;
1586 ts->stat = SAS_DATA_UNDERRUN;
1587 ts->residual = param;
1588 if (pm8001_dev)
1589 pm8001_dev->running_req--;
1590 break;
1591 case IO_NO_DEVICE:
1592 PM8001_IO_DBG(pm8001_ha,
1593 pm8001_printk("IO_NO_DEVICE\n"));
1594 ts->resp = SAS_TASK_UNDELIVERED;
1595 ts->stat = SAS_PHY_DOWN;
1596 break;
1597 case IO_XFER_ERROR_BREAK:
1598 PM8001_IO_DBG(pm8001_ha,
1599 pm8001_printk("IO_XFER_ERROR_BREAK\n"));
1600 ts->resp = SAS_TASK_COMPLETE;
1601 ts->stat = SAS_OPEN_REJECT;
1602 /* Force the midlayer to retry */
1603 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1604 break;
1605 case IO_XFER_ERROR_PHY_NOT_READY:
1606 PM8001_IO_DBG(pm8001_ha,
1607 pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
1608 ts->resp = SAS_TASK_COMPLETE;
1609 ts->stat = SAS_OPEN_REJECT;
1610 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1611 break;
Viswas G27ecfa52015-08-11 15:06:31 +05301612 case IO_XFER_ERROR_INVALID_SSP_RSP_FRAME:
1613 PM8001_IO_DBG(pm8001_ha,
1614 pm8001_printk("IO_XFER_ERROR_INVALID_SSP_RSP_FRAME\n"));
1615 ts->resp = SAS_TASK_COMPLETE;
1616 ts->stat = SAS_OPEN_REJECT;
1617 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1618 break;
Sakthivel Kf5860992013-04-17 16:37:02 +05301619 case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
1620 PM8001_IO_DBG(pm8001_ha,
1621 pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"));
1622 ts->resp = SAS_TASK_COMPLETE;
1623 ts->stat = SAS_OPEN_REJECT;
1624 ts->open_rej_reason = SAS_OREJ_EPROTO;
1625 break;
1626 case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
1627 PM8001_IO_DBG(pm8001_ha,
1628 pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
1629 ts->resp = SAS_TASK_COMPLETE;
1630 ts->stat = SAS_OPEN_REJECT;
1631 ts->open_rej_reason = SAS_OREJ_UNKNOWN;
1632 break;
1633 case IO_OPEN_CNX_ERROR_BREAK:
1634 PM8001_IO_DBG(pm8001_ha,
1635 pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n"));
1636 ts->resp = SAS_TASK_COMPLETE;
1637 ts->stat = SAS_OPEN_REJECT;
1638 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1639 break;
1640 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
Sakthivel Ka6cb3d02013-03-19 18:08:40 +05301641 case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
1642 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
1643 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
1644 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
1645 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
Sakthivel Kf5860992013-04-17 16:37:02 +05301646 PM8001_IO_DBG(pm8001_ha,
1647 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
1648 ts->resp = SAS_TASK_COMPLETE;
1649 ts->stat = SAS_OPEN_REJECT;
1650 ts->open_rej_reason = SAS_OREJ_UNKNOWN;
1651 if (!t->uldd_task)
1652 pm8001_handle_event(pm8001_ha,
1653 pm8001_dev,
1654 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
1655 break;
1656 case IO_OPEN_CNX_ERROR_BAD_DESTINATION:
1657 PM8001_IO_DBG(pm8001_ha,
1658 pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"));
1659 ts->resp = SAS_TASK_COMPLETE;
1660 ts->stat = SAS_OPEN_REJECT;
1661 ts->open_rej_reason = SAS_OREJ_BAD_DEST;
1662 break;
1663 case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
1664 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
1665 "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
1666 ts->resp = SAS_TASK_COMPLETE;
1667 ts->stat = SAS_OPEN_REJECT;
1668 ts->open_rej_reason = SAS_OREJ_CONN_RATE;
1669 break;
1670 case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:
1671 PM8001_IO_DBG(pm8001_ha,
1672 pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"));
1673 ts->resp = SAS_TASK_UNDELIVERED;
1674 ts->stat = SAS_OPEN_REJECT;
1675 ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
1676 break;
1677 case IO_XFER_ERROR_NAK_RECEIVED:
1678 PM8001_IO_DBG(pm8001_ha,
1679 pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n"));
1680 ts->resp = SAS_TASK_COMPLETE;
1681 ts->stat = SAS_OPEN_REJECT;
1682 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1683 break;
1684 case IO_XFER_ERROR_ACK_NAK_TIMEOUT:
1685 PM8001_IO_DBG(pm8001_ha,
1686 pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"));
1687 ts->resp = SAS_TASK_COMPLETE;
1688 ts->stat = SAS_NAK_R_ERR;
1689 break;
1690 case IO_XFER_ERROR_DMA:
1691 PM8001_IO_DBG(pm8001_ha,
1692 pm8001_printk("IO_XFER_ERROR_DMA\n"));
1693 ts->resp = SAS_TASK_COMPLETE;
1694 ts->stat = SAS_OPEN_REJECT;
1695 break;
1696 case IO_XFER_OPEN_RETRY_TIMEOUT:
1697 PM8001_IO_DBG(pm8001_ha,
1698 pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
1699 ts->resp = SAS_TASK_COMPLETE;
1700 ts->stat = SAS_OPEN_REJECT;
1701 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1702 break;
1703 case IO_XFER_ERROR_OFFSET_MISMATCH:
1704 PM8001_IO_DBG(pm8001_ha,
1705 pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n"));
1706 ts->resp = SAS_TASK_COMPLETE;
1707 ts->stat = SAS_OPEN_REJECT;
1708 break;
1709 case IO_PORT_IN_RESET:
1710 PM8001_IO_DBG(pm8001_ha,
1711 pm8001_printk("IO_PORT_IN_RESET\n"));
1712 ts->resp = SAS_TASK_COMPLETE;
1713 ts->stat = SAS_OPEN_REJECT;
1714 break;
1715 case IO_DS_NON_OPERATIONAL:
1716 PM8001_IO_DBG(pm8001_ha,
1717 pm8001_printk("IO_DS_NON_OPERATIONAL\n"));
1718 ts->resp = SAS_TASK_COMPLETE;
1719 ts->stat = SAS_OPEN_REJECT;
1720 if (!t->uldd_task)
1721 pm8001_handle_event(pm8001_ha,
1722 pm8001_dev,
1723 IO_DS_NON_OPERATIONAL);
1724 break;
1725 case IO_DS_IN_RECOVERY:
1726 PM8001_IO_DBG(pm8001_ha,
1727 pm8001_printk("IO_DS_IN_RECOVERY\n"));
1728 ts->resp = SAS_TASK_COMPLETE;
1729 ts->stat = SAS_OPEN_REJECT;
1730 break;
1731 case IO_TM_TAG_NOT_FOUND:
1732 PM8001_IO_DBG(pm8001_ha,
1733 pm8001_printk("IO_TM_TAG_NOT_FOUND\n"));
1734 ts->resp = SAS_TASK_COMPLETE;
1735 ts->stat = SAS_OPEN_REJECT;
1736 break;
1737 case IO_SSP_EXT_IU_ZERO_LEN_ERROR:
1738 PM8001_IO_DBG(pm8001_ha,
1739 pm8001_printk("IO_SSP_EXT_IU_ZERO_LEN_ERROR\n"));
1740 ts->resp = SAS_TASK_COMPLETE;
1741 ts->stat = SAS_OPEN_REJECT;
1742 break;
1743 case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY:
1744 PM8001_IO_DBG(pm8001_ha,
1745 pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"));
1746 ts->resp = SAS_TASK_COMPLETE;
1747 ts->stat = SAS_OPEN_REJECT;
1748 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1749 break;
1750 default:
1751 PM8001_IO_DBG(pm8001_ha,
1752 pm8001_printk("Unknown status 0x%x\n", status));
1753 /* not allowed case. Therefore, return failed status */
1754 ts->resp = SAS_TASK_COMPLETE;
1755 ts->stat = SAS_OPEN_REJECT;
1756 break;
1757 }
1758 PM8001_IO_DBG(pm8001_ha,
1759 pm8001_printk("scsi_status = 0x%x\n ",
1760 psspPayload->ssp_resp_iu.status));
1761 spin_lock_irqsave(&t->task_state_lock, flags);
1762 t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
1763 t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
1764 t->task_state_flags |= SAS_TASK_STATE_DONE;
1765 if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
1766 spin_unlock_irqrestore(&t->task_state_lock, flags);
1767 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
1768 "task 0x%p done with io_status 0x%x resp 0x%x "
1769 "stat 0x%x but aborted by upper layer!\n",
1770 t, status, ts->resp, ts->stat));
1771 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
1772 } else {
1773 spin_unlock_irqrestore(&t->task_state_lock, flags);
1774 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
1775 mb();/* in order to force CPU ordering */
1776 t->task_done(t);
1777 }
1778}
1779
1780/*See the comments for mpi_ssp_completion */
1781static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
1782{
1783 struct sas_task *t;
1784 unsigned long flags;
1785 struct task_status_struct *ts;
1786 struct pm8001_ccb_info *ccb;
1787 struct pm8001_device *pm8001_dev;
1788 struct ssp_event_resp *psspPayload =
1789 (struct ssp_event_resp *)(piomb + 4);
1790 u32 event = le32_to_cpu(psspPayload->event);
1791 u32 tag = le32_to_cpu(psspPayload->tag);
1792 u32 port_id = le32_to_cpu(psspPayload->port_id);
1793
1794 ccb = &pm8001_ha->ccb_info[tag];
1795 t = ccb->task;
1796 pm8001_dev = ccb->device;
1797 if (event)
1798 PM8001_FAIL_DBG(pm8001_ha,
1799 pm8001_printk("sas IO status 0x%x\n", event));
1800 if (unlikely(!t || !t->lldd_task || !t->dev))
1801 return;
1802 ts = &t->task_status;
1803 PM8001_IO_DBG(pm8001_ha,
1804 pm8001_printk("port_id:0x%x, tag:0x%x, event:0x%x\n",
1805 port_id, tag, event));
1806 switch (event) {
1807 case IO_OVERFLOW:
1808 PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n");)
1809 ts->resp = SAS_TASK_COMPLETE;
1810 ts->stat = SAS_DATA_OVERRUN;
1811 ts->residual = 0;
1812 if (pm8001_dev)
1813 pm8001_dev->running_req--;
1814 break;
1815 case IO_XFER_ERROR_BREAK:
1816 PM8001_IO_DBG(pm8001_ha,
1817 pm8001_printk("IO_XFER_ERROR_BREAK\n"));
1818 pm8001_handle_event(pm8001_ha, t, IO_XFER_ERROR_BREAK);
1819 return;
1820 case IO_XFER_ERROR_PHY_NOT_READY:
1821 PM8001_IO_DBG(pm8001_ha,
1822 pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
1823 ts->resp = SAS_TASK_COMPLETE;
1824 ts->stat = SAS_OPEN_REJECT;
1825 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1826 break;
1827 case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
1828 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
1829 "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"));
1830 ts->resp = SAS_TASK_COMPLETE;
1831 ts->stat = SAS_OPEN_REJECT;
1832 ts->open_rej_reason = SAS_OREJ_EPROTO;
1833 break;
1834 case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
1835 PM8001_IO_DBG(pm8001_ha,
1836 pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
1837 ts->resp = SAS_TASK_COMPLETE;
1838 ts->stat = SAS_OPEN_REJECT;
1839 ts->open_rej_reason = SAS_OREJ_UNKNOWN;
1840 break;
1841 case IO_OPEN_CNX_ERROR_BREAK:
1842 PM8001_IO_DBG(pm8001_ha,
1843 pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n"));
1844 ts->resp = SAS_TASK_COMPLETE;
1845 ts->stat = SAS_OPEN_REJECT;
1846 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1847 break;
1848 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
Sakthivel Ka6cb3d02013-03-19 18:08:40 +05301849 case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
1850 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
1851 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
1852 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
1853 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
Sakthivel Kf5860992013-04-17 16:37:02 +05301854 PM8001_IO_DBG(pm8001_ha,
1855 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
1856 ts->resp = SAS_TASK_COMPLETE;
1857 ts->stat = SAS_OPEN_REJECT;
1858 ts->open_rej_reason = SAS_OREJ_UNKNOWN;
1859 if (!t->uldd_task)
1860 pm8001_handle_event(pm8001_ha,
1861 pm8001_dev,
1862 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
1863 break;
1864 case IO_OPEN_CNX_ERROR_BAD_DESTINATION:
1865 PM8001_IO_DBG(pm8001_ha,
1866 pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"));
1867 ts->resp = SAS_TASK_COMPLETE;
1868 ts->stat = SAS_OPEN_REJECT;
1869 ts->open_rej_reason = SAS_OREJ_BAD_DEST;
1870 break;
1871 case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
1872 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
1873 "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
1874 ts->resp = SAS_TASK_COMPLETE;
1875 ts->stat = SAS_OPEN_REJECT;
1876 ts->open_rej_reason = SAS_OREJ_CONN_RATE;
1877 break;
1878 case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:
1879 PM8001_IO_DBG(pm8001_ha,
1880 pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"));
1881 ts->resp = SAS_TASK_COMPLETE;
1882 ts->stat = SAS_OPEN_REJECT;
1883 ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
1884 break;
1885 case IO_XFER_ERROR_NAK_RECEIVED:
1886 PM8001_IO_DBG(pm8001_ha,
1887 pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n"));
1888 ts->resp = SAS_TASK_COMPLETE;
1889 ts->stat = SAS_OPEN_REJECT;
1890 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1891 break;
1892 case IO_XFER_ERROR_ACK_NAK_TIMEOUT:
1893 PM8001_IO_DBG(pm8001_ha,
1894 pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"));
1895 ts->resp = SAS_TASK_COMPLETE;
1896 ts->stat = SAS_NAK_R_ERR;
1897 break;
1898 case IO_XFER_OPEN_RETRY_TIMEOUT:
1899 PM8001_IO_DBG(pm8001_ha,
1900 pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
1901 pm8001_handle_event(pm8001_ha, t, IO_XFER_OPEN_RETRY_TIMEOUT);
1902 return;
1903 case IO_XFER_ERROR_UNEXPECTED_PHASE:
1904 PM8001_IO_DBG(pm8001_ha,
1905 pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n"));
1906 ts->resp = SAS_TASK_COMPLETE;
1907 ts->stat = SAS_DATA_OVERRUN;
1908 break;
1909 case IO_XFER_ERROR_XFER_RDY_OVERRUN:
1910 PM8001_IO_DBG(pm8001_ha,
1911 pm8001_printk("IO_XFER_ERROR_XFER_RDY_OVERRUN\n"));
1912 ts->resp = SAS_TASK_COMPLETE;
1913 ts->stat = SAS_DATA_OVERRUN;
1914 break;
1915 case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED:
1916 PM8001_IO_DBG(pm8001_ha,
1917 pm8001_printk("IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n"));
1918 ts->resp = SAS_TASK_COMPLETE;
1919 ts->stat = SAS_DATA_OVERRUN;
1920 break;
1921 case IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT:
1922 PM8001_IO_DBG(pm8001_ha,
1923 pm8001_printk("IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT\n"));
1924 ts->resp = SAS_TASK_COMPLETE;
1925 ts->stat = SAS_DATA_OVERRUN;
1926 break;
1927 case IO_XFER_ERROR_OFFSET_MISMATCH:
1928 PM8001_IO_DBG(pm8001_ha,
1929 pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n"));
1930 ts->resp = SAS_TASK_COMPLETE;
1931 ts->stat = SAS_DATA_OVERRUN;
1932 break;
1933 case IO_XFER_ERROR_XFER_ZERO_DATA_LEN:
1934 PM8001_IO_DBG(pm8001_ha,
1935 pm8001_printk("IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n"));
1936 ts->resp = SAS_TASK_COMPLETE;
1937 ts->stat = SAS_DATA_OVERRUN;
1938 break;
Sakthivel Ka6cb3d02013-03-19 18:08:40 +05301939 case IO_XFER_ERROR_INTERNAL_CRC_ERROR:
1940 PM8001_IO_DBG(pm8001_ha,
1941 pm8001_printk("IO_XFR_ERROR_INTERNAL_CRC_ERROR\n"));
1942 /* TBC: used default set values */
1943 ts->resp = SAS_TASK_COMPLETE;
1944 ts->stat = SAS_DATA_OVERRUN;
1945 break;
Sakthivel Kf5860992013-04-17 16:37:02 +05301946 case IO_XFER_CMD_FRAME_ISSUED:
1947 PM8001_IO_DBG(pm8001_ha,
1948 pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n"));
1949 return;
1950 default:
1951 PM8001_IO_DBG(pm8001_ha,
1952 pm8001_printk("Unknown status 0x%x\n", event));
1953 /* not allowed case. Therefore, return failed status */
1954 ts->resp = SAS_TASK_COMPLETE;
1955 ts->stat = SAS_DATA_OVERRUN;
1956 break;
1957 }
1958 spin_lock_irqsave(&t->task_state_lock, flags);
1959 t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
1960 t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
1961 t->task_state_flags |= SAS_TASK_STATE_DONE;
1962 if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
1963 spin_unlock_irqrestore(&t->task_state_lock, flags);
1964 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
1965 "task 0x%p done with event 0x%x resp 0x%x "
1966 "stat 0x%x but aborted by upper layer!\n",
1967 t, event, ts->resp, ts->stat));
1968 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
1969 } else {
1970 spin_unlock_irqrestore(&t->task_state_lock, flags);
1971 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
1972 mb();/* in order to force CPU ordering */
1973 t->task_done(t);
1974 }
1975}
1976
1977/*See the comments for mpi_ssp_completion */
1978static void
1979mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
1980{
1981 struct sas_task *t;
1982 struct pm8001_ccb_info *ccb;
1983 u32 param;
1984 u32 status;
1985 u32 tag;
Anand Kumar Santhanamcb269c22013-09-17 16:47:21 +05301986 int i, j;
1987 u8 sata_addr_low[4];
1988 u32 temp_sata_addr_low, temp_sata_addr_hi;
1989 u8 sata_addr_hi[4];
Sakthivel Kf5860992013-04-17 16:37:02 +05301990 struct sata_completion_resp *psataPayload;
1991 struct task_status_struct *ts;
1992 struct ata_task_resp *resp ;
1993 u32 *sata_resp;
1994 struct pm8001_device *pm8001_dev;
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05301995 unsigned long flags;
Sakthivel Kf5860992013-04-17 16:37:02 +05301996
1997 psataPayload = (struct sata_completion_resp *)(piomb + 4);
1998 status = le32_to_cpu(psataPayload->status);
1999 tag = le32_to_cpu(psataPayload->tag);
2000
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05302001 if (!tag) {
2002 PM8001_FAIL_DBG(pm8001_ha,
2003 pm8001_printk("tag null\n"));
2004 return;
2005 }
Sakthivel Kf5860992013-04-17 16:37:02 +05302006 ccb = &pm8001_ha->ccb_info[tag];
2007 param = le32_to_cpu(psataPayload->param);
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05302008 if (ccb) {
2009 t = ccb->task;
2010 pm8001_dev = ccb->device;
2011 } else {
Sakthivel Kf5860992013-04-17 16:37:02 +05302012 PM8001_FAIL_DBG(pm8001_ha,
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05302013 pm8001_printk("ccb null\n"));
Sakthivel Kf5860992013-04-17 16:37:02 +05302014 return;
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05302015 }
2016
2017 if (t) {
2018 if (t->dev && (t->dev->lldd_dev))
2019 pm8001_dev = t->dev->lldd_dev;
2020 } else {
2021 PM8001_FAIL_DBG(pm8001_ha,
2022 pm8001_printk("task null\n"));
2023 return;
2024 }
2025
2026 if ((pm8001_dev && !(pm8001_dev->id & NCQ_READ_LOG_FLAG))
2027 && unlikely(!t || !t->lldd_task || !t->dev)) {
2028 PM8001_FAIL_DBG(pm8001_ha,
2029 pm8001_printk("task or dev null\n"));
2030 return;
2031 }
2032
2033 ts = &t->task_status;
2034 if (!ts) {
2035 PM8001_FAIL_DBG(pm8001_ha,
2036 pm8001_printk("ts null\n"));
2037 return;
2038 }
Anand Kumar Santhanamcb269c22013-09-17 16:47:21 +05302039 /* Print sas address of IO failed device */
2040 if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) &&
2041 (status != IO_UNDERFLOW)) {
2042 if (!((t->dev->parent) &&
2043 (DEV_IS_EXPANDER(t->dev->parent->dev_type)))) {
2044 for (i = 0 , j = 4; i <= 3 && j <= 7; i++ , j++)
2045 sata_addr_low[i] = pm8001_ha->sas_addr[j];
2046 for (i = 0 , j = 0; i <= 3 && j <= 3; i++ , j++)
2047 sata_addr_hi[i] = pm8001_ha->sas_addr[j];
2048 memcpy(&temp_sata_addr_low, sata_addr_low,
2049 sizeof(sata_addr_low));
2050 memcpy(&temp_sata_addr_hi, sata_addr_hi,
2051 sizeof(sata_addr_hi));
2052 temp_sata_addr_hi = (((temp_sata_addr_hi >> 24) & 0xff)
2053 |((temp_sata_addr_hi << 8) &
2054 0xff0000) |
2055 ((temp_sata_addr_hi >> 8)
2056 & 0xff00) |
2057 ((temp_sata_addr_hi << 24) &
2058 0xff000000));
2059 temp_sata_addr_low = ((((temp_sata_addr_low >> 24)
2060 & 0xff) |
2061 ((temp_sata_addr_low << 8)
2062 & 0xff0000) |
2063 ((temp_sata_addr_low >> 8)
2064 & 0xff00) |
2065 ((temp_sata_addr_low << 24)
2066 & 0xff000000)) +
2067 pm8001_dev->attached_phy +
2068 0x10);
2069 PM8001_FAIL_DBG(pm8001_ha,
2070 pm8001_printk("SAS Address of IO Failure Drive:"
2071 "%08x%08x", temp_sata_addr_hi,
2072 temp_sata_addr_low));
Sakthivel Kf5860992013-04-17 16:37:02 +05302073
Anand Kumar Santhanamcb269c22013-09-17 16:47:21 +05302074 } else {
2075 PM8001_FAIL_DBG(pm8001_ha,
2076 pm8001_printk("SAS Address of IO Failure Drive:"
2077 "%016llx", SAS_ADDR(t->dev->sas_addr)));
2078 }
2079 }
Sakthivel Kf5860992013-04-17 16:37:02 +05302080 switch (status) {
2081 case IO_SUCCESS:
2082 PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n"));
2083 if (param == 0) {
2084 ts->resp = SAS_TASK_COMPLETE;
2085 ts->stat = SAM_STAT_GOOD;
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05302086 /* check if response is for SEND READ LOG */
2087 if (pm8001_dev &&
2088 (pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
2089 /* set new bit for abort_all */
2090 pm8001_dev->id |= NCQ_ABORT_ALL_FLAG;
2091 /* clear bit for read log */
2092 pm8001_dev->id = pm8001_dev->id & 0x7FFFFFFF;
2093 pm80xx_send_abort_all(pm8001_ha, pm8001_dev);
2094 /* Free the tag */
2095 pm8001_tag_free(pm8001_ha, tag);
2096 sas_free_task(t);
2097 return;
2098 }
Sakthivel Kf5860992013-04-17 16:37:02 +05302099 } else {
2100 u8 len;
2101 ts->resp = SAS_TASK_COMPLETE;
2102 ts->stat = SAS_PROTO_RESPONSE;
2103 ts->residual = param;
2104 PM8001_IO_DBG(pm8001_ha,
2105 pm8001_printk("SAS_PROTO_RESPONSE len = %d\n",
2106 param));
2107 sata_resp = &psataPayload->sata_resp[0];
2108 resp = (struct ata_task_resp *)ts->buf;
2109 if (t->ata_task.dma_xfer == 0 &&
2110 t->data_dir == PCI_DMA_FROMDEVICE) {
2111 len = sizeof(struct pio_setup_fis);
2112 PM8001_IO_DBG(pm8001_ha,
2113 pm8001_printk("PIO read len = %d\n", len));
2114 } else if (t->ata_task.use_ncq) {
2115 len = sizeof(struct set_dev_bits_fis);
2116 PM8001_IO_DBG(pm8001_ha,
2117 pm8001_printk("FPDMA len = %d\n", len));
2118 } else {
2119 len = sizeof(struct dev_to_host_fis);
2120 PM8001_IO_DBG(pm8001_ha,
2121 pm8001_printk("other len = %d\n", len));
2122 }
2123 if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) {
2124 resp->frame_len = len;
2125 memcpy(&resp->ending_fis[0], sata_resp, len);
2126 ts->buf_valid_size = sizeof(*resp);
2127 } else
2128 PM8001_IO_DBG(pm8001_ha,
2129 pm8001_printk("response to large\n"));
2130 }
2131 if (pm8001_dev)
2132 pm8001_dev->running_req--;
2133 break;
2134 case IO_ABORTED:
2135 PM8001_IO_DBG(pm8001_ha,
2136 pm8001_printk("IO_ABORTED IOMB Tag\n"));
2137 ts->resp = SAS_TASK_COMPLETE;
2138 ts->stat = SAS_ABORTED_TASK;
2139 if (pm8001_dev)
2140 pm8001_dev->running_req--;
2141 break;
2142 /* following cases are to do cases */
2143 case IO_UNDERFLOW:
2144 /* SATA Completion with error */
2145 PM8001_IO_DBG(pm8001_ha,
2146 pm8001_printk("IO_UNDERFLOW param = %d\n", param));
2147 ts->resp = SAS_TASK_COMPLETE;
2148 ts->stat = SAS_DATA_UNDERRUN;
2149 ts->residual = param;
2150 if (pm8001_dev)
2151 pm8001_dev->running_req--;
2152 break;
2153 case IO_NO_DEVICE:
2154 PM8001_IO_DBG(pm8001_ha,
2155 pm8001_printk("IO_NO_DEVICE\n"));
2156 ts->resp = SAS_TASK_UNDELIVERED;
2157 ts->stat = SAS_PHY_DOWN;
2158 break;
2159 case IO_XFER_ERROR_BREAK:
2160 PM8001_IO_DBG(pm8001_ha,
2161 pm8001_printk("IO_XFER_ERROR_BREAK\n"));
2162 ts->resp = SAS_TASK_COMPLETE;
2163 ts->stat = SAS_INTERRUPTED;
2164 break;
2165 case IO_XFER_ERROR_PHY_NOT_READY:
2166 PM8001_IO_DBG(pm8001_ha,
2167 pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
2168 ts->resp = SAS_TASK_COMPLETE;
2169 ts->stat = SAS_OPEN_REJECT;
2170 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
2171 break;
2172 case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
2173 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
2174 "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"));
2175 ts->resp = SAS_TASK_COMPLETE;
2176 ts->stat = SAS_OPEN_REJECT;
2177 ts->open_rej_reason = SAS_OREJ_EPROTO;
2178 break;
2179 case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
2180 PM8001_IO_DBG(pm8001_ha,
2181 pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
2182 ts->resp = SAS_TASK_COMPLETE;
2183 ts->stat = SAS_OPEN_REJECT;
2184 ts->open_rej_reason = SAS_OREJ_UNKNOWN;
2185 break;
2186 case IO_OPEN_CNX_ERROR_BREAK:
2187 PM8001_IO_DBG(pm8001_ha,
2188 pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n"));
2189 ts->resp = SAS_TASK_COMPLETE;
2190 ts->stat = SAS_OPEN_REJECT;
2191 ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;
2192 break;
2193 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
Sakthivel Ka6cb3d02013-03-19 18:08:40 +05302194 case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
2195 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
2196 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
2197 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
2198 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
Sakthivel Kf5860992013-04-17 16:37:02 +05302199 PM8001_IO_DBG(pm8001_ha,
2200 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
2201 ts->resp = SAS_TASK_COMPLETE;
2202 ts->stat = SAS_DEV_NO_RESPONSE;
2203 if (!t->uldd_task) {
2204 pm8001_handle_event(pm8001_ha,
2205 pm8001_dev,
2206 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
2207 ts->resp = SAS_TASK_UNDELIVERED;
2208 ts->stat = SAS_QUEUE_FULL;
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05302209 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +05302210 return;
2211 }
2212 break;
2213 case IO_OPEN_CNX_ERROR_BAD_DESTINATION:
2214 PM8001_IO_DBG(pm8001_ha,
2215 pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"));
2216 ts->resp = SAS_TASK_UNDELIVERED;
2217 ts->stat = SAS_OPEN_REJECT;
2218 ts->open_rej_reason = SAS_OREJ_BAD_DEST;
2219 if (!t->uldd_task) {
2220 pm8001_handle_event(pm8001_ha,
2221 pm8001_dev,
2222 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
2223 ts->resp = SAS_TASK_UNDELIVERED;
2224 ts->stat = SAS_QUEUE_FULL;
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05302225 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +05302226 return;
2227 }
2228 break;
2229 case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
2230 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
2231 "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
2232 ts->resp = SAS_TASK_COMPLETE;
2233 ts->stat = SAS_OPEN_REJECT;
2234 ts->open_rej_reason = SAS_OREJ_CONN_RATE;
2235 break;
2236 case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
2237 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
2238 "IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY\n"));
2239 ts->resp = SAS_TASK_COMPLETE;
2240 ts->stat = SAS_DEV_NO_RESPONSE;
2241 if (!t->uldd_task) {
2242 pm8001_handle_event(pm8001_ha,
2243 pm8001_dev,
2244 IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY);
2245 ts->resp = SAS_TASK_UNDELIVERED;
2246 ts->stat = SAS_QUEUE_FULL;
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05302247 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +05302248 return;
2249 }
2250 break;
2251 case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:
2252 PM8001_IO_DBG(pm8001_ha,
2253 pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"));
2254 ts->resp = SAS_TASK_COMPLETE;
2255 ts->stat = SAS_OPEN_REJECT;
2256 ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
2257 break;
2258 case IO_XFER_ERROR_NAK_RECEIVED:
2259 PM8001_IO_DBG(pm8001_ha,
2260 pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n"));
2261 ts->resp = SAS_TASK_COMPLETE;
2262 ts->stat = SAS_NAK_R_ERR;
2263 break;
2264 case IO_XFER_ERROR_ACK_NAK_TIMEOUT:
2265 PM8001_IO_DBG(pm8001_ha,
2266 pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"));
2267 ts->resp = SAS_TASK_COMPLETE;
2268 ts->stat = SAS_NAK_R_ERR;
2269 break;
2270 case IO_XFER_ERROR_DMA:
2271 PM8001_IO_DBG(pm8001_ha,
2272 pm8001_printk("IO_XFER_ERROR_DMA\n"));
2273 ts->resp = SAS_TASK_COMPLETE;
2274 ts->stat = SAS_ABORTED_TASK;
2275 break;
2276 case IO_XFER_ERROR_SATA_LINK_TIMEOUT:
2277 PM8001_IO_DBG(pm8001_ha,
2278 pm8001_printk("IO_XFER_ERROR_SATA_LINK_TIMEOUT\n"));
2279 ts->resp = SAS_TASK_UNDELIVERED;
2280 ts->stat = SAS_DEV_NO_RESPONSE;
2281 break;
2282 case IO_XFER_ERROR_REJECTED_NCQ_MODE:
2283 PM8001_IO_DBG(pm8001_ha,
2284 pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n"));
2285 ts->resp = SAS_TASK_COMPLETE;
2286 ts->stat = SAS_DATA_UNDERRUN;
2287 break;
2288 case IO_XFER_OPEN_RETRY_TIMEOUT:
2289 PM8001_IO_DBG(pm8001_ha,
2290 pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
2291 ts->resp = SAS_TASK_COMPLETE;
2292 ts->stat = SAS_OPEN_TO;
2293 break;
2294 case IO_PORT_IN_RESET:
2295 PM8001_IO_DBG(pm8001_ha,
2296 pm8001_printk("IO_PORT_IN_RESET\n"));
2297 ts->resp = SAS_TASK_COMPLETE;
2298 ts->stat = SAS_DEV_NO_RESPONSE;
2299 break;
2300 case IO_DS_NON_OPERATIONAL:
2301 PM8001_IO_DBG(pm8001_ha,
2302 pm8001_printk("IO_DS_NON_OPERATIONAL\n"));
2303 ts->resp = SAS_TASK_COMPLETE;
2304 ts->stat = SAS_DEV_NO_RESPONSE;
2305 if (!t->uldd_task) {
2306 pm8001_handle_event(pm8001_ha, pm8001_dev,
2307 IO_DS_NON_OPERATIONAL);
2308 ts->resp = SAS_TASK_UNDELIVERED;
2309 ts->stat = SAS_QUEUE_FULL;
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05302310 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +05302311 return;
2312 }
2313 break;
2314 case IO_DS_IN_RECOVERY:
2315 PM8001_IO_DBG(pm8001_ha,
2316 pm8001_printk("IO_DS_IN_RECOVERY\n"));
2317 ts->resp = SAS_TASK_COMPLETE;
2318 ts->stat = SAS_DEV_NO_RESPONSE;
2319 break;
2320 case IO_DS_IN_ERROR:
2321 PM8001_IO_DBG(pm8001_ha,
2322 pm8001_printk("IO_DS_IN_ERROR\n"));
2323 ts->resp = SAS_TASK_COMPLETE;
2324 ts->stat = SAS_DEV_NO_RESPONSE;
2325 if (!t->uldd_task) {
2326 pm8001_handle_event(pm8001_ha, pm8001_dev,
2327 IO_DS_IN_ERROR);
2328 ts->resp = SAS_TASK_UNDELIVERED;
2329 ts->stat = SAS_QUEUE_FULL;
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05302330 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +05302331 return;
2332 }
2333 break;
2334 case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY:
2335 PM8001_IO_DBG(pm8001_ha,
2336 pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"));
2337 ts->resp = SAS_TASK_COMPLETE;
2338 ts->stat = SAS_OPEN_REJECT;
2339 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
2340 default:
2341 PM8001_IO_DBG(pm8001_ha,
2342 pm8001_printk("Unknown status 0x%x\n", status));
2343 /* not allowed case. Therefore, return failed status */
2344 ts->resp = SAS_TASK_COMPLETE;
2345 ts->stat = SAS_DEV_NO_RESPONSE;
2346 break;
2347 }
2348 spin_lock_irqsave(&t->task_state_lock, flags);
2349 t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
2350 t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
2351 t->task_state_flags |= SAS_TASK_STATE_DONE;
2352 if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
2353 spin_unlock_irqrestore(&t->task_state_lock, flags);
2354 PM8001_FAIL_DBG(pm8001_ha,
2355 pm8001_printk("task 0x%p done with io_status 0x%x"
2356 " resp 0x%x stat 0x%x but aborted by upper layer!\n",
2357 t, status, ts->resp, ts->stat));
2358 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05302359 } else {
Sakthivel Kf5860992013-04-17 16:37:02 +05302360 spin_unlock_irqrestore(&t->task_state_lock, flags);
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05302361 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +05302362 }
2363}
2364
2365/*See the comments for mpi_ssp_completion */
2366static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2367{
2368 struct sas_task *t;
2369 struct task_status_struct *ts;
2370 struct pm8001_ccb_info *ccb;
2371 struct pm8001_device *pm8001_dev;
2372 struct sata_event_resp *psataPayload =
2373 (struct sata_event_resp *)(piomb + 4);
2374 u32 event = le32_to_cpu(psataPayload->event);
2375 u32 tag = le32_to_cpu(psataPayload->tag);
2376 u32 port_id = le32_to_cpu(psataPayload->port_id);
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05302377 u32 dev_id = le32_to_cpu(psataPayload->device_id);
2378 unsigned long flags;
Sakthivel Kf5860992013-04-17 16:37:02 +05302379
2380 ccb = &pm8001_ha->ccb_info[tag];
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05302381
2382 if (ccb) {
2383 t = ccb->task;
2384 pm8001_dev = ccb->device;
2385 } else {
2386 PM8001_FAIL_DBG(pm8001_ha,
2387 pm8001_printk("No CCB !!!. returning\n"));
2388 return;
2389 }
Sakthivel Kf5860992013-04-17 16:37:02 +05302390 if (event)
2391 PM8001_FAIL_DBG(pm8001_ha,
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05302392 pm8001_printk("SATA EVENT 0x%x\n", event));
2393
2394 /* Check if this is NCQ error */
2395 if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE) {
2396 /* find device using device id */
2397 pm8001_dev = pm8001_find_dev(pm8001_ha, dev_id);
2398 /* send read log extension */
2399 if (pm8001_dev)
2400 pm80xx_send_read_log(pm8001_ha, pm8001_dev);
Sakthivel Kf5860992013-04-17 16:37:02 +05302401 return;
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05302402 }
2403
2404 if (unlikely(!t || !t->lldd_task || !t->dev)) {
2405 PM8001_FAIL_DBG(pm8001_ha,
2406 pm8001_printk("task or dev null\n"));
2407 return;
2408 }
2409
Sakthivel Kf5860992013-04-17 16:37:02 +05302410 ts = &t->task_status;
2411 PM8001_IO_DBG(pm8001_ha,
2412 pm8001_printk("port_id:0x%x, tag:0x%x, event:0x%x\n",
2413 port_id, tag, event));
2414 switch (event) {
2415 case IO_OVERFLOW:
2416 PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n"));
2417 ts->resp = SAS_TASK_COMPLETE;
2418 ts->stat = SAS_DATA_OVERRUN;
2419 ts->residual = 0;
2420 if (pm8001_dev)
2421 pm8001_dev->running_req--;
2422 break;
2423 case IO_XFER_ERROR_BREAK:
2424 PM8001_IO_DBG(pm8001_ha,
2425 pm8001_printk("IO_XFER_ERROR_BREAK\n"));
2426 ts->resp = SAS_TASK_COMPLETE;
2427 ts->stat = SAS_INTERRUPTED;
2428 break;
2429 case IO_XFER_ERROR_PHY_NOT_READY:
2430 PM8001_IO_DBG(pm8001_ha,
2431 pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
2432 ts->resp = SAS_TASK_COMPLETE;
2433 ts->stat = SAS_OPEN_REJECT;
2434 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
2435 break;
2436 case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
2437 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
2438 "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"));
2439 ts->resp = SAS_TASK_COMPLETE;
2440 ts->stat = SAS_OPEN_REJECT;
2441 ts->open_rej_reason = SAS_OREJ_EPROTO;
2442 break;
2443 case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
2444 PM8001_IO_DBG(pm8001_ha,
2445 pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
2446 ts->resp = SAS_TASK_COMPLETE;
2447 ts->stat = SAS_OPEN_REJECT;
2448 ts->open_rej_reason = SAS_OREJ_UNKNOWN;
2449 break;
2450 case IO_OPEN_CNX_ERROR_BREAK:
2451 PM8001_IO_DBG(pm8001_ha,
2452 pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n"));
2453 ts->resp = SAS_TASK_COMPLETE;
2454 ts->stat = SAS_OPEN_REJECT;
2455 ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;
2456 break;
2457 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
Sakthivel Ka6cb3d02013-03-19 18:08:40 +05302458 case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
2459 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
2460 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
2461 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
2462 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
2463 PM8001_FAIL_DBG(pm8001_ha,
Sakthivel Kf5860992013-04-17 16:37:02 +05302464 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
2465 ts->resp = SAS_TASK_UNDELIVERED;
2466 ts->stat = SAS_DEV_NO_RESPONSE;
2467 if (!t->uldd_task) {
2468 pm8001_handle_event(pm8001_ha,
2469 pm8001_dev,
2470 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
2471 ts->resp = SAS_TASK_COMPLETE;
2472 ts->stat = SAS_QUEUE_FULL;
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05302473 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +05302474 return;
2475 }
2476 break;
2477 case IO_OPEN_CNX_ERROR_BAD_DESTINATION:
2478 PM8001_IO_DBG(pm8001_ha,
2479 pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"));
2480 ts->resp = SAS_TASK_UNDELIVERED;
2481 ts->stat = SAS_OPEN_REJECT;
2482 ts->open_rej_reason = SAS_OREJ_BAD_DEST;
2483 break;
2484 case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
2485 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
2486 "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
2487 ts->resp = SAS_TASK_COMPLETE;
2488 ts->stat = SAS_OPEN_REJECT;
2489 ts->open_rej_reason = SAS_OREJ_CONN_RATE;
2490 break;
2491 case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:
2492 PM8001_IO_DBG(pm8001_ha,
2493 pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"));
2494 ts->resp = SAS_TASK_COMPLETE;
2495 ts->stat = SAS_OPEN_REJECT;
2496 ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
2497 break;
2498 case IO_XFER_ERROR_NAK_RECEIVED:
2499 PM8001_IO_DBG(pm8001_ha,
2500 pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n"));
2501 ts->resp = SAS_TASK_COMPLETE;
2502 ts->stat = SAS_NAK_R_ERR;
2503 break;
2504 case IO_XFER_ERROR_PEER_ABORTED:
2505 PM8001_IO_DBG(pm8001_ha,
2506 pm8001_printk("IO_XFER_ERROR_PEER_ABORTED\n"));
2507 ts->resp = SAS_TASK_COMPLETE;
2508 ts->stat = SAS_NAK_R_ERR;
2509 break;
2510 case IO_XFER_ERROR_REJECTED_NCQ_MODE:
2511 PM8001_IO_DBG(pm8001_ha,
2512 pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n"));
2513 ts->resp = SAS_TASK_COMPLETE;
2514 ts->stat = SAS_DATA_UNDERRUN;
2515 break;
2516 case IO_XFER_OPEN_RETRY_TIMEOUT:
2517 PM8001_IO_DBG(pm8001_ha,
2518 pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
2519 ts->resp = SAS_TASK_COMPLETE;
2520 ts->stat = SAS_OPEN_TO;
2521 break;
2522 case IO_XFER_ERROR_UNEXPECTED_PHASE:
2523 PM8001_IO_DBG(pm8001_ha,
2524 pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n"));
2525 ts->resp = SAS_TASK_COMPLETE;
2526 ts->stat = SAS_OPEN_TO;
2527 break;
2528 case IO_XFER_ERROR_XFER_RDY_OVERRUN:
2529 PM8001_IO_DBG(pm8001_ha,
2530 pm8001_printk("IO_XFER_ERROR_XFER_RDY_OVERRUN\n"));
2531 ts->resp = SAS_TASK_COMPLETE;
2532 ts->stat = SAS_OPEN_TO;
2533 break;
2534 case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED:
2535 PM8001_IO_DBG(pm8001_ha,
2536 pm8001_printk("IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n"));
2537 ts->resp = SAS_TASK_COMPLETE;
2538 ts->stat = SAS_OPEN_TO;
2539 break;
2540 case IO_XFER_ERROR_OFFSET_MISMATCH:
2541 PM8001_IO_DBG(pm8001_ha,
2542 pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n"));
2543 ts->resp = SAS_TASK_COMPLETE;
2544 ts->stat = SAS_OPEN_TO;
2545 break;
2546 case IO_XFER_ERROR_XFER_ZERO_DATA_LEN:
2547 PM8001_IO_DBG(pm8001_ha,
2548 pm8001_printk("IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n"));
2549 ts->resp = SAS_TASK_COMPLETE;
2550 ts->stat = SAS_OPEN_TO;
2551 break;
2552 case IO_XFER_CMD_FRAME_ISSUED:
2553 PM8001_IO_DBG(pm8001_ha,
2554 pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n"));
2555 break;
2556 case IO_XFER_PIO_SETUP_ERROR:
2557 PM8001_IO_DBG(pm8001_ha,
2558 pm8001_printk("IO_XFER_PIO_SETUP_ERROR\n"));
2559 ts->resp = SAS_TASK_COMPLETE;
2560 ts->stat = SAS_OPEN_TO;
2561 break;
Sakthivel Ka6cb3d02013-03-19 18:08:40 +05302562 case IO_XFER_ERROR_INTERNAL_CRC_ERROR:
2563 PM8001_FAIL_DBG(pm8001_ha,
2564 pm8001_printk("IO_XFR_ERROR_INTERNAL_CRC_ERROR\n"));
2565 /* TBC: used default set values */
2566 ts->resp = SAS_TASK_COMPLETE;
2567 ts->stat = SAS_OPEN_TO;
2568 break;
2569 case IO_XFER_DMA_ACTIVATE_TIMEOUT:
2570 PM8001_FAIL_DBG(pm8001_ha,
2571 pm8001_printk("IO_XFR_DMA_ACTIVATE_TIMEOUT\n"));
2572 /* TBC: used default set values */
2573 ts->resp = SAS_TASK_COMPLETE;
2574 ts->stat = SAS_OPEN_TO;
2575 break;
Sakthivel Kf5860992013-04-17 16:37:02 +05302576 default:
2577 PM8001_IO_DBG(pm8001_ha,
2578 pm8001_printk("Unknown status 0x%x\n", event));
2579 /* not allowed case. Therefore, return failed status */
2580 ts->resp = SAS_TASK_COMPLETE;
2581 ts->stat = SAS_OPEN_TO;
2582 break;
2583 }
2584 spin_lock_irqsave(&t->task_state_lock, flags);
2585 t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
2586 t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
2587 t->task_state_flags |= SAS_TASK_STATE_DONE;
2588 if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
2589 spin_unlock_irqrestore(&t->task_state_lock, flags);
2590 PM8001_FAIL_DBG(pm8001_ha,
2591 pm8001_printk("task 0x%p done with io_status 0x%x"
2592 " resp 0x%x stat 0x%x but aborted by upper layer!\n",
2593 t, event, ts->resp, ts->stat));
2594 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05302595 } else {
Sakthivel Kf5860992013-04-17 16:37:02 +05302596 spin_unlock_irqrestore(&t->task_state_lock, flags);
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05302597 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +05302598 }
2599}
2600
2601/*See the comments for mpi_ssp_completion */
2602static void
2603mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2604{
2605 u32 param, i;
2606 struct sas_task *t;
2607 struct pm8001_ccb_info *ccb;
2608 unsigned long flags;
2609 u32 status;
2610 u32 tag;
2611 struct smp_completion_resp *psmpPayload;
2612 struct task_status_struct *ts;
2613 struct pm8001_device *pm8001_dev;
2614 char *pdma_respaddr = NULL;
2615
2616 psmpPayload = (struct smp_completion_resp *)(piomb + 4);
2617 status = le32_to_cpu(psmpPayload->status);
2618 tag = le32_to_cpu(psmpPayload->tag);
2619
2620 ccb = &pm8001_ha->ccb_info[tag];
2621 param = le32_to_cpu(psmpPayload->param);
2622 t = ccb->task;
2623 ts = &t->task_status;
2624 pm8001_dev = ccb->device;
2625 if (status)
2626 PM8001_FAIL_DBG(pm8001_ha,
2627 pm8001_printk("smp IO status 0x%x\n", status));
2628 if (unlikely(!t || !t->lldd_task || !t->dev))
2629 return;
2630
2631 switch (status) {
2632
2633 case IO_SUCCESS:
2634 PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n"));
2635 ts->resp = SAS_TASK_COMPLETE;
2636 ts->stat = SAM_STAT_GOOD;
2637 if (pm8001_dev)
2638 pm8001_dev->running_req--;
2639 if (pm8001_ha->smp_exp_mode == SMP_DIRECT) {
2640 PM8001_IO_DBG(pm8001_ha,
2641 pm8001_printk("DIRECT RESPONSE Length:%d\n",
2642 param));
2643 pdma_respaddr = (char *)(phys_to_virt(cpu_to_le64
2644 ((u64)sg_dma_address
2645 (&t->smp_task.smp_resp))));
2646 for (i = 0; i < param; i++) {
2647 *(pdma_respaddr+i) = psmpPayload->_r_a[i];
2648 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
2649 "SMP Byte%d DMA data 0x%x psmp 0x%x\n",
2650 i, *(pdma_respaddr+i),
2651 psmpPayload->_r_a[i]));
2652 }
2653 }
2654 break;
2655 case IO_ABORTED:
2656 PM8001_IO_DBG(pm8001_ha,
2657 pm8001_printk("IO_ABORTED IOMB\n"));
2658 ts->resp = SAS_TASK_COMPLETE;
2659 ts->stat = SAS_ABORTED_TASK;
2660 if (pm8001_dev)
2661 pm8001_dev->running_req--;
2662 break;
2663 case IO_OVERFLOW:
2664 PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n"));
2665 ts->resp = SAS_TASK_COMPLETE;
2666 ts->stat = SAS_DATA_OVERRUN;
2667 ts->residual = 0;
2668 if (pm8001_dev)
2669 pm8001_dev->running_req--;
2670 break;
2671 case IO_NO_DEVICE:
2672 PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_NO_DEVICE\n"));
2673 ts->resp = SAS_TASK_COMPLETE;
2674 ts->stat = SAS_PHY_DOWN;
2675 break;
2676 case IO_ERROR_HW_TIMEOUT:
2677 PM8001_IO_DBG(pm8001_ha,
2678 pm8001_printk("IO_ERROR_HW_TIMEOUT\n"));
2679 ts->resp = SAS_TASK_COMPLETE;
2680 ts->stat = SAM_STAT_BUSY;
2681 break;
2682 case IO_XFER_ERROR_BREAK:
2683 PM8001_IO_DBG(pm8001_ha,
2684 pm8001_printk("IO_XFER_ERROR_BREAK\n"));
2685 ts->resp = SAS_TASK_COMPLETE;
2686 ts->stat = SAM_STAT_BUSY;
2687 break;
2688 case IO_XFER_ERROR_PHY_NOT_READY:
2689 PM8001_IO_DBG(pm8001_ha,
2690 pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
2691 ts->resp = SAS_TASK_COMPLETE;
2692 ts->stat = SAM_STAT_BUSY;
2693 break;
2694 case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
2695 PM8001_IO_DBG(pm8001_ha,
2696 pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"));
2697 ts->resp = SAS_TASK_COMPLETE;
2698 ts->stat = SAS_OPEN_REJECT;
2699 ts->open_rej_reason = SAS_OREJ_UNKNOWN;
2700 break;
2701 case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
2702 PM8001_IO_DBG(pm8001_ha,
2703 pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
2704 ts->resp = SAS_TASK_COMPLETE;
2705 ts->stat = SAS_OPEN_REJECT;
2706 ts->open_rej_reason = SAS_OREJ_UNKNOWN;
2707 break;
2708 case IO_OPEN_CNX_ERROR_BREAK:
2709 PM8001_IO_DBG(pm8001_ha,
2710 pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n"));
2711 ts->resp = SAS_TASK_COMPLETE;
2712 ts->stat = SAS_OPEN_REJECT;
2713 ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;
2714 break;
2715 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
Sakthivel Ka6cb3d02013-03-19 18:08:40 +05302716 case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
2717 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
2718 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
2719 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
2720 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
Sakthivel Kf5860992013-04-17 16:37:02 +05302721 PM8001_IO_DBG(pm8001_ha,
2722 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
2723 ts->resp = SAS_TASK_COMPLETE;
2724 ts->stat = SAS_OPEN_REJECT;
2725 ts->open_rej_reason = SAS_OREJ_UNKNOWN;
2726 pm8001_handle_event(pm8001_ha,
2727 pm8001_dev,
2728 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
2729 break;
2730 case IO_OPEN_CNX_ERROR_BAD_DESTINATION:
2731 PM8001_IO_DBG(pm8001_ha,
2732 pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"));
2733 ts->resp = SAS_TASK_COMPLETE;
2734 ts->stat = SAS_OPEN_REJECT;
2735 ts->open_rej_reason = SAS_OREJ_BAD_DEST;
2736 break;
2737 case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
2738 PM8001_IO_DBG(pm8001_ha, pm8001_printk(\
2739 "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
2740 ts->resp = SAS_TASK_COMPLETE;
2741 ts->stat = SAS_OPEN_REJECT;
2742 ts->open_rej_reason = SAS_OREJ_CONN_RATE;
2743 break;
2744 case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:
2745 PM8001_IO_DBG(pm8001_ha,
2746 pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"));
2747 ts->resp = SAS_TASK_COMPLETE;
2748 ts->stat = SAS_OPEN_REJECT;
2749 ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
2750 break;
2751 case IO_XFER_ERROR_RX_FRAME:
2752 PM8001_IO_DBG(pm8001_ha,
2753 pm8001_printk("IO_XFER_ERROR_RX_FRAME\n"));
2754 ts->resp = SAS_TASK_COMPLETE;
2755 ts->stat = SAS_DEV_NO_RESPONSE;
2756 break;
2757 case IO_XFER_OPEN_RETRY_TIMEOUT:
2758 PM8001_IO_DBG(pm8001_ha,
2759 pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
2760 ts->resp = SAS_TASK_COMPLETE;
2761 ts->stat = SAS_OPEN_REJECT;
2762 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
2763 break;
2764 case IO_ERROR_INTERNAL_SMP_RESOURCE:
2765 PM8001_IO_DBG(pm8001_ha,
2766 pm8001_printk("IO_ERROR_INTERNAL_SMP_RESOURCE\n"));
2767 ts->resp = SAS_TASK_COMPLETE;
2768 ts->stat = SAS_QUEUE_FULL;
2769 break;
2770 case IO_PORT_IN_RESET:
2771 PM8001_IO_DBG(pm8001_ha,
2772 pm8001_printk("IO_PORT_IN_RESET\n"));
2773 ts->resp = SAS_TASK_COMPLETE;
2774 ts->stat = SAS_OPEN_REJECT;
2775 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
2776 break;
2777 case IO_DS_NON_OPERATIONAL:
2778 PM8001_IO_DBG(pm8001_ha,
2779 pm8001_printk("IO_DS_NON_OPERATIONAL\n"));
2780 ts->resp = SAS_TASK_COMPLETE;
2781 ts->stat = SAS_DEV_NO_RESPONSE;
2782 break;
2783 case IO_DS_IN_RECOVERY:
2784 PM8001_IO_DBG(pm8001_ha,
2785 pm8001_printk("IO_DS_IN_RECOVERY\n"));
2786 ts->resp = SAS_TASK_COMPLETE;
2787 ts->stat = SAS_OPEN_REJECT;
2788 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
2789 break;
2790 case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY:
2791 PM8001_IO_DBG(pm8001_ha,
2792 pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"));
2793 ts->resp = SAS_TASK_COMPLETE;
2794 ts->stat = SAS_OPEN_REJECT;
2795 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
2796 break;
2797 default:
2798 PM8001_IO_DBG(pm8001_ha,
2799 pm8001_printk("Unknown status 0x%x\n", status));
2800 ts->resp = SAS_TASK_COMPLETE;
2801 ts->stat = SAS_DEV_NO_RESPONSE;
2802 /* not allowed case. Therefore, return failed status */
2803 break;
2804 }
2805 spin_lock_irqsave(&t->task_state_lock, flags);
2806 t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
2807 t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
2808 t->task_state_flags |= SAS_TASK_STATE_DONE;
2809 if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
2810 spin_unlock_irqrestore(&t->task_state_lock, flags);
2811 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
2812 "task 0x%p done with io_status 0x%x resp 0x%x"
2813 "stat 0x%x but aborted by upper layer!\n",
2814 t, status, ts->resp, ts->stat));
2815 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2816 } else {
2817 spin_unlock_irqrestore(&t->task_state_lock, flags);
2818 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2819 mb();/* in order to force CPU ordering */
2820 t->task_done(t);
2821 }
2822}
2823
2824/**
2825 * pm80xx_hw_event_ack_req- For PM8001,some events need to acknowage to FW.
2826 * @pm8001_ha: our hba card information
2827 * @Qnum: the outbound queue message number.
2828 * @SEA: source of event to ack
2829 * @port_id: port id.
2830 * @phyId: phy id.
2831 * @param0: parameter 0.
2832 * @param1: parameter 1.
2833 */
2834static void pm80xx_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha,
2835 u32 Qnum, u32 SEA, u32 port_id, u32 phyId, u32 param0, u32 param1)
2836{
2837 struct hw_event_ack_req payload;
2838 u32 opc = OPC_INB_SAS_HW_EVENT_ACK;
2839
2840 struct inbound_queue_table *circularQ;
2841
2842 memset((u8 *)&payload, 0, sizeof(payload));
2843 circularQ = &pm8001_ha->inbnd_q_tbl[Qnum];
2844 payload.tag = cpu_to_le32(1);
2845 payload.phyid_sea_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) |
2846 ((phyId & 0xFF) << 24) | (port_id & 0xFF));
2847 payload.param0 = cpu_to_le32(param0);
2848 payload.param1 = cpu_to_le32(param1);
2849 pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
2850}
2851
2852static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
2853 u32 phyId, u32 phy_op);
2854
Viswas G8414cd82015-08-11 15:06:30 +05302855static void hw_event_port_recover(struct pm8001_hba_info *pm8001_ha,
2856 void *piomb)
2857{
2858 struct hw_event_resp *pPayload = (struct hw_event_resp *)(piomb + 4);
2859 u32 phyid_npip_portstate = le32_to_cpu(pPayload->phyid_npip_portstate);
2860 u8 phy_id = (u8)((phyid_npip_portstate & 0xFF0000) >> 16);
2861 u32 lr_status_evt_portid =
2862 le32_to_cpu(pPayload->lr_status_evt_portid);
2863 u8 deviceType = pPayload->sas_identify.dev_type;
2864 u8 link_rate = (u8)((lr_status_evt_portid & 0xF0000000) >> 28);
2865 struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
2866 u8 port_id = (u8)(lr_status_evt_portid & 0x000000FF);
2867 struct pm8001_port *port = &pm8001_ha->port[port_id];
2868
2869 if (deviceType == SAS_END_DEVICE) {
2870 pm80xx_chip_phy_ctl_req(pm8001_ha, phy_id,
2871 PHY_NOTIFY_ENABLE_SPINUP);
2872 }
2873
2874 port->wide_port_phymap |= (1U << phy_id);
2875 pm8001_get_lrate_mode(phy, link_rate);
2876 phy->sas_phy.oob_mode = SAS_OOB_MODE;
2877 phy->phy_state = PHY_STATE_LINK_UP_SPCV;
2878 phy->phy_attached = 1;
2879}
2880
Sakthivel Kf5860992013-04-17 16:37:02 +05302881/**
2882 * hw_event_sas_phy_up -FW tells me a SAS phy up event.
2883 * @pm8001_ha: our hba card information
2884 * @piomb: IO message buffer
2885 */
2886static void
2887hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
2888{
2889 struct hw_event_resp *pPayload =
2890 (struct hw_event_resp *)(piomb + 4);
2891 u32 lr_status_evt_portid =
2892 le32_to_cpu(pPayload->lr_status_evt_portid);
2893 u32 phyid_npip_portstate = le32_to_cpu(pPayload->phyid_npip_portstate);
2894
2895 u8 link_rate =
2896 (u8)((lr_status_evt_portid & 0xF0000000) >> 28);
2897 u8 port_id = (u8)(lr_status_evt_portid & 0x000000FF);
2898 u8 phy_id =
2899 (u8)((phyid_npip_portstate & 0xFF0000) >> 16);
2900 u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F);
2901
2902 struct pm8001_port *port = &pm8001_ha->port[port_id];
2903 struct sas_ha_struct *sas_ha = pm8001_ha->sas;
2904 struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
2905 unsigned long flags;
2906 u8 deviceType = pPayload->sas_identify.dev_type;
2907 port->port_state = portstate;
Viswas G8414cd82015-08-11 15:06:30 +05302908 port->wide_port_phymap |= (1U << phy_id);
Nikith Ganigarakoppal7d029002013-10-30 16:23:47 +05302909 phy->phy_state = PHY_STATE_LINK_UP_SPCV;
Sakthivel Kf5860992013-04-17 16:37:02 +05302910 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
2911 "portid:%d; phyid:%d; linkrate:%d; "
2912 "portstate:%x; devicetype:%x\n",
2913 port_id, phy_id, link_rate, portstate, deviceType));
2914
2915 switch (deviceType) {
2916 case SAS_PHY_UNUSED:
2917 PM8001_MSG_DBG(pm8001_ha,
2918 pm8001_printk("device type no device.\n"));
2919 break;
2920 case SAS_END_DEVICE:
2921 PM8001_MSG_DBG(pm8001_ha, pm8001_printk("end device.\n"));
2922 pm80xx_chip_phy_ctl_req(pm8001_ha, phy_id,
2923 PHY_NOTIFY_ENABLE_SPINUP);
2924 port->port_attached = 1;
2925 pm8001_get_lrate_mode(phy, link_rate);
2926 break;
2927 case SAS_EDGE_EXPANDER_DEVICE:
2928 PM8001_MSG_DBG(pm8001_ha,
2929 pm8001_printk("expander device.\n"));
2930 port->port_attached = 1;
2931 pm8001_get_lrate_mode(phy, link_rate);
2932 break;
2933 case SAS_FANOUT_EXPANDER_DEVICE:
2934 PM8001_MSG_DBG(pm8001_ha,
2935 pm8001_printk("fanout expander device.\n"));
2936 port->port_attached = 1;
2937 pm8001_get_lrate_mode(phy, link_rate);
2938 break;
2939 default:
2940 PM8001_MSG_DBG(pm8001_ha,
2941 pm8001_printk("unknown device type(%x)\n", deviceType));
2942 break;
2943 }
2944 phy->phy_type |= PORT_TYPE_SAS;
2945 phy->identify.device_type = deviceType;
2946 phy->phy_attached = 1;
2947 if (phy->identify.device_type == SAS_END_DEVICE)
2948 phy->identify.target_port_protocols = SAS_PROTOCOL_SSP;
2949 else if (phy->identify.device_type != SAS_PHY_UNUSED)
2950 phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;
2951 phy->sas_phy.oob_mode = SAS_OOB_MODE;
2952 sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
2953 spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
2954 memcpy(phy->frame_rcvd, &pPayload->sas_identify,
2955 sizeof(struct sas_identify_frame)-4);
2956 phy->frame_rcvd_size = sizeof(struct sas_identify_frame) - 4;
2957 pm8001_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
2958 spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
2959 if (pm8001_ha->flags == PM8001F_RUN_TIME)
2960 mdelay(200);/*delay a moment to wait disk to spinup*/
2961 pm8001_bytes_dmaed(pm8001_ha, phy_id);
2962}
2963
2964/**
2965 * hw_event_sata_phy_up -FW tells me a SATA phy up event.
2966 * @pm8001_ha: our hba card information
2967 * @piomb: IO message buffer
2968 */
2969static void
2970hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
2971{
2972 struct hw_event_resp *pPayload =
2973 (struct hw_event_resp *)(piomb + 4);
2974 u32 phyid_npip_portstate = le32_to_cpu(pPayload->phyid_npip_portstate);
2975 u32 lr_status_evt_portid =
2976 le32_to_cpu(pPayload->lr_status_evt_portid);
2977 u8 link_rate =
2978 (u8)((lr_status_evt_portid & 0xF0000000) >> 28);
2979 u8 port_id = (u8)(lr_status_evt_portid & 0x000000FF);
2980 u8 phy_id =
2981 (u8)((phyid_npip_portstate & 0xFF0000) >> 16);
2982
2983 u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F);
2984
2985 struct pm8001_port *port = &pm8001_ha->port[port_id];
2986 struct sas_ha_struct *sas_ha = pm8001_ha->sas;
2987 struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
2988 unsigned long flags;
2989 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
2990 "port id %d, phy id %d link_rate %d portstate 0x%x\n",
2991 port_id, phy_id, link_rate, portstate));
2992
2993 port->port_state = portstate;
Nikith Ganigarakoppal7d029002013-10-30 16:23:47 +05302994 phy->phy_state = PHY_STATE_LINK_UP_SPCV;
Sakthivel Kf5860992013-04-17 16:37:02 +05302995 port->port_attached = 1;
2996 pm8001_get_lrate_mode(phy, link_rate);
2997 phy->phy_type |= PORT_TYPE_SATA;
2998 phy->phy_attached = 1;
2999 phy->sas_phy.oob_mode = SATA_OOB_MODE;
3000 sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
3001 spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
3002 memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4),
3003 sizeof(struct dev_to_host_fis));
3004 phy->frame_rcvd_size = sizeof(struct dev_to_host_fis);
3005 phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;
James Bottomleyaa9f8322013-05-07 14:44:06 -07003006 phy->identify.device_type = SAS_SATA_DEV;
Sakthivel Kf5860992013-04-17 16:37:02 +05303007 pm8001_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
3008 spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
3009 pm8001_bytes_dmaed(pm8001_ha, phy_id);
3010}
3011
3012/**
3013 * hw_event_phy_down -we should notify the libsas the phy is down.
3014 * @pm8001_ha: our hba card information
3015 * @piomb: IO message buffer
3016 */
3017static void
3018hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
3019{
3020 struct hw_event_resp *pPayload =
3021 (struct hw_event_resp *)(piomb + 4);
3022
3023 u32 lr_status_evt_portid =
3024 le32_to_cpu(pPayload->lr_status_evt_portid);
3025 u8 port_id = (u8)(lr_status_evt_portid & 0x000000FF);
3026 u32 phyid_npip_portstate = le32_to_cpu(pPayload->phyid_npip_portstate);
3027 u8 phy_id =
3028 (u8)((phyid_npip_portstate & 0xFF0000) >> 16);
3029 u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F);
3030
3031 struct pm8001_port *port = &pm8001_ha->port[port_id];
3032 struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
3033 port->port_state = portstate;
Sakthivel Kf5860992013-04-17 16:37:02 +05303034 phy->identify.device_type = 0;
3035 phy->phy_attached = 0;
3036 memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE);
3037 switch (portstate) {
3038 case PORT_VALID:
3039 break;
3040 case PORT_INVALID:
3041 PM8001_MSG_DBG(pm8001_ha,
3042 pm8001_printk(" PortInvalid portID %d\n", port_id));
3043 PM8001_MSG_DBG(pm8001_ha,
3044 pm8001_printk(" Last phy Down and port invalid\n"));
Viswas G8414cd82015-08-11 15:06:30 +05303045 if (phy->phy_type & PORT_TYPE_SATA) {
3046 phy->phy_type = 0;
3047 port->port_attached = 0;
3048 pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,
3049 port_id, phy_id, 0, 0);
3050 }
3051 sas_phy_disconnected(&phy->sas_phy);
Sakthivel Kf5860992013-04-17 16:37:02 +05303052 break;
3053 case PORT_IN_RESET:
3054 PM8001_MSG_DBG(pm8001_ha,
3055 pm8001_printk(" Port In Reset portID %d\n", port_id));
3056 break;
3057 case PORT_NOT_ESTABLISHED:
3058 PM8001_MSG_DBG(pm8001_ha,
Viswas G8414cd82015-08-11 15:06:30 +05303059 pm8001_printk(" Phy Down and PORT_NOT_ESTABLISHED\n"));
Sakthivel Kf5860992013-04-17 16:37:02 +05303060 port->port_attached = 0;
3061 break;
3062 case PORT_LOSTCOMM:
3063 PM8001_MSG_DBG(pm8001_ha,
Viswas G8414cd82015-08-11 15:06:30 +05303064 pm8001_printk(" Phy Down and PORT_LOSTCOMM\n"));
Sakthivel Kf5860992013-04-17 16:37:02 +05303065 PM8001_MSG_DBG(pm8001_ha,
3066 pm8001_printk(" Last phy Down and port invalid\n"));
Viswas G8414cd82015-08-11 15:06:30 +05303067 if (phy->phy_type & PORT_TYPE_SATA) {
3068 port->port_attached = 0;
3069 phy->phy_type = 0;
3070 pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,
3071 port_id, phy_id, 0, 0);
3072 }
3073 sas_phy_disconnected(&phy->sas_phy);
Sakthivel Kf5860992013-04-17 16:37:02 +05303074 break;
3075 default:
3076 port->port_attached = 0;
3077 PM8001_MSG_DBG(pm8001_ha,
Viswas G8414cd82015-08-11 15:06:30 +05303078 pm8001_printk(" Phy Down and(default) = 0x%x\n",
Sakthivel Kf5860992013-04-17 16:37:02 +05303079 portstate));
3080 break;
3081
3082 }
3083}
3084
3085static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
3086{
3087 struct phy_start_resp *pPayload =
3088 (struct phy_start_resp *)(piomb + 4);
3089 u32 status =
3090 le32_to_cpu(pPayload->status);
3091 u32 phy_id =
3092 le32_to_cpu(pPayload->phyid);
3093 struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
3094
3095 PM8001_INIT_DBG(pm8001_ha,
3096 pm8001_printk("phy start resp status:0x%x, phyid:0x%x\n",
3097 status, phy_id));
3098 if (status == 0) {
3099 phy->phy_state = 1;
3100 if (pm8001_ha->flags == PM8001F_RUN_TIME)
3101 complete(phy->enable_completion);
3102 }
3103 return 0;
3104
3105}
3106
3107/**
3108 * mpi_thermal_hw_event -The hw event has come.
3109 * @pm8001_ha: our hba card information
3110 * @piomb: IO message buffer
3111 */
3112static int mpi_thermal_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
3113{
3114 struct thermal_hw_event *pPayload =
3115 (struct thermal_hw_event *)(piomb + 4);
3116
3117 u32 thermal_event = le32_to_cpu(pPayload->thermal_event);
3118 u32 rht_lht = le32_to_cpu(pPayload->rht_lht);
3119
3120 if (thermal_event & 0x40) {
3121 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
3122 "Thermal Event: Local high temperature violated!\n"));
3123 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
3124 "Thermal Event: Measured local high temperature %d\n",
3125 ((rht_lht & 0xFF00) >> 8)));
3126 }
3127 if (thermal_event & 0x10) {
3128 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
3129 "Thermal Event: Remote high temperature violated!\n"));
3130 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
3131 "Thermal Event: Measured remote high temperature %d\n",
3132 ((rht_lht & 0xFF000000) >> 24)));
3133 }
3134 return 0;
3135}
3136
3137/**
3138 * mpi_hw_event -The hw event has come.
3139 * @pm8001_ha: our hba card information
3140 * @piomb: IO message buffer
3141 */
3142static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
3143{
Viswas G8414cd82015-08-11 15:06:30 +05303144 unsigned long flags, i;
Sakthivel Kf5860992013-04-17 16:37:02 +05303145 struct hw_event_resp *pPayload =
3146 (struct hw_event_resp *)(piomb + 4);
3147 u32 lr_status_evt_portid =
3148 le32_to_cpu(pPayload->lr_status_evt_portid);
3149 u32 phyid_npip_portstate = le32_to_cpu(pPayload->phyid_npip_portstate);
3150 u8 port_id = (u8)(lr_status_evt_portid & 0x000000FF);
3151 u8 phy_id =
3152 (u8)((phyid_npip_portstate & 0xFF0000) >> 16);
3153 u16 eventType =
3154 (u16)((lr_status_evt_portid & 0x00FFFF00) >> 8);
3155 u8 status =
3156 (u8)((lr_status_evt_portid & 0x0F000000) >> 24);
Sakthivel Kf5860992013-04-17 16:37:02 +05303157 struct sas_ha_struct *sas_ha = pm8001_ha->sas;
3158 struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
Viswas G8414cd82015-08-11 15:06:30 +05303159 struct pm8001_port *port = &pm8001_ha->port[port_id];
Sakthivel Kf5860992013-04-17 16:37:02 +05303160 struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
3161 PM8001_MSG_DBG(pm8001_ha,
3162 pm8001_printk("portid:%d phyid:%d event:0x%x status:0x%x\n",
3163 port_id, phy_id, eventType, status));
3164
3165 switch (eventType) {
3166
3167 case HW_EVENT_SAS_PHY_UP:
3168 PM8001_MSG_DBG(pm8001_ha,
3169 pm8001_printk("HW_EVENT_PHY_START_STATUS\n"));
3170 hw_event_sas_phy_up(pm8001_ha, piomb);
3171 break;
3172 case HW_EVENT_SATA_PHY_UP:
3173 PM8001_MSG_DBG(pm8001_ha,
3174 pm8001_printk("HW_EVENT_SATA_PHY_UP\n"));
3175 hw_event_sata_phy_up(pm8001_ha, piomb);
3176 break;
3177 case HW_EVENT_SATA_SPINUP_HOLD:
3178 PM8001_MSG_DBG(pm8001_ha,
3179 pm8001_printk("HW_EVENT_SATA_SPINUP_HOLD\n"));
3180 sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD);
3181 break;
3182 case HW_EVENT_PHY_DOWN:
3183 PM8001_MSG_DBG(pm8001_ha,
3184 pm8001_printk("HW_EVENT_PHY_DOWN\n"));
Viswas G8414cd82015-08-11 15:06:30 +05303185 if (phy->phy_type & PORT_TYPE_SATA)
3186 sas_ha->notify_phy_event(&phy->sas_phy,
3187 PHYE_LOSS_OF_SIGNAL);
Sakthivel Kf5860992013-04-17 16:37:02 +05303188 phy->phy_attached = 0;
3189 phy->phy_state = 0;
3190 hw_event_phy_down(pm8001_ha, piomb);
3191 break;
3192 case HW_EVENT_PORT_INVALID:
3193 PM8001_MSG_DBG(pm8001_ha,
3194 pm8001_printk("HW_EVENT_PORT_INVALID\n"));
3195 sas_phy_disconnected(sas_phy);
3196 phy->phy_attached = 0;
3197 sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
3198 break;
3199 /* the broadcast change primitive received, tell the LIBSAS this event
3200 to revalidate the sas domain*/
3201 case HW_EVENT_BROADCAST_CHANGE:
3202 PM8001_MSG_DBG(pm8001_ha,
3203 pm8001_printk("HW_EVENT_BROADCAST_CHANGE\n"));
3204 pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_BROADCAST_CHANGE,
3205 port_id, phy_id, 1, 0);
3206 spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
3207 sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE;
3208 spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
3209 sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
3210 break;
3211 case HW_EVENT_PHY_ERROR:
3212 PM8001_MSG_DBG(pm8001_ha,
3213 pm8001_printk("HW_EVENT_PHY_ERROR\n"));
3214 sas_phy_disconnected(&phy->sas_phy);
3215 phy->phy_attached = 0;
3216 sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR);
3217 break;
3218 case HW_EVENT_BROADCAST_EXP:
3219 PM8001_MSG_DBG(pm8001_ha,
3220 pm8001_printk("HW_EVENT_BROADCAST_EXP\n"));
3221 spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
3222 sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP;
3223 spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
3224 sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
3225 break;
3226 case HW_EVENT_LINK_ERR_INVALID_DWORD:
3227 PM8001_MSG_DBG(pm8001_ha,
3228 pm8001_printk("HW_EVENT_LINK_ERR_INVALID_DWORD\n"));
3229 pm80xx_hw_event_ack_req(pm8001_ha, 0,
3230 HW_EVENT_LINK_ERR_INVALID_DWORD, port_id, phy_id, 0, 0);
Sakthivel Kf5860992013-04-17 16:37:02 +05303231 break;
3232 case HW_EVENT_LINK_ERR_DISPARITY_ERROR:
3233 PM8001_MSG_DBG(pm8001_ha,
3234 pm8001_printk("HW_EVENT_LINK_ERR_DISPARITY_ERROR\n"));
3235 pm80xx_hw_event_ack_req(pm8001_ha, 0,
3236 HW_EVENT_LINK_ERR_DISPARITY_ERROR,
3237 port_id, phy_id, 0, 0);
Sakthivel Kf5860992013-04-17 16:37:02 +05303238 break;
3239 case HW_EVENT_LINK_ERR_CODE_VIOLATION:
3240 PM8001_MSG_DBG(pm8001_ha,
3241 pm8001_printk("HW_EVENT_LINK_ERR_CODE_VIOLATION\n"));
3242 pm80xx_hw_event_ack_req(pm8001_ha, 0,
3243 HW_EVENT_LINK_ERR_CODE_VIOLATION,
3244 port_id, phy_id, 0, 0);
Sakthivel Kf5860992013-04-17 16:37:02 +05303245 break;
3246 case HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH:
3247 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3248 "HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH\n"));
3249 pm80xx_hw_event_ack_req(pm8001_ha, 0,
3250 HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH,
3251 port_id, phy_id, 0, 0);
Sakthivel Kf5860992013-04-17 16:37:02 +05303252 break;
3253 case HW_EVENT_MALFUNCTION:
3254 PM8001_MSG_DBG(pm8001_ha,
3255 pm8001_printk("HW_EVENT_MALFUNCTION\n"));
3256 break;
3257 case HW_EVENT_BROADCAST_SES:
3258 PM8001_MSG_DBG(pm8001_ha,
3259 pm8001_printk("HW_EVENT_BROADCAST_SES\n"));
3260 spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
3261 sas_phy->sas_prim = HW_EVENT_BROADCAST_SES;
3262 spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
3263 sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
3264 break;
3265 case HW_EVENT_INBOUND_CRC_ERROR:
3266 PM8001_MSG_DBG(pm8001_ha,
3267 pm8001_printk("HW_EVENT_INBOUND_CRC_ERROR\n"));
3268 pm80xx_hw_event_ack_req(pm8001_ha, 0,
3269 HW_EVENT_INBOUND_CRC_ERROR,
3270 port_id, phy_id, 0, 0);
3271 break;
3272 case HW_EVENT_HARD_RESET_RECEIVED:
3273 PM8001_MSG_DBG(pm8001_ha,
3274 pm8001_printk("HW_EVENT_HARD_RESET_RECEIVED\n"));
3275 sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
3276 break;
3277 case HW_EVENT_ID_FRAME_TIMEOUT:
3278 PM8001_MSG_DBG(pm8001_ha,
3279 pm8001_printk("HW_EVENT_ID_FRAME_TIMEOUT\n"));
3280 sas_phy_disconnected(sas_phy);
3281 phy->phy_attached = 0;
3282 sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
3283 break;
3284 case HW_EVENT_LINK_ERR_PHY_RESET_FAILED:
3285 PM8001_MSG_DBG(pm8001_ha,
3286 pm8001_printk("HW_EVENT_LINK_ERR_PHY_RESET_FAILED\n"));
3287 pm80xx_hw_event_ack_req(pm8001_ha, 0,
3288 HW_EVENT_LINK_ERR_PHY_RESET_FAILED,
3289 port_id, phy_id, 0, 0);
3290 sas_phy_disconnected(sas_phy);
3291 phy->phy_attached = 0;
3292 sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
3293 break;
3294 case HW_EVENT_PORT_RESET_TIMER_TMO:
3295 PM8001_MSG_DBG(pm8001_ha,
3296 pm8001_printk("HW_EVENT_PORT_RESET_TIMER_TMO\n"));
3297 sas_phy_disconnected(sas_phy);
3298 phy->phy_attached = 0;
3299 sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
3300 break;
3301 case HW_EVENT_PORT_RECOVERY_TIMER_TMO:
3302 PM8001_MSG_DBG(pm8001_ha,
3303 pm8001_printk("HW_EVENT_PORT_RECOVERY_TIMER_TMO\n"));
Sakthivel Ka6cb3d02013-03-19 18:08:40 +05303304 pm80xx_hw_event_ack_req(pm8001_ha, 0,
3305 HW_EVENT_PORT_RECOVERY_TIMER_TMO,
3306 port_id, phy_id, 0, 0);
Viswas G8414cd82015-08-11 15:06:30 +05303307 for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
3308 if (port->wide_port_phymap & (1 << i)) {
3309 phy = &pm8001_ha->phy[i];
3310 sas_ha->notify_phy_event(&phy->sas_phy,
3311 PHYE_LOSS_OF_SIGNAL);
3312 port->wide_port_phymap &= ~(1 << i);
3313 }
3314 }
Sakthivel Kf5860992013-04-17 16:37:02 +05303315 break;
3316 case HW_EVENT_PORT_RECOVER:
3317 PM8001_MSG_DBG(pm8001_ha,
3318 pm8001_printk("HW_EVENT_PORT_RECOVER\n"));
Viswas G8414cd82015-08-11 15:06:30 +05303319 hw_event_port_recover(pm8001_ha, piomb);
Sakthivel Kf5860992013-04-17 16:37:02 +05303320 break;
3321 case HW_EVENT_PORT_RESET_COMPLETE:
3322 PM8001_MSG_DBG(pm8001_ha,
3323 pm8001_printk("HW_EVENT_PORT_RESET_COMPLETE\n"));
3324 break;
3325 case EVENT_BROADCAST_ASYNCH_EVENT:
3326 PM8001_MSG_DBG(pm8001_ha,
3327 pm8001_printk("EVENT_BROADCAST_ASYNCH_EVENT\n"));
3328 break;
3329 default:
3330 PM8001_MSG_DBG(pm8001_ha,
3331 pm8001_printk("Unknown event type 0x%x\n", eventType));
3332 break;
3333 }
3334 return 0;
3335}
3336
3337/**
3338 * mpi_phy_stop_resp - SPCv specific
3339 * @pm8001_ha: our hba card information
3340 * @piomb: IO message buffer
3341 */
3342static int mpi_phy_stop_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
3343{
3344 struct phy_stop_resp *pPayload =
3345 (struct phy_stop_resp *)(piomb + 4);
3346 u32 status =
3347 le32_to_cpu(pPayload->status);
3348 u32 phyid =
3349 le32_to_cpu(pPayload->phyid);
3350 struct pm8001_phy *phy = &pm8001_ha->phy[phyid];
3351 PM8001_MSG_DBG(pm8001_ha,
3352 pm8001_printk("phy:0x%x status:0x%x\n",
3353 phyid, status));
3354 if (status == 0)
3355 phy->phy_state = 0;
3356 return 0;
3357}
3358
3359/**
3360 * mpi_set_controller_config_resp - SPCv specific
3361 * @pm8001_ha: our hba card information
3362 * @piomb: IO message buffer
3363 */
3364static int mpi_set_controller_config_resp(struct pm8001_hba_info *pm8001_ha,
3365 void *piomb)
3366{
3367 struct set_ctrl_cfg_resp *pPayload =
3368 (struct set_ctrl_cfg_resp *)(piomb + 4);
3369 u32 status = le32_to_cpu(pPayload->status);
3370 u32 err_qlfr_pgcd = le32_to_cpu(pPayload->err_qlfr_pgcd);
3371
3372 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3373 "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n",
3374 status, err_qlfr_pgcd));
3375
3376 return 0;
3377}
3378
3379/**
3380 * mpi_get_controller_config_resp - SPCv specific
3381 * @pm8001_ha: our hba card information
3382 * @piomb: IO message buffer
3383 */
3384static int mpi_get_controller_config_resp(struct pm8001_hba_info *pm8001_ha,
3385 void *piomb)
3386{
3387 PM8001_MSG_DBG(pm8001_ha,
3388 pm8001_printk(" pm80xx_addition_functionality\n"));
3389
3390 return 0;
3391}
3392
3393/**
3394 * mpi_get_phy_profile_resp - SPCv specific
3395 * @pm8001_ha: our hba card information
3396 * @piomb: IO message buffer
3397 */
3398static int mpi_get_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
3399 void *piomb)
3400{
3401 PM8001_MSG_DBG(pm8001_ha,
3402 pm8001_printk(" pm80xx_addition_functionality\n"));
3403
3404 return 0;
3405}
3406
3407/**
3408 * mpi_flash_op_ext_resp - SPCv specific
3409 * @pm8001_ha: our hba card information
3410 * @piomb: IO message buffer
3411 */
3412static int mpi_flash_op_ext_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
3413{
3414 PM8001_MSG_DBG(pm8001_ha,
3415 pm8001_printk(" pm80xx_addition_functionality\n"));
3416
3417 return 0;
3418}
3419
3420/**
3421 * mpi_set_phy_profile_resp - SPCv specific
3422 * @pm8001_ha: our hba card information
3423 * @piomb: IO message buffer
3424 */
3425static int mpi_set_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
3426 void *piomb)
3427{
Anand Kumar Santhanam27909402013-09-18 13:02:44 +05303428 u8 page_code;
3429 struct set_phy_profile_resp *pPayload =
3430 (struct set_phy_profile_resp *)(piomb + 4);
3431 u32 ppc_phyid = le32_to_cpu(pPayload->ppc_phyid);
3432 u32 status = le32_to_cpu(pPayload->status);
Sakthivel Kf5860992013-04-17 16:37:02 +05303433
Anand Kumar Santhanam27909402013-09-18 13:02:44 +05303434 page_code = (u8)((ppc_phyid & 0xFF00) >> 8);
3435 if (status) {
3436 /* status is FAILED */
3437 PM8001_FAIL_DBG(pm8001_ha,
3438 pm8001_printk("PhyProfile command failed with status "
3439 "0x%08X \n", status));
3440 return -1;
3441 } else {
3442 if (page_code != SAS_PHY_ANALOG_SETTINGS_PAGE) {
3443 PM8001_FAIL_DBG(pm8001_ha,
3444 pm8001_printk("Invalid page code 0x%X\n",
3445 page_code));
3446 return -1;
3447 }
3448 }
Sakthivel Kf5860992013-04-17 16:37:02 +05303449 return 0;
3450}
3451
3452/**
3453 * mpi_kek_management_resp - SPCv specific
3454 * @pm8001_ha: our hba card information
3455 * @piomb: IO message buffer
3456 */
3457static int mpi_kek_management_resp(struct pm8001_hba_info *pm8001_ha,
3458 void *piomb)
3459{
3460 struct kek_mgmt_resp *pPayload = (struct kek_mgmt_resp *)(piomb + 4);
3461
3462 u32 status = le32_to_cpu(pPayload->status);
3463 u32 kidx_new_curr_ksop = le32_to_cpu(pPayload->kidx_new_curr_ksop);
3464 u32 err_qlfr = le32_to_cpu(pPayload->err_qlfr);
3465
3466 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3467 "KEK MGMT RESP. Status 0x%x idx_ksop 0x%x err_qlfr 0x%x\n",
3468 status, kidx_new_curr_ksop, err_qlfr));
3469
3470 return 0;
3471}
3472
3473/**
3474 * mpi_dek_management_resp - SPCv specific
3475 * @pm8001_ha: our hba card information
3476 * @piomb: IO message buffer
3477 */
3478static int mpi_dek_management_resp(struct pm8001_hba_info *pm8001_ha,
3479 void *piomb)
3480{
3481 PM8001_MSG_DBG(pm8001_ha,
3482 pm8001_printk(" pm80xx_addition_functionality\n"));
3483
3484 return 0;
3485}
3486
3487/**
3488 * ssp_coalesced_comp_resp - SPCv specific
3489 * @pm8001_ha: our hba card information
3490 * @piomb: IO message buffer
3491 */
3492static int ssp_coalesced_comp_resp(struct pm8001_hba_info *pm8001_ha,
3493 void *piomb)
3494{
3495 PM8001_MSG_DBG(pm8001_ha,
3496 pm8001_printk(" pm80xx_addition_functionality\n"));
3497
3498 return 0;
3499}
3500
3501/**
3502 * process_one_iomb - process one outbound Queue memory block
3503 * @pm8001_ha: our hba card information
3504 * @piomb: IO message buffer
3505 */
3506static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)
3507{
3508 __le32 pHeader = *(__le32 *)piomb;
3509 u32 opc = (u32)((le32_to_cpu(pHeader)) & 0xFFF);
3510
3511 switch (opc) {
3512 case OPC_OUB_ECHO:
3513 PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_ECHO\n"));
3514 break;
3515 case OPC_OUB_HW_EVENT:
3516 PM8001_MSG_DBG(pm8001_ha,
3517 pm8001_printk("OPC_OUB_HW_EVENT\n"));
3518 mpi_hw_event(pm8001_ha, piomb);
3519 break;
3520 case OPC_OUB_THERM_HW_EVENT:
3521 PM8001_MSG_DBG(pm8001_ha,
3522 pm8001_printk("OPC_OUB_THERMAL_EVENT\n"));
3523 mpi_thermal_hw_event(pm8001_ha, piomb);
3524 break;
3525 case OPC_OUB_SSP_COMP:
3526 PM8001_MSG_DBG(pm8001_ha,
3527 pm8001_printk("OPC_OUB_SSP_COMP\n"));
3528 mpi_ssp_completion(pm8001_ha, piomb);
3529 break;
3530 case OPC_OUB_SMP_COMP:
3531 PM8001_MSG_DBG(pm8001_ha,
3532 pm8001_printk("OPC_OUB_SMP_COMP\n"));
3533 mpi_smp_completion(pm8001_ha, piomb);
3534 break;
3535 case OPC_OUB_LOCAL_PHY_CNTRL:
3536 PM8001_MSG_DBG(pm8001_ha,
3537 pm8001_printk("OPC_OUB_LOCAL_PHY_CNTRL\n"));
3538 pm8001_mpi_local_phy_ctl(pm8001_ha, piomb);
3539 break;
3540 case OPC_OUB_DEV_REGIST:
3541 PM8001_MSG_DBG(pm8001_ha,
3542 pm8001_printk("OPC_OUB_DEV_REGIST\n"));
3543 pm8001_mpi_reg_resp(pm8001_ha, piomb);
3544 break;
3545 case OPC_OUB_DEREG_DEV:
3546 PM8001_MSG_DBG(pm8001_ha,
Masanari Iida8b513d02013-05-21 23:13:12 +09003547 pm8001_printk("unregister the device\n"));
Sakthivel Kf5860992013-04-17 16:37:02 +05303548 pm8001_mpi_dereg_resp(pm8001_ha, piomb);
3549 break;
3550 case OPC_OUB_GET_DEV_HANDLE:
3551 PM8001_MSG_DBG(pm8001_ha,
3552 pm8001_printk("OPC_OUB_GET_DEV_HANDLE\n"));
3553 break;
3554 case OPC_OUB_SATA_COMP:
3555 PM8001_MSG_DBG(pm8001_ha,
3556 pm8001_printk("OPC_OUB_SATA_COMP\n"));
3557 mpi_sata_completion(pm8001_ha, piomb);
3558 break;
3559 case OPC_OUB_SATA_EVENT:
3560 PM8001_MSG_DBG(pm8001_ha,
3561 pm8001_printk("OPC_OUB_SATA_EVENT\n"));
3562 mpi_sata_event(pm8001_ha, piomb);
3563 break;
3564 case OPC_OUB_SSP_EVENT:
3565 PM8001_MSG_DBG(pm8001_ha,
3566 pm8001_printk("OPC_OUB_SSP_EVENT\n"));
3567 mpi_ssp_event(pm8001_ha, piomb);
3568 break;
3569 case OPC_OUB_DEV_HANDLE_ARRIV:
3570 PM8001_MSG_DBG(pm8001_ha,
3571 pm8001_printk("OPC_OUB_DEV_HANDLE_ARRIV\n"));
3572 /*This is for target*/
3573 break;
3574 case OPC_OUB_SSP_RECV_EVENT:
3575 PM8001_MSG_DBG(pm8001_ha,
3576 pm8001_printk("OPC_OUB_SSP_RECV_EVENT\n"));
3577 /*This is for target*/
3578 break;
3579 case OPC_OUB_FW_FLASH_UPDATE:
3580 PM8001_MSG_DBG(pm8001_ha,
3581 pm8001_printk("OPC_OUB_FW_FLASH_UPDATE\n"));
3582 pm8001_mpi_fw_flash_update_resp(pm8001_ha, piomb);
3583 break;
3584 case OPC_OUB_GPIO_RESPONSE:
3585 PM8001_MSG_DBG(pm8001_ha,
3586 pm8001_printk("OPC_OUB_GPIO_RESPONSE\n"));
3587 break;
3588 case OPC_OUB_GPIO_EVENT:
3589 PM8001_MSG_DBG(pm8001_ha,
3590 pm8001_printk("OPC_OUB_GPIO_EVENT\n"));
3591 break;
3592 case OPC_OUB_GENERAL_EVENT:
3593 PM8001_MSG_DBG(pm8001_ha,
3594 pm8001_printk("OPC_OUB_GENERAL_EVENT\n"));
3595 pm8001_mpi_general_event(pm8001_ha, piomb);
3596 break;
3597 case OPC_OUB_SSP_ABORT_RSP:
3598 PM8001_MSG_DBG(pm8001_ha,
3599 pm8001_printk("OPC_OUB_SSP_ABORT_RSP\n"));
3600 pm8001_mpi_task_abort_resp(pm8001_ha, piomb);
3601 break;
3602 case OPC_OUB_SATA_ABORT_RSP:
3603 PM8001_MSG_DBG(pm8001_ha,
3604 pm8001_printk("OPC_OUB_SATA_ABORT_RSP\n"));
3605 pm8001_mpi_task_abort_resp(pm8001_ha, piomb);
3606 break;
3607 case OPC_OUB_SAS_DIAG_MODE_START_END:
3608 PM8001_MSG_DBG(pm8001_ha,
3609 pm8001_printk("OPC_OUB_SAS_DIAG_MODE_START_END\n"));
3610 break;
3611 case OPC_OUB_SAS_DIAG_EXECUTE:
3612 PM8001_MSG_DBG(pm8001_ha,
3613 pm8001_printk("OPC_OUB_SAS_DIAG_EXECUTE\n"));
3614 break;
3615 case OPC_OUB_GET_TIME_STAMP:
3616 PM8001_MSG_DBG(pm8001_ha,
3617 pm8001_printk("OPC_OUB_GET_TIME_STAMP\n"));
3618 break;
3619 case OPC_OUB_SAS_HW_EVENT_ACK:
3620 PM8001_MSG_DBG(pm8001_ha,
3621 pm8001_printk("OPC_OUB_SAS_HW_EVENT_ACK\n"));
3622 break;
3623 case OPC_OUB_PORT_CONTROL:
3624 PM8001_MSG_DBG(pm8001_ha,
3625 pm8001_printk("OPC_OUB_PORT_CONTROL\n"));
3626 break;
3627 case OPC_OUB_SMP_ABORT_RSP:
3628 PM8001_MSG_DBG(pm8001_ha,
3629 pm8001_printk("OPC_OUB_SMP_ABORT_RSP\n"));
3630 pm8001_mpi_task_abort_resp(pm8001_ha, piomb);
3631 break;
3632 case OPC_OUB_GET_NVMD_DATA:
3633 PM8001_MSG_DBG(pm8001_ha,
3634 pm8001_printk("OPC_OUB_GET_NVMD_DATA\n"));
3635 pm8001_mpi_get_nvmd_resp(pm8001_ha, piomb);
3636 break;
3637 case OPC_OUB_SET_NVMD_DATA:
3638 PM8001_MSG_DBG(pm8001_ha,
3639 pm8001_printk("OPC_OUB_SET_NVMD_DATA\n"));
3640 pm8001_mpi_set_nvmd_resp(pm8001_ha, piomb);
3641 break;
3642 case OPC_OUB_DEVICE_HANDLE_REMOVAL:
3643 PM8001_MSG_DBG(pm8001_ha,
3644 pm8001_printk("OPC_OUB_DEVICE_HANDLE_REMOVAL\n"));
3645 break;
3646 case OPC_OUB_SET_DEVICE_STATE:
3647 PM8001_MSG_DBG(pm8001_ha,
3648 pm8001_printk("OPC_OUB_SET_DEVICE_STATE\n"));
3649 pm8001_mpi_set_dev_state_resp(pm8001_ha, piomb);
3650 break;
3651 case OPC_OUB_GET_DEVICE_STATE:
3652 PM8001_MSG_DBG(pm8001_ha,
3653 pm8001_printk("OPC_OUB_GET_DEVICE_STATE\n"));
3654 break;
3655 case OPC_OUB_SET_DEV_INFO:
3656 PM8001_MSG_DBG(pm8001_ha,
3657 pm8001_printk("OPC_OUB_SET_DEV_INFO\n"));
3658 break;
3659 /* spcv specifc commands */
3660 case OPC_OUB_PHY_START_RESP:
3661 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3662 "OPC_OUB_PHY_START_RESP opcode:%x\n", opc));
3663 mpi_phy_start_resp(pm8001_ha, piomb);
3664 break;
3665 case OPC_OUB_PHY_STOP_RESP:
3666 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3667 "OPC_OUB_PHY_STOP_RESP opcode:%x\n", opc));
3668 mpi_phy_stop_resp(pm8001_ha, piomb);
3669 break;
3670 case OPC_OUB_SET_CONTROLLER_CONFIG:
3671 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3672 "OPC_OUB_SET_CONTROLLER_CONFIG opcode:%x\n", opc));
3673 mpi_set_controller_config_resp(pm8001_ha, piomb);
3674 break;
3675 case OPC_OUB_GET_CONTROLLER_CONFIG:
3676 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3677 "OPC_OUB_GET_CONTROLLER_CONFIG opcode:%x\n", opc));
3678 mpi_get_controller_config_resp(pm8001_ha, piomb);
3679 break;
3680 case OPC_OUB_GET_PHY_PROFILE:
3681 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3682 "OPC_OUB_GET_PHY_PROFILE opcode:%x\n", opc));
3683 mpi_get_phy_profile_resp(pm8001_ha, piomb);
3684 break;
3685 case OPC_OUB_FLASH_OP_EXT:
3686 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3687 "OPC_OUB_FLASH_OP_EXT opcode:%x\n", opc));
3688 mpi_flash_op_ext_resp(pm8001_ha, piomb);
3689 break;
3690 case OPC_OUB_SET_PHY_PROFILE:
3691 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3692 "OPC_OUB_SET_PHY_PROFILE opcode:%x\n", opc));
3693 mpi_set_phy_profile_resp(pm8001_ha, piomb);
3694 break;
3695 case OPC_OUB_KEK_MANAGEMENT_RESP:
3696 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3697 "OPC_OUB_KEK_MANAGEMENT_RESP opcode:%x\n", opc));
3698 mpi_kek_management_resp(pm8001_ha, piomb);
3699 break;
3700 case OPC_OUB_DEK_MANAGEMENT_RESP:
3701 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3702 "OPC_OUB_DEK_MANAGEMENT_RESP opcode:%x\n", opc));
3703 mpi_dek_management_resp(pm8001_ha, piomb);
3704 break;
3705 case OPC_OUB_SSP_COALESCED_COMP_RESP:
3706 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3707 "OPC_OUB_SSP_COALESCED_COMP_RESP opcode:%x\n", opc));
3708 ssp_coalesced_comp_resp(pm8001_ha, piomb);
3709 break;
3710 default:
3711 PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
3712 "Unknown outbound Queue IOMB OPC = 0x%x\n", opc));
3713 break;
3714 }
3715}
3716
3717static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec)
3718{
3719 struct outbound_queue_table *circularQ;
3720 void *pMsg1 = NULL;
3721 u8 uninitialized_var(bc);
3722 u32 ret = MPI_IO_STATUS_FAIL;
3723 unsigned long flags;
3724
3725 spin_lock_irqsave(&pm8001_ha->lock, flags);
3726 circularQ = &pm8001_ha->outbnd_q_tbl[vec];
3727 do {
3728 ret = pm8001_mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc);
3729 if (MPI_IO_STATUS_SUCCESS == ret) {
3730 /* process the outbound message */
3731 process_one_iomb(pm8001_ha, (void *)(pMsg1 - 4));
3732 /* free the message from the outbound circular buffer */
3733 pm8001_mpi_msg_free_set(pm8001_ha, pMsg1,
3734 circularQ, bc);
3735 }
3736 if (MPI_IO_STATUS_BUSY == ret) {
3737 /* Update the producer index from SPC */
3738 circularQ->producer_index =
3739 cpu_to_le32(pm8001_read_32(circularQ->pi_virt));
3740 if (le32_to_cpu(circularQ->producer_index) ==
3741 circularQ->consumer_idx)
3742 /* OQ is empty */
3743 break;
3744 }
3745 } while (1);
3746 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
3747 return ret;
3748}
3749
3750/* PCI_DMA_... to our direction translation. */
3751static const u8 data_dir_flags[] = {
3752 [PCI_DMA_BIDIRECTIONAL] = DATA_DIR_BYRECIPIENT,/* UNSPECIFIED */
3753 [PCI_DMA_TODEVICE] = DATA_DIR_OUT,/* OUTBOUND */
3754 [PCI_DMA_FROMDEVICE] = DATA_DIR_IN,/* INBOUND */
3755 [PCI_DMA_NONE] = DATA_DIR_NONE,/* NO TRANSFER */
3756};
3757
3758static void build_smp_cmd(u32 deviceID, __le32 hTag,
3759 struct smp_req *psmp_cmd, int mode, int length)
3760{
3761 psmp_cmd->tag = hTag;
3762 psmp_cmd->device_id = cpu_to_le32(deviceID);
3763 if (mode == SMP_DIRECT) {
3764 length = length - 4; /* subtract crc */
3765 psmp_cmd->len_ip_ir = cpu_to_le32(length << 16);
3766 } else {
3767 psmp_cmd->len_ip_ir = cpu_to_le32(1|(1 << 1));
3768 }
3769}
3770
3771/**
3772 * pm8001_chip_smp_req - send a SMP task to FW
3773 * @pm8001_ha: our hba card information.
3774 * @ccb: the ccb information this request used.
3775 */
3776static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
3777 struct pm8001_ccb_info *ccb)
3778{
3779 int elem, rc;
3780 struct sas_task *task = ccb->task;
3781 struct domain_device *dev = task->dev;
3782 struct pm8001_device *pm8001_dev = dev->lldd_dev;
3783 struct scatterlist *sg_req, *sg_resp;
3784 u32 req_len, resp_len;
3785 struct smp_req smp_cmd;
3786 u32 opc;
3787 struct inbound_queue_table *circularQ;
3788 char *preq_dma_addr = NULL;
3789 __le64 tmp_addr;
3790 u32 i, length;
3791
3792 memset(&smp_cmd, 0, sizeof(smp_cmd));
3793 /*
3794 * DMA-map SMP request, response buffers
3795 */
3796 sg_req = &task->smp_task.smp_req;
3797 elem = dma_map_sg(pm8001_ha->dev, sg_req, 1, PCI_DMA_TODEVICE);
3798 if (!elem)
3799 return -ENOMEM;
3800 req_len = sg_dma_len(sg_req);
3801
3802 sg_resp = &task->smp_task.smp_resp;
3803 elem = dma_map_sg(pm8001_ha->dev, sg_resp, 1, PCI_DMA_FROMDEVICE);
3804 if (!elem) {
3805 rc = -ENOMEM;
3806 goto err_out;
3807 }
3808 resp_len = sg_dma_len(sg_resp);
3809 /* must be in dwords */
3810 if ((req_len & 0x3) || (resp_len & 0x3)) {
3811 rc = -EINVAL;
3812 goto err_out_2;
3813 }
3814
3815 opc = OPC_INB_SMP_REQUEST;
3816 circularQ = &pm8001_ha->inbnd_q_tbl[0];
3817 smp_cmd.tag = cpu_to_le32(ccb->ccb_tag);
3818
3819 length = sg_req->length;
3820 PM8001_IO_DBG(pm8001_ha,
3821 pm8001_printk("SMP Frame Length %d\n", sg_req->length));
3822 if (!(length - 8))
3823 pm8001_ha->smp_exp_mode = SMP_DIRECT;
3824 else
3825 pm8001_ha->smp_exp_mode = SMP_INDIRECT;
3826
Sakthivel Kf5860992013-04-17 16:37:02 +05303827
3828 tmp_addr = cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_req));
3829 preq_dma_addr = (char *)phys_to_virt(tmp_addr);
3830
3831 /* INDIRECT MODE command settings. Use DMA */
3832 if (pm8001_ha->smp_exp_mode == SMP_INDIRECT) {
3833 PM8001_IO_DBG(pm8001_ha,
3834 pm8001_printk("SMP REQUEST INDIRECT MODE\n"));
3835 /* for SPCv indirect mode. Place the top 4 bytes of
3836 * SMP Request header here. */
3837 for (i = 0; i < 4; i++)
3838 smp_cmd.smp_req16[i] = *(preq_dma_addr + i);
3839 /* exclude top 4 bytes for SMP req header */
3840 smp_cmd.long_smp_req.long_req_addr =
3841 cpu_to_le64((u64)sg_dma_address
Anand Kumar Santhanamcb993e52013-09-17 14:37:14 +05303842 (&task->smp_task.smp_req) + 4);
Sakthivel Kf5860992013-04-17 16:37:02 +05303843 /* exclude 4 bytes for SMP req header and CRC */
3844 smp_cmd.long_smp_req.long_req_size =
3845 cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_req)-8);
3846 smp_cmd.long_smp_req.long_resp_addr =
3847 cpu_to_le64((u64)sg_dma_address
3848 (&task->smp_task.smp_resp));
3849 smp_cmd.long_smp_req.long_resp_size =
3850 cpu_to_le32((u32)sg_dma_len
3851 (&task->smp_task.smp_resp)-4);
3852 } else { /* DIRECT MODE */
3853 smp_cmd.long_smp_req.long_req_addr =
3854 cpu_to_le64((u64)sg_dma_address
3855 (&task->smp_task.smp_req));
3856 smp_cmd.long_smp_req.long_req_size =
3857 cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_req)-4);
3858 smp_cmd.long_smp_req.long_resp_addr =
3859 cpu_to_le64((u64)sg_dma_address
3860 (&task->smp_task.smp_resp));
3861 smp_cmd.long_smp_req.long_resp_size =
3862 cpu_to_le32
3863 ((u32)sg_dma_len(&task->smp_task.smp_resp)-4);
3864 }
3865 if (pm8001_ha->smp_exp_mode == SMP_DIRECT) {
3866 PM8001_IO_DBG(pm8001_ha,
3867 pm8001_printk("SMP REQUEST DIRECT MODE\n"));
3868 for (i = 0; i < length; i++)
3869 if (i < 16) {
3870 smp_cmd.smp_req16[i] = *(preq_dma_addr+i);
3871 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
3872 "Byte[%d]:%x (DMA data:%x)\n",
3873 i, smp_cmd.smp_req16[i],
3874 *(preq_dma_addr)));
3875 } else {
3876 smp_cmd.smp_req[i] = *(preq_dma_addr+i);
3877 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
3878 "Byte[%d]:%x (DMA data:%x)\n",
3879 i, smp_cmd.smp_req[i],
3880 *(preq_dma_addr)));
3881 }
3882 }
3883
3884 build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag,
3885 &smp_cmd, pm8001_ha->smp_exp_mode, length);
Tomas Henzl5533abc2014-07-09 17:20:49 +05303886 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
3887 (u32 *)&smp_cmd, 0);
3888 if (rc)
3889 goto err_out_2;
Sakthivel Kf5860992013-04-17 16:37:02 +05303890 return 0;
3891
3892err_out_2:
3893 dma_unmap_sg(pm8001_ha->dev, &ccb->task->smp_task.smp_resp, 1,
3894 PCI_DMA_FROMDEVICE);
3895err_out:
3896 dma_unmap_sg(pm8001_ha->dev, &ccb->task->smp_task.smp_req, 1,
3897 PCI_DMA_TODEVICE);
3898 return rc;
3899}
3900
3901static int check_enc_sas_cmd(struct sas_task *task)
3902{
James Bottomleye73823f2013-05-07 15:38:18 -07003903 u8 cmd = task->ssp_task.cmd->cmnd[0];
3904
3905 if (cmd == READ_10 || cmd == WRITE_10 || cmd == WRITE_VERIFY)
Sakthivel Kf5860992013-04-17 16:37:02 +05303906 return 1;
3907 else
3908 return 0;
3909}
3910
3911static int check_enc_sat_cmd(struct sas_task *task)
3912{
3913 int ret = 0;
3914 switch (task->ata_task.fis.command) {
3915 case ATA_CMD_FPDMA_READ:
3916 case ATA_CMD_READ_EXT:
3917 case ATA_CMD_READ:
3918 case ATA_CMD_FPDMA_WRITE:
3919 case ATA_CMD_WRITE_EXT:
3920 case ATA_CMD_WRITE:
3921 case ATA_CMD_PIO_READ:
3922 case ATA_CMD_PIO_READ_EXT:
3923 case ATA_CMD_PIO_WRITE:
3924 case ATA_CMD_PIO_WRITE_EXT:
3925 ret = 1;
3926 break;
3927 default:
3928 ret = 0;
3929 break;
3930 }
3931 return ret;
3932}
3933
3934/**
3935 * pm80xx_chip_ssp_io_req - send a SSP task to FW
3936 * @pm8001_ha: our hba card information.
3937 * @ccb: the ccb information this request used.
3938 */
3939static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
3940 struct pm8001_ccb_info *ccb)
3941{
3942 struct sas_task *task = ccb->task;
3943 struct domain_device *dev = task->dev;
3944 struct pm8001_device *pm8001_dev = dev->lldd_dev;
3945 struct ssp_ini_io_start_req ssp_cmd;
3946 u32 tag = ccb->ccb_tag;
3947 int ret;
Anand Kumar Santhanam0ecdf002013-09-18 11:14:54 +05303948 u64 phys_addr, start_addr, end_addr;
3949 u32 end_addr_high, end_addr_low;
Sakthivel Kf5860992013-04-17 16:37:02 +05303950 struct inbound_queue_table *circularQ;
Anand Kumar Santhanamf9cd6cb2013-09-18 11:12:59 +05303951 u32 q_index;
Sakthivel Kf5860992013-04-17 16:37:02 +05303952 u32 opc = OPC_INB_SSPINIIOSTART;
3953 memset(&ssp_cmd, 0, sizeof(ssp_cmd));
3954 memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8);
3955 /* data address domain added for spcv; set to 0 by host,
3956 * used internally by controller
3957 * 0 for SAS 1.1 and SAS 2.0 compatible TLR
3958 */
3959 ssp_cmd.dad_dir_m_tlr =
3960 cpu_to_le32(data_dir_flags[task->data_dir] << 8 | 0x0);
3961 ssp_cmd.data_len = cpu_to_le32(task->total_xfer_len);
3962 ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id);
3963 ssp_cmd.tag = cpu_to_le32(tag);
3964 if (task->ssp_task.enable_first_burst)
3965 ssp_cmd.ssp_iu.efb_prio_attr |= 0x80;
3966 ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3);
3967 ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
James Bottomleye73823f2013-05-07 15:38:18 -07003968 memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
3969 task->ssp_task.cmd->cmd_len);
Anand Kumar Santhanamf9cd6cb2013-09-18 11:12:59 +05303970 q_index = (u32) (pm8001_dev->id & 0x00ffffff) % PM8001_MAX_INB_NUM;
3971 circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
Sakthivel Kf5860992013-04-17 16:37:02 +05303972
3973 /* Check if encryption is set */
3974 if (pm8001_ha->chip->encrypt &&
3975 !(pm8001_ha->encrypt_info.status) && check_enc_sas_cmd(task)) {
3976 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
3977 "Encryption enabled.Sending Encrypt SAS command 0x%x\n",
James Bottomleye73823f2013-05-07 15:38:18 -07003978 task->ssp_task.cmd->cmnd[0]));
Sakthivel Kf5860992013-04-17 16:37:02 +05303979 opc = OPC_INB_SSP_INI_DIF_ENC_IO;
3980 /* enable encryption. 0 for SAS 1.1 and SAS 2.0 compatible TLR*/
3981 ssp_cmd.dad_dir_m_tlr = cpu_to_le32
3982 ((data_dir_flags[task->data_dir] << 8) | 0x20 | 0x0);
3983
3984 /* fill in PRD (scatter/gather) table, if any */
3985 if (task->num_scatter > 1) {
3986 pm8001_chip_make_sg(task->scatter,
3987 ccb->n_elem, ccb->buf_prd);
3988 phys_addr = ccb->ccb_dma_handle +
3989 offsetof(struct pm8001_ccb_info, buf_prd[0]);
3990 ssp_cmd.enc_addr_low =
3991 cpu_to_le32(lower_32_bits(phys_addr));
3992 ssp_cmd.enc_addr_high =
3993 cpu_to_le32(upper_32_bits(phys_addr));
3994 ssp_cmd.enc_esgl = cpu_to_le32(1<<31);
3995 } else if (task->num_scatter == 1) {
3996 u64 dma_addr = sg_dma_address(task->scatter);
3997 ssp_cmd.enc_addr_low =
3998 cpu_to_le32(lower_32_bits(dma_addr));
3999 ssp_cmd.enc_addr_high =
4000 cpu_to_le32(upper_32_bits(dma_addr));
4001 ssp_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
4002 ssp_cmd.enc_esgl = 0;
Anand Kumar Santhanam0ecdf002013-09-18 11:14:54 +05304003 /* Check 4G Boundary */
4004 start_addr = cpu_to_le64(dma_addr);
4005 end_addr = (start_addr + ssp_cmd.enc_len) - 1;
4006 end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
4007 end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
4008 if (end_addr_high != ssp_cmd.enc_addr_high) {
4009 PM8001_FAIL_DBG(pm8001_ha,
4010 pm8001_printk("The sg list address "
4011 "start_addr=0x%016llx data_len=0x%x "
4012 "end_addr_high=0x%08x end_addr_low="
4013 "0x%08x has crossed 4G boundary\n",
4014 start_addr, ssp_cmd.enc_len,
4015 end_addr_high, end_addr_low));
4016 pm8001_chip_make_sg(task->scatter, 1,
4017 ccb->buf_prd);
4018 phys_addr = ccb->ccb_dma_handle +
4019 offsetof(struct pm8001_ccb_info,
4020 buf_prd[0]);
4021 ssp_cmd.enc_addr_low =
4022 cpu_to_le32(lower_32_bits(phys_addr));
4023 ssp_cmd.enc_addr_high =
4024 cpu_to_le32(upper_32_bits(phys_addr));
4025 ssp_cmd.enc_esgl = cpu_to_le32(1<<31);
4026 }
Sakthivel Kf5860992013-04-17 16:37:02 +05304027 } else if (task->num_scatter == 0) {
4028 ssp_cmd.enc_addr_low = 0;
4029 ssp_cmd.enc_addr_high = 0;
4030 ssp_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
4031 ssp_cmd.enc_esgl = 0;
4032 }
4033 /* XTS mode. All other fields are 0 */
4034 ssp_cmd.key_cmode = 0x6 << 4;
4035 /* set tweak values. Should be the start lba */
James Bottomleye73823f2013-05-07 15:38:18 -07004036 ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cmd->cmnd[2] << 24) |
4037 (task->ssp_task.cmd->cmnd[3] << 16) |
4038 (task->ssp_task.cmd->cmnd[4] << 8) |
4039 (task->ssp_task.cmd->cmnd[5]));
Sakthivel Kf5860992013-04-17 16:37:02 +05304040 } else {
4041 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
4042 "Sending Normal SAS command 0x%x inb q %x\n",
Anand Kumar Santhanamf9cd6cb2013-09-18 11:12:59 +05304043 task->ssp_task.cmd->cmnd[0], q_index));
Sakthivel Kf5860992013-04-17 16:37:02 +05304044 /* fill in PRD (scatter/gather) table, if any */
4045 if (task->num_scatter > 1) {
4046 pm8001_chip_make_sg(task->scatter, ccb->n_elem,
4047 ccb->buf_prd);
4048 phys_addr = ccb->ccb_dma_handle +
4049 offsetof(struct pm8001_ccb_info, buf_prd[0]);
4050 ssp_cmd.addr_low =
4051 cpu_to_le32(lower_32_bits(phys_addr));
4052 ssp_cmd.addr_high =
4053 cpu_to_le32(upper_32_bits(phys_addr));
4054 ssp_cmd.esgl = cpu_to_le32(1<<31);
4055 } else if (task->num_scatter == 1) {
4056 u64 dma_addr = sg_dma_address(task->scatter);
4057 ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(dma_addr));
4058 ssp_cmd.addr_high =
4059 cpu_to_le32(upper_32_bits(dma_addr));
4060 ssp_cmd.len = cpu_to_le32(task->total_xfer_len);
4061 ssp_cmd.esgl = 0;
Anand Kumar Santhanam0ecdf002013-09-18 11:14:54 +05304062 /* Check 4G Boundary */
4063 start_addr = cpu_to_le64(dma_addr);
4064 end_addr = (start_addr + ssp_cmd.len) - 1;
4065 end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
4066 end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
4067 if (end_addr_high != ssp_cmd.addr_high) {
4068 PM8001_FAIL_DBG(pm8001_ha,
4069 pm8001_printk("The sg list address "
4070 "start_addr=0x%016llx data_len=0x%x "
4071 "end_addr_high=0x%08x end_addr_low="
4072 "0x%08x has crossed 4G boundary\n",
4073 start_addr, ssp_cmd.len,
4074 end_addr_high, end_addr_low));
4075 pm8001_chip_make_sg(task->scatter, 1,
4076 ccb->buf_prd);
4077 phys_addr = ccb->ccb_dma_handle +
4078 offsetof(struct pm8001_ccb_info,
4079 buf_prd[0]);
4080 ssp_cmd.addr_low =
4081 cpu_to_le32(lower_32_bits(phys_addr));
4082 ssp_cmd.addr_high =
4083 cpu_to_le32(upper_32_bits(phys_addr));
4084 ssp_cmd.esgl = cpu_to_le32(1<<31);
4085 }
Sakthivel Kf5860992013-04-17 16:37:02 +05304086 } else if (task->num_scatter == 0) {
4087 ssp_cmd.addr_low = 0;
4088 ssp_cmd.addr_high = 0;
4089 ssp_cmd.len = cpu_to_le32(task->total_xfer_len);
4090 ssp_cmd.esgl = 0;
4091 }
4092 }
Anand Kumar Santhanamf9cd6cb2013-09-18 11:12:59 +05304093 q_index = (u32) (pm8001_dev->id & 0x00ffffff) % PM8001_MAX_OUTB_NUM;
4094 ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
4095 &ssp_cmd, q_index);
Sakthivel Kf5860992013-04-17 16:37:02 +05304096 return ret;
4097}
4098
4099static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
4100 struct pm8001_ccb_info *ccb)
4101{
4102 struct sas_task *task = ccb->task;
4103 struct domain_device *dev = task->dev;
4104 struct pm8001_device *pm8001_ha_dev = dev->lldd_dev;
4105 u32 tag = ccb->ccb_tag;
4106 int ret;
Anand Kumar Santhanamf9cd6cb2013-09-18 11:12:59 +05304107 u32 q_index;
Sakthivel Kf5860992013-04-17 16:37:02 +05304108 struct sata_start_req sata_cmd;
4109 u32 hdr_tag, ncg_tag = 0;
Anand Kumar Santhanam0ecdf002013-09-18 11:14:54 +05304110 u64 phys_addr, start_addr, end_addr;
4111 u32 end_addr_high, end_addr_low;
Sakthivel Kf5860992013-04-17 16:37:02 +05304112 u32 ATAP = 0x0;
4113 u32 dir;
4114 struct inbound_queue_table *circularQ;
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05304115 unsigned long flags;
Sakthivel Kf5860992013-04-17 16:37:02 +05304116 u32 opc = OPC_INB_SATA_HOST_OPSTART;
4117 memset(&sata_cmd, 0, sizeof(sata_cmd));
Anand Kumar Santhanamf9cd6cb2013-09-18 11:12:59 +05304118 q_index = (u32) (pm8001_ha_dev->id & 0x00ffffff) % PM8001_MAX_INB_NUM;
4119 circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
Sakthivel Kf5860992013-04-17 16:37:02 +05304120
4121 if (task->data_dir == PCI_DMA_NONE) {
4122 ATAP = 0x04; /* no data*/
4123 PM8001_IO_DBG(pm8001_ha, pm8001_printk("no data\n"));
4124 } else if (likely(!task->ata_task.device_control_reg_update)) {
4125 if (task->ata_task.dma_xfer) {
4126 ATAP = 0x06; /* DMA */
4127 PM8001_IO_DBG(pm8001_ha, pm8001_printk("DMA\n"));
4128 } else {
4129 ATAP = 0x05; /* PIO*/
4130 PM8001_IO_DBG(pm8001_ha, pm8001_printk("PIO\n"));
4131 }
4132 if (task->ata_task.use_ncq &&
Hannes Reinecke1cbd7722014-11-05 13:08:20 +01004133 dev->sata_dev.class != ATA_DEV_ATAPI) {
Sakthivel Kf5860992013-04-17 16:37:02 +05304134 ATAP = 0x07; /* FPDMA */
4135 PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n"));
4136 }
4137 }
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05304138 if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) {
4139 task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
Sakthivel Kf5860992013-04-17 16:37:02 +05304140 ncg_tag = hdr_tag;
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05304141 }
Sakthivel Kf5860992013-04-17 16:37:02 +05304142 dir = data_dir_flags[task->data_dir] << 8;
4143 sata_cmd.tag = cpu_to_le32(tag);
4144 sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
4145 sata_cmd.data_len = cpu_to_le32(task->total_xfer_len);
4146
4147 sata_cmd.sata_fis = task->ata_task.fis;
4148 if (likely(!task->ata_task.device_control_reg_update))
4149 sata_cmd.sata_fis.flags |= 0x80;/* C=1: update ATA cmd reg */
4150 sata_cmd.sata_fis.flags &= 0xF0;/* PM_PORT field shall be 0 */
4151
4152 /* Check if encryption is set */
4153 if (pm8001_ha->chip->encrypt &&
4154 !(pm8001_ha->encrypt_info.status) && check_enc_sat_cmd(task)) {
4155 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
4156 "Encryption enabled.Sending Encrypt SATA cmd 0x%x\n",
4157 sata_cmd.sata_fis.command));
4158 opc = OPC_INB_SATA_DIF_ENC_IO;
4159
4160 /* set encryption bit */
4161 sata_cmd.ncqtag_atap_dir_m_dad =
4162 cpu_to_le32(((ncg_tag & 0xff)<<16)|
4163 ((ATAP & 0x3f) << 10) | 0x20 | dir);
4164 /* dad (bit 0-1) is 0 */
4165 /* fill in PRD (scatter/gather) table, if any */
4166 if (task->num_scatter > 1) {
4167 pm8001_chip_make_sg(task->scatter,
4168 ccb->n_elem, ccb->buf_prd);
4169 phys_addr = ccb->ccb_dma_handle +
4170 offsetof(struct pm8001_ccb_info, buf_prd[0]);
4171 sata_cmd.enc_addr_low = lower_32_bits(phys_addr);
4172 sata_cmd.enc_addr_high = upper_32_bits(phys_addr);
4173 sata_cmd.enc_esgl = cpu_to_le32(1 << 31);
4174 } else if (task->num_scatter == 1) {
4175 u64 dma_addr = sg_dma_address(task->scatter);
4176 sata_cmd.enc_addr_low = lower_32_bits(dma_addr);
4177 sata_cmd.enc_addr_high = upper_32_bits(dma_addr);
4178 sata_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
4179 sata_cmd.enc_esgl = 0;
Anand Kumar Santhanam0ecdf002013-09-18 11:14:54 +05304180 /* Check 4G Boundary */
4181 start_addr = cpu_to_le64(dma_addr);
4182 end_addr = (start_addr + sata_cmd.enc_len) - 1;
4183 end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
4184 end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
4185 if (end_addr_high != sata_cmd.enc_addr_high) {
4186 PM8001_FAIL_DBG(pm8001_ha,
4187 pm8001_printk("The sg list address "
4188 "start_addr=0x%016llx data_len=0x%x "
4189 "end_addr_high=0x%08x end_addr_low"
4190 "=0x%08x has crossed 4G boundary\n",
4191 start_addr, sata_cmd.enc_len,
4192 end_addr_high, end_addr_low));
4193 pm8001_chip_make_sg(task->scatter, 1,
4194 ccb->buf_prd);
4195 phys_addr = ccb->ccb_dma_handle +
4196 offsetof(struct pm8001_ccb_info,
4197 buf_prd[0]);
4198 sata_cmd.enc_addr_low =
4199 lower_32_bits(phys_addr);
4200 sata_cmd.enc_addr_high =
4201 upper_32_bits(phys_addr);
4202 sata_cmd.enc_esgl =
4203 cpu_to_le32(1 << 31);
4204 }
Sakthivel Kf5860992013-04-17 16:37:02 +05304205 } else if (task->num_scatter == 0) {
4206 sata_cmd.enc_addr_low = 0;
4207 sata_cmd.enc_addr_high = 0;
4208 sata_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
4209 sata_cmd.enc_esgl = 0;
4210 }
4211 /* XTS mode. All other fields are 0 */
4212 sata_cmd.key_index_mode = 0x6 << 4;
4213 /* set tweak values. Should be the start lba */
4214 sata_cmd.twk_val0 =
4215 cpu_to_le32((sata_cmd.sata_fis.lbal_exp << 24) |
4216 (sata_cmd.sata_fis.lbah << 16) |
4217 (sata_cmd.sata_fis.lbam << 8) |
4218 (sata_cmd.sata_fis.lbal));
4219 sata_cmd.twk_val1 =
4220 cpu_to_le32((sata_cmd.sata_fis.lbah_exp << 8) |
4221 (sata_cmd.sata_fis.lbam_exp));
4222 } else {
4223 PM8001_IO_DBG(pm8001_ha, pm8001_printk(
4224 "Sending Normal SATA command 0x%x inb %x\n",
Anand Kumar Santhanamf9cd6cb2013-09-18 11:12:59 +05304225 sata_cmd.sata_fis.command, q_index));
Sakthivel Kf5860992013-04-17 16:37:02 +05304226 /* dad (bit 0-1) is 0 */
4227 sata_cmd.ncqtag_atap_dir_m_dad =
4228 cpu_to_le32(((ncg_tag & 0xff)<<16) |
4229 ((ATAP & 0x3f) << 10) | dir);
4230
4231 /* fill in PRD (scatter/gather) table, if any */
4232 if (task->num_scatter > 1) {
4233 pm8001_chip_make_sg(task->scatter,
4234 ccb->n_elem, ccb->buf_prd);
4235 phys_addr = ccb->ccb_dma_handle +
4236 offsetof(struct pm8001_ccb_info, buf_prd[0]);
4237 sata_cmd.addr_low = lower_32_bits(phys_addr);
4238 sata_cmd.addr_high = upper_32_bits(phys_addr);
4239 sata_cmd.esgl = cpu_to_le32(1 << 31);
4240 } else if (task->num_scatter == 1) {
4241 u64 dma_addr = sg_dma_address(task->scatter);
4242 sata_cmd.addr_low = lower_32_bits(dma_addr);
4243 sata_cmd.addr_high = upper_32_bits(dma_addr);
4244 sata_cmd.len = cpu_to_le32(task->total_xfer_len);
4245 sata_cmd.esgl = 0;
Anand Kumar Santhanam0ecdf002013-09-18 11:14:54 +05304246 /* Check 4G Boundary */
4247 start_addr = cpu_to_le64(dma_addr);
4248 end_addr = (start_addr + sata_cmd.len) - 1;
4249 end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
4250 end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
4251 if (end_addr_high != sata_cmd.addr_high) {
4252 PM8001_FAIL_DBG(pm8001_ha,
4253 pm8001_printk("The sg list address "
4254 "start_addr=0x%016llx data_len=0x%x"
4255 "end_addr_high=0x%08x end_addr_low="
4256 "0x%08x has crossed 4G boundary\n",
4257 start_addr, sata_cmd.len,
4258 end_addr_high, end_addr_low));
4259 pm8001_chip_make_sg(task->scatter, 1,
4260 ccb->buf_prd);
4261 phys_addr = ccb->ccb_dma_handle +
4262 offsetof(struct pm8001_ccb_info,
4263 buf_prd[0]);
4264 sata_cmd.addr_low =
4265 lower_32_bits(phys_addr);
4266 sata_cmd.addr_high =
4267 upper_32_bits(phys_addr);
4268 sata_cmd.esgl = cpu_to_le32(1 << 31);
4269 }
Sakthivel Kf5860992013-04-17 16:37:02 +05304270 } else if (task->num_scatter == 0) {
4271 sata_cmd.addr_low = 0;
4272 sata_cmd.addr_high = 0;
4273 sata_cmd.len = cpu_to_le32(task->total_xfer_len);
4274 sata_cmd.esgl = 0;
4275 }
4276 /* scsi cdb */
4277 sata_cmd.atapi_scsi_cdb[0] =
4278 cpu_to_le32(((task->ata_task.atapi_packet[0]) |
4279 (task->ata_task.atapi_packet[1] << 8) |
4280 (task->ata_task.atapi_packet[2] << 16) |
4281 (task->ata_task.atapi_packet[3] << 24)));
4282 sata_cmd.atapi_scsi_cdb[1] =
4283 cpu_to_le32(((task->ata_task.atapi_packet[4]) |
4284 (task->ata_task.atapi_packet[5] << 8) |
4285 (task->ata_task.atapi_packet[6] << 16) |
4286 (task->ata_task.atapi_packet[7] << 24)));
4287 sata_cmd.atapi_scsi_cdb[2] =
4288 cpu_to_le32(((task->ata_task.atapi_packet[8]) |
4289 (task->ata_task.atapi_packet[9] << 8) |
4290 (task->ata_task.atapi_packet[10] << 16) |
4291 (task->ata_task.atapi_packet[11] << 24)));
4292 sata_cmd.atapi_scsi_cdb[3] =
4293 cpu_to_le32(((task->ata_task.atapi_packet[12]) |
4294 (task->ata_task.atapi_packet[13] << 8) |
4295 (task->ata_task.atapi_packet[14] << 16) |
4296 (task->ata_task.atapi_packet[15] << 24)));
4297 }
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05304298
4299 /* Check for read log for failed drive and return */
4300 if (sata_cmd.sata_fis.command == 0x2f) {
4301 if (pm8001_ha_dev && ((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) ||
4302 (pm8001_ha_dev->id & NCQ_ABORT_ALL_FLAG) ||
4303 (pm8001_ha_dev->id & NCQ_2ND_RLE_FLAG))) {
4304 struct task_status_struct *ts;
4305
4306 pm8001_ha_dev->id &= 0xDFFFFFFF;
4307 ts = &task->task_status;
4308
4309 spin_lock_irqsave(&task->task_state_lock, flags);
4310 ts->resp = SAS_TASK_COMPLETE;
4311 ts->stat = SAM_STAT_GOOD;
4312 task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
4313 task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
4314 task->task_state_flags |= SAS_TASK_STATE_DONE;
4315 if (unlikely((task->task_state_flags &
4316 SAS_TASK_STATE_ABORTED))) {
4317 spin_unlock_irqrestore(&task->task_state_lock,
4318 flags);
4319 PM8001_FAIL_DBG(pm8001_ha,
4320 pm8001_printk("task 0x%p resp 0x%x "
4321 " stat 0x%x but aborted by upper layer "
4322 "\n", task, ts->resp, ts->stat));
4323 pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
4324 return 0;
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05304325 } else {
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05304326 spin_unlock_irqrestore(&task->task_state_lock,
4327 flags);
Suresh Thiagarajan2b01d812014-01-16 15:26:21 +05304328 pm8001_ccb_task_free_done(pm8001_ha, task,
4329 ccb, tag);
Sakthivel Kc6b9ef52013-03-19 18:08:08 +05304330 return 0;
4331 }
4332 }
4333 }
Anand Kumar Santhanamf9cd6cb2013-09-18 11:12:59 +05304334 q_index = (u32) (pm8001_ha_dev->id & 0x00ffffff) % PM8001_MAX_OUTB_NUM;
Sakthivel Kf5860992013-04-17 16:37:02 +05304335 ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
Anand Kumar Santhanamf9cd6cb2013-09-18 11:12:59 +05304336 &sata_cmd, q_index);
Sakthivel Kf5860992013-04-17 16:37:02 +05304337 return ret;
4338}
4339
4340/**
4341 * pm80xx_chip_phy_start_req - start phy via PHY_START COMMAND
4342 * @pm8001_ha: our hba card information.
4343 * @num: the inbound queue number
4344 * @phy_id: the phy id which we wanted to start up.
4345 */
4346static int
4347pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
4348{
4349 struct phy_start_req payload;
4350 struct inbound_queue_table *circularQ;
4351 int ret;
4352 u32 tag = 0x01;
4353 u32 opcode = OPC_INB_PHYSTART;
4354 circularQ = &pm8001_ha->inbnd_q_tbl[0];
4355 memset(&payload, 0, sizeof(payload));
4356 payload.tag = cpu_to_le32(tag);
4357
4358 PM8001_INIT_DBG(pm8001_ha,
4359 pm8001_printk("PHY START REQ for phy_id %d\n", phy_id));
4360 /*
4361 ** [0:7] PHY Identifier
4362 ** [8:11] link rate 1.5G, 3G, 6G
4363 ** [12:13] link mode 01b SAS mode; 10b SATA mode; 11b Auto mode
4364 ** [14] 0b disable spin up hold; 1b enable spin up hold
4365 ** [15] ob no change in current PHY analig setup 1b enable using SPAST
4366 */
Anand Kumar Santhanama9a923e2013-09-03 15:09:42 +05304367 if (!IS_SPCV_12G(pm8001_ha->pdev))
4368 payload.ase_sh_lm_slr_phyid = cpu_to_le32(SPINHOLD_DISABLE |
4369 LINKMODE_AUTO | LINKRATE_15 |
4370 LINKRATE_30 | LINKRATE_60 | phy_id);
4371 else
4372 payload.ase_sh_lm_slr_phyid = cpu_to_le32(SPINHOLD_DISABLE |
4373 LINKMODE_AUTO | LINKRATE_15 |
4374 LINKRATE_30 | LINKRATE_60 | LINKRATE_120 |
4375 phy_id);
4376
Sakthivel Kf5860992013-04-17 16:37:02 +05304377 /* SSC Disable and SAS Analog ST configuration */
4378 /**
4379 payload.ase_sh_lm_slr_phyid =
4380 cpu_to_le32(SSC_DISABLE_30 | SAS_ASE | SPINHOLD_DISABLE |
4381 LINKMODE_AUTO | LINKRATE_15 | LINKRATE_30 | LINKRATE_60 |
4382 phy_id);
4383 Have to add "SAS PHY Analog Setup SPASTI 1 Byte" Based on need
4384 **/
4385
James Bottomleyaa9f8322013-05-07 14:44:06 -07004386 payload.sas_identify.dev_type = SAS_END_DEVICE;
Sakthivel Kf5860992013-04-17 16:37:02 +05304387 payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL;
4388 memcpy(payload.sas_identify.sas_addr,
4389 pm8001_ha->sas_addr, SAS_ADDR_SIZE);
4390 payload.sas_identify.phy_id = phy_id;
4391 ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, 0);
4392 return ret;
4393}
4394
4395/**
4396 * pm8001_chip_phy_stop_req - start phy via PHY_STOP COMMAND
4397 * @pm8001_ha: our hba card information.
4398 * @num: the inbound queue number
4399 * @phy_id: the phy id which we wanted to start up.
4400 */
4401static int pm80xx_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,
4402 u8 phy_id)
4403{
4404 struct phy_stop_req payload;
4405 struct inbound_queue_table *circularQ;
4406 int ret;
4407 u32 tag = 0x01;
4408 u32 opcode = OPC_INB_PHYSTOP;
4409 circularQ = &pm8001_ha->inbnd_q_tbl[0];
4410 memset(&payload, 0, sizeof(payload));
4411 payload.tag = cpu_to_le32(tag);
4412 payload.phy_id = cpu_to_le32(phy_id);
4413 ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, 0);
4414 return ret;
4415}
4416
4417/**
4418 * see comments on pm8001_mpi_reg_resp.
4419 */
4420static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
4421 struct pm8001_device *pm8001_dev, u32 flag)
4422{
4423 struct reg_dev_req payload;
4424 u32 opc;
4425 u32 stp_sspsmp_sata = 0x4;
4426 struct inbound_queue_table *circularQ;
4427 u32 linkrate, phy_id;
4428 int rc, tag = 0xdeadbeef;
4429 struct pm8001_ccb_info *ccb;
4430 u8 retryFlag = 0x1;
4431 u16 firstBurstSize = 0;
4432 u16 ITNT = 2000;
4433 struct domain_device *dev = pm8001_dev->sas_device;
4434 struct domain_device *parent_dev = dev->parent;
4435 circularQ = &pm8001_ha->inbnd_q_tbl[0];
4436
4437 memset(&payload, 0, sizeof(payload));
4438 rc = pm8001_tag_alloc(pm8001_ha, &tag);
4439 if (rc)
4440 return rc;
4441 ccb = &pm8001_ha->ccb_info[tag];
4442 ccb->device = pm8001_dev;
4443 ccb->ccb_tag = tag;
4444 payload.tag = cpu_to_le32(tag);
4445
4446 if (flag == 1) {
4447 stp_sspsmp_sata = 0x02; /*direct attached sata */
4448 } else {
James Bottomleyaa9f8322013-05-07 14:44:06 -07004449 if (pm8001_dev->dev_type == SAS_SATA_DEV)
Sakthivel Kf5860992013-04-17 16:37:02 +05304450 stp_sspsmp_sata = 0x00; /* stp*/
James Bottomleyaa9f8322013-05-07 14:44:06 -07004451 else if (pm8001_dev->dev_type == SAS_END_DEVICE ||
4452 pm8001_dev->dev_type == SAS_EDGE_EXPANDER_DEVICE ||
4453 pm8001_dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE)
Sakthivel Kf5860992013-04-17 16:37:02 +05304454 stp_sspsmp_sata = 0x01; /*ssp or smp*/
4455 }
4456 if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type))
4457 phy_id = parent_dev->ex_dev.ex_phy->phy_id;
4458 else
4459 phy_id = pm8001_dev->attached_phy;
4460
4461 opc = OPC_INB_REG_DEV;
4462
4463 linkrate = (pm8001_dev->sas_device->linkrate < dev->port->linkrate) ?
4464 pm8001_dev->sas_device->linkrate : dev->port->linkrate;
4465
4466 payload.phyid_portid =
4467 cpu_to_le32(((pm8001_dev->sas_device->port->id) & 0xFF) |
4468 ((phy_id & 0xFF) << 8));
4469
4470 payload.dtype_dlr_mcn_ir_retry = cpu_to_le32((retryFlag & 0x01) |
4471 ((linkrate & 0x0F) << 24) |
4472 ((stp_sspsmp_sata & 0x03) << 28));
4473 payload.firstburstsize_ITNexustimeout =
4474 cpu_to_le32(ITNT | (firstBurstSize * 0x10000));
4475
4476 memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr,
4477 SAS_ADDR_SIZE);
4478
4479 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
Tomas Henzl5533abc2014-07-09 17:20:49 +05304480 if (rc)
4481 pm8001_tag_free(pm8001_ha, tag);
Sakthivel Kf5860992013-04-17 16:37:02 +05304482
4483 return rc;
4484}
4485
4486/**
4487 * pm80xx_chip_phy_ctl_req - support the local phy operation
4488 * @pm8001_ha: our hba card information.
4489 * @num: the inbound queue number
4490 * @phy_id: the phy id which we wanted to operate
4491 * @phy_op:
4492 */
4493static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
4494 u32 phyId, u32 phy_op)
4495{
4496 struct local_phy_ctl_req payload;
4497 struct inbound_queue_table *circularQ;
4498 int ret;
4499 u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
4500 memset(&payload, 0, sizeof(payload));
4501 circularQ = &pm8001_ha->inbnd_q_tbl[0];
4502 payload.tag = cpu_to_le32(1);
4503 payload.phyop_phyid =
4504 cpu_to_le32(((phy_op & 0xFF) << 8) | (phyId & 0xFF));
4505 ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
4506 return ret;
4507}
4508
4509static u32 pm80xx_chip_is_our_interupt(struct pm8001_hba_info *pm8001_ha)
4510{
4511 u32 value;
4512#ifdef PM8001_USE_MSIX
4513 return 1;
4514#endif
4515 value = pm8001_cr32(pm8001_ha, 0, MSGU_ODR);
4516 if (value)
4517 return 1;
4518 return 0;
4519
4520}
4521
4522/**
4523 * pm8001_chip_isr - PM8001 isr handler.
4524 * @pm8001_ha: our hba card information.
4525 * @irq: irq number.
4526 * @stat: stat.
4527 */
4528static irqreturn_t
4529pm80xx_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec)
4530{
4531 pm80xx_chip_interrupt_disable(pm8001_ha, vec);
4532 process_oq(pm8001_ha, vec);
4533 pm80xx_chip_interrupt_enable(pm8001_ha, vec);
4534 return IRQ_HANDLED;
4535}
4536
Anand Kumar Santhanam27909402013-09-18 13:02:44 +05304537void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
4538 u32 operation, u32 phyid, u32 length, u32 *buf)
4539{
4540 u32 tag , i, j = 0;
4541 int rc;
4542 struct set_phy_profile_req payload;
4543 struct inbound_queue_table *circularQ;
4544 u32 opc = OPC_INB_SET_PHY_PROFILE;
4545
4546 memset(&payload, 0, sizeof(payload));
4547 rc = pm8001_tag_alloc(pm8001_ha, &tag);
4548 if (rc)
4549 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Invalid tag\n"));
4550 circularQ = &pm8001_ha->inbnd_q_tbl[0];
4551 payload.tag = cpu_to_le32(tag);
4552 payload.ppc_phyid = (((operation & 0xF) << 8) | (phyid & 0xFF));
4553 PM8001_INIT_DBG(pm8001_ha,
4554 pm8001_printk(" phy profile command for phy %x ,length is %d\n",
4555 payload.ppc_phyid, length));
4556 for (i = length; i < (length + PHY_DWORD_LENGTH - 1); i++) {
4557 payload.reserved[j] = cpu_to_le32(*((u32 *)buf + i));
4558 j++;
4559 }
Tomas Henzl5533abc2014-07-09 17:20:49 +05304560 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
4561 if (rc)
4562 pm8001_tag_free(pm8001_ha, tag);
Anand Kumar Santhanam27909402013-09-18 13:02:44 +05304563}
4564
4565void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
4566 u32 length, u8 *buf)
4567{
4568 u32 page_code, i;
4569
4570 page_code = SAS_PHY_ANALOG_SETTINGS_PAGE;
4571 for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
4572 mpi_set_phy_profile_req(pm8001_ha,
4573 SAS_PHY_ANALOG_SETTINGS_PAGE, i, length, (u32 *)buf);
4574 length = length + PHY_DWORD_LENGTH;
4575 }
4576 PM8001_INIT_DBG(pm8001_ha, pm8001_printk("phy settings completed\n"));
4577}
Sakthivel Kf5860992013-04-17 16:37:02 +05304578const struct pm8001_dispatch pm8001_80xx_dispatch = {
4579 .name = "pmc80xx",
4580 .chip_init = pm80xx_chip_init,
4581 .chip_soft_rst = pm80xx_chip_soft_rst,
4582 .chip_rst = pm80xx_hw_chip_rst,
4583 .chip_iounmap = pm8001_chip_iounmap,
4584 .isr = pm80xx_chip_isr,
4585 .is_our_interupt = pm80xx_chip_is_our_interupt,
4586 .isr_process_oq = process_oq,
4587 .interrupt_enable = pm80xx_chip_interrupt_enable,
4588 .interrupt_disable = pm80xx_chip_interrupt_disable,
4589 .make_prd = pm8001_chip_make_sg,
4590 .smp_req = pm80xx_chip_smp_req,
4591 .ssp_io_req = pm80xx_chip_ssp_io_req,
4592 .sata_req = pm80xx_chip_sata_req,
4593 .phy_start_req = pm80xx_chip_phy_start_req,
4594 .phy_stop_req = pm80xx_chip_phy_stop_req,
4595 .reg_dev_req = pm80xx_chip_reg_dev_req,
4596 .dereg_dev_req = pm8001_chip_dereg_dev_req,
4597 .phy_ctl_req = pm80xx_chip_phy_ctl_req,
4598 .task_abort = pm8001_chip_abort_task,
4599 .ssp_tm_req = pm8001_chip_ssp_tm_req,
4600 .get_nvmd_req = pm8001_chip_get_nvmd_req,
4601 .set_nvmd_req = pm8001_chip_set_nvmd_req,
4602 .fw_flash_update_req = pm8001_chip_fw_flash_update_req,
4603 .set_dev_state_req = pm8001_chip_set_dev_state_req,
4604};