@@ -250,9 +250,16 @@ static int sparx5_create_port(struct sparx5 *sparx5,
250
250
struct initial_port_config * config )
251
251
{
252
252
struct sparx5_port * spx5_port ;
253
-
254
- /* netdev creation to be added in later patches */
255
- spx5_port = devm_kzalloc (sparx5 -> dev , sizeof (* spx5_port ), GFP_KERNEL );
253
+ struct net_device * ndev ;
254
+ struct phylink * phylink ;
255
+
256
+ ndev = sparx5_create_netdev (sparx5 , config -> portno );
257
+ if (IS_ERR (ndev )) {
258
+ dev_err (sparx5 -> dev , "Could not create net device: %02u\n" ,
259
+ config -> portno );
260
+ return PTR_ERR (ndev );
261
+ }
262
+ spx5_port = netdev_priv (ndev );
256
263
spx5_port -> of_node = config -> node ;
257
264
spx5_port -> serdes = config -> serdes ;
258
265
spx5_port -> pvid = NULL_VID ;
@@ -262,8 +269,28 @@ static int sparx5_create_port(struct sparx5 *sparx5,
262
269
spx5_port -> max_vlan_tags = SPX5_PORT_MAX_TAGS_NONE ;
263
270
spx5_port -> vlan_type = SPX5_VLAN_PORT_TYPE_UNAWARE ;
264
271
spx5_port -> custom_etype = 0x8880 ; /* Vitesse */
272
+ spx5_port -> phylink_pcs .poll = true;
273
+ spx5_port -> phylink_pcs .ops = & sparx5_phylink_pcs_ops ;
274
+ sparx5 -> ports [config -> portno ] = spx5_port ;
275
+
276
+ spx5_port -> conf = config -> conf ;
277
+
278
+ /* VLAN setup to be added in later patches */
279
+
280
+ /* Create a phylink for PHY management. Also handles SFPs */
281
+ spx5_port -> phylink_config .dev = & spx5_port -> ndev -> dev ;
282
+ spx5_port -> phylink_config .type = PHYLINK_NETDEV ;
283
+ spx5_port -> phylink_config .pcs_poll = true;
284
+
285
+ phylink = phylink_create (& spx5_port -> phylink_config ,
286
+ of_fwnode_handle (config -> node ),
287
+ config -> conf .phy_mode ,
288
+ & sparx5_phylink_mac_ops );
289
+ if (IS_ERR (phylink ))
290
+ return PTR_ERR (phylink );
265
291
266
- /* PHYLINK support to be added in later patches */
292
+ spx5_port -> phylink = phylink ;
293
+ phylink_set_pcs (phylink , & spx5_port -> phylink_pcs );
267
294
268
295
return 0 ;
269
296
}
@@ -525,6 +552,7 @@ static void sparx5_board_init(struct sparx5 *sparx5)
525
552
static int sparx5_start (struct sparx5 * sparx5 )
526
553
{
527
554
u32 idx ;
555
+ int err ;
528
556
529
557
/* Setup own UPSIDs */
530
558
for (idx = 0 ; idx < 3 ; idx ++ ) {
@@ -558,13 +586,34 @@ static int sparx5_start(struct sparx5 *sparx5)
558
586
/* Enable queue limitation watermarks */
559
587
sparx5_qlim_set (sparx5 );
560
588
561
- /* netdev and resource calendar support to be added in later patches */
589
+ /* Resource calendar support to be added in later patches */
590
+
591
+ err = sparx5_register_netdevs (sparx5 );
592
+ if (err )
593
+ return err ;
562
594
563
595
sparx5_board_init (sparx5 );
564
596
565
- /* Injection/Extraction config to be added in later patches */
597
+ /* Start register based INJ/XTR */
598
+ err = - ENXIO ;
599
+ if (err && sparx5 -> xtr_irq >= 0 ) {
600
+ err = devm_request_irq (sparx5 -> dev , sparx5 -> xtr_irq ,
601
+ sparx5_xtr_handler , IRQF_SHARED ,
602
+ "sparx5-xtr" , sparx5 );
603
+ if (!err )
604
+ err = sparx5_manual_injection_mode (sparx5 );
605
+ if (err )
606
+ sparx5 -> xtr_irq = - ENXIO ;
607
+ } else {
608
+ sparx5 -> xtr_irq = - ENXIO ;
609
+ }
610
+ return err ;
611
+ }
566
612
567
- return 0 ;
613
+ static void sparx5_cleanup_ports (struct sparx5 * sparx5 )
614
+ {
615
+ sparx5_unregister_netdevs (sparx5 );
616
+ sparx5_destroy_netdevs (sparx5 );
568
617
}
569
618
570
619
static int mchp_sparx5_probe (struct platform_device * pdev )
@@ -674,7 +723,8 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
674
723
ether_addr_copy (sparx5 -> base_mac , mac_addr );
675
724
}
676
725
677
- /* Inj/Xtr IRQ support to be added in later patches */
726
+ sparx5 -> xtr_irq = platform_get_irq_byname (sparx5 -> pdev , "xtr" );
727
+
678
728
/* Read chip ID to check CPU interface */
679
729
sparx5 -> chip_id = spx5_rd (sparx5 , GCB_CHIP_ID );
680
730
@@ -715,14 +765,26 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
715
765
goto cleanup_config ;
716
766
717
767
cleanup_ports :
718
- /* Port cleanup to be added in later patches */
768
+ sparx5_cleanup_ports ( sparx5 );
719
769
cleanup_config :
720
770
kfree (configs );
721
771
cleanup_pnode :
722
772
of_node_put (ports );
723
773
return err ;
724
774
}
725
775
776
+ static int mchp_sparx5_remove (struct platform_device * pdev )
777
+ {
778
+ struct sparx5 * sparx5 = platform_get_drvdata (pdev );
779
+
780
+ if (sparx5 -> xtr_irq ) {
781
+ disable_irq (sparx5 -> xtr_irq );
782
+ sparx5 -> xtr_irq = - ENXIO ;
783
+ }
784
+ sparx5_cleanup_ports (sparx5 );
785
+ return 0 ;
786
+ }
787
+
726
788
static const struct of_device_id mchp_sparx5_match [] = {
727
789
{ .compatible = "microchip,sparx5-switch" },
728
790
{ }
@@ -731,6 +793,7 @@ MODULE_DEVICE_TABLE(of, mchp_sparx5_match);
731
793
732
794
static struct platform_driver mchp_sparx5_driver = {
733
795
.probe = mchp_sparx5_probe ,
796
+ .remove = mchp_sparx5_remove ,
734
797
.driver = {
735
798
.name = "sparx5-switch" ,
736
799
.of_match_table = mchp_sparx5_match ,
0 commit comments