brintos

brintos / linux-shallow public Read only

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