aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hisi_sas
diff options
context:
space:
mode:
authorJohn Garry <john.garry@huawei.com>2016-01-25 13:47:19 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2016-02-23 21:27:02 -0500
commit85b2c3c040ccb15109bb286139b03ce8817b2c7c (patch)
tree5cde129eacc9e1eaa014cc585785722bf32cf39e /drivers/scsi/hisi_sas
parentc2d89392753aded5719dcdb85b45e7c249ea19b7 (diff)
hisi_sas: add v2 code for itct setup and free
Signed-off-by: John Garry <john.garry@huawei.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/hisi_sas')
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v2_hw.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 2c6a753e0933..8b51acf9e23d 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -353,6 +353,96 @@ static void init_id_frame_v2_hw(struct hisi_hba *hisi_hba)
353 config_id_frame_v2_hw(hisi_hba, i); 353 config_id_frame_v2_hw(hisi_hba, i);
354} 354}
355 355
356static void setup_itct_v2_hw(struct hisi_hba *hisi_hba,
357 struct hisi_sas_device *sas_dev)
358{
359 struct domain_device *device = sas_dev->sas_device;
360 struct device *dev = &hisi_hba->pdev->dev;
361 u64 qw0, device_id = sas_dev->device_id;
362 struct hisi_sas_itct *itct = &hisi_hba->itct[device_id];
363 struct domain_device *parent_dev = device->parent;
364 struct hisi_sas_port *port = device->port->lldd_port;
365
366 memset(itct, 0, sizeof(*itct));
367
368 /* qw0 */
369 qw0 = 0;
370 switch (sas_dev->dev_type) {
371 case SAS_END_DEVICE:
372 case SAS_EDGE_EXPANDER_DEVICE:
373 case SAS_FANOUT_EXPANDER_DEVICE:
374 qw0 = HISI_SAS_DEV_TYPE_SSP << ITCT_HDR_DEV_TYPE_OFF;
375 break;
376 case SAS_SATA_DEV:
377 if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type))
378 qw0 = HISI_SAS_DEV_TYPE_STP << ITCT_HDR_DEV_TYPE_OFF;
379 else
380 qw0 = HISI_SAS_DEV_TYPE_SATA << ITCT_HDR_DEV_TYPE_OFF;
381 break;
382 default:
383 dev_warn(dev, "setup itct: unsupported dev type (%d)\n",
384 sas_dev->dev_type);
385 }
386
387 qw0 |= ((1 << ITCT_HDR_VALID_OFF) |
388 (device->max_linkrate << ITCT_HDR_MCR_OFF) |
389 (1 << ITCT_HDR_VLN_OFF) |
390 (port->id << ITCT_HDR_PORT_ID_OFF));
391 itct->qw0 = cpu_to_le64(qw0);
392
393 /* qw1 */
394 memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE);
395 itct->sas_addr = __swab64(itct->sas_addr);
396
397 /* qw2 */
398 itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_INLT_OFF) |
399 (0xff00ULL << ITCT_HDR_BITLT_OFF) |
400 (0xff00ULL << ITCT_HDR_MCTLT_OFF) |
401 (0xff00ULL << ITCT_HDR_RTOLT_OFF));
402}
403
404static void free_device_v2_hw(struct hisi_hba *hisi_hba,
405 struct hisi_sas_device *sas_dev)
406{
407 u64 qw0, dev_id = sas_dev->device_id;
408 struct device *dev = &hisi_hba->pdev->dev;
409 struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id];
410 u32 reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);
411 int i;
412
413 /* clear the itct interrupt state */
414 if (ENT_INT_SRC3_ITC_INT_MSK & reg_val)
415 hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
416 ENT_INT_SRC3_ITC_INT_MSK);
417
418 /* clear the itct int*/
419 for (i = 0; i < 2; i++) {
420 /* clear the itct table*/
421 reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR);
422 reg_val |= ITCT_CLR_EN_MSK | (dev_id & ITCT_DEV_MSK);
423 hisi_sas_write32(hisi_hba, ITCT_CLR, reg_val);
424
425 udelay(10);
426 reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);
427 if (ENT_INT_SRC3_ITC_INT_MSK & reg_val) {
428 dev_dbg(dev, "got clear ITCT done interrupt\n");
429
430 /* invalid the itct state*/
431 qw0 = cpu_to_le64(itct->qw0);
432 qw0 &= ~(1 << ITCT_HDR_VALID_OFF);
433 hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
434 ENT_INT_SRC3_ITC_INT_MSK);
435 hisi_hba->devices[dev_id].dev_type = SAS_PHY_UNUSED;
436 hisi_hba->devices[dev_id].dev_status = HISI_SAS_DEV_NORMAL;
437
438 /* clear the itct */
439 hisi_sas_write32(hisi_hba, ITCT_CLR, 0);
440 dev_dbg(dev, "clear ITCT ok\n");
441 break;
442 }
443 }
444}
445
356static int reset_hw_v2_hw(struct hisi_hba *hisi_hba) 446static int reset_hw_v2_hw(struct hisi_hba *hisi_hba)
357{ 447{
358 int i, reset_val; 448 int i, reset_val;
@@ -1463,8 +1553,10 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)
1463 1553
1464static const struct hisi_sas_hw hisi_sas_v2_hw = { 1554static const struct hisi_sas_hw hisi_sas_v2_hw = {
1465 .hw_init = hisi_sas_v2_init, 1555 .hw_init = hisi_sas_v2_init,
1556 .setup_itct = setup_itct_v2_hw,
1466 .sl_notify = sl_notify_v2_hw, 1557 .sl_notify = sl_notify_v2_hw,
1467 .get_wideport_bitmap = get_wideport_bitmap_v2_hw, 1558 .get_wideport_bitmap = get_wideport_bitmap_v2_hw,
1559 .free_device = free_device_v2_hw,
1468 .prep_smp = prep_smp_v2_hw, 1560 .prep_smp = prep_smp_v2_hw,
1469 .prep_ssp = prep_ssp_v2_hw, 1561 .prep_ssp = prep_ssp_v2_hw,
1470 .get_free_slot = get_free_slot_v2_hw, 1562 .get_free_slot = get_free_slot_v2_hw,