Skip to content

Commit

Permalink
Merge branch 'upstream-davem' of master.kernel.org:/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/jgarzik/netdev-2.6
  • Loading branch information
David S. Miller committed Apr 25, 2008
2 parents 461e6c8 + f946dff commit cc93d7d
Show file tree
Hide file tree
Showing 55 changed files with 1,290 additions and 671 deletions.
38 changes: 37 additions & 1 deletion Documentation/networking/phy.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

-------
PHY Abstraction Layer
(Updated 2006-11-30)
(Updated 2008-04-08)

Purpose

Expand Down Expand Up @@ -291,3 +291,39 @@ Writing a PHY driver
Feel free to look at the Marvell, Cicada, and Davicom drivers in
drivers/net/phy/ for examples (the lxt and qsemi drivers have
not been tested as of this writing)

Board Fixups

Sometimes the specific interaction between the platform and the PHY requires
special handling. For instance, to change where the PHY's clock input is,
or to add a delay to account for latency issues in the data path. In order
to support such contingencies, the PHY Layer allows platform code to register
fixups to be run when the PHY is brought up (or subsequently reset).

When the PHY Layer brings up a PHY it checks to see if there are any fixups
registered for it, matching based on UID (contained in the PHY device's phy_id
field) and the bus identifier (contained in phydev->dev.bus_id). Both must
match, however two constants, PHY_ANY_ID and PHY_ANY_UID, are provided as
wildcards for the bus ID and UID, respectively.

When a match is found, the PHY layer will invoke the run function associated
with the fixup. This function is passed a pointer to the phy_device of
interest. It should therefore only operate on that PHY.

The platform code can either register the fixup using phy_register_fixup():

int phy_register_fixup(const char *phy_id,
u32 phy_uid, u32 phy_uid_mask,
int (*run)(struct phy_device *));

Or using one of the two stubs, phy_register_fixup_for_uid() and
phy_register_fixup_for_id():

int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
int (*run)(struct phy_device *));
int phy_register_fixup_for_id(const char *phy_id,
int (*run)(struct phy_device *));

The stubs set one of the two matching criteria, and set the other one to
match anything.

1 change: 1 addition & 0 deletions drivers/net/arm/at91_ether.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,3 +1246,4 @@ module_exit(at91ether_exit)
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver");
MODULE_AUTHOR("Andrew Victor");
MODULE_ALIAS("platform:" DRV_NAME);
2 changes: 2 additions & 0 deletions drivers/net/arm/ep93xx_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,7 @@ static struct platform_driver ep93xx_eth_driver = {
.remove = ep93xx_eth_remove,
.driver = {
.name = "ep93xx-eth",
.owner = THIS_MODULE,
},
};

Expand All @@ -914,3 +915,4 @@ static void __exit ep93xx_eth_cleanup_module(void)
module_init(ep93xx_eth_init_module);
module_exit(ep93xx_eth_cleanup_module);
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ep93xx-eth");
138 changes: 138 additions & 0 deletions drivers/net/atlx/atl1.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,144 @@
/* Temporary hack for merging atl1 and atl2 */
#include "atlx.c"

/*
* This is the only thing that needs to be changed to adjust the
* maximum number of ports that the driver can manage.
*/
#define ATL1_MAX_NIC 4

#define OPTION_UNSET -1
#define OPTION_DISABLED 0
#define OPTION_ENABLED 1

#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET }

/*
* Interrupt Moderate Timer in units of 2 us
*
* Valid Range: 10-65535
*
* Default Value: 100 (200us)
*/
static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
static int num_int_mod_timer;
module_param_array_named(int_mod_timer, int_mod_timer, int,
&num_int_mod_timer, 0);
MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");

#define DEFAULT_INT_MOD_CNT 100 /* 200us */
#define MAX_INT_MOD_CNT 65000
#define MIN_INT_MOD_CNT 50

struct atl1_option {
enum { enable_option, range_option, list_option } type;
char *name;
char *err;
int def;
union {
struct { /* range_option info */
int min;
int max;
} r;
struct { /* list_option info */
int nr;
struct atl1_opt_list {
int i;
char *str;
} *p;
} l;
} arg;
};

static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
struct pci_dev *pdev)
{
if (*value == OPTION_UNSET) {
*value = opt->def;
return 0;
}

switch (opt->type) {
case enable_option:
switch (*value) {
case OPTION_ENABLED:
dev_info(&pdev->dev, "%s enabled\n", opt->name);
return 0;
case OPTION_DISABLED:
dev_info(&pdev->dev, "%s disabled\n", opt->name);
return 0;
}
break;
case range_option:
if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
dev_info(&pdev->dev, "%s set to %i\n", opt->name,
*value);
return 0;
}
break;
case list_option:{
int i;
struct atl1_opt_list *ent;

for (i = 0; i < opt->arg.l.nr; i++) {
ent = &opt->arg.l.p[i];
if (*value == ent->i) {
if (ent->str[0] != '\0')
dev_info(&pdev->dev, "%s\n",
ent->str);
return 0;
}
}
}
break;

default:
break;
}

dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
opt->name, *value, opt->err);
*value = opt->def;
return -1;
}

/*
* atl1_check_options - Range Checking for Command Line Parameters
* @adapter: board private structure
*
* This routine checks all command line parameters for valid user
* input. If an invalid value is given, or if no user specified
* value exists, a default value is used. The final value is stored
* in a variable in the adapter structure.
*/
void __devinit atl1_check_options(struct atl1_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
int bd = adapter->bd_number;
if (bd >= ATL1_MAX_NIC) {
dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
dev_notice(&pdev->dev, "using defaults for all values\n");
}
{ /* Interrupt Moderate Timer */
struct atl1_option opt = {
.type = range_option,
.name = "Interrupt Moderator Timer",
.err = "using default of "
__MODULE_STRING(DEFAULT_INT_MOD_CNT),
.def = DEFAULT_INT_MOD_CNT,
.arg = {.r = {.min = MIN_INT_MOD_CNT,
.max = MAX_INT_MOD_CNT} }
};
int val;
if (num_int_mod_timer > bd) {
val = int_mod_timer[bd];
atl1_validate_option(&val, &opt, pdev);
adapter->imt = (u16) val;
} else
adapter->imt = (u16) (opt.def);
}
}

/*
* atl1_pci_tbl - PCI Device ID Table
*/
Expand Down
177 changes: 0 additions & 177 deletions drivers/net/atlx/atlx.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,181 +253,4 @@ static void atlx_restore_vlan(struct atlx_adapter *adapter)
atlx_vlan_rx_register(adapter->netdev, adapter->vlgrp);
}

/*
* This is the only thing that needs to be changed to adjust the
* maximum number of ports that the driver can manage.
*/
#define ATL1_MAX_NIC 4

#define OPTION_UNSET -1
#define OPTION_DISABLED 0
#define OPTION_ENABLED 1

#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET }

/*
* Interrupt Moderate Timer in units of 2 us
*
* Valid Range: 10-65535
*
* Default Value: 100 (200us)
*/
static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
static int num_int_mod_timer;
module_param_array_named(int_mod_timer, int_mod_timer, int,
&num_int_mod_timer, 0);
MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");

/*
* flash_vendor
*
* Valid Range: 0-2
*
* 0 - Atmel
* 1 - SST
* 2 - ST
*
* Default Value: 0
*/
static int __devinitdata flash_vendor[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
static int num_flash_vendor;
module_param_array_named(flash_vendor, flash_vendor, int, &num_flash_vendor, 0);
MODULE_PARM_DESC(flash_vendor, "SPI flash vendor");

#define DEFAULT_INT_MOD_CNT 100 /* 200us */
#define MAX_INT_MOD_CNT 65000
#define MIN_INT_MOD_CNT 50

#define FLASH_VENDOR_DEFAULT 0
#define FLASH_VENDOR_MIN 0
#define FLASH_VENDOR_MAX 2

struct atl1_option {
enum { enable_option, range_option, list_option } type;
char *name;
char *err;
int def;
union {
struct { /* range_option info */
int min;
int max;
} r;
struct { /* list_option info */
int nr;
struct atl1_opt_list {
int i;
char *str;
} *p;
} l;
} arg;
};

static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
struct pci_dev *pdev)
{
if (*value == OPTION_UNSET) {
*value = opt->def;
return 0;
}

switch (opt->type) {
case enable_option:
switch (*value) {
case OPTION_ENABLED:
dev_info(&pdev->dev, "%s enabled\n", opt->name);
return 0;
case OPTION_DISABLED:
dev_info(&pdev->dev, "%s disabled\n", opt->name);
return 0;
}
break;
case range_option:
if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
dev_info(&pdev->dev, "%s set to %i\n", opt->name,
*value);
return 0;
}
break;
case list_option:{
int i;
struct atl1_opt_list *ent;

for (i = 0; i < opt->arg.l.nr; i++) {
ent = &opt->arg.l.p[i];
if (*value == ent->i) {
if (ent->str[0] != '\0')
dev_info(&pdev->dev, "%s\n",
ent->str);
return 0;
}
}
}
break;

default:
break;
}

dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
opt->name, *value, opt->err);
*value = opt->def;
return -1;
}

/*
* atl1_check_options - Range Checking for Command Line Parameters
* @adapter: board private structure
*
* This routine checks all command line parameters for valid user
* input. If an invalid value is given, or if no user specified
* value exists, a default value is used. The final value is stored
* in a variable in the adapter structure.
*/
void __devinit atl1_check_options(struct atl1_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
int bd = adapter->bd_number;
if (bd >= ATL1_MAX_NIC) {
dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
dev_notice(&pdev->dev, "using defaults for all values\n");
}
{ /* Interrupt Moderate Timer */
struct atl1_option opt = {
.type = range_option,
.name = "Interrupt Moderator Timer",
.err = "using default of "
__MODULE_STRING(DEFAULT_INT_MOD_CNT),
.def = DEFAULT_INT_MOD_CNT,
.arg = {.r = {.min = MIN_INT_MOD_CNT,
.max = MAX_INT_MOD_CNT} }
};
int val;
if (num_int_mod_timer > bd) {
val = int_mod_timer[bd];
atl1_validate_option(&val, &opt, pdev);
adapter->imt = (u16) val;
} else
adapter->imt = (u16) (opt.def);
}

{ /* Flash Vendor */
struct atl1_option opt = {
.type = range_option,
.name = "SPI Flash Vendor",
.err = "using default of "
__MODULE_STRING(FLASH_VENDOR_DEFAULT),
.def = DEFAULT_INT_MOD_CNT,
.arg = {.r = {.min = FLASH_VENDOR_MIN,
.max = FLASH_VENDOR_MAX} }
};
int val;
if (num_flash_vendor > bd) {
val = flash_vendor[bd];
atl1_validate_option(&val, &opt, pdev);
adapter->hw.flash_vendor = (u8) val;
} else
adapter->hw.flash_vendor = (u8) (opt.def);
}
}

#endif /* ATLX_C */
1 change: 1 addition & 0 deletions drivers/net/ax88796.c
Original file line number Diff line number Diff line change
Expand Up @@ -1005,3 +1005,4 @@ module_exit(axdrv_exit);
MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:ax88796");
Loading

0 comments on commit cc93d7d

Please sign in to comment.