diff options
author | John Garry <john.garry@huawei.com> | 2016-01-25 13:47:19 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-02-23 21:27:02 -0500 |
commit | 85b2c3c040ccb15109bb286139b03ce8817b2c7c (patch) | |
tree | 5cde129eacc9e1eaa014cc585785722bf32cf39e /drivers/scsi/hisi_sas | |
parent | c2d89392753aded5719dcdb85b45e7c249ea19b7 (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.c | 92 |
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 | ||
356 | static 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 | |||
404 | static 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 | |||
356 | static int reset_hw_v2_hw(struct hisi_hba *hisi_hba) | 446 | static 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 | ||
1464 | static const struct hisi_sas_hw hisi_sas_v2_hw = { | 1554 | static 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, |