0551a79a2454663d15407f58a5bbd4153b4fb840
[deliverable/linux.git] / drivers / net / phy / swphy.c
1 /*
2 * Software PHY emulation
3 *
4 * Code taken from fixed_phy.c by Russell King <rmk+kernel@arm.linux.org.uk>
5 *
6 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
7 * Anton Vorontsov <avorontsov@ru.mvista.com>
8 *
9 * Copyright (c) 2006-2007 MontaVista Software, Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16 #include <linux/export.h>
17 #include <linux/mii.h>
18 #include <linux/phy.h>
19 #include <linux/phy_fixed.h>
20
21 #include "swphy.h"
22
23 /**
24 * swphy_update_regs - update MII register array with fixed phy state
25 * @regs: array of 32 registers to update
26 * @state: fixed phy status
27 *
28 * Update the array of MII registers with the fixed phy link, speed,
29 * duplex and pause mode settings.
30 */
31 int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
32 {
33 u16 bmsr = BMSR_ANEGCAPABLE;
34 u16 bmcr = 0;
35 u16 lpagb = 0;
36 u16 lpa = 0;
37
38 if (state->duplex) {
39 switch (state->speed) {
40 case 1000:
41 bmsr |= BMSR_ESTATEN;
42 break;
43 case 100:
44 bmsr |= BMSR_100FULL;
45 break;
46 case 10:
47 bmsr |= BMSR_10FULL;
48 break;
49 default:
50 break;
51 }
52 } else {
53 switch (state->speed) {
54 case 1000:
55 bmsr |= BMSR_ESTATEN;
56 break;
57 case 100:
58 bmsr |= BMSR_100HALF;
59 break;
60 case 10:
61 bmsr |= BMSR_10HALF;
62 break;
63 default:
64 break;
65 }
66 }
67
68 if (state->link) {
69 bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
70
71 if (state->duplex) {
72 bmcr |= BMCR_FULLDPLX;
73
74 switch (state->speed) {
75 case 1000:
76 bmcr |= BMCR_SPEED1000;
77 lpagb |= LPA_1000FULL;
78 break;
79 case 100:
80 bmcr |= BMCR_SPEED100;
81 lpa |= LPA_100FULL;
82 break;
83 case 10:
84 lpa |= LPA_10FULL;
85 break;
86 default:
87 pr_warn("swphy: unknown speed\n");
88 return -EINVAL;
89 }
90 } else {
91 switch (state->speed) {
92 case 1000:
93 bmcr |= BMCR_SPEED1000;
94 lpagb |= LPA_1000HALF;
95 break;
96 case 100:
97 bmcr |= BMCR_SPEED100;
98 lpa |= LPA_100HALF;
99 break;
100 case 10:
101 lpa |= LPA_10HALF;
102 break;
103 default:
104 pr_warn("swphy: unknown speed\n");
105 return -EINVAL;
106 }
107 }
108
109 if (state->pause)
110 lpa |= LPA_PAUSE_CAP;
111
112 if (state->asym_pause)
113 lpa |= LPA_PAUSE_ASYM;
114 }
115
116 regs[MII_PHYSID1] = 0;
117 regs[MII_PHYSID2] = 0;
118
119 regs[MII_BMSR] = bmsr;
120 regs[MII_BMCR] = bmcr;
121 regs[MII_LPA] = lpa;
122 regs[MII_STAT1000] = lpagb;
123
124 return 0;
125 }
126 EXPORT_SYMBOL_GPL(swphy_update_regs);
This page took 0.032998 seconds and 4 git commands to generate.