cxgb4_ptp.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /*
  2. * cxgb4_ptp.c:Chelsio PTP support for T5/T6
  3. *
  4. * Copyright (c) 2003-2017 Chelsio Communications, Inc. All rights reserved.
  5. *
  6. * This software is available to you under a choice of one of two
  7. * licenses. You may choose to be licensed under the terms of the GNU
  8. * General Public License (GPL) Version 2, available from the file
  9. * COPYING in the main directory of this source tree, or the
  10. * OpenIB.org BSD license below:
  11. *
  12. * Redistribution and use in source and binary forms, with or
  13. * without modification, are permitted provided that the following
  14. * conditions are met:
  15. *
  16. * - Redistributions of source code must retain the above
  17. * copyright notice, this list of conditions and the following
  18. * disclaimer.
  19. *
  20. * - Redistributions in binary form must reproduce the above
  21. * copyright notice, this list of conditions and the following
  22. * disclaimer in the documentation and/or other materials
  23. * provided with the distribution.
  24. *
  25. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  26. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  27. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  28. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  29. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  30. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  31. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  32. * SOFTWARE.
  33. *
  34. * Written by: Atul Gupta (atul.gupta@chelsio.com)
  35. */
  36. #include <linux/module.h>
  37. #include <linux/net_tstamp.h>
  38. #include <linux/skbuff.h>
  39. #include <linux/netdevice.h>
  40. #include <linux/pps_kernel.h>
  41. #include <linux/ptp_clock_kernel.h>
  42. #include <linux/ptp_classify.h>
  43. #include <linux/udp.h>
  44. #include "cxgb4.h"
  45. #include "t4_hw.h"
  46. #include "t4_regs.h"
  47. #include "t4_msg.h"
  48. #include "t4fw_api.h"
  49. #include "cxgb4_ptp.h"
  50. /**
  51. * cxgb4_ptp_is_ptp_tx - determine whether TX packet is PTP or not
  52. * @skb: skb of outgoing ptp request
  53. *
  54. */
  55. bool cxgb4_ptp_is_ptp_tx(struct sk_buff *skb)
  56. {
  57. struct udphdr *uh;
  58. uh = udp_hdr(skb);
  59. return skb->len >= PTP_MIN_LENGTH &&
  60. skb->len <= PTP_IN_TRANSMIT_PACKET_MAXNUM &&
  61. likely(skb->protocol == htons(ETH_P_IP)) &&
  62. ip_hdr(skb)->protocol == IPPROTO_UDP &&
  63. uh->dest == htons(PTP_EVENT_PORT);
  64. }
  65. bool is_ptp_enabled(struct sk_buff *skb, struct net_device *dev)
  66. {
  67. struct port_info *pi;
  68. pi = netdev_priv(dev);
  69. return (pi->ptp_enable && cxgb4_xmit_with_hwtstamp(skb) &&
  70. cxgb4_ptp_is_ptp_tx(skb));
  71. }
  72. /**
  73. * cxgb4_ptp_is_ptp_rx - determine whether RX packet is PTP or not
  74. * @skb: skb of incoming ptp request
  75. *
  76. */
  77. bool cxgb4_ptp_is_ptp_rx(struct sk_buff *skb)
  78. {
  79. struct udphdr *uh = (struct udphdr *)(skb->data + ETH_HLEN +
  80. IPV4_HLEN(skb->data));
  81. return uh->dest == htons(PTP_EVENT_PORT) &&
  82. uh->source == htons(PTP_EVENT_PORT);
  83. }
  84. /**
  85. * cxgb4_ptp_read_hwstamp - read timestamp for TX event PTP message
  86. * @adapter: board private structure
  87. * @pi: port private structure
  88. *
  89. */
  90. void cxgb4_ptp_read_hwstamp(struct adapter *adapter, struct port_info *pi)
  91. {
  92. struct skb_shared_hwtstamps *skb_ts = NULL;
  93. u64 tx_ts;
  94. skb_ts = skb_hwtstamps(adapter->ptp_tx_skb);
  95. tx_ts = t4_read_reg(adapter,
  96. T5_PORT_REG(pi->port_id, MAC_PORT_TX_TS_VAL_LO));
  97. tx_ts |= (u64)t4_read_reg(adapter,
  98. T5_PORT_REG(pi->port_id,
  99. MAC_PORT_TX_TS_VAL_HI)) << 32;
  100. skb_ts->hwtstamp = ns_to_ktime(tx_ts);
  101. skb_tstamp_tx(adapter->ptp_tx_skb, skb_ts);
  102. dev_kfree_skb_any(adapter->ptp_tx_skb);
  103. spin_lock(&adapter->ptp_lock);
  104. adapter->ptp_tx_skb = NULL;
  105. spin_unlock(&adapter->ptp_lock);
  106. }
  107. /**
  108. * cxgb4_ptprx_timestamping - Enable Timestamp for RX PTP event message
  109. * @pi: port private structure
  110. * @port: pot number
  111. * @mode: RX mode
  112. *
  113. */
  114. int cxgb4_ptprx_timestamping(struct port_info *pi, u8 port, u16 mode)
  115. {
  116. struct adapter *adapter = pi->adapter;
  117. struct fw_ptp_cmd c;
  118. int err;
  119. memset(&c, 0, sizeof(c));
  120. c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) |
  121. FW_CMD_REQUEST_F |
  122. FW_CMD_WRITE_F |
  123. FW_PTP_CMD_PORTID_V(port));
  124. c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16));
  125. c.u.init.sc = FW_PTP_SC_RXTIME_STAMP;
  126. c.u.init.mode = cpu_to_be16(mode);
  127. err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL);
  128. if (err < 0)
  129. dev_err(adapter->pdev_dev,
  130. "PTP: %s error %d\n", __func__, -err);
  131. return err;
  132. }
  133. int cxgb4_ptp_txtype(struct adapter *adapter, u8 port)
  134. {
  135. struct fw_ptp_cmd c;
  136. int err;
  137. memset(&c, 0, sizeof(c));
  138. c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) |
  139. FW_CMD_REQUEST_F |
  140. FW_CMD_WRITE_F |
  141. FW_PTP_CMD_PORTID_V(port));
  142. c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16));
  143. c.u.init.sc = FW_PTP_SC_TX_TYPE;
  144. c.u.init.mode = cpu_to_be16(PTP_TS_NONE);
  145. err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL);
  146. if (err < 0)
  147. dev_err(adapter->pdev_dev,
  148. "PTP: %s error %d\n", __func__, -err);
  149. return err;
  150. }
  151. int cxgb4_ptp_redirect_rx_packet(struct adapter *adapter, struct port_info *pi)
  152. {
  153. struct sge *s = &adapter->sge;
  154. struct sge_eth_rxq *receive_q = &s->ethrxq[pi->first_qset];
  155. struct fw_ptp_cmd c;
  156. int err;
  157. memset(&c, 0, sizeof(c));
  158. c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) |
  159. FW_CMD_REQUEST_F |
  160. FW_CMD_WRITE_F |
  161. FW_PTP_CMD_PORTID_V(pi->port_id));
  162. c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16));
  163. c.u.init.sc = FW_PTP_SC_RDRX_TYPE;
  164. c.u.init.txchan = pi->tx_chan;
  165. c.u.init.absid = cpu_to_be16(receive_q->rspq.abs_id);
  166. err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL);
  167. if (err < 0)
  168. dev_err(adapter->pdev_dev,
  169. "PTP: %s error %d\n", __func__, -err);
  170. return err;
  171. }
  172. /**
  173. * @ptp: ptp clock structure
  174. * @ppb: Desired frequency change in parts per billion
  175. *
  176. * Adjust the frequency of the PHC cycle counter by the indicated ppb from
  177. * the base frequency.
  178. */
  179. static int cxgb4_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
  180. {
  181. struct adapter *adapter = (struct adapter *)container_of(ptp,
  182. struct adapter, ptp_clock_info);
  183. struct fw_ptp_cmd c;
  184. int err;
  185. memset(&c, 0, sizeof(c));
  186. c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) |
  187. FW_CMD_REQUEST_F |
  188. FW_CMD_WRITE_F |
  189. FW_PTP_CMD_PORTID_V(0));
  190. c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16));
  191. c.u.ts.sc = FW_PTP_SC_ADJ_FREQ;
  192. c.u.ts.sign = (ppb < 0) ? 1 : 0;
  193. if (ppb < 0)
  194. ppb = -ppb;
  195. c.u.ts.ppb = cpu_to_be32(ppb);
  196. err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL);
  197. if (err < 0)
  198. dev_err(adapter->pdev_dev,
  199. "PTP: %s error %d\n", __func__, -err);
  200. return err;
  201. }
  202. /**
  203. * cxgb4_ptp_fineadjtime - Shift the time of the hardware clock
  204. * @ptp: ptp clock structure
  205. * @delta: Desired change in nanoseconds
  206. *
  207. * Adjust the timer by resetting the timecounter structure.
  208. */
  209. static int cxgb4_ptp_fineadjtime(struct adapter *adapter, s64 delta)
  210. {
  211. struct fw_ptp_cmd c;
  212. int err;
  213. memset(&c, 0, sizeof(c));
  214. c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) |
  215. FW_CMD_REQUEST_F |
  216. FW_CMD_WRITE_F |
  217. FW_PTP_CMD_PORTID_V(0));
  218. c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16));
  219. c.u.ts.sc = FW_PTP_SC_ADJ_FTIME;
  220. c.u.ts.tm = cpu_to_be64(delta);
  221. err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL);
  222. if (err < 0)
  223. dev_err(adapter->pdev_dev,
  224. "PTP: %s error %d\n", __func__, -err);
  225. return err;
  226. }
  227. /**
  228. * cxgb4_ptp_adjtime - Shift the time of the hardware clock
  229. * @ptp: ptp clock structure
  230. * @delta: Desired change in nanoseconds
  231. *
  232. * Adjust the timer by resetting the timecounter structure.
  233. */
  234. static int cxgb4_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
  235. {
  236. struct adapter *adapter =
  237. (struct adapter *)container_of(ptp, struct adapter,
  238. ptp_clock_info);
  239. struct fw_ptp_cmd c;
  240. s64 sign = 1;
  241. int err;
  242. if (delta < 0)
  243. sign = -1;
  244. if (delta * sign > PTP_CLOCK_MAX_ADJTIME) {
  245. memset(&c, 0, sizeof(c));
  246. c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) |
  247. FW_CMD_REQUEST_F |
  248. FW_CMD_WRITE_F |
  249. FW_PTP_CMD_PORTID_V(0));
  250. c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16));
  251. c.u.ts.sc = FW_PTP_SC_ADJ_TIME;
  252. c.u.ts.sign = (delta < 0) ? 1 : 0;
  253. if (delta < 0)
  254. delta = -delta;
  255. c.u.ts.tm = cpu_to_be64(delta);
  256. err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL);
  257. if (err < 0)
  258. dev_err(adapter->pdev_dev,
  259. "PTP: %s error %d\n", __func__, -err);
  260. } else {
  261. err = cxgb4_ptp_fineadjtime(adapter, delta);
  262. }
  263. return err;
  264. }
  265. /**
  266. * cxgb4_ptp_gettime - Reads the current time from the hardware clock
  267. * @ptp: ptp clock structure
  268. * @ts: timespec structure to hold the current time value
  269. *
  270. * Read the timecounter and return the correct value in ns after converting
  271. * it into a struct timespec.
  272. */
  273. static int cxgb4_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
  274. {
  275. struct adapter *adapter = (struct adapter *)container_of(ptp,
  276. struct adapter, ptp_clock_info);
  277. struct fw_ptp_cmd c;
  278. u64 ns;
  279. int err;
  280. memset(&c, 0, sizeof(c));
  281. c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) |
  282. FW_CMD_REQUEST_F |
  283. FW_CMD_READ_F |
  284. FW_PTP_CMD_PORTID_V(0));
  285. c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16));
  286. c.u.ts.sc = FW_PTP_SC_GET_TIME;
  287. err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), &c);
  288. if (err < 0) {
  289. dev_err(adapter->pdev_dev,
  290. "PTP: %s error %d\n", __func__, -err);
  291. return err;
  292. }
  293. /* convert to timespec*/
  294. ns = be64_to_cpu(c.u.ts.tm);
  295. *ts = ns_to_timespec64(ns);
  296. return err;
  297. }
  298. /**
  299. * cxgb4_ptp_settime - Set the current time on the hardware clock
  300. * @ptp: ptp clock structure
  301. * @ts: timespec containing the new time for the cycle counter
  302. *
  303. * Reset value to new base value instead of the kernel
  304. * wall timer value.
  305. */
  306. static int cxgb4_ptp_settime(struct ptp_clock_info *ptp,
  307. const struct timespec64 *ts)
  308. {
  309. struct adapter *adapter = (struct adapter *)container_of(ptp,
  310. struct adapter, ptp_clock_info);
  311. struct fw_ptp_cmd c;
  312. u64 ns;
  313. int err;
  314. memset(&c, 0, sizeof(c));
  315. c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) |
  316. FW_CMD_REQUEST_F |
  317. FW_CMD_WRITE_F |
  318. FW_PTP_CMD_PORTID_V(0));
  319. c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16));
  320. c.u.ts.sc = FW_PTP_SC_SET_TIME;
  321. ns = timespec64_to_ns(ts);
  322. c.u.ts.tm = cpu_to_be64(ns);
  323. err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL);
  324. if (err < 0)
  325. dev_err(adapter->pdev_dev,
  326. "PTP: %s error %d\n", __func__, -err);
  327. return err;
  328. }
  329. static void cxgb4_init_ptp_timer(struct adapter *adapter)
  330. {
  331. struct fw_ptp_cmd c;
  332. int err;
  333. memset(&c, 0, sizeof(c));
  334. c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) |
  335. FW_CMD_REQUEST_F |
  336. FW_CMD_WRITE_F |
  337. FW_PTP_CMD_PORTID_V(0));
  338. c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16));
  339. c.u.scmd.sc = FW_PTP_SC_INIT_TIMER;
  340. err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL);
  341. if (err < 0)
  342. dev_err(adapter->pdev_dev,
  343. "PTP: %s error %d\n", __func__, -err);
  344. }
  345. /**
  346. * cxgb4_ptp_enable - enable or disable an ancillary feature
  347. * @ptp: ptp clock structure
  348. * @request: Desired resource to enable or disable
  349. * @on: Caller passes one to enable or zero to disable
  350. *
  351. * Enable (or disable) ancillary features of the PHC subsystem.
  352. * Currently, no ancillary features are supported.
  353. */
  354. static int cxgb4_ptp_enable(struct ptp_clock_info __always_unused *ptp,
  355. struct ptp_clock_request __always_unused *request,
  356. int __always_unused on)
  357. {
  358. return -ENOTSUPP;
  359. }
  360. static const struct ptp_clock_info cxgb4_ptp_clock_info = {
  361. .owner = THIS_MODULE,
  362. .name = "cxgb4_clock",
  363. .max_adj = MAX_PTP_FREQ_ADJ,
  364. .n_alarm = 0,
  365. .n_ext_ts = 0,
  366. .n_per_out = 0,
  367. .pps = 0,
  368. .adjfreq = cxgb4_ptp_adjfreq,
  369. .adjtime = cxgb4_ptp_adjtime,
  370. .gettime64 = cxgb4_ptp_gettime,
  371. .settime64 = cxgb4_ptp_settime,
  372. .enable = cxgb4_ptp_enable,
  373. };
  374. /**
  375. * cxgb4_ptp_init - initialize PTP for devices which support it
  376. * @adapter: board private structure
  377. *
  378. * This function performs the required steps for enabling PTP support.
  379. */
  380. void cxgb4_ptp_init(struct adapter *adapter)
  381. {
  382. struct timespec64 now;
  383. /* no need to create a clock device if we already have one */
  384. if (!IS_ERR_OR_NULL(adapter->ptp_clock))
  385. return;
  386. adapter->ptp_tx_skb = NULL;
  387. adapter->ptp_clock_info = cxgb4_ptp_clock_info;
  388. spin_lock_init(&adapter->ptp_lock);
  389. adapter->ptp_clock = ptp_clock_register(&adapter->ptp_clock_info,
  390. &adapter->pdev->dev);
  391. if (IS_ERR_OR_NULL(adapter->ptp_clock)) {
  392. adapter->ptp_clock = NULL;
  393. dev_err(adapter->pdev_dev,
  394. "PTP %s Clock registration has failed\n", __func__);
  395. return;
  396. }
  397. now = ktime_to_timespec64(ktime_get_real());
  398. cxgb4_init_ptp_timer(adapter);
  399. if (cxgb4_ptp_settime(&adapter->ptp_clock_info, &now) < 0) {
  400. ptp_clock_unregister(adapter->ptp_clock);
  401. adapter->ptp_clock = NULL;
  402. }
  403. }
  404. /**
  405. * cxgb4_ptp_remove - disable PTP device and stop the overflow check
  406. * @adapter: board private structure
  407. *
  408. * Stop the PTP support.
  409. */
  410. void cxgb4_ptp_stop(struct adapter *adapter)
  411. {
  412. if (adapter->ptp_tx_skb) {
  413. dev_kfree_skb_any(adapter->ptp_tx_skb);
  414. adapter->ptp_tx_skb = NULL;
  415. }
  416. if (adapter->ptp_clock) {
  417. ptp_clock_unregister(adapter->ptp_clock);
  418. adapter->ptp_clock = NULL;
  419. }
  420. }