Root/package/system/ep80579-drivers/patches/150-ocracoke_island.patch

1--- a/Embedded/src/GbE/iegbe_oem_phy.c
2+++ b/Embedded/src/GbE/iegbe_oem_phy.c
3@@ -65,6 +65,10 @@ static int32_t iegbe_oem_link_m88_setup(
4 static int32_t iegbe_oem_set_phy_mode(struct iegbe_hw *hw);
5 static int32_t iegbe_oem_detect_phy(struct iegbe_hw *hw);
6 
7+static int32_t iegbe_oem_link_bcm5481_setup(struct iegbe_hw *hw);
8+static int32_t bcm5481_read_18sv (struct iegbe_hw *hw, int sv, uint16_t *data);
9+static int32_t oi_phy_setup (struct iegbe_hw *hw);
10+
11 /**
12  * iegbe_oem_setup_link
13  * @hw: iegbe_hw struct containing device specific information
14@@ -114,6 +118,10 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
15     }
16 
17     switch (hw->phy_id) {
18+ case BCM5395S_PHY_ID:
19+ return E1000_SUCCESS;
20+ break;
21+
22         case M88E1000_I_PHY_ID:
23         case M88E1141_E_PHY_ID:
24             ret_val = iegbe_oem_link_m88_setup(hw);
25@@ -121,6 +129,12 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
26                 return ret_val;
27             }
28         break;
29+ case BCM5481_PHY_ID:
30+ ret_val = iegbe_oem_link_bcm5481_setup(hw);
31+ if(ret_val) {
32+ return ret_val;
33+ }
34+ break;
35         default:
36             DEBUGOUT("Invalid PHY ID\n");
37             return -E1000_ERR_PHY_TYPE;
38@@ -179,6 +193,51 @@ iegbe_oem_setup_link(struct iegbe_hw *hw
39 #endif /* ifdef EXTERNAL_MDIO */
40 }
41 
42+/**
43+ * iegbe_oem_link_bcm5481_setup
44+ * @hw: iegbe_hw struct containing device specific information
45+ *
46+ * Returns E1000_SUCCESS, negative E1000 error code on failure
47+ *
48+ * copied verbatim from iegbe_oem_link_m88_setup
49+ **/
50+static int32_t
51+iegbe_oem_link_bcm5481_setup(struct iegbe_hw *hw)
52+{
53+ int32_t ret_val;
54+ uint16_t phy_data;
55+
56+ //DEBUGFUNC(__func__);
57+
58+ if(!hw)
59+ return -1;
60+
61+ /* phy_reset_disable is set in iegbe_oem_set_phy_mode */
62+ if(hw->phy_reset_disable)
63+ return E1000_SUCCESS;
64+
65+ // Enable MDIX in extended control reg.
66+ ret_val = iegbe_oem_read_phy_reg_ex(hw, BCM5481_ECTRL, &phy_data);
67+ if(ret_val)
68+ {
69+ DEBUGOUT("Unable to read BCM5481_ECTRL register\n");
70+ return ret_val;
71+ }
72+
73+ phy_data &= ~BCM5481_ECTRL_DISMDIX;
74+ ret_val = iegbe_oem_write_phy_reg_ex(hw, BCM5481_ECTRL, phy_data);
75+ if(ret_val)
76+ {
77+ DEBUGOUT("Unable to write BCM5481_ECTRL register\n");
78+ return ret_val;
79+ }
80+
81+ ret_val = oi_phy_setup (hw);
82+ if (ret_val)
83+ return ret_val;
84+
85+ return E1000_SUCCESS;
86+}
87 
88 /**
89  * iegbe_oem_link_m88_setup
90@@ -340,6 +399,11 @@ iegbe_oem_force_mdi(struct iegbe_hw *hw,
91      * see iegbe_phy_force_speed_duplex, which does the following for M88
92      */
93       switch (hw->phy_id) {
94+ case BCM5395S_PHY_ID:
95+ case BCM5481_PHY_ID:
96+ DEBUGOUT("WARNING: An empty iegbe_oem_force_mdi() has been called!\n");
97+ break;
98+
99           case M88E1000_I_PHY_ID:
100           case M88E1141_E_PHY_ID:
101               ret_val = iegbe_oem_read_phy_reg_ex(hw,
102@@ -415,6 +479,8 @@ iegbe_oem_phy_reset_dsp(struct iegbe_hw
103      switch (hw->phy_id) {
104          case M88E1000_I_PHY_ID:
105          case M88E1141_E_PHY_ID:
106+ case BCM5481_PHY_ID:
107+ case BCM5395S_PHY_ID:
108              DEBUGOUT("No DSP to reset on OEM PHY\n");
109          break;
110          default:
111@@ -460,6 +526,11 @@ iegbe_oem_cleanup_after_phy_reset(struct
112      * see iegbe_phy_force_speed_duplex, which does the following for M88
113      */
114     switch (hw->phy_id) {
115+ case BCM5395S_PHY_ID:
116+ case BCM5481_PHY_ID:
117+ DEBUGOUT("WARNING: An empty iegbe_oem_cleanup_after_phy_reset() has been called!\n");
118+ break;
119+
120         case M88E1000_I_PHY_ID:
121         case M88E1141_E_PHY_ID:
122             /*
123@@ -573,6 +644,11 @@ iegbe_oem_set_phy_mode(struct iegbe_hw *
124      * use iegbe_set_phy_mode as example
125      */
126     switch (hw->phy_id) {
127+ case BCM5395S_PHY_ID:
128+ case BCM5481_PHY_ID:
129+ DEBUGOUT("WARNING: An empty iegbe_oem_set_phy_mode() has been called!\n");
130+ break;
131+
132          case M88E1000_I_PHY_ID:
133          case M88E1141_E_PHY_ID:
134              ret_val = iegbe_read_eeprom(hw,
135@@ -641,6 +717,19 @@ iegbe_oem_detect_phy(struct iegbe_hw *hw
136     }
137     hw->phy_type = iegbe_phy_oem;
138 
139+{
140+ // If MAC2 (BCM5395 switch), manually detect the phy
141+ struct iegbe_adapter *adapter;
142+ uint32_t device_number;
143+ adapter = (struct iegbe_adapter *) hw->back;
144+ device_number = PCI_SLOT(adapter->pdev->devfn);
145+ if (device_number == ICP_XXXX_MAC_2) {
146+ hw->phy_id = BCM5395S_PHY_ID;
147+ hw->phy_revision = 0;
148+ return E1000_SUCCESS;
149+ }
150+}
151+
152     ret_val = iegbe_oem_read_phy_reg_ex(hw, PHY_ID1, &phy_id_high);
153     if(ret_val) {
154         DEBUGOUT("Unable to read PHY register PHY_ID1\n");
155@@ -690,6 +779,8 @@ iegbe_oem_get_tipg(struct iegbe_hw *hw)
156     switch (hw->phy_id) {
157          case M88E1000_I_PHY_ID:
158          case M88E1141_E_PHY_ID:
159+ case BCM5481_PHY_ID:
160+ case BCM5395S_PHY_ID:
161              phy_num = DEFAULT_ICP_XXXX_TIPG_IPGT;
162          break;
163          default:
164@@ -738,6 +829,8 @@ iegbe_oem_phy_is_copper(struct iegbe_hw
165     switch (hw->phy_id) {
166         case M88E1000_I_PHY_ID:
167         case M88E1141_E_PHY_ID:
168+ case BCM5481_PHY_ID:
169+ case BCM5395S_PHY_ID:
170             isCopper = TRUE;
171         break;
172         default:
173@@ -796,13 +889,13 @@ iegbe_oem_get_phy_dev_number(struct iegb
174     switch(device_number)
175     {
176       case ICP_XXXX_MAC_0:
177- hw->phy_addr = 0x00;
178+ hw->phy_addr = 0x01;
179       break;
180       case ICP_XXXX_MAC_1:
181- hw->phy_addr = 0x01;
182+ hw->phy_addr = 0x02;
183       break;
184       case ICP_XXXX_MAC_2:
185- hw->phy_addr = 0x02;
186+ hw->phy_addr = 0x00;
187       break;
188       default: hw->phy_addr = 0x00;
189     }
190@@ -851,6 +944,12 @@ iegbe_oem_mii_ioctl(struct iegbe_adapter
191     if(!adapter || !ifr) {
192         return -1;
193     }
194+
195+ // If MAC2 (BCM5395 switch) then leave now
196+ if ((PCI_SLOT(adapter->pdev->devfn)) == ICP_XXXX_MAC_2) {
197+ return -1;
198+ }
199+
200     switch (data->reg_num) {
201         case PHY_CTRL:
202             if(mii_reg & MII_CR_POWER_DOWN) {
203@@ -987,6 +1086,11 @@ void iegbe_oem_get_phy_regs(struct iegbe
204      * [10] = mdix mode
205      */
206     switch (adapter->hw.phy_id) {
207+ case BCM5395S_PHY_ID:
208+ case BCM5481_PHY_ID:
209+ DEBUGOUT("WARNING: An empty iegbe_oem_get_phy_regs() has been called!\n");
210+ break;
211+
212         case M88E1000_I_PHY_ID:
213         case M88E1141_E_PHY_ID:
214             if(corrected_len > 0) {
215@@ -1068,8 +1172,13 @@ iegbe_oem_phy_loopback(struct iegbe_adap
216      * Loopback configuration is the same for each of the supported PHYs.
217      */
218     switch (adapter->hw.phy_id) {
219+ case BCM5395S_PHY_ID:
220+ DEBUGOUT("WARNING: An empty iegbe_oem_phy_loopback() has been called!\n");
221+ break;
222+
223         case M88E1000_I_PHY_ID:
224         case M88E1141_E_PHY_ID:
225+ case BCM5481_PHY_ID:
226 
227           adapter->hw.autoneg = FALSE;
228 
229@@ -1182,8 +1291,14 @@ iegbe_oem_loopback_cleanup(struct iegbe_
230     }
231 
232     switch (adapter->hw.phy_id) {
233+ case BCM5395S_PHY_ID:
234+ DEBUGOUT("WARNING: An empty iegbe_oem_loopback_cleanup() has been called!\n");
235+ return;
236+ break;
237+
238         case M88E1000_I_PHY_ID:
239         case M88E1141_E_PHY_ID:
240+ case BCM5481_PHY_ID:
241         default:
242             adapter->hw.autoneg = TRUE;
243         
244@@ -1243,6 +1358,11 @@ iegbe_oem_phy_speed_downgraded(struct ie
245      */
246 
247     switch (hw->phy_id) {
248+ case BCM5395S_PHY_ID:
249+ case BCM5481_PHY_ID:
250+ *isDowngraded = 0;
251+ break;
252+
253         case M88E1000_I_PHY_ID:
254         case M88E1141_E_PHY_ID:
255             ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
256@@ -1305,6 +1425,11 @@ iegbe_oem_check_polarity(struct iegbe_hw
257      */
258 
259     switch (hw->phy_id) {
260+ case BCM5395S_PHY_ID:
261+ case BCM5481_PHY_ID:
262+ *polarity = 0;
263+ break;
264+
265         case M88E1000_I_PHY_ID:
266         case M88E1141_E_PHY_ID:
267             /* return the Polarity bit in the Status register. */
268@@ -1367,6 +1492,25 @@ iegbe_oem_phy_is_full_duplex(struct iegb
269      */
270         
271       switch (hw->phy_id) {
272+ case BCM5395S_PHY_ID:
273+ /* Always full duplex */
274+ *isFD = 1;
275+ break;
276+
277+ case BCM5481_PHY_ID:
278+ ret_val = iegbe_read_phy_reg(hw, BCM5481_ASTAT, &phy_data);
279+ if(ret_val) return ret_val;
280+
281+ switch (BCM5481_ASTAT_HCD(phy_data)) {
282+ case BCM5481_ASTAT_1KBTFD:
283+ case BCM5481_ASTAT_100BTXFD:
284+ *isFD = 1;
285+ break;
286+ default:
287+ *isFD = 0;
288+ }
289+ break;
290+
291           case M88E1000_I_PHY_ID:
292           case M88E1141_E_PHY_ID:
293              ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
294@@ -1423,6 +1567,25 @@ iegbe_oem_phy_is_speed_1000(struct iegbe
295      */
296 
297     switch (hw->phy_id) {
298+ case BCM5395S_PHY_ID:
299+ /* Always 1000mb */
300+ *is1000 = 1;
301+ break;
302+
303+ case BCM5481_PHY_ID:
304+ ret_val = iegbe_read_phy_reg(hw, BCM5481_ASTAT, &phy_data);
305+ if(ret_val) return ret_val;
306+
307+ switch (BCM5481_ASTAT_HCD(phy_data)) {
308+ case BCM5481_ASTAT_1KBTFD:
309+ case BCM5481_ASTAT_1KBTHD:
310+ *is1000 = 1;
311+ break;
312+ default:
313+ *is1000 = 0;
314+ }
315+ break;
316+
317         case M88E1000_I_PHY_ID:
318         case M88E1141_E_PHY_ID:
319             ret_val = iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS,
320@@ -1478,6 +1641,25 @@ iegbe_oem_phy_is_speed_100(struct iegbe_
321      * see iegbe_config_mac_to_phy
322      */
323     switch (hw->phy_id) {
324+ case BCM5395S_PHY_ID:
325+ /* Always 1000Mb, never 100mb */
326+ *is100 = 0;
327+ break;
328+
329+ case BCM5481_PHY_ID:
330+ ret_val = iegbe_read_phy_reg(hw, BCM5481_ASTAT, &phy_data);
331+ if(ret_val) return ret_val;
332+
333+ switch (BCM5481_ASTAT_HCD(phy_data)) {
334+ case BCM5481_ASTAT_100BTXFD:
335+ case BCM5481_ASTAT_100BTXHD:
336+ *is100 = 1;
337+ break;
338+ default:
339+ *is100 = 0;
340+ }
341+ break;
342+
343         case M88E1000_I_PHY_ID:
344         case M88E1141_E_PHY_ID:
345             ret_val = iegbe_oem_read_phy_reg_ex(hw,
346@@ -1535,6 +1717,11 @@ iegbe_oem_phy_get_info(struct iegbe_hw *
347      * see iegbe_phy_m88_get_info
348      */
349     switch (hw->phy_id) {
350+ case BCM5395S_PHY_ID:
351+ case BCM5481_PHY_ID:
352+ DEBUGOUT("WARNING: An empty iegbe_oem_phy_get_info() has been called!\n");
353+ break;
354+
355         case M88E1000_I_PHY_ID:
356         case M88E1141_E_PHY_ID:
357   /* The downshift status is checked only once, after link is
358@@ -1636,8 +1823,13 @@ iegbe_oem_phy_hw_reset(struct iegbe_hw *
359      * the M88 used in truxton.
360      */
361     switch (hw->phy_id) {
362+ case BCM5395S_PHY_ID:
363+ DEBUGOUT("WARNING: An empty iegbe_oem_phy_hw_reset() has been called!\n");
364+ break;
365+
366         case M88E1000_I_PHY_ID:
367         case M88E1141_E_PHY_ID:
368+ case BCM5481_PHY_ID:
369             ret_val = iegbe_oem_read_phy_reg_ex(hw, PHY_CTRL, &phy_data);
370             if(ret_val) {
371                 DEBUGOUT("Unable to read register PHY_CTRL\n");
372@@ -1699,6 +1891,8 @@ iegbe_oem_phy_init_script(struct iegbe_h
373     switch (hw->phy_id) {
374         case M88E1000_I_PHY_ID:
375         case M88E1141_E_PHY_ID:
376+ case BCM5481_PHY_ID:
377+ case BCM5395S_PHY_ID:
378             DEBUGOUT("Nothing to do for OEM PHY Init");
379         break;
380         default:
381@@ -1735,6 +1929,11 @@ iegbe_oem_read_phy_reg_ex(struct iegbe_h
382         return -1;
383     }
384 
385+ if (hw->phy_id == BCM5395S_PHY_ID) {
386+ DEBUGOUT("WARNING: iegbe_oem_read_phy_reg_ex() has been unexpectedly called!\n");
387+ return -1;
388+ }
389+
390     /* call the GCU func that will read the phy
391      *
392      * Make note that the M88 phy is what'll be used on Truxton.
393@@ -1782,6 +1981,11 @@ iegbe_oem_set_trans_gasket(struct iegbe_
394     }
395 
396      switch (hw->phy_id) {
397+ case BCM5395S_PHY_ID:
398+ case BCM5481_PHY_ID:
399+ DEBUGOUT("WARNING: An empty iegbe_oem_set_trans_gasket() has been called!\n");
400+ break;
401+
402          case M88E1000_I_PHY_ID:
403          case M88E1141_E_PHY_ID:
404          /* Gasket set correctly for Marvell Phys, so nothing to do */
405@@ -1886,6 +2090,8 @@ iegbe_oem_phy_needs_reset_with_mac(struc
406     switch (hw->phy_id) {
407         case M88E1000_I_PHY_ID:
408         case M88E1141_E_PHY_ID:
409+ case BCM5481_PHY_ID:
410+ case BCM5395S_PHY_ID:
411             ret_val = FALSE;
412         break;
413         default:
414@@ -1935,6 +2141,8 @@ iegbe_oem_config_dsp_after_link_change(s
415     switch (hw->phy_id) {
416         case M88E1000_I_PHY_ID:
417         case M88E1141_E_PHY_ID:
418+ case BCM5481_PHY_ID:
419+ case BCM5395S_PHY_ID:
420             DEBUGOUT("No DSP to configure on OEM PHY");
421         break;
422         default:
423@@ -1978,6 +2186,12 @@ iegbe_oem_get_cable_length(struct iegbe_
424     }
425 
426     switch (hw->phy_id) {
427+ case BCM5395S_PHY_ID:
428+ case BCM5481_PHY_ID:
429+ *min_length = 0;
430+ *max_length = iegbe_igp_cable_length_150;
431+ break;
432+
433         case M88E1000_I_PHY_ID:
434         case M88E1141_E_PHY_ID:
435             ret_val = iegbe_oem_read_phy_reg_ex(hw,
436@@ -2061,6 +2275,23 @@ iegbe_oem_phy_is_link_up(struct iegbe_hw
437      */
438 
439     switch (hw->phy_id) {
440+ case BCM5395S_PHY_ID:
441+ /* Link always up */
442+ *isUp = TRUE;
443+ return E1000_SUCCESS;
444+ break;
445+
446+ case BCM5481_PHY_ID:
447+ iegbe_oem_read_phy_reg_ex(hw, BCM5481_ESTAT, &phy_data);
448+ ret_val = iegbe_oem_read_phy_reg_ex(hw, BCM5481_ESTAT, &phy_data);
449+ if(ret_val)
450+ {
451+ DEBUGOUT("Unable to read PHY register BCM5481_ESTAT\n");
452+ return ret_val;
453+ }
454+ statusMask = BCM5481_ESTAT_LINK;
455+ break;
456+
457         case M88E1000_I_PHY_ID:
458         case M88E1141_E_PHY_ID:
459             iegbe_oem_read_phy_reg_ex(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
460@@ -2092,3 +2323,210 @@ iegbe_oem_phy_is_link_up(struct iegbe_hw
461 #endif /* ifdef EXTERNAL_MDIO */
462 }
463 
464+
465+
466+//-----
467+// Read BCM5481 expansion register
468+//
469+int32_t
470+bcm5481_read_ex (struct iegbe_hw *hw, uint16_t reg, uint16_t *data)
471+{
472+ int ret;
473+ uint16_t selector;
474+ uint16_t reg_data;
475+
476+ // Get the current value of bits 15:12
477+ ret = iegbe_oem_read_phy_reg_ex (hw, 0x15, &selector);
478+ if (ret)
479+ return ret;
480+
481+ // Select the expansion register
482+ selector &= 0xf000;
483+ selector |= (0xf << 8) | (reg);
484+ iegbe_oem_write_phy_reg_ex (hw, 0x17, selector);
485+
486+ // Read the expansion register
487+ ret = iegbe_oem_read_phy_reg_ex (hw, 0x15, &reg_data);
488+
489+ // De-select the expansion registers.
490+ selector &= 0xf000;
491+ iegbe_oem_write_phy_reg_ex (hw, 0x17, selector);
492+
493+ if (ret)
494+ return ret;
495+
496+ *data = reg_data;
497+ return ret;
498+}
499+
500+//-----
501+// Read reg 0x18 sub-register
502+//
503+static int32_t
504+bcm5481_read_18sv (struct iegbe_hw *hw, int sv, uint16_t *data)
505+{
506+ int ret;
507+ uint16_t tmp_data;
508+
509+ // Select reg 0x18, sv
510+ tmp_data = ((sv & BCM5481_R18H_SV_MASK) << 12) | BCM5481_R18H_SV_MCTRL;
511+ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R18H, tmp_data);
512+ if(ret)
513+ return ret;
514+
515+ // Read reg 0x18, sv
516+ ret = iegbe_oem_read_phy_reg_ex (hw, BCM5481_R18H, &tmp_data);
517+ if(ret)
518+ return ret;
519+
520+ *data = tmp_data;
521+ return ret;
522+}
523+
524+//-----
525+// Read reg 0x1C sub-register
526+//
527+int32_t
528+bcm5481_read_1csv (struct iegbe_hw *hw, int sv, uint16_t *data)
529+{
530+ int ret;
531+ uint16_t tmp_data;
532+
533+ // Select reg 0x1c, sv
534+ tmp_data = ((sv & BCM5481_R1CH_SV_MASK) << BCM5481_R1CH_SV_SHIFT);
535+
536+ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R1CH, tmp_data);
537+ if(ret)
538+ return ret;
539+
540+ // Read reg 0x1c, sv
541+ ret = iegbe_oem_read_phy_reg_ex (hw, BCM5481_R1CH, &tmp_data);
542+ if(ret)
543+ return ret;
544+
545+ *data = tmp_data;
546+ return ret;
547+}
548+
549+//-----
550+// Read-modify-write a 0x1C register.
551+//
552+// hw - hardware access info.
553+// reg - 0x1C register to modify.
554+// data - bits which should be set.
555+// mask - the '1' bits in this argument will be cleared in the data
556+// read from 'reg' then 'data' will be or'd in and the result
557+// will be written to 'reg'.
558+
559+int32_t
560+bcm5481_rmw_1csv (struct iegbe_hw *hw, uint16_t reg, uint16_t data, uint16_t mask)
561+{
562+ int32_t ret;
563+ uint16_t reg_data;
564+
565+ ret = 0;
566+
567+ ret = bcm5481_read_1csv (hw, reg, &reg_data);
568+ if (ret)
569+ {
570+ DEBUGOUT("Unable to read BCM5481 1CH register\n");
571+ printk (KERN_ERR "Unable to read BCM5481 1CH register [0x%x]\n", reg);
572+ return ret;
573+ }
574+
575+ reg_data &= ~mask;
576+ reg_data |= (BCM5481_R1CH_WE | data);
577+
578+ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R1CH, reg_data);
579+ if(ret)
580+ {
581+ DEBUGOUT("Unable to write BCM5481 1CH register\n");
582+ printk (KERN_ERR "Unable to write BCM5481 1CH register\n");
583+ return ret;
584+ }
585+
586+ return ret;
587+}
588+
589+int32_t
590+oi_phy_setup (struct iegbe_hw *hw)
591+{
592+ int ret;
593+ uint16_t pmii_data;
594+ uint16_t mctrl_data;
595+ uint16_t cacr_data;
596+
597+ ret = 0;
598+
599+ // Set low power mode via reg 0x18, sv010, bit 6
600+ // Do a read-modify-write on reg 0x18, sv010 register to preserve existing bits.
601+ ret = bcm5481_read_18sv (hw, BCM5481_R18H_SV_PMII, &pmii_data);
602+ if (ret)
603+ {
604+ DEBUGOUT("Unable to read BCM5481_R18H_SV_PMII register\n");
605+ printk (KERN_ERR "Unable to read BCM5481_R18H_SV_PMII register\n");
606+ return ret;
607+ }
608+
609+ // Set the LPM bit in the data just read and write back to sv010
610+ // The shadow register select bits [2:0] are set by reading the sv010
611+ // register.
612+ pmii_data |= BCM5481_R18H_SV010_LPM;
613+ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R18H, pmii_data);
614+ if(ret)
615+ {
616+ DEBUGOUT("Unable to write BCM5481_R18H register\n");
617+ printk (KERN_ERR "Unable to write BCM5481_R18H register\n");
618+ return ret;
619+ }
620+
621+
622+ // Set the RGMII RXD to RXC skew bit in reg 0x18, sv111
623+
624+ if (bcm5481_read_18sv (hw, BCM5481_R18H_SV_MCTRL, &mctrl_data))
625+ {
626+ DEBUGOUT("Unable to read BCM5481_R18H_SV_MCTRL register\n");
627+ printk (KERN_ERR "Unable to read BCM5481_R18H_SV_MCTRL register\n");
628+ return ret;
629+ }
630+ mctrl_data |= (BCM5481_R18H_WE | BCM5481_R18H_SV111_SKEW);
631+
632+ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R18H, mctrl_data);
633+ if(ret)
634+ {
635+ DEBUGOUT("Unable to write BCM5481_R18H register\n");
636+ printk (KERN_ERR "Unable to write BCM5481_R18H register\n");
637+ return ret;
638+ }
639+
640+ // Enable RGMII transmit clock delay in reg 0x1c, sv00011
641+ ret = bcm5481_read_1csv (hw, BCM5481_R1CH_CACR, &cacr_data);
642+ if (ret)
643+ {
644+ DEBUGOUT("Unable to read BCM5481_R1CH_CACR register\n");
645+ printk (KERN_ERR "Unable to read BCM5481_R1CH_CACR register\n");
646+ return ret;
647+ }
648+
649+ cacr_data |= (BCM5481_R1CH_WE | BCM5481_R1CH_CACR_TCD);
650+
651+ ret = iegbe_oem_write_phy_reg_ex (hw, BCM5481_R1CH, cacr_data);
652+ if(ret)
653+ {
654+ DEBUGOUT("Unable to write BCM5481_R1CH register\n");
655+ printk (KERN_ERR "Unable to write BCM5481_R1CH register\n");
656+ return ret;
657+ }
658+
659+ // Enable dual link speed indication (0x1c, sv 00010, bit 2)
660+ ret = bcm5481_rmw_1csv (hw, BCM5481_R1CH_SC1, BCM5481_R1CH_SC1_LINK, BCM5481_R1CH_SC1_LINK);
661+ if (ret)
662+ return ret;
663+
664+ // Enable link and activity on ACTIVITY LED (0x1c, sv 01001, bit 4=1, bit 3=0)
665+ ret = bcm5481_rmw_1csv (hw, BCM5481_R1CH_LCTRL, BCM5481_R1CH_LCTRL_ALEN, BCM5481_R1CH_LCTRL_ALEN | BCM5481_R1CH_LCTRL_AEN);
666+ if (ret)
667+ return ret;
668+
669+ return ret;
670+}
671--- a/Embedded/src/GbE/iegbe_oem_phy.h
672+++ b/Embedded/src/GbE/iegbe_oem_phy.h
673@@ -95,6 +95,8 @@ int32_t iegbe_oem_phy_is_link_up(struct
674 
675 #define DEFAULT_ICP_XXXX_TIPG_IPGT 8 /* Inter Packet Gap Transmit Time */
676 #define ICP_XXXX_TIPG_IPGT_MASK 0x000003FFUL
677+#define BCM5481_PHY_ID 0x0143BCA0
678+#define BCM5395S_PHY_ID 0x0143BCF0
679 
680 /* Miscellaneous defines */
681 #ifdef IEGBE_10_100_ONLY
682@@ -103,5 +105,65 @@ int32_t iegbe_oem_phy_is_link_up(struct
683     #define ICP_XXXX_AUTONEG_ADV_DEFAULT 0x2F
684 #endif
685 
686+/* BCM5481 specifics */
687+
688+#define BCM5481_ECTRL (0x10)
689+#define BCM5481_ESTAT (0x11)
690+#define BCM5481_RXERR (0x12)
691+#define BCM5481_EXPRW (0x15)
692+#define BCM5481_EXPACC (0x17)
693+#define BCM5481_ASTAT (0x19)
694+#define BCM5481_R18H (0x18)
695+#define BCM5481_R1CH (0x1c)
696+
697+/* indirect register access via register 18h */
698+
699+#define BCM5481_R18H_SV_MASK (7) // Mask for SV bits.
700+#define BCM5481_R18H_SV_ACTRL (0) // SV000 Aux. control
701+#define BCM5481_R18H_SV_10BT (1) // SV001 10Base-T
702+#define BCM5481_R18H_SV_PMII (2) // SV010 Power/MII control
703+#define BCM5481_R18H_SV_MTEST (4) // SV100 Misc. test
704+#define BCM5481_R18H_SV_MCTRL (7) // SV111 Misc. control
705+
706+#define BCM5481_R18H_SV001_POL (1 << 13) // Polarity
707+#define BCM5481_R18H_SV010_LPM (1 << 6)
708+#define BCM5481_R18H_SV111_SKEW (1 << 8)
709+#define BCM5481_R18H_WE (1 << 15) // Write enable
710+
711+// 0x1c registers
712+#define BCM5481_R1CH_SV_SHIFT (10)
713+#define BCM5481_R1CH_SV_MASK (0x1f)
714+#define BCM5481_R1CH_SC1 (0x02) // sv00010 Spare control 1
715+#define BCM5481_R1CH_CACR (0x03) // sv00011 Clock alignment control
716+#define BCM5481_R1CH_LCTRL (0x09) // sv01001 LED control
717+#define BCM5481_R1CH_LEDS1 (0x0d) // sv01101 LED selector 1
718+
719+// 0x1c common
720+#define BCM5481_R1CH_WE (1 << 15) // Write enable
721+
722+// 0x1c, sv 00010
723+#define BCM5481_R1CH_SC1_LINK (1 << 2) // sv00010 Linkspeed
724+
725+// 0x1c, sv 00011
726+#define BCM5481_R1CH_CACR_TCD (1 << 9) // sv00011 RGMII tx clock delay
727+
728+// 0x1c, sv 01001
729+#define BCM5481_R1CH_LCTRL_ALEN (1 << 4) // Activity/Link enable on ACTIVITY LED
730+#define BCM5481_R1CH_LCTRL_AEN (1 << 3) // Activity enable on ACTIVITY LED
731+
732+#define BCM5481_ECTRL_DISMDIX (1 <<14)
733+
734+#define BCM5481_MCTRL_AUTOMDIX (1 <<9)
735+
736+#define BCM5481_ESTAT_LINK (1 << 8)
737+
738+#define BCM5481_ASTAT_ANC (1 << 15)
739+#define BCM5481_ASTAT_ANHCD (7 << 8)
740+#define BCM5481_ASTAT_HCD(x) ((x >> 8) & 7)
741+#define BCM5481_ASTAT_1KBTFD (0x7)
742+#define BCM5481_ASTAT_1KBTHD (0x6)
743+#define BCM5481_ASTAT_100BTXFD (0x5)
744+#define BCM5481_ASTAT_100BTXHD (0x3)
745+
746 #endif /* ifndef _IEGBE_OEM_PHY_H_ */
747  
748

Archive Download this file



interactive