cc2520.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* Driver for TI CC2520 802.15.4 Wireless-PAN Networking controller
  3. *
  4. * Copyright (C) 2014 Varka Bhadram <varkab@cdac.in>
  5. * Md.Jamal Mohiuddin <mjmohiuddin@cdac.in>
  6. * P Sowjanya <sowjanyap@cdac.in>
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/gpio/consumer.h>
  11. #include <linux/delay.h>
  12. #include <linux/spi/spi.h>
  13. #include <linux/property.h>
  14. #include <linux/workqueue.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/skbuff.h>
  17. #include <linux/ieee802154.h>
  18. #include <linux/crc-ccitt.h>
  19. #include <linux/unaligned.h>
  20. #include <net/mac802154.h>
  21. #include <net/cfg802154.h>
  22. #define SPI_COMMAND_BUFFER 3
  23. #define HIGH 1
  24. #define LOW 0
  25. #define STATE_IDLE 0
  26. #define RSSI_VALID 0
  27. #define RSSI_OFFSET 78
  28. #define CC2520_RAM_SIZE 640
  29. #define CC2520_FIFO_SIZE 128
  30. #define CC2520RAM_TXFIFO 0x100
  31. #define CC2520RAM_RXFIFO 0x180
  32. #define CC2520RAM_IEEEADDR 0x3EA
  33. #define CC2520RAM_PANID 0x3F2
  34. #define CC2520RAM_SHORTADDR 0x3F4
  35. #define CC2520_FREG_MASK 0x3F
  36. /* status byte values */
  37. #define CC2520_STATUS_XOSC32M_STABLE BIT(7)
  38. #define CC2520_STATUS_RSSI_VALID BIT(6)
  39. #define CC2520_STATUS_TX_UNDERFLOW BIT(3)
  40. /* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
  41. #define CC2520_MINCHANNEL 11
  42. #define CC2520_MAXCHANNEL 26
  43. #define CC2520_CHANNEL_SPACING 5
  44. /* command strobes */
  45. #define CC2520_CMD_SNOP 0x00
  46. #define CC2520_CMD_IBUFLD 0x02
  47. #define CC2520_CMD_SIBUFEX 0x03
  48. #define CC2520_CMD_SSAMPLECCA 0x04
  49. #define CC2520_CMD_SRES 0x0f
  50. #define CC2520_CMD_MEMORY_MASK 0x0f
  51. #define CC2520_CMD_MEMORY_READ 0x10
  52. #define CC2520_CMD_MEMORY_WRITE 0x20
  53. #define CC2520_CMD_RXBUF 0x30
  54. #define CC2520_CMD_RXBUFCP 0x38
  55. #define CC2520_CMD_RXBUFMOV 0x32
  56. #define CC2520_CMD_TXBUF 0x3A
  57. #define CC2520_CMD_TXBUFCP 0x3E
  58. #define CC2520_CMD_RANDOM 0x3C
  59. #define CC2520_CMD_SXOSCON 0x40
  60. #define CC2520_CMD_STXCAL 0x41
  61. #define CC2520_CMD_SRXON 0x42
  62. #define CC2520_CMD_STXON 0x43
  63. #define CC2520_CMD_STXONCCA 0x44
  64. #define CC2520_CMD_SRFOFF 0x45
  65. #define CC2520_CMD_SXOSCOFF 0x46
  66. #define CC2520_CMD_SFLUSHRX 0x47
  67. #define CC2520_CMD_SFLUSHTX 0x48
  68. #define CC2520_CMD_SACK 0x49
  69. #define CC2520_CMD_SACKPEND 0x4A
  70. #define CC2520_CMD_SNACK 0x4B
  71. #define CC2520_CMD_SRXMASKBITSET 0x4C
  72. #define CC2520_CMD_SRXMASKBITCLR 0x4D
  73. #define CC2520_CMD_RXMASKAND 0x4E
  74. #define CC2520_CMD_RXMASKOR 0x4F
  75. #define CC2520_CMD_MEMCP 0x50
  76. #define CC2520_CMD_MEMCPR 0x52
  77. #define CC2520_CMD_MEMXCP 0x54
  78. #define CC2520_CMD_MEMXWR 0x56
  79. #define CC2520_CMD_BCLR 0x58
  80. #define CC2520_CMD_BSET 0x59
  81. #define CC2520_CMD_CTR_UCTR 0x60
  82. #define CC2520_CMD_CBCMAC 0x64
  83. #define CC2520_CMD_UCBCMAC 0x66
  84. #define CC2520_CMD_CCM 0x68
  85. #define CC2520_CMD_UCCM 0x6A
  86. #define CC2520_CMD_ECB 0x70
  87. #define CC2520_CMD_ECBO 0x72
  88. #define CC2520_CMD_ECBX 0x74
  89. #define CC2520_CMD_INC 0x78
  90. #define CC2520_CMD_ABORT 0x7F
  91. #define CC2520_CMD_REGISTER_READ 0x80
  92. #define CC2520_CMD_REGISTER_WRITE 0xC0
  93. /* status registers */
  94. #define CC2520_CHIPID 0x40
  95. #define CC2520_VERSION 0x42
  96. #define CC2520_EXTCLOCK 0x44
  97. #define CC2520_MDMCTRL0 0x46
  98. #define CC2520_MDMCTRL1 0x47
  99. #define CC2520_FREQEST 0x48
  100. #define CC2520_RXCTRL 0x4A
  101. #define CC2520_FSCTRL 0x4C
  102. #define CC2520_FSCAL0 0x4E
  103. #define CC2520_FSCAL1 0x4F
  104. #define CC2520_FSCAL2 0x50
  105. #define CC2520_FSCAL3 0x51
  106. #define CC2520_AGCCTRL0 0x52
  107. #define CC2520_AGCCTRL1 0x53
  108. #define CC2520_AGCCTRL2 0x54
  109. #define CC2520_AGCCTRL3 0x55
  110. #define CC2520_ADCTEST0 0x56
  111. #define CC2520_ADCTEST1 0x57
  112. #define CC2520_ADCTEST2 0x58
  113. #define CC2520_MDMTEST0 0x5A
  114. #define CC2520_MDMTEST1 0x5B
  115. #define CC2520_DACTEST0 0x5C
  116. #define CC2520_DACTEST1 0x5D
  117. #define CC2520_ATEST 0x5E
  118. #define CC2520_DACTEST2 0x5F
  119. #define CC2520_PTEST0 0x60
  120. #define CC2520_PTEST1 0x61
  121. #define CC2520_RESERVED 0x62
  122. #define CC2520_DPUBIST 0x7A
  123. #define CC2520_ACTBIST 0x7C
  124. #define CC2520_RAMBIST 0x7E
  125. /* frame registers */
  126. #define CC2520_FRMFILT0 0x00
  127. #define CC2520_FRMFILT1 0x01
  128. #define CC2520_SRCMATCH 0x02
  129. #define CC2520_SRCSHORTEN0 0x04
  130. #define CC2520_SRCSHORTEN1 0x05
  131. #define CC2520_SRCSHORTEN2 0x06
  132. #define CC2520_SRCEXTEN0 0x08
  133. #define CC2520_SRCEXTEN1 0x09
  134. #define CC2520_SRCEXTEN2 0x0A
  135. #define CC2520_FRMCTRL0 0x0C
  136. #define CC2520_FRMCTRL1 0x0D
  137. #define CC2520_RXENABLE0 0x0E
  138. #define CC2520_RXENABLE1 0x0F
  139. #define CC2520_EXCFLAG0 0x10
  140. #define CC2520_EXCFLAG1 0x11
  141. #define CC2520_EXCFLAG2 0x12
  142. #define CC2520_EXCMASKA0 0x14
  143. #define CC2520_EXCMASKA1 0x15
  144. #define CC2520_EXCMASKA2 0x16
  145. #define CC2520_EXCMASKB0 0x18
  146. #define CC2520_EXCMASKB1 0x19
  147. #define CC2520_EXCMASKB2 0x1A
  148. #define CC2520_EXCBINDX0 0x1C
  149. #define CC2520_EXCBINDX1 0x1D
  150. #define CC2520_EXCBINDY0 0x1E
  151. #define CC2520_EXCBINDY1 0x1F
  152. #define CC2520_GPIOCTRL0 0x20
  153. #define CC2520_GPIOCTRL1 0x21
  154. #define CC2520_GPIOCTRL2 0x22
  155. #define CC2520_GPIOCTRL3 0x23
  156. #define CC2520_GPIOCTRL4 0x24
  157. #define CC2520_GPIOCTRL5 0x25
  158. #define CC2520_GPIOPOLARITY 0x26
  159. #define CC2520_GPIOCTRL 0x28
  160. #define CC2520_DPUCON 0x2A
  161. #define CC2520_DPUSTAT 0x2C
  162. #define CC2520_FREQCTRL 0x2E
  163. #define CC2520_FREQTUNE 0x2F
  164. #define CC2520_TXPOWER 0x30
  165. #define CC2520_TXCTRL 0x31
  166. #define CC2520_FSMSTAT0 0x32
  167. #define CC2520_FSMSTAT1 0x33
  168. #define CC2520_FIFOPCTRL 0x34
  169. #define CC2520_FSMCTRL 0x35
  170. #define CC2520_CCACTRL0 0x36
  171. #define CC2520_CCACTRL1 0x37
  172. #define CC2520_RSSI 0x38
  173. #define CC2520_RSSISTAT 0x39
  174. #define CC2520_RXFIRST 0x3C
  175. #define CC2520_RXFIFOCNT 0x3E
  176. #define CC2520_TXFIFOCNT 0x3F
  177. /* CC2520_FRMFILT0 */
  178. #define FRMFILT0_FRAME_FILTER_EN BIT(0)
  179. #define FRMFILT0_PAN_COORDINATOR BIT(1)
  180. /* CC2520_FRMCTRL0 */
  181. #define FRMCTRL0_AUTOACK BIT(5)
  182. #define FRMCTRL0_AUTOCRC BIT(6)
  183. /* CC2520_FRMCTRL1 */
  184. #define FRMCTRL1_SET_RXENMASK_ON_TX BIT(0)
  185. #define FRMCTRL1_IGNORE_TX_UNDERF BIT(1)
  186. /* Driver private information */
  187. struct cc2520_private {
  188. struct spi_device *spi; /* SPI device structure */
  189. struct ieee802154_hw *hw; /* IEEE-802.15.4 device */
  190. u8 *buf; /* SPI TX/Rx data buffer */
  191. struct mutex buffer_mutex; /* SPI buffer mutex */
  192. bool is_tx; /* Flag for sync b/w Tx and Rx */
  193. bool amplified; /* Flag for CC2591 */
  194. struct gpio_desc *fifo_pin; /* FIFO GPIO pin number */
  195. struct work_struct fifop_irqwork;/* Workqueue for FIFOP */
  196. spinlock_t lock; /* Lock for is_tx*/
  197. struct completion tx_complete; /* Work completion for Tx */
  198. bool promiscuous; /* Flag for promiscuous mode */
  199. };
  200. /* Generic Functions */
  201. static int
  202. cc2520_cmd_strobe(struct cc2520_private *priv, u8 cmd)
  203. {
  204. int ret;
  205. struct spi_message msg;
  206. struct spi_transfer xfer = {
  207. .len = 0,
  208. .tx_buf = priv->buf,
  209. .rx_buf = priv->buf,
  210. };
  211. spi_message_init(&msg);
  212. spi_message_add_tail(&xfer, &msg);
  213. mutex_lock(&priv->buffer_mutex);
  214. priv->buf[xfer.len++] = cmd;
  215. dev_vdbg(&priv->spi->dev,
  216. "command strobe buf[0] = %02x\n",
  217. priv->buf[0]);
  218. ret = spi_sync(priv->spi, &msg);
  219. dev_vdbg(&priv->spi->dev,
  220. "buf[0] = %02x\n", priv->buf[0]);
  221. mutex_unlock(&priv->buffer_mutex);
  222. return ret;
  223. }
  224. static int
  225. cc2520_get_status(struct cc2520_private *priv, u8 *status)
  226. {
  227. int ret;
  228. struct spi_message msg;
  229. struct spi_transfer xfer = {
  230. .len = 0,
  231. .tx_buf = priv->buf,
  232. .rx_buf = priv->buf,
  233. };
  234. spi_message_init(&msg);
  235. spi_message_add_tail(&xfer, &msg);
  236. mutex_lock(&priv->buffer_mutex);
  237. priv->buf[xfer.len++] = CC2520_CMD_SNOP;
  238. dev_vdbg(&priv->spi->dev,
  239. "get status command buf[0] = %02x\n", priv->buf[0]);
  240. ret = spi_sync(priv->spi, &msg);
  241. if (!ret)
  242. *status = priv->buf[0];
  243. dev_vdbg(&priv->spi->dev,
  244. "buf[0] = %02x\n", priv->buf[0]);
  245. mutex_unlock(&priv->buffer_mutex);
  246. return ret;
  247. }
  248. static int
  249. cc2520_write_register(struct cc2520_private *priv, u8 reg, u8 value)
  250. {
  251. int status;
  252. struct spi_message msg;
  253. struct spi_transfer xfer = {
  254. .len = 0,
  255. .tx_buf = priv->buf,
  256. .rx_buf = priv->buf,
  257. };
  258. spi_message_init(&msg);
  259. spi_message_add_tail(&xfer, &msg);
  260. mutex_lock(&priv->buffer_mutex);
  261. if (reg <= CC2520_FREG_MASK) {
  262. priv->buf[xfer.len++] = CC2520_CMD_REGISTER_WRITE | reg;
  263. priv->buf[xfer.len++] = value;
  264. } else {
  265. priv->buf[xfer.len++] = CC2520_CMD_MEMORY_WRITE;
  266. priv->buf[xfer.len++] = reg;
  267. priv->buf[xfer.len++] = value;
  268. }
  269. status = spi_sync(priv->spi, &msg);
  270. if (msg.status)
  271. status = msg.status;
  272. mutex_unlock(&priv->buffer_mutex);
  273. return status;
  274. }
  275. static int
  276. cc2520_write_ram(struct cc2520_private *priv, u16 reg, u8 len, u8 *data)
  277. {
  278. int status;
  279. struct spi_message msg;
  280. struct spi_transfer xfer_head = {
  281. .len = 0,
  282. .tx_buf = priv->buf,
  283. .rx_buf = priv->buf,
  284. };
  285. struct spi_transfer xfer_buf = {
  286. .len = len,
  287. .tx_buf = data,
  288. };
  289. mutex_lock(&priv->buffer_mutex);
  290. priv->buf[xfer_head.len++] = (CC2520_CMD_MEMORY_WRITE |
  291. ((reg >> 8) & 0xff));
  292. priv->buf[xfer_head.len++] = reg & 0xff;
  293. spi_message_init(&msg);
  294. spi_message_add_tail(&xfer_head, &msg);
  295. spi_message_add_tail(&xfer_buf, &msg);
  296. status = spi_sync(priv->spi, &msg);
  297. dev_dbg(&priv->spi->dev, "spi status = %d\n", status);
  298. if (msg.status)
  299. status = msg.status;
  300. mutex_unlock(&priv->buffer_mutex);
  301. return status;
  302. }
  303. static int
  304. cc2520_read_register(struct cc2520_private *priv, u8 reg, u8 *data)
  305. {
  306. int status;
  307. struct spi_message msg;
  308. struct spi_transfer xfer1 = {
  309. .len = 0,
  310. .tx_buf = priv->buf,
  311. .rx_buf = priv->buf,
  312. };
  313. struct spi_transfer xfer2 = {
  314. .len = 1,
  315. .rx_buf = data,
  316. };
  317. spi_message_init(&msg);
  318. spi_message_add_tail(&xfer1, &msg);
  319. spi_message_add_tail(&xfer2, &msg);
  320. mutex_lock(&priv->buffer_mutex);
  321. priv->buf[xfer1.len++] = CC2520_CMD_MEMORY_READ;
  322. priv->buf[xfer1.len++] = reg;
  323. status = spi_sync(priv->spi, &msg);
  324. dev_dbg(&priv->spi->dev,
  325. "spi status = %d\n", status);
  326. if (msg.status)
  327. status = msg.status;
  328. mutex_unlock(&priv->buffer_mutex);
  329. return status;
  330. }
  331. static int
  332. cc2520_write_txfifo(struct cc2520_private *priv, u8 pkt_len, u8 *data, u8 len)
  333. {
  334. int status;
  335. /* length byte must include FCS even
  336. * if it is calculated in the hardware
  337. */
  338. int len_byte = pkt_len;
  339. struct spi_message msg;
  340. struct spi_transfer xfer_head = {
  341. .len = 0,
  342. .tx_buf = priv->buf,
  343. .rx_buf = priv->buf,
  344. };
  345. struct spi_transfer xfer_len = {
  346. .len = 1,
  347. .tx_buf = &len_byte,
  348. };
  349. struct spi_transfer xfer_buf = {
  350. .len = len,
  351. .tx_buf = data,
  352. };
  353. spi_message_init(&msg);
  354. spi_message_add_tail(&xfer_head, &msg);
  355. spi_message_add_tail(&xfer_len, &msg);
  356. spi_message_add_tail(&xfer_buf, &msg);
  357. mutex_lock(&priv->buffer_mutex);
  358. priv->buf[xfer_head.len++] = CC2520_CMD_TXBUF;
  359. dev_vdbg(&priv->spi->dev,
  360. "TX_FIFO cmd buf[0] = %02x\n", priv->buf[0]);
  361. status = spi_sync(priv->spi, &msg);
  362. dev_vdbg(&priv->spi->dev, "status = %d\n", status);
  363. if (msg.status)
  364. status = msg.status;
  365. dev_vdbg(&priv->spi->dev, "status = %d\n", status);
  366. dev_vdbg(&priv->spi->dev, "buf[0] = %02x\n", priv->buf[0]);
  367. mutex_unlock(&priv->buffer_mutex);
  368. return status;
  369. }
  370. static int
  371. cc2520_read_rxfifo(struct cc2520_private *priv, u8 *data, u8 len)
  372. {
  373. int status;
  374. struct spi_message msg;
  375. struct spi_transfer xfer_head = {
  376. .len = 0,
  377. .tx_buf = priv->buf,
  378. .rx_buf = priv->buf,
  379. };
  380. struct spi_transfer xfer_buf = {
  381. .len = len,
  382. .rx_buf = data,
  383. };
  384. spi_message_init(&msg);
  385. spi_message_add_tail(&xfer_head, &msg);
  386. spi_message_add_tail(&xfer_buf, &msg);
  387. mutex_lock(&priv->buffer_mutex);
  388. priv->buf[xfer_head.len++] = CC2520_CMD_RXBUF;
  389. dev_vdbg(&priv->spi->dev, "read rxfifo buf[0] = %02x\n", priv->buf[0]);
  390. dev_vdbg(&priv->spi->dev, "buf[1] = %02x\n", priv->buf[1]);
  391. status = spi_sync(priv->spi, &msg);
  392. dev_vdbg(&priv->spi->dev, "status = %d\n", status);
  393. if (msg.status)
  394. status = msg.status;
  395. dev_vdbg(&priv->spi->dev, "status = %d\n", status);
  396. dev_vdbg(&priv->spi->dev,
  397. "return status buf[0] = %02x\n", priv->buf[0]);
  398. dev_vdbg(&priv->spi->dev, "length buf[1] = %02x\n", priv->buf[1]);
  399. mutex_unlock(&priv->buffer_mutex);
  400. return status;
  401. }
  402. static int cc2520_start(struct ieee802154_hw *hw)
  403. {
  404. return cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRXON);
  405. }
  406. static void cc2520_stop(struct ieee802154_hw *hw)
  407. {
  408. cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRFOFF);
  409. }
  410. static int
  411. cc2520_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
  412. {
  413. struct cc2520_private *priv = hw->priv;
  414. unsigned long flags;
  415. int rc;
  416. u8 status = 0;
  417. u8 pkt_len;
  418. /* In promiscuous mode we disable AUTOCRC so we can get the raw CRC
  419. * values on RX. This means we need to manually add the CRC on TX.
  420. */
  421. if (priv->promiscuous) {
  422. u16 crc = crc_ccitt(0, skb->data, skb->len);
  423. put_unaligned_le16(crc, skb_put(skb, 2));
  424. pkt_len = skb->len;
  425. } else {
  426. pkt_len = skb->len + 2;
  427. }
  428. rc = cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHTX);
  429. if (rc)
  430. goto err_tx;
  431. rc = cc2520_write_txfifo(priv, pkt_len, skb->data, skb->len);
  432. if (rc)
  433. goto err_tx;
  434. rc = cc2520_get_status(priv, &status);
  435. if (rc)
  436. goto err_tx;
  437. if (status & CC2520_STATUS_TX_UNDERFLOW) {
  438. rc = -EINVAL;
  439. dev_err(&priv->spi->dev, "cc2520 tx underflow exception\n");
  440. goto err_tx;
  441. }
  442. spin_lock_irqsave(&priv->lock, flags);
  443. WARN_ON(priv->is_tx);
  444. priv->is_tx = 1;
  445. spin_unlock_irqrestore(&priv->lock, flags);
  446. rc = cc2520_cmd_strobe(priv, CC2520_CMD_STXONCCA);
  447. if (rc)
  448. goto err;
  449. rc = wait_for_completion_interruptible(&priv->tx_complete);
  450. if (rc < 0)
  451. goto err;
  452. cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHTX);
  453. cc2520_cmd_strobe(priv, CC2520_CMD_SRXON);
  454. return rc;
  455. err:
  456. spin_lock_irqsave(&priv->lock, flags);
  457. priv->is_tx = 0;
  458. spin_unlock_irqrestore(&priv->lock, flags);
  459. err_tx:
  460. return rc;
  461. }
  462. static int cc2520_rx(struct cc2520_private *priv)
  463. {
  464. u8 len = 0, lqi = 0, bytes = 1;
  465. struct sk_buff *skb;
  466. /* Read single length byte from the radio. */
  467. cc2520_read_rxfifo(priv, &len, bytes);
  468. if (!ieee802154_is_valid_psdu_len(len)) {
  469. /* Corrupted frame received, clear frame buffer by
  470. * reading entire buffer.
  471. */
  472. dev_dbg(&priv->spi->dev, "corrupted frame received\n");
  473. len = IEEE802154_MTU;
  474. }
  475. skb = dev_alloc_skb(len);
  476. if (!skb)
  477. return -ENOMEM;
  478. if (cc2520_read_rxfifo(priv, skb_put(skb, len), len)) {
  479. dev_dbg(&priv->spi->dev, "frame reception failed\n");
  480. kfree_skb(skb);
  481. return -EINVAL;
  482. }
  483. /* In promiscuous mode, we configure the radio to include the
  484. * CRC (AUTOCRC==0) and we pass on the packet unconditionally. If not
  485. * in promiscuous mode, we check the CRC here, but leave the
  486. * RSSI/LQI/CRC_OK bytes as they will get removed in the mac layer.
  487. */
  488. if (!priv->promiscuous) {
  489. bool crc_ok;
  490. /* Check if the CRC is valid. With AUTOCRC set, the most
  491. * significant bit of the last byte returned from the CC2520
  492. * is CRC_OK flag. See section 20.3.4 of the datasheet.
  493. */
  494. crc_ok = skb->data[len - 1] & BIT(7);
  495. /* If we failed CRC drop the packet in the driver layer. */
  496. if (!crc_ok) {
  497. dev_dbg(&priv->spi->dev, "CRC check failed\n");
  498. kfree_skb(skb);
  499. return -EINVAL;
  500. }
  501. /* To calculate LQI, the lower 7 bits of the last byte (the
  502. * correlation value provided by the radio) must be scaled to
  503. * the range 0-255. According to section 20.6, the correlation
  504. * value ranges from 50-110. Ideally this would be calibrated
  505. * per hardware design, but we use roughly the datasheet values
  506. * to get close enough while avoiding floating point.
  507. */
  508. lqi = skb->data[len - 1] & 0x7f;
  509. if (lqi < 50)
  510. lqi = 50;
  511. else if (lqi > 113)
  512. lqi = 113;
  513. lqi = (lqi - 50) * 4;
  514. }
  515. ieee802154_rx_irqsafe(priv->hw, skb, lqi);
  516. dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi);
  517. return 0;
  518. }
  519. static int
  520. cc2520_ed(struct ieee802154_hw *hw, u8 *level)
  521. {
  522. struct cc2520_private *priv = hw->priv;
  523. u8 status = 0xff;
  524. u8 rssi;
  525. int ret;
  526. ret = cc2520_read_register(priv, CC2520_RSSISTAT, &status);
  527. if (ret)
  528. return ret;
  529. if (status != RSSI_VALID)
  530. return -EINVAL;
  531. ret = cc2520_read_register(priv, CC2520_RSSI, &rssi);
  532. if (ret)
  533. return ret;
  534. /* level = RSSI(rssi) - OFFSET [dBm] : offset is 76dBm */
  535. *level = rssi - RSSI_OFFSET;
  536. return 0;
  537. }
  538. static int
  539. cc2520_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
  540. {
  541. struct cc2520_private *priv = hw->priv;
  542. int ret;
  543. dev_dbg(&priv->spi->dev, "trying to set channel\n");
  544. WARN_ON(page != 0);
  545. WARN_ON(channel < CC2520_MINCHANNEL);
  546. WARN_ON(channel > CC2520_MAXCHANNEL);
  547. ret = cc2520_write_register(priv, CC2520_FREQCTRL,
  548. 11 + 5 * (channel - 11));
  549. return ret;
  550. }
  551. static int
  552. cc2520_filter(struct ieee802154_hw *hw,
  553. struct ieee802154_hw_addr_filt *filt, unsigned long changed)
  554. {
  555. struct cc2520_private *priv = hw->priv;
  556. int ret = 0;
  557. if (changed & IEEE802154_AFILT_PANID_CHANGED) {
  558. u16 panid = le16_to_cpu(filt->pan_id);
  559. dev_vdbg(&priv->spi->dev, "%s called for pan id\n", __func__);
  560. ret = cc2520_write_ram(priv, CC2520RAM_PANID,
  561. sizeof(panid), (u8 *)&panid);
  562. }
  563. if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
  564. dev_vdbg(&priv->spi->dev,
  565. "%s called for IEEE addr\n", __func__);
  566. ret = cc2520_write_ram(priv, CC2520RAM_IEEEADDR,
  567. sizeof(filt->ieee_addr),
  568. (u8 *)&filt->ieee_addr);
  569. }
  570. if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
  571. u16 addr = le16_to_cpu(filt->short_addr);
  572. dev_vdbg(&priv->spi->dev, "%s called for saddr\n", __func__);
  573. ret = cc2520_write_ram(priv, CC2520RAM_SHORTADDR,
  574. sizeof(addr), (u8 *)&addr);
  575. }
  576. if (changed & IEEE802154_AFILT_PANC_CHANGED) {
  577. u8 frmfilt0;
  578. dev_vdbg(&priv->spi->dev,
  579. "%s called for panc change\n", __func__);
  580. cc2520_read_register(priv, CC2520_FRMFILT0, &frmfilt0);
  581. if (filt->pan_coord)
  582. frmfilt0 |= FRMFILT0_PAN_COORDINATOR;
  583. else
  584. frmfilt0 &= ~FRMFILT0_PAN_COORDINATOR;
  585. ret = cc2520_write_register(priv, CC2520_FRMFILT0, frmfilt0);
  586. }
  587. return ret;
  588. }
  589. static inline int cc2520_set_tx_power(struct cc2520_private *priv, s32 mbm)
  590. {
  591. u8 power;
  592. switch (mbm) {
  593. case 500:
  594. power = 0xF7;
  595. break;
  596. case 300:
  597. power = 0xF2;
  598. break;
  599. case 200:
  600. power = 0xAB;
  601. break;
  602. case 100:
  603. power = 0x13;
  604. break;
  605. case 0:
  606. power = 0x32;
  607. break;
  608. case -200:
  609. power = 0x81;
  610. break;
  611. case -400:
  612. power = 0x88;
  613. break;
  614. case -700:
  615. power = 0x2C;
  616. break;
  617. case -1800:
  618. power = 0x03;
  619. break;
  620. default:
  621. return -EINVAL;
  622. }
  623. return cc2520_write_register(priv, CC2520_TXPOWER, power);
  624. }
  625. static inline int cc2520_cc2591_set_tx_power(struct cc2520_private *priv,
  626. s32 mbm)
  627. {
  628. u8 power;
  629. switch (mbm) {
  630. case 1700:
  631. power = 0xF9;
  632. break;
  633. case 1600:
  634. power = 0xF0;
  635. break;
  636. case 1400:
  637. power = 0xA0;
  638. break;
  639. case 1100:
  640. power = 0x2C;
  641. break;
  642. case -100:
  643. power = 0x03;
  644. break;
  645. case -800:
  646. power = 0x01;
  647. break;
  648. default:
  649. return -EINVAL;
  650. }
  651. return cc2520_write_register(priv, CC2520_TXPOWER, power);
  652. }
  653. #define CC2520_MAX_TX_POWERS 0x8
  654. static const s32 cc2520_powers[CC2520_MAX_TX_POWERS + 1] = {
  655. 500, 300, 200, 100, 0, -200, -400, -700, -1800,
  656. };
  657. #define CC2520_CC2591_MAX_TX_POWERS 0x5
  658. static const s32 cc2520_cc2591_powers[CC2520_CC2591_MAX_TX_POWERS + 1] = {
  659. 1700, 1600, 1400, 1100, -100, -800,
  660. };
  661. static int
  662. cc2520_set_txpower(struct ieee802154_hw *hw, s32 mbm)
  663. {
  664. struct cc2520_private *priv = hw->priv;
  665. if (!priv->amplified)
  666. return cc2520_set_tx_power(priv, mbm);
  667. return cc2520_cc2591_set_tx_power(priv, mbm);
  668. }
  669. static int
  670. cc2520_set_promiscuous_mode(struct ieee802154_hw *hw, bool on)
  671. {
  672. struct cc2520_private *priv = hw->priv;
  673. u8 frmfilt0;
  674. dev_dbg(&priv->spi->dev, "%s : mode %d\n", __func__, on);
  675. priv->promiscuous = on;
  676. cc2520_read_register(priv, CC2520_FRMFILT0, &frmfilt0);
  677. if (on) {
  678. /* Disable automatic ACK, automatic CRC, and frame filtering. */
  679. cc2520_write_register(priv, CC2520_FRMCTRL0, 0);
  680. frmfilt0 &= ~FRMFILT0_FRAME_FILTER_EN;
  681. } else {
  682. cc2520_write_register(priv, CC2520_FRMCTRL0, FRMCTRL0_AUTOACK |
  683. FRMCTRL0_AUTOCRC);
  684. frmfilt0 |= FRMFILT0_FRAME_FILTER_EN;
  685. }
  686. return cc2520_write_register(priv, CC2520_FRMFILT0, frmfilt0);
  687. }
  688. static const struct ieee802154_ops cc2520_ops = {
  689. .owner = THIS_MODULE,
  690. .start = cc2520_start,
  691. .stop = cc2520_stop,
  692. .xmit_sync = cc2520_tx,
  693. .ed = cc2520_ed,
  694. .set_channel = cc2520_set_channel,
  695. .set_hw_addr_filt = cc2520_filter,
  696. .set_txpower = cc2520_set_txpower,
  697. .set_promiscuous_mode = cc2520_set_promiscuous_mode,
  698. };
  699. static int cc2520_register(struct cc2520_private *priv)
  700. {
  701. int ret = -ENOMEM;
  702. priv->hw = ieee802154_alloc_hw(sizeof(*priv), &cc2520_ops);
  703. if (!priv->hw)
  704. goto err_ret;
  705. priv->hw->priv = priv;
  706. priv->hw->parent = &priv->spi->dev;
  707. priv->hw->extra_tx_headroom = 0;
  708. ieee802154_random_extended_addr(&priv->hw->phy->perm_extended_addr);
  709. /* We do support only 2.4 Ghz */
  710. priv->hw->phy->supported.channels[0] = 0x7FFF800;
  711. priv->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT |
  712. IEEE802154_HW_PROMISCUOUS;
  713. priv->hw->phy->flags = WPAN_PHY_FLAG_TXPOWER;
  714. if (!priv->amplified) {
  715. priv->hw->phy->supported.tx_powers = cc2520_powers;
  716. priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_powers);
  717. priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[4];
  718. } else {
  719. priv->hw->phy->supported.tx_powers = cc2520_cc2591_powers;
  720. priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_cc2591_powers);
  721. priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[0];
  722. }
  723. priv->hw->phy->current_channel = 11;
  724. dev_vdbg(&priv->spi->dev, "registered cc2520\n");
  725. ret = ieee802154_register_hw(priv->hw);
  726. if (ret)
  727. goto err_free_device;
  728. return 0;
  729. err_free_device:
  730. ieee802154_free_hw(priv->hw);
  731. err_ret:
  732. return ret;
  733. }
  734. static void cc2520_fifop_irqwork(struct work_struct *work)
  735. {
  736. struct cc2520_private *priv
  737. = container_of(work, struct cc2520_private, fifop_irqwork);
  738. dev_dbg(&priv->spi->dev, "fifop interrupt received\n");
  739. if (gpiod_get_value(priv->fifo_pin))
  740. cc2520_rx(priv);
  741. else
  742. dev_dbg(&priv->spi->dev, "rxfifo overflow\n");
  743. cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHRX);
  744. cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHRX);
  745. }
  746. static irqreturn_t cc2520_fifop_isr(int irq, void *data)
  747. {
  748. struct cc2520_private *priv = data;
  749. schedule_work(&priv->fifop_irqwork);
  750. return IRQ_HANDLED;
  751. }
  752. static irqreturn_t cc2520_sfd_isr(int irq, void *data)
  753. {
  754. struct cc2520_private *priv = data;
  755. unsigned long flags;
  756. spin_lock_irqsave(&priv->lock, flags);
  757. if (priv->is_tx) {
  758. priv->is_tx = 0;
  759. spin_unlock_irqrestore(&priv->lock, flags);
  760. dev_dbg(&priv->spi->dev, "SFD for TX\n");
  761. complete(&priv->tx_complete);
  762. } else {
  763. spin_unlock_irqrestore(&priv->lock, flags);
  764. dev_dbg(&priv->spi->dev, "SFD for RX\n");
  765. }
  766. return IRQ_HANDLED;
  767. }
  768. static int cc2520_hw_init(struct cc2520_private *priv)
  769. {
  770. u8 status = 0, state = 0xff;
  771. int ret;
  772. int timeout = 100;
  773. ret = cc2520_read_register(priv, CC2520_FSMSTAT1, &state);
  774. if (ret)
  775. goto err_ret;
  776. if (state != STATE_IDLE)
  777. return -EINVAL;
  778. do {
  779. ret = cc2520_get_status(priv, &status);
  780. if (ret)
  781. goto err_ret;
  782. if (timeout-- <= 0) {
  783. dev_err(&priv->spi->dev, "oscillator start failed!\n");
  784. return -ETIMEDOUT;
  785. }
  786. udelay(1);
  787. } while (!(status & CC2520_STATUS_XOSC32M_STABLE));
  788. dev_vdbg(&priv->spi->dev, "oscillator brought up\n");
  789. /* If the CC2520 is connected to a CC2591 amplifier, we must both
  790. * configure GPIOs on the CC2520 to correctly configure the CC2591
  791. * and change a couple settings of the CC2520 to work with the
  792. * amplifier. See section 8 page 17 of TI application note AN065.
  793. * http://www.ti.com/lit/an/swra229a/swra229a.pdf
  794. */
  795. if (priv->amplified) {
  796. ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x16);
  797. if (ret)
  798. goto err_ret;
  799. ret = cc2520_write_register(priv, CC2520_GPIOCTRL0, 0x46);
  800. if (ret)
  801. goto err_ret;
  802. ret = cc2520_write_register(priv, CC2520_GPIOCTRL5, 0x47);
  803. if (ret)
  804. goto err_ret;
  805. ret = cc2520_write_register(priv, CC2520_GPIOPOLARITY, 0x1e);
  806. if (ret)
  807. goto err_ret;
  808. ret = cc2520_write_register(priv, CC2520_TXCTRL, 0xc1);
  809. if (ret)
  810. goto err_ret;
  811. } else {
  812. ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11);
  813. if (ret)
  814. goto err_ret;
  815. }
  816. /* Registers default value: section 28.1 in Datasheet */
  817. /* Set the CCA threshold to -50 dBm. This seems to have been copied
  818. * from the TinyOS CC2520 driver and is much higher than the -84 dBm
  819. * threshold suggested in the datasheet.
  820. */
  821. ret = cc2520_write_register(priv, CC2520_CCACTRL0, 0x1A);
  822. if (ret)
  823. goto err_ret;
  824. ret = cc2520_write_register(priv, CC2520_MDMCTRL0, 0x85);
  825. if (ret)
  826. goto err_ret;
  827. ret = cc2520_write_register(priv, CC2520_MDMCTRL1, 0x14);
  828. if (ret)
  829. goto err_ret;
  830. ret = cc2520_write_register(priv, CC2520_RXCTRL, 0x3f);
  831. if (ret)
  832. goto err_ret;
  833. ret = cc2520_write_register(priv, CC2520_FSCTRL, 0x5a);
  834. if (ret)
  835. goto err_ret;
  836. ret = cc2520_write_register(priv, CC2520_FSCAL1, 0x2b);
  837. if (ret)
  838. goto err_ret;
  839. ret = cc2520_write_register(priv, CC2520_ADCTEST0, 0x10);
  840. if (ret)
  841. goto err_ret;
  842. ret = cc2520_write_register(priv, CC2520_ADCTEST1, 0x0e);
  843. if (ret)
  844. goto err_ret;
  845. ret = cc2520_write_register(priv, CC2520_ADCTEST2, 0x03);
  846. if (ret)
  847. goto err_ret;
  848. /* Configure registers correctly for this driver. */
  849. ret = cc2520_write_register(priv, CC2520_FRMCTRL1,
  850. FRMCTRL1_SET_RXENMASK_ON_TX |
  851. FRMCTRL1_IGNORE_TX_UNDERF);
  852. if (ret)
  853. goto err_ret;
  854. ret = cc2520_write_register(priv, CC2520_FIFOPCTRL, 127);
  855. if (ret)
  856. goto err_ret;
  857. return 0;
  858. err_ret:
  859. return ret;
  860. }
  861. static int cc2520_probe(struct spi_device *spi)
  862. {
  863. struct cc2520_private *priv;
  864. struct gpio_desc *fifop;
  865. struct gpio_desc *cca;
  866. struct gpio_desc *sfd;
  867. struct gpio_desc *reset;
  868. struct gpio_desc *vreg;
  869. int ret;
  870. priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
  871. if (!priv)
  872. return -ENOMEM;
  873. spi_set_drvdata(spi, priv);
  874. /* CC2591 front end for CC2520 */
  875. /* Assumption that CC2591 is not connected */
  876. priv->amplified = false;
  877. if (device_property_read_bool(&spi->dev, "amplified"))
  878. priv->amplified = true;
  879. priv->spi = spi;
  880. priv->buf = devm_kzalloc(&spi->dev,
  881. SPI_COMMAND_BUFFER, GFP_KERNEL);
  882. if (!priv->buf)
  883. return -ENOMEM;
  884. mutex_init(&priv->buffer_mutex);
  885. INIT_WORK(&priv->fifop_irqwork, cc2520_fifop_irqwork);
  886. spin_lock_init(&priv->lock);
  887. init_completion(&priv->tx_complete);
  888. /* Request all the gpio's */
  889. priv->fifo_pin = devm_gpiod_get(&spi->dev, "fifo", GPIOD_IN);
  890. if (IS_ERR(priv->fifo_pin)) {
  891. dev_err(&spi->dev, "fifo gpio is not valid\n");
  892. ret = PTR_ERR(priv->fifo_pin);
  893. goto err_hw_init;
  894. }
  895. cca = devm_gpiod_get(&spi->dev, "cca", GPIOD_IN);
  896. if (IS_ERR(cca)) {
  897. dev_err(&spi->dev, "cca gpio is not valid\n");
  898. ret = PTR_ERR(cca);
  899. goto err_hw_init;
  900. }
  901. fifop = devm_gpiod_get(&spi->dev, "fifop", GPIOD_IN);
  902. if (IS_ERR(fifop)) {
  903. dev_err(&spi->dev, "fifop gpio is not valid\n");
  904. ret = PTR_ERR(fifop);
  905. goto err_hw_init;
  906. }
  907. sfd = devm_gpiod_get(&spi->dev, "sfd", GPIOD_IN);
  908. if (IS_ERR(sfd)) {
  909. dev_err(&spi->dev, "sfd gpio is not valid\n");
  910. ret = PTR_ERR(sfd);
  911. goto err_hw_init;
  912. }
  913. reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW);
  914. if (IS_ERR(reset)) {
  915. dev_err(&spi->dev, "reset gpio is not valid\n");
  916. ret = PTR_ERR(reset);
  917. goto err_hw_init;
  918. }
  919. vreg = devm_gpiod_get(&spi->dev, "vreg", GPIOD_OUT_LOW);
  920. if (IS_ERR(vreg)) {
  921. dev_err(&spi->dev, "vreg gpio is not valid\n");
  922. ret = PTR_ERR(vreg);
  923. goto err_hw_init;
  924. }
  925. gpiod_set_value(vreg, HIGH);
  926. usleep_range(100, 150);
  927. gpiod_set_value(reset, HIGH);
  928. usleep_range(200, 250);
  929. ret = cc2520_hw_init(priv);
  930. if (ret)
  931. goto err_hw_init;
  932. /* Set up fifop interrupt */
  933. ret = devm_request_irq(&spi->dev,
  934. gpiod_to_irq(fifop),
  935. cc2520_fifop_isr,
  936. IRQF_TRIGGER_RISING,
  937. dev_name(&spi->dev),
  938. priv);
  939. if (ret) {
  940. dev_err(&spi->dev, "could not get fifop irq\n");
  941. goto err_hw_init;
  942. }
  943. /* Set up sfd interrupt */
  944. ret = devm_request_irq(&spi->dev,
  945. gpiod_to_irq(sfd),
  946. cc2520_sfd_isr,
  947. IRQF_TRIGGER_FALLING,
  948. dev_name(&spi->dev),
  949. priv);
  950. if (ret) {
  951. dev_err(&spi->dev, "could not get sfd irq\n");
  952. goto err_hw_init;
  953. }
  954. ret = cc2520_register(priv);
  955. if (ret)
  956. goto err_hw_init;
  957. return 0;
  958. err_hw_init:
  959. mutex_destroy(&priv->buffer_mutex);
  960. flush_work(&priv->fifop_irqwork);
  961. return ret;
  962. }
  963. static void cc2520_remove(struct spi_device *spi)
  964. {
  965. struct cc2520_private *priv = spi_get_drvdata(spi);
  966. mutex_destroy(&priv->buffer_mutex);
  967. flush_work(&priv->fifop_irqwork);
  968. ieee802154_unregister_hw(priv->hw);
  969. ieee802154_free_hw(priv->hw);
  970. }
  971. static const struct spi_device_id cc2520_ids[] = {
  972. {"cc2520", },
  973. {},
  974. };
  975. MODULE_DEVICE_TABLE(spi, cc2520_ids);
  976. static const struct of_device_id cc2520_of_ids[] = {
  977. {.compatible = "ti,cc2520", },
  978. {},
  979. };
  980. MODULE_DEVICE_TABLE(of, cc2520_of_ids);
  981. /* SPI driver structure */
  982. static struct spi_driver cc2520_driver = {
  983. .driver = {
  984. .name = "cc2520",
  985. .of_match_table = cc2520_of_ids,
  986. },
  987. .id_table = cc2520_ids,
  988. .probe = cc2520_probe,
  989. .remove = cc2520_remove,
  990. };
  991. module_spi_driver(cc2520_driver);
  992. MODULE_AUTHOR("Varka Bhadram <varkab@cdac.in>");
  993. MODULE_DESCRIPTION("CC2520 Transceiver Driver");
  994. MODULE_LICENSE("GPL v2");