@@ -4919,6 +4919,37 @@ static const struct net_device_ops mtk_netdev_ops = {
49194919 .ndo_select_queue = mtk_select_queue ,
49204920};
49214921
4922+ static struct phylink * mtk_mux_create_phylink (struct mtk_mux * mux , unsigned int channel )
4923+ {
4924+ struct mtk_mux_data * data = mux -> data [channel ];
4925+ struct mtk_mac * mac = mux -> mac ;
4926+ struct mtk_eth * eth = mac -> hw ;
4927+ phy_interface_t phy_mode ;
4928+ struct phylink * pl ;
4929+ int err ;
4930+
4931+ if (!data || !data -> of_node )
4932+ return ERR_PTR (- EINVAL );
4933+
4934+ err = of_get_phy_mode (data -> of_node , & phy_mode );
4935+ if (err ) {
4936+ dev_err (eth -> dev , "invalid phy-mode for mux channel %u\n" , channel );
4937+ return ERR_PTR (err );
4938+ }
4939+
4940+ pl = phylink_create (& mac -> phylink_config ,
4941+ of_fwnode_handle (data -> of_node ),
4942+ phy_mode , & mtk_phylink_ops );
4943+ if (IS_ERR (pl )) {
4944+ dev_err (eth -> dev , "failed to create phylink for channel %u\n" , channel );
4945+ return pl ;
4946+ }
4947+
4948+ dev_info (eth -> dev , "Created phylink for channel %u\n" , channel );
4949+ data -> phylink = pl ;
4950+ return pl ;
4951+ }
4952+
49224953static void mux_poll (struct work_struct * work )
49234954{
49244955 struct mtk_mux * mux = container_of (work , struct mtk_mux , poll .work );
@@ -4928,6 +4959,7 @@ static void mux_poll(struct work_struct *work)
49284959 unsigned int new_channel ;
49294960 int sfp_present ;
49304961
4962+ //dev_info(eth->dev, "ethernet mux: %s:%d\n",__func__,__LINE__);
49314963 if (IS_ERR (mux -> mod_def0_gpio ) || IS_ERR (mux -> chan_sel_gpio ))
49324964 goto reschedule ;
49334965
@@ -4937,23 +4969,51 @@ static void mux_poll(struct work_struct *work)
49374969 if (mux -> channel == new_channel || !netif_running (dev ))
49384970 goto reschedule ;
49394971
4940- rtnl_lock ( );
4972+ dev_info ( eth -> dev , "ethernet mux: line:%d new channel:%d,sfp:%d\n" , __LINE__ , new_channel , sfp_present );
49414973
4974+ rtnl_lock ();
49424975 mtk_stop (dev );
49434976
4944- mac -> of_node = mux -> data [new_channel ]-> of_node ;
4945- mac -> phylink = mux -> data [new_channel ]-> phylink ;
4977+ /* Destroy old phylink if it exists */
4978+ if (mux -> data [mux -> channel ] && mux -> data [mux -> channel ]-> phylink ) {
4979+ dev_info (eth -> dev , "Destroying phylink for channel %u\n" , mux -> channel );
4980+ phylink_destroy (mux -> data [mux -> channel ]-> phylink );
4981+ phylink_stop (mux -> data [mux -> channel ]-> phylink );
4982+ phylink_disconnect_phy (mux -> data [mux -> channel ]-> phylink );
4983+ phylink_destroy (mux -> data [mux -> channel ]-> phylink );
4984+ mux -> data [mux -> channel ]-> phylink = NULL ;
4985+ }
4986+ rtnl_unlock ();
49464987
49474988 dev_info (eth -> dev , "ethernet mux: switch to channel%d\n" , new_channel );
49484989
49494990 gpiod_set_value_cansleep (mux -> chan_sel_gpio , new_channel );
49504991
4992+ usleep_range (100000 ,200000 );
4993+
4994+ /* Create new phylink if not yet present */
4995+ if (!mux -> data [new_channel ]-> phylink ) {
4996+ mux -> data [new_channel ]-> phylink = mtk_mux_create_phylink (mux , new_channel );
4997+ if (IS_ERR (mux -> data [new_channel ]-> phylink )) {
4998+ dev_err (eth -> dev , "Failed to create new phylink\n" );
4999+ mux -> data [new_channel ]-> phylink = NULL ;
5000+ goto out_unlock ;
5001+ }
5002+ }
5003+
5004+ mac -> of_node = mux -> data [new_channel ]-> of_node ;
5005+ mac -> phylink = mux -> data [new_channel ]-> phylink ;
5006+
5007+ rtnl_lock ();
49515008 mtk_open (dev );
49525009
49535010 rtnl_unlock ();
49545011
49555012 mux -> channel = new_channel ;
5013+ goto reschedule ;
49565014
5015+ out_unlock :
5016+ rtnl_unlock ();
49575017reschedule :
49585018 mod_delayed_work (system_wq , & mux -> poll , msecs_to_jiffies (100 ));
49595019}
@@ -4991,17 +5051,18 @@ static int mtk_add_mux_channel(struct mtk_mux *mux, struct device_node *np)
49915051 goto err_free_data ;
49925052 }
49935053
4994- phylink = phylink_create (& mux -> mac -> phylink_config ,
5054+ /* phylink = phylink_create(&mux->mac->phylink_config,
49955055 of_fwnode_handle(np),
49965056 phy_mode, &mtk_phylink_ops);
49975057 if (IS_ERR(phylink)) {
49985058 dev_err(eth->dev, "failed to create phylink structure\n");
49995059 err = PTR_ERR(phylink);
50005060 goto err_free_data;
5001- }
5061+ }*/
50025062
5063+ dev_info (eth -> dev , "ethernet mux: line:%d added new channel:%d\n" ,__LINE__ ,id );
50035064 data -> of_node = np ;
5004- data -> phylink = phylink ;
5065+ data -> phylink = NULL ; // phylink;
50055066 mux -> data [id ] = data ;
50065067
50075068 return 0 ;
@@ -5072,7 +5133,7 @@ static int mtk_add_mux(struct mtk_eth *eth, struct device_node *np)
50725133
50735134 eth -> mux [id ] = mux ;
50745135 mux -> mac = eth -> mac [id ];
5075- mux -> channel = 0 ;
5136+ mux -> channel = 0 ;//more than channels, just to make current channel invalid for switching the first time the gpio is read
50765137
50775138 mux -> mod_def0_gpio = fwnode_gpiod_get_index (of_fwnode_handle (np ),
50785139 "mod-def0" , 0 , GPIOD_IN |
@@ -5103,8 +5164,12 @@ static int mtk_add_mux(struct mtk_eth *eth, struct device_node *np)
51035164 of_node_put (child );
51045165 goto err_put_chan_sel ;
51055166 }
5167+ //should set initial mux->channel be set if ! mux->sfp_present_channel?
51065168 }
51075169
5170+ gpiod_set_value_cansleep (mux -> chan_sel_gpio , mux -> sfp_present_channel ? 0 : 1 );
5171+
5172+ dev_info (eth -> dev , "ethernet mux: line:%d added new mux\n" ,__LINE__ );
51085173 INIT_DELAYED_WORK (& mux -> poll , mux_poll );
51095174 mod_delayed_work (system_wq , & mux -> poll , msecs_to_jiffies (3000 ));
51105175
0 commit comments