phy.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396
  1. /*
  2. * This file is provided under a dual BSD/GPLv2 license. When using or
  3. * redistributing this file, you may do so under either license.
  4. *
  5. * GPL LICENSE SUMMARY
  6. *
  7. * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of version 2 of the GNU General Public License as
  11. * published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  21. * The full GNU General Public License is included in this distribution
  22. * in the file called LICENSE.GPL.
  23. *
  24. * BSD LICENSE
  25. *
  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 without
  30. * modification, are permitted provided that the following conditions
  31. * are met:
  32. *
  33. * * Redistributions of source code must retain the above copyright
  34. * notice, this list of conditions and the following disclaimer.
  35. * * Redistributions in binary form must reproduce the above copyright
  36. * notice, this list of conditions and the following disclaimer in
  37. * the documentation and/or other materials provided with the
  38. * distribution.
  39. * * Neither the name of Intel Corporation nor the names of its
  40. * contributors may be used to endorse or promote products derived
  41. * from this software without specific prior written permission.
  42. *
  43. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  44. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  45. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  46. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  47. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  48. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  49. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  50. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  51. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  52. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  53. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54. */
  55. #include "isci.h"
  56. #include "host.h"
  57. #include "phy.h"
  58. #include "scu_event_codes.h"
  59. #include "probe_roms.h"
  60. /* Maximum arbitration wait time in micro-seconds */
  61. #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
  62. enum sas_linkrate sci_phy_linkrate(struct isci_phy *iphy)
  63. {
  64. return iphy->max_negotiated_speed;
  65. }
  66. /*
  67. * *****************************************************************************
  68. * * SCIC SDS PHY Internal Methods
  69. * ***************************************************************************** */
  70. /**
  71. * This method will initialize the phy transport layer registers
  72. * @sci_phy:
  73. * @transport_layer_registers
  74. *
  75. * enum sci_status
  76. */
  77. static enum sci_status scic_sds_phy_transport_layer_initialization(
  78. struct isci_phy *iphy,
  79. struct scu_transport_layer_registers __iomem *transport_layer_registers)
  80. {
  81. u32 tl_control;
  82. iphy->transport_layer_registers = transport_layer_registers;
  83. writel(SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX,
  84. &iphy->transport_layer_registers->stp_rni);
  85. /*
  86. * Hardware team recommends that we enable the STP prefetch for all
  87. * transports
  88. */
  89. tl_control = readl(&iphy->transport_layer_registers->control);
  90. tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
  91. writel(tl_control, &iphy->transport_layer_registers->control);
  92. return SCI_SUCCESS;
  93. }
  94. /**
  95. * This method will initialize the phy link layer registers
  96. * @sci_phy:
  97. * @link_layer_registers:
  98. *
  99. * enum sci_status
  100. */
  101. static enum sci_status
  102. scic_sds_phy_link_layer_initialization(struct isci_phy *iphy,
  103. struct scu_link_layer_registers __iomem *link_layer_registers)
  104. {
  105. struct scic_sds_controller *scic =
  106. iphy->owning_port->owning_controller;
  107. int phy_idx = iphy->phy_index;
  108. struct sci_phy_user_params *phy_user =
  109. &scic->user_parameters.sds1.phys[phy_idx];
  110. struct sci_phy_oem_params *phy_oem =
  111. &scic->oem_parameters.sds1.phys[phy_idx];
  112. u32 phy_configuration;
  113. struct scic_phy_cap phy_cap;
  114. u32 parity_check = 0;
  115. u32 parity_count = 0;
  116. u32 llctl, link_rate;
  117. u32 clksm_value = 0;
  118. iphy->link_layer_registers = link_layer_registers;
  119. /* Set our IDENTIFY frame data */
  120. #define SCI_END_DEVICE 0x01
  121. writel(SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR) |
  122. SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR) |
  123. SCU_SAS_TIID_GEN_BIT(STP_INITIATOR) |
  124. SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST) |
  125. SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE),
  126. &iphy->link_layer_registers->transmit_identification);
  127. /* Write the device SAS Address */
  128. writel(0xFEDCBA98,
  129. &iphy->link_layer_registers->sas_device_name_high);
  130. writel(phy_idx, &iphy->link_layer_registers->sas_device_name_low);
  131. /* Write the source SAS Address */
  132. writel(phy_oem->sas_address.high,
  133. &iphy->link_layer_registers->source_sas_address_high);
  134. writel(phy_oem->sas_address.low,
  135. &iphy->link_layer_registers->source_sas_address_low);
  136. /* Clear and Set the PHY Identifier */
  137. writel(0, &iphy->link_layer_registers->identify_frame_phy_id);
  138. writel(SCU_SAS_TIPID_GEN_VALUE(ID, phy_idx),
  139. &iphy->link_layer_registers->identify_frame_phy_id);
  140. /* Change the initial state of the phy configuration register */
  141. phy_configuration =
  142. readl(&iphy->link_layer_registers->phy_configuration);
  143. /* Hold OOB state machine in reset */
  144. phy_configuration |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
  145. writel(phy_configuration,
  146. &iphy->link_layer_registers->phy_configuration);
  147. /* Configure the SNW capabilities */
  148. phy_cap.all = 0;
  149. phy_cap.start = 1;
  150. phy_cap.gen3_no_ssc = 1;
  151. phy_cap.gen2_no_ssc = 1;
  152. phy_cap.gen1_no_ssc = 1;
  153. if (scic->oem_parameters.sds1.controller.do_enable_ssc == true) {
  154. phy_cap.gen3_ssc = 1;
  155. phy_cap.gen2_ssc = 1;
  156. phy_cap.gen1_ssc = 1;
  157. }
  158. /*
  159. * The SAS specification indicates that the phy_capabilities that
  160. * are transmitted shall have an even parity. Calculate the parity. */
  161. parity_check = phy_cap.all;
  162. while (parity_check != 0) {
  163. if (parity_check & 0x1)
  164. parity_count++;
  165. parity_check >>= 1;
  166. }
  167. /*
  168. * If parity indicates there are an odd number of bits set, then
  169. * set the parity bit to 1 in the phy capabilities. */
  170. if ((parity_count % 2) != 0)
  171. phy_cap.parity = 1;
  172. writel(phy_cap.all, &iphy->link_layer_registers->phy_capabilities);
  173. /* Set the enable spinup period but disable the ability to send
  174. * notify enable spinup
  175. */
  176. writel(SCU_ENSPINUP_GEN_VAL(COUNT,
  177. phy_user->notify_enable_spin_up_insertion_frequency),
  178. &iphy->link_layer_registers->notify_enable_spinup_control);
  179. /* Write the ALIGN Insertion Ferequency for connected phy and
  180. * inpendent of connected state
  181. */
  182. clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED,
  183. phy_user->in_connection_align_insertion_frequency);
  184. clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
  185. phy_user->align_insertion_frequency);
  186. writel(clksm_value, &iphy->link_layer_registers->clock_skew_management);
  187. /* @todo Provide a way to write this register correctly */
  188. writel(0x02108421,
  189. &iphy->link_layer_registers->afe_lookup_table_control);
  190. llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
  191. (u8)scic->user_parameters.sds1.no_outbound_task_timeout);
  192. switch(phy_user->max_speed_generation) {
  193. case SCIC_SDS_PARM_GEN3_SPEED:
  194. link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3;
  195. break;
  196. case SCIC_SDS_PARM_GEN2_SPEED:
  197. link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2;
  198. break;
  199. default:
  200. link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1;
  201. break;
  202. }
  203. llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
  204. writel(llctl, &iphy->link_layer_registers->link_layer_control);
  205. if (is_a0() || is_a2()) {
  206. /* Program the max ARB time for the PHY to 700us so we inter-operate with
  207. * the PMC expander which shuts down PHYs if the expander PHY generates too
  208. * many breaks. This time value will guarantee that the initiator PHY will
  209. * generate the break.
  210. */
  211. writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME,
  212. &iphy->link_layer_registers->maximum_arbitration_wait_timer_timeout);
  213. }
  214. /* Disable link layer hang detection, rely on the OS timeout for I/O timeouts. */
  215. writel(0, &iphy->link_layer_registers->link_layer_hang_detection_timeout);
  216. /* We can exit the initial state to the stopped state */
  217. sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
  218. return SCI_SUCCESS;
  219. }
  220. static void phy_sata_timeout(unsigned long data)
  221. {
  222. struct sci_timer *tmr = (struct sci_timer *)data;
  223. struct isci_phy *iphy = container_of(tmr, typeof(*iphy), sata_timer);
  224. struct isci_host *ihost = scic_to_ihost(iphy->owning_port->owning_controller);
  225. unsigned long flags;
  226. spin_lock_irqsave(&ihost->scic_lock, flags);
  227. if (tmr->cancel)
  228. goto done;
  229. dev_dbg(sciphy_to_dev(iphy),
  230. "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
  231. "timeout.\n",
  232. __func__,
  233. iphy);
  234. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  235. done:
  236. spin_unlock_irqrestore(&ihost->scic_lock, flags);
  237. }
  238. /**
  239. * This method returns the port currently containing this phy. If the phy is
  240. * currently contained by the dummy port, then the phy is considered to not
  241. * be part of a port.
  242. * @sci_phy: This parameter specifies the phy for which to retrieve the
  243. * containing port.
  244. *
  245. * This method returns a handle to a port that contains the supplied phy.
  246. * NULL This value is returned if the phy is not part of a real
  247. * port (i.e. it's contained in the dummy port). !NULL All other
  248. * values indicate a handle/pointer to the port containing the phy.
  249. */
  250. struct isci_port *phy_get_non_dummy_port(
  251. struct isci_phy *iphy)
  252. {
  253. if (scic_sds_port_get_index(iphy->owning_port) == SCIC_SDS_DUMMY_PORT)
  254. return NULL;
  255. return iphy->owning_port;
  256. }
  257. /**
  258. * This method will assign a port to the phy object.
  259. * @out]: iphy This parameter specifies the phy for which to assign a port
  260. * object.
  261. *
  262. *
  263. */
  264. void scic_sds_phy_set_port(
  265. struct isci_phy *iphy,
  266. struct isci_port *iport)
  267. {
  268. iphy->owning_port = iport;
  269. if (iphy->bcn_received_while_port_unassigned) {
  270. iphy->bcn_received_while_port_unassigned = false;
  271. scic_sds_port_broadcast_change_received(iphy->owning_port, iphy);
  272. }
  273. }
  274. /**
  275. * This method will initialize the constructed phy
  276. * @sci_phy:
  277. * @link_layer_registers:
  278. *
  279. * enum sci_status
  280. */
  281. enum sci_status scic_sds_phy_initialize(
  282. struct isci_phy *iphy,
  283. struct scu_transport_layer_registers __iomem *transport_layer_registers,
  284. struct scu_link_layer_registers __iomem *link_layer_registers)
  285. {
  286. /* Perfrom the initialization of the TL hardware */
  287. scic_sds_phy_transport_layer_initialization(
  288. iphy,
  289. transport_layer_registers);
  290. /* Perofrm the initialization of the PE hardware */
  291. scic_sds_phy_link_layer_initialization(iphy, link_layer_registers);
  292. /*
  293. * There is nothing that needs to be done in this state just
  294. * transition to the stopped state. */
  295. sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
  296. return SCI_SUCCESS;
  297. }
  298. /**
  299. * This method assigns the direct attached device ID for this phy.
  300. *
  301. * @iphy The phy for which the direct attached device id is to
  302. * be assigned.
  303. * @device_id The direct attached device ID to assign to the phy.
  304. * This will either be the RNi for the device or an invalid RNi if there
  305. * is no current device assigned to the phy.
  306. */
  307. void scic_sds_phy_setup_transport(
  308. struct isci_phy *iphy,
  309. u32 device_id)
  310. {
  311. u32 tl_control;
  312. writel(device_id, &iphy->transport_layer_registers->stp_rni);
  313. /*
  314. * The read should guarantee that the first write gets posted
  315. * before the next write
  316. */
  317. tl_control = readl(&iphy->transport_layer_registers->control);
  318. tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
  319. writel(tl_control, &iphy->transport_layer_registers->control);
  320. }
  321. /**
  322. *
  323. * @sci_phy: The phy object to be suspended.
  324. *
  325. * This function will perform the register reads/writes to suspend the SCU
  326. * hardware protocol engine. none
  327. */
  328. static void scic_sds_phy_suspend(
  329. struct isci_phy *iphy)
  330. {
  331. u32 scu_sas_pcfg_value;
  332. scu_sas_pcfg_value =
  333. readl(&iphy->link_layer_registers->phy_configuration);
  334. scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
  335. writel(scu_sas_pcfg_value,
  336. &iphy->link_layer_registers->phy_configuration);
  337. scic_sds_phy_setup_transport(
  338. iphy,
  339. SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
  340. }
  341. void scic_sds_phy_resume(struct isci_phy *iphy)
  342. {
  343. u32 scu_sas_pcfg_value;
  344. scu_sas_pcfg_value =
  345. readl(&iphy->link_layer_registers->phy_configuration);
  346. scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
  347. writel(scu_sas_pcfg_value,
  348. &iphy->link_layer_registers->phy_configuration);
  349. }
  350. void scic_sds_phy_get_sas_address(struct isci_phy *iphy,
  351. struct sci_sas_address *sas_address)
  352. {
  353. sas_address->high = readl(&iphy->link_layer_registers->source_sas_address_high);
  354. sas_address->low = readl(&iphy->link_layer_registers->source_sas_address_low);
  355. }
  356. void scic_sds_phy_get_attached_sas_address(struct isci_phy *iphy,
  357. struct sci_sas_address *sas_address)
  358. {
  359. struct sas_identify_frame *iaf;
  360. iaf = &iphy->frame_rcvd.iaf;
  361. memcpy(sas_address, iaf->sas_addr, SAS_ADDR_SIZE);
  362. }
  363. void scic_sds_phy_get_protocols(struct isci_phy *iphy,
  364. struct scic_phy_proto *protocols)
  365. {
  366. protocols->all =
  367. (u16)(readl(&iphy->
  368. link_layer_registers->transmit_identification) &
  369. 0x0000FFFF);
  370. }
  371. enum sci_status scic_sds_phy_start(struct isci_phy *iphy)
  372. {
  373. enum scic_sds_phy_states state = iphy->sm.current_state_id;
  374. if (state != SCI_PHY_STOPPED) {
  375. dev_dbg(sciphy_to_dev(iphy),
  376. "%s: in wrong state: %d\n", __func__, state);
  377. return SCI_FAILURE_INVALID_STATE;
  378. }
  379. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  380. return SCI_SUCCESS;
  381. }
  382. enum sci_status scic_sds_phy_stop(struct isci_phy *iphy)
  383. {
  384. enum scic_sds_phy_states state = iphy->sm.current_state_id;
  385. switch (state) {
  386. case SCI_PHY_SUB_INITIAL:
  387. case SCI_PHY_SUB_AWAIT_OSSP_EN:
  388. case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
  389. case SCI_PHY_SUB_AWAIT_SAS_POWER:
  390. case SCI_PHY_SUB_AWAIT_SATA_POWER:
  391. case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
  392. case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
  393. case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
  394. case SCI_PHY_SUB_FINAL:
  395. case SCI_PHY_READY:
  396. break;
  397. default:
  398. dev_dbg(sciphy_to_dev(iphy),
  399. "%s: in wrong state: %d\n", __func__, state);
  400. return SCI_FAILURE_INVALID_STATE;
  401. }
  402. sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
  403. return SCI_SUCCESS;
  404. }
  405. enum sci_status scic_sds_phy_reset(struct isci_phy *iphy)
  406. {
  407. enum scic_sds_phy_states state = iphy->sm.current_state_id;
  408. if (state != SCI_PHY_READY) {
  409. dev_dbg(sciphy_to_dev(iphy),
  410. "%s: in wrong state: %d\n", __func__, state);
  411. return SCI_FAILURE_INVALID_STATE;
  412. }
  413. sci_change_state(&iphy->sm, SCI_PHY_RESETTING);
  414. return SCI_SUCCESS;
  415. }
  416. enum sci_status scic_sds_phy_consume_power_handler(struct isci_phy *iphy)
  417. {
  418. enum scic_sds_phy_states state = iphy->sm.current_state_id;
  419. switch (state) {
  420. case SCI_PHY_SUB_AWAIT_SAS_POWER: {
  421. u32 enable_spinup;
  422. enable_spinup = readl(&iphy->link_layer_registers->notify_enable_spinup_control);
  423. enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
  424. writel(enable_spinup, &iphy->link_layer_registers->notify_enable_spinup_control);
  425. /* Change state to the final state this substate machine has run to completion */
  426. sci_change_state(&iphy->sm, SCI_PHY_SUB_FINAL);
  427. return SCI_SUCCESS;
  428. }
  429. case SCI_PHY_SUB_AWAIT_SATA_POWER: {
  430. u32 scu_sas_pcfg_value;
  431. /* Release the spinup hold state and reset the OOB state machine */
  432. scu_sas_pcfg_value =
  433. readl(&iphy->link_layer_registers->phy_configuration);
  434. scu_sas_pcfg_value &=
  435. ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
  436. scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
  437. writel(scu_sas_pcfg_value,
  438. &iphy->link_layer_registers->phy_configuration);
  439. /* Now restart the OOB operation */
  440. scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
  441. scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
  442. writel(scu_sas_pcfg_value,
  443. &iphy->link_layer_registers->phy_configuration);
  444. /* Change state to the final state this substate machine has run to completion */
  445. sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_PHY_EN);
  446. return SCI_SUCCESS;
  447. }
  448. default:
  449. dev_dbg(sciphy_to_dev(iphy),
  450. "%s: in wrong state: %d\n", __func__, state);
  451. return SCI_FAILURE_INVALID_STATE;
  452. }
  453. }
  454. /*
  455. * *****************************************************************************
  456. * * SCIC SDS PHY HELPER FUNCTIONS
  457. * ***************************************************************************** */
  458. /**
  459. *
  460. * @sci_phy: The phy object that received SAS PHY DETECTED.
  461. *
  462. * This method continues the link training for the phy as if it were a SAS PHY
  463. * instead of a SATA PHY. This is done because the completion queue had a SAS
  464. * PHY DETECTED event when the state machine was expecting a SATA PHY event.
  465. * none
  466. */
  467. static void scic_sds_phy_start_sas_link_training(
  468. struct isci_phy *iphy)
  469. {
  470. u32 phy_control;
  471. phy_control =
  472. readl(&iphy->link_layer_registers->phy_configuration);
  473. phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
  474. writel(phy_control,
  475. &iphy->link_layer_registers->phy_configuration);
  476. sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SAS_SPEED_EN);
  477. iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
  478. }
  479. /**
  480. *
  481. * @sci_phy: The phy object that received a SATA SPINUP HOLD event
  482. *
  483. * This method continues the link training for the phy as if it were a SATA PHY
  484. * instead of a SAS PHY. This is done because the completion queue had a SATA
  485. * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
  486. */
  487. static void scic_sds_phy_start_sata_link_training(
  488. struct isci_phy *iphy)
  489. {
  490. sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_POWER);
  491. iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
  492. }
  493. /**
  494. * scic_sds_phy_complete_link_training - perform processing common to
  495. * all protocols upon completion of link training.
  496. * @sci_phy: This parameter specifies the phy object for which link training
  497. * has completed.
  498. * @max_link_rate: This parameter specifies the maximum link rate to be
  499. * associated with this phy.
  500. * @next_state: This parameter specifies the next state for the phy's starting
  501. * sub-state machine.
  502. *
  503. */
  504. static void scic_sds_phy_complete_link_training(
  505. struct isci_phy *iphy,
  506. enum sas_linkrate max_link_rate,
  507. u32 next_state)
  508. {
  509. iphy->max_negotiated_speed = max_link_rate;
  510. sci_change_state(&iphy->sm, next_state);
  511. }
  512. enum sci_status scic_sds_phy_event_handler(struct isci_phy *iphy,
  513. u32 event_code)
  514. {
  515. enum scic_sds_phy_states state = iphy->sm.current_state_id;
  516. switch (state) {
  517. case SCI_PHY_SUB_AWAIT_OSSP_EN:
  518. switch (scu_get_event_code(event_code)) {
  519. case SCU_EVENT_SAS_PHY_DETECTED:
  520. scic_sds_phy_start_sas_link_training(iphy);
  521. iphy->is_in_link_training = true;
  522. break;
  523. case SCU_EVENT_SATA_SPINUP_HOLD:
  524. scic_sds_phy_start_sata_link_training(iphy);
  525. iphy->is_in_link_training = true;
  526. break;
  527. default:
  528. dev_dbg(sciphy_to_dev(iphy),
  529. "%s: PHY starting substate machine received "
  530. "unexpected event_code %x\n",
  531. __func__,
  532. event_code);
  533. return SCI_FAILURE;
  534. }
  535. return SCI_SUCCESS;
  536. case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
  537. switch (scu_get_event_code(event_code)) {
  538. case SCU_EVENT_SAS_PHY_DETECTED:
  539. /*
  540. * Why is this being reported again by the controller?
  541. * We would re-enter this state so just stay here */
  542. break;
  543. case SCU_EVENT_SAS_15:
  544. case SCU_EVENT_SAS_15_SSC:
  545. scic_sds_phy_complete_link_training(
  546. iphy,
  547. SAS_LINK_RATE_1_5_GBPS,
  548. SCI_PHY_SUB_AWAIT_IAF_UF);
  549. break;
  550. case SCU_EVENT_SAS_30:
  551. case SCU_EVENT_SAS_30_SSC:
  552. scic_sds_phy_complete_link_training(
  553. iphy,
  554. SAS_LINK_RATE_3_0_GBPS,
  555. SCI_PHY_SUB_AWAIT_IAF_UF);
  556. break;
  557. case SCU_EVENT_SAS_60:
  558. case SCU_EVENT_SAS_60_SSC:
  559. scic_sds_phy_complete_link_training(
  560. iphy,
  561. SAS_LINK_RATE_6_0_GBPS,
  562. SCI_PHY_SUB_AWAIT_IAF_UF);
  563. break;
  564. case SCU_EVENT_SATA_SPINUP_HOLD:
  565. /*
  566. * We were doing SAS PHY link training and received a SATA PHY event
  567. * continue OOB/SN as if this were a SATA PHY */
  568. scic_sds_phy_start_sata_link_training(iphy);
  569. break;
  570. case SCU_EVENT_LINK_FAILURE:
  571. /* Link failure change state back to the starting state */
  572. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  573. break;
  574. default:
  575. dev_warn(sciphy_to_dev(iphy),
  576. "%s: PHY starting substate machine received "
  577. "unexpected event_code %x\n",
  578. __func__, event_code);
  579. return SCI_FAILURE;
  580. break;
  581. }
  582. return SCI_SUCCESS;
  583. case SCI_PHY_SUB_AWAIT_IAF_UF:
  584. switch (scu_get_event_code(event_code)) {
  585. case SCU_EVENT_SAS_PHY_DETECTED:
  586. /* Backup the state machine */
  587. scic_sds_phy_start_sas_link_training(iphy);
  588. break;
  589. case SCU_EVENT_SATA_SPINUP_HOLD:
  590. /* We were doing SAS PHY link training and received a
  591. * SATA PHY event continue OOB/SN as if this were a
  592. * SATA PHY
  593. */
  594. scic_sds_phy_start_sata_link_training(iphy);
  595. break;
  596. case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
  597. case SCU_EVENT_LINK_FAILURE:
  598. case SCU_EVENT_HARD_RESET_RECEIVED:
  599. /* Start the oob/sn state machine over again */
  600. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  601. break;
  602. default:
  603. dev_warn(sciphy_to_dev(iphy),
  604. "%s: PHY starting substate machine received "
  605. "unexpected event_code %x\n",
  606. __func__, event_code);
  607. return SCI_FAILURE;
  608. }
  609. return SCI_SUCCESS;
  610. case SCI_PHY_SUB_AWAIT_SAS_POWER:
  611. switch (scu_get_event_code(event_code)) {
  612. case SCU_EVENT_LINK_FAILURE:
  613. /* Link failure change state back to the starting state */
  614. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  615. break;
  616. default:
  617. dev_warn(sciphy_to_dev(iphy),
  618. "%s: PHY starting substate machine received unexpected "
  619. "event_code %x\n",
  620. __func__,
  621. event_code);
  622. return SCI_FAILURE;
  623. }
  624. return SCI_SUCCESS;
  625. case SCI_PHY_SUB_AWAIT_SATA_POWER:
  626. switch (scu_get_event_code(event_code)) {
  627. case SCU_EVENT_LINK_FAILURE:
  628. /* Link failure change state back to the starting state */
  629. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  630. break;
  631. case SCU_EVENT_SATA_SPINUP_HOLD:
  632. /* These events are received every 10ms and are
  633. * expected while in this state
  634. */
  635. break;
  636. case SCU_EVENT_SAS_PHY_DETECTED:
  637. /* There has been a change in the phy type before OOB/SN for the
  638. * SATA finished start down the SAS link traning path.
  639. */
  640. scic_sds_phy_start_sas_link_training(iphy);
  641. break;
  642. default:
  643. dev_warn(sciphy_to_dev(iphy),
  644. "%s: PHY starting substate machine received "
  645. "unexpected event_code %x\n",
  646. __func__, event_code);
  647. return SCI_FAILURE;
  648. }
  649. return SCI_SUCCESS;
  650. case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
  651. switch (scu_get_event_code(event_code)) {
  652. case SCU_EVENT_LINK_FAILURE:
  653. /* Link failure change state back to the starting state */
  654. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  655. break;
  656. case SCU_EVENT_SATA_SPINUP_HOLD:
  657. /* These events might be received since we dont know how many may be in
  658. * the completion queue while waiting for power
  659. */
  660. break;
  661. case SCU_EVENT_SATA_PHY_DETECTED:
  662. iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
  663. /* We have received the SATA PHY notification change state */
  664. sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
  665. break;
  666. case SCU_EVENT_SAS_PHY_DETECTED:
  667. /* There has been a change in the phy type before OOB/SN for the
  668. * SATA finished start down the SAS link traning path.
  669. */
  670. scic_sds_phy_start_sas_link_training(iphy);
  671. break;
  672. default:
  673. dev_warn(sciphy_to_dev(iphy),
  674. "%s: PHY starting substate machine received "
  675. "unexpected event_code %x\n",
  676. __func__,
  677. event_code);
  678. return SCI_FAILURE;;
  679. }
  680. return SCI_SUCCESS;
  681. case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
  682. switch (scu_get_event_code(event_code)) {
  683. case SCU_EVENT_SATA_PHY_DETECTED:
  684. /*
  685. * The hardware reports multiple SATA PHY detected events
  686. * ignore the extras */
  687. break;
  688. case SCU_EVENT_SATA_15:
  689. case SCU_EVENT_SATA_15_SSC:
  690. scic_sds_phy_complete_link_training(
  691. iphy,
  692. SAS_LINK_RATE_1_5_GBPS,
  693. SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
  694. break;
  695. case SCU_EVENT_SATA_30:
  696. case SCU_EVENT_SATA_30_SSC:
  697. scic_sds_phy_complete_link_training(
  698. iphy,
  699. SAS_LINK_RATE_3_0_GBPS,
  700. SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
  701. break;
  702. case SCU_EVENT_SATA_60:
  703. case SCU_EVENT_SATA_60_SSC:
  704. scic_sds_phy_complete_link_training(
  705. iphy,
  706. SAS_LINK_RATE_6_0_GBPS,
  707. SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
  708. break;
  709. case SCU_EVENT_LINK_FAILURE:
  710. /* Link failure change state back to the starting state */
  711. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  712. break;
  713. case SCU_EVENT_SAS_PHY_DETECTED:
  714. /*
  715. * There has been a change in the phy type before OOB/SN for the
  716. * SATA finished start down the SAS link traning path. */
  717. scic_sds_phy_start_sas_link_training(iphy);
  718. break;
  719. default:
  720. dev_warn(sciphy_to_dev(iphy),
  721. "%s: PHY starting substate machine received "
  722. "unexpected event_code %x\n",
  723. __func__, event_code);
  724. return SCI_FAILURE;
  725. }
  726. return SCI_SUCCESS;
  727. case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
  728. switch (scu_get_event_code(event_code)) {
  729. case SCU_EVENT_SATA_PHY_DETECTED:
  730. /* Backup the state machine */
  731. sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
  732. break;
  733. case SCU_EVENT_LINK_FAILURE:
  734. /* Link failure change state back to the starting state */
  735. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  736. break;
  737. default:
  738. dev_warn(sciphy_to_dev(iphy),
  739. "%s: PHY starting substate machine received "
  740. "unexpected event_code %x\n",
  741. __func__,
  742. event_code);
  743. return SCI_FAILURE;
  744. }
  745. return SCI_SUCCESS;
  746. case SCI_PHY_READY:
  747. switch (scu_get_event_code(event_code)) {
  748. case SCU_EVENT_LINK_FAILURE:
  749. /* Link failure change state back to the starting state */
  750. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  751. break;
  752. case SCU_EVENT_BROADCAST_CHANGE:
  753. /* Broadcast change received. Notify the port. */
  754. if (phy_get_non_dummy_port(iphy) != NULL)
  755. scic_sds_port_broadcast_change_received(iphy->owning_port, iphy);
  756. else
  757. iphy->bcn_received_while_port_unassigned = true;
  758. break;
  759. default:
  760. dev_warn(sciphy_to_dev(iphy),
  761. "%sP SCIC PHY 0x%p ready state machine received "
  762. "unexpected event_code %x\n",
  763. __func__, iphy, event_code);
  764. return SCI_FAILURE_INVALID_STATE;
  765. }
  766. return SCI_SUCCESS;
  767. case SCI_PHY_RESETTING:
  768. switch (scu_get_event_code(event_code)) {
  769. case SCU_EVENT_HARD_RESET_TRANSMITTED:
  770. /* Link failure change state back to the starting state */
  771. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  772. break;
  773. default:
  774. dev_warn(sciphy_to_dev(iphy),
  775. "%s: SCIC PHY 0x%p resetting state machine received "
  776. "unexpected event_code %x\n",
  777. __func__, iphy, event_code);
  778. return SCI_FAILURE_INVALID_STATE;
  779. break;
  780. }
  781. return SCI_SUCCESS;
  782. default:
  783. dev_dbg(sciphy_to_dev(iphy),
  784. "%s: in wrong state: %d\n", __func__, state);
  785. return SCI_FAILURE_INVALID_STATE;
  786. }
  787. }
  788. enum sci_status scic_sds_phy_frame_handler(struct isci_phy *iphy,
  789. u32 frame_index)
  790. {
  791. enum scic_sds_phy_states state = iphy->sm.current_state_id;
  792. struct scic_sds_controller *scic = iphy->owning_port->owning_controller;
  793. enum sci_status result;
  794. unsigned long flags;
  795. switch (state) {
  796. case SCI_PHY_SUB_AWAIT_IAF_UF: {
  797. u32 *frame_words;
  798. struct sas_identify_frame iaf;
  799. result = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control,
  800. frame_index,
  801. (void **)&frame_words);
  802. if (result != SCI_SUCCESS)
  803. return result;
  804. sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32));
  805. if (iaf.frame_type == 0) {
  806. u32 state;
  807. spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
  808. memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf));
  809. spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
  810. if (iaf.smp_tport) {
  811. /* We got the IAF for an expander PHY go to the final
  812. * state since there are no power requirements for
  813. * expander phys.
  814. */
  815. state = SCI_PHY_SUB_FINAL;
  816. } else {
  817. /* We got the IAF we can now go to the await spinup
  818. * semaphore state
  819. */
  820. state = SCI_PHY_SUB_AWAIT_SAS_POWER;
  821. }
  822. sci_change_state(&iphy->sm, state);
  823. result = SCI_SUCCESS;
  824. } else
  825. dev_warn(sciphy_to_dev(iphy),
  826. "%s: PHY starting substate machine received "
  827. "unexpected frame id %x\n",
  828. __func__, frame_index);
  829. scic_sds_controller_release_frame(scic, frame_index);
  830. return result;
  831. }
  832. case SCI_PHY_SUB_AWAIT_SIG_FIS_UF: {
  833. struct dev_to_host_fis *frame_header;
  834. u32 *fis_frame_data;
  835. result = scic_sds_unsolicited_frame_control_get_header(
  836. &(scic_sds_phy_get_controller(iphy)->uf_control),
  837. frame_index,
  838. (void **)&frame_header);
  839. if (result != SCI_SUCCESS)
  840. return result;
  841. if ((frame_header->fis_type == FIS_REGD2H) &&
  842. !(frame_header->status & ATA_BUSY)) {
  843. scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control,
  844. frame_index,
  845. (void **)&fis_frame_data);
  846. spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
  847. scic_sds_controller_copy_sata_response(&iphy->frame_rcvd.fis,
  848. frame_header,
  849. fis_frame_data);
  850. spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
  851. /* got IAF we can now go to the await spinup semaphore state */
  852. sci_change_state(&iphy->sm, SCI_PHY_SUB_FINAL);
  853. result = SCI_SUCCESS;
  854. } else
  855. dev_warn(sciphy_to_dev(iphy),
  856. "%s: PHY starting substate machine received "
  857. "unexpected frame id %x\n",
  858. __func__, frame_index);
  859. /* Regardless of the result we are done with this frame with it */
  860. scic_sds_controller_release_frame(scic, frame_index);
  861. return result;
  862. }
  863. default:
  864. dev_dbg(sciphy_to_dev(iphy),
  865. "%s: in wrong state: %d\n", __func__, state);
  866. return SCI_FAILURE_INVALID_STATE;
  867. }
  868. }
  869. static void scic_sds_phy_starting_initial_substate_enter(struct sci_base_state_machine *sm)
  870. {
  871. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  872. /* This is just an temporary state go off to the starting state */
  873. sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_OSSP_EN);
  874. }
  875. static void scic_sds_phy_starting_await_sas_power_substate_enter(struct sci_base_state_machine *sm)
  876. {
  877. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  878. struct scic_sds_controller *scic = iphy->owning_port->owning_controller;
  879. scic_sds_controller_power_control_queue_insert(scic, iphy);
  880. }
  881. static void scic_sds_phy_starting_await_sas_power_substate_exit(struct sci_base_state_machine *sm)
  882. {
  883. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  884. struct scic_sds_controller *scic = iphy->owning_port->owning_controller;
  885. scic_sds_controller_power_control_queue_remove(scic, iphy);
  886. }
  887. static void scic_sds_phy_starting_await_sata_power_substate_enter(struct sci_base_state_machine *sm)
  888. {
  889. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  890. struct scic_sds_controller *scic = iphy->owning_port->owning_controller;
  891. scic_sds_controller_power_control_queue_insert(scic, iphy);
  892. }
  893. static void scic_sds_phy_starting_await_sata_power_substate_exit(struct sci_base_state_machine *sm)
  894. {
  895. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  896. struct scic_sds_controller *scic = iphy->owning_port->owning_controller;
  897. scic_sds_controller_power_control_queue_remove(scic, iphy);
  898. }
  899. static void scic_sds_phy_starting_await_sata_phy_substate_enter(struct sci_base_state_machine *sm)
  900. {
  901. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  902. sci_mod_timer(&iphy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
  903. }
  904. static void scic_sds_phy_starting_await_sata_phy_substate_exit(struct sci_base_state_machine *sm)
  905. {
  906. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  907. sci_del_timer(&iphy->sata_timer);
  908. }
  909. static void scic_sds_phy_starting_await_sata_speed_substate_enter(struct sci_base_state_machine *sm)
  910. {
  911. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  912. sci_mod_timer(&iphy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
  913. }
  914. static void scic_sds_phy_starting_await_sata_speed_substate_exit(struct sci_base_state_machine *sm)
  915. {
  916. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  917. sci_del_timer(&iphy->sata_timer);
  918. }
  919. static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(struct sci_base_state_machine *sm)
  920. {
  921. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  922. if (scic_sds_port_link_detected(iphy->owning_port, iphy)) {
  923. /*
  924. * Clear the PE suspend condition so we can actually
  925. * receive SIG FIS
  926. * The hardware will not respond to the XRDY until the PE
  927. * suspend condition is cleared.
  928. */
  929. scic_sds_phy_resume(iphy);
  930. sci_mod_timer(&iphy->sata_timer,
  931. SCIC_SDS_SIGNATURE_FIS_TIMEOUT);
  932. } else
  933. iphy->is_in_link_training = false;
  934. }
  935. static void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(struct sci_base_state_machine *sm)
  936. {
  937. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  938. sci_del_timer(&iphy->sata_timer);
  939. }
  940. static void scic_sds_phy_starting_final_substate_enter(struct sci_base_state_machine *sm)
  941. {
  942. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  943. /* State machine has run to completion so exit out and change
  944. * the base state machine to the ready state
  945. */
  946. sci_change_state(&iphy->sm, SCI_PHY_READY);
  947. }
  948. /**
  949. *
  950. * @sci_phy: This is the struct isci_phy object to stop.
  951. *
  952. * This method will stop the struct isci_phy object. This does not reset the
  953. * protocol engine it just suspends it and places it in a state where it will
  954. * not cause the end device to power up. none
  955. */
  956. static void scu_link_layer_stop_protocol_engine(
  957. struct isci_phy *iphy)
  958. {
  959. u32 scu_sas_pcfg_value;
  960. u32 enable_spinup_value;
  961. /* Suspend the protocol engine and place it in a sata spinup hold state */
  962. scu_sas_pcfg_value =
  963. readl(&iphy->link_layer_registers->phy_configuration);
  964. scu_sas_pcfg_value |=
  965. (SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
  966. SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE) |
  967. SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD));
  968. writel(scu_sas_pcfg_value,
  969. &iphy->link_layer_registers->phy_configuration);
  970. /* Disable the notify enable spinup primitives */
  971. enable_spinup_value = readl(&iphy->link_layer_registers->notify_enable_spinup_control);
  972. enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
  973. writel(enable_spinup_value, &iphy->link_layer_registers->notify_enable_spinup_control);
  974. }
  975. /**
  976. *
  977. *
  978. * This method will start the OOB/SN state machine for this struct isci_phy object.
  979. */
  980. static void scu_link_layer_start_oob(
  981. struct isci_phy *iphy)
  982. {
  983. u32 scu_sas_pcfg_value;
  984. scu_sas_pcfg_value =
  985. readl(&iphy->link_layer_registers->phy_configuration);
  986. scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
  987. scu_sas_pcfg_value &=
  988. ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
  989. SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
  990. writel(scu_sas_pcfg_value,
  991. &iphy->link_layer_registers->phy_configuration);
  992. }
  993. /**
  994. *
  995. *
  996. * This method will transmit a hard reset request on the specified phy. The SCU
  997. * hardware requires that we reset the OOB state machine and set the hard reset
  998. * bit in the phy configuration register. We then must start OOB over with the
  999. * hard reset bit set.
  1000. */
  1001. static void scu_link_layer_tx_hard_reset(
  1002. struct isci_phy *iphy)
  1003. {
  1004. u32 phy_configuration_value;
  1005. /*
  1006. * SAS Phys must wait for the HARD_RESET_TX event notification to transition
  1007. * to the starting state. */
  1008. phy_configuration_value =
  1009. readl(&iphy->link_layer_registers->phy_configuration);
  1010. phy_configuration_value |=
  1011. (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) |
  1012. SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
  1013. writel(phy_configuration_value,
  1014. &iphy->link_layer_registers->phy_configuration);
  1015. /* Now take the OOB state machine out of reset */
  1016. phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
  1017. phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
  1018. writel(phy_configuration_value,
  1019. &iphy->link_layer_registers->phy_configuration);
  1020. }
  1021. static void scic_sds_phy_stopped_state_enter(struct sci_base_state_machine *sm)
  1022. {
  1023. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  1024. /*
  1025. * @todo We need to get to the controller to place this PE in a
  1026. * reset state
  1027. */
  1028. sci_del_timer(&iphy->sata_timer);
  1029. scu_link_layer_stop_protocol_engine(iphy);
  1030. if (iphy->sm.previous_state_id != SCI_PHY_INITIAL)
  1031. scic_sds_controller_link_down(scic_sds_phy_get_controller(iphy),
  1032. phy_get_non_dummy_port(iphy),
  1033. iphy);
  1034. }
  1035. static void scic_sds_phy_starting_state_enter(struct sci_base_state_machine *sm)
  1036. {
  1037. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  1038. scu_link_layer_stop_protocol_engine(iphy);
  1039. scu_link_layer_start_oob(iphy);
  1040. /* We don't know what kind of phy we are going to be just yet */
  1041. iphy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
  1042. iphy->bcn_received_while_port_unassigned = false;
  1043. if (iphy->sm.previous_state_id == SCI_PHY_READY)
  1044. scic_sds_controller_link_down(scic_sds_phy_get_controller(iphy),
  1045. phy_get_non_dummy_port(iphy),
  1046. iphy);
  1047. sci_change_state(&iphy->sm, SCI_PHY_SUB_INITIAL);
  1048. }
  1049. static void scic_sds_phy_ready_state_enter(struct sci_base_state_machine *sm)
  1050. {
  1051. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  1052. scic_sds_controller_link_up(scic_sds_phy_get_controller(iphy),
  1053. phy_get_non_dummy_port(iphy),
  1054. iphy);
  1055. }
  1056. static void scic_sds_phy_ready_state_exit(struct sci_base_state_machine *sm)
  1057. {
  1058. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  1059. scic_sds_phy_suspend(iphy);
  1060. }
  1061. static void scic_sds_phy_resetting_state_enter(struct sci_base_state_machine *sm)
  1062. {
  1063. struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
  1064. /* The phy is being reset, therefore deactivate it from the port. In
  1065. * the resetting state we don't notify the user regarding link up and
  1066. * link down notifications
  1067. */
  1068. scic_sds_port_deactivate_phy(iphy->owning_port, iphy, false);
  1069. if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
  1070. scu_link_layer_tx_hard_reset(iphy);
  1071. } else {
  1072. /* The SCU does not need to have a discrete reset state so
  1073. * just go back to the starting state.
  1074. */
  1075. sci_change_state(&iphy->sm, SCI_PHY_STARTING);
  1076. }
  1077. }
  1078. static const struct sci_base_state scic_sds_phy_state_table[] = {
  1079. [SCI_PHY_INITIAL] = { },
  1080. [SCI_PHY_STOPPED] = {
  1081. .enter_state = scic_sds_phy_stopped_state_enter,
  1082. },
  1083. [SCI_PHY_STARTING] = {
  1084. .enter_state = scic_sds_phy_starting_state_enter,
  1085. },
  1086. [SCI_PHY_SUB_INITIAL] = {
  1087. .enter_state = scic_sds_phy_starting_initial_substate_enter,
  1088. },
  1089. [SCI_PHY_SUB_AWAIT_OSSP_EN] = { },
  1090. [SCI_PHY_SUB_AWAIT_SAS_SPEED_EN] = { },
  1091. [SCI_PHY_SUB_AWAIT_IAF_UF] = { },
  1092. [SCI_PHY_SUB_AWAIT_SAS_POWER] = {
  1093. .enter_state = scic_sds_phy_starting_await_sas_power_substate_enter,
  1094. .exit_state = scic_sds_phy_starting_await_sas_power_substate_exit,
  1095. },
  1096. [SCI_PHY_SUB_AWAIT_SATA_POWER] = {
  1097. .enter_state = scic_sds_phy_starting_await_sata_power_substate_enter,
  1098. .exit_state = scic_sds_phy_starting_await_sata_power_substate_exit
  1099. },
  1100. [SCI_PHY_SUB_AWAIT_SATA_PHY_EN] = {
  1101. .enter_state = scic_sds_phy_starting_await_sata_phy_substate_enter,
  1102. .exit_state = scic_sds_phy_starting_await_sata_phy_substate_exit
  1103. },
  1104. [SCI_PHY_SUB_AWAIT_SATA_SPEED_EN] = {
  1105. .enter_state = scic_sds_phy_starting_await_sata_speed_substate_enter,
  1106. .exit_state = scic_sds_phy_starting_await_sata_speed_substate_exit
  1107. },
  1108. [SCI_PHY_SUB_AWAIT_SIG_FIS_UF] = {
  1109. .enter_state = scic_sds_phy_starting_await_sig_fis_uf_substate_enter,
  1110. .exit_state = scic_sds_phy_starting_await_sig_fis_uf_substate_exit
  1111. },
  1112. [SCI_PHY_SUB_FINAL] = {
  1113. .enter_state = scic_sds_phy_starting_final_substate_enter,
  1114. },
  1115. [SCI_PHY_READY] = {
  1116. .enter_state = scic_sds_phy_ready_state_enter,
  1117. .exit_state = scic_sds_phy_ready_state_exit,
  1118. },
  1119. [SCI_PHY_RESETTING] = {
  1120. .enter_state = scic_sds_phy_resetting_state_enter,
  1121. },
  1122. [SCI_PHY_FINAL] = { },
  1123. };
  1124. void scic_sds_phy_construct(struct isci_phy *iphy,
  1125. struct isci_port *iport, u8 phy_index)
  1126. {
  1127. sci_init_sm(&iphy->sm, scic_sds_phy_state_table, SCI_PHY_INITIAL);
  1128. /* Copy the rest of the input data to our locals */
  1129. iphy->owning_port = iport;
  1130. iphy->phy_index = phy_index;
  1131. iphy->bcn_received_while_port_unassigned = false;
  1132. iphy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
  1133. iphy->link_layer_registers = NULL;
  1134. iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
  1135. /* Create the SIGNATURE FIS Timeout timer for this phy */
  1136. sci_init_timer(&iphy->sata_timer, phy_sata_timeout);
  1137. }
  1138. void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
  1139. {
  1140. union scic_oem_parameters oem;
  1141. u64 sci_sas_addr;
  1142. __be64 sas_addr;
  1143. scic_oem_parameters_get(&ihost->sci, &oem);
  1144. sci_sas_addr = oem.sds1.phys[index].sas_address.high;
  1145. sci_sas_addr <<= 32;
  1146. sci_sas_addr |= oem.sds1.phys[index].sas_address.low;
  1147. sas_addr = cpu_to_be64(sci_sas_addr);
  1148. memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr));
  1149. iphy->isci_port = NULL;
  1150. iphy->sas_phy.enabled = 0;
  1151. iphy->sas_phy.id = index;
  1152. iphy->sas_phy.sas_addr = &iphy->sas_addr[0];
  1153. iphy->sas_phy.frame_rcvd = (u8 *)&iphy->frame_rcvd;
  1154. iphy->sas_phy.ha = &ihost->sas_ha;
  1155. iphy->sas_phy.lldd_phy = iphy;
  1156. iphy->sas_phy.enabled = 1;
  1157. iphy->sas_phy.class = SAS;
  1158. iphy->sas_phy.iproto = SAS_PROTOCOL_ALL;
  1159. iphy->sas_phy.tproto = 0;
  1160. iphy->sas_phy.type = PHY_TYPE_PHYSICAL;
  1161. iphy->sas_phy.role = PHY_ROLE_INITIATOR;
  1162. iphy->sas_phy.oob_mode = OOB_NOT_CONNECTED;
  1163. iphy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN;
  1164. memset(&iphy->frame_rcvd, 0, sizeof(iphy->frame_rcvd));
  1165. }
  1166. /**
  1167. * isci_phy_control() - This function is one of the SAS Domain Template
  1168. * functions. This is a phy management function.
  1169. * @phy: This parameter specifies the sphy being controlled.
  1170. * @func: This parameter specifies the phy control function being invoked.
  1171. * @buf: This parameter is specific to the phy function being invoked.
  1172. *
  1173. * status, zero indicates success.
  1174. */
  1175. int isci_phy_control(struct asd_sas_phy *sas_phy,
  1176. enum phy_func func,
  1177. void *buf)
  1178. {
  1179. int ret = 0;
  1180. struct isci_phy *iphy = sas_phy->lldd_phy;
  1181. struct isci_port *iport = iphy->isci_port;
  1182. struct isci_host *ihost = sas_phy->ha->lldd_ha;
  1183. unsigned long flags;
  1184. dev_dbg(&ihost->pdev->dev,
  1185. "%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
  1186. __func__, sas_phy, func, buf, iphy, iport);
  1187. switch (func) {
  1188. case PHY_FUNC_DISABLE:
  1189. spin_lock_irqsave(&ihost->scic_lock, flags);
  1190. scic_sds_phy_stop(iphy);
  1191. spin_unlock_irqrestore(&ihost->scic_lock, flags);
  1192. break;
  1193. case PHY_FUNC_LINK_RESET:
  1194. spin_lock_irqsave(&ihost->scic_lock, flags);
  1195. scic_sds_phy_stop(iphy);
  1196. scic_sds_phy_start(iphy);
  1197. spin_unlock_irqrestore(&ihost->scic_lock, flags);
  1198. break;
  1199. case PHY_FUNC_HARD_RESET:
  1200. if (!iport)
  1201. return -ENODEV;
  1202. /* Perform the port reset. */
  1203. ret = isci_port_perform_hard_reset(ihost, iport, iphy);
  1204. break;
  1205. default:
  1206. dev_dbg(&ihost->pdev->dev,
  1207. "%s: phy %p; func %d NOT IMPLEMENTED!\n",
  1208. __func__, sas_phy, func);
  1209. ret = -ENOSYS;
  1210. break;
  1211. }
  1212. return ret;
  1213. }