]>
Commit | Line | Data |
---|---|---|
1a59d1b8 | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
a6a53252 JY |
2 | /* |
3 | * Copyright(c) 2007 Atheros Corporation. All rights reserved. | |
4 | * | |
5 | * Derived from Intel e1000 driver | |
6 | * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. | |
a6a53252 JY |
7 | */ |
8 | ||
9 | #include <linux/netdevice.h> | |
10 | ||
11 | #include "atl1e.h" | |
12 | ||
13 | /* This is the only thing that needs to be changed to adjust the | |
14 | * maximum number of ports that the driver can manage. | |
15 | */ | |
16 | ||
17 | #define ATL1E_MAX_NIC 32 | |
18 | ||
19 | #define OPTION_UNSET -1 | |
20 | #define OPTION_DISABLED 0 | |
21 | #define OPTION_ENABLED 1 | |
22 | ||
23 | /* All parameters are treated the same, as an integer array of values. | |
24 | * This macro just reduces the need to repeat the same declaration code | |
25 | * over and over (plus this helps to avoid typo bugs). | |
26 | */ | |
27 | #define ATL1E_PARAM_INIT { [0 ... ATL1E_MAX_NIC] = OPTION_UNSET } | |
28 | ||
29 | #define ATL1E_PARAM(x, desc) \ | |
093d369d | 30 | static int x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \ |
fd8ef49e | 31 | static unsigned int num_##x; \ |
a6a53252 JY |
32 | module_param_array_named(x, x, int, &num_##x, 0); \ |
33 | MODULE_PARM_DESC(x, desc); | |
34 | ||
35 | /* Transmit Memory count | |
36 | * | |
37 | * Valid Range: 64-2048 | |
38 | * | |
39 | * Default Value: 128 | |
40 | */ | |
41 | #define ATL1E_MIN_TX_DESC_CNT 32 | |
42 | #define ATL1E_MAX_TX_DESC_CNT 1020 | |
43 | #define ATL1E_DEFAULT_TX_DESC_CNT 128 | |
44 | ATL1E_PARAM(tx_desc_cnt, "Transmit description count"); | |
45 | ||
46 | /* Receive Memory Block Count | |
47 | * | |
48 | * Valid Range: 16-512 | |
49 | * | |
50 | * Default Value: 128 | |
51 | */ | |
52 | #define ATL1E_MIN_RX_MEM_SIZE 8 /* 8KB */ | |
53 | #define ATL1E_MAX_RX_MEM_SIZE 1024 /* 1MB */ | |
54 | #define ATL1E_DEFAULT_RX_MEM_SIZE 256 /* 128KB */ | |
55 | ATL1E_PARAM(rx_mem_size, "memory size of rx buffer(KB)"); | |
56 | ||
57 | /* User Specified MediaType Override | |
58 | * | |
59 | * Valid Range: 0-5 | |
60 | * - 0 - auto-negotiate at all supported speeds | |
61 | * - 1 - only link at 100Mbps Full Duplex | |
62 | * - 2 - only link at 100Mbps Half Duplex | |
63 | * - 3 - only link at 10Mbps Full Duplex | |
64 | * - 4 - only link at 10Mbps Half Duplex | |
65 | * Default Value: 0 | |
66 | */ | |
67 | ||
68 | ATL1E_PARAM(media_type, "MediaType Select"); | |
69 | ||
70 | /* Interrupt Moderate Timer in units of 2 us | |
71 | * | |
72 | * Valid Range: 10-65535 | |
73 | * | |
74 | * Default Value: 45000(90ms) | |
75 | */ | |
76 | #define INT_MOD_DEFAULT_CNT 100 /* 200us */ | |
77 | #define INT_MOD_MAX_CNT 65000 | |
78 | #define INT_MOD_MIN_CNT 50 | |
79 | ATL1E_PARAM(int_mod_timer, "Interrupt Moderator Timer"); | |
80 | ||
81 | #define AUTONEG_ADV_DEFAULT 0x2F | |
82 | #define AUTONEG_ADV_MASK 0x2F | |
83 | #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL | |
84 | ||
85 | #define FLASH_VENDOR_DEFAULT 0 | |
86 | #define FLASH_VENDOR_MIN 0 | |
87 | #define FLASH_VENDOR_MAX 2 | |
88 | ||
89 | struct atl1e_option { | |
90 | enum { enable_option, range_option, list_option } type; | |
91 | char *name; | |
92 | char *err; | |
93 | int def; | |
94 | union { | |
95 | struct { /* range_option info */ | |
96 | int min; | |
97 | int max; | |
98 | } r; | |
99 | struct { /* list_option info */ | |
100 | int nr; | |
101 | struct atl1e_opt_list { int i; char *str; } *p; | |
102 | } l; | |
103 | } arg; | |
104 | }; | |
105 | ||
093d369d BP |
106 | static int atl1e_validate_option(int *value, struct atl1e_option *opt, |
107 | struct atl1e_adapter *adapter) | |
a6a53252 JY |
108 | { |
109 | if (*value == OPTION_UNSET) { | |
110 | *value = opt->def; | |
111 | return 0; | |
112 | } | |
113 | ||
114 | switch (opt->type) { | |
115 | case enable_option: | |
116 | switch (*value) { | |
117 | case OPTION_ENABLED: | |
ba211e3e JP |
118 | netdev_info(adapter->netdev, |
119 | "%s Enabled\n", opt->name); | |
a6a53252 JY |
120 | return 0; |
121 | case OPTION_DISABLED: | |
ba211e3e JP |
122 | netdev_info(adapter->netdev, |
123 | "%s Disabled\n", opt->name); | |
a6a53252 JY |
124 | return 0; |
125 | } | |
126 | break; | |
127 | case range_option: | |
128 | if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { | |
ba211e3e JP |
129 | netdev_info(adapter->netdev, "%s set to %i\n", |
130 | opt->name, *value); | |
a6a53252 JY |
131 | return 0; |
132 | } | |
133 | break; | |
134 | case list_option:{ | |
135 | int i; | |
136 | struct atl1e_opt_list *ent; | |
137 | ||
138 | for (i = 0; i < opt->arg.l.nr; i++) { | |
139 | ent = &opt->arg.l.p[i]; | |
140 | if (*value == ent->i) { | |
141 | if (ent->str[0] != '\0') | |
ba211e3e JP |
142 | netdev_info(adapter->netdev, |
143 | "%s\n", ent->str); | |
a6a53252 JY |
144 | return 0; |
145 | } | |
146 | } | |
147 | break; | |
148 | } | |
149 | default: | |
150 | BUG(); | |
151 | } | |
152 | ||
ba211e3e JP |
153 | netdev_info(adapter->netdev, "Invalid %s specified (%i) %s\n", |
154 | opt->name, *value, opt->err); | |
a6a53252 JY |
155 | *value = opt->def; |
156 | return -1; | |
157 | } | |
158 | ||
49ce9c2c | 159 | /** |
a6a53252 JY |
160 | * atl1e_check_options - Range Checking for Command Line Parameters |
161 | * @adapter: board private structure | |
162 | * | |
163 | * This routine checks all command line parameters for valid user | |
164 | * input. If an invalid value is given, or if no user specified | |
165 | * value exists, a default value is used. The final value is stored | |
166 | * in a variable in the adapter structure. | |
167 | */ | |
093d369d | 168 | void atl1e_check_options(struct atl1e_adapter *adapter) |
a6a53252 | 169 | { |
a6a53252 | 170 | int bd = adapter->bd_number; |
ba211e3e | 171 | |
a6a53252 | 172 | if (bd >= ATL1E_MAX_NIC) { |
ba211e3e JP |
173 | netdev_notice(adapter->netdev, |
174 | "no configuration for board #%i\n", bd); | |
175 | netdev_notice(adapter->netdev, | |
176 | "Using defaults for all values\n"); | |
a6a53252 JY |
177 | } |
178 | ||
179 | { /* Transmit Ring Size */ | |
180 | struct atl1e_option opt = { | |
181 | .type = range_option, | |
182 | .name = "Transmit Ddescription Count", | |
183 | .err = "using default of " | |
184 | __MODULE_STRING(ATL1E_DEFAULT_TX_DESC_CNT), | |
185 | .def = ATL1E_DEFAULT_TX_DESC_CNT, | |
186 | .arg = { .r = { .min = ATL1E_MIN_TX_DESC_CNT, | |
187 | .max = ATL1E_MAX_TX_DESC_CNT} } | |
188 | }; | |
189 | int val; | |
190 | if (num_tx_desc_cnt > bd) { | |
191 | val = tx_desc_cnt[bd]; | |
ba211e3e | 192 | atl1e_validate_option(&val, &opt, adapter); |
a6a53252 JY |
193 | adapter->tx_ring.count = (u16) val & 0xFFFC; |
194 | } else | |
195 | adapter->tx_ring.count = (u16)opt.def; | |
196 | } | |
197 | ||
198 | { /* Receive Memory Block Count */ | |
199 | struct atl1e_option opt = { | |
200 | .type = range_option, | |
201 | .name = "Memory size of rx buffer(KB)", | |
202 | .err = "using default of " | |
203 | __MODULE_STRING(ATL1E_DEFAULT_RX_MEM_SIZE), | |
204 | .def = ATL1E_DEFAULT_RX_MEM_SIZE, | |
205 | .arg = { .r = { .min = ATL1E_MIN_RX_MEM_SIZE, | |
206 | .max = ATL1E_MAX_RX_MEM_SIZE} } | |
207 | }; | |
208 | int val; | |
209 | if (num_rx_mem_size > bd) { | |
210 | val = rx_mem_size[bd]; | |
ba211e3e | 211 | atl1e_validate_option(&val, &opt, adapter); |
a6a53252 JY |
212 | adapter->rx_ring.page_size = (u32)val * 1024; |
213 | } else { | |
214 | adapter->rx_ring.page_size = (u32)opt.def * 1024; | |
215 | } | |
216 | } | |
217 | ||
218 | { /* Interrupt Moderate Timer */ | |
219 | struct atl1e_option opt = { | |
220 | .type = range_option, | |
221 | .name = "Interrupt Moderate Timer", | |
222 | .err = "using default of " | |
223 | __MODULE_STRING(INT_MOD_DEFAULT_CNT), | |
224 | .def = INT_MOD_DEFAULT_CNT, | |
225 | .arg = { .r = { .min = INT_MOD_MIN_CNT, | |
226 | .max = INT_MOD_MAX_CNT} } | |
227 | } ; | |
228 | int val; | |
229 | if (num_int_mod_timer > bd) { | |
230 | val = int_mod_timer[bd]; | |
ba211e3e | 231 | atl1e_validate_option(&val, &opt, adapter); |
a6a53252 JY |
232 | adapter->hw.imt = (u16) val; |
233 | } else | |
234 | adapter->hw.imt = (u16)(opt.def); | |
235 | } | |
236 | ||
237 | { /* MediaType */ | |
238 | struct atl1e_option opt = { | |
239 | .type = range_option, | |
240 | .name = "Speed/Duplex Selection", | |
241 | .err = "using default of " | |
242 | __MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR), | |
243 | .def = MEDIA_TYPE_AUTO_SENSOR, | |
244 | .arg = { .r = { .min = MEDIA_TYPE_AUTO_SENSOR, | |
245 | .max = MEDIA_TYPE_10M_HALF} } | |
246 | } ; | |
247 | int val; | |
248 | if (num_media_type > bd) { | |
249 | val = media_type[bd]; | |
ba211e3e | 250 | atl1e_validate_option(&val, &opt, adapter); |
a6a53252 JY |
251 | adapter->hw.media_type = (u16) val; |
252 | } else | |
253 | adapter->hw.media_type = (u16)(opt.def); | |
254 | ||
255 | } | |
256 | } |