Lines Matching +full:i3c +full:- +full:master

1 // SPDX-License-Identifier: GPL-2.0
4 * "DSP0233 Management Component Transport Protocol (MCTP) I3C Transport
13 #include <linux/i3c/device.h>
14 #include <linux/i3c/master.h>
27 static const int MCTP_I3C_MAXMTU = MCTP_I3C_MAXBUF - 1;
42 static const char *MCTP_I3C_OF_PROP = "mctp-controller";
73 struct i3c_device *i3c; member
82 /* I3C dynamic address */
102 struct i3c_priv_xfer xfer = { .rnw = 1, .len = mi->mrl }; in mctp_i3c_read()
103 struct net_device_stats *stats = &mi->mbus->ndev->stats; in mctp_i3c_read()
110 skb = netdev_alloc_skb(mi->mbus->ndev, in mctp_i3c_read()
111 mi->mrl + sizeof(struct mctp_i3c_internal_hdr)); in mctp_i3c_read()
113 stats->rx_dropped++; in mctp_i3c_read()
114 rc = -ENOMEM; in mctp_i3c_read()
118 skb->protocol = htons(ETH_P_MCTP); in mctp_i3c_read()
122 put_unaligned_be48(mi->pid, ihdr->source); in mctp_i3c_read()
123 put_unaligned_be48(mi->mbus->pid, ihdr->dest); in mctp_i3c_read()
126 xfer.data.in = skb_put(skb, mi->mrl); in mctp_i3c_read()
128 /* Make sure netif_rx() is read in the same order as i3c. */ in mctp_i3c_read()
129 mutex_lock(&mi->lock); in mctp_i3c_read()
130 rc = i3c_device_do_priv_xfers(mi->i3c, &xfer, 1); in mctp_i3c_read()
134 if (WARN_ON_ONCE(xfer.len > mi->mrl)) { in mctp_i3c_read()
135 /* Bad i3c bus driver */ in mctp_i3c_read()
136 rc = -EIO; in mctp_i3c_read()
140 stats->rx_length_errors++; in mctp_i3c_read()
141 rc = -EIO; in mctp_i3c_read()
146 addr = mi->addr << 1 | 1; in mctp_i3c_read()
148 pec = i2c_smbus_pec(pec, xfer.data.in, xfer.len - 1); in mctp_i3c_read()
149 if (pec != ((u8 *)xfer.data.in)[xfer.len - 1]) { in mctp_i3c_read()
150 stats->rx_crc_errors++; in mctp_i3c_read()
151 rc = -EINVAL; in mctp_i3c_read()
156 skb_trim(skb, xfer.len - 1); in mctp_i3c_read()
159 cb->halen = PID_SIZE; in mctp_i3c_read()
160 put_unaligned_be48(mi->pid, cb->haddr); in mctp_i3c_read()
165 stats->rx_packets++; in mctp_i3c_read()
166 stats->rx_bytes += xfer.len - 1; in mctp_i3c_read()
168 stats->rx_dropped++; in mctp_i3c_read()
171 mutex_unlock(&mi->lock); in mctp_i3c_read()
174 mutex_unlock(&mi->lock); in mctp_i3c_read()
179 static void mctp_i3c_ibi_handler(struct i3c_device *i3c, in mctp_i3c_ibi_handler() argument
182 struct mctp_i3c_device *mi = i3cdev_get_drvdata(i3c); in mctp_i3c_ibi_handler()
187 if (mi->have_mdb) { in mctp_i3c_ibi_handler()
188 if (payload->len > 0) { in mctp_i3c_ibi_handler()
189 if (((u8 *)payload->data)[0] != I3C_MDB_MCTP) { in mctp_i3c_ibi_handler()
190 /* Not a mctp-i3c interrupt, ignore it */ in mctp_i3c_ibi_handler()
197 dev_warn_once(i3cdev_to_dev(i3c), "IBI with missing MDB"); in mctp_i3c_ibi_handler()
214 i3c_device_get_info(mi->i3c, &info); in mctp_i3c_setup()
215 mi->have_mdb = info.bcr & BIT(2); in mctp_i3c_setup()
216 mi->addr = info.dyn_addr; in mctp_i3c_setup()
217 mi->mwl = info.max_write_len; in mctp_i3c_setup()
218 mi->mrl = info.max_read_len; in mctp_i3c_setup()
219 mi->pid = info.pid; in mctp_i3c_setup()
221 rc = i3c_device_request_ibi(mi->i3c, &ibi); in mctp_i3c_setup()
222 if (rc == -ENOTSUPP) { in mctp_i3c_setup()
223 /* This driver only supports In-Band Interrupt mode. in mctp_i3c_setup()
225 * (ENOTSUPP is from the i3c layer, not EOPNOTSUPP). in mctp_i3c_setup()
227 dev_warn(i3cdev_to_dev(mi->i3c), in mctp_i3c_setup()
228 "Failed, bus driver doesn't support In-Band Interrupts"); in mctp_i3c_setup()
231 dev_err(i3cdev_to_dev(mi->i3c), in mctp_i3c_setup()
236 rc = i3c_device_enable_ibi(mi->i3c); in mctp_i3c_setup()
241 dev_err(i3cdev_to_dev(mi->i3c), "Failed enabling IBI (%d)\n", rc); in mctp_i3c_setup()
248 i3c_device_free_ibi(mi->i3c); in mctp_i3c_setup()
256 struct i3c_device *i3c) in mctp_i3c_add_device() argument
264 rc = -ENOMEM; in mctp_i3c_add_device()
267 mi->mbus = mbus; in mctp_i3c_add_device()
268 mi->i3c = i3c; in mctp_i3c_add_device()
269 mutex_init(&mi->lock); in mctp_i3c_add_device()
270 list_add(&mi->list, &mbus->devs); in mctp_i3c_add_device()
272 i3cdev_set_drvdata(i3c, mi); in mctp_i3c_add_device()
280 list_del(&mi->list); in mctp_i3c_add_device()
284 dev_warn(i3cdev_to_dev(i3c), "Error adding mctp-i3c device, %d\n", rc); in mctp_i3c_add_device()
288 static int mctp_i3c_probe(struct i3c_device *i3c) in mctp_i3c_probe() argument
295 if (b->bus == i3c->bus) { in mctp_i3c_probe()
302 /* probably no "mctp-controller" property on the i3c bus */ in mctp_i3c_probe()
303 return -ENODEV; in mctp_i3c_probe()
306 return mctp_i3c_add_device(mbus, i3c); in mctp_i3c_probe()
313 mutex_lock(&mi->lock); in mctp_i3c_remove_device()
316 i3c_device_disable_ibi(mi->i3c); in mctp_i3c_remove_device()
317 i3c_device_free_ibi(mi->i3c); in mctp_i3c_remove_device()
320 i3cdev_set_drvdata(mi->i3c, NULL); in mctp_i3c_remove_device()
321 list_del(&mi->list); in mctp_i3c_remove_device()
324 mutex_unlock(&mi->lock); in mctp_i3c_remove_device()
328 static void mctp_i3c_remove(struct i3c_device *i3c) in mctp_i3c_remove() argument
330 struct mctp_i3c_device *mi = i3cdev_get_drvdata(i3c); in mctp_i3c_remove()
343 /* Returns the device for an address, with mi->lock held */
350 list_for_each_entry(mi, &mbus->devs, list) in mctp_i3c_lookup()
351 if (mi->pid == pid) { in mctp_i3c_lookup()
353 mutex_lock(&mi->lock); in mctp_i3c_lookup()
362 struct net_device_stats *stats = &mbus->ndev->stats; in mctp_i3c_xmit()
373 data_len = skb->len; in mctp_i3c_xmit()
377 pid = get_unaligned_be48(ihdr->dest); in mctp_i3c_xmit()
380 /* I3C endpoint went away after the packet was enqueued? */ in mctp_i3c_xmit()
381 stats->tx_dropped++; in mctp_i3c_xmit()
388 if (data_len + 1 > (unsigned int)mi->mwl) { in mctp_i3c_xmit()
390 stats->tx_dropped++; in mctp_i3c_xmit()
398 data = skb->data; in mctp_i3c_xmit()
401 skb_copy_bits(skb, 0, mbus->tx_scratch, skb->len); in mctp_i3c_xmit()
402 data = mbus->tx_scratch; in mctp_i3c_xmit()
406 addr = mi->addr << 1; in mctp_i3c_xmit()
412 rc = i3c_device_do_priv_xfers(mi->i3c, &xfer, 1); in mctp_i3c_xmit()
414 stats->tx_bytes += data_len; in mctp_i3c_xmit()
415 stats->tx_packets++; in mctp_i3c_xmit()
417 stats->tx_errors++; in mctp_i3c_xmit()
422 mutex_unlock(&mi->lock); in mctp_i3c_xmit()
434 spin_lock_bh(&mbus->tx_lock); in mctp_i3c_tx_thread()
435 skb = mbus->tx_skb; in mctp_i3c_tx_thread()
436 mbus->tx_skb = NULL; in mctp_i3c_tx_thread()
437 spin_unlock_bh(&mbus->tx_lock); in mctp_i3c_tx_thread()
439 if (netif_queue_stopped(mbus->ndev)) in mctp_i3c_tx_thread()
440 netif_wake_queue(mbus->ndev); in mctp_i3c_tx_thread()
446 wait_event_idle(mbus->tx_wq, in mctp_i3c_tx_thread()
447 mbus->tx_skb || kthread_should_stop()); in mctp_i3c_tx_thread()
460 spin_lock(&mbus->tx_lock); in mctp_i3c_start_xmit()
462 if (mbus->tx_skb) { in mctp_i3c_start_xmit()
463 dev_warn_ratelimited(&ndev->dev, "TX with queue stopped"); in mctp_i3c_start_xmit()
466 mbus->tx_skb = skb; in mctp_i3c_start_xmit()
469 spin_unlock(&mbus->tx_lock); in mctp_i3c_start_xmit()
472 wake_up(&mbus->tx_wq); in mctp_i3c_start_xmit()
482 if (mbus->tx_thread) { in mctp_i3c_bus_free()
483 kthread_stop(mbus->tx_thread); in mctp_i3c_bus_free()
484 mbus->tx_thread = NULL; in mctp_i3c_bus_free()
488 list_for_each_entry_safe(mi, tmp, &mbus->devs, list) { in mctp_i3c_bus_free()
492 kfree_skb(mbus->tx_skb); in mctp_i3c_bus_free()
493 list_del(&mbus->list); in mctp_i3c_bus_free()
512 return -EINVAL; in mctp_i3c_header_create()
521 memcpy(ihdr->dest, daddr, PID_SIZE); in mctp_i3c_header_create()
522 memcpy(ihdr->source, saddr, PID_SIZE); in mctp_i3c_header_create()
537 dev->type = ARPHRD_MCTP; in mctp_i3c_net_setup()
539 dev->mtu = MCTP_I3C_MAXMTU; in mctp_i3c_net_setup()
540 dev->min_mtu = MCTP_I3C_MINMTU; in mctp_i3c_net_setup()
541 dev->max_mtu = MCTP_I3C_MAXMTU; in mctp_i3c_net_setup()
542 dev->tx_queue_len = MCTP_I3C_TX_QUEUE_LEN; in mctp_i3c_net_setup()
544 dev->hard_header_len = sizeof(struct mctp_i3c_internal_hdr); in mctp_i3c_net_setup()
545 dev->addr_len = PID_SIZE; in mctp_i3c_net_setup()
547 dev->netdev_ops = &mctp_i3c_ops; in mctp_i3c_net_setup()
548 dev->header_ops = &mctp_i3c_headops; in mctp_i3c_net_setup()
553 struct i3c_dev_desc *master = bus->cur_master; in mctp_i3c_is_mctp_controller() local
555 if (!master) in mctp_i3c_is_mctp_controller()
558 return of_property_read_bool(master->common.master->dev.of_node, in mctp_i3c_is_mctp_controller()
562 /* Returns the Provisioned Id of a local bus master */
565 struct i3c_dev_desc *master; in mctp_i3c_bus_local_pid() local
567 master = bus->cur_master; in mctp_i3c_bus_local_pid()
568 if (WARN_ON_ONCE(!master)) in mctp_i3c_bus_local_pid()
569 return -ENOENT; in mctp_i3c_bus_local_pid()
570 *ret_pid = master->info.pid; in mctp_i3c_bus_local_pid()
586 return ERR_PTR(-ENOENT); in mctp_i3c_bus_add()
588 snprintf(namebuf, sizeof(namebuf), "mctpi3c%d", bus->id); in mctp_i3c_bus_add()
592 rc = -ENOMEM; in mctp_i3c_bus_add()
597 mbus->ndev = ndev; in mctp_i3c_bus_add()
598 mbus->bus = bus; in mctp_i3c_bus_add()
599 INIT_LIST_HEAD(&mbus->devs); in mctp_i3c_bus_add()
600 list_add(&mbus->list, &busdevs); in mctp_i3c_bus_add()
602 rc = mctp_i3c_bus_local_pid(bus, &mbus->pid); in mctp_i3c_bus_add()
604 dev_err(&ndev->dev, "No I3C PID available\n"); in mctp_i3c_bus_add()
607 put_unaligned_be48(mbus->pid, addr); in mctp_i3c_bus_add()
610 init_waitqueue_head(&mbus->tx_wq); in mctp_i3c_bus_add()
611 spin_lock_init(&mbus->tx_lock); in mctp_i3c_bus_add()
612 mbus->tx_thread = kthread_run(mctp_i3c_tx_thread, mbus, in mctp_i3c_bus_add()
613 "%s/tx", ndev->name); in mctp_i3c_bus_add()
614 if (IS_ERR(mbus->tx_thread)) { in mctp_i3c_bus_add()
615 dev_warn(&ndev->dev, "Error creating thread: %pe\n", in mctp_i3c_bus_add()
616 mbus->tx_thread); in mctp_i3c_bus_add()
617 rc = PTR_ERR(mbus->tx_thread); in mctp_i3c_bus_add()
618 mbus->tx_thread = NULL; in mctp_i3c_bus_add()
624 dev_warn(&ndev->dev, "netdev register failed: %d\n", rc); in mctp_i3c_bus_add()
645 /* Unregister calls through to ndo_uninit -> mctp_i3c_bus_free() */ in mctp_i3c_bus_remove()
646 mctp_unregister_netdev(mbus->ndev); in mctp_i3c_bus_remove()
648 free_netdev(mbus->ndev); in mctp_i3c_bus_remove()
652 /* Removes all mctp-i3c busses */
674 if (mbus->bus == bus) in mctp_i3c_bus_add_new()
692 if (mbus->bus == bus) in mctp_i3c_notify_bus_remove()
722 .name = "mctp-i3c",
756 pr_warn("MCTP I3C could not unregister notifier, %d\n", rc); in mctp_i3c_mod_exit()
764 MODULE_DEVICE_TABLE(i3c, mctp_i3c_ids);
765 MODULE_DESCRIPTION("MCTP I3C device");