source: rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c @ 967481a0

4.115
Last change on this file since 967481a0 was 967481a0, checked in by Peter Dufault <dufault@…>, on 10/01/12 at 13:12:25

bsps: PR2076: SMC91111 fixes for mpc55xxevb BSP

  • A typo prevents if_smc.c from being built when configured;
  • The argument passed to the interrupt handler was incorrect and the addition of support for RTEMS_INTERRUPT_SHARED exposed it;
  • A "#ifdef DEBUG" is supposed to be "#if DEBUG" since 0 is supposed to make it quiet.
  • Property mode set to 100644
File size: 4.4 KB
Line 
1#include <bsp.h>
2
3#ifdef HAS_SMC91111
4
5#include <mpc55xx/mpc55xx.h>
6#include <mpc55xx/regs.h>
7
8#include <rtems.h>
9
10#include <bsp/irq.h>
11#include <rtems/bspIo.h>
12#include <libcpu/powerpc-utility.h>
13
14
15#include <stdlib.h>
16#include <stdio.h>
17#include <stdarg.h>
18#include <rtems/error.h>
19#include <rtems/rtems_bsdnet.h>
20#include <rtems/irq-extension.h>
21
22#include <sys/param.h>
23#include <sys/mbuf.h>
24
25#include <sys/socket.h>
26#include <sys/sockio.h>
27#include <net/if.h>
28#include <netinet/in.h>
29#include <netinet/if_ether.h>
30
31#include <libchip/smc91111exp.h>
32
33
34
35/* The SMC91111 on the MPC5554SOM is IRQ2.
36 */
37#define SMC91111_BASE_ADDR (void*)0x22000300
38#define SMC91111_BASE_IRQ  MPC55XX_IRQ_SIU_EXTERNAL_2
39#define SMC91111_BASE_PIO  4
40
41extern void lan91cxx_interrupt_handler(void *arg);
42
43static const union SIU_EISR_tag clear_eisr_2 = {.B.EIF2 = 1};
44
45static void rtems_smc91111_interrupt_wrapper(void *arg)
46{
47    /* Clear external interrupt status */
48
49    SIU.EISR = clear_eisr_2;
50
51    lan91cxx_interrupt_handler(arg);
52}
53
54scmv91111_configuration_t mpc5554_scmv91111_configuration = {
55  SMC91111_BASE_ADDR, /* base address */
56  SMC91111_BASE_IRQ,  /* vector number */
57  SMC91111_BASE_PIO,  /* XXX: What's this? */
58  100,                /* 100b */
59  1,                  /* fulldx */
60  1,                  /* autoneg */
61  "SMC91111",
62  RTEMS_INTERRUPT_UNIQUE,
63  rtems_smc91111_interrupt_wrapper,
64  (void *)0
65};
66
67int _rtems_smc91111_driver_attach(
68  struct rtems_bsdnet_ifconfig *config,
69  scmv91111_configuration_t    *scm_config
70);
71
72/*
73 * Attach an SMC91111 driver to the system
74 */
75int rtems_smc91111_driver_attach_mpc5554(struct rtems_bsdnet_ifconfig *config)
76{
77  /* Configure IRQ2 (GPIO pin 211) is set up properly:
78   * Secondary, Alternate, Input.
79   */
80  static const union SIU_PCR_tag irq_input_pcr = {
81      .B.PA = 2,     /* Alternate function 1 */
82      .B.OBE = 0,
83      .B.IBE = 1,    /* Input Buffer Enable */
84      .B.DSC = 0,
85      .B.ODE = 0,
86      .B.HYS = 1,
87      .B.SRC = 3,    /* Maximum slew rate */
88      .B.WPE = 0,    /* Disable weak pullup/pulldown */
89      .B.WPS = 1     /* Specify weak pullup?  But it isn't enabled! */
90    };
91
92    union SIU_ORER_tag orer = MPC55XX_ZERO_FLAGS;
93    union SIU_DIRER_tag direr = MPC55XX_ZERO_FLAGS;
94    union SIU_IREER_tag ireer = MPC55XX_ZERO_FLAGS;
95    union SIU_IFEER_tag ifeer = MPC55XX_ZERO_FLAGS;
96    union SIU_IDFR_tag idfr = MPC55XX_ZERO_FLAGS;
97    union SIU_DIRSR_tag dirsr = MPC55XX_ZERO_FLAGS;
98    rtems_interrupt_level level;
99
100#define MPC55XX_EBI_CS_2_BR 0x22000003
101#define MPC55XX_EBI_CS_2_OR 0xff000010
102#if MPC55XX_EBI_CS_2_BR
103    static const union SIU_PCR_tag primary_50pf_weak_pullup = {                 /* 0x4c3 */
104        .B.PA = 1,
105        .B.DSC = 3,
106        .B.WPE = 1,
107        .B.WPS = 1
108    };
109    EBI.CS[2].BR.R = MPC55XX_EBI_CS_2_BR;
110    EBI.CS[2].OR.R = MPC55XX_EBI_CS_2_OR;
111    SIU.PCR[2] = primary_50pf_weak_pullup;
112#endif
113
114    SIU.PCR[211] = irq_input_pcr;
115
116    /* XXX These should be using bit set and bit clear instructions */
117
118    /* DMA/Interrupt Request Select */
119    rtems_interrupt_disable(level);
120    dirsr.R = SIU.DIRSR.R;
121    dirsr.B.DIRS2 = 0;                  /* Select interrupt not DMA */
122    SIU.DIRSR.R = dirsr.R;
123    rtems_interrupt_enable(level);
124
125    /* Overrun Request Enable */
126    rtems_interrupt_disable(level);
127    orer.R = SIU.ORER.R;
128    orer.B.ORE2 = 0;                    /* Disable overruns. */
129    SIU.ORER.R = orer.R;
130    rtems_interrupt_enable(level);
131
132    /* IRQ Rising-Edge Enable */
133    rtems_interrupt_disable(level);
134    ireer.R = SIU.IREER.R;
135    ireer.B.IREE2 = 1;              /* Enable rising edge. */
136    SIU.IREER.R = ireer.R;
137    rtems_interrupt_enable(level);
138
139    /* IRQ Falling-Edge Enable */
140    rtems_interrupt_disable(level);
141    ifeer.R = SIU.IFEER.R;
142    ifeer.B.IFEE2 = 0;              /* Disable falling edge. */
143    SIU.IFEER.R = ifeer.R;
144    rtems_interrupt_enable(level);
145
146    /* IRQ Digital Filter */
147    rtems_interrupt_disable(level);
148    idfr.R = SIU.IDFR.R;
149    idfr.B.DFL = 0;                 /* Minimal digital filter. */
150    SIU.IDFR.R = idfr.R;
151    rtems_interrupt_enable(level);
152
153    /* Clear external interrupt status */
154    SIU.EISR = clear_eisr_2;
155
156    /* DMA/Interrupt Request Enable */
157    rtems_interrupt_disable(level);
158    direr.R = SIU.DIRER.R;
159    direr.B.EIRE2 = 1;              /* Enable. */
160    SIU.DIRER.R = direr.R;
161    rtems_interrupt_enable(level);
162
163    return _rtems_smc91111_driver_attach(config,&mpc5554_scmv91111_configuration);
164};
165
166#endif /* HAS_SMC91111 */
Note: See TracBrowser for help on using the repository browser.