0001
0002
0003
0004 #include "ice.h"
0005 #include "ice_lib.h"
0006 #include <linux/tty_driver.h>
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 static unsigned int
0017 ice_gnss_do_write(struct ice_pf *pf, unsigned char *buf, unsigned int size)
0018 {
0019 struct ice_aqc_link_topo_addr link_topo;
0020 struct ice_hw *hw = &pf->hw;
0021 unsigned int offset = 0;
0022 int err = 0;
0023
0024 memset(&link_topo, 0, sizeof(struct ice_aqc_link_topo_addr));
0025 link_topo.topo_params.index = ICE_E810T_GNSS_I2C_BUS;
0026 link_topo.topo_params.node_type_ctx |=
0027 FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M,
0028 ICE_AQC_LINK_TOPO_NODE_CTX_OVERRIDE);
0029
0030
0031
0032
0033
0034
0035
0036 while (size - offset > ICE_GNSS_UBX_WRITE_BYTES + 1) {
0037 err = ice_aq_write_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR,
0038 cpu_to_le16(buf[offset]),
0039 ICE_MAX_I2C_WRITE_BYTES,
0040 &buf[offset + 1], NULL);
0041 if (err)
0042 goto err_out;
0043
0044 offset += ICE_GNSS_UBX_WRITE_BYTES;
0045 }
0046
0047
0048 if (size - offset == ICE_GNSS_UBX_WRITE_BYTES + 1) {
0049 err = ice_aq_write_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR,
0050 cpu_to_le16(buf[offset]),
0051 ICE_MAX_I2C_WRITE_BYTES - 1,
0052 &buf[offset + 1], NULL);
0053 if (err)
0054 goto err_out;
0055
0056 offset += ICE_GNSS_UBX_WRITE_BYTES - 1;
0057 }
0058
0059
0060 err = ice_aq_write_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR,
0061 cpu_to_le16(buf[offset]), size - offset - 1,
0062 &buf[offset + 1], NULL);
0063 if (err)
0064 goto err_out;
0065
0066 return size;
0067
0068 err_out:
0069 dev_err(ice_pf_to_dev(pf), "GNSS failed to write, offset=%u, size=%u, err=%d\n",
0070 offset, size, err);
0071
0072 return offset;
0073 }
0074
0075
0076
0077
0078
0079 static void ice_gnss_write_pending(struct kthread_work *work)
0080 {
0081 struct gnss_serial *gnss = container_of(work, struct gnss_serial,
0082 write_work);
0083 struct ice_pf *pf = gnss->back;
0084
0085 if (!list_empty(&gnss->queue)) {
0086 struct gnss_write_buf *write_buf = NULL;
0087 unsigned int bytes;
0088
0089 write_buf = list_first_entry(&gnss->queue,
0090 struct gnss_write_buf, queue);
0091
0092 bytes = ice_gnss_do_write(pf, write_buf->buf, write_buf->size);
0093 dev_dbg(ice_pf_to_dev(pf), "%u bytes written to GNSS\n", bytes);
0094
0095 list_del(&write_buf->queue);
0096 kfree(write_buf->buf);
0097 kfree(write_buf);
0098 }
0099 }
0100
0101
0102
0103
0104
0105
0106
0107
0108 static void ice_gnss_read(struct kthread_work *work)
0109 {
0110 struct gnss_serial *gnss = container_of(work, struct gnss_serial,
0111 read_work.work);
0112 struct ice_aqc_link_topo_addr link_topo;
0113 unsigned int i, bytes_read, data_len;
0114 struct tty_port *port;
0115 struct ice_pf *pf;
0116 struct ice_hw *hw;
0117 __be16 data_len_b;
0118 char *buf = NULL;
0119 u8 i2c_params;
0120 int err = 0;
0121
0122 pf = gnss->back;
0123 if (!pf || !gnss->tty || !gnss->tty->port) {
0124 err = -EFAULT;
0125 goto exit;
0126 }
0127
0128 hw = &pf->hw;
0129 port = gnss->tty->port;
0130
0131 buf = (char *)get_zeroed_page(GFP_KERNEL);
0132 if (!buf) {
0133 err = -ENOMEM;
0134 goto exit;
0135 }
0136
0137 memset(&link_topo, 0, sizeof(struct ice_aqc_link_topo_addr));
0138 link_topo.topo_params.index = ICE_E810T_GNSS_I2C_BUS;
0139 link_topo.topo_params.node_type_ctx |=
0140 FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M,
0141 ICE_AQC_LINK_TOPO_NODE_CTX_OVERRIDE);
0142
0143 i2c_params = ICE_GNSS_UBX_DATA_LEN_WIDTH |
0144 ICE_AQC_I2C_USE_REPEATED_START;
0145
0146
0147 for (i = 0; i < ICE_MAX_UBX_READ_TRIES; i++) {
0148 err = ice_aq_read_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR,
0149 cpu_to_le16(ICE_GNSS_UBX_DATA_LEN_H),
0150 i2c_params, (u8 *)&data_len_b, NULL);
0151 if (err)
0152 goto exit_buf;
0153
0154 data_len = be16_to_cpu(data_len_b);
0155 if (data_len != 0 && data_len != U16_MAX)
0156 break;
0157
0158 mdelay(10);
0159 }
0160
0161 data_len = min_t(typeof(data_len), data_len, PAGE_SIZE);
0162 data_len = tty_buffer_request_room(port, data_len);
0163 if (!data_len) {
0164 err = -ENOMEM;
0165 goto exit_buf;
0166 }
0167
0168
0169 for (i = 0; i < data_len; i += bytes_read) {
0170 unsigned int bytes_left = data_len - i;
0171
0172 bytes_read = min_t(typeof(bytes_left), bytes_left,
0173 ICE_MAX_I2C_DATA_SIZE);
0174
0175 err = ice_aq_read_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR,
0176 cpu_to_le16(ICE_GNSS_UBX_EMPTY_DATA),
0177 bytes_read, &buf[i], NULL);
0178 if (err)
0179 goto exit_buf;
0180 }
0181
0182
0183
0184
0185 tty_insert_flip_string(port, buf, i);
0186 tty_flip_buffer_push(port);
0187
0188 exit_buf:
0189 free_page((unsigned long)buf);
0190 kthread_queue_delayed_work(gnss->kworker, &gnss->read_work,
0191 ICE_GNSS_TIMER_DELAY_TIME);
0192 exit:
0193 if (err)
0194 dev_dbg(ice_pf_to_dev(pf), "GNSS failed to read err=%d\n", err);
0195 }
0196
0197
0198
0199
0200
0201
0202 static struct gnss_serial *ice_gnss_struct_init(struct ice_pf *pf, int index)
0203 {
0204 struct device *dev = ice_pf_to_dev(pf);
0205 struct kthread_worker *kworker;
0206 struct gnss_serial *gnss;
0207
0208 gnss = kzalloc(sizeof(*gnss), GFP_KERNEL);
0209 if (!gnss)
0210 return NULL;
0211
0212 mutex_init(&gnss->gnss_mutex);
0213 gnss->open_count = 0;
0214 gnss->back = pf;
0215 pf->gnss_serial[index] = gnss;
0216
0217 kthread_init_delayed_work(&gnss->read_work, ice_gnss_read);
0218 INIT_LIST_HEAD(&gnss->queue);
0219 kthread_init_work(&gnss->write_work, ice_gnss_write_pending);
0220
0221
0222
0223 kworker = kthread_create_worker(0, "ice-gnss-%s", dev_name(dev));
0224 if (IS_ERR(kworker)) {
0225 kfree(gnss);
0226 return NULL;
0227 }
0228
0229 gnss->kworker = kworker;
0230
0231 return gnss;
0232 }
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 static int ice_gnss_tty_open(struct tty_struct *tty, struct file *filp)
0243 {
0244 struct gnss_serial *gnss;
0245 struct ice_pf *pf;
0246
0247 pf = (struct ice_pf *)tty->driver->driver_state;
0248 if (!pf)
0249 return -EFAULT;
0250
0251
0252 tty->driver_data = NULL;
0253
0254
0255 gnss = pf->gnss_serial[tty->index];
0256 if (!gnss) {
0257
0258 gnss = ice_gnss_struct_init(pf, tty->index);
0259 if (!gnss)
0260 return -ENOMEM;
0261 }
0262
0263 mutex_lock(&gnss->gnss_mutex);
0264
0265
0266 tty->driver_data = gnss;
0267 gnss->tty = tty;
0268 gnss->open_count++;
0269 kthread_queue_delayed_work(gnss->kworker, &gnss->read_work, 0);
0270
0271 mutex_unlock(&gnss->gnss_mutex);
0272
0273 return 0;
0274 }
0275
0276
0277
0278
0279
0280
0281 static void ice_gnss_tty_close(struct tty_struct *tty, struct file *filp)
0282 {
0283 struct gnss_serial *gnss = tty->driver_data;
0284 struct ice_pf *pf;
0285
0286 if (!gnss)
0287 return;
0288
0289 pf = (struct ice_pf *)tty->driver->driver_state;
0290 if (!pf)
0291 return;
0292
0293 mutex_lock(&gnss->gnss_mutex);
0294
0295 if (!gnss->open_count) {
0296
0297 dev_err(ice_pf_to_dev(pf), "GNSS port not opened\n");
0298 goto exit;
0299 }
0300
0301 gnss->open_count--;
0302 if (gnss->open_count <= 0) {
0303
0304 kthread_cancel_delayed_work_sync(&gnss->read_work);
0305 }
0306 exit:
0307 mutex_unlock(&gnss->gnss_mutex);
0308 }
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 static int
0324 ice_gnss_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
0325 {
0326 struct gnss_write_buf *write_buf;
0327 struct gnss_serial *gnss;
0328 unsigned char *cmd_buf;
0329 struct ice_pf *pf;
0330 int err = count;
0331
0332
0333 if (count <= 1 || count > ICE_GNSS_TTY_WRITE_BUF)
0334 return -EINVAL;
0335
0336 gnss = tty->driver_data;
0337 if (!gnss)
0338 return -EFAULT;
0339
0340 pf = (struct ice_pf *)tty->driver->driver_state;
0341 if (!pf)
0342 return -EFAULT;
0343
0344
0345 if (gnss != pf->gnss_serial[0])
0346 return -EIO;
0347
0348 mutex_lock(&gnss->gnss_mutex);
0349
0350 if (!gnss->open_count) {
0351 err = -EINVAL;
0352 goto exit;
0353 }
0354
0355 cmd_buf = kcalloc(count, sizeof(*buf), GFP_KERNEL);
0356 if (!cmd_buf) {
0357 err = -ENOMEM;
0358 goto exit;
0359 }
0360
0361 memcpy(cmd_buf, buf, count);
0362
0363
0364 write_buf = kzalloc(sizeof(*write_buf), GFP_KERNEL);
0365 if (!write_buf) {
0366 err = -ENOMEM;
0367 goto exit;
0368 }
0369
0370 write_buf->buf = cmd_buf;
0371 write_buf->size = count;
0372 INIT_LIST_HEAD(&write_buf->queue);
0373 list_add_tail(&write_buf->queue, &gnss->queue);
0374 kthread_queue_work(gnss->kworker, &gnss->write_work);
0375 exit:
0376 mutex_unlock(&gnss->gnss_mutex);
0377 return err;
0378 }
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388 static unsigned int ice_gnss_tty_write_room(struct tty_struct *tty)
0389 {
0390 struct gnss_serial *gnss = tty->driver_data;
0391
0392
0393 if (!gnss || gnss != gnss->back->gnss_serial[0])
0394 return 0;
0395
0396 mutex_lock(&gnss->gnss_mutex);
0397
0398 if (!gnss->open_count) {
0399 mutex_unlock(&gnss->gnss_mutex);
0400 return 0;
0401 }
0402
0403 mutex_unlock(&gnss->gnss_mutex);
0404 return ICE_GNSS_TTY_WRITE_BUF;
0405 }
0406
0407 static const struct tty_operations tty_gps_ops = {
0408 .open = ice_gnss_tty_open,
0409 .close = ice_gnss_tty_close,
0410 .write = ice_gnss_tty_write,
0411 .write_room = ice_gnss_tty_write_room,
0412 };
0413
0414
0415
0416
0417
0418 static struct tty_driver *ice_gnss_create_tty_driver(struct ice_pf *pf)
0419 {
0420 struct device *dev = ice_pf_to_dev(pf);
0421 const int ICE_TTYDRV_NAME_MAX = 14;
0422 struct tty_driver *tty_driver;
0423 char *ttydrv_name;
0424 unsigned int i;
0425 int err;
0426
0427 tty_driver = tty_alloc_driver(ICE_GNSS_TTY_MINOR_DEVICES,
0428 TTY_DRIVER_REAL_RAW);
0429 if (IS_ERR(tty_driver)) {
0430 dev_err(dev, "Failed to allocate memory for GNSS TTY\n");
0431 return NULL;
0432 }
0433
0434 ttydrv_name = kzalloc(ICE_TTYDRV_NAME_MAX, GFP_KERNEL);
0435 if (!ttydrv_name) {
0436 tty_driver_kref_put(tty_driver);
0437 return NULL;
0438 }
0439
0440 snprintf(ttydrv_name, ICE_TTYDRV_NAME_MAX, "ttyGNSS_%02x%02x_",
0441 (u8)pf->pdev->bus->number, (u8)PCI_SLOT(pf->pdev->devfn));
0442
0443
0444 tty_driver->owner = THIS_MODULE;
0445 tty_driver->driver_name = dev_driver_string(dev);
0446 tty_driver->name = (const char *)ttydrv_name;
0447 tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
0448 tty_driver->subtype = SERIAL_TYPE_NORMAL;
0449 tty_driver->init_termios = tty_std_termios;
0450 tty_driver->init_termios.c_iflag &= ~INLCR;
0451 tty_driver->init_termios.c_iflag |= IGNCR;
0452 tty_driver->init_termios.c_oflag &= ~OPOST;
0453 tty_driver->init_termios.c_lflag &= ~ICANON;
0454 tty_driver->init_termios.c_cflag &= ~(CSIZE | CBAUD | CBAUDEX);
0455
0456 tty_termios_encode_baud_rate(&tty_driver->init_termios, 9600, 9600);
0457 tty_driver->driver_state = pf;
0458 tty_set_operations(tty_driver, &tty_gps_ops);
0459
0460 for (i = 0; i < ICE_GNSS_TTY_MINOR_DEVICES; i++) {
0461 pf->gnss_tty_port[i] = kzalloc(sizeof(*pf->gnss_tty_port[i]),
0462 GFP_KERNEL);
0463 pf->gnss_serial[i] = NULL;
0464
0465 tty_port_init(pf->gnss_tty_port[i]);
0466 tty_port_link_device(pf->gnss_tty_port[i], tty_driver, i);
0467 }
0468
0469 err = tty_register_driver(tty_driver);
0470 if (err) {
0471 dev_err(dev, "Failed to register TTY driver err=%d\n", err);
0472
0473 for (i = 0; i < ICE_GNSS_TTY_MINOR_DEVICES; i++) {
0474 tty_port_destroy(pf->gnss_tty_port[i]);
0475 kfree(pf->gnss_tty_port[i]);
0476 }
0477 kfree(ttydrv_name);
0478 tty_driver_kref_put(pf->ice_gnss_tty_driver);
0479
0480 return NULL;
0481 }
0482
0483 for (i = 0; i < ICE_GNSS_TTY_MINOR_DEVICES; i++)
0484 dev_info(dev, "%s%d registered\n", ttydrv_name, i);
0485
0486 return tty_driver;
0487 }
0488
0489
0490
0491
0492
0493 void ice_gnss_init(struct ice_pf *pf)
0494 {
0495 struct tty_driver *tty_driver;
0496
0497 tty_driver = ice_gnss_create_tty_driver(pf);
0498 if (!tty_driver)
0499 return;
0500
0501 pf->ice_gnss_tty_driver = tty_driver;
0502
0503 set_bit(ICE_FLAG_GNSS, pf->flags);
0504 dev_info(ice_pf_to_dev(pf), "GNSS TTY init successful\n");
0505 }
0506
0507
0508
0509
0510
0511 void ice_gnss_exit(struct ice_pf *pf)
0512 {
0513 unsigned int i;
0514
0515 if (!test_bit(ICE_FLAG_GNSS, pf->flags) || !pf->ice_gnss_tty_driver)
0516 return;
0517
0518 for (i = 0; i < ICE_GNSS_TTY_MINOR_DEVICES; i++) {
0519 if (pf->gnss_tty_port[i]) {
0520 tty_port_destroy(pf->gnss_tty_port[i]);
0521 kfree(pf->gnss_tty_port[i]);
0522 }
0523
0524 if (pf->gnss_serial[i]) {
0525 struct gnss_serial *gnss = pf->gnss_serial[i];
0526
0527 kthread_cancel_work_sync(&gnss->write_work);
0528 kthread_cancel_delayed_work_sync(&gnss->read_work);
0529 kfree(gnss);
0530 pf->gnss_serial[i] = NULL;
0531 }
0532 }
0533
0534 tty_unregister_driver(pf->ice_gnss_tty_driver);
0535 kfree(pf->ice_gnss_tty_driver->name);
0536 tty_driver_kref_put(pf->ice_gnss_tty_driver);
0537 pf->ice_gnss_tty_driver = NULL;
0538 }
0539
0540
0541
0542
0543
0544 bool ice_gnss_is_gps_present(struct ice_hw *hw)
0545 {
0546 if (!hw->func_caps.ts_func_info.src_tmr_owned)
0547 return false;
0548
0549 #if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
0550 if (ice_is_e810t(hw)) {
0551 int err;
0552 u8 data;
0553
0554 err = ice_read_pca9575_reg_e810t(hw, ICE_PCA9575_P0_IN, &data);
0555 if (err || !!(data & ICE_E810T_P0_GNSS_PRSNT_N))
0556 return false;
0557 } else {
0558 return false;
0559 }
0560 #else
0561 if (!ice_is_e810t(hw))
0562 return false;
0563 #endif
0564
0565 return true;
0566 }