1*1a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
22b133ad6SJeff Kirsher /*
32b133ad6SJeff Kirsher * Copyright(c) 2007 Atheros Corporation. All rights reserved.
42b133ad6SJeff Kirsher *
52b133ad6SJeff Kirsher * Derived from Intel e1000 driver
62b133ad6SJeff Kirsher * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
72b133ad6SJeff Kirsher */
82b133ad6SJeff Kirsher
92b133ad6SJeff Kirsher #include <linux/netdevice.h>
102b133ad6SJeff Kirsher
112b133ad6SJeff Kirsher #include "atl1e.h"
122b133ad6SJeff Kirsher
132b133ad6SJeff Kirsher /* This is the only thing that needs to be changed to adjust the
142b133ad6SJeff Kirsher * maximum number of ports that the driver can manage.
152b133ad6SJeff Kirsher */
162b133ad6SJeff Kirsher
172b133ad6SJeff Kirsher #define ATL1E_MAX_NIC 32
182b133ad6SJeff Kirsher
192b133ad6SJeff Kirsher #define OPTION_UNSET -1
202b133ad6SJeff Kirsher #define OPTION_DISABLED 0
212b133ad6SJeff Kirsher #define OPTION_ENABLED 1
222b133ad6SJeff Kirsher
232b133ad6SJeff Kirsher /* All parameters are treated the same, as an integer array of values.
242b133ad6SJeff Kirsher * This macro just reduces the need to repeat the same declaration code
252b133ad6SJeff Kirsher * over and over (plus this helps to avoid typo bugs).
262b133ad6SJeff Kirsher */
272b133ad6SJeff Kirsher #define ATL1E_PARAM_INIT { [0 ... ATL1E_MAX_NIC] = OPTION_UNSET }
282b133ad6SJeff Kirsher
292b133ad6SJeff Kirsher #define ATL1E_PARAM(x, desc) \
30093d369dSBill Pemberton static int x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
312b133ad6SJeff Kirsher static unsigned int num_##x; \
322b133ad6SJeff Kirsher module_param_array_named(x, x, int, &num_##x, 0); \
332b133ad6SJeff Kirsher MODULE_PARM_DESC(x, desc);
342b133ad6SJeff Kirsher
352b133ad6SJeff Kirsher /* Transmit Memory count
362b133ad6SJeff Kirsher *
372b133ad6SJeff Kirsher * Valid Range: 64-2048
382b133ad6SJeff Kirsher *
392b133ad6SJeff Kirsher * Default Value: 128
402b133ad6SJeff Kirsher */
412b133ad6SJeff Kirsher #define ATL1E_MIN_TX_DESC_CNT 32
422b133ad6SJeff Kirsher #define ATL1E_MAX_TX_DESC_CNT 1020
432b133ad6SJeff Kirsher #define ATL1E_DEFAULT_TX_DESC_CNT 128
442b133ad6SJeff Kirsher ATL1E_PARAM(tx_desc_cnt, "Transmit description count");
452b133ad6SJeff Kirsher
462b133ad6SJeff Kirsher /* Receive Memory Block Count
472b133ad6SJeff Kirsher *
482b133ad6SJeff Kirsher * Valid Range: 16-512
492b133ad6SJeff Kirsher *
502b133ad6SJeff Kirsher * Default Value: 128
512b133ad6SJeff Kirsher */
522b133ad6SJeff Kirsher #define ATL1E_MIN_RX_MEM_SIZE 8 /* 8KB */
532b133ad6SJeff Kirsher #define ATL1E_MAX_RX_MEM_SIZE 1024 /* 1MB */
542b133ad6SJeff Kirsher #define ATL1E_DEFAULT_RX_MEM_SIZE 256 /* 128KB */
552b133ad6SJeff Kirsher ATL1E_PARAM(rx_mem_size, "memory size of rx buffer(KB)");
562b133ad6SJeff Kirsher
572b133ad6SJeff Kirsher /* User Specified MediaType Override
582b133ad6SJeff Kirsher *
592b133ad6SJeff Kirsher * Valid Range: 0-5
602b133ad6SJeff Kirsher * - 0 - auto-negotiate at all supported speeds
612b133ad6SJeff Kirsher * - 1 - only link at 100Mbps Full Duplex
622b133ad6SJeff Kirsher * - 2 - only link at 100Mbps Half Duplex
632b133ad6SJeff Kirsher * - 3 - only link at 10Mbps Full Duplex
642b133ad6SJeff Kirsher * - 4 - only link at 10Mbps Half Duplex
652b133ad6SJeff Kirsher * Default Value: 0
662b133ad6SJeff Kirsher */
672b133ad6SJeff Kirsher
682b133ad6SJeff Kirsher ATL1E_PARAM(media_type, "MediaType Select");
692b133ad6SJeff Kirsher
702b133ad6SJeff Kirsher /* Interrupt Moderate Timer in units of 2 us
712b133ad6SJeff Kirsher *
722b133ad6SJeff Kirsher * Valid Range: 10-65535
732b133ad6SJeff Kirsher *
742b133ad6SJeff Kirsher * Default Value: 45000(90ms)
752b133ad6SJeff Kirsher */
762b133ad6SJeff Kirsher #define INT_MOD_DEFAULT_CNT 100 /* 200us */
772b133ad6SJeff Kirsher #define INT_MOD_MAX_CNT 65000
782b133ad6SJeff Kirsher #define INT_MOD_MIN_CNT 50
792b133ad6SJeff Kirsher ATL1E_PARAM(int_mod_timer, "Interrupt Moderator Timer");
802b133ad6SJeff Kirsher
812b133ad6SJeff Kirsher #define AUTONEG_ADV_DEFAULT 0x2F
822b133ad6SJeff Kirsher #define AUTONEG_ADV_MASK 0x2F
832b133ad6SJeff Kirsher #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
842b133ad6SJeff Kirsher
852b133ad6SJeff Kirsher #define FLASH_VENDOR_DEFAULT 0
862b133ad6SJeff Kirsher #define FLASH_VENDOR_MIN 0
872b133ad6SJeff Kirsher #define FLASH_VENDOR_MAX 2
882b133ad6SJeff Kirsher
892b133ad6SJeff Kirsher struct atl1e_option {
902b133ad6SJeff Kirsher enum { enable_option, range_option, list_option } type;
912b133ad6SJeff Kirsher char *name;
922b133ad6SJeff Kirsher char *err;
932b133ad6SJeff Kirsher int def;
942b133ad6SJeff Kirsher union {
952b133ad6SJeff Kirsher struct { /* range_option info */
962b133ad6SJeff Kirsher int min;
972b133ad6SJeff Kirsher int max;
982b133ad6SJeff Kirsher } r;
992b133ad6SJeff Kirsher struct { /* list_option info */
1002b133ad6SJeff Kirsher int nr;
1012b133ad6SJeff Kirsher struct atl1e_opt_list { int i; char *str; } *p;
1022b133ad6SJeff Kirsher } l;
1032b133ad6SJeff Kirsher } arg;
1042b133ad6SJeff Kirsher };
1052b133ad6SJeff Kirsher
atl1e_validate_option(int * value,struct atl1e_option * opt,struct atl1e_adapter * adapter)106093d369dSBill Pemberton static int atl1e_validate_option(int *value, struct atl1e_option *opt,
107093d369dSBill Pemberton struct atl1e_adapter *adapter)
1082b133ad6SJeff Kirsher {
1092b133ad6SJeff Kirsher if (*value == OPTION_UNSET) {
1102b133ad6SJeff Kirsher *value = opt->def;
1112b133ad6SJeff Kirsher return 0;
1122b133ad6SJeff Kirsher }
1132b133ad6SJeff Kirsher
1142b133ad6SJeff Kirsher switch (opt->type) {
1152b133ad6SJeff Kirsher case enable_option:
1162b133ad6SJeff Kirsher switch (*value) {
1172b133ad6SJeff Kirsher case OPTION_ENABLED:
1182b133ad6SJeff Kirsher netdev_info(adapter->netdev,
1192b133ad6SJeff Kirsher "%s Enabled\n", opt->name);
1202b133ad6SJeff Kirsher return 0;
1212b133ad6SJeff Kirsher case OPTION_DISABLED:
1222b133ad6SJeff Kirsher netdev_info(adapter->netdev,
1232b133ad6SJeff Kirsher "%s Disabled\n", opt->name);
1242b133ad6SJeff Kirsher return 0;
1252b133ad6SJeff Kirsher }
1262b133ad6SJeff Kirsher break;
1272b133ad6SJeff Kirsher case range_option:
1282b133ad6SJeff Kirsher if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
1292b133ad6SJeff Kirsher netdev_info(adapter->netdev, "%s set to %i\n",
1302b133ad6SJeff Kirsher opt->name, *value);
1312b133ad6SJeff Kirsher return 0;
1322b133ad6SJeff Kirsher }
1332b133ad6SJeff Kirsher break;
1342b133ad6SJeff Kirsher case list_option:{
1352b133ad6SJeff Kirsher int i;
1362b133ad6SJeff Kirsher struct atl1e_opt_list *ent;
1372b133ad6SJeff Kirsher
1382b133ad6SJeff Kirsher for (i = 0; i < opt->arg.l.nr; i++) {
1392b133ad6SJeff Kirsher ent = &opt->arg.l.p[i];
1402b133ad6SJeff Kirsher if (*value == ent->i) {
1412b133ad6SJeff Kirsher if (ent->str[0] != '\0')
1422b133ad6SJeff Kirsher netdev_info(adapter->netdev,
1432b133ad6SJeff Kirsher "%s\n", ent->str);
1442b133ad6SJeff Kirsher return 0;
1452b133ad6SJeff Kirsher }
1462b133ad6SJeff Kirsher }
1472b133ad6SJeff Kirsher break;
1482b133ad6SJeff Kirsher }
1492b133ad6SJeff Kirsher default:
1502b133ad6SJeff Kirsher BUG();
1512b133ad6SJeff Kirsher }
1522b133ad6SJeff Kirsher
1532b133ad6SJeff Kirsher netdev_info(adapter->netdev, "Invalid %s specified (%i) %s\n",
1542b133ad6SJeff Kirsher opt->name, *value, opt->err);
1552b133ad6SJeff Kirsher *value = opt->def;
1562b133ad6SJeff Kirsher return -1;
1572b133ad6SJeff Kirsher }
1582b133ad6SJeff Kirsher
15949ce9c2cSBen Hutchings /**
1602b133ad6SJeff Kirsher * atl1e_check_options - Range Checking for Command Line Parameters
1612b133ad6SJeff Kirsher * @adapter: board private structure
1622b133ad6SJeff Kirsher *
1632b133ad6SJeff Kirsher * This routine checks all command line parameters for valid user
1642b133ad6SJeff Kirsher * input. If an invalid value is given, or if no user specified
1652b133ad6SJeff Kirsher * value exists, a default value is used. The final value is stored
1662b133ad6SJeff Kirsher * in a variable in the adapter structure.
1672b133ad6SJeff Kirsher */
atl1e_check_options(struct atl1e_adapter * adapter)168093d369dSBill Pemberton void atl1e_check_options(struct atl1e_adapter *adapter)
1692b133ad6SJeff Kirsher {
1702b133ad6SJeff Kirsher int bd = adapter->bd_number;
1712b133ad6SJeff Kirsher
1722b133ad6SJeff Kirsher if (bd >= ATL1E_MAX_NIC) {
1732b133ad6SJeff Kirsher netdev_notice(adapter->netdev,
1742b133ad6SJeff Kirsher "no configuration for board #%i\n", bd);
1752b133ad6SJeff Kirsher netdev_notice(adapter->netdev,
1762b133ad6SJeff Kirsher "Using defaults for all values\n");
1772b133ad6SJeff Kirsher }
1782b133ad6SJeff Kirsher
1792b133ad6SJeff Kirsher { /* Transmit Ring Size */
1802b133ad6SJeff Kirsher struct atl1e_option opt = {
1812b133ad6SJeff Kirsher .type = range_option,
1822b133ad6SJeff Kirsher .name = "Transmit Ddescription Count",
1832b133ad6SJeff Kirsher .err = "using default of "
1842b133ad6SJeff Kirsher __MODULE_STRING(ATL1E_DEFAULT_TX_DESC_CNT),
1852b133ad6SJeff Kirsher .def = ATL1E_DEFAULT_TX_DESC_CNT,
1862b133ad6SJeff Kirsher .arg = { .r = { .min = ATL1E_MIN_TX_DESC_CNT,
1872b133ad6SJeff Kirsher .max = ATL1E_MAX_TX_DESC_CNT} }
1882b133ad6SJeff Kirsher };
1892b133ad6SJeff Kirsher int val;
1902b133ad6SJeff Kirsher if (num_tx_desc_cnt > bd) {
1912b133ad6SJeff Kirsher val = tx_desc_cnt[bd];
1922b133ad6SJeff Kirsher atl1e_validate_option(&val, &opt, adapter);
1932b133ad6SJeff Kirsher adapter->tx_ring.count = (u16) val & 0xFFFC;
1942b133ad6SJeff Kirsher } else
1952b133ad6SJeff Kirsher adapter->tx_ring.count = (u16)opt.def;
1962b133ad6SJeff Kirsher }
1972b133ad6SJeff Kirsher
1982b133ad6SJeff Kirsher { /* Receive Memory Block Count */
1992b133ad6SJeff Kirsher struct atl1e_option opt = {
2002b133ad6SJeff Kirsher .type = range_option,
2012b133ad6SJeff Kirsher .name = "Memory size of rx buffer(KB)",
2022b133ad6SJeff Kirsher .err = "using default of "
2032b133ad6SJeff Kirsher __MODULE_STRING(ATL1E_DEFAULT_RX_MEM_SIZE),
2042b133ad6SJeff Kirsher .def = ATL1E_DEFAULT_RX_MEM_SIZE,
2052b133ad6SJeff Kirsher .arg = { .r = { .min = ATL1E_MIN_RX_MEM_SIZE,
2062b133ad6SJeff Kirsher .max = ATL1E_MAX_RX_MEM_SIZE} }
2072b133ad6SJeff Kirsher };
2082b133ad6SJeff Kirsher int val;
2092b133ad6SJeff Kirsher if (num_rx_mem_size > bd) {
2102b133ad6SJeff Kirsher val = rx_mem_size[bd];
2112b133ad6SJeff Kirsher atl1e_validate_option(&val, &opt, adapter);
2122b133ad6SJeff Kirsher adapter->rx_ring.page_size = (u32)val * 1024;
2132b133ad6SJeff Kirsher } else {
2142b133ad6SJeff Kirsher adapter->rx_ring.page_size = (u32)opt.def * 1024;
2152b133ad6SJeff Kirsher }
2162b133ad6SJeff Kirsher }
2172b133ad6SJeff Kirsher
2182b133ad6SJeff Kirsher { /* Interrupt Moderate Timer */
2192b133ad6SJeff Kirsher struct atl1e_option opt = {
2202b133ad6SJeff Kirsher .type = range_option,
2212b133ad6SJeff Kirsher .name = "Interrupt Moderate Timer",
2222b133ad6SJeff Kirsher .err = "using default of "
2232b133ad6SJeff Kirsher __MODULE_STRING(INT_MOD_DEFAULT_CNT),
2242b133ad6SJeff Kirsher .def = INT_MOD_DEFAULT_CNT,
2252b133ad6SJeff Kirsher .arg = { .r = { .min = INT_MOD_MIN_CNT,
2262b133ad6SJeff Kirsher .max = INT_MOD_MAX_CNT} }
2272b133ad6SJeff Kirsher } ;
2282b133ad6SJeff Kirsher int val;
2292b133ad6SJeff Kirsher if (num_int_mod_timer > bd) {
2302b133ad6SJeff Kirsher val = int_mod_timer[bd];
2312b133ad6SJeff Kirsher atl1e_validate_option(&val, &opt, adapter);
2322b133ad6SJeff Kirsher adapter->hw.imt = (u16) val;
2332b133ad6SJeff Kirsher } else
2342b133ad6SJeff Kirsher adapter->hw.imt = (u16)(opt.def);
2352b133ad6SJeff Kirsher }
2362b133ad6SJeff Kirsher
2372b133ad6SJeff Kirsher { /* MediaType */
2382b133ad6SJeff Kirsher struct atl1e_option opt = {
2392b133ad6SJeff Kirsher .type = range_option,
2402b133ad6SJeff Kirsher .name = "Speed/Duplex Selection",
2412b133ad6SJeff Kirsher .err = "using default of "
2422b133ad6SJeff Kirsher __MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR),
2432b133ad6SJeff Kirsher .def = MEDIA_TYPE_AUTO_SENSOR,
2442b133ad6SJeff Kirsher .arg = { .r = { .min = MEDIA_TYPE_AUTO_SENSOR,
2452b133ad6SJeff Kirsher .max = MEDIA_TYPE_10M_HALF} }
2462b133ad6SJeff Kirsher } ;
2472b133ad6SJeff Kirsher int val;
2482b133ad6SJeff Kirsher if (num_media_type > bd) {
2492b133ad6SJeff Kirsher val = media_type[bd];
2502b133ad6SJeff Kirsher atl1e_validate_option(&val, &opt, adapter);
2512b133ad6SJeff Kirsher adapter->hw.media_type = (u16) val;
2522b133ad6SJeff Kirsher } else
2532b133ad6SJeff Kirsher adapter->hw.media_type = (u16)(opt.def);
2542b133ad6SJeff Kirsher
2552b133ad6SJeff Kirsher }
2562b133ad6SJeff Kirsher }
257