@@ -367,6 +367,15 @@ struct r8152 {
367367 spinlock_t rx_lock , tx_lock ;
368368 struct delayed_work schedule ;
369369 struct mii_if_info mii ;
370+
371+ struct rtl_ops {
372+ void (* init )(struct r8152 * );
373+ int (* enable )(struct r8152 * );
374+ void (* disable )(struct r8152 * );
375+ void (* down )(struct r8152 * );
376+ void (* unload )(struct r8152 * );
377+ } rtl_ops ;
378+
370379 int intr_interval ;
371380 u32 msg_enable ;
372381 u32 tx_qlen ;
@@ -1751,15 +1760,15 @@ static void set_carrier(struct r8152 *tp)
17511760
17521761 if (speed & LINK_STATUS ) {
17531762 if (!(tp -> speed & LINK_STATUS )) {
1754- rtl8152_enable (tp );
1763+ tp -> rtl_ops . enable (tp );
17551764 set_bit (RTL8152_SET_RX_MODE , & tp -> flags );
17561765 netif_carrier_on (netdev );
17571766 }
17581767 } else {
17591768 if (tp -> speed & LINK_STATUS ) {
17601769 netif_carrier_off (netdev );
17611770 tasklet_disable (& tp -> tl );
1762- rtl8152_disable (tp );
1771+ tp -> rtl_ops . disable (tp );
17631772 tasklet_enable (& tp -> tl );
17641773 }
17651774 }
@@ -1819,7 +1828,7 @@ static int rtl8152_close(struct net_device *netdev)
18191828 cancel_delayed_work_sync (& tp -> schedule );
18201829 netif_stop_queue (netdev );
18211830 tasklet_disable (& tp -> tl );
1822- rtl8152_disable (tp );
1831+ tp -> rtl_ops . disable (tp );
18231832 tasklet_enable (& tp -> tl );
18241833
18251834 return res ;
@@ -1945,7 +1954,7 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
19451954 tasklet_disable (& tp -> tl );
19461955 }
19471956
1948- rtl8152_down (tp );
1957+ tp -> rtl_ops . down (tp );
19491958
19501959 return 0 ;
19511960}
@@ -1954,7 +1963,7 @@ static int rtl8152_resume(struct usb_interface *intf)
19541963{
19551964 struct r8152 * tp = usb_get_intfdata (intf );
19561965
1957- r8152b_init (tp );
1966+ tp -> rtl_ops . init (tp );
19581967 netif_device_attach (tp -> netdev );
19591968 if (netif_running (tp -> netdev )) {
19601969 rtl8152_set_speed (tp , AUTONEG_ENABLE , SPEED_100 , DUPLEX_FULL );
@@ -2083,6 +2092,35 @@ static void rtl8152_unload(struct r8152 *tp)
20832092 ocp_write_word (tp , MCU_TYPE_USB , USB_PM_CTRL_STATUS , ocp_data );
20842093}
20852094
2095+ static bool rtl_ops_init (struct r8152 * tp , const struct usb_device_id * id )
2096+ {
2097+ struct rtl_ops * ops = & tp -> rtl_ops ;
2098+ bool ret = true;
2099+
2100+ switch (id -> idVendor ) {
2101+ case VENDOR_ID_REALTEK :
2102+ switch (id -> idProduct ) {
2103+ case PRODUCT_ID_RTL8152 :
2104+ ops -> init = r8152b_init ;
2105+ ops -> enable = rtl8152_enable ;
2106+ ops -> disable = rtl8152_disable ;
2107+ ops -> down = rtl8152_down ;
2108+ ops -> unload = rtl8152_unload ;
2109+ break ;
2110+ default :
2111+ ret = false;
2112+ break ;
2113+ }
2114+ break ;
2115+
2116+ default :
2117+ ret = false;
2118+ break ;
2119+ }
2120+
2121+ return ret ;
2122+ }
2123+
20862124static int rtl8152_probe (struct usb_interface * intf ,
20872125 const struct usb_device_id * id )
20882126{
@@ -2106,6 +2144,11 @@ static int rtl8152_probe(struct usb_interface *intf,
21062144 tp = netdev_priv (netdev );
21072145 tp -> msg_enable = 0x7FFF ;
21082146
2147+ if (!rtl_ops_init (tp , id )) {
2148+ netif_err (tp , probe , netdev , "Unknown Device" );
2149+ return - ENODEV ;
2150+ }
2151+
21092152 tasklet_init (& tp -> tl , bottom_half , (unsigned long )tp );
21102153 INIT_DELAYED_WORK (& tp -> schedule , rtl_work_func_t );
21112154
@@ -2128,7 +2171,7 @@ static int rtl8152_probe(struct usb_interface *intf,
21282171 tp -> mii .supports_gmii = 0 ;
21292172
21302173 r8152b_get_version (tp );
2131- r8152b_init (tp );
2174+ tp -> rtl_ops . init (tp );
21322175 set_ethernet_addr (tp );
21332176
21342177 ret = alloc_all_mem (tp );
@@ -2163,7 +2206,7 @@ static void rtl8152_disconnect(struct usb_interface *intf)
21632206 set_bit (RTL8152_UNPLUG , & tp -> flags );
21642207 tasklet_kill (& tp -> tl );
21652208 unregister_netdev (tp -> netdev );
2166- rtl8152_unload (tp );
2209+ tp -> rtl_ops . unload (tp );
21672210 free_all_mem (tp );
21682211 free_netdev (tp -> netdev );
21692212 }
0 commit comments