@@ -530,6 +530,48 @@ void ice_devlink_destroy_sf_dev_port(struct ice_sf_dev *sf_dev)
530530 devl_port_unregister (& sf_dev -> priv -> devlink_port );
531531}
532532
533+ /**
534+ * ice_activate_dynamic_port - Activate a dynamic port
535+ * @dyn_port: dynamic port instance to activate
536+ * @extack: extack for reporting error messages
537+ *
538+ * Activate the dynamic port based on its flavour.
539+ *
540+ * Return: zero on success or an error code on failure.
541+ */
542+ static int
543+ ice_activate_dynamic_port (struct ice_dynamic_port * dyn_port ,
544+ struct netlink_ext_ack * extack )
545+ {
546+ int err ;
547+
548+ if (dyn_port -> active )
549+ return 0 ;
550+
551+ err = ice_sf_eth_activate (dyn_port , extack );
552+ if (err )
553+ return err ;
554+
555+ dyn_port -> active = true;
556+
557+ return 0 ;
558+ }
559+
560+ /**
561+ * ice_deactivate_dynamic_port - Deactivate a dynamic port
562+ * @dyn_port: dynamic port instance to deactivate
563+ *
564+ * Undo activation of a dynamic port.
565+ */
566+ static void ice_deactivate_dynamic_port (struct ice_dynamic_port * dyn_port )
567+ {
568+ if (!dyn_port -> active )
569+ return ;
570+
571+ ice_sf_eth_deactivate (dyn_port );
572+ dyn_port -> active = false;
573+ }
574+
533575/**
534576 * ice_dealloc_dynamic_port - Deallocate and remove a dynamic port
535577 * @dyn_port: dynamic port instance to deallocate
@@ -542,6 +584,8 @@ static void ice_dealloc_dynamic_port(struct ice_dynamic_port *dyn_port)
542584 struct devlink_port * devlink_port = & dyn_port -> devlink_port ;
543585 struct ice_pf * pf = dyn_port -> pf ;
544586
587+ ice_deactivate_dynamic_port (dyn_port );
588+
545589 xa_erase (& pf -> sf_nums , devlink_port -> attrs .pci_sf .sf );
546590 ice_eswitch_detach_sf (pf , dyn_port );
547591 ice_vsi_free (dyn_port -> vsi );
@@ -629,8 +673,140 @@ ice_devlink_port_del(struct devlink *devlink, struct devlink_port *port,
629673 return 0 ;
630674}
631675
676+ /**
677+ * ice_devlink_port_fn_hw_addr_set - devlink handler for mac address set
678+ * @port: pointer to devlink port
679+ * @hw_addr: hw address to set
680+ * @hw_addr_len: hw address length
681+ * @extack: extack for reporting error messages
682+ *
683+ * Sets mac address for the port, verifies arguments and copies address
684+ * to the subfunction structure.
685+ *
686+ * Return: zero on success or an error code on failure.
687+ */
688+ static int
689+ ice_devlink_port_fn_hw_addr_set (struct devlink_port * port , const u8 * hw_addr ,
690+ int hw_addr_len ,
691+ struct netlink_ext_ack * extack )
692+ {
693+ struct ice_dynamic_port * dyn_port ;
694+
695+ dyn_port = ice_devlink_port_to_dyn (port );
696+
697+ if (dyn_port -> attached ) {
698+ NL_SET_ERR_MSG_MOD (extack ,
699+ "Ethernet address can be change only in detached state" );
700+ return - EBUSY ;
701+ }
702+
703+ if (hw_addr_len != ETH_ALEN || !is_valid_ether_addr (hw_addr )) {
704+ NL_SET_ERR_MSG_MOD (extack , "Invalid ethernet address" );
705+ return - EADDRNOTAVAIL ;
706+ }
707+
708+ ether_addr_copy (dyn_port -> hw_addr , hw_addr );
709+
710+ return 0 ;
711+ }
712+
713+ /**
714+ * ice_devlink_port_fn_hw_addr_get - devlink handler for mac address get
715+ * @port: pointer to devlink port
716+ * @hw_addr: hw address to set
717+ * @hw_addr_len: hw address length
718+ * @extack: extack for reporting error messages
719+ *
720+ * Returns mac address for the port.
721+ *
722+ * Return: zero on success or an error code on failure.
723+ */
724+ static int
725+ ice_devlink_port_fn_hw_addr_get (struct devlink_port * port , u8 * hw_addr ,
726+ int * hw_addr_len ,
727+ struct netlink_ext_ack * extack )
728+ {
729+ struct ice_dynamic_port * dyn_port ;
730+
731+ dyn_port = ice_devlink_port_to_dyn (port );
732+
733+ ether_addr_copy (hw_addr , dyn_port -> hw_addr );
734+ * hw_addr_len = ETH_ALEN ;
735+
736+ return 0 ;
737+ }
738+
739+ /**
740+ * ice_devlink_port_fn_state_set - devlink handler for port state set
741+ * @port: pointer to devlink port
742+ * @state: state to set
743+ * @extack: extack for reporting error messages
744+ *
745+ * Activates or deactivates the port.
746+ *
747+ * Return: zero on success or an error code on failure.
748+ */
749+ static int
750+ ice_devlink_port_fn_state_set (struct devlink_port * port ,
751+ enum devlink_port_fn_state state ,
752+ struct netlink_ext_ack * extack )
753+ {
754+ struct ice_dynamic_port * dyn_port ;
755+
756+ dyn_port = ice_devlink_port_to_dyn (port );
757+
758+ switch (state ) {
759+ case DEVLINK_PORT_FN_STATE_ACTIVE :
760+ return ice_activate_dynamic_port (dyn_port , extack );
761+
762+ case DEVLINK_PORT_FN_STATE_INACTIVE :
763+ ice_deactivate_dynamic_port (dyn_port );
764+ break ;
765+ }
766+
767+ return 0 ;
768+ }
769+
770+ /**
771+ * ice_devlink_port_fn_state_get - devlink handler for port state get
772+ * @port: pointer to devlink port
773+ * @state: admin configured state of the port
774+ * @opstate: current port operational state
775+ * @extack: extack for reporting error messages
776+ *
777+ * Gets port state.
778+ *
779+ * Return: zero on success or an error code on failure.
780+ */
781+ static int
782+ ice_devlink_port_fn_state_get (struct devlink_port * port ,
783+ enum devlink_port_fn_state * state ,
784+ enum devlink_port_fn_opstate * opstate ,
785+ struct netlink_ext_ack * extack )
786+ {
787+ struct ice_dynamic_port * dyn_port ;
788+
789+ dyn_port = ice_devlink_port_to_dyn (port );
790+
791+ if (dyn_port -> active )
792+ * state = DEVLINK_PORT_FN_STATE_ACTIVE ;
793+ else
794+ * state = DEVLINK_PORT_FN_STATE_INACTIVE ;
795+
796+ if (dyn_port -> attached )
797+ * opstate = DEVLINK_PORT_FN_OPSTATE_ATTACHED ;
798+ else
799+ * opstate = DEVLINK_PORT_FN_OPSTATE_DETACHED ;
800+
801+ return 0 ;
802+ }
803+
632804static const struct devlink_port_ops ice_devlink_port_sf_ops = {
633805 .port_del = ice_devlink_port_del ,
806+ .port_fn_hw_addr_get = ice_devlink_port_fn_hw_addr_get ,
807+ .port_fn_hw_addr_set = ice_devlink_port_fn_hw_addr_set ,
808+ .port_fn_state_get = ice_devlink_port_fn_state_get ,
809+ .port_fn_state_set = ice_devlink_port_fn_state_set ,
634810};
635811
636812/**
0 commit comments