ncsi-manage.c (2ac5e38ea4203852d6e99edd3cf11f044b0a409f) ncsi-manage.c (16e8c4ca21a238cdf0355475bf15bd72e92feb8f)
1/*
2 * Copyright Gavin Shan, IBM Corporation 2016.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */

--- 14 unchanged lines hidden (view full) ---

23
24#include "internal.h"
25#include "ncsi-pkt.h"
26#include "ncsi-netlink.h"
27
28LIST_HEAD(ncsi_dev_list);
29DEFINE_SPINLOCK(ncsi_dev_lock);
30
1/*
2 * Copyright Gavin Shan, IBM Corporation 2016.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */

--- 14 unchanged lines hidden (view full) ---

23
24#include "internal.h"
25#include "ncsi-pkt.h"
26#include "ncsi-netlink.h"
27
28LIST_HEAD(ncsi_dev_list);
29DEFINE_SPINLOCK(ncsi_dev_lock);
30
31bool ncsi_channel_has_link(struct ncsi_channel *channel)
32{
33 return !!(channel->modes[NCSI_MODE_LINK].data[2] & 0x1);
34}
35
36bool ncsi_channel_is_last(struct ncsi_dev_priv *ndp,
37 struct ncsi_channel *channel)
38{
39 struct ncsi_package *np;
40 struct ncsi_channel *nc;
41
42 NCSI_FOR_EACH_PACKAGE(ndp, np)
43 NCSI_FOR_EACH_CHANNEL(np, nc) {
44 if (nc == channel)
45 continue;
46 if (nc->state == NCSI_CHANNEL_ACTIVE &&
47 ncsi_channel_has_link(nc))
48 return false;
49 }
50
51 return true;
52}
53
31static void ncsi_report_link(struct ncsi_dev_priv *ndp, bool force_down)
32{
33 struct ncsi_dev *nd = &ndp->ndev;
34 struct ncsi_package *np;
35 struct ncsi_channel *nc;
36 unsigned long flags;
37
38 nd->state = ncsi_dev_state_functional;

--- 8 unchanged lines hidden (view full) ---

47 spin_lock_irqsave(&nc->lock, flags);
48
49 if (!list_empty(&nc->link) ||
50 nc->state != NCSI_CHANNEL_ACTIVE) {
51 spin_unlock_irqrestore(&nc->lock, flags);
52 continue;
53 }
54
54static void ncsi_report_link(struct ncsi_dev_priv *ndp, bool force_down)
55{
56 struct ncsi_dev *nd = &ndp->ndev;
57 struct ncsi_package *np;
58 struct ncsi_channel *nc;
59 unsigned long flags;
60
61 nd->state = ncsi_dev_state_functional;

--- 8 unchanged lines hidden (view full) ---

70 spin_lock_irqsave(&nc->lock, flags);
71
72 if (!list_empty(&nc->link) ||
73 nc->state != NCSI_CHANNEL_ACTIVE) {
74 spin_unlock_irqrestore(&nc->lock, flags);
75 continue;
76 }
77
55 if (nc->modes[NCSI_MODE_LINK].data[2] & 0x1) {
78 if (ncsi_channel_has_link(nc)) {
56 spin_unlock_irqrestore(&nc->lock, flags);
57 nd->link_up = 1;
58 goto report;
59 }
60
61 spin_unlock_irqrestore(&nc->lock, flags);
62 }
63 }

--- 44 unchanged lines hidden (view full) ---

108 netdev_err(ndp->ndev.dev, "Error %d sending GLS\n",
109 ret);
110 break;
111 case NCSI_CHANNEL_MONITOR_WAIT ... NCSI_CHANNEL_MONITOR_WAIT_MAX:
112 break;
113 default:
114 netdev_err(ndp->ndev.dev, "NCSI Channel %d timed out!\n",
115 nc->id);
79 spin_unlock_irqrestore(&nc->lock, flags);
80 nd->link_up = 1;
81 goto report;
82 }
83
84 spin_unlock_irqrestore(&nc->lock, flags);
85 }
86 }

--- 44 unchanged lines hidden (view full) ---

131 netdev_err(ndp->ndev.dev, "Error %d sending GLS\n",
132 ret);
133 break;
134 case NCSI_CHANNEL_MONITOR_WAIT ... NCSI_CHANNEL_MONITOR_WAIT_MAX:
135 break;
136 default:
137 netdev_err(ndp->ndev.dev, "NCSI Channel %d timed out!\n",
138 nc->id);
116 if (!(ndp->flags & NCSI_DEV_HWA)) {
117 ncsi_report_link(ndp, true);
118 ndp->flags |= NCSI_DEV_RESHUFFLE;
119 }
139 ncsi_report_link(ndp, true);
140 ndp->flags |= NCSI_DEV_RESHUFFLE;
120
121 ncsi_stop_channel_monitor(nc);
122
123 ncm = &nc->modes[NCSI_MODE_LINK];
124 spin_lock_irqsave(&nc->lock, flags);
125 nc->state = NCSI_CHANNEL_INVISIBLE;
126 ncm->data[2] &= ~0x1;
127 spin_unlock_irqrestore(&nc->lock, flags);

--- 136 unchanged lines hidden (view full) ---

264 np = kzalloc(sizeof(*np), GFP_ATOMIC);
265 if (!np)
266 return NULL;
267
268 np->id = id;
269 np->ndp = ndp;
270 spin_lock_init(&np->lock);
271 INIT_LIST_HEAD(&np->channels);
141
142 ncsi_stop_channel_monitor(nc);
143
144 ncm = &nc->modes[NCSI_MODE_LINK];
145 spin_lock_irqsave(&nc->lock, flags);
146 nc->state = NCSI_CHANNEL_INVISIBLE;
147 ncm->data[2] &= ~0x1;
148 spin_unlock_irqrestore(&nc->lock, flags);

--- 136 unchanged lines hidden (view full) ---

285 np = kzalloc(sizeof(*np), GFP_ATOMIC);
286 if (!np)
287 return NULL;
288
289 np->id = id;
290 np->ndp = ndp;
291 spin_lock_init(&np->lock);
292 INIT_LIST_HEAD(&np->channels);
293 np->channel_whitelist = UINT_MAX;
272
273 spin_lock_irqsave(&ndp->lock, flags);
274 tmp = ncsi_find_package(ndp, id);
275 if (tmp) {
276 spin_unlock_irqrestore(&ndp->lock, flags);
277 kfree(np);
278 return tmp;
279 }

--- 157 unchanged lines hidden (view full) ---

437
438 /* Release the request */
439 ncsi_free_request(nr);
440}
441
442static void ncsi_suspend_channel(struct ncsi_dev_priv *ndp)
443{
444 struct ncsi_dev *nd = &ndp->ndev;
294
295 spin_lock_irqsave(&ndp->lock, flags);
296 tmp = ncsi_find_package(ndp, id);
297 if (tmp) {
298 spin_unlock_irqrestore(&ndp->lock, flags);
299 kfree(np);
300 return tmp;
301 }

--- 157 unchanged lines hidden (view full) ---

459
460 /* Release the request */
461 ncsi_free_request(nr);
462}
463
464static void ncsi_suspend_channel(struct ncsi_dev_priv *ndp)
465{
466 struct ncsi_dev *nd = &ndp->ndev;
445 struct ncsi_package *np = ndp->active_package;
446 struct ncsi_channel *nc = ndp->active_channel;
467 struct ncsi_package *np;
468 struct ncsi_channel *nc, *tmp;
447 struct ncsi_cmd_arg nca;
448 unsigned long flags;
449 int ret;
450
469 struct ncsi_cmd_arg nca;
470 unsigned long flags;
471 int ret;
472
473 np = ndp->active_package;
474 nc = ndp->active_channel;
451 nca.ndp = ndp;
452 nca.req_flags = NCSI_REQ_FLAG_EVENT_DRIVEN;
453 switch (nd->state) {
454 case ncsi_dev_state_suspend:
455 nd->state = ncsi_dev_state_suspend_select;
456 /* Fall through */
457 case ncsi_dev_state_suspend_select:
458 ndp->pending_req_num = 1;

--- 59 unchanged lines hidden (view full) ---

518 nca.channel = nc->id;
519 nca.bytes[0] = 1;
520
521 nd->state = ncsi_dev_state_suspend_deselect;
522 ret = ncsi_xmit_cmd(&nca);
523 if (ret)
524 goto error;
525
475 nca.ndp = ndp;
476 nca.req_flags = NCSI_REQ_FLAG_EVENT_DRIVEN;
477 switch (nd->state) {
478 case ncsi_dev_state_suspend:
479 nd->state = ncsi_dev_state_suspend_select;
480 /* Fall through */
481 case ncsi_dev_state_suspend_select:
482 ndp->pending_req_num = 1;

--- 59 unchanged lines hidden (view full) ---

542 nca.channel = nc->id;
543 nca.bytes[0] = 1;
544
545 nd->state = ncsi_dev_state_suspend_deselect;
546 ret = ncsi_xmit_cmd(&nca);
547 if (ret)
548 goto error;
549
550 NCSI_FOR_EACH_CHANNEL(np, tmp) {
551 /* If there is another channel active on this package
552 * do not deselect the package.
553 */
554 if (tmp != nc && tmp->state == NCSI_CHANNEL_ACTIVE) {
555 nd->state = ncsi_dev_state_suspend_done;
556 break;
557 }
558 }
526 break;
527 case ncsi_dev_state_suspend_deselect:
528 ndp->pending_req_num = 1;
529
530 nca.type = NCSI_PKT_CMD_DP;
531 nca.package = np->id;
532 nca.channel = NCSI_RESERVED_CHANNEL;
533
534 nd->state = ncsi_dev_state_suspend_done;
535 ret = ncsi_xmit_cmd(&nca);
536 if (ret)
537 goto error;
538
539 break;
540 case ncsi_dev_state_suspend_done:
541 spin_lock_irqsave(&nc->lock, flags);
542 nc->state = NCSI_CHANNEL_INACTIVE;
543 spin_unlock_irqrestore(&nc->lock, flags);
559 break;
560 case ncsi_dev_state_suspend_deselect:
561 ndp->pending_req_num = 1;
562
563 nca.type = NCSI_PKT_CMD_DP;
564 nca.package = np->id;
565 nca.channel = NCSI_RESERVED_CHANNEL;
566
567 nd->state = ncsi_dev_state_suspend_done;
568 ret = ncsi_xmit_cmd(&nca);
569 if (ret)
570 goto error;
571
572 break;
573 case ncsi_dev_state_suspend_done:
574 spin_lock_irqsave(&nc->lock, flags);
575 nc->state = NCSI_CHANNEL_INACTIVE;
576 spin_unlock_irqrestore(&nc->lock, flags);
544 ncsi_process_next_channel(ndp);
545
577 if (ndp->flags & NCSI_DEV_RESET)
578 ncsi_reset_dev(nd);
579 else
580 ncsi_process_next_channel(ndp);
546 break;
547 default:
548 netdev_warn(nd->dev, "Wrong NCSI state 0x%x in suspend\n",
549 nd->state);
550 }
551
552 return;
553error:

--- 116 unchanged lines hidden (view full) ---

670 ret = ncsi_xmit_cmd(nca);
671 if (ret)
672 netdev_err(nca->ndp->ndev.dev,
673 "NCSI: Failed to transmit cmd 0x%x during configure\n",
674 nca->type);
675 return ret;
676}
677
581 break;
582 default:
583 netdev_warn(nd->dev, "Wrong NCSI state 0x%x in suspend\n",
584 nd->state);
585 }
586
587 return;
588error:

--- 116 unchanged lines hidden (view full) ---

705 ret = ncsi_xmit_cmd(nca);
706 if (ret)
707 netdev_err(nca->ndp->ndev.dev,
708 "NCSI: Failed to transmit cmd 0x%x during configure\n",
709 nca->type);
710 return ret;
711}
712
713static int ncsi_oem_gma_handler_mlx(struct ncsi_cmd_arg *nca)
714{
715 union {
716 u8 data_u8[NCSI_OEM_MLX_CMD_GMA_LEN];
717 u32 data_u32[NCSI_OEM_MLX_CMD_GMA_LEN / sizeof(u32)];
718 } u;
719 int ret = 0;
720
721 nca->payload = NCSI_OEM_MLX_CMD_GMA_LEN;
722
723 memset(&u, 0, sizeof(u));
724 u.data_u32[0] = ntohl(NCSI_OEM_MFR_MLX_ID);
725 u.data_u8[5] = NCSI_OEM_MLX_CMD_GMA;
726 u.data_u8[6] = NCSI_OEM_MLX_CMD_GMA_PARAM;
727
728 nca->data = u.data_u8;
729
730 ret = ncsi_xmit_cmd(nca);
731 if (ret)
732 netdev_err(nca->ndp->ndev.dev,
733 "NCSI: Failed to transmit cmd 0x%x during configure\n",
734 nca->type);
735 return ret;
736}
737
678/* OEM Command handlers initialization */
679static struct ncsi_oem_gma_handler {
680 unsigned int mfr_id;
681 int (*handler)(struct ncsi_cmd_arg *nca);
682} ncsi_oem_gma_handlers[] = {
738/* OEM Command handlers initialization */
739static struct ncsi_oem_gma_handler {
740 unsigned int mfr_id;
741 int (*handler)(struct ncsi_cmd_arg *nca);
742} ncsi_oem_gma_handlers[] = {
683 { NCSI_OEM_MFR_BCM_ID, ncsi_oem_gma_handler_bcm }
743 { NCSI_OEM_MFR_BCM_ID, ncsi_oem_gma_handler_bcm },
744 { NCSI_OEM_MFR_MLX_ID, ncsi_oem_gma_handler_mlx }
684};
685
686static int ncsi_gma_handler(struct ncsi_cmd_arg *nca, unsigned int mf_id)
687{
688 struct ncsi_oem_gma_handler *nch = NULL;
689 int i;
690
691 /* This function should only be called once, return if flag set */

--- 20 unchanged lines hidden (view full) ---

712 nca->ndp->gma_flag = 1;
713
714 /* Get Mac address from NCSI device */
715 return nch->handler(nca);
716}
717
718#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */
719
745};
746
747static int ncsi_gma_handler(struct ncsi_cmd_arg *nca, unsigned int mf_id)
748{
749 struct ncsi_oem_gma_handler *nch = NULL;
750 int i;
751
752 /* This function should only be called once, return if flag set */

--- 20 unchanged lines hidden (view full) ---

773 nca->ndp->gma_flag = 1;
774
775 /* Get Mac address from NCSI device */
776 return nch->handler(nca);
777}
778
779#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */
780
781/* Determine if a given channel from the channel_queue should be used for Tx */
782static bool ncsi_channel_is_tx(struct ncsi_dev_priv *ndp,
783 struct ncsi_channel *nc)
784{
785 struct ncsi_channel_mode *ncm;
786 struct ncsi_channel *channel;
787 struct ncsi_package *np;
788
789 /* Check if any other channel has Tx enabled; a channel may have already
790 * been configured and removed from the channel queue.
791 */
792 NCSI_FOR_EACH_PACKAGE(ndp, np) {
793 if (!ndp->multi_package && np != nc->package)
794 continue;
795 NCSI_FOR_EACH_CHANNEL(np, channel) {
796 ncm = &channel->modes[NCSI_MODE_TX_ENABLE];
797 if (ncm->enable)
798 return false;
799 }
800 }
801
802 /* This channel is the preferred channel and has link */
803 list_for_each_entry_rcu(channel, &ndp->channel_queue, link) {
804 np = channel->package;
805 if (np->preferred_channel &&
806 ncsi_channel_has_link(np->preferred_channel)) {
807 return np->preferred_channel == nc;
808 }
809 }
810
811 /* This channel has link */
812 if (ncsi_channel_has_link(nc))
813 return true;
814
815 list_for_each_entry_rcu(channel, &ndp->channel_queue, link)
816 if (ncsi_channel_has_link(channel))
817 return false;
818
819 /* No other channel has link; default to this one */
820 return true;
821}
822
823/* Change the active Tx channel in a multi-channel setup */
824int ncsi_update_tx_channel(struct ncsi_dev_priv *ndp,
825 struct ncsi_package *package,
826 struct ncsi_channel *disable,
827 struct ncsi_channel *enable)
828{
829 struct ncsi_cmd_arg nca;
830 struct ncsi_channel *nc;
831 struct ncsi_package *np;
832 int ret = 0;
833
834 if (!package->multi_channel && !ndp->multi_package)
835 netdev_warn(ndp->ndev.dev,
836 "NCSI: Trying to update Tx channel in single-channel mode\n");
837 nca.ndp = ndp;
838 nca.req_flags = 0;
839
840 /* Find current channel with Tx enabled */
841 NCSI_FOR_EACH_PACKAGE(ndp, np) {
842 if (disable)
843 break;
844 if (!ndp->multi_package && np != package)
845 continue;
846
847 NCSI_FOR_EACH_CHANNEL(np, nc)
848 if (nc->modes[NCSI_MODE_TX_ENABLE].enable) {
849 disable = nc;
850 break;
851 }
852 }
853
854 /* Find a suitable channel for Tx */
855 NCSI_FOR_EACH_PACKAGE(ndp, np) {
856 if (enable)
857 break;
858 if (!ndp->multi_package && np != package)
859 continue;
860 if (!(ndp->package_whitelist & (0x1 << np->id)))
861 continue;
862
863 if (np->preferred_channel &&
864 ncsi_channel_has_link(np->preferred_channel)) {
865 enable = np->preferred_channel;
866 break;
867 }
868
869 NCSI_FOR_EACH_CHANNEL(np, nc) {
870 if (!(np->channel_whitelist & 0x1 << nc->id))
871 continue;
872 if (nc->state != NCSI_CHANNEL_ACTIVE)
873 continue;
874 if (ncsi_channel_has_link(nc)) {
875 enable = nc;
876 break;
877 }
878 }
879 }
880
881 if (disable == enable)
882 return -1;
883
884 if (!enable)
885 return -1;
886
887 if (disable) {
888 nca.channel = disable->id;
889 nca.package = disable->package->id;
890 nca.type = NCSI_PKT_CMD_DCNT;
891 ret = ncsi_xmit_cmd(&nca);
892 if (ret)
893 netdev_err(ndp->ndev.dev,
894 "Error %d sending DCNT\n",
895 ret);
896 }
897
898 netdev_info(ndp->ndev.dev, "NCSI: channel %u enables Tx\n", enable->id);
899
900 nca.channel = enable->id;
901 nca.package = enable->package->id;
902 nca.type = NCSI_PKT_CMD_ECNT;
903 ret = ncsi_xmit_cmd(&nca);
904 if (ret)
905 netdev_err(ndp->ndev.dev,
906 "Error %d sending ECNT\n",
907 ret);
908
909 return ret;
910}
911
720static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
721{
912static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
913{
722 struct ncsi_dev *nd = &ndp->ndev;
723 struct net_device *dev = nd->dev;
724 struct ncsi_package *np = ndp->active_package;
725 struct ncsi_channel *nc = ndp->active_channel;
726 struct ncsi_channel *hot_nc = NULL;
914 struct ncsi_package *np = ndp->active_package;
915 struct ncsi_channel *nc = ndp->active_channel;
916 struct ncsi_channel *hot_nc = NULL;
917 struct ncsi_dev *nd = &ndp->ndev;
918 struct net_device *dev = nd->dev;
727 struct ncsi_cmd_arg nca;
728 unsigned char index;
729 unsigned long flags;
730 int ret;
731
732 nca.ndp = ndp;
733 nca.req_flags = NCSI_REQ_FLAG_EVENT_DRIVEN;
734 switch (nd->state) {

--- 105 unchanged lines hidden (view full) ---

840 for (index = 0; index < 6; index++)
841 nca.bytes[index] = dev->dev_addr[index];
842 nca.bytes[6] = 0x1;
843 nca.bytes[7] = 0x1;
844 nd->state = ncsi_dev_state_config_ebf;
845 } else if (nd->state == ncsi_dev_state_config_ebf) {
846 nca.type = NCSI_PKT_CMD_EBF;
847 nca.dwords[0] = nc->caps[NCSI_CAP_BC].cap;
919 struct ncsi_cmd_arg nca;
920 unsigned char index;
921 unsigned long flags;
922 int ret;
923
924 nca.ndp = ndp;
925 nca.req_flags = NCSI_REQ_FLAG_EVENT_DRIVEN;
926 switch (nd->state) {

--- 105 unchanged lines hidden (view full) ---

1032 for (index = 0; index < 6; index++)
1033 nca.bytes[index] = dev->dev_addr[index];
1034 nca.bytes[6] = 0x1;
1035 nca.bytes[7] = 0x1;
1036 nd->state = ncsi_dev_state_config_ebf;
1037 } else if (nd->state == ncsi_dev_state_config_ebf) {
1038 nca.type = NCSI_PKT_CMD_EBF;
1039 nca.dwords[0] = nc->caps[NCSI_CAP_BC].cap;
848 nd->state = ncsi_dev_state_config_ecnt;
1040 if (ncsi_channel_is_tx(ndp, nc))
1041 nd->state = ncsi_dev_state_config_ecnt;
1042 else
1043 nd->state = ncsi_dev_state_config_ec;
849#if IS_ENABLED(CONFIG_IPV6)
850 if (ndp->inet6_addr_num > 0 &&
851 (nc->caps[NCSI_CAP_GENERIC].cap &
852 NCSI_CAP_GENERIC_MC))
853 nd->state = ncsi_dev_state_config_egmf;
1044#if IS_ENABLED(CONFIG_IPV6)
1045 if (ndp->inet6_addr_num > 0 &&
1046 (nc->caps[NCSI_CAP_GENERIC].cap &
1047 NCSI_CAP_GENERIC_MC))
1048 nd->state = ncsi_dev_state_config_egmf;
854 else
855 nd->state = ncsi_dev_state_config_ecnt;
856 } else if (nd->state == ncsi_dev_state_config_egmf) {
857 nca.type = NCSI_PKT_CMD_EGMF;
858 nca.dwords[0] = nc->caps[NCSI_CAP_MC].cap;
1049 } else if (nd->state == ncsi_dev_state_config_egmf) {
1050 nca.type = NCSI_PKT_CMD_EGMF;
1051 nca.dwords[0] = nc->caps[NCSI_CAP_MC].cap;
859 nd->state = ncsi_dev_state_config_ecnt;
1052 if (ncsi_channel_is_tx(ndp, nc))
1053 nd->state = ncsi_dev_state_config_ecnt;
1054 else
1055 nd->state = ncsi_dev_state_config_ec;
860#endif /* CONFIG_IPV6 */
861 } else if (nd->state == ncsi_dev_state_config_ecnt) {
1056#endif /* CONFIG_IPV6 */
1057 } else if (nd->state == ncsi_dev_state_config_ecnt) {
1058 if (np->preferred_channel &&
1059 nc != np->preferred_channel)
1060 netdev_info(ndp->ndev.dev,
1061 "NCSI: Tx failed over to channel %u\n",
1062 nc->id);
862 nca.type = NCSI_PKT_CMD_ECNT;
863 nd->state = ncsi_dev_state_config_ec;
864 } else if (nd->state == ncsi_dev_state_config_ec) {
865 /* Enable AEN if it's supported */
866 nca.type = NCSI_PKT_CMD_EC;
867 nd->state = ncsi_dev_state_config_ae;
868 if (!(nc->caps[NCSI_CAP_AEN].cap & NCSI_CAP_AEN_MASK))
869 nd->state = ncsi_dev_state_config_gls;

--- 14 unchanged lines hidden (view full) ---

884 nca.type);
885 goto error;
886 }
887 break;
888 case ncsi_dev_state_config_done:
889 netdev_dbg(ndp->ndev.dev, "NCSI: channel %u config done\n",
890 nc->id);
891 spin_lock_irqsave(&nc->lock, flags);
1063 nca.type = NCSI_PKT_CMD_ECNT;
1064 nd->state = ncsi_dev_state_config_ec;
1065 } else if (nd->state == ncsi_dev_state_config_ec) {
1066 /* Enable AEN if it's supported */
1067 nca.type = NCSI_PKT_CMD_EC;
1068 nd->state = ncsi_dev_state_config_ae;
1069 if (!(nc->caps[NCSI_CAP_AEN].cap & NCSI_CAP_AEN_MASK))
1070 nd->state = ncsi_dev_state_config_gls;

--- 14 unchanged lines hidden (view full) ---

1085 nca.type);
1086 goto error;
1087 }
1088 break;
1089 case ncsi_dev_state_config_done:
1090 netdev_dbg(ndp->ndev.dev, "NCSI: channel %u config done\n",
1091 nc->id);
1092 spin_lock_irqsave(&nc->lock, flags);
1093 nc->state = NCSI_CHANNEL_ACTIVE;
1094
1095 if (ndp->flags & NCSI_DEV_RESET) {
1096 /* A reset event happened during config, start it now */
1097 nc->reconfigure_needed = false;
1098 spin_unlock_irqrestore(&nc->lock, flags);
1099 ncsi_reset_dev(nd);
1100 break;
1101 }
1102
892 if (nc->reconfigure_needed) {
893 /* This channel's configuration has been updated
894 * part-way during the config state - start the
895 * channel configuration over
896 */
897 nc->reconfigure_needed = false;
898 nc->state = NCSI_CHANNEL_INACTIVE;
899 spin_unlock_irqrestore(&nc->lock, flags);

--- 4 unchanged lines hidden (view full) ---

904
905 netdev_dbg(dev, "Dirty NCSI channel state reset\n");
906 ncsi_process_next_channel(ndp);
907 break;
908 }
909
910 if (nc->modes[NCSI_MODE_LINK].data[2] & 0x1) {
911 hot_nc = nc;
1103 if (nc->reconfigure_needed) {
1104 /* This channel's configuration has been updated
1105 * part-way during the config state - start the
1106 * channel configuration over
1107 */
1108 nc->reconfigure_needed = false;
1109 nc->state = NCSI_CHANNEL_INACTIVE;
1110 spin_unlock_irqrestore(&nc->lock, flags);

--- 4 unchanged lines hidden (view full) ---

1115
1116 netdev_dbg(dev, "Dirty NCSI channel state reset\n");
1117 ncsi_process_next_channel(ndp);
1118 break;
1119 }
1120
1121 if (nc->modes[NCSI_MODE_LINK].data[2] & 0x1) {
1122 hot_nc = nc;
912 nc->state = NCSI_CHANNEL_ACTIVE;
913 } else {
914 hot_nc = NULL;
1123 } else {
1124 hot_nc = NULL;
915 nc->state = NCSI_CHANNEL_INACTIVE;
916 netdev_dbg(ndp->ndev.dev,
917 "NCSI: channel %u link down after config\n",
918 nc->id);
919 }
920 spin_unlock_irqrestore(&nc->lock, flags);
921
922 /* Update the hot channel */
923 spin_lock_irqsave(&ndp->lock, flags);

--- 11 unchanged lines hidden (view full) ---

935 return;
936
937error:
938 ncsi_report_link(ndp, true);
939}
940
941static int ncsi_choose_active_channel(struct ncsi_dev_priv *ndp)
942{
1125 netdev_dbg(ndp->ndev.dev,
1126 "NCSI: channel %u link down after config\n",
1127 nc->id);
1128 }
1129 spin_unlock_irqrestore(&nc->lock, flags);
1130
1131 /* Update the hot channel */
1132 spin_lock_irqsave(&ndp->lock, flags);

--- 11 unchanged lines hidden (view full) ---

1144 return;
1145
1146error:
1147 ncsi_report_link(ndp, true);
1148}
1149
1150static int ncsi_choose_active_channel(struct ncsi_dev_priv *ndp)
1151{
943 struct ncsi_package *np, *force_package;
944 struct ncsi_channel *nc, *found, *hot_nc, *force_channel;
1152 struct ncsi_channel *nc, *found, *hot_nc;
945 struct ncsi_channel_mode *ncm;
1153 struct ncsi_channel_mode *ncm;
946 unsigned long flags;
1154 unsigned long flags, cflags;
1155 struct ncsi_package *np;
1156 bool with_link;
947
948 spin_lock_irqsave(&ndp->lock, flags);
949 hot_nc = ndp->hot_channel;
1157
1158 spin_lock_irqsave(&ndp->lock, flags);
1159 hot_nc = ndp->hot_channel;
950 force_channel = ndp->force_channel;
951 force_package = ndp->force_package;
952 spin_unlock_irqrestore(&ndp->lock, flags);
953
1160 spin_unlock_irqrestore(&ndp->lock, flags);
1161
954 /* Force a specific channel whether or not it has link if we have been
955 * configured to do so
1162 /* By default the search is done once an inactive channel with up
1163 * link is found, unless a preferred channel is set.
1164 * If multi_package or multi_channel are configured all channels in the
1165 * whitelist are added to the channel queue.
956 */
1166 */
957 if (force_package && force_channel) {
958 found = force_channel;
959 ncm = &found->modes[NCSI_MODE_LINK];
960 if (!(ncm->data[2] & 0x1))
961 netdev_info(ndp->ndev.dev,
962 "NCSI: Channel %u forced, but it is link down\n",
963 found->id);
964 goto out;
965 }
966
967 /* The search is done once an inactive channel with up
968 * link is found.
969 */
970 found = NULL;
1167 found = NULL;
1168 with_link = false;
971 NCSI_FOR_EACH_PACKAGE(ndp, np) {
1169 NCSI_FOR_EACH_PACKAGE(ndp, np) {
972 if (ndp->force_package && np != ndp->force_package)
1170 if (!(ndp->package_whitelist & (0x1 << np->id)))
973 continue;
974 NCSI_FOR_EACH_CHANNEL(np, nc) {
1171 continue;
1172 NCSI_FOR_EACH_CHANNEL(np, nc) {
975 spin_lock_irqsave(&nc->lock, flags);
1173 if (!(np->channel_whitelist & (0x1 << nc->id)))
1174 continue;
976
1175
1176 spin_lock_irqsave(&nc->lock, cflags);
1177
977 if (!list_empty(&nc->link) ||
978 nc->state != NCSI_CHANNEL_INACTIVE) {
1178 if (!list_empty(&nc->link) ||
1179 nc->state != NCSI_CHANNEL_INACTIVE) {
979 spin_unlock_irqrestore(&nc->lock, flags);
1180 spin_unlock_irqrestore(&nc->lock, cflags);
980 continue;
981 }
982
983 if (!found)
984 found = nc;
985
986 if (nc == hot_nc)
987 found = nc;
988
989 ncm = &nc->modes[NCSI_MODE_LINK];
990 if (ncm->data[2] & 0x1) {
1181 continue;
1182 }
1183
1184 if (!found)
1185 found = nc;
1186
1187 if (nc == hot_nc)
1188 found = nc;
1189
1190 ncm = &nc->modes[NCSI_MODE_LINK];
1191 if (ncm->data[2] & 0x1) {
991 spin_unlock_irqrestore(&nc->lock, flags);
992 found = nc;
1192 found = nc;
993 goto out;
1193 with_link = true;
994 }
995
1194 }
1195
996 spin_unlock_irqrestore(&nc->lock, flags);
1196 /* If multi_channel is enabled configure all valid
1197 * channels whether or not they currently have link
1198 * so they will have AENs enabled.
1199 */
1200 if (with_link || np->multi_channel) {
1201 spin_lock_irqsave(&ndp->lock, flags);
1202 list_add_tail_rcu(&nc->link,
1203 &ndp->channel_queue);
1204 spin_unlock_irqrestore(&ndp->lock, flags);
1205
1206 netdev_dbg(ndp->ndev.dev,
1207 "NCSI: Channel %u added to queue (link %s)\n",
1208 nc->id,
1209 ncm->data[2] & 0x1 ? "up" : "down");
1210 }
1211
1212 spin_unlock_irqrestore(&nc->lock, cflags);
1213
1214 if (with_link && !np->multi_channel)
1215 break;
997 }
1216 }
1217 if (with_link && !ndp->multi_package)
1218 break;
998 }
999
1219 }
1220
1000 if (!found) {
1221 if (list_empty(&ndp->channel_queue) && found) {
1222 netdev_info(ndp->ndev.dev,
1223 "NCSI: No channel with link found, configuring channel %u\n",
1224 found->id);
1225 spin_lock_irqsave(&ndp->lock, flags);
1226 list_add_tail_rcu(&found->link, &ndp->channel_queue);
1227 spin_unlock_irqrestore(&ndp->lock, flags);
1228 } else if (!found) {
1001 netdev_warn(ndp->ndev.dev,
1229 netdev_warn(ndp->ndev.dev,
1002 "NCSI: No channel found with link\n");
1230 "NCSI: No channel found to configure!\n");
1003 ncsi_report_link(ndp, true);
1004 return -ENODEV;
1005 }
1006
1231 ncsi_report_link(ndp, true);
1232 return -ENODEV;
1233 }
1234
1007 ncm = &found->modes[NCSI_MODE_LINK];
1008 netdev_dbg(ndp->ndev.dev,
1009 "NCSI: Channel %u added to queue (link %s)\n",
1010 found->id, ncm->data[2] & 0x1 ? "up" : "down");
1011
1012out:
1013 spin_lock_irqsave(&ndp->lock, flags);
1014 list_add_tail_rcu(&found->link, &ndp->channel_queue);
1015 spin_unlock_irqrestore(&ndp->lock, flags);
1016
1017 return ncsi_process_next_channel(ndp);
1018}
1019
1020static bool ncsi_check_hwa(struct ncsi_dev_priv *ndp)
1021{
1022 struct ncsi_package *np;
1023 struct ncsi_channel *nc;
1024 unsigned int cap;

--- 20 unchanged lines hidden (view full) ---

1045 ndp->flags |= NCSI_DEV_HWA;
1046 return true;
1047 }
1048
1049 ndp->flags &= ~NCSI_DEV_HWA;
1050 return false;
1051}
1052
1235 return ncsi_process_next_channel(ndp);
1236}
1237
1238static bool ncsi_check_hwa(struct ncsi_dev_priv *ndp)
1239{
1240 struct ncsi_package *np;
1241 struct ncsi_channel *nc;
1242 unsigned int cap;

--- 20 unchanged lines hidden (view full) ---

1263 ndp->flags |= NCSI_DEV_HWA;
1264 return true;
1265 }
1266
1267 ndp->flags &= ~NCSI_DEV_HWA;
1268 return false;
1269}
1270
1053static int ncsi_enable_hwa(struct ncsi_dev_priv *ndp)
1054{
1055 struct ncsi_package *np;
1056 struct ncsi_channel *nc;
1057 unsigned long flags;
1058
1059 /* Move all available channels to processing queue */
1060 spin_lock_irqsave(&ndp->lock, flags);
1061 NCSI_FOR_EACH_PACKAGE(ndp, np) {
1062 NCSI_FOR_EACH_CHANNEL(np, nc) {
1063 WARN_ON_ONCE(nc->state != NCSI_CHANNEL_INACTIVE ||
1064 !list_empty(&nc->link));
1065 ncsi_stop_channel_monitor(nc);
1066 list_add_tail_rcu(&nc->link, &ndp->channel_queue);
1067 }
1068 }
1069 spin_unlock_irqrestore(&ndp->lock, flags);
1070
1071 /* We can have no channels in extremely case */
1072 if (list_empty(&ndp->channel_queue)) {
1073 netdev_err(ndp->ndev.dev,
1074 "NCSI: No available channels for HWA\n");
1075 ncsi_report_link(ndp, false);
1076 return -ENOENT;
1077 }
1078
1079 return ncsi_process_next_channel(ndp);
1080}
1081
1082static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
1083{
1084 struct ncsi_dev *nd = &ndp->ndev;
1085 struct ncsi_package *np;
1086 struct ncsi_channel *nc;
1087 struct ncsi_cmd_arg nca;
1088 unsigned char index;
1089 int ret;

--- 15 unchanged lines hidden (view full) ---

1105 ret = ncsi_xmit_cmd(&nca);
1106 if (ret)
1107 goto error;
1108 }
1109
1110 nd->state = ncsi_dev_state_probe_package;
1111 break;
1112 case ncsi_dev_state_probe_package:
1271static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
1272{
1273 struct ncsi_dev *nd = &ndp->ndev;
1274 struct ncsi_package *np;
1275 struct ncsi_channel *nc;
1276 struct ncsi_cmd_arg nca;
1277 unsigned char index;
1278 int ret;

--- 15 unchanged lines hidden (view full) ---

1294 ret = ncsi_xmit_cmd(&nca);
1295 if (ret)
1296 goto error;
1297 }
1298
1299 nd->state = ncsi_dev_state_probe_package;
1300 break;
1301 case ncsi_dev_state_probe_package:
1113 ndp->pending_req_num = 16;
1302 ndp->pending_req_num = 1;
1114
1303
1115 /* Select all possible packages */
1116 nca.type = NCSI_PKT_CMD_SP;
1117 nca.bytes[0] = 1;
1304 nca.type = NCSI_PKT_CMD_SP;
1305 nca.bytes[0] = 1;
1306 nca.package = ndp->package_probe_id;
1118 nca.channel = NCSI_RESERVED_CHANNEL;
1307 nca.channel = NCSI_RESERVED_CHANNEL;
1119 for (index = 0; index < 8; index++) {
1120 nca.package = index;
1121 ret = ncsi_xmit_cmd(&nca);
1122 if (ret)
1123 goto error;
1124 }
1125
1126 /* Disable all possible packages */
1127 nca.type = NCSI_PKT_CMD_DP;
1128 for (index = 0; index < 8; index++) {
1129 nca.package = index;
1130 ret = ncsi_xmit_cmd(&nca);
1131 if (ret)
1132 goto error;
1133 }
1134
1308 ret = ncsi_xmit_cmd(&nca);
1309 if (ret)
1310 goto error;
1135 nd->state = ncsi_dev_state_probe_channel;
1136 break;
1137 case ncsi_dev_state_probe_channel:
1311 nd->state = ncsi_dev_state_probe_channel;
1312 break;
1313 case ncsi_dev_state_probe_channel:
1138 if (!ndp->active_package)
1139 ndp->active_package = list_first_or_null_rcu(
1140 &ndp->packages, struct ncsi_package, node);
1141 else if (list_is_last(&ndp->active_package->node,
1142 &ndp->packages))
1143 ndp->active_package = NULL;
1144 else
1145 ndp->active_package = list_next_entry(
1146 ndp->active_package, node);
1147
1148 /* All available packages and channels are enumerated. The
1149 * enumeration happens for once when the NCSI interface is
1150 * started. So we need continue to start the interface after
1151 * the enumeration.
1152 *
1153 * We have to choose an active channel before configuring it.
1154 * Note that we possibly don't have active channel in extreme
1155 * situation.
1156 */
1314 ndp->active_package = ncsi_find_package(ndp,
1315 ndp->package_probe_id);
1157 if (!ndp->active_package) {
1316 if (!ndp->active_package) {
1158 ndp->flags |= NCSI_DEV_PROBED;
1159 if (ncsi_check_hwa(ndp))
1160 ncsi_enable_hwa(ndp);
1161 else
1162 ncsi_choose_active_channel(ndp);
1163 return;
1317 /* No response */
1318 nd->state = ncsi_dev_state_probe_dp;
1319 schedule_work(&ndp->work);
1320 break;
1164 }
1321 }
1165
1166 /* Select the active package */
1167 ndp->pending_req_num = 1;
1168 nca.type = NCSI_PKT_CMD_SP;
1169 nca.bytes[0] = 1;
1170 nca.package = ndp->active_package->id;
1171 nca.channel = NCSI_RESERVED_CHANNEL;
1172 ret = ncsi_xmit_cmd(&nca);
1173 if (ret)
1174 goto error;
1175
1176 nd->state = ncsi_dev_state_probe_cis;
1322 nd->state = ncsi_dev_state_probe_cis;
1323 schedule_work(&ndp->work);
1177 break;
1178 case ncsi_dev_state_probe_cis:
1179 ndp->pending_req_num = NCSI_RESERVED_CHANNEL;
1180
1181 /* Clear initial state */
1182 nca.type = NCSI_PKT_CMD_CIS;
1183 nca.package = ndp->active_package->id;
1184 for (index = 0; index < NCSI_RESERVED_CHANNEL; index++) {

--- 32 unchanged lines hidden (view full) ---

1217 else if (nd->state == ncsi_dev_state_probe_gc)
1218 nd->state = ncsi_dev_state_probe_gls;
1219 else
1220 nd->state = ncsi_dev_state_probe_dp;
1221 break;
1222 case ncsi_dev_state_probe_dp:
1223 ndp->pending_req_num = 1;
1224
1324 break;
1325 case ncsi_dev_state_probe_cis:
1326 ndp->pending_req_num = NCSI_RESERVED_CHANNEL;
1327
1328 /* Clear initial state */
1329 nca.type = NCSI_PKT_CMD_CIS;
1330 nca.package = ndp->active_package->id;
1331 for (index = 0; index < NCSI_RESERVED_CHANNEL; index++) {

--- 32 unchanged lines hidden (view full) ---

1364 else if (nd->state == ncsi_dev_state_probe_gc)
1365 nd->state = ncsi_dev_state_probe_gls;
1366 else
1367 nd->state = ncsi_dev_state_probe_dp;
1368 break;
1369 case ncsi_dev_state_probe_dp:
1370 ndp->pending_req_num = 1;
1371
1225 /* Deselect the active package */
1372 /* Deselect the current package */
1226 nca.type = NCSI_PKT_CMD_DP;
1373 nca.type = NCSI_PKT_CMD_DP;
1227 nca.package = ndp->active_package->id;
1374 nca.package = ndp->package_probe_id;
1228 nca.channel = NCSI_RESERVED_CHANNEL;
1229 ret = ncsi_xmit_cmd(&nca);
1230 if (ret)
1231 goto error;
1232
1375 nca.channel = NCSI_RESERVED_CHANNEL;
1376 ret = ncsi_xmit_cmd(&nca);
1377 if (ret)
1378 goto error;
1379
1233 /* Scan channels in next package */
1234 nd->state = ncsi_dev_state_probe_channel;
1380 /* Probe next package */
1381 ndp->package_probe_id++;
1382 if (ndp->package_probe_id >= 8) {
1383 /* Probe finished */
1384 ndp->flags |= NCSI_DEV_PROBED;
1385 break;
1386 }
1387 nd->state = ncsi_dev_state_probe_package;
1388 ndp->active_package = NULL;
1235 break;
1236 default:
1237 netdev_warn(nd->dev, "Wrong NCSI state 0x%0x in enumeration\n",
1238 nd->state);
1239 }
1240
1389 break;
1390 default:
1391 netdev_warn(nd->dev, "Wrong NCSI state 0x%0x in enumeration\n",
1392 nd->state);
1393 }
1394
1395 if (ndp->flags & NCSI_DEV_PROBED) {
1396 /* Check if all packages have HWA support */
1397 ncsi_check_hwa(ndp);
1398 ncsi_choose_active_channel(ndp);
1399 }
1400
1241 return;
1242error:
1243 netdev_err(ndp->ndev.dev,
1244 "NCSI: Failed to transmit cmd 0x%x during probe\n",
1245 nca.type);
1246 ncsi_report_link(ndp, true);
1247}
1248

--- 302 unchanged lines hidden (view full) ---

1551 nd = &ndp->ndev;
1552 nd->state = ncsi_dev_state_registered;
1553 nd->dev = dev;
1554 nd->handler = handler;
1555 ndp->pending_req_num = 0;
1556 INIT_LIST_HEAD(&ndp->channel_queue);
1557 INIT_LIST_HEAD(&ndp->vlan_vids);
1558 INIT_WORK(&ndp->work, ncsi_dev_work);
1401 return;
1402error:
1403 netdev_err(ndp->ndev.dev,
1404 "NCSI: Failed to transmit cmd 0x%x during probe\n",
1405 nca.type);
1406 ncsi_report_link(ndp, true);
1407}
1408

--- 302 unchanged lines hidden (view full) ---

1711 nd = &ndp->ndev;
1712 nd->state = ncsi_dev_state_registered;
1713 nd->dev = dev;
1714 nd->handler = handler;
1715 ndp->pending_req_num = 0;
1716 INIT_LIST_HEAD(&ndp->channel_queue);
1717 INIT_LIST_HEAD(&ndp->vlan_vids);
1718 INIT_WORK(&ndp->work, ncsi_dev_work);
1719 ndp->package_whitelist = UINT_MAX;
1559
1560 /* Initialize private NCSI device */
1561 spin_lock_init(&ndp->lock);
1562 INIT_LIST_HEAD(&ndp->packages);
1563 ndp->request_id = NCSI_REQ_START_IDX;
1564 for (i = 0; i < ARRAY_SIZE(ndp->requests); i++) {
1565 ndp->requests[i].id = i;
1566 ndp->requests[i].ndp = ndp;

--- 20 unchanged lines hidden (view full) ---

1587
1588 return nd;
1589}
1590EXPORT_SYMBOL_GPL(ncsi_register_dev);
1591
1592int ncsi_start_dev(struct ncsi_dev *nd)
1593{
1594 struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd);
1720
1721 /* Initialize private NCSI device */
1722 spin_lock_init(&ndp->lock);
1723 INIT_LIST_HEAD(&ndp->packages);
1724 ndp->request_id = NCSI_REQ_START_IDX;
1725 for (i = 0; i < ARRAY_SIZE(ndp->requests); i++) {
1726 ndp->requests[i].id = i;
1727 ndp->requests[i].ndp = ndp;

--- 20 unchanged lines hidden (view full) ---

1748
1749 return nd;
1750}
1751EXPORT_SYMBOL_GPL(ncsi_register_dev);
1752
1753int ncsi_start_dev(struct ncsi_dev *nd)
1754{
1755 struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd);
1595 int ret;
1596
1597 if (nd->state != ncsi_dev_state_registered &&
1598 nd->state != ncsi_dev_state_functional)
1599 return -ENOTTY;
1600
1601 if (!(ndp->flags & NCSI_DEV_PROBED)) {
1756
1757 if (nd->state != ncsi_dev_state_registered &&
1758 nd->state != ncsi_dev_state_functional)
1759 return -ENOTTY;
1760
1761 if (!(ndp->flags & NCSI_DEV_PROBED)) {
1762 ndp->package_probe_id = 0;
1602 nd->state = ncsi_dev_state_probe;
1603 schedule_work(&ndp->work);
1604 return 0;
1605 }
1606
1763 nd->state = ncsi_dev_state_probe;
1764 schedule_work(&ndp->work);
1765 return 0;
1766 }
1767
1607 if (ndp->flags & NCSI_DEV_HWA) {
1608 netdev_info(ndp->ndev.dev, "NCSI: Enabling HWA mode\n");
1609 ret = ncsi_enable_hwa(ndp);
1610 } else {
1611 ret = ncsi_choose_active_channel(ndp);
1612 }
1613
1614 return ret;
1768 return ncsi_reset_dev(nd);
1615}
1616EXPORT_SYMBOL_GPL(ncsi_start_dev);
1617
1618void ncsi_stop_dev(struct ncsi_dev *nd)
1619{
1620 struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd);
1621 struct ncsi_package *np;
1622 struct ncsi_channel *nc;
1623 bool chained;
1624 int old_state;
1625 unsigned long flags;
1626
1769}
1770EXPORT_SYMBOL_GPL(ncsi_start_dev);
1771
1772void ncsi_stop_dev(struct ncsi_dev *nd)
1773{
1774 struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd);
1775 struct ncsi_package *np;
1776 struct ncsi_channel *nc;
1777 bool chained;
1778 int old_state;
1779 unsigned long flags;
1780
1627 /* Stop the channel monitor and reset channel's state */
1781 /* Stop the channel monitor on any active channels. Don't reset the
1782 * channel state so we know which were active when ncsi_start_dev()
1783 * is next called.
1784 */
1628 NCSI_FOR_EACH_PACKAGE(ndp, np) {
1629 NCSI_FOR_EACH_CHANNEL(np, nc) {
1630 ncsi_stop_channel_monitor(nc);
1631
1632 spin_lock_irqsave(&nc->lock, flags);
1633 chained = !list_empty(&nc->link);
1634 old_state = nc->state;
1785 NCSI_FOR_EACH_PACKAGE(ndp, np) {
1786 NCSI_FOR_EACH_CHANNEL(np, nc) {
1787 ncsi_stop_channel_monitor(nc);
1788
1789 spin_lock_irqsave(&nc->lock, flags);
1790 chained = !list_empty(&nc->link);
1791 old_state = nc->state;
1635 nc->state = NCSI_CHANNEL_INACTIVE;
1636 spin_unlock_irqrestore(&nc->lock, flags);
1637
1638 WARN_ON_ONCE(chained ||
1639 old_state == NCSI_CHANNEL_INVISIBLE);
1640 }
1641 }
1642
1643 netdev_dbg(ndp->ndev.dev, "NCSI: Stopping device\n");
1644 ncsi_report_link(ndp, true);
1645}
1646EXPORT_SYMBOL_GPL(ncsi_stop_dev);
1647
1792 spin_unlock_irqrestore(&nc->lock, flags);
1793
1794 WARN_ON_ONCE(chained ||
1795 old_state == NCSI_CHANNEL_INVISIBLE);
1796 }
1797 }
1798
1799 netdev_dbg(ndp->ndev.dev, "NCSI: Stopping device\n");
1800 ncsi_report_link(ndp, true);
1801}
1802EXPORT_SYMBOL_GPL(ncsi_stop_dev);
1803
1804int ncsi_reset_dev(struct ncsi_dev *nd)
1805{
1806 struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd);
1807 struct ncsi_channel *nc, *active, *tmp;
1808 struct ncsi_package *np;
1809 unsigned long flags;
1810
1811 spin_lock_irqsave(&ndp->lock, flags);
1812
1813 if (!(ndp->flags & NCSI_DEV_RESET)) {
1814 /* Haven't been called yet, check states */
1815 switch (nd->state & ncsi_dev_state_major) {
1816 case ncsi_dev_state_registered:
1817 case ncsi_dev_state_probe:
1818 /* Not even probed yet - do nothing */
1819 spin_unlock_irqrestore(&ndp->lock, flags);
1820 return 0;
1821 case ncsi_dev_state_suspend:
1822 case ncsi_dev_state_config:
1823 /* Wait for the channel to finish its suspend/config
1824 * operation; once it finishes it will check for
1825 * NCSI_DEV_RESET and reset the state.
1826 */
1827 ndp->flags |= NCSI_DEV_RESET;
1828 spin_unlock_irqrestore(&ndp->lock, flags);
1829 return 0;
1830 }
1831 } else {
1832 switch (nd->state) {
1833 case ncsi_dev_state_suspend_done:
1834 case ncsi_dev_state_config_done:
1835 case ncsi_dev_state_functional:
1836 /* Ok */
1837 break;
1838 default:
1839 /* Current reset operation happening */
1840 spin_unlock_irqrestore(&ndp->lock, flags);
1841 return 0;
1842 }
1843 }
1844
1845 if (!list_empty(&ndp->channel_queue)) {
1846 /* Clear any channel queue we may have interrupted */
1847 list_for_each_entry_safe(nc, tmp, &ndp->channel_queue, link)
1848 list_del_init(&nc->link);
1849 }
1850 spin_unlock_irqrestore(&ndp->lock, flags);
1851
1852 active = NULL;
1853 NCSI_FOR_EACH_PACKAGE(ndp, np) {
1854 NCSI_FOR_EACH_CHANNEL(np, nc) {
1855 spin_lock_irqsave(&nc->lock, flags);
1856
1857 if (nc->state == NCSI_CHANNEL_ACTIVE) {
1858 active = nc;
1859 nc->state = NCSI_CHANNEL_INVISIBLE;
1860 spin_unlock_irqrestore(&nc->lock, flags);
1861 ncsi_stop_channel_monitor(nc);
1862 break;
1863 }
1864
1865 spin_unlock_irqrestore(&nc->lock, flags);
1866 }
1867 if (active)
1868 break;
1869 }
1870
1871 if (!active) {
1872 /* Done */
1873 spin_lock_irqsave(&ndp->lock, flags);
1874 ndp->flags &= ~NCSI_DEV_RESET;
1875 spin_unlock_irqrestore(&ndp->lock, flags);
1876 return ncsi_choose_active_channel(ndp);
1877 }
1878
1879 spin_lock_irqsave(&ndp->lock, flags);
1880 ndp->flags |= NCSI_DEV_RESET;
1881 ndp->active_channel = active;
1882 ndp->active_package = active->package;
1883 spin_unlock_irqrestore(&ndp->lock, flags);
1884
1885 nd->state = ncsi_dev_state_suspend;
1886 schedule_work(&ndp->work);
1887 return 0;
1888}
1889
1648void ncsi_unregister_dev(struct ncsi_dev *nd)
1649{
1650 struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd);
1651 struct ncsi_package *np, *tmp;
1652 unsigned long flags;
1653
1654 dev_remove_pack(&ndp->ptype);
1655

--- 16 unchanged lines hidden ---
1890void ncsi_unregister_dev(struct ncsi_dev *nd)
1891{
1892 struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd);
1893 struct ncsi_package *np, *tmp;
1894 unsigned long flags;
1895
1896 dev_remove_pack(&ndp->ptype);
1897

--- 16 unchanged lines hidden ---