phy.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Intel Wireless UWB Link 1480
  3. * PHY parameters upload
  4. *
  5. * Copyright (C) 2005-2006 Intel Corporation
  6. * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License version
  10. * 2 as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20. * 02110-1301, USA.
  21. *
  22. *
  23. * Code for uploading the PHY parameters to the PHY through the UWB
  24. * Radio Control interface.
  25. *
  26. * We just send the data through the MPI interface using HWA-like
  27. * commands and then reset the PHY to make sure it is ok.
  28. */
  29. #include <linux/delay.h>
  30. #include <linux/device.h>
  31. #include <linux/firmware.h>
  32. #include <linux/usb/wusb.h>
  33. #include "i1480-dfu.h"
  34. /**
  35. * Write a value array to an address of the MPI interface
  36. *
  37. * @i1480: Device descriptor
  38. * @data: Data array to write
  39. * @size: Size of the data array
  40. * @returns: 0 if ok, < 0 errno code on error.
  41. *
  42. * The data array is organized into pairs:
  43. *
  44. * ADDRESS VALUE
  45. *
  46. * ADDRESS is BE 16 bit unsigned, VALUE 8 bit unsigned. Size thus has
  47. * to be a multiple of three.
  48. */
  49. static
  50. int i1480_mpi_write(struct i1480 *i1480, const void *data, size_t size)
  51. {
  52. int result;
  53. struct i1480_cmd_mpi_write *cmd = i1480->cmd_buf;
  54. struct i1480_evt_confirm *reply = i1480->evt_buf;
  55. BUG_ON(size > 480);
  56. result = -ENOMEM;
  57. cmd->rccb.bCommandType = i1480_CET_VS1;
  58. cmd->rccb.wCommand = cpu_to_le16(i1480_CMD_MPI_WRITE);
  59. cmd->size = cpu_to_le16(size);
  60. memcpy(cmd->data, data, size);
  61. reply->rceb.bEventType = i1480_CET_VS1;
  62. reply->rceb.wEvent = i1480_CMD_MPI_WRITE;
  63. result = i1480_cmd(i1480, "MPI-WRITE", sizeof(*cmd) + size, sizeof(*reply));
  64. if (result < 0)
  65. goto out;
  66. if (reply->bResultCode != UWB_RC_RES_SUCCESS) {
  67. dev_err(i1480->dev, "MPI-WRITE: command execution failed: %d\n",
  68. reply->bResultCode);
  69. result = -EIO;
  70. }
  71. out:
  72. return result;
  73. }
  74. /**
  75. * Read a value array to from an address of the MPI interface
  76. *
  77. * @i1480: Device descriptor
  78. * @data: where to place the read array
  79. * @srcaddr: Where to read from
  80. * @size: Size of the data read array
  81. * @returns: 0 if ok, < 0 errno code on error.
  82. *
  83. * The command data array is organized into pairs ADDR0 ADDR1..., and
  84. * the returned data in ADDR0 VALUE0 ADDR1 VALUE1...
  85. *
  86. * We generate the command array to be a sequential read and then
  87. * rearrange the result.
  88. *
  89. * We use the i1480->cmd_buf for the command, i1480->evt_buf for the reply.
  90. *
  91. * As the reply has to fit in 512 bytes (i1480->evt_buffer), the max amount
  92. * of values we can read is (512 - sizeof(*reply)) / 3
  93. */
  94. static
  95. int i1480_mpi_read(struct i1480 *i1480, u8 *data, u16 srcaddr, size_t size)
  96. {
  97. int result;
  98. struct i1480_cmd_mpi_read *cmd = i1480->cmd_buf;
  99. struct i1480_evt_mpi_read *reply = i1480->evt_buf;
  100. unsigned cnt;
  101. memset(i1480->cmd_buf, 0x69, 512);
  102. memset(i1480->evt_buf, 0x69, 512);
  103. BUG_ON(size > (i1480->buf_size - sizeof(*reply)) / 3);
  104. result = -ENOMEM;
  105. cmd->rccb.bCommandType = i1480_CET_VS1;
  106. cmd->rccb.wCommand = cpu_to_le16(i1480_CMD_MPI_READ);
  107. cmd->size = cpu_to_le16(3*size);
  108. for (cnt = 0; cnt < size; cnt++) {
  109. cmd->data[cnt].page = (srcaddr + cnt) >> 8;
  110. cmd->data[cnt].offset = (srcaddr + cnt) & 0xff;
  111. }
  112. reply->rceb.bEventType = i1480_CET_VS1;
  113. reply->rceb.wEvent = i1480_CMD_MPI_READ;
  114. result = i1480_cmd(i1480, "MPI-READ", sizeof(*cmd) + 2*size,
  115. sizeof(*reply) + 3*size);
  116. if (result < 0)
  117. goto out;
  118. if (reply->bResultCode != UWB_RC_RES_SUCCESS) {
  119. dev_err(i1480->dev, "MPI-READ: command execution failed: %d\n",
  120. reply->bResultCode);
  121. result = -EIO;
  122. }
  123. for (cnt = 0; cnt < size; cnt++) {
  124. if (reply->data[cnt].page != (srcaddr + cnt) >> 8)
  125. dev_err(i1480->dev, "MPI-READ: page inconsistency at "
  126. "index %u: expected 0x%02x, got 0x%02x\n", cnt,
  127. (srcaddr + cnt) >> 8, reply->data[cnt].page);
  128. if (reply->data[cnt].offset != ((srcaddr + cnt) & 0x00ff))
  129. dev_err(i1480->dev, "MPI-READ: offset inconsistency at "
  130. "index %u: expected 0x%02x, got 0x%02x\n", cnt,
  131. (srcaddr + cnt) & 0x00ff,
  132. reply->data[cnt].offset);
  133. data[cnt] = reply->data[cnt].value;
  134. }
  135. result = 0;
  136. out:
  137. return result;
  138. }
  139. /**
  140. * Upload a PHY firmware, wait for it to start
  141. *
  142. * @i1480: Device instance
  143. * @fw_name: Name of the file that contains the firmware
  144. *
  145. * We assume the MAC fw is up and running. This means we can use the
  146. * MPI interface to write the PHY firmware. Once done, we issue an
  147. * MBOA Reset, which will force the MAC to reset and reinitialize the
  148. * PHY. If that works, we are ready to go.
  149. *
  150. * Max packet size for the MPI write is 512, so the max buffer is 480
  151. * (which gives us 160 byte triads of MSB, LSB and VAL for the data).
  152. */
  153. int i1480_phy_fw_upload(struct i1480 *i1480)
  154. {
  155. int result;
  156. const struct firmware *fw;
  157. const char *data_itr, *data_top;
  158. const size_t MAX_BLK_SIZE = 480; /* 160 triads */
  159. size_t data_size;
  160. u8 phy_stat;
  161. result = request_firmware(&fw, i1480->phy_fw_name, i1480->dev);
  162. if (result < 0)
  163. goto out;
  164. /* Loop writing data in chunks as big as possible until done. */
  165. for (data_itr = fw->data, data_top = data_itr + fw->size;
  166. data_itr < data_top; data_itr += MAX_BLK_SIZE) {
  167. data_size = min(MAX_BLK_SIZE, (size_t) (data_top - data_itr));
  168. result = i1480_mpi_write(i1480, data_itr, data_size);
  169. if (result < 0)
  170. goto error_mpi_write;
  171. }
  172. /* Read MPI page 0, offset 6; if 0, PHY was initialized correctly. */
  173. result = i1480_mpi_read(i1480, &phy_stat, 0x0006, 1);
  174. if (result < 0) {
  175. dev_err(i1480->dev, "PHY: can't get status: %d\n", result);
  176. goto error_mpi_status;
  177. }
  178. if (phy_stat != 0) {
  179. result = -ENODEV;
  180. dev_info(i1480->dev, "error, PHY not ready: %u\n", phy_stat);
  181. goto error_phy_status;
  182. }
  183. dev_info(i1480->dev, "PHY fw '%s': uploaded\n", i1480->phy_fw_name);
  184. error_phy_status:
  185. error_mpi_status:
  186. error_mpi_write:
  187. release_firmware(fw);
  188. if (result < 0)
  189. dev_err(i1480->dev, "PHY fw '%s': failed to upload (%d), "
  190. "power cycle device\n", i1480->phy_fw_name, result);
  191. out:
  192. return result;
  193. }