^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is provided under a dual BSD/GPLv2 license. When using or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * redistributing this file, you may do so under either license.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * GPL LICENSE SUMMARY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * it under the terms of version 2 of the GNU General Public License as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This program is distributed in the hope that it will be useful, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * The full GNU General Public License is included in this distribution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * in the file called LICENSE.GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * BSD LICENSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * * Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * * Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * notice, this list of conditions and the following disclaimer in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * the documentation and/or other materials provided with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * * Neither the name of Intel Corporation nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * contributors may be used to endorse or promote products derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include "isci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include "host.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include "phy.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include "scu_event_codes.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include "probe_roms.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #undef C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define C(a) (#a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static const char *phy_state_name(enum sci_phy_states state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static const char * const strings[] = PHY_STATES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return strings[state];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #undef C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Maximum arbitration wait time in micro-seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) enum sas_linkrate sci_phy_linkrate(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return iphy->max_negotiated_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static struct isci_host *phy_to_host(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct isci_phy *table = iphy - iphy->phy_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct isci_host *ihost = container_of(table, typeof(*ihost), phys[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return ihost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static struct device *sciphy_to_dev(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return &phy_to_host(iphy)->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static enum sci_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) sci_phy_transport_layer_initialization(struct isci_phy *iphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct scu_transport_layer_registers __iomem *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u32 tl_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) iphy->transport_layer_registers = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) writel(SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) &iphy->transport_layer_registers->stp_rni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Hardware team recommends that we enable the STP prefetch for all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * transports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) tl_control = readl(&iphy->transport_layer_registers->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) writel(tl_control, &iphy->transport_layer_registers->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static enum sci_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) sci_phy_link_layer_initialization(struct isci_phy *iphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct scu_link_layer_registers __iomem *llr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct isci_host *ihost = iphy->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct sci_phy_user_params *phy_user;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct sci_phy_oem_params *phy_oem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int phy_idx = iphy->phy_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct sci_phy_cap phy_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) u32 phy_configuration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u32 parity_check = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u32 parity_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u32 llctl, link_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u32 clksm_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u32 sp_timeouts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) phy_user = &ihost->user_parameters.phys[phy_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) phy_oem = &ihost->oem_parameters.phys[phy_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) iphy->link_layer_registers = llr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* Set our IDENTIFY frame data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define SCI_END_DEVICE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) writel(SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) SCU_SAS_TIID_GEN_BIT(STP_INITIATOR) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) &llr->transmit_identification);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Write the device SAS Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) writel(0xFEDCBA98, &llr->sas_device_name_high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) writel(phy_idx, &llr->sas_device_name_low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Write the source SAS Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) writel(phy_oem->sas_address.high, &llr->source_sas_address_high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) writel(phy_oem->sas_address.low, &llr->source_sas_address_low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Clear and Set the PHY Identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) writel(0, &llr->identify_frame_phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) writel(SCU_SAS_TIPID_GEN_VALUE(ID, phy_idx), &llr->identify_frame_phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* Change the initial state of the phy configuration register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) phy_configuration = readl(&llr->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Hold OOB state machine in reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) phy_configuration |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) writel(phy_configuration, &llr->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* Configure the SNW capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) phy_cap.all = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) phy_cap.start = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) phy_cap.gen3_no_ssc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) phy_cap.gen2_no_ssc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) phy_cap.gen1_no_ssc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (ihost->oem_parameters.controller.do_enable_ssc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct scu_afe_transceiver __iomem *xcvr = &afe->scu_afe_xcvr[phy_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct isci_pci_info *pci_info = to_pci_info(ihost->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) bool en_sas = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) bool en_sata = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u32 sas_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u32 sata_spread = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u32 sas_spread = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) phy_cap.gen3_ssc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) phy_cap.gen2_ssc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) phy_cap.gen1_ssc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (pci_info->orom->hdr.version < ISCI_ROM_VER_1_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) en_sas = en_sata = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) sata_spread = ihost->oem_parameters.controller.ssc_sata_tx_spread_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) sas_spread = ihost->oem_parameters.controller.ssc_sas_tx_spread_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (sata_spread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) en_sata = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (sas_spread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) en_sas = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) sas_type = ihost->oem_parameters.controller.ssc_sas_tx_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (en_sas) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) reg = readl(&xcvr->afe_xcvr_control0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) reg |= (0x00100000 | (sas_type << 19));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) writel(reg, &xcvr->afe_xcvr_control0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) reg = readl(&xcvr->afe_tx_ssc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) reg |= sas_spread << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) writel(reg, &xcvr->afe_tx_ssc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (en_sata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) reg = readl(&xcvr->afe_tx_ssc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) reg |= sata_spread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) writel(reg, &xcvr->afe_tx_ssc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) reg = readl(&llr->stp_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) reg |= 1 << 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) writel(reg, &llr->stp_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* The SAS specification indicates that the phy_capabilities that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * are transmitted shall have an even parity. Calculate the parity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) parity_check = phy_cap.all;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) while (parity_check != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (parity_check & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) parity_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) parity_check >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* If parity indicates there are an odd number of bits set, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * set the parity bit to 1 in the phy capabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if ((parity_count % 2) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) phy_cap.parity = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) writel(phy_cap.all, &llr->phy_capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* Set the enable spinup period but disable the ability to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * notify enable spinup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) writel(SCU_ENSPINUP_GEN_VAL(COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) phy_user->notify_enable_spin_up_insertion_frequency),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) &llr->notify_enable_spinup_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* Write the ALIGN Insertion Ferequency for connected phy and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * inpendent of connected state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) phy_user->in_connection_align_insertion_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) phy_user->align_insertion_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) writel(clksm_value, &llr->clock_skew_management);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (is_c0(ihost->pdev) || is_c1(ihost->pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) writel(0x04210400, &llr->afe_lookup_table_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) writel(0x020A7C05, &llr->sas_primitive_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) writel(0x02108421, &llr->afe_lookup_table_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) (u8)ihost->user_parameters.no_outbound_task_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) switch (phy_user->max_speed_generation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case SCIC_SDS_PARM_GEN3_SPEED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case SCIC_SDS_PARM_GEN2_SPEED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) writel(llctl, &llr->link_layer_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) sp_timeouts = readl(&llr->sas_phy_timeouts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* Set RATE_CHANGE timeout value to 0x3B (59us). This ensures SCU can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * lock with 3Gb drive when SCU max rate is set to 1.5Gb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) writel(sp_timeouts, &llr->sas_phy_timeouts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (is_a2(ihost->pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* Program the max ARB time for the PHY to 700us so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * inter-operate with the PMC expander which shuts down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * PHYs if the expander PHY generates too many breaks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * This time value will guarantee that the initiator PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * will generate the break.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) &llr->maximum_arbitration_wait_timer_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Disable link layer hang detection, rely on the OS timeout for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * I/O timeouts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) writel(0, &llr->link_layer_hang_detection_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* We can exit the initial state to the stopped state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static void phy_sata_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct sci_timer *tmr = from_timer(tmr, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct isci_phy *iphy = container_of(tmr, typeof(*iphy), sata_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct isci_host *ihost = iphy->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (tmr->cancel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) dev_dbg(sciphy_to_dev(iphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) "timeout.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * This method returns the port currently containing this phy. If the phy is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * currently contained by the dummy port, then the phy is considered to not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * be part of a port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * @sci_phy: This parameter specifies the phy for which to retrieve the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * containing port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * This method returns a handle to a port that contains the supplied phy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * NULL This value is returned if the phy is not part of a real
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * port (i.e. it's contained in the dummy port). !NULL All other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * values indicate a handle/pointer to the port containing the phy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct isci_port *phy_get_non_dummy_port(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct isci_port *iport = iphy->owning_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (iport->physical_port_index == SCIC_SDS_DUMMY_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return iphy->owning_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * This method will assign a port to the phy object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * @out]: iphy This parameter specifies the phy for which to assign a port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) void sci_phy_set_port(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct isci_phy *iphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct isci_port *iport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) iphy->owning_port = iport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (iphy->bcn_received_while_port_unassigned) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) iphy->bcn_received_while_port_unassigned = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) sci_port_broadcast_change_received(iphy->owning_port, iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) enum sci_status sci_phy_initialize(struct isci_phy *iphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct scu_transport_layer_registers __iomem *tl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct scu_link_layer_registers __iomem *ll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* Perfrom the initialization of the TL hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) sci_phy_transport_layer_initialization(iphy, tl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* Perofrm the initialization of the PE hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) sci_phy_link_layer_initialization(iphy, ll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* There is nothing that needs to be done in this state just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * transition to the stopped state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * This method assigns the direct attached device ID for this phy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * @iphy The phy for which the direct attached device id is to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * be assigned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * @device_id The direct attached device ID to assign to the phy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * This will either be the RNi for the device or an invalid RNi if there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * is no current device assigned to the phy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) void sci_phy_setup_transport(struct isci_phy *iphy, u32 device_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) u32 tl_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) writel(device_id, &iphy->transport_layer_registers->stp_rni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * The read should guarantee that the first write gets posted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * before the next write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) tl_control = readl(&iphy->transport_layer_registers->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) writel(tl_control, &iphy->transport_layer_registers->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static void sci_phy_suspend(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) u32 scu_sas_pcfg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) scu_sas_pcfg_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) readl(&iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) writel(scu_sas_pcfg_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) &iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) sci_phy_setup_transport(iphy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) void sci_phy_resume(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) u32 scu_sas_pcfg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) scu_sas_pcfg_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) readl(&iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) writel(scu_sas_pcfg_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) &iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) void sci_phy_get_sas_address(struct isci_phy *iphy, struct sci_sas_address *sas)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) sas->high = readl(&iphy->link_layer_registers->source_sas_address_high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) sas->low = readl(&iphy->link_layer_registers->source_sas_address_low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) void sci_phy_get_attached_sas_address(struct isci_phy *iphy, struct sci_sas_address *sas)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct sas_identify_frame *iaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) iaf = &iphy->frame_rcvd.iaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) memcpy(sas, iaf->sas_addr, SAS_ADDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) void sci_phy_get_protocols(struct isci_phy *iphy, struct sci_phy_proto *proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) proto->all = readl(&iphy->link_layer_registers->transmit_identification);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) enum sci_status sci_phy_start(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) enum sci_phy_states state = iphy->sm.current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (state != SCI_PHY_STOPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) __func__, phy_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) enum sci_status sci_phy_stop(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) enum sci_phy_states state = iphy->sm.current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) case SCI_PHY_SUB_INITIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case SCI_PHY_SUB_AWAIT_OSSP_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) case SCI_PHY_SUB_AWAIT_SAS_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) case SCI_PHY_SUB_AWAIT_SATA_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) case SCI_PHY_SUB_FINAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) case SCI_PHY_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) __func__, phy_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) enum sci_status sci_phy_reset(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) enum sci_phy_states state = iphy->sm.current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (state != SCI_PHY_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) __func__, phy_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) sci_change_state(&iphy->sm, SCI_PHY_RESETTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) enum sci_status sci_phy_consume_power_handler(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) enum sci_phy_states state = iphy->sm.current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) case SCI_PHY_SUB_AWAIT_SAS_POWER: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) u32 enable_spinup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) enable_spinup = readl(&iphy->link_layer_registers->notify_enable_spinup_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) writel(enable_spinup, &iphy->link_layer_registers->notify_enable_spinup_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* Change state to the final state this substate machine has run to completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) sci_change_state(&iphy->sm, SCI_PHY_SUB_FINAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) case SCI_PHY_SUB_AWAIT_SATA_POWER: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) u32 scu_sas_pcfg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* Release the spinup hold state and reset the OOB state machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) scu_sas_pcfg_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) readl(&iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) scu_sas_pcfg_value &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) writel(scu_sas_pcfg_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) &iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* Now restart the OOB operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) writel(scu_sas_pcfg_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) &iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* Change state to the final state this substate machine has run to completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_PHY_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) __func__, phy_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static void sci_phy_start_sas_link_training(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* continue the link training for the phy as if it were a SAS PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * instead of a SATA PHY. This is done because the completion queue had a SAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * PHY DETECTED event when the state machine was expecting a SATA PHY event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) u32 phy_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) phy_control = readl(&iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) writel(phy_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) &iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SAS_SPEED_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) iphy->protocol = SAS_PROTOCOL_SSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static void sci_phy_start_sata_link_training(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* This method continues the link training for the phy as if it were a SATA PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * instead of a SAS PHY. This is done because the completion queue had a SATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) iphy->protocol = SAS_PROTOCOL_SATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * sci_phy_complete_link_training - perform processing common to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * all protocols upon completion of link training.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * @sci_phy: This parameter specifies the phy object for which link training
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * has completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * @max_link_rate: This parameter specifies the maximum link rate to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * associated with this phy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * @next_state: This parameter specifies the next state for the phy's starting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * sub-state machine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static void sci_phy_complete_link_training(struct isci_phy *iphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) enum sas_linkrate max_link_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) u32 next_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) iphy->max_negotiated_speed = max_link_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) sci_change_state(&iphy->sm, next_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static const char *phy_event_name(u32 event_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) case SCU_EVENT_PORT_SELECTOR_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return "port selector";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) case SCU_EVENT_SENT_PORT_SELECTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return "port selection";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case SCU_EVENT_HARD_RESET_TRANSMITTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return "tx hard reset";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) case SCU_EVENT_HARD_RESET_RECEIVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) return "rx hard reset";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return "identify timeout";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) case SCU_EVENT_LINK_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return "link fail";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) case SCU_EVENT_SATA_SPINUP_HOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return "sata spinup hold";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) case SCU_EVENT_SAS_15_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case SCU_EVENT_SAS_15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return "sas 1.5";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) case SCU_EVENT_SAS_30_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) case SCU_EVENT_SAS_30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return "sas 3.0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) case SCU_EVENT_SAS_60_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) case SCU_EVENT_SAS_60:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return "sas 6.0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) case SCU_EVENT_SATA_15_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) case SCU_EVENT_SATA_15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return "sata 1.5";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) case SCU_EVENT_SATA_30_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) case SCU_EVENT_SATA_30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return "sata 3.0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) case SCU_EVENT_SATA_60_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) case SCU_EVENT_SATA_60:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return "sata 6.0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) case SCU_EVENT_SAS_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return "sas detect";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) case SCU_EVENT_SATA_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return "sata detect";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) #define phy_event_dbg(iphy, state, code) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) dev_dbg(sciphy_to_dev(iphy), "phy-%d:%d: %s event: %s (%x)\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) phy_to_host(iphy)->id, iphy->phy_index, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) phy_state_name(state), phy_event_name(code), code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) #define phy_event_warn(iphy, state, code) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) dev_warn(sciphy_to_dev(iphy), "phy-%d:%d: %s event: %s (%x)\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) phy_to_host(iphy)->id, iphy->phy_index, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) phy_state_name(state), phy_event_name(code), code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static void scu_link_layer_set_txcomsas_timeout(struct isci_phy *iphy, u32 timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* Extend timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) val = readl(&iphy->link_layer_registers->transmit_comsas_signal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) val &= ~SCU_SAS_LLTXCOMSAS_GEN_VAL(NEGTIME, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) val |= SCU_SAS_LLTXCOMSAS_GEN_VAL(NEGTIME, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) writel(val, &iphy->link_layer_registers->transmit_comsas_signal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) enum sci_phy_states state = iphy->sm.current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) case SCI_PHY_SUB_AWAIT_OSSP_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) case SCU_EVENT_SAS_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) sci_phy_start_sas_link_training(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) iphy->is_in_link_training = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) case SCU_EVENT_SATA_SPINUP_HOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) sci_phy_start_sata_link_training(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) iphy->is_in_link_training = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /* Extend timeout value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_EXTENDED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /* Start the oob/sn state machine over again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) phy_event_dbg(iphy, state, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return SCI_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) case SCU_EVENT_SAS_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * Why is this being reported again by the controller?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * We would re-enter this state so just stay here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) case SCU_EVENT_SAS_15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) case SCU_EVENT_SAS_15_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) sci_phy_complete_link_training(iphy, SAS_LINK_RATE_1_5_GBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) SCI_PHY_SUB_AWAIT_IAF_UF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) case SCU_EVENT_SAS_30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) case SCU_EVENT_SAS_30_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) sci_phy_complete_link_training(iphy, SAS_LINK_RATE_3_0_GBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) SCI_PHY_SUB_AWAIT_IAF_UF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) case SCU_EVENT_SAS_60:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) case SCU_EVENT_SAS_60_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) sci_phy_complete_link_training(iphy, SAS_LINK_RATE_6_0_GBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) SCI_PHY_SUB_AWAIT_IAF_UF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) case SCU_EVENT_SATA_SPINUP_HOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * We were doing SAS PHY link training and received a SATA PHY event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * continue OOB/SN as if this were a SATA PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) sci_phy_start_sata_link_training(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) case SCU_EVENT_LINK_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* Change the timeout value to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* Link failure change state back to the starting state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* Extend the timeout value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_EXTENDED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) /* Start the oob/sn state machine over again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) phy_event_warn(iphy, state, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return SCI_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) case SCI_PHY_SUB_AWAIT_IAF_UF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) case SCU_EVENT_SAS_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* Backup the state machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) sci_phy_start_sas_link_training(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) case SCU_EVENT_SATA_SPINUP_HOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /* We were doing SAS PHY link training and received a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * SATA PHY event continue OOB/SN as if this were a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * SATA PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) sci_phy_start_sata_link_training(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /* Extend the timeout value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_EXTENDED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /* Start the oob/sn state machine over again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) case SCU_EVENT_LINK_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) case SCU_EVENT_HARD_RESET_RECEIVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* Start the oob/sn state machine over again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) phy_event_warn(iphy, state, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return SCI_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case SCI_PHY_SUB_AWAIT_SAS_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) case SCU_EVENT_LINK_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) /* Change the timeout value to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) /* Link failure change state back to the starting state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) phy_event_warn(iphy, state, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return SCI_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) case SCI_PHY_SUB_AWAIT_SATA_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) case SCU_EVENT_LINK_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* Change the timeout value to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* Link failure change state back to the starting state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) case SCU_EVENT_SATA_SPINUP_HOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* These events are received every 10ms and are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * expected while in this state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) case SCU_EVENT_SAS_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /* There has been a change in the phy type before OOB/SN for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * SATA finished start down the SAS link traning path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) sci_phy_start_sas_link_training(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) phy_event_warn(iphy, state, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return SCI_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) case SCU_EVENT_LINK_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* Change the timeout value to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /* Link failure change state back to the starting state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) case SCU_EVENT_SATA_SPINUP_HOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) /* These events might be received since we dont know how many may be in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * the completion queue while waiting for power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case SCU_EVENT_SATA_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) iphy->protocol = SAS_PROTOCOL_SATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /* We have received the SATA PHY notification change state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) case SCU_EVENT_SAS_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) /* There has been a change in the phy type before OOB/SN for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * SATA finished start down the SAS link traning path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) sci_phy_start_sas_link_training(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) phy_event_warn(iphy, state, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return SCI_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) case SCU_EVENT_SATA_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * The hardware reports multiple SATA PHY detected events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * ignore the extras */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) case SCU_EVENT_SATA_15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) case SCU_EVENT_SATA_15_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) sci_phy_complete_link_training(iphy, SAS_LINK_RATE_1_5_GBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) case SCU_EVENT_SATA_30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case SCU_EVENT_SATA_30_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) sci_phy_complete_link_training(iphy, SAS_LINK_RATE_3_0_GBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) case SCU_EVENT_SATA_60:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) case SCU_EVENT_SATA_60_SSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) sci_phy_complete_link_training(iphy, SAS_LINK_RATE_6_0_GBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) case SCU_EVENT_LINK_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* Change the timeout value to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) /* Link failure change state back to the starting state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) case SCU_EVENT_SAS_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * There has been a change in the phy type before OOB/SN for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * SATA finished start down the SAS link traning path. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) sci_phy_start_sas_link_training(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) phy_event_warn(iphy, state, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return SCI_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case SCU_EVENT_SATA_PHY_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* Backup the state machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) case SCU_EVENT_LINK_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /* Change the timeout value to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) /* Link failure change state back to the starting state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) phy_event_warn(iphy, state, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return SCI_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) case SCI_PHY_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) case SCU_EVENT_LINK_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) /* Set default timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /* Link failure change state back to the starting state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) case SCU_EVENT_BROADCAST_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) case SCU_EVENT_BROADCAST_SES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) case SCU_EVENT_BROADCAST_RESERVED0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) case SCU_EVENT_BROADCAST_RESERVED1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) case SCU_EVENT_BROADCAST_EXPANDER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) case SCU_EVENT_BROADCAST_AEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) /* Broadcast change received. Notify the port. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (phy_get_non_dummy_port(iphy) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) sci_port_broadcast_change_received(iphy->owning_port, iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) iphy->bcn_received_while_port_unassigned = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) case SCU_EVENT_BROADCAST_RESERVED3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) case SCU_EVENT_BROADCAST_RESERVED4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) phy_event_warn(iphy, state, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case SCI_PHY_RESETTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) switch (scu_get_event_code(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) case SCU_EVENT_HARD_RESET_TRANSMITTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) /* Link failure change state back to the starting state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) phy_event_warn(iphy, state, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) __func__, phy_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) enum sci_status sci_phy_frame_handler(struct isci_phy *iphy, u32 frame_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) enum sci_phy_states state = iphy->sm.current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct isci_host *ihost = iphy->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) enum sci_status result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) case SCI_PHY_SUB_AWAIT_IAF_UF: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) u32 *frame_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct sas_identify_frame iaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) result = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) frame_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) (void **)&frame_words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (result != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (iaf.frame_type == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) u32 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (iaf.smp_tport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /* We got the IAF for an expander PHY go to the final
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * state since there are no power requirements for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * expander phys.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) state = SCI_PHY_SUB_FINAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) /* We got the IAF we can now go to the await spinup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) * semaphore state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) state = SCI_PHY_SUB_AWAIT_SAS_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) sci_change_state(&iphy->sm, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) result = SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) dev_warn(sciphy_to_dev(iphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) "%s: PHY starting substate machine received "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) "unexpected frame id %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) __func__, frame_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) sci_controller_release_frame(ihost, frame_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) case SCI_PHY_SUB_AWAIT_SIG_FIS_UF: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct dev_to_host_fis *frame_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) u32 *fis_frame_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) result = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) frame_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) (void **)&frame_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (result != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if ((frame_header->fis_type == FIS_REGD2H) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) !(frame_header->status & ATA_BUSY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) frame_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) (void **)&fis_frame_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) sci_controller_copy_sata_response(&iphy->frame_rcvd.fis,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) frame_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) fis_frame_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /* got IAF we can now go to the await spinup semaphore state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) sci_change_state(&iphy->sm, SCI_PHY_SUB_FINAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) result = SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) dev_warn(sciphy_to_dev(iphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) "%s: PHY starting substate machine received "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) "unexpected frame id %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) __func__, frame_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /* Regardless of the result we are done with this frame with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) sci_controller_release_frame(ihost, frame_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) __func__, phy_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) static void sci_phy_starting_initial_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) /* This is just an temporary state go off to the starting state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_OSSP_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) static void sci_phy_starting_await_sas_power_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct isci_host *ihost = iphy->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) sci_controller_power_control_queue_insert(ihost, iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static void sci_phy_starting_await_sas_power_substate_exit(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) struct isci_host *ihost = iphy->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) sci_controller_power_control_queue_remove(ihost, iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) static void sci_phy_starting_await_sata_power_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) struct isci_host *ihost = iphy->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) sci_controller_power_control_queue_insert(ihost, iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) static void sci_phy_starting_await_sata_power_substate_exit(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct isci_host *ihost = iphy->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) sci_controller_power_control_queue_remove(ihost, iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) static void sci_phy_starting_await_sata_phy_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) sci_mod_timer(&iphy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) static void sci_phy_starting_await_sata_phy_substate_exit(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) sci_del_timer(&iphy->sata_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static void sci_phy_starting_await_sata_speed_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) sci_mod_timer(&iphy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) static void sci_phy_starting_await_sata_speed_substate_exit(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) sci_del_timer(&iphy->sata_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) static void sci_phy_starting_await_sig_fis_uf_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (sci_port_link_detected(iphy->owning_port, iphy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) * Clear the PE suspend condition so we can actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) * receive SIG FIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) * The hardware will not respond to the XRDY until the PE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) * suspend condition is cleared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) sci_phy_resume(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) sci_mod_timer(&iphy->sata_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) SCIC_SDS_SIGNATURE_FIS_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) iphy->is_in_link_training = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) static void sci_phy_starting_await_sig_fis_uf_substate_exit(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) sci_del_timer(&iphy->sata_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) static void sci_phy_starting_final_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) /* State machine has run to completion so exit out and change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) * the base state machine to the ready state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) sci_change_state(&iphy->sm, SCI_PHY_READY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * @sci_phy: This is the struct isci_phy object to stop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * This method will stop the struct isci_phy object. This does not reset the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * protocol engine it just suspends it and places it in a state where it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * not cause the end device to power up. none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) static void scu_link_layer_stop_protocol_engine(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) u32 scu_sas_pcfg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) u32 enable_spinup_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* Suspend the protocol engine and place it in a sata spinup hold state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) scu_sas_pcfg_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) readl(&iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) scu_sas_pcfg_value |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) (SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) writel(scu_sas_pcfg_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) &iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) /* Disable the notify enable spinup primitives */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) enable_spinup_value = readl(&iphy->link_layer_registers->notify_enable_spinup_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) writel(enable_spinup_value, &iphy->link_layer_registers->notify_enable_spinup_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) static void scu_link_layer_start_oob(struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) struct scu_link_layer_registers __iomem *ll = iphy->link_layer_registers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) /** Reset OOB sequence - start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) val = readl(&ll->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) val &= ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) writel(val, &ll->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) readl(&ll->phy_configuration); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) /** Reset OOB sequence - end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) /** Start OOB sequence - start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) val = readl(&ll->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) val |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) writel(val, &ll->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) readl(&ll->phy_configuration); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) /** Start OOB sequence - end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * This method will transmit a hard reset request on the specified phy. The SCU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) * hardware requires that we reset the OOB state machine and set the hard reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * bit in the phy configuration register. We then must start OOB over with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * hard reset bit set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) static void scu_link_layer_tx_hard_reset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) struct isci_phy *iphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) u32 phy_configuration_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * SAS Phys must wait for the HARD_RESET_TX event notification to transition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) * to the starting state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) phy_configuration_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) readl(&iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) phy_configuration_value &= ~(SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) phy_configuration_value |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) writel(phy_configuration_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) &iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) /* Now take the OOB state machine out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) writel(phy_configuration_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) &iphy->link_layer_registers->phy_configuration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static void sci_phy_stopped_state_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) struct isci_port *iport = iphy->owning_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) struct isci_host *ihost = iport->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) * @todo We need to get to the controller to place this PE in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) * reset state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) sci_del_timer(&iphy->sata_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) scu_link_layer_stop_protocol_engine(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (iphy->sm.previous_state_id != SCI_PHY_INITIAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) sci_controller_link_down(ihost, phy_get_non_dummy_port(iphy), iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static void sci_phy_starting_state_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct isci_port *iport = iphy->owning_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct isci_host *ihost = iport->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) scu_link_layer_stop_protocol_engine(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) scu_link_layer_start_oob(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) /* We don't know what kind of phy we are going to be just yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) iphy->protocol = SAS_PROTOCOL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) iphy->bcn_received_while_port_unassigned = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (iphy->sm.previous_state_id == SCI_PHY_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) sci_controller_link_down(ihost, phy_get_non_dummy_port(iphy), iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) sci_change_state(&iphy->sm, SCI_PHY_SUB_INITIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static void sci_phy_ready_state_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) struct isci_port *iport = iphy->owning_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) struct isci_host *ihost = iport->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) sci_controller_link_up(ihost, phy_get_non_dummy_port(iphy), iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) static void sci_phy_ready_state_exit(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) sci_phy_suspend(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) static void sci_phy_resetting_state_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /* The phy is being reset, therefore deactivate it from the port. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) * the resetting state we don't notify the user regarding link up and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) * link down notifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) sci_port_deactivate_phy(iphy->owning_port, iphy, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (iphy->protocol == SAS_PROTOCOL_SSP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) scu_link_layer_tx_hard_reset(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) /* The SCU does not need to have a discrete reset state so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) * just go back to the starting state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) sci_change_state(&iphy->sm, SCI_PHY_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static const struct sci_base_state sci_phy_state_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) [SCI_PHY_INITIAL] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) [SCI_PHY_STOPPED] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) .enter_state = sci_phy_stopped_state_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) [SCI_PHY_STARTING] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) .enter_state = sci_phy_starting_state_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) [SCI_PHY_SUB_INITIAL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) .enter_state = sci_phy_starting_initial_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) [SCI_PHY_SUB_AWAIT_OSSP_EN] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) [SCI_PHY_SUB_AWAIT_SAS_SPEED_EN] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) [SCI_PHY_SUB_AWAIT_IAF_UF] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) [SCI_PHY_SUB_AWAIT_SAS_POWER] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) .enter_state = sci_phy_starting_await_sas_power_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) .exit_state = sci_phy_starting_await_sas_power_substate_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) [SCI_PHY_SUB_AWAIT_SATA_POWER] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) .enter_state = sci_phy_starting_await_sata_power_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) .exit_state = sci_phy_starting_await_sata_power_substate_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) [SCI_PHY_SUB_AWAIT_SATA_PHY_EN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) .enter_state = sci_phy_starting_await_sata_phy_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) .exit_state = sci_phy_starting_await_sata_phy_substate_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) [SCI_PHY_SUB_AWAIT_SATA_SPEED_EN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) .enter_state = sci_phy_starting_await_sata_speed_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) .exit_state = sci_phy_starting_await_sata_speed_substate_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) [SCI_PHY_SUB_AWAIT_SIG_FIS_UF] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) .enter_state = sci_phy_starting_await_sig_fis_uf_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) .exit_state = sci_phy_starting_await_sig_fis_uf_substate_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) [SCI_PHY_SUB_FINAL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) .enter_state = sci_phy_starting_final_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) [SCI_PHY_READY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) .enter_state = sci_phy_ready_state_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) .exit_state = sci_phy_ready_state_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) [SCI_PHY_RESETTING] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) .enter_state = sci_phy_resetting_state_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) [SCI_PHY_FINAL] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) void sci_phy_construct(struct isci_phy *iphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) struct isci_port *iport, u8 phy_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) sci_init_sm(&iphy->sm, sci_phy_state_table, SCI_PHY_INITIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) /* Copy the rest of the input data to our locals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) iphy->owning_port = iport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) iphy->phy_index = phy_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) iphy->bcn_received_while_port_unassigned = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) iphy->protocol = SAS_PROTOCOL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) iphy->link_layer_registers = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) /* Create the SIGNATURE FIS Timeout timer for this phy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) sci_init_timer(&iphy->sata_timer, phy_sata_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) struct sci_oem_params *oem = &ihost->oem_parameters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) u64 sci_sas_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) __be64 sas_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) sci_sas_addr = oem->phys[index].sas_address.high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) sci_sas_addr <<= 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) sci_sas_addr |= oem->phys[index].sas_address.low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) sas_addr = cpu_to_be64(sci_sas_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) iphy->sas_phy.enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) iphy->sas_phy.id = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) iphy->sas_phy.sas_addr = &iphy->sas_addr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) iphy->sas_phy.frame_rcvd = (u8 *)&iphy->frame_rcvd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) iphy->sas_phy.ha = &ihost->sas_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) iphy->sas_phy.lldd_phy = iphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) iphy->sas_phy.enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) iphy->sas_phy.class = SAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) iphy->sas_phy.iproto = SAS_PROTOCOL_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) iphy->sas_phy.tproto = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) iphy->sas_phy.type = PHY_TYPE_PHYSICAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) iphy->sas_phy.role = PHY_ROLE_INITIATOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) iphy->sas_phy.oob_mode = OOB_NOT_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) iphy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) memset(&iphy->frame_rcvd, 0, sizeof(iphy->frame_rcvd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) * isci_phy_control() - This function is one of the SAS Domain Template
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) * functions. This is a phy management function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) * @phy: This parameter specifies the sphy being controlled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) * @func: This parameter specifies the phy control function being invoked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) * @buf: This parameter is specific to the phy function being invoked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) * status, zero indicates success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) int isci_phy_control(struct asd_sas_phy *sas_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) enum phy_func func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) struct isci_phy *iphy = sas_phy->lldd_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) struct asd_sas_port *port = sas_phy->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) struct isci_host *ihost = sas_phy->ha->lldd_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) "%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) __func__, sas_phy, func, buf, iphy, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) switch (func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) case PHY_FUNC_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) scu_link_layer_start_oob(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) sci_phy_stop(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) case PHY_FUNC_LINK_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) scu_link_layer_start_oob(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) sci_phy_stop(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) sci_phy_start(iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) case PHY_FUNC_HARD_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (!port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) ret = isci_port_perform_hard_reset(ihost, port->lldd_port, iphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) case PHY_FUNC_GET_EVENTS: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct scu_link_layer_registers __iomem *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) struct sas_phy *phy = sas_phy->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) r = iphy->link_layer_registers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) phy->running_disparity_error_count = readl(&r->running_disparity_error_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) phy->loss_of_dword_sync_count = readl(&r->loss_of_sync_error_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) phy->phy_reset_problem_count = readl(&r->phy_reset_problem_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) phy->invalid_dword_count = readl(&r->invalid_dword_counter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) "%s: phy %p; func %d NOT IMPLEMENTED!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) __func__, sas_phy, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) ret = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) }