Lines Matching +full:key +full:- +full:release

1 // SPDX-License-Identifier: GPL-2.0
11 * shared between all mux I2C busses underneath. For non-mux cases an I2C client
14 * mctp-i2c-controller.yml devicetree binding has further details.
23 #include <linux/i2c-mux.h>
31 #define MCTP_I2C_MAXMTU (MCTP_I2C_MAXBLOCK - 1)
41 #define MCTP_I2C_OF_PROP "mctp-controller"
118 return i2c_root_adapter(&adap->dev); in mux_root_adapter()
120 /* In non-mux config all i2c adapters are root adapters */ in mux_root_adapter()
135 if (client->flags & I2C_CLIENT_TEN) { in mctp_i2c_new_client()
136 dev_err(&client->dev, "failed, MCTP requires a 7-bit I2C address, addr=0x%x\n", in mctp_i2c_new_client()
137 client->addr); in mctp_i2c_new_client()
138 rc = -EINVAL; in mctp_i2c_new_client()
142 root = mux_root_adapter(client->adapter); in mctp_i2c_new_client()
144 dev_err(&client->dev, "failed to find root adapter\n"); in mctp_i2c_new_client()
145 rc = -ENOENT; in mctp_i2c_new_client()
148 if (root != client->adapter) { in mctp_i2c_new_client()
149 dev_err(&client->dev, in mctp_i2c_new_client()
150 "A mctp-i2c-controller client cannot be placed on an I2C mux adapter.\n" in mctp_i2c_new_client()
152 " then set mctp-controller property on adapters to attach\n"); in mctp_i2c_new_client()
153 rc = -EINVAL; in mctp_i2c_new_client()
159 rc = -ENOMEM; in mctp_i2c_new_client()
162 spin_lock_init(&mcli->sel_lock); in mctp_i2c_new_client()
163 INIT_LIST_HEAD(&mcli->devs); in mctp_i2c_new_client()
164 INIT_LIST_HEAD(&mcli->list); in mctp_i2c_new_client()
165 mcli->lladdr = client->addr & 0xff; in mctp_i2c_new_client()
166 mcli->client = client; in mctp_i2c_new_client()
169 rc = i2c_slave_register(mcli->client, mctp_i2c_slave_cb); in mctp_i2c_new_client()
171 dev_err(&client->dev, "i2c register failed %d\n", rc); in mctp_i2c_new_client()
172 mcli->client = NULL; in mctp_i2c_new_client()
180 i2c_unregister_device(mcli->client); in mctp_i2c_new_client()
191 WARN_ON(!list_empty(&mcli->devs)); in mctp_i2c_free_client()
192 WARN_ON(mcli->sel); /* sanity check, no locking */ in mctp_i2c_free_client()
194 rc = i2c_slave_unregister(mcli->client); in mctp_i2c_free_client()
197 dev_err(&mcli->client->dev, "i2c unregister failed %d\n", rc); in mctp_i2c_free_client()
208 assert_spin_locked(&mcli->sel_lock); in __mctp_i2c_device_select()
210 dev_hold(midev->ndev); in __mctp_i2c_device_select()
211 if (mcli->sel) in __mctp_i2c_device_select()
212 dev_put(mcli->sel->ndev); in __mctp_i2c_device_select()
213 mcli->sel = midev; in __mctp_i2c_device_select()
222 spin_lock_irqsave(&mcli->sel_lock, flags); in mctp_i2c_device_select()
224 spin_unlock_irqrestore(&mcli->sel_lock, flags); in mctp_i2c_device_select()
235 spin_lock_irqsave(&mcli->sel_lock, flags); in mctp_i2c_slave_cb()
236 midev = mcli->sel; in mctp_i2c_slave_cb()
238 dev_hold(midev->ndev); in mctp_i2c_slave_cb()
239 spin_unlock_irqrestore(&mcli->sel_lock, flags); in mctp_i2c_slave_cb()
246 if (midev->rx_pos < MCTP_I2C_BUFSZ) { in mctp_i2c_slave_cb()
247 midev->rx_buffer[midev->rx_pos] = *val; in mctp_i2c_slave_cb()
248 midev->rx_pos++; in mctp_i2c_slave_cb()
250 midev->ndev->stats.rx_over_errors++; in mctp_i2c_slave_cb()
256 midev->rx_buffer[0] = mcli->lladdr << 1; in mctp_i2c_slave_cb()
257 midev->rx_pos = 1; in mctp_i2c_slave_cb()
266 dev_put(midev->ndev); in mctp_i2c_slave_cb()
273 struct net_device *ndev = midev->ndev; in mctp_i2c_recv()
283 if (midev->rx_pos < MCTP_I2C_MINLEN + 1) { in mctp_i2c_recv()
284 ndev->stats.rx_length_errors++; in mctp_i2c_recv()
285 return -EINVAL; in mctp_i2c_recv()
288 recvlen = midev->rx_pos - 1; in mctp_i2c_recv()
290 hdr = (void *)midev->rx_buffer; in mctp_i2c_recv()
291 if (hdr->command != MCTP_I2C_COMMANDCODE) { in mctp_i2c_recv()
292 ndev->stats.rx_dropped++; in mctp_i2c_recv()
293 return -EINVAL; in mctp_i2c_recv()
296 if (hdr->byte_count + offsetof(struct mctp_i2c_hdr, source_slave) != recvlen) { in mctp_i2c_recv()
297 ndev->stats.rx_length_errors++; in mctp_i2c_recv()
298 return -EINVAL; in mctp_i2c_recv()
301 pec = midev->rx_buffer[midev->rx_pos - 1]; in mctp_i2c_recv()
302 calc_pec = i2c_smbus_pec(0, midev->rx_buffer, recvlen); in mctp_i2c_recv()
304 ndev->stats.rx_crc_errors++; in mctp_i2c_recv()
305 return -EINVAL; in mctp_i2c_recv()
310 ndev->stats.rx_dropped++; in mctp_i2c_recv()
311 return -ENOMEM; in mctp_i2c_recv()
314 skb->protocol = htons(ETH_P_MCTP); in mctp_i2c_recv()
315 skb_put_data(skb, midev->rx_buffer, recvlen); in mctp_i2c_recv()
321 cb->halen = 1; in mctp_i2c_recv()
322 cb->haddr[0] = hdr->source_slave >> 1; in mctp_i2c_recv()
327 spin_lock_irqsave(&midev->lock, flags); in mctp_i2c_recv()
328 if (midev->allow_rx) { in mctp_i2c_recv()
329 reinit_completion(&midev->rx_done); in mctp_i2c_recv()
330 spin_unlock_irqrestore(&midev->lock, flags); in mctp_i2c_recv()
333 complete(&midev->rx_done); in mctp_i2c_recv()
336 spin_unlock_irqrestore(&midev->lock, flags); in mctp_i2c_recv()
340 ndev->stats.rx_packets++; in mctp_i2c_recv()
341 ndev->stats.rx_bytes += recvlen; in mctp_i2c_recv()
343 ndev->stats.rx_dropped++; in mctp_i2c_recv()
359 struct mctp_sk_key *key; in mctp_i2c_get_tx_flow_state() local
367 key = flow->key; in mctp_i2c_get_tx_flow_state()
368 if (!key) in mctp_i2c_get_tx_flow_state()
371 spin_lock_irqsave(&key->lock, flags); in mctp_i2c_get_tx_flow_state()
372 /* If the key is present but invalid, we're unlikely to be able in mctp_i2c_get_tx_flow_state()
375 if (!key->valid) { in mctp_i2c_get_tx_flow_state()
378 switch (key->dev_flow_state) { in mctp_i2c_get_tx_flow_state()
380 key->dev_flow_state = MCTP_I2C_FLOW_STATE_ACTIVE; in mctp_i2c_get_tx_flow_state()
391 spin_unlock_irqrestore(&key->lock, flags); in mctp_i2c_get_tx_flow_state()
405 spin_lock_irqsave(&midev->lock, flags); in mctp_i2c_lock_nest()
406 lock = midev->i2c_lock_count == 0; in mctp_i2c_lock_nest()
407 midev->i2c_lock_count++; in mctp_i2c_lock_nest()
408 spin_unlock_irqrestore(&midev->lock, flags); in mctp_i2c_lock_nest()
411 i2c_lock_bus(midev->adapter, I2C_LOCK_SEGMENT); in mctp_i2c_lock_nest()
419 spin_lock_irqsave(&midev->lock, flags); in mctp_i2c_unlock_nest()
420 if (!WARN_ONCE(midev->i2c_lock_count == 0, "lock count underflow!")) in mctp_i2c_unlock_nest()
421 midev->i2c_lock_count--; in mctp_i2c_unlock_nest()
422 unlock = midev->i2c_lock_count == 0; in mctp_i2c_unlock_nest()
423 spin_unlock_irqrestore(&midev->lock, flags); in mctp_i2c_unlock_nest()
426 i2c_unlock_bus(midev->adapter, I2C_LOCK_SEGMENT); in mctp_i2c_unlock_nest()
435 spin_lock_irqsave(&midev->lock, flags); in mctp_i2c_unlock_reset()
436 unlock = midev->i2c_lock_count > 0; in mctp_i2c_unlock_reset()
437 midev->i2c_lock_count = 0; in mctp_i2c_unlock_reset()
438 spin_unlock_irqrestore(&midev->lock, flags); in mctp_i2c_unlock_reset()
441 i2c_unlock_bus(midev->adapter, I2C_LOCK_SEGMENT); in mctp_i2c_unlock_reset()
447 struct mctp_sk_key *key; in mctp_i2c_invalidate_tx_flow() local
450 bool release; in mctp_i2c_invalidate_tx_flow() local
456 key = flow->key; in mctp_i2c_invalidate_tx_flow()
457 if (!key) in mctp_i2c_invalidate_tx_flow()
460 spin_lock_irqsave(&key->lock, flags); in mctp_i2c_invalidate_tx_flow()
461 if (key->manual_alloc) { in mctp_i2c_invalidate_tx_flow()
462 /* we don't have control over lifetimes for manually-allocated in mctp_i2c_invalidate_tx_flow()
464 * that would use this key. in mctp_i2c_invalidate_tx_flow()
466 release = false; in mctp_i2c_invalidate_tx_flow()
468 release = key->dev_flow_state == MCTP_I2C_FLOW_STATE_ACTIVE; in mctp_i2c_invalidate_tx_flow()
469 key->dev_flow_state = MCTP_I2C_FLOW_STATE_INVALID; in mctp_i2c_invalidate_tx_flow()
471 spin_unlock_irqrestore(&key->lock, flags); in mctp_i2c_invalidate_tx_flow()
474 * the lock; release that now. in mctp_i2c_invalidate_tx_flow()
476 if (release) in mctp_i2c_invalidate_tx_flow()
482 struct net_device_stats *stats = &midev->ndev->stats; in mctp_i2c_xmit()
495 if (skb->len != hdr->byte_count + 3) { in mctp_i2c_xmit()
496 dev_warn_ratelimited(&midev->adapter->dev, in mctp_i2c_xmit()
498 hdr->byte_count + 3, skb->len); in mctp_i2c_xmit()
507 skb_copy_bits(skb, 0, midev->tx_scratch, skb->len); in mctp_i2c_xmit()
508 hdr = (void *)midev->tx_scratch; in mctp_i2c_xmit()
511 pecp = (void *)&hdr->source_slave + hdr->byte_count; in mctp_i2c_xmit()
512 *pecp = i2c_smbus_pec(0, (u8 *)hdr, hdr->byte_count + 3); in mctp_i2c_xmit()
513 msg.buf = (void *)&hdr->command; in mctp_i2c_xmit()
515 msg.len = 2 + hdr->byte_count + 1; in mctp_i2c_xmit()
516 msg.addr = hdr->dest_slave >> 1; in mctp_i2c_xmit()
522 mctp_i2c_device_select(midev->client, midev); in mctp_i2c_xmit()
523 rc = __i2c_transfer(midev->adapter, &msg, 1); in mctp_i2c_xmit()
529 * on flow release in mctp_i2c_xmit()
532 mctp_i2c_device_select(midev->client, midev); in mctp_i2c_xmit()
537 rc = __i2c_transfer(midev->adapter, &msg, 1); in mctp_i2c_xmit()
550 dev_warn_ratelimited(&midev->adapter->dev, in mctp_i2c_xmit()
552 stats->tx_errors++; in mctp_i2c_xmit()
554 stats->tx_bytes += skb->len; in mctp_i2c_xmit()
555 stats->tx_packets++; in mctp_i2c_xmit()
564 spin_lock_irqsave(&midev->lock, flags); in mctp_i2c_flow_release()
565 if (midev->release_count > midev->i2c_lock_count) { in mctp_i2c_flow_release()
566 WARN_ONCE(1, "release count overflow"); in mctp_i2c_flow_release()
567 midev->release_count = midev->i2c_lock_count; in mctp_i2c_flow_release()
570 midev->i2c_lock_count -= midev->release_count; in mctp_i2c_flow_release()
571 unlock = midev->i2c_lock_count == 0 && midev->release_count > 0; in mctp_i2c_flow_release()
572 midev->release_count = 0; in mctp_i2c_flow_release()
573 spin_unlock_irqrestore(&midev->lock, flags); in mctp_i2c_flow_release()
576 i2c_unlock_bus(midev->adapter, I2C_LOCK_SEGMENT); in mctp_i2c_flow_release()
589 return -EMSGSIZE; in mctp_i2c_header_create()
592 return -EINVAL; in mctp_i2c_header_create()
605 hdr->dest_slave = (lldst << 1) & 0xff; in mctp_i2c_header_create()
606 hdr->command = MCTP_I2C_COMMANDCODE; in mctp_i2c_header_create()
607 hdr->byte_count = len + 1; in mctp_i2c_header_create()
608 hdr->source_slave = ((llsrc << 1) & 0xff) | 0x01; in mctp_i2c_header_create()
609 mhdr->ver = 0x01; in mctp_i2c_header_create()
624 spin_lock_irqsave(&midev->tx_queue.lock, flags); in mctp_i2c_tx_thread()
625 skb = __skb_dequeue(&midev->tx_queue); in mctp_i2c_tx_thread()
626 if (netif_queue_stopped(midev->ndev)) in mctp_i2c_tx_thread()
627 netif_wake_queue(midev->ndev); in mctp_i2c_tx_thread()
628 spin_unlock_irqrestore(&midev->tx_queue.lock, flags); in mctp_i2c_tx_thread()
630 if (skb == &midev->unlock_marker) { in mctp_i2c_tx_thread()
638 wait_event_idle(midev->tx_wq, in mctp_i2c_tx_thread()
639 !skb_queue_empty(&midev->tx_queue) || in mctp_i2c_tx_thread()
653 spin_lock_irqsave(&midev->tx_queue.lock, flags); in mctp_i2c_start_xmit()
654 if (skb_queue_len(&midev->tx_queue) >= MCTP_I2C_TX_WORK_LEN) { in mctp_i2c_start_xmit()
656 spin_unlock_irqrestore(&midev->tx_queue.lock, flags); in mctp_i2c_start_xmit()
661 __skb_queue_tail(&midev->tx_queue, skb); in mctp_i2c_start_xmit()
662 if (skb_queue_len(&midev->tx_queue) == MCTP_I2C_TX_WORK_LEN) in mctp_i2c_start_xmit()
664 spin_unlock_irqrestore(&midev->tx_queue.lock, flags); in mctp_i2c_start_xmit()
666 wake_up(&midev->tx_wq); in mctp_i2c_start_xmit()
671 struct mctp_sk_key *key) in mctp_i2c_release_flow() argument
674 struct mctp_i2c_dev *midev = netdev_priv(mdev->dev); in mctp_i2c_release_flow()
678 spin_lock_irqsave(&midev->lock, flags); in mctp_i2c_release_flow()
679 /* if we have seen the flow/key previously, we need to pair the in mctp_i2c_release_flow()
680 * original lock with a release in mctp_i2c_release_flow()
682 if (key->dev_flow_state == MCTP_I2C_FLOW_STATE_ACTIVE) { in mctp_i2c_release_flow()
683 midev->release_count++; in mctp_i2c_release_flow()
686 key->dev_flow_state = MCTP_I2C_FLOW_STATE_INVALID; in mctp_i2c_release_flow()
687 spin_unlock_irqrestore(&midev->lock, flags); in mctp_i2c_release_flow()
690 /* Ensure we have a release operation queued, through the fake in mctp_i2c_release_flow()
693 spin_lock(&midev->tx_queue.lock); in mctp_i2c_release_flow()
694 if (!midev->unlock_marker.next) in mctp_i2c_release_flow()
695 __skb_queue_tail(&midev->tx_queue, in mctp_i2c_release_flow()
696 &midev->unlock_marker); in mctp_i2c_release_flow()
697 spin_unlock(&midev->tx_queue.lock); in mctp_i2c_release_flow()
698 wake_up(&midev->tx_wq); in mctp_i2c_release_flow()
718 dev->type = ARPHRD_MCTP; in mctp_i2c_net_setup()
720 dev->mtu = MCTP_I2C_MAXMTU; in mctp_i2c_net_setup()
721 dev->min_mtu = MCTP_I2C_MINMTU; in mctp_i2c_net_setup()
722 dev->max_mtu = MCTP_I2C_MAXMTU; in mctp_i2c_net_setup()
723 dev->tx_queue_len = MCTP_I2C_TX_QUEUE_LEN; in mctp_i2c_net_setup()
725 dev->hard_header_len = sizeof(struct mctp_i2c_hdr); in mctp_i2c_net_setup()
726 dev->addr_len = 1; in mctp_i2c_net_setup()
728 dev->netdev_ops = &mctp_i2c_ops; in mctp_i2c_net_setup()
729 dev->header_ops = &mctp_i2c_headops; in mctp_i2c_net_setup()
742 midev->tx_thread = kthread_create(mctp_i2c_tx_thread, midev, in mctp_i2c_midev_init()
743 "%s/tx", dev->name); in mctp_i2c_midev_init()
744 if (IS_ERR(midev->tx_thread)) in mctp_i2c_midev_init()
745 return ERR_CAST(midev->tx_thread); in mctp_i2c_midev_init()
747 midev->ndev = dev; in mctp_i2c_midev_init()
748 get_device(&adap->dev); in mctp_i2c_midev_init()
749 midev->adapter = adap; in mctp_i2c_midev_init()
750 get_device(&mcli->client->dev); in mctp_i2c_midev_init()
751 midev->client = mcli; in mctp_i2c_midev_init()
752 INIT_LIST_HEAD(&midev->list); in mctp_i2c_midev_init()
753 spin_lock_init(&midev->lock); in mctp_i2c_midev_init()
754 midev->i2c_lock_count = 0; in mctp_i2c_midev_init()
755 midev->release_count = 0; in mctp_i2c_midev_init()
756 init_completion(&midev->rx_done); in mctp_i2c_midev_init()
757 complete(&midev->rx_done); in mctp_i2c_midev_init()
758 init_waitqueue_head(&midev->tx_wq); in mctp_i2c_midev_init()
759 skb_queue_head_init(&midev->tx_queue); in mctp_i2c_midev_init()
762 spin_lock_irqsave(&mcli->sel_lock, flags); in mctp_i2c_midev_init()
763 list_add(&midev->list, &mcli->devs); in mctp_i2c_midev_init()
765 if (!mcli->sel) in mctp_i2c_midev_init()
767 spin_unlock_irqrestore(&mcli->sel_lock, flags); in mctp_i2c_midev_init()
770 wake_up_process(midev->tx_thread); in mctp_i2c_midev_init()
778 struct mctp_i2c_client *mcli = midev->client; in mctp_i2c_midev_free()
781 if (midev->tx_thread) { in mctp_i2c_midev_free()
782 kthread_stop(midev->tx_thread); in mctp_i2c_midev_free()
783 midev->tx_thread = NULL; in mctp_i2c_midev_free()
790 spin_lock_irqsave(&mcli->sel_lock, flags); in mctp_i2c_midev_free()
791 list_del(&midev->list); in mctp_i2c_midev_free()
792 if (mcli->sel == midev) { in mctp_i2c_midev_free()
795 first = list_first_entry_or_null(&mcli->devs, struct mctp_i2c_dev, list); in mctp_i2c_midev_free()
798 spin_unlock_irqrestore(&mcli->sel_lock, flags); in mctp_i2c_midev_free()
800 skb_queue_purge(&midev->tx_queue); in mctp_i2c_midev_free()
801 put_device(&midev->adapter->dev); in mctp_i2c_midev_free()
802 put_device(&mcli->client->dev); in mctp_i2c_midev_free()
811 kthread_stop(midev->tx_thread); in mctp_i2c_unregister()
812 midev->tx_thread = NULL; in mctp_i2c_unregister()
815 spin_lock_irqsave(&midev->lock, flags); in mctp_i2c_unregister()
816 midev->allow_rx = false; in mctp_i2c_unregister()
817 spin_unlock_irqrestore(&midev->lock, flags); in mctp_i2c_unregister()
818 wait_for_completion(&midev->rx_done); in mctp_i2c_unregister()
820 mctp_unregister_netdev(midev->ndev); in mctp_i2c_unregister()
823 free_netdev(midev->ndev); in mctp_i2c_unregister()
830 /* Perform cleanup here to ensure that mcli->sel isn't holding in mctp_i2c_ndo_uninit()
843 spin_lock_irqsave(&midev->lock, flags); in mctp_i2c_ndo_open()
844 midev->allow_rx = true; in mctp_i2c_ndo_open()
845 spin_unlock_irqrestore(&midev->lock, flags); in mctp_i2c_ndo_open()
861 if (root != mcli->client->adapter) { in mctp_i2c_add_netdev()
862 dev_err(&mcli->client->dev, in mctp_i2c_add_netdev()
864 mcli->client->adapter->name, root->name); in mctp_i2c_add_netdev()
865 return -EINVAL; in mctp_i2c_add_netdev()
869 snprintf(namebuf, sizeof(namebuf), "mctpi2c%d", adap->nr); in mctp_i2c_add_netdev()
872 dev_err(&mcli->client->dev, "alloc netdev failed\n"); in mctp_i2c_add_netdev()
873 rc = -ENOMEM; in mctp_i2c_add_netdev()
876 dev_net_set(ndev, current->nsproxy->net_ns); in mctp_i2c_add_netdev()
877 SET_NETDEV_DEV(ndev, &adap->dev); in mctp_i2c_add_netdev()
878 dev_addr_set(ndev, &mcli->lladdr); in mctp_i2c_add_netdev()
890 dev_err(&mcli->client->dev, in mctp_i2c_add_netdev()
892 ndev->name, rc); in mctp_i2c_add_netdev()
896 spin_lock_irqsave(&midev->lock, flags); in mctp_i2c_add_netdev()
897 midev->allow_rx = false; in mctp_i2c_add_netdev()
898 spin_unlock_irqrestore(&midev->lock, flags); in mctp_i2c_add_netdev()
917 spin_lock_irqsave(&mcli->sel_lock, flags); in mctp_i2c_remove_netdev()
919 list_for_each_entry(m, &mcli->devs, list) in mctp_i2c_remove_netdev()
920 if (m->adapter == adap) { in mctp_i2c_remove_netdev()
924 spin_unlock_irqrestore(&mcli->sel_lock, flags); in mctp_i2c_remove_netdev()
938 if (dev->type != &i2c_adapter_type) in mctp_i2c_get_adapter()
951 /* Determines whether a device is an i2c adapter with the "mctp-controller"
956 if (!adap->dev.of_node) in mctp_i2c_adapter_match()
958 return of_property_read_bool(adap->dev.of_node, MCTP_I2C_OF_PROP); in mctp_i2c_adapter_match()
962 * new mctp-i2c client is probed.
972 if (mcli->client->adapter != root) in mctp_i2c_client_try_attach()
974 /* Must either have mctp-controller property on the adapter, or in mctp_i2c_client_try_attach()
975 * be a root adapter if it's non-devicetree in mctp_i2c_client_try_attach()
992 /* Check for mctp-controller property on the adapter */ in mctp_i2c_notify_add()
999 if (m->client->adapter == root) { in mctp_i2c_notify_add()
1008 dev_warn(dev, "Failed adding mctp-i2c net device\n"); in mctp_i2c_notify_add()
1024 if (mcli->client->adapter == root) { in mctp_i2c_notify_del()
1044 list_add(&mcli->list, &driver_clients); in mctp_i2c_probe()
1047 /* Add a netdev for adapters that have a 'mctp-controller' property */ in mctp_i2c_probe()
1061 list_del(&mcli->list); in mctp_i2c_remove()
1063 list_for_each_entry_safe(midev, tmp, &mcli->devs, list) in mctp_i2c_remove()
1070 /* We look for a 'mctp-controller' property on I2C busses as they are
1094 { "mctp-i2c-interface" },
1100 { .compatible = "mctp-i2c-controller" },
1107 .name = "mctp-i2c-interface",