embkernel
 All Classes Functions Variables Typedefs Groups Pages
NetMac.hpp
1 //------------------------------------------------------------------------------
2 //This file is part of embKernel.
3 //See license.txt for the full license governing this code.
4 //------------------------------------------------------------------------------
5 
6 #ifndef NET_MAC_STM32F4XX_HPP_
7 #define NET_MAC_STM32F4XX_HPP_
8 
9 #include "RtosSemaphore.hpp"
10 #include "NetDefs.hpp"
11 
12 class NetMac {
13  friend class Net;
14 public:
15  NetMac();
16 
17  static const int EMAC_RX_FRAG_COUNT = 4;
18  static const int EMAC_TX_FRAG_COUNT = 8;
19 private:
20  //Phy registers
21  const static uint32_t PHY_REG_BMCR = 0x00; // Basic Mode Control Register
22  const static uint32_t PHY_REG_BMSR = 0x01; // Basic Mode Status Register
23  const static uint32_t PHY_REG_IDR1 = 0x02; // PHY Identifier 1
24  const static uint32_t PHY_REG_IDR2 = 0x03; // PHY Identifier 2
25  const static uint32_t PHY_REG_ANAR = 0x04; // Auto-Negotiation Advertisement
26  const static uint32_t PHY_REG_ANLPAR = 0x05; // Auto-Neg. Link Partner Abitily
27  const static uint32_t PHY_REG_ANER = 0x06; // Auto-Neg. Expansion Register
28  const static uint32_t PHY_REG_ANNPTR = 0x07; // Auto-Neg. Next Page TX
29  const static uint32_t PHY_REG_LPNPA = 0x08; //
30 
31  //Basic Mode Control Register bits
32  const static uint32_t PHY_BMCR_RESET = (1 << 15); // Reset bit
33  const static uint32_t PHY_BMCR_LOOPBACK = (1 << 14); // Loop back
34  const static uint32_t PHY_BMCR_SPEED_SEL = (1 << 13); // Speed selection
35  const static uint32_t PHY_BMCR_AN = (1 << 12); // Auto Negotiation
36  const static uint32_t PHY_BMCR_POWERDOWN = (1 << 11); // Power down mode
37  const static uint32_t PHY_BMCR_ISOLATE = (1 << 10); // Isolate
38  const static uint32_t PHY_BMCR_RE_AN = (1 << 9); // Restart auto negotiation
39  const static uint32_t PHY_BMCR_DUPLEX = (1 << 8); // Duplex mode
40 
41  //Basic Mode Status Register bits
42  const static uint32_t PHY_BMSR_100BE_T4 = (1 << 15); // 100 base T4
43  const static uint32_t PHY_BMSR_100TX_FULL = (1 << 14); // 100 base full duplex
44  const static uint32_t PHY_BMSR_100TX_HALF = (1 << 13); // 100 base half duplex
45  const static uint32_t PHY_BMSR_10BE_FULL = (1 << 12); // 10 base T full duplex
46  const static uint32_t PHY_BMSR_10BE_HALF = (1 << 11); // 10 base T half duplex
47  const static uint32_t PHY_BMSR_NOPREAM = (1 << 6); // MF Preamable Supress
48  const static uint32_t PHY_BMSR_AUTO_DONE = (1 << 5); // Auto negotiation complete
49  const static uint32_t PHY_BMSR_REMOTE_FAULT = (1 << 4); // Remote fault
50  const static uint32_t PHY_BMSR_NO_AUTO = (1 << 3); // Auto Negotiation ability
51  const static uint32_t PHY_BMSR_LINK_ESTABLISHED = (1 << 2); // Link status
52 
53  const static uint32_t RX_DESC0_OWN = 0x80000000; // OWN bit: descriptor is owned by DMA engine
54  const static uint32_t RX_DESC0_AFM = 0x40000000; // DA Filter Fail for the rx frame
55  const static uint32_t RX_DESC0_FL = 0x3FFF0000; // Receive descriptor frame length
56  const static uint32_t RX_DESC0_ES = 0x00008000; // Error summary: OR of the following bits: DE || OE || IPC || LC || RWT || RE || CE
57  const static uint32_t RX_DESC0_DE = 0x00004000; // Descriptor error: no more descriptors for receive frame
58  const static uint32_t RX_DESC0_SAF = 0x00002000; // SA Filter Fail for the received frame
59  const static uint32_t RX_DESC0_LE = 0x00001000; // Frame size not matching with length field
60  const static uint32_t RX_DESC0_OE = 0x00000800; // Overflow Error: Frame was damaged due to buffer overflow
61  const static uint32_t RX_DESC0_VLAN = 0x00000400; // VLAN Tag: received frame is a VLAN frame
62  const static uint32_t RX_DESC0_FS = 0x00000200; // First descriptor of the frame
63  const static uint32_t RX_DESC0_LS = 0x00000100; // Last descriptor of the frame
64  const static uint32_t RX_DESC0_IPV4HCE = 0x00000080; // IPC Checksum Error: Rx Ipv4 header checksum error
65  const static uint32_t RX_DESC0_LC = 0x00000040; // Late collision occurred during reception
66  const static uint32_t RX_DESC0_FT = 0x00000020; // Frame type - Ethernet, otherwise 802.3
67  const static uint32_t RX_DESC0_RWT = 0x00000010; // Receive Watchdog Timeout: watchdog timer expired during reception
68  const static uint32_t RX_DESC0_RE = 0x00000008; // Receive error: error reported by MII interface
69  const static uint32_t RX_DESC0_DBE = 0x00000004; // Dribble bit error: frame contains non int multiple of 8 bits
70  const static uint32_t RX_DESC0_CE = 0x00000002; // CRC error
71  const static uint32_t RX_DESC0_MAMPCE = 0x00000001; // Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error
72 
73  const static uint32_t TX_DESC0_OWN = 0x80000000; //OWN bit: descriptor is owned by DMA engine
74  const static uint32_t TX_DESC0_IC = 0x40000000; //Interrupt on Completion
75  const static uint32_t TX_DESC0_LS = 0x20000000; //Last Segment
76  const static uint32_t TX_DESC0_FS = 0x10000000; //First Segment
77  const static uint32_t TX_DESC0_DC = 0x08000000; //Disable CRC
78  const static uint32_t TX_DESC0_DP = 0x04000000; //Disable Padding
79  const static uint32_t TX_DESC0_TTSE = 0x02000000; //Transmit Time Stamp Enable
80  const static uint32_t TX_DESC0_CIC = 0x00C00000; //Checksum Insertion Control: 4 cases
81  const static uint32_t TX_DESC0_CIC_ByPass = 0x00000000; //Do Nothing: Checksum Engine is bypassed
82  const static uint32_t TX_DESC0_CIC_IPV4Header = 0x00400000; //IPV4 header Checksum Insertion
83  const static uint32_t TX_DESC0_CIC_TCPUDPICMP_Segment = 0x00800000; //TCP/UDP/ICMP Checksum Insertion calculated over segment only
84  const static uint32_t TX_DESC0_CIC_TCPUDPICMP_Full = 0x00C00000; //TCP/UDP/ICMP Checksum Insertion fully calculated
85  const static uint32_t TX_DESC0_TER = 0x00200000; //Transmit End of Ring
86  const static uint32_t TX_DESC0_TCH = 0x00100000; //Second Address Chained
87  const static uint32_t TX_DESC0_TTSS = 0x00020000; //Tx Time Stamp Status
88  const static uint32_t TX_DESC0_IHE = 0x00010000; //IP Header Error
89  const static uint32_t TX_DESC0_ES = 0x00008000; //Error summary: OR of the following bits: UE || ED || EC || LCO || NC || LCA || FF || JT
90  const static uint32_t TX_DESC0_JT = 0x00004000; //Jabber Timeout
91  const static uint32_t TX_DESC0_FF = 0x00002000; //Frame Flushed: DMA/MTL flushed the frame due to SW flush
92  const static uint32_t TX_DESC0_PCE = 0x00001000; //Payload Checksum Error
93  const static uint32_t TX_DESC0_LCA = 0x00000800; //Loss of Carrier: carrier lost during transmission
94  const static uint32_t TX_DESC0_NC = 0x00000400; //No Carrier: no carrier signal from the transceiver
95  const static uint32_t TX_DESC0_LCO = 0x00000200; //Late Collision: transmission aborted due to collision
96  const static uint32_t TX_DESC0_EC = 0x00000100; //Excessive Collision: transmission aborted after 16 collisions
97  const static uint32_t TX_DESC0_VF = 0x00000080; //VLAN Frame
98  const static uint32_t TX_DESC0_CC = 0x00000078; //Collision Count
99  const static uint32_t TX_DESC0_ED = 0x00000004; //Excessive Deferral
100  const static uint32_t TX_DESC0_UF = 0x00000002; //Underflow Error: late data arrival from the memory
101  const static uint32_t TX_DESC0_DB = 0x00000001; //Deferred Bit
102 
103  typedef struct {
104  union {
105  uint32_t value;
106  struct {
107  uint32_t RMAM_PCE :1; //Payload checksum error / extended status available
108  uint32_t CE :1; //CRC error
109  uint32_t DE :1; //Dribble bit error
110  uint32_t RE :1; //Receive error
111  uint32_t RWT :1; //Receive watchdog timeout
112  uint32_t FT :1; //Frame type
113  uint32_t LC :1; //Late collision
114  uint32_t IPHCE :1; //IPv header checksum error / time stamp valid
115  uint32_t LS :1; //Last descriptor
116  uint32_t FS :1; //First descriptor
117  uint32_t VLAN :1; //VLAN tag
118  uint32_t OE :1; //Overflow error
119  uint32_t LE :1; //Length error
120  uint32_t SAF :1; //Source address filter fail
121  uint32_t DERR :1; //Descriptor error
122  uint32_t ES :1; //Error summary
123  uint32_t FL :14; //Frame length
124  uint32_t AFM :1; //Destination address filter fail
125  uint32_t OWN :1; //Own bit, 1 when owned by DMA, 0 otherwise
126  } bits;
127  } rdes0;
128  union {
129  uint32_t value;
130  struct {
131  uint32_t RBS1 :13; //Receive buffer 1 size
132  uint32_t :1; //Reserved, must be kept at reset value.
133  uint32_t RCH :1; //Second address chained
134  uint32_t RER :1; //Receive end of ring
135  uint32_t RBS2 :13; //Receive buffer 2 size
136  uint32_t :2; //Reserved, must be kept at reset value.
137  uint32_t DIC :1; //Disable interrupt on completion
138  } bits;
139  } rdes1;
140  uint32_t rdes2;
141  uint32_t rdes3;
142  }__attribute__((packed)) RX_DESC;
143 
144  typedef enum uint8_t {
145  TX_FRAG_NO_BUFFER = 0,
146  TX_FRAG_DISCARDABLE,
147  TX_FRAG_NOT_DISCARDABLE
148  } TX_FRAG_STATE;
149 
150  typedef struct {
151  union {
152  uint32_t value;
153  struct {
154  uint32_t DB :1; //Deferred bit
155  uint32_t UF :1; //Underflow error
156  uint32_t ED :1; //Excessive deferral
157  uint32_t CC :4; //Collision count
158  uint32_t VF :1; //VLAN frame
159  uint32_t EC :1; //Excessive collision
160  uint32_t LC :1; //Late collision
161  uint32_t NC :1; //No carrier
162  uint32_t LSC :1; //Loss of carrier
163  uint32_t IPE :1; //IP payload error
164  uint32_t FF :1; //Frame flushed
165  uint32_t JT :1; //Jabber timeout
166  uint32_t ES :1; //Error summary
167  uint32_t IHE :1; //IP header error
168  uint32_t TTSS :1; //Transmit time stamp status
169  uint32_t Res1 :2; //Reserved, must be kept at reset value.
170  uint32_t TCH :1; //Second address chained
171  uint32_t TER :1; //Transmit end of ring
172  uint32_t CIC :2; //Checksum insertion control
173  uint32_t Res2 :1; //Reserved, must be kept at reset value.
174  uint32_t TTSE :1; //Transmit time stamp enable
175  uint32_t DP :1; //Disable pad
176  uint32_t DC :1; //Disable CRC
177  uint32_t FS :1; //First segment
178  uint32_t LSEG :1; //Last segment
179  uint32_t IC :1; //Interrupt on completion
180  uint32_t OWN :1; //Own bit, 1 when owned by DMA, 0 otherwise
181  } bits;
182  } tdes0;
183  union {
184  uint32_t value;
185  struct {
186  uint32_t TBS1 :13; //TBS1: Transmit buffer 1 size
187  uint32_t Res1 :3; //Reserved, must be kept at reset value.
188  uint32_t TBS2 :12; //Transmit buffer 2 size
189  uint32_t Res2 :3; //Reserved, must be kept at reset value.
190  } bits;
191  } tdes1;
192  uint32_t tdes2;
193  uint32_t tdes3;
194  TX_FRAG_STATE state;
195  uint8_t spare[3];
196  }__attribute__((packed)) TX_DESC;
197 
198  __attribute__ ((aligned (4))) RX_DESC sRxDesc[EMAC_RX_FRAG_COUNT];
199  __attribute__ ((aligned (4))) TX_DESC sTxDesc[EMAC_TX_FRAG_COUNT];
200 
201  int sTxNextToSend;
202  int sTxNextToCheck;
203 
204  int mRxIdx;
205 
206  NetDefs::MAC_ADDR sAddr;
207 
208  bool phyWrite(uint16_t reg, uint16_t value);
209  uint32_t phyRead(uint16_t reg);
210 
211  RtosSemaphore mSema;
212 
213  uint32_t mPhyId;
214 
215  uint16_t mPhyAddr;
216 
217 private:
218  void start(const NetDefs::MAC_ADDR& addr);
219  NetDefs::FRAME* getFrame();
220  void putHeader(NetDefs::FRAME& frame, const NetDefs::MAC_ADDR& dst, NetDefs::MAC_TYPE type);
221  bool flush(NetDefs::FRAME& frame, size_t len, bool discardable);
222  void freeSentFrames();
223 };
224 
225 #endif /* NET_MAC_STM32F4XX_HPP_ */