Changeset d101ed8 in rtems-libbsd
- Timestamp:
- 09/14/18 07:43:12 (6 years ago)
- Branches:
- 5, 5-freebsd-12, 6-freebsd-12, master
- Children:
- 1b70957
- Parents:
- 457b4fc
- git-author:
- Sebastian Huber <sebastian.huber@…> (09/14/18 07:43:12)
- git-committer:
- Sebastian Huber <sebastian.huber@…> (09/21/18 08:29:43)
- Location:
- rtemsbsd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
rtemsbsd/include/bsp/nexus-devices.h
r457b4fc rd101ed8 179 179 180 180 RTEMS_BSD_DEFINE_NEXUS_DEVICE(fec, 0, 0, NULL); 181 SYSINIT_DRIVER_REFERENCE(ukphy, miibus); 181 182 182 183 #endif -
rtemsbsd/sys/dev/ffec/if_ffec_mpc8xx.c
r457b4fc rd101ed8 77 77 #include <net/if_var.h> 78 78 79 #include <machine/bus.h> 80 81 #include <dev/mii/mii.h> 82 #include <dev/mii/miivar.h> 83 84 #include <rtems/bsd/local/miibus_if.h> 85 79 86 #include <bsp/irq.h> 80 #include <rtems/rtems_mii_ioctl.h>81 87 #include <rtems/bsd/bsd.h> 82 #include <errno.h>83 88 84 89 /* FIXME */ … … 143 148 int txBdActiveCount; 144 149 struct callout watchdogCallout; 150 device_t miibus; 151 struct mii_data *mii_softc; 145 152 m8xxBufferDescriptor_t *rxBdBase; 146 153 m8xxBufferDescriptor_t *txBdBase; … … 152 159 * MDIO/Phy info 153 160 */ 154 struct rtems_mdio_info mdio_info;155 161 int phy_default; 156 int media_state; /* (last detected) state of media */157 162 /* 158 163 * Statistics … … 178 183 }; 179 184 180 int fec_mode_adapt (struct ifnet *ifp);181 182 185 #define FEC_LOCK(sc) mtx_lock(&(sc)->mtx) 183 186 … … 202 205 } 203 206 204 /* declare ioctl function for internal use */205 static int fec_ioctl (struct ifnet *ifp,206 ioctl_command_t command, caddr_t data);207 207 /***************************************************************************\ 208 208 | MII Management access functions | … … 232 232 * set clock divider 233 233 */ 234 m8xx.fec.mii_speed = BSP_bus_frequency / 25000000 / 2 + 1; 235 } 236 237 /*=========================================================================*\ 238 | Function: | 239 \*-------------------------------------------------------------------------*/ 240 int fec_mdio_read 241 ( 242 /*-------------------------------------------------------------------------*\ 243 | Purpose: | 244 | read register of a phy | 245 +---------------------------------------------------------------------------+ 246 | Input Parameters: | 247 \*-------------------------------------------------------------------------*/ 248 int phy, /* PHY number to access or -1 */ 249 void *uarg, /* unit argument */ 250 unsigned reg, /* register address */ 251 uint32_t *pval /* ptr to read buffer */ 252 ) 253 /*-------------------------------------------------------------------------*\ 254 | Return Value: | 255 | 0, if ok, else error | 256 \*=========================================================================*/ 257 { 258 struct m8xx_fec_enet_struct *sc = uarg;/* control structure */ 234 m8xx.fec.mii_speed = BSP_bus_frequency / 1250000 / 2 + 1; 235 } 236 237 static int 238 fec_miibus_read_reg(device_t dev, int phy, int reg) 239 { 240 struct m8xx_fec_enet_struct *sc; 241 242 sc = device_get_softc(dev); 259 243 260 244 /* … … 271 255 * invalid phy number 272 256 */ 273 return EINVAL;257 return 0; 274 258 } 275 259 /* … … 284 268 M8xx_FEC_MII_DATA_PHYAD(phy) | 285 269 M8xx_FEC_MII_DATA_PHYRA(reg) | 270 M8xx_FEC_MII_DATA_TA | 286 271 M8xx_FEC_MII_DATA_WDATA(0)); 287 272 … … 296 281 * fetch read data, if available 297 282 */ 298 if (pval != NULL) { 299 *pval = M8xx_FEC_MII_DATA_RDATA(m8xx.fec.mii_data); 300 } 301 return 0; 302 } 303 304 /*=========================================================================*\ 305 | Function: | 306 \*-------------------------------------------------------------------------*/ 307 int fec_mdio_write 308 ( 309 /*-------------------------------------------------------------------------*\ 310 | Purpose: | 311 | write register of a phy | 312 +---------------------------------------------------------------------------+ 313 | Input Parameters: | 314 \*-------------------------------------------------------------------------*/ 315 int phy, /* PHY number to access or -1 */ 316 void *uarg, /* unit argument */ 317 unsigned reg, /* register address */ 318 uint32_t val /* write value */ 319 ) 320 /*-------------------------------------------------------------------------*\ 321 | Return Value: | 322 | 0, if ok, else error | 323 \*=========================================================================*/ 324 { 325 struct m8xx_fec_enet_struct *sc = uarg;/* control structure */ 283 return M8xx_FEC_MII_DATA_RDATA(m8xx.fec.mii_data); 284 } 285 286 static int 287 fec_miibus_write_reg(device_t dev, int phy, int reg, int val) 288 { 289 struct m8xx_fec_enet_struct *sc; 290 291 sc = device_get_softc(dev); 326 292 327 293 /* … … 351 317 M8xx_FEC_MII_DATA_PHYAD(phy) | 352 318 M8xx_FEC_MII_DATA_PHYRA(reg) | 319 M8xx_FEC_MII_DATA_TA | 353 320 M8xx_FEC_MII_DATA_WDATA(val)); 354 321 … … 516 483 sc->txBdHead = sc->txBdTail = 0; 517 484 sc->txBdActiveCount = 0; 485 486 /* Set pin multiplexing */ 487 m8xx.fec.ecntrl = M8xx_FEC_ECNTRL_FEC_PINMUX; 518 488 519 489 /* … … 880 850 struct m8xx_fec_enet_struct *sc = arg; 881 851 882 fec_mode_adapt(sc->ifp);852 mii_tick(sc->mii_softc); 883 853 callout_reset(&sc->watchdogCallout, FEC_WATCHDOG_TIMEOUT * hz, 884 854 fec_watchdog, sc); 885 855 } 886 856 857 static int 858 fec_media_change(struct ifnet * ifp) 859 { 860 struct m8xx_fec_enet_struct *sc; 861 struct mii_data *mii; 862 int error; 863 864 sc = ifp->if_softc; 865 mii = sc->mii_softc; 866 867 if (mii != NULL) { 868 FEC_LOCK(sc); 869 error = mii_mediachg(sc->mii_softc); 870 FEC_UNLOCK(sc); 871 } else { 872 error = ENXIO; 873 } 874 875 return (error); 876 } 877 878 static void 879 fec_media_status(struct ifnet * ifp, struct ifmediareq *ifmr) 880 { 881 struct m8xx_fec_enet_struct *sc; 882 struct mii_data *mii; 883 884 sc = ifp->if_softc; 885 mii = sc->mii_softc; 886 887 if (mii != NULL) { 888 FEC_LOCK(sc); 889 mii_pollstat(mii); 890 ifmr->ifm_active = mii->mii_media_active; 891 ifmr->ifm_status = mii->mii_media_status; 892 FEC_UNLOCK(sc); 893 } 894 } 895 887 896 static void fec_init (void *arg) 888 897 { … … 891 900 892 901 if (sc->txDaemonTid == 0) { 902 int error; 893 903 894 904 /* … … 908 918 sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, fec_rxDaemon, sc); 909 919 920 /* Attach the mii driver. */ 921 error = mii_attach(sc->dev, &sc->miibus, ifp, fec_media_change, 922 fec_media_status, BMSR_DEFCAPMASK, MII_PHY_ANY, 923 MII_OFFSET_ANY, 0); 924 if (error == 0) { 925 sc->mii_softc = device_get_softc(sc->miibus); 926 } 910 927 } 911 928 … … 918 935 m8xx.fec.r_cntrl &= ~M8xx_FEC_R_CNTRL_PROM; 919 936 920 /* 921 * init timer so the "watchdog function gets called periodically 922 */ 923 callout_reset(&sc->watchdogCallout, hz, fec_watchdog, sc); 937 if (sc->mii_softc != NULL ) { 938 /* 939 * init timer so the "watchdog function gets called periodically 940 */ 941 mii_mediachg(sc->mii_softc); 942 callout_reset(&sc->watchdogCallout, hz, fec_watchdog, sc); 943 } 924 944 925 945 /* … … 931 951 * Enable receiver and transmitter 932 952 */ 933 m8xx.fec.ecntrl = M8xx_FEC_ECNTRL_ETHER_EN | M8xx_FEC_ECNTRL_FEC_PINMUX;953 m8xx.fec.ecntrl |= M8xx_FEC_ECNTRL_ETHER_EN; 934 954 } 935 955 … … 955 975 * Shut down receiver and transmitter 956 976 */ 957 m8xx.fec.ecntrl = 0x0;977 m8xx.fec.ecntrl &= ~M8xx_FEC_ECNTRL_ETHER_EN; 958 978 } 959 979 … … 983 1003 } 984 1004 985 static int fec_ioctl (struct ifnet *ifp, 986 ioctl_command_t command, caddr_t data) 987 { 988 struct m8xx_fec_enet_struct *sc = ifp->if_softc; 989 int error = 0; 990 991 switch (command) { 992 /* 993 * access PHY via MII 994 */ 995 case SIOCGIFMEDIA: 996 case SIOCSIFMEDIA: 997 rtems_mii_ioctl (&(sc->mdio_info),sc,command,(void *)data); 998 break; 999 1005 static int fec_ioctl (struct ifnet *ifp, ioctl_command_t cmd, caddr_t data) 1006 { 1007 struct m8xx_fec_enet_struct *sc; 1008 struct ifreq *ifr; 1009 int error; 1010 struct mii_data *mii; 1011 1012 sc = ifp->if_softc; 1013 ifr = (struct ifreq *)data; 1014 1015 error = 0; 1016 switch (cmd) { 1000 1017 case SIOCSIFFLAGS: 1001 1018 FEC_LOCK(sc); … … 1012 1029 break; 1013 1030 1031 case SIOCSIFMEDIA: 1032 case SIOCGIFMEDIA: 1033 mii = sc->mii_softc; 1034 1035 if (mii != NULL) { 1036 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); 1037 } else { 1038 error = ether_ioctl(ifp, cmd, data); 1039 } 1040 1041 break; 1042 1014 1043 case SIO_RTEMS_SHOW_STATS: 1015 1044 fec_enet_stats (sc); … … 1020 1049 */ 1021 1050 default: 1022 error = ether_ioctl(ifp, c ommand, data);1051 error = ether_ioctl(ifp, cmd, data); 1023 1052 break; 1024 1053 } … … 1026 1055 } 1027 1056 1028 /*=========================================================================*\ 1029 | Function: | 1030 \*-------------------------------------------------------------------------*/ 1031 int fec_mode_adapt 1032 ( 1033 /*-------------------------------------------------------------------------*\ 1034 | Purpose: | 1035 | init the PHY and adapt FEC settings | 1036 +---------------------------------------------------------------------------+ 1037 | Input Parameters: | 1038 \*-------------------------------------------------------------------------*/ 1039 struct ifnet *ifp 1040 ) 1041 /*-------------------------------------------------------------------------*\ 1042 | Return Value: | 1043 | 0, if success | 1044 \*=========================================================================*/ 1045 { 1046 int result = 0; 1047 struct m8xx_fec_enet_struct *sc = ifp->if_softc; 1048 int media = IFM_MAKEWORD( 0, 0, 0, sc->phy_default); 1049 1050 #ifdef DEBUG 1051 printf("c"); 1052 #endif 1053 /* 1054 * fetch media status 1055 */ 1056 result = fec_ioctl(ifp,SIOCGIFMEDIA,(caddr_t)&media); 1057 if (result != 0) { 1058 return result; 1059 } 1060 #ifdef DEBUG 1061 printf("C"); 1062 #endif 1063 /* 1064 * status is unchanged? then do nothing 1065 */ 1066 if (media == sc->media_state) { 1067 return 0; 1068 } 1069 /* 1070 * otherwise: for the first call, try to negotiate mode 1071 */ 1072 if (sc->media_state == 0) { 1073 /* 1074 * set media status: set auto negotiation -> start auto-negotiation 1075 */ 1076 media = IFM_MAKEWORD(0,IFM_AUTO,0,sc->phy_default); 1077 result = fec_ioctl(ifp,SIOCSIFMEDIA,(caddr_t)&media); 1078 if (result != 0) { 1079 return result; 1080 } 1081 /* 1082 * wait for auto-negotiation to terminate 1083 */ 1084 do { 1085 media = IFM_MAKEWORD(0,0,0,sc->phy_default); 1086 result = fec_ioctl(ifp,SIOCGIFMEDIA,(caddr_t)&media); 1087 if (result != 0) { 1088 return result; 1089 } 1090 } while (IFM_NONE == IFM_SUBTYPE(media)); 1091 } 1092 1093 /* 1094 * now set HW according to media results: 1095 */ 1096 /* 1097 * if we are half duplex then switch to half duplex 1098 */ 1099 if (0 == (IFM_FDX & IFM_OPTIONS(media))) { 1100 m8xx.fec.x_cntrl &= ~M8xx_FEC_X_CNTRL_FDEN; 1101 m8xx.fec.r_cntrl |= M8xx_FEC_R_CNTRL_DRT; 1102 } 1103 else { 1104 m8xx.fec.x_cntrl |= M8xx_FEC_X_CNTRL_FDEN; 1105 m8xx.fec.r_cntrl &= ~M8xx_FEC_R_CNTRL_DRT; 1106 } 1107 /* 1108 * store current media state for future compares 1109 */ 1110 sc->media_state = media; 1111 1112 return 0; 1057 static void 1058 fec_miibus_statchg(device_t dev) 1059 { 1060 struct m8xx_fec_enet_struct *sc; 1061 struct mii_data *mii; 1062 1063 sc = device_get_softc(dev); 1064 mii = sc->mii_softc; 1065 1066 if (mii == NULL || 1067 (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { 1068 m8xx.fec.x_cntrl |= M8xx_FEC_X_CNTRL_FDEN; 1069 m8xx.fec.r_cntrl &= ~M8xx_FEC_R_CNTRL_DRT; 1070 } else { 1071 m8xx.fec.x_cntrl &= ~M8xx_FEC_X_CNTRL_FDEN; 1072 m8xx.fec.r_cntrl |= M8xx_FEC_R_CNTRL_DRT; 1073 } 1113 1074 } 1114 1075 … … 1120 1081 uint8_t hwaddr[ETHER_ADDR_LEN]; 1121 1082 1122 /*1123 * enable FEC functionality at hardware pins*1124 * PD[3-15] are FEC pins1125 */1126 m8xx.pdpar |= 0x1fff;1127 m8xx.pddir |= 0x1fff;1128 1129 1083 rtems_bsd_get_mac_address(device_get_name(dev), device_get_unit(dev), 1130 1084 hwaddr); … … 1140 1094 sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF; 1141 1095 1142 /*1143 * setup info about mdio interface1144 */1145 sc->mdio_info.mdio_r = fec_mdio_read;1146 sc->mdio_info.mdio_w = fec_mdio_write;1147 sc->mdio_info.has_gmii = 0; /* we do not support gigabit IF */1148 1096 /* 1149 1097 * assume: IF 1 -> PHY 0 … … 1191 1139 DEVMETHOD(device_attach, fec_attach), 1192 1140 1141 /* MII Interface */ 1142 DEVMETHOD(miibus_readreg, fec_miibus_read_reg), 1143 DEVMETHOD(miibus_writereg, fec_miibus_write_reg), 1144 DEVMETHOD(miibus_statchg, fec_miibus_statchg), 1145 1193 1146 DEVMETHOD_END 1194 1147 }; … … 1201 1154 1202 1155 static devclass_t fec_devclass; 1156 1203 1157 DRIVER_MODULE(fec, nexus, fec_nexus_driver, fec_devclass, 0, 0); 1158 DRIVER_MODULE(miibus, fec, miibus_driver, miibus_devclass, 0, 0); 1159 1204 1160 MODULE_DEPEND(fec, nexus, 1, 1, 1); 1205 1161 MODULE_DEPEND(fec, ether, 1, 1, 1);
Note: See TracChangeset
for help on using the changeset viewer.