aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/acenic.c4
-rw-r--r--drivers/net/bonding/bond_3ad.c70
-rw-r--r--drivers/net/bonding/bond_main.c228
-rw-r--r--drivers/net/bonding/bond_sysfs.c56
-rw-r--r--drivers/net/bonding/bonding.h34
-rw-r--r--drivers/net/e1000/e1000_hw.h4
-rw-r--r--drivers/net/forcedeth.c8
-rw-r--r--drivers/net/gt64240eth.h402
-rw-r--r--drivers/net/phy/phy_device.c2
-rw-r--r--drivers/net/s2io.c10
-rw-r--r--drivers/net/skge.c357
-rw-r--r--drivers/net/skge.h37
-rw-r--r--drivers/net/smc91x.h18
-rw-r--r--drivers/net/tokenring/lanstreamer.c59
-rw-r--r--drivers/net/tokenring/lanstreamer.h12
-rw-r--r--drivers/net/typhoon.c4
-rw-r--r--drivers/net/wireless/airo.c19
-rw-r--r--drivers/net/wireless/atmel.c18
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h1
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c10
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c15
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.c5
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c10
-rw-r--r--drivers/net/wireless/ipw2100.c14
-rw-r--r--drivers/net/wireless/ipw2200.c16
-rw-r--r--drivers/net/wireless/orinoco.c10
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c16
-rw-r--r--drivers/net/wireless/ray_cs.c2
-rw-r--r--drivers/net/wireless/wl3501_cs.c6
-rw-r--r--drivers/net/wireless/zd1201.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c137
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h23
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c50
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_netdev.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c10
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h2
38 files changed, 860 insertions, 820 deletions
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index a075246f6f4..71a4f60f732 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -163,11 +163,7 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
#define SET_NETDEV_DEV(net, pdev) do{} while(0)
#endif
-#if LINUX_VERSION_CODE >= 0x2051c
#define ace_sync_irq(irq) synchronize_irq(irq)
-#else
-#define ace_sync_irq(irq) synchronize_irq()
-#endif
#ifndef offset_in_page
#define offset_in_page(ptr) ((unsigned long)(ptr) & ~PAGE_MASK)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 6a407070c2e..3fb354d9c51 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -85,6 +85,7 @@
#define AD_LINK_SPEED_BITMASK_10MBPS 0x2
#define AD_LINK_SPEED_BITMASK_100MBPS 0x4
#define AD_LINK_SPEED_BITMASK_1000MBPS 0x8
+#define AD_LINK_SPEED_BITMASK_10000MBPS 0x10
//endalloun
// compare MAC addresses
@@ -99,7 +100,7 @@ static u16 __get_link_speed(struct port *port);
static u8 __get_duplex(struct port *port);
static inline void __initialize_port_locks(struct port *port);
//conversions
-static void __ntohs_lacpdu(struct lacpdu *lacpdu);
+static void __htons_lacpdu(struct lacpdu *lacpdu);
static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par);
@@ -330,7 +331,8 @@ static inline void __release_rx_machine_lock(struct port *port)
* 0,
* %AD_LINK_SPEED_BITMASK_10MBPS,
* %AD_LINK_SPEED_BITMASK_100MBPS,
- * %AD_LINK_SPEED_BITMASK_1000MBPS
+ * %AD_LINK_SPEED_BITMASK_1000MBPS,
+ * %AD_LINK_SPEED_BITMASK_10000MBPS
*/
static u16 __get_link_speed(struct port *port)
{
@@ -357,6 +359,10 @@ static u16 __get_link_speed(struct port *port)
speed = AD_LINK_SPEED_BITMASK_1000MBPS;
break;
+ case SPEED_10000:
+ speed = AD_LINK_SPEED_BITMASK_10000MBPS;
+ break;
+
default:
speed = 0; // unknown speed value from ethtool. shouldn't happen
break;
@@ -414,23 +420,23 @@ static inline void __initialize_port_locks(struct port *port)
//conversions
/**
- * __ntohs_lacpdu - convert the contents of a LACPDU to host byte order
+ * __htons_lacpdu - convert the contents of a LACPDU to network byte order
* @lacpdu: the speicifed lacpdu
*
* For each multi-byte field in the lacpdu, convert its content
*/
-static void __ntohs_lacpdu(struct lacpdu *lacpdu)
+static void __htons_lacpdu(struct lacpdu *lacpdu)
{
if (lacpdu) {
- lacpdu->actor_system_priority = ntohs(lacpdu->actor_system_priority);
- lacpdu->actor_key = ntohs(lacpdu->actor_key);
- lacpdu->actor_port_priority = ntohs(lacpdu->actor_port_priority);
- lacpdu->actor_port = ntohs(lacpdu->actor_port);
- lacpdu->partner_system_priority = ntohs(lacpdu->partner_system_priority);
- lacpdu->partner_key = ntohs(lacpdu->partner_key);
- lacpdu->partner_port_priority = ntohs(lacpdu->partner_port_priority);
- lacpdu->partner_port = ntohs(lacpdu->partner_port);
- lacpdu->collector_max_delay = ntohs(lacpdu->collector_max_delay);
+ lacpdu->actor_system_priority = htons(lacpdu->actor_system_priority);
+ lacpdu->actor_key = htons(lacpdu->actor_key);
+ lacpdu->actor_port_priority = htons(lacpdu->actor_port_priority);
+ lacpdu->actor_port = htons(lacpdu->actor_port);
+ lacpdu->partner_system_priority = htons(lacpdu->partner_system_priority);
+ lacpdu->partner_key = htons(lacpdu->partner_key);
+ lacpdu->partner_port_priority = htons(lacpdu->partner_port_priority);
+ lacpdu->partner_port = htons(lacpdu->partner_port);
+ lacpdu->collector_max_delay = htons(lacpdu->collector_max_delay);
}
}
@@ -490,11 +496,11 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port)
// validate lacpdu and port
if (lacpdu && port) {
// record the new parameter values for the partner operational
- port->partner_oper_port_number = lacpdu->actor_port;
- port->partner_oper_port_priority = lacpdu->actor_port_priority;
+ port->partner_oper_port_number = ntohs(lacpdu->actor_port);
+ port->partner_oper_port_priority = ntohs(lacpdu->actor_port_priority);
port->partner_oper_system = lacpdu->actor_system;
- port->partner_oper_system_priority = lacpdu->actor_system_priority;
- port->partner_oper_key = lacpdu->actor_key;
+ port->partner_oper_system_priority = ntohs(lacpdu->actor_system_priority);
+ port->partner_oper_key = ntohs(lacpdu->actor_key);
// zero partener's lase states
port->partner_oper_port_state = 0;
port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY);
@@ -561,11 +567,11 @@ static void __update_selected(struct lacpdu *lacpdu, struct port *port)
// validate lacpdu and port
if (lacpdu && port) {
// check if any parameter is different
- if ((lacpdu->actor_port != port->partner_oper_port_number) ||
- (lacpdu->actor_port_priority != port->partner_oper_port_priority) ||
+ if ((ntohs(lacpdu->actor_port) != port->partner_oper_port_number) ||
+ (ntohs(lacpdu->actor_port_priority) != port->partner_oper_port_priority) ||
MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) ||
- (lacpdu->actor_system_priority != port->partner_oper_system_priority) ||
- (lacpdu->actor_key != port->partner_oper_key) ||
+ (ntohs(lacpdu->actor_system_priority) != port->partner_oper_system_priority) ||
+ (ntohs(lacpdu->actor_key) != port->partner_oper_key) ||
((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION))
) {
// update the state machine Selected variable
@@ -628,11 +634,11 @@ static void __choose_matched(struct lacpdu *lacpdu, struct port *port)
// validate lacpdu and port
if (lacpdu && port) {
// check if all parameters are alike
- if (((lacpdu->partner_port == port->actor_port_number) &&
- (lacpdu->partner_port_priority == port->actor_port_priority) &&
+ if (((ntohs(lacpdu->partner_port) == port->actor_port_number) &&
+ (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) &&
!MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) &&
- (lacpdu->partner_system_priority == port->actor_system_priority) &&
- (lacpdu->partner_key == port->actor_oper_port_key) &&
+ (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) &&
+ (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) &&
((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) ||
// or this is individual link(aggregation == FALSE)
((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0)
@@ -662,11 +668,11 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
// validate lacpdu and port
if (lacpdu && port) {
// check if any parameter is different
- if ((lacpdu->partner_port != port->actor_port_number) ||
- (lacpdu->partner_port_priority != port->actor_port_priority) ||
+ if ((ntohs(lacpdu->partner_port) != port->actor_port_number) ||
+ (ntohs(lacpdu->partner_port_priority) != port->actor_port_priority) ||
MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) ||
- (lacpdu->partner_system_priority != port->actor_system_priority) ||
- (lacpdu->partner_key != port->actor_oper_port_key) ||
+ (ntohs(lacpdu->partner_system_priority) != port->actor_system_priority) ||
+ (ntohs(lacpdu->partner_key) != port->actor_oper_port_key) ||
((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) ||
((lacpdu->partner_state & AD_STATE_LACP_TIMEOUT) != (port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)) ||
((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) ||
@@ -775,6 +781,9 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
case AD_LINK_SPEED_BITMASK_1000MBPS:
bandwidth = aggregator->num_of_ports * 1000;
break;
+ case AD_LINK_SPEED_BITMASK_10000MBPS:
+ bandwidth = aggregator->num_of_ports * 10000;
+ break;
default:
bandwidth=0; // to silent the compilor ....
}
@@ -847,7 +856,7 @@ static inline void __update_lacpdu_from_port(struct port *port)
*/
/* Convert all non u8 parameters to Big Endian for transmit */
- __ntohs_lacpdu(lacpdu);
+ __htons_lacpdu(lacpdu);
}
//////////////////////////////////////////////////////////////////////////////////////
@@ -2171,7 +2180,6 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
switch (lacpdu->subtype) {
case AD_TYPE_LACPDU:
- __ntohs_lacpdu(lacpdu);
dprintk("Received LACPDU on port %d\n", port->actor_port_number);
ad_rx_machine(lacpdu, port);
break;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 850aae21a2f..0fb5f653d3c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -96,6 +96,7 @@ static char *lacp_rate = NULL;
static char *xmit_hash_policy = NULL;
static int arp_interval = BOND_LINK_ARP_INTERV;
static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
+static char *arp_validate = NULL;
struct bond_params bonding_defaults;
module_param(max_bonds, int, 0);
@@ -127,6 +128,8 @@ module_param(arp_interval, int, 0);
MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
module_param_array(arp_ip_target, charp, NULL, 0);
MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
+module_param(arp_validate, charp, 0);
+MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
/*----------------------------- Global variables ----------------------------*/
@@ -170,6 +173,14 @@ struct bond_parm_tbl xmit_hashtype_tbl[] = {
{ NULL, -1},
};
+struct bond_parm_tbl arp_validate_tbl[] = {
+{ "none", BOND_ARP_VALIDATE_NONE},
+{ "active", BOND_ARP_VALIDATE_ACTIVE},
+{ "backup", BOND_ARP_VALIDATE_BACKUP},
+{ "all", BOND_ARP_VALIDATE_ALL},
+{ NULL, -1},
+};
+
/*-------------------------- Forward declarations ---------------------------*/
static void bond_send_gratuitous_arp(struct bonding *bond);
@@ -638,6 +649,7 @@ verify:
case SPEED_10:
case SPEED_100:
case SPEED_1000:
+ case SPEED_10000:
break;
default:
return -1;
@@ -1210,10 +1222,14 @@ static int bond_compute_features(struct bonding *bond)
unsigned long features = BOND_INTERSECT_FEATURES;
struct slave *slave;
struct net_device *bond_dev = bond->dev;
+ unsigned short max_hard_header_len = ETH_HLEN;
int i;
- bond_for_each_slave(bond, slave, i)
+ bond_for_each_slave(bond, slave, i) {
features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
+ if (slave->dev->hard_header_len > max_hard_header_len)
+ max_hard_header_len = slave->dev->hard_header_len;
+ }
if ((features & NETIF_F_SG) &&
!(features & NETIF_F_ALL_CSUM))
@@ -1231,6 +1247,7 @@ static int bond_compute_features(struct bonding *bond)
features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
bond_dev->features = features;
+ bond_dev->hard_header_len = max_hard_header_len;
return 0;
}
@@ -1365,6 +1382,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
}
new_slave->dev = slave_dev;
+ slave_dev->priv_flags |= IFF_BONDING;
if ((bond->params.mode == BOND_MODE_TLB) ||
(bond->params.mode == BOND_MODE_ALB)) {
@@ -1417,6 +1435,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
bond_compute_features(bond);
+ new_slave->last_arp_rx = jiffies;
+
if (bond->params.miimon && !bond->params.use_carrier) {
link_reporting = bond_check_dev_link(bond, slave_dev, 1);
@@ -1493,29 +1513,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
switch (bond->params.mode) {
case BOND_MODE_ACTIVEBACKUP:
- /* if we're in active-backup mode, we need one and
- * only one active interface. The backup interfaces
- * will have their SLAVE_INACTIVE flag set because we
- * need them to be drop all packets. Thus, since we
- * guarantee that curr_active_slave always point to
- * the last usable interface, we just have to verify
- * this interface's flag.
- */
- if (((!bond->curr_active_slave) ||
- (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) &&
- (new_slave->link != BOND_LINK_DOWN)) {
- /* first slave or no active slave yet, and this link
- is OK, so make this interface the active one */
- bond_change_active_slave(bond, new_slave);
- printk(KERN_INFO DRV_NAME
- ": %s: first active interface up!\n",
- bond->dev->name);
- netif_carrier_on(bond->dev);
-
- } else {
- dprintk("This is just a backup slave\n");
- bond_set_slave_inactive_flags(new_slave);
- }
+ bond_set_slave_inactive_flags(new_slave);
+ bond_select_active_slave(bond);
break;
case BOND_MODE_8023AD:
/* in 802.3ad mode, the internal mechanism
@@ -1778,7 +1777,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
dev_set_mac_address(slave_dev, &addr);
slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
- IFF_SLAVE_INACTIVE);
+ IFF_SLAVE_INACTIVE | IFF_BONDING |
+ IFF_SLAVE_NEEDARP);
kfree(slave);
@@ -2291,6 +2291,25 @@ static int bond_has_ip(struct bonding *bond)
return 0;
}
+static int bond_has_this_ip(struct bonding *bond, u32 ip)
+{
+ struct vlan_entry *vlan, *vlan_next;
+
+ if (ip == bond->master_ip)
+ return 1;
+
+ if (list_empty(&bond->vlan_list))
+ return 0;
+
+ list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
+ vlan_list) {
+ if (ip == vlan->vlan_ip)
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* We go to the (large) trouble of VLAN tagging ARP frames because
* switches in VLAN mode (especially if ports are configured as
@@ -2429,6 +2448,93 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
}
}
+static void bond_validate_arp(struct bonding *bond, struct slave *slave, u32 sip, u32 tip)
+{
+ int i;
+ u32 *targets = bond->params.arp_targets;
+
+ targets = bond->params.arp_targets;
+ for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
+ dprintk("bva: sip %u.%u.%u.%u tip %u.%u.%u.%u t[%d] "
+ "%u.%u.%u.%u bhti(tip) %d\n",
+ NIPQUAD(sip), NIPQUAD(tip), i, NIPQUAD(targets[i]),
+ bond_has_this_ip(bond, tip));
+ if (sip == targets[i]) {
+ if (bond_has_this_ip(bond, tip))
+ slave->last_arp_rx = jiffies;
+ return;
+ }
+ }
+}
+
+static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
+{
+ struct arphdr *arp;
+ struct slave *slave;
+ struct bonding *bond;
+ unsigned char *arp_ptr;
+ u32 sip, tip;
+
+ if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
+ goto out;
+
+ bond = dev->priv;
+ read_lock(&bond->lock);
+
+ dprintk("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n",
+ bond->dev->name, skb->dev ? skb->dev->name : "NULL",
+ orig_dev ? orig_dev->name : "NULL");
+
+ slave = bond_get_slave_by_dev(bond, orig_dev);
+ if (!slave || !slave_do_arp_validate(bond, slave))
+ goto out_unlock;
+
+ /* ARP header, plus 2 device addresses, plus 2 IP addresses. */
+ if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
+ (2 * dev->addr_len) +
+ (2 * sizeof(u32)))))
+ goto out_unlock;
+
+ arp = skb->nh.arph;
+ if (arp->ar_hln != dev->addr_len ||
+ skb->pkt_type == PACKET_OTHERHOST ||
+ skb->pkt_type == PACKET_LOOPBACK ||
+ arp->ar_hrd != htons(ARPHRD_ETHER) ||
+ arp->ar_pro != htons(ETH_P_IP) ||
+ arp->ar_pln != 4)
+ goto out_unlock;
+
+ arp_ptr = (unsigned char *)(arp + 1);
+ arp_ptr += dev->addr_len;
+ memcpy(&sip, arp_ptr, 4);
+ arp_ptr += 4 + dev->addr_len;
+ memcpy(&tip, arp_ptr, 4);
+
+ dprintk("bond_arp_rcv: %s %s/%d av %d sv %d sip %u.%u.%u.%u"
+ " tip %u.%u.%u.%u\n", bond->dev->name, slave->dev->name,
+ slave->state, bond->params.arp_validate,
+ slave_do_arp_validate(bond, slave), NIPQUAD(sip), NIPQUAD(tip));
+
+ /*
+ * Backup slaves won't see the ARP reply, but do come through
+ * here for each ARP probe (so we swap the sip/tip to validate
+ * the probe). In a "redundant switch, common router" type of
+ * configuration, the ARP probe will (hopefully) travel from
+ * the active, through one switch, the router, then the other
+ * switch before reaching the backup.
+ */
+ if (slave->state == BOND_STATE_ACTIVE)
+ bond_validate_arp(bond, slave, sip, tip);
+ else
+ bond_validate_arp(bond, slave, tip, sip);
+
+out_unlock:
+ read_unlock(&bond->lock);
+out:
+ dev_kfree_skb(skb);
+ return NET_RX_SUCCESS;
+}
+
/*
* this function is called regularly to monitor each slave's link
* ensuring that traffic is being sent and received when arp monitoring
@@ -2593,7 +2699,8 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
*/
bond_for_each_slave(bond, slave, i) {
if (slave->link != BOND_LINK_UP) {
- if ((jiffies - slave->dev->last_rx) <= delta_in_ticks) {
+ if ((jiffies - slave_last_rx(bond, slave)) <=
+ delta_in_ticks) {
slave->link = BOND_LINK_UP;
@@ -2638,7 +2745,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
if ((slave != bond->curr_active_slave) &&
(!bond->current_arp_slave) &&
- (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) &&
+ (((jiffies - slave_last_rx(bond, slave)) >= 3*delta_in_ticks) &&
bond_has_ip(bond))) {
/* a backup slave has gone down; three times
* the delta allows the current slave to be
@@ -2685,7 +2792,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
* if it is up and needs to take over as the curr_active_slave
*/
if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
- (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) &&
+ (((jiffies - slave_last_rx(bond, slave)) >= (2*delta_in_ticks)) &&
bond_has_ip(bond))) &&
((jiffies - slave->jiffies) >= 2*delta_in_ticks)) {
@@ -2950,7 +3057,7 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave
seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
seq_printf(seq, "MII Status: %s\n",
(slave->link == BOND_LINK_UP) ? "up" : "down");
- seq_printf(seq, "Link Failure Count: %d\n",
+ seq_printf(seq, "Link Failure Count: %u\n",
slave->link_failure_count);
seq_printf(seq,
@@ -3210,6 +3317,9 @@ static int bond_netdev_event(struct notifier_block *this, unsigned long event, v
(event_dev ? event_dev->name : "None"),
event);
+ if (!(event_dev->priv_flags & IFF_BONDING))
+ return NOTIFY_DONE;
+
if (event_dev->flags & IFF_MASTER) {
dprintk("IFF_MASTER\n");
return bond_master_netdev_event(event, event_dev);
@@ -3305,6 +3415,21 @@ static void bond_unregister_lacpdu(struct bonding *bond)
dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
}
+void bond_register_arp(struct bonding *bond)
+{
+ struct packet_type *pt = &bond->arp_mon_pt;
+
+ pt->type = htons(ETH_P_ARP);
+ pt->dev = NULL; /*bond->dev;XXX*/
+ pt->func = bond_arp_rcv;
+ dev_add_pack(pt);
+}
+
+void bond_unregister_arp(struct bonding *bond)
+{
+ dev_remove_pack(&bond->arp_mon_pt);
+}
+
/*---------------------------- Hashing Policies -----------------------------*/
/*
@@ -3391,6 +3516,9 @@ static int bond_open(struct net_device *bond_dev)
} else {
arp_timer->function = (void *)&bond_loadbalance_arp_mon;
}
+ if (bond->params.arp_validate)
+ bond_register_arp(bond);
+
add_timer(arp_timer);
}
@@ -3418,9 +3546,11 @@ static int bond_close(struct net_device *bond_dev)
bond_unregister_lacpdu(bond);
}
+ if (bond->params.arp_validate)
+ bond_unregister_arp(bond);
+
write_lock_bh(&bond->lock);
- bond_mc_list_destroy(bond);
/* signal timers not to re-arm */
bond->kill_timers = 1;
@@ -3451,8 +3581,6 @@ static int bond_close(struct net_device *bond_dev)
break;
}
- /* Release the bonded slaves */
- bond_release_all(bond_dev);
if ((bond->params.mode == BOND_MODE_TLB) ||
(bond->params.mode == BOND_MODE_ALB)) {
@@ -4179,6 +4307,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
/* Initialize the device options */
bond_dev->tx_queue_len = 0;
bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
+ bond_dev->priv_flags |= IFF_BONDING;
/* At first, we block adding VLANs. That's the only way to
* prevent problems that occur when adding VLANs over an
@@ -4237,6 +4366,9 @@ static void bond_free_all(void)
list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
struct net_device *bond_dev = bond->dev;
+ bond_mc_list_destroy(bond);
+ /* Release the bonded slaves */
+ bond_release_all(bond_dev);
unregister_netdevice(bond_dev);
bond_deinit(bond_dev);
}
@@ -4270,6 +4402,8 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
static int bond_check_params(struct bond_params *params)
{
+ int arp_validate_value;
+
/*
* Convert string parameters.
*/
@@ -4473,6 +4607,29 @@ static int bond_check_params(struct bond_params *params)
arp_interval = 0;
}
+ if (arp_validate) {
+ if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
+ printk(KERN_ERR DRV_NAME
+ ": arp_validate only supported in active-backup mode\n");
+ return -EINVAL;
+ }
+ if (!arp_interval) {
+ printk(KERN_ERR DRV_NAME
+ ": arp_validate requires arp_interval\n");
+ return -EINVAL;
+ }
+
+ arp_validate_value = bond_parse_parm(arp_validate,
+ arp_validate_tbl);
+ if (arp_validate_value == -1) {
+ printk(KERN_ERR DRV_NAME
+ ": Error: invalid arp_validate \"%s\"\n",
+ arp_validate == NULL ? "NULL" : arp_validate);
+ return -EINVAL;
+ }
+ } else
+ arp_validate_value = 0;
+
if (miimon) {
printk(KERN_INFO DRV_NAME
": MII link monitoring set to %d ms\n",
@@ -4481,8 +4638,10 @@ static int bond_check_params(struct bond_params *params)
int i;
printk(KERN_INFO DRV_NAME
- ": ARP monitoring set to %d ms with %d target(s):",
- arp_interval, arp_ip_count);
+ ": ARP monitoring set to %d ms, validate %s, with %d target(s):",
+ arp_interval,
+ arp_validate_tbl[arp_validate_value].modename,
+ arp_ip_count);
for (i = 0; i < arp_ip_count; i++)
printk (" %s", arp_ip_target[i]);
@@ -4516,6 +4675,7 @@ static int bond_check_params(struct bond_params *params)
params->xmit_policy = xmit_hashtype;
params->miimon = miimon;
params->arp_interval = arp_interval;
+ params->arp_validate = arp_validate_value;
params->updelay = updelay;
params->downdelay = downdelay;
params->use_carrier = use_carrier;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index cfe4dc3a93a..ced9ed8f995 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -51,6 +51,7 @@ extern struct bond_params bonding_defaults;
extern struct bond_parm_tbl bond_mode_tbl[];
extern struct bond_parm_tbl bond_lacp_tbl[];
extern struct bond_parm_tbl xmit_hashtype_tbl[];
+extern struct bond_parm_tbl arp_validate_tbl[];
static int expected_refcount = -1;
static struct class *netdev_class;
@@ -503,6 +504,53 @@ out:
static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
/*
+ * Show and set arp_validate.
+ */
+static ssize_t bonding_show_arp_validate(struct class_device *cd, char *buf)
+{
+ struct bonding *bond = to_bond(cd);
+
+ return sprintf(buf, "%s %d\n",
+ arp_validate_tbl[bond->params.arp_validate].modename,
+ bond->params.arp_validate) + 1;
+}
+
+static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *buf, size_t count)
+{
+ int new_value;
+ struct bonding *bond = to_bond(cd);
+
+ new_value = bond_parse_parm((char *)buf, arp_validate_tbl);
+ if (new_value < 0) {
+ printk(KERN_ERR DRV_NAME
+ ": %s: Ignoring invalid arp_validate value %s\n",
+ bond->dev->name, buf);
+ return -EINVAL;
+ }
+ if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
+ printk(KERN_ERR DRV_NAME
+ ": %s: arp_validate only supported in active-backup mode.\n",
+ bond->dev->name);
+ return -EINVAL;
+ }
+ printk(KERN_INFO DRV_NAME ": %s: setting arp_validate to %s (%d).\n",
+ bond->dev->name, arp_validate_tbl[new_value].modename,
+ new_value);
+
+ if (!bond->params.arp_validate && new_value) {
+ bond_register_arp(bond);
+ } else if (bond->params.arp_validate && !new_value) {
+ bond_unregister_arp(bond);
+ }
+
+ bond->params.arp_validate = new_value;
+
+ return count;
+}
+
+static CLASS_DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
+
+/*
* Show and set the arp timer interval. There are two tricky bits
* here. First, if ARP monitoring is activated, then we must disable
* MII monitoring. Second, if the ARP timer isn't running, we must
@@ -914,6 +962,11 @@ static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, si
"ARP monitoring. Disabling ARP monitoring...\n",
bond->dev->name);
bond->params.arp_interval = 0;
+ if (bond->params.arp_validate) {
+ bond_unregister_arp(bond);
+ bond->params.arp_validate =
+ BOND_ARP_VALIDATE_NONE;
+ }
/* Kill ARP timer, else it brings bond's link down */
if (bond->mii_timer.function) {
printk(KERN_INFO DRV_NAME
@@ -1093,7 +1146,7 @@ static ssize_t bonding_store_active_slave(struct class_device *cd, const char *b
strlen(slave->dev->name)) == 0) {
old_active = bond->curr_active_slave;
new_active = slave;
- if (new_active && (new_active == old_active)) {
+ if (new_active == old_active) {
/* do nothing */
printk(KERN_INFO DRV_NAME
": %s: %s is already the current active slave.\n",
@@ -1273,6 +1326,7 @@ static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, N
static struct attribute *per_bond_attrs[] = {
&class_device_attr_slaves.attr,
&class_device_attr_mode.attr,
+ &class_device_attr_arp_validate.attr,
&class_device_attr_arp_interval.attr,
&class_device_attr_arp_ip_target.attr,
&class_device_attr_downdelay.attr,
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 0bdfe2c7145..db16fee40a5 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
-#define DRV_VERSION "3.0.3"
-#define DRV_RELDATE "March 23, 2006"
+#define DRV_VERSION "3.1.0-test"
+#define DRV_RELDATE "September 9, 2006"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
@@ -126,6 +126,7 @@ struct bond_params {
int xmit_policy;
int miimon;
int arp_interval;
+ int arp_validate;
int use_carrier;
int updelay;
int downdelay;
@@ -149,8 +150,9 @@ struct slave {
struct net_device *dev; /* first - useful for panic debug */
struct slave *next;
struct slave *prev;
- s16 delay;
+ int delay;
u32 jiffies;
+ u32 last_arp_rx;
s8 link; /* one of BOND_LINK_XXXX */
s8 state; /* one of BOND_STATE_XXXX */
u32 original_flags;
@@ -198,6 +200,7 @@ struct bonding {
struct bond_params params;
struct list_head vlan_list;
struct vlan_group *vlgrp;
+ struct packet_type arp_mon_pt;
};
/**
@@ -228,6 +231,25 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
return (struct bonding *)slave->dev->master->priv;
}
+#define BOND_ARP_VALIDATE_NONE 0
+#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
+#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)
+#define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \
+ BOND_ARP_VALIDATE_BACKUP)
+
+extern inline int slave_do_arp_validate(struct bonding *bond, struct slave *slave)
+{
+ return bond->params.arp_validate & (1 << slave->state);
+}
+
+extern inline u32 slave_last_rx(struct bonding *bond, struct slave *slave)
+{
+ if (slave_do_arp_validate(bond, slave))
+ return slave->last_arp_rx;
+
+ return slave->dev->last_rx;
+}
+
static inline void bond_set_slave_inactive_flags(struct slave *slave)
{
struct bonding *bond = slave->dev->master->priv;
@@ -235,12 +257,14 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave)
bond->params.mode != BOND_MODE_ALB)
slave->state = BOND_STATE_BACKUP;
slave->dev->priv_flags |= IFF_SLAVE_INACTIVE;
+ if (slave_do_arp_validate(bond, slave))
+ slave->dev->priv_flags |= IFF_SLAVE_NEEDARP;
}
static inline void bond_set_slave_active_flags(struct slave *slave)
{
slave->state = BOND_STATE_ACTIVE;
- slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE;
+ slave->dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_SLAVE_NEEDARP);
}
static inline void bond_set_master_3ad_flags(struct bonding *bond)
@@ -284,6 +308,8 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
const char *bond_mode_name(int mode);
void bond_select_active_slave(struct bonding *bond);
void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
+void bond_register_arp(struct bonding *);
+void bond_unregister_arp(struct bonding *);
#endif /* _LINUX_BONDING_H */
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index a170e96251f..4020acb5500 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1367,8 +1367,8 @@ struct e1000_hw_stats {
/* Structure containing variables used by the shared code (e1000_hw.c) */
struct e1000_hw {
- uint8_t *hw_addr;
- uint8_t *flash_address;
+ uint8_t __iomem *hw_addr;
+ uint8_t __iomem *flash_address;
e1000_mac_type mac_type;
e1000_phy_type phy_type;
uint32_t phy_init_script;
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 97db910fbc8..eea1d66c530 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -3789,6 +3789,12 @@ static int nv_loopback_test(struct net_device *dev)
/* setup packet for tx */
pkt_len = ETH_DATA_LEN;
tx_skb = dev_alloc_skb(pkt_len);
+ if (!tx_skb) {
+ printk(KERN_ERR "dev_alloc_skb() failed during loopback test"
+ " of %s\n", dev->name);
+ ret = 0;
+ goto out;
+ }
pkt_data = skb_put(tx_skb, pkt_len);
for (i = 0; i < pkt_len; i++)
pkt_data[i] = (u8)(i & 0xff);
@@ -3853,7 +3859,7 @@ static int nv_loopback_test(struct net_device *dev)
tx_skb->end-tx_skb->data,
PCI_DMA_TODEVICE);
dev_kfree_skb_any(tx_skb);
-
+ out:
/* stop engines */
nv_stop_rx(dev);
nv_stop_tx(dev);
diff --git a/drivers/net/gt64240eth.h b/drivers/net/gt64240eth.h
deleted file mode 100644
index 0d6f486e457..00000000000
--- a/drivers/net/gt64240eth.h
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 Patton Electronics Company
- * Copyright (C) 2002 Momentum Computer
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- * stevel@mvista.com or support@mvista.com
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Ethernet driver definitions for the MIPS GT96100 Advanced
- * Communication Controller.
- *
- * Modified for the Marvellous GT64240 Retarded Communication Controller.
- */
-#ifndef _GT64240ETH_H
-#define _GT64240ETH_H
-
-#include <asm/gt64240.h>
-
-#define ETHERNET_PORTS_DIFFERENCE_OFFSETS 0x400
-
-/* Translate those weanie names from Galileo/VxWorks header files: */
-
-#define GT64240_MRR MAIN_ROUTING_REGISTER
-#define GT64240_CIU_ARBITER_CONFIG COMM_UNIT_ARBITER_CONFIGURATION_REGISTER
-#define GT64240_CIU_ARBITER_CONTROL COMM_UNIT_ARBITER_CONTROL
-#define GT64240_MAIN_LOW_CAUSE LOW_INTERRUPT_CAUSE_REGISTER
-#define GT64240_MAIN_HIGH_CAUSE HIGH_INTERRUPT_CAUSE_REGISTER
-#define GT64240_CPU_LOW_MASK CPU_INTERRUPT_MASK_REGISTER_LOW
-#define GT64240_CPU_HIGH_MASK CPU_INTERRUPT_MASK_REGISTER_HIGH
-#define GT64240_CPU_SELECT_CAUSE CPU_SELECT_CAUSE_REGISTER
-
-#define GT64240_ETH_PHY_ADDR_REG ETHERNET_PHY_ADDRESS_REGISTER
-#define GT64240_ETH_PORT_CONFIG ETHERNET0_PORT_CONFIGURATION_REGISTER
-#define GT64240_ETH_PORT_CONFIG_EXT ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER
-#define GT64240_ETH_PORT_COMMAND ETHERNET0_PORT_COMMAND_REGISTER
-#define GT64240_ETH_PORT_STATUS ETHERNET0_PORT_STATUS_REGISTER
-#define GT64240_ETH_IO_SIZE ETHERNET_PORTS_DIFFERENCE_OFFSETS
-#define GT64240_ETH_SMI_REG ETHERNET_SMI_REGISTER
-#define GT64240_ETH_MIB_COUNT_BASE ETHERNET0_MIB_COUNTER_BASE
-#define GT64240_ETH_SDMA_CONFIG ETHERNET0_SDMA_CONFIGURATION_REGISTER
-#define GT64240_ETH_SDMA_COMM ETHERNET0_SDMA_COMMAND_REGISTER
-#define GT64240_ETH_INT_MASK ETHERNET0_INTERRUPT_MASK_REGISTER
-#define GT64240_ETH_INT_CAUSE ETHERNET0_INTERRUPT_CAUSE_REGISTER
-#define GT64240_ETH_CURR_TX_DESC_PTR0 ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0
-#define GT64240_ETH_CURR_TX_DESC_PTR1 ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1
-#define GT64240_ETH_1ST_RX_DESC_PTR0 ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0
-#define GT64240_ETH_CURR_RX_DESC_PTR0 ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0
-#define GT64240_ETH_HASH_TBL_PTR ETHERNET0_HASH_TABLE_POINTER_REGISTER
-
-/* Turn on NAPI by default */
-
-#define GT64240_NAPI 1
-
-/* Some 64240 settings that SHOULD eventually be setup in PROM monitor: */
-/* (Board-specific to the DSL3224 Rev A board ONLY!) */
-#define D3224_MPP_CTRL0_SETTING 0x66669900
-#define D3224_MPP_CTRL1_SETTING 0x00000000
-#define D3224_MPP_CTRL2_SETTING 0x00887700
-#define D3224_MPP_CTRL3_SETTING 0x00000044
-#define D3224_GPP_IO_CTRL_SETTING 0x0000e800
-#define D3224_GPP_LEVEL_CTRL_SETTING 0xf001f703
-#define D3224_GPP_VALUE_SETTING 0x00000000
-
-/* Keep the ring sizes a power of two for efficiency. */
-//-#define TX_RING_SIZE 16
-#define TX_RING_SIZE 64 /* TESTING !!! */
-#define RX_RING_SIZE 32
-#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */
-
-#define RX_HASH_TABLE_SIZE 16384
-#define HASH_HOP_NUMBER 12
-
-#define NUM_INTERFACES 3
-
-#define GT64240ETH_TX_TIMEOUT HZ/4
-
-#define MIPS_GT64240_BASE 0xf4000000
-#define GT64240_ETH0_BASE (MIPS_GT64240_BASE + GT64240_ETH_PORT_CONFIG)
-#define GT64240_ETH1_BASE (GT64240_ETH0_BASE + GT64240_ETH_IO_SIZE)
-#define GT64240_ETH2_BASE (GT64240_ETH1_BASE + GT64240_ETH_IO_SIZE)
-
-#if defined(CONFIG_MIPS_DSL3224)
-#define GT64240_ETHER0_IRQ 4
-#define GT64240_ETHER1_IRQ 4
-#else
-#define GT64240_ETHER0_IRQ -1
-#define GT64240_ETHER1_IRQ -1
-#endif
-
-#define REV_GT64240 0x1
-#define REV_GT64240A 0x10
-
-#define GT64240ETH_READ(gp, offset) \
- GT_READ((gp)->port_offset + (offset))
-
-#define GT64240ETH_WRITE(gp, offset, data) \
- GT_WRITE((gp)->port_offset + (offset), (data))
-
-#define GT64240ETH_SETBIT(gp, offset, bits) \
- GT64240ETH_WRITE((gp), (offset), \
- GT64240ETH_READ((gp), (offset)) | (bits))
-
-#define GT64240ETH_CLRBIT(gp, offset, bits) \
- GT64240ETH_WRITE((gp), (offset), \
- GT64240ETH_READ((gp), (offset)) & ~(bits))
-
-#define GT64240_READ(ofs) GT_READ(ofs)
-#define GT64240_WRITE(ofs, data) GT_WRITE((ofs), (data))
-
-/* Bit definitions of the SMI Reg */
-enum {
- smirDataMask = 0xffff,
- smirPhyAdMask = 0x1f << 16,
- smirPhyAdBit = 16,
- smirRegAdMask = 0x1f << 21,
- smirRegAdBit = 21,
- smirOpCode = 1 << 26,
- smirReadValid = 1 << 27,
- smirBusy = 1 << 28
-};
-
-/* Bit definitions of the Port Config Reg */
-enum pcr_bits {
- pcrPM = 1 << 0,
- pcrRBM = 1 << 1,
- pcrPBF = 1 << 2,
- pcrEN = 1 << 7,
- pcrLPBKMask = 0x3 << 8,
- pcrLPBKBit = 1 << 8,
- pcrFC = 1 << 10,
- pcrHS = 1 << 12,
- pcrHM = 1 << 13,
- pcrHDM = 1 << 14,
- pcrHD = 1 << 15,
- pcrISLMask = 0x7 << 28,
- pcrISLBit = 28,
- pcrACCS = 1 << 31
-};
-
-/* Bit definitions of the Port Config Extend Reg */
-enum pcxr_bits {
- pcxrIGMP = 1,
- pcxrSPAN = 2,
- pcxrPAR = 4,
- pcxrPRIOtxMask = 0x7 << 3,
- pcxrPRIOtxBit = 3,
- pcxrPRIOrxMask = 0x3 << 6,
- pcxrPRIOrxBit = 6,
- pcxrPRIOrxOverride = 1 << 8,
- pcxrDPLXen = 1 << 9,
- pcxrFCTLen = 1 << 10,
- pcxrFLP = 1 << 11,
- pcxrFCTL = 1 << 12,
- pcxrMFLMask = 0x3 << 14,
- pcxrMFLBit = 14,
- pcxrMIBclrMode = 1 << 16,
- pcxrSpeed = 1 << 18,
- pcxrSpeeden = 1 << 19,
- pcxrRMIIen = 1 << 20,
- pcxrDSCPen = 1 << 21
-};
-
-/* Bit definitions of the Port Command Reg */
-enum pcmr_bits {
- pcmrFJ = 1 << 15
-};
-
-
-/* Bit definitions of the Port Status Reg */
-enum psr_bits {
- psrSpeed = 1,
- psrDuplex = 2,
- psrFctl = 4,
- psrLink = 8,
- psrPause = 1 << 4,
- psrTxLow = 1 << 5,
- psrTxHigh = 1 << 6,
- psrTxInProg = 1 << 7
-};
-
-/* Bit definitions of the SDMA Config Reg */
-enum sdcr_bits {
- sdcrRCMask = 0xf << 2,
- sdcrRCBit = 2,
- sdcrBLMR = 1 << 6,
- sdcrBLMT = 1 << 7,
- sdcrPOVR = 1 << 8,
- sdcrRIFB = 1 << 9,
- sdcrBSZMask = 0x3 << 12,
- sdcrBSZBit = 12
-};
-
-/* Bit definitions of the SDMA Command Reg */
-enum sdcmr_bits {
- sdcmrERD = 1 << 7,
- sdcmrAR = 1 << 15,
- sdcmrSTDH = 1 << 16,
- sdcmrSTDL = 1 << 17,
- sdcmrTXDH = 1 << 23,
- sdcmrTXDL = 1 << 24,
- sdcmrAT = 1 << 31
-};
-
-/* Bit definitions of the Interrupt Cause Reg */
-enum icr_bits {
- icrRxBuffer = 1,
- icrTxBufferHigh = 1 << 2,
- icrTxBufferLow = 1 << 3,
- icrTxEndHigh = 1 << 6,
- icrTxEndLow = 1 << 7,
- icrRxError = 1 << 8,
- icrTxErrorHigh = 1 << 10,
- icrTxErrorLow = 1 << 11,
- icrRxOVR = 1 << 12,
- icrTxUdr = 1 << 13,
- icrRxBufferQ0 = 1 << 16,
- icrRxBufferQ1 = 1 << 17,
- icrRxBufferQ2 = 1 << 18,
- icrRxBufferQ3 = 1 << 19,
- icrRxErrorQ0 = 1 << 20,
- icrRxErrorQ1 = 1 << 21,
- icrRxErrorQ2 = 1 << 22,
- icrRxErrorQ3 = 1 << 23,
- icrMIIPhySTC = 1 << 28,
- icrSMIdone = 1 << 29,
- icrEtherIntSum = 1 << 31
-};
-
-
-/* The Rx and Tx descriptor lists. */
-#ifdef __LITTLE_ENDIAN
-typedef struct {
- u32 cmdstat;
- u16 reserved; //-prk21aug01 u32 reserved:16;
- u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16;
- u32 buff_ptr;
- u32 next;
-} gt64240_td_t;
-
-typedef struct {
- u32 cmdstat;
- u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16;
- u16 buff_sz; //-prk21aug01 u32 buff_sz:16;
- u32 buff_ptr;
- u32 next;
-} gt64240_rd_t;
-#elif defined(__BIG_ENDIAN)
-typedef struct {
- u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16;
- u16 reserved; //-prk21aug01 u32 reserved:16;
- u32 cmdstat;
- u32 next;
- u32 buff_ptr;
-} gt64240_td_t;
-
-typedef struct {
- u16 buff_sz; //-prk21aug01 u32 buff_sz:16;
- u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16;
- u32 cmdstat;
- u32 next;
- u32 buff_ptr;
-} gt64240_rd_t;
-#else
-#error Either __BIG_ENDIAN or __LITTLE_ENDIAN must be defined!
-#endif
-
-
-/* Values for the Tx command-status descriptor entry. */
-enum td_cmdstat {
- txOwn = 1 << 31,
- txAutoMode = 1 << 30,
- txEI = 1 << 23,
- txGenCRC = 1 << 22,
- txPad = 1 << 18,
- txFirst = 1 << 17,
- txLast = 1 << 16,
- txErrorSummary = 1 << 15,
- txReTxCntMask = 0x0f << 10,
- txReTxCntBit = 10,
- txCollision = 1 << 9,
- txReTxLimit = 1 << 8,
- txUnderrun = 1 << 6,
- txLateCollision = 1 << 5
-};
-
-
-/* Values for the Rx command-status descriptor entry. */
-enum rd_cmdstat {
- rxOwn = 1 << 31,
- rxAutoMode = 1 << 30,
- rxEI = 1 << 23,
- rxFirst = 1 << 17,
- rxLast = 1 << 16,
- rxErrorSummary = 1 << 15,
- rxIGMP = 1 << 14,
- rxHashExpired = 1 << 13,
- rxMissedFrame = 1 << 12,
- rxFrameType = 1 << 11,
- rxShortFrame = 1 << 8,
- rxMaxFrameLen = 1 << 7,
- rxOverrun = 1 << 6,
- rxCollision = 1 << 4,
- rxCRCError = 1
-};
-
-/* Bit fields of a Hash Table Entry */
-enum hash_table_entry {
- hteValid = 1,
- hteSkip = 2,
- hteRD = 4
-};
-
-// The MIB counters
-typedef struct {
- u32 byteReceived;
- u32 byteSent;
- u32 framesReceived;
- u32 framesSent;
- u32 totalByteReceived;
- u32 totalFramesReceived;
- u32 broadcastFramesReceived;
- u32 multicastFramesReceived;
- u32 cRCError;
- u32 oversizeFrames;
- u32 fragments;
- u32 jabber;
- u32 collision;
- u32 lateCollision;
- u32 frames64;
- u32 frames65_127;
- u32 frames128_255;
- u32 frames256_511;
- u32 frames512_1023;
- u32 frames1024_MaxSize;
- u32 macRxError;
- u32 droppedFrames;
- u32 outMulticastFrames;
- u32 outBroadcastFrames;
- u32 undersizeFrames;
-} mib_counters_t;
-
-
-struct gt64240_private {
- gt64240_rd_t *rx_ring;
- gt64240_td_t *tx_ring;
- // The Rx and Tx rings must be 16-byte aligned
- dma_addr_t rx_ring_dma;
- dma_addr_t tx_ring_dma;
- char *hash_table;
- // The Hash Table must be 8-byte aligned
- dma_addr_t hash_table_dma;
- int hash_mode;
-
- // The Rx buffers must be 8-byte aligned
- char *rx_buff;
- dma_addr_t rx_buff_dma;
- // Tx buffers (tx_skbuff[i]->data) with less than 8 bytes
- // of payload must be 8-byte aligned
- struct sk_buff *tx_skbuff[TX_RING_SIZE];
- int rx_next_out; /* The next free ring entry to receive */
- int tx_next_in; /* The next free ring entry to send */
- int tx_next_out; /* The last ring entry the ISR processed */
- int tx_count; /* current # of pkts waiting to be sent in Tx ring */
- int intr_work_done; /* number of Rx and Tx pkts processed in the isr */
- int tx_full; /* Tx ring is full */
-
- mib_counters_t mib;
- struct net_device_stats stats;
-
- int io_size;
- int port_num; // 0 or 1
- u32 port_offset;
-
- int phy_addr; // PHY address
- u32 last_psr; // last value of the port status register
-
- int options; /* User-settable misc. driver options. */
- int drv_flags;
- spinlock_t lock; /* Serialise access to device */
- struct mii_if_info mii_if;
-
- u32 msg_enable;
-};
-
-#endif /* _GT64240ETH_H */
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 2d1ecfdc80d..ecd3da151e2 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -522,7 +522,7 @@ EXPORT_SYMBOL(genphy_read_status);
static int genphy_config_init(struct phy_device *phydev)
{
- u32 val;
+ int val;
u32 features;
/* For now, I'll claim that the generic driver supports
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index f5dbeb27b6f..1bf23e41f58 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2904,7 +2904,7 @@ static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device
{
u64 val64 = 0x0;
nic_t *sp = dev->priv;
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0;
+ XENA_dev_config_t __iomem *bar0 = sp->bar0;
//address transaction
val64 = val64 | MDIO_MMD_INDX_ADDR(addr)
@@ -2953,7 +2953,7 @@ static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev)
u64 val64 = 0x0;
u64 rval64 = 0x0;
nic_t *sp = dev->priv;
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0;
+ XENA_dev_config_t __iomem *bar0 = sp->bar0;
/* address transaction */
val64 = val64 | MDIO_MMD_INDX_ADDR(addr)
@@ -3276,7 +3276,7 @@ static void alarm_intr_handler(struct s2io_nic *nic)
* SUCCESS on success and FAILURE on failure.
*/
-static int wait_for_cmd_complete(void *addr, u64 busy_bit)
+static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit)
{
int ret = FAILURE, cnt = 0;
u64 val64;
@@ -4303,11 +4303,11 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
sp->stats.tx_errors =
le32_to_cpu(mac_control->stats_info->tmac_any_err_frms);
sp->stats.rx_errors =
- le32_to_cpu(mac_control->stats_info->rmac_drop_frms);
+ le64_to_cpu(mac_control->stats_info->rmac_drop_frms);
sp->stats.multicast =
le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms);
sp->stats.rx_length_errors =
- le32_to_cpu(mac_control->stats_info->rmac_long_frms);
+ le64_to_cpu(mac_control->stats_info->rmac_long_frms);
return (&sp->stats);
}
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 9142d91355b..705e9a8fa30 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -58,6 +58,7 @@
#define TX_WATCHDOG (5 * HZ)
#define NAPI_WEIGHT 64
#define BLINK_MS 250
+#define LINK_HZ (HZ/2)
MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
@@ -605,7 +606,12 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
if (hw->chip_id == CHIP_ID_GENESIS) {
switch (mode) {
case LED_MODE_OFF:
- xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
+ if (hw->phy_type == SK_PHY_BCOM)
+ xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
+ else {
+ skge_write32(hw, SK_REG(port, TX_LED_VAL), 0);
+ skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_T_OFF);
+ }
skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
skge_write32(hw, SK_REG(port, RX_LED_VAL), 0);
skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF);
@@ -625,8 +631,14 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
skge_write32(hw, SK_REG(port, RX_LED_VAL), 100);
skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
- xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
- break;
+ if (hw->phy_type == SK_PHY_BCOM)
+ xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
+ else {
+ skge_write8(hw, SK_REG(port, TX_LED_TST), LED_T_ON);
+ skge_write32(hw, SK_REG(port, TX_LED_VAL), 100);
+ skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
+ }
+
}
} else {
switch (mode) {
@@ -879,6 +891,9 @@ static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
*val = xm_read16(hw, port, XM_PHY_DATA);
+ if (hw->phy_type == SK_PHY_XMAC)
+ goto ready;
+
for (i = 0; i < PHY_RETRIES; i++) {
if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
goto ready;
@@ -965,7 +980,8 @@ static void genesis_reset(struct skge_hw *hw, int port)
xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */
/* disable Broadcom PHY IRQ */
- xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
+ if (hw->phy_type == SK_PHY_BCOM)
+ xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
xm_outhash(hw, port, XM_HSM, zero);
}
@@ -1000,60 +1016,64 @@ static void bcom_check_link(struct skge_hw *hw, int port)
if (netif_carrier_ok(dev))
skge_link_down(skge);
- } else {
- if (skge->autoneg == AUTONEG_ENABLE &&
- (status & PHY_ST_AN_OVER)) {
- u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP);
- u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
-
- if (lpa & PHY_B_AN_RF) {
- printk(KERN_NOTICE PFX "%s: remote fault\n",
- dev->name);
- return;
- }
+ return;
+ }
- /* Check Duplex mismatch */
- switch (aux & PHY_B_AS_AN_RES_MSK) {
- case PHY_B_RES_1000FD:
- skge->duplex = DUPLEX_FULL;
- break;
- case PHY_B_RES_1000HD:
- skge->duplex = DUPLEX_HALF;
- break;
- default:
- printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
- dev->name);
- return;
- }
+ if (skge->autoneg == AUTONEG_ENABLE) {
+ u16 lpa, aux;
+ if (!(status & PHY_ST_AN_OVER))
+ return;
- /* We are using IEEE 802.3z/D5.0 Table 37-4 */
- switch (aux & PHY_B_AS_PAUSE_MSK) {
- case PHY_B_AS_PAUSE_MSK:
- skge->flow_control = FLOW_MODE_SYMMETRIC;
- break;
- case PHY_B_AS_PRR:
- skge->flow_control = FLOW_MODE_REM_SEND;
- break;
- case PHY_B_AS_PRT:
- skge->flow_control = FLOW_MODE_LOC_SEND;
- break;
- default:
- skge->flow_control = FLOW_MODE_NONE;
- }
+ lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
+ if (lpa & PHY_B_AN_RF) {
+ printk(KERN_NOTICE PFX "%s: remote fault\n",
+ dev->name);
+ return;
+ }
- skge->speed = SPEED_1000;
+ aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
+
+ /* Check Duplex mismatch */
+ switch (aux & PHY_B_AS_AN_RES_MSK) {
+ case PHY_B_RES_1000FD:
+ skge->duplex = DUPLEX_FULL;
+ break;
+ case PHY_B_RES_1000HD:
+ skge->duplex = DUPLEX_HALF;
+ break;
+ default:
+ printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
+ dev->name);
+ return;
}
- if (!netif_carrier_ok(dev))
- genesis_link_up(skge);
+
+ /* We are using IEEE 802.3z/D5.0 Table 37-4 */
+ switch (aux & PHY_B_AS_PAUSE_MSK) {
+ case PHY_B_AS_PAUSE_MSK:
+ skge->flow_control = FLOW_MODE_SYMMETRIC;
+ break;
+ case PHY_B_AS_PRR:
+ skge->flow_control = FLOW_MODE_REM_SEND;
+ break;
+ case PHY_B_AS_PRT:
+ skge->flow_control = FLOW_MODE_LOC_SEND;
+ break;
+ default:
+ skge->flow_control = FLOW_MODE_NONE;
+ }
+ skge->speed = SPEED_1000;
}
+
+ if (!netif_carrier_ok(dev))
+ genesis_link_up(skge);
}
/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
* Phy on for 100 or 10Mbit operation
*/
-static void bcom_phy_init(struct skge_port *skge, int jumbo)
+static void bcom_phy_init(struct skge_port *skge)
{
struct skge_hw *hw = skge->hw;
int port = skge->port;
@@ -1144,7 +1164,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
phy_pause_map[skge->flow_control] | PHY_AN_CSMA);
/* Handle Jumbo frames */
- if (jumbo) {
+ if (hw->dev[port]->mtu > ETH_DATA_LEN) {
xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK);
@@ -1157,8 +1177,154 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
/* Use link status change interrupt */
xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
+}
- bcom_check_link(hw, port);
+static void xm_phy_init(struct skge_port *skge)
+{
+ struct skge_hw *hw = skge->hw;
+ int port = skge->port;
+ u16 ctrl = 0;
+
+ if (skge->autoneg == AUTONEG_ENABLE) {
+ if (skge->advertising & ADVERTISED_1000baseT_Half)
+ ctrl |= PHY_X_AN_HD;
+ if (skge->advertising & ADVERTISED_1000baseT_Full)
+ ctrl |= PHY_X_AN_FD;
+
+ switch(skge->flow_control) {
+ case FLOW_MODE_NONE:
+ ctrl |= PHY_X_P_NO_PAUSE;
+ break;
+ case FLOW_MODE_LOC_SEND:
+ ctrl |= PHY_X_P_ASYM_MD;
+ break;
+ case FLOW_MODE_SYMMETRIC:
+ ctrl |= PHY_X_P_BOTH_MD;
+ break;
+ }
+
+ xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl);
+
+ /* Restart Auto-negotiation */
+ ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
+ } else {
+ /* Set DuplexMode in Config register */
+ if (skge->duplex == DUPLEX_FULL)
+ ctrl |= PHY_CT_DUP_MD;
+ /*
+ * Do NOT enable Auto-negotiation here. This would hold
+ * the link down because no IDLEs are transmitted
+ */
+ }
+
+ xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl);
+
+ /* Poll PHY for status changes */
+ schedule_delayed_work(&skge->link_thread, LINK_HZ);
+}
+
+static void xm_check_link(struct net_device *dev)
+{
+ struct skge_port *skge = netdev_priv(dev);
+ struct skge_hw *hw = skge->hw;
+ int port = skge->port;
+ u16 status;
+
+ /* read twice because of latch */
+ (void) xm_phy_read(hw, port, PHY_XMAC_STAT);
+ status = xm_phy_read(hw, port, PHY_XMAC_STAT);
+
+ if ((status & PHY_ST_LSYNC) == 0) {
+ u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
+ cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+ xm_write16(hw, port, XM_MMU_CMD, cmd);
+ /* dummy read to ensure writing */
+ (void) xm_read16(hw, port, XM_MMU_CMD);
+
+ if (netif_carrier_ok(dev))
+ skge_link_down(skge);
+ return;
+ }
+
+ if (skge->autoneg == AUTONEG_ENABLE) {
+ u16 lpa, res;
+
+ if (!(status & PHY_ST_AN_OVER))
+ return;
+
+ lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
+ if (lpa & PHY_B_AN_RF) {
+ printk(KERN_NOTICE PFX "%s: remote fault\n",
+ dev->name);
+ return;
+ }
+
+ res = xm_phy_read(hw, port, PHY_XMAC_RES_ABI);
+
+ /* Check Duplex mismatch */
+ switch (res & (PHY_X_RS_HD | PHY_X_RS_FD)) {
+ case PHY_X_RS_FD:
+ skge->duplex = DUPLEX_FULL;
+ break;
+ case PHY_X_RS_HD:
+ skge->duplex = DUPLEX_HALF;
+ break;
+ default:
+ printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
+ dev->name);
+ return;
+ }
+
+ /* We are using IEEE 802.3z/D5.0 Table 37-4 */
+ if (lpa & PHY_X_P_SYM_MD)
+ skge->flow_control = FLOW_MODE_SYMMETRIC;
+ else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD)
+ skge->flow_control = FLOW_MODE_REM_SEND;
+ else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD)
+ skge->flow_control = FLOW_MODE_LOC_SEND;
+ else
+ skge->flow_control = FLOW_MODE_NONE;
+
+
+ skge->speed = SPEED_1000;
+ }
+
+ if (!netif_carrier_ok(dev))
+ genesis_link_up(skge);
+}
+
+/* Poll to check for link coming up.
+ * Since internal PHY is wired to a level triggered pin, can't
+ * get an interrupt when carrier is detected.
+ */
+static void xm_link_timer(void *arg)
+{
+ struct net_device *dev = arg;
+ struct skge_port *skge = netdev_priv(arg);
+ struct skge_hw *hw = skge->hw;
+ int port = skge->port;
+
+ if (!netif_running(dev))
+ return;
+
+ if (netif_carrier_ok(dev)) {
+ xm_read16(hw, port, XM_ISRC);
+ if (!(xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS))
+ goto nochange;
+ } else {
+ if (xm_read32(hw, port, XM_GP_PORT) & XM_GP_INP_ASS)
+ goto nochange;
+ xm_read16(hw, port, XM_ISRC);
+ if (xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS)
+ goto nochange;
+ }
+
+ mutex_lock(&hw->phy_mutex);
+ xm_check_link(dev);
+ mutex_unlock(&hw->phy_mutex);
+
+nochange:
+ schedule_delayed_work(&skge->link_thread, LINK_HZ);
}
static void genesis_mac_init(struct skge_hw *hw, int port)
@@ -1189,20 +1355,29 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
* namely for the 1000baseTX cards that use the XMAC's
* GMII mode.
*/
- /* Take external Phy out of reset */
- r = skge_read32(hw, B2_GP_IO);
- if (port == 0)
- r |= GP_DIR_0|GP_IO_0;
- else
- r |= GP_DIR_2|GP_IO_2;
+ if (hw->phy_type != SK_PHY_XMAC) {
+ /* Take external Phy out of reset */
+ r = skge_read32(hw, B2_GP_IO);
+ if (port == 0)
+ r |= GP_DIR_0|GP_IO_0;
+ else
+ r |= GP_DIR_2|GP_IO_2;
- skge_write32(hw, B2_GP_IO, r);
+ skge_write32(hw, B2_GP_IO, r);
+ /* Enable GMII interface */
+ xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
+ }
- /* Enable GMII interface */
- xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
- bcom_phy_init(skge, jumbo);
+ switch(hw->phy_type) {
+ case SK_PHY_XMAC:
+ xm_phy_init(skge);
+ break;
+ case SK_PHY_BCOM:
+ bcom_phy_init(skge);
+ bcom_check_link(hw, port);
+ }
/* Set Station Address */
xm_outaddr(hw, port, XM_SA, dev->dev_addr);
@@ -1335,16 +1510,18 @@ static void genesis_stop(struct skge_port *skge)
skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
/* For external PHYs there must be special handling */
- reg = skge_read32(hw, B2_GP_IO);
- if (port == 0) {
- reg |= GP_DIR_0;
- reg &= ~GP_IO_0;
- } else {
- reg |= GP_DIR_2;
- reg &= ~GP_IO_2;
+ if (hw->phy_type != SK_PHY_XMAC) {
+ reg = skge_read32(hw, B2_GP_IO);
+ if (port == 0) {
+ reg |= GP_DIR_0;
+ reg &= ~GP_IO_0;
+ } else {
+ reg |= GP_DIR_2;
+ reg &= ~GP_IO_2;
+ }
+ skge_write32(hw, B2_GP_IO, reg);
+ skge_read32(hw, B2_GP_IO);
}
- skge_write32(hw, B2_GP_IO, reg);
- skge_read32(hw, B2_GP_IO);
xm_write16(hw, port, XM_MMU_CMD,
xm_read16(hw, port, XM_MMU_CMD)
@@ -1406,7 +1583,7 @@ static void genesis_link_up(struct skge_port *skge)
struct skge_hw *hw = skge->hw;
int port = skge->port;
u16 cmd;
- u32 mode, msk;
+ u32 mode;
cmd = xm_read16(hw, port, XM_MMU_CMD);
@@ -1454,27 +1631,24 @@ static void genesis_link_up(struct skge_port *skge)
}
xm_write32(hw, port, XM_MODE, mode);
-
- msk = XM_DEF_MSK;
- /* disable GP0 interrupt bit for external Phy */
- msk |= XM_IS_INP_ASS;
-
- xm_write16(hw, port, XM_IMSK, msk);
+ xm_write16(hw, port, XM_IMSK, XM_DEF_MSK);
xm_read16(hw, port, XM_ISRC);
/* get MMU Command Reg. */
cmd = xm_read16(hw, port, XM_MMU_CMD);
- if (skge->duplex == DUPLEX_FULL)
+ if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL)
cmd |= XM_MMU_GMII_FD;
/*
* Workaround BCOM Errata (#10523) for all BCom Phys
* Enable Power Management after link up
*/
- xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
- xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
- & ~PHY_B_AC_DIS_PM);
- xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
+ if (hw->phy_type == SK_PHY_BCOM) {
+ xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
+ xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
+ & ~PHY_B_AC_DIS_PM);
+ xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
+ }
/* enable Rx/Tx */
xm_write16(hw, port, XM_MMU_CMD,
@@ -2240,6 +2414,8 @@ static int skge_down(struct net_device *dev)
printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
netif_stop_queue(dev);
+ if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
+ cancel_rearming_delayed_work(&skge->link_thread);
skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
if (hw->chip_id == CHIP_ID_GENESIS)
@@ -2862,7 +3038,7 @@ static void skge_extirq(void *arg)
if (netif_running(dev)) {
if (hw->chip_id != CHIP_ID_GENESIS)
yukon_phy_intr(skge);
- else
+ else if (hw->phy_type == SK_PHY_BCOM)
bcom_phy_intr(skge);
}
}
@@ -3014,7 +3190,7 @@ static int skge_reset(struct skge_hw *hw)
{
u32 reg;
u16 ctst, pci_status;
- u8 t8, mac_cfg, pmd_type, phy_type;
+ u8 t8, mac_cfg, pmd_type;
int i;
ctst = skge_read16(hw, B0_CTST);
@@ -3038,19 +3214,22 @@ static int skge_reset(struct skge_hw *hw)
ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA));
hw->chip_id = skge_read8(hw, B2_CHIP_ID);
- phy_type = skge_read8(hw, B2_E_1) & 0xf;
+ hw->phy_type = skge_read8(hw, B2_E_1) & 0xf;
pmd_type = skge_read8(hw, B2_PMD_TYP);
hw->copper = (pmd_type == 'T' || pmd_type == '1');
switch (hw->chip_id) {
case CHIP_ID_GENESIS:
- switch (phy_type) {
+ switch (hw->phy_type) {
+ case SK_PHY_XMAC:
+ hw->phy_addr = PHY_ADDR_XMAC;
+ break;
case SK_PHY_BCOM:
hw->phy_addr = PHY_ADDR_BCOM;
break;
default:
printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n",
- pci_name(hw->pdev), phy_type);
+ pci_name(hw->pdev), hw->phy_type);
return -EOPNOTSUPP;
}
break;
@@ -3058,7 +3237,7 @@ static int skge_reset(struct skge_hw *hw)
case CHIP_ID_YUKON:
case CHIP_ID_YUKON_LITE:
case CHIP_ID_YUKON_LP:
- if (phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S')
+ if (hw->phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S')
hw->copper = 1;
hw->phy_addr = PHY_ADDR_MARV;
@@ -3089,10 +3268,13 @@ static int skge_reset(struct skge_hw *hw)
else
hw->ram_size = t8 * 4096;
- hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1;
+ hw->intr_mask = IS_HW_ERR | IS_PORT_1;
if (hw->ports > 1)
hw->intr_mask |= IS_PORT_2;
+ if (!(hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC))
+ hw->intr_mask |= IS_EXT_REG;
+
if (hw->chip_id == CHIP_ID_GENESIS)
genesis_init(hw);
else {
@@ -3226,6 +3408,9 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
skge->port = port;
+ /* Only used for Genesis XMAC */
+ INIT_WORK(&skge->link_thread, xm_link_timer, dev);
+
if (hw->chip_id != CHIP_ID_GENESIS) {
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
skge->rx_csum = 1;
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 79e09271bcf..d0b47d46cf9 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -934,7 +934,7 @@ enum {
PHY_XMAC_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */
PHY_XMAC_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Abi Reg */
PHY_XMAC_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */
- PHY_XMAC_NEPG = 0x07,/* 16 bit r/w Next Page Register */
+ PHY_XMAC_NEPG = 0x07,/* 16 bit r/w Next Page Register */
PHY_XMAC_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */
PHY_XMAC_EXT_STAT = 0x0f,/* 16 bit r/o Ext Status Register */
@@ -1097,13 +1097,36 @@ enum {
/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
enum {
- PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */
+ PHY_X_P_NO_PAUSE= 0<<7,/* Bit 8..7: no Pause Mode */
PHY_X_P_SYM_MD = 1<<7, /* Bit 8..7: symmetric Pause Mode */
PHY_X_P_ASYM_MD = 2<<7,/* Bit 8..7: asymmetric Pause Mode */
PHY_X_P_BOTH_MD = 3<<7,/* Bit 8..7: both Pause Mode */
};
+/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/
+enum {
+ PHY_X_EX_FD = 1<<15, /* Bit 15: Device Supports Full Duplex */
+ PHY_X_EX_HD = 1<<14, /* Bit 14: Device Supports Half Duplex */
+};
+
+/***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/
+enum {
+ PHY_X_RS_PAUSE = 3<<7, /* Bit 8..7: selected Pause Mode */
+ PHY_X_RS_HD = 1<<6, /* Bit 6: Half Duplex Mode selected */
+ PHY_X_RS_FD = 1<<5, /* Bit 5: Full Duplex Mode selected */
+ PHY_X_RS_ABLMIS = 1<<4, /* Bit 4: duplex or pause cap mismatch */
+ PHY_X_RS_PAUMIS = 1<<3, /* Bit 3: pause capability mismatch */
+};
+
+/* Remote Fault Bits (PHY_X_AN_RFB) encoding */
+enum {
+ X_RFB_OK = 0<<12,/* Bit 13..12 No errors, Link OK */
+ X_RFB_LF = 1<<12,/* Bit 13..12 Link Failure */
+ X_RFB_OFF = 2<<12,/* Bit 13..12 Offline */
+ X_RFB_AN_ERR = 3<<12,/* Bit 13..12 Auto-Negotiation Error */
+};
+
/* Broadcom-Specific */
/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
enum {
@@ -2158,8 +2181,8 @@ enum {
XM_IS_LNK_AE = 1<<14, /* Bit 14: Link Asynchronous Event */
XM_IS_TX_ABORT = 1<<13, /* Bit 13: Transmit Abort, late Col. etc */
XM_IS_FRC_INT = 1<<12, /* Bit 12: Force INT bit set in GP */
- XM_IS_INP_ASS = 1<<11, /* Bit 11: Input Asserted, GP bit 0 set */
- XM_IS_LIPA_RC = 1<<10, /* Bit 10: Link Partner requests config */
+ XM_IS_INP_ASS = 1<<11, /* Bit 11: Input Asserted, GP bit 0 set */
+ XM_IS_LIPA_RC = 1<<10, /* Bit 10: Link Partner requests config */
XM_IS_RX_PAGE = 1<<9, /* Bit 9: Page Received */
XM_IS_TX_PAGE = 1<<8, /* Bit 8: Next Page Loaded for Transmit */
XM_IS_AND = 1<<7, /* Bit 7: Auto-Negotiation Done */
@@ -2172,9 +2195,7 @@ enum {
XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */
};
-#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | \
- XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | \
- XM_IS_RXF_OV | XM_IS_TXF_UR))
+#define XM_DEF_MSK (~(XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_RXF_OV | XM_IS_TXF_UR))
/* XM_HW_CFG 16 bit r/w Hardware Config Register */
@@ -2396,6 +2417,7 @@ struct skge_hw {
u8 chip_rev;
u8 copper;
u8 ports;
+ u8 phy_type;
u32 ram_size;
u32 ram_offset;
@@ -2422,6 +2444,7 @@ struct skge_port {
struct net_device_stats net_stats;
+ struct work_struct link_thread;
u8 rx_csum;
u8 blink_on;
u8 flow_control;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 7aa7fbac822..c660e33f43a 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -379,6 +379,24 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#define SMC_IRQ_FLAGS (0)
+#elif defined(CONFIG_ARCH_VERSATILE)
+
+#define SMC_CAN_USE_8BIT 1
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 1
+#define SMC_NOWAIT 1
+
+#define SMC_inb(a, r) readb((a) + (r))
+#define SMC_inw(a, r) readw((a) + (r))
+#define SMC_inl(a, r) readl((a) + (r))
+#define SMC_outb(v, a, r) writeb(v, (a) + (r))
+#define SMC_outw(v, a, r) writew(v, (a) + (r))
+#define SMC_outl(v, a, r) writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
+
+#define SMC_IRQ_FLAGS (0)
+
#else
#define SMC_CAN_USE_8BIT 1
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index 0d66700c6ce..bfc8c3eae9a 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -1876,7 +1876,6 @@ static int sprintf_info(char *buffer, struct net_device *dev)
datap[size+1]=io_word & 0xff;
}
-
size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name);
size += sprintf(buffer + size,
@@ -1932,64 +1931,6 @@ static int sprintf_info(char *buffer, struct net_device *dev)
#endif
#endif
-#if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static int streamer_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
- int i;
- struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv;
- u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
-
- switch(cmd) {
- case IOCTL_SISR_MASK:
- writew(SISR_MI, streamer_mmio + SISR_MASK_SUM);
- break;
- case IOCTL_SPIN_LOCK_TEST:
- printk(KERN_INFO "spin_lock() called.\n");
- spin_lock(&streamer_priv->streamer_lock);
- spin_unlock(&streamer_priv->streamer_lock);
- printk(KERN_INFO "spin_unlock() finished.\n");
- break;
- case IOCTL_PRINT_BDAS:
- printk(KERN_INFO "bdas: RXBDA: %x RXLBDA: %x TX2FDA: %x TX2LFDA: %x\n",
- readw(streamer_mmio + RXBDA),
- readw(streamer_mmio + RXLBDA),
- readw(streamer_mmio + TX2FDA),
- readw(streamer_mmio + TX2LFDA));
- break;
- case IOCTL_PRINT_REGISTERS:
- printk(KERN_INFO "registers:\n");
- printk(KERN_INFO "SISR: %04x MISR: %04x LISR: %04x BCTL: %04x BMCTL: %04x\nmask %04x mask %04x\n",
- readw(streamer_mmio + SISR),
- readw(streamer_mmio + MISR_RUM),
- readw(streamer_mmio + LISR),
- readw(streamer_mmio + BCTL),
- readw(streamer_mmio + BMCTL_SUM),
- readw(streamer_mmio + SISR_MASK),
- readw(streamer_mmio + MISR_MASK));
- break;
- case IOCTL_PRINT_RX_BUFS:
- printk(KERN_INFO "Print rx bufs:\n");
- for(i=0; i<STREAMER_RX_RING_SIZE; i++)
- printk(KERN_INFO "rx_ring %d status: 0x%x\n", i,
- streamer_priv->streamer_rx_ring[i].status);
- break;
- case IOCTL_PRINT_TX_BUFS:
- printk(KERN_INFO "Print tx bufs:\n");
- for(i=0; i<STREAMER_TX_RING_SIZE; i++)
- printk(KERN_INFO "tx_ring %d status: 0x%x\n", i,
- streamer_priv->streamer_tx_ring[i].status);
- break;
- case IOCTL_RX_CMD:
- streamer_rx(dev);
- printk(KERN_INFO "Sent rx command.\n");
- break;
- default:
- printk(KERN_INFO "Bad ioctl!\n");
- }
- return 0;
-}
-#endif
-
static struct pci_driver streamer_pci_driver = {
.name = "lanstreamer",
.id_table = streamer_pci_tbl,
diff --git a/drivers/net/tokenring/lanstreamer.h b/drivers/net/tokenring/lanstreamer.h
index 5557d8e1e22..e7bb3494afc 100644
--- a/drivers/net/tokenring/lanstreamer.h
+++ b/drivers/net/tokenring/lanstreamer.h
@@ -62,18 +62,6 @@
#include <linux/version.h>
-#if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include <asm/ioctl.h>
-#define IOCTL_PRINT_RX_BUFS SIOCDEVPRIVATE
-#define IOCTL_PRINT_TX_BUFS SIOCDEVPRIVATE+1
-#define IOCTL_RX_CMD SIOCDEVPRIVATE+2
-#define IOCTL_TX_CMD SIOCDEVPRIVATE+3
-#define IOCTL_PRINT_REGISTERS SIOCDEVPRIVATE+4
-#define IOCTL_PRINT_BDAS SIOCDEVPRIVATE+5
-#define IOCTL_SPIN_LOCK_TEST SIOCDEVPRIVATE+6
-#define IOCTL_SISR_MASK SIOCDEVPRIVATE+7
-#endif
-
/* MAX_INTR - the maximum number of times we can loop
* inside the interrupt function before returning
* control to the OS (maximum value is 256)
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 8f6f6fd8b87..d5c32e9caa9 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -333,11 +333,7 @@ enum state_values {
#define TYPHOON_RESET_TIMEOUT_NOSLEEP ((6 * 1000000) / TYPHOON_UDELAY)
#define TYPHOON_WAIT_TIMEOUT ((1000000 / 2) / TYPHOON_UDELAY)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 28)
-#define typhoon_synchronize_irq(x) synchronize_irq()
-#else
#define typhoon_synchronize_irq(x) synchronize_irq(x)
-#endif
#if defined(NETIF_F_TSO)
#define skb_tso_size(x) (skb_shinfo(x)->gso_size)
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index bff04cba3fe..ba737c6cebe 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -5868,7 +5868,7 @@ static int airo_set_essid(struct net_device *dev,
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
/* Check the size of the string */
- if(dwrq->length > IW_ESSID_MAX_SIZE+1) {
+ if(dwrq->length > IW_ESSID_MAX_SIZE) {
return -E2BIG ;
}
/* Check if index is valid */
@@ -5880,7 +5880,7 @@ static int airo_set_essid(struct net_device *dev,
memset(SSID_rid.ssids[index].ssid, 0,
sizeof(SSID_rid.ssids[index].ssid));
memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
- SSID_rid.ssids[index].len = dwrq->length - 1;
+ SSID_rid.ssids[index].len = dwrq->length;
}
SSID_rid.len = sizeof(SSID_rid);
/* Write it to the card */
@@ -5990,7 +5990,7 @@ static int airo_set_nick(struct net_device *dev,
struct airo_info *local = dev->priv;
/* Check the size of the string */
- if(dwrq->length > 16 + 1) {
+ if(dwrq->length > 16) {
return -E2BIG;
}
readConfigRid(local, 1);
@@ -6015,7 +6015,7 @@ static int airo_get_nick(struct net_device *dev,
readConfigRid(local, 1);
strncpy(extra, local->config.nodeName, 16);
extra[16] = '\0';
- dwrq->length = strlen(extra) + 1;
+ dwrq->length = strlen(extra);
return 0;
}
@@ -6767,9 +6767,9 @@ static int airo_set_retry(struct net_device *dev,
}
readConfigRid(local, 1);
if(vwrq->flags & IW_RETRY_LIMIT) {
- if(vwrq->flags & IW_RETRY_MAX)
+ if(vwrq->flags & IW_RETRY_LONG)
local->config.longRetryLimit = vwrq->value;
- else if (vwrq->flags & IW_RETRY_MIN)
+ else if (vwrq->flags & IW_RETRY_SHORT)
local->config.shortRetryLimit = vwrq->value;
else {
/* No modifier : set both */
@@ -6805,14 +6805,14 @@ static int airo_get_retry(struct net_device *dev,
if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
vwrq->flags = IW_RETRY_LIFETIME;
vwrq->value = (int)local->config.txLifetime * 1024;
- } else if((vwrq->flags & IW_RETRY_MAX)) {
- vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ } else if((vwrq->flags & IW_RETRY_LONG)) {
+ vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
vwrq->value = (int)local->config.longRetryLimit;
} else {
vwrq->flags = IW_RETRY_LIMIT;
vwrq->value = (int)local->config.shortRetryLimit;
if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit)
- vwrq->flags |= IW_RETRY_MIN;
+ vwrq->flags |= IW_RETRY_SHORT;
}
return 0;
@@ -6990,6 +6990,7 @@ static int airo_set_power(struct net_device *dev,
local->config.rmode |= RXMODE_BC_MC_ADDR;
set_bit (FLAG_COMMIT, &local->flags);
case IW_POWER_ON:
+ /* This is broken, fixme ;-) */
break;
default:
return -EINVAL;
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 995c7bea589..0fc267d626d 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1656,13 +1656,13 @@ static int atmel_set_essid(struct net_device *dev,
priv->connect_to_any_BSS = 0;
/* Check the size of the string */
- if (dwrq->length > MAX_SSID_LENGTH + 1)
+ if (dwrq->length > MAX_SSID_LENGTH)
return -E2BIG;
if (index != 0)
return -EINVAL;
- memcpy(priv->new_SSID, extra, dwrq->length - 1);
- priv->new_SSID_size = dwrq->length - 1;
+ memcpy(priv->new_SSID, extra, dwrq->length);
+ priv->new_SSID_size = dwrq->length;
}
return -EINPROGRESS;
@@ -2120,9 +2120,9 @@ static int atmel_set_retry(struct net_device *dev,
struct atmel_private *priv = netdev_priv(dev);
if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
- if (vwrq->flags & IW_RETRY_MAX)
+ if (vwrq->flags & IW_RETRY_LONG)
priv->long_retry = vwrq->value;
- else if (vwrq->flags & IW_RETRY_MIN)
+ else if (vwrq->flags & IW_RETRY_SHORT)
priv->short_retry = vwrq->value;
else {
/* No modifier : set both */
@@ -2144,15 +2144,15 @@ static int atmel_get_retry(struct net_device *dev,
vwrq->disabled = 0; /* Can't be disabled */
- /* Note : by default, display the min retry number */
- if (vwrq->flags & IW_RETRY_MAX) {
- vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ /* Note : by default, display the short retry number */
+ if (vwrq->flags & IW_RETRY_LONG) {
+ vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
vwrq->value = priv->long_retry;
} else {
vwrq->flags = IW_RETRY_LIMIT;
vwrq->value = priv->short_retry;
if (priv->long_retry != priv->short_retry)
- vwrq->flags |= IW_RETRY_MIN;
+ vwrq->flags |= IW_RETRY_SHORT;
}
return 0;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 6d4ea36bc56..d6a8bf09878 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -666,7 +666,6 @@ struct bcm43xx_noise_calculation {
};
struct bcm43xx_stats {
- u8 link_quality;
u8 noise;
struct iw_statistics wstats;
/* Store the last TX/RX times here for updating the leds. */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index cb9a3ae8463..eb65db7393b 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2405,9 +2405,10 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
BCM43xx_UCODE_TIME) & 0x1f);
if ( value16 > 0x128 ) {
- dprintk(KERN_ERR PFX
- "Firmware: no support for microcode rev > 0x128\n");
- err = -1;
+ printk(KERN_ERR PFX
+ "Firmware: no support for microcode extracted "
+ "from version 4.x binary drivers.\n");
+ err = -EOPNOTSUPP;
goto err_release_fw;
}
@@ -3169,8 +3170,7 @@ static void bcm43xx_periodic_work_handler(void *d)
* be preemtible.
*/
mutex_lock(&bcm->mutex);
- netif_stop_queue(bcm->net_dev);
- synchronize_net();
+ netif_tx_disable(bcm->net_dev);
spin_lock_irqsave(&bcm->irq_lock, flags);
bcm43xx_mac_suspend(bcm);
if (bcm43xx_using_pio(bcm))
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index eafd0f66268..52ce2a9334f 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -361,7 +361,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
if (phy->rev <= 2)
for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]);
- else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
+ else if ((phy->rev >= 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]);
else
@@ -371,7 +371,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
if (phy->rev == 2)
for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]);
- else if ((phy->rev > 2) && (phy->rev <= 7))
+ else if ((phy->rev > 2) && (phy->rev <= 8))
for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]);
@@ -1197,7 +1197,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
if (phy->rev == 1)
bcm43xx_phy_initb5(bcm);
- else if (phy->rev >= 2 && phy->rev <= 7)
+ else
bcm43xx_phy_initb6(bcm);
if (phy->rev >= 2 || phy->connected)
bcm43xx_phy_inita(bcm);
@@ -1241,23 +1241,22 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
bcm43xx_phy_lo_g_measure(bcm);
} else {
if (radio->version == 0x2050 && radio->revision == 8) {
- //FIXME
+ bcm43xx_radio_write16(bcm, 0x0052,
+ (radio->txctl1 << 4) | radio->txctl2);
} else {
bcm43xx_radio_write16(bcm, 0x0052,
(bcm43xx_radio_read16(bcm, 0x0052)
& 0xFFF0) | radio->txctl1);
}
if (phy->rev >= 6) {
- /*
bcm43xx_phy_write(bcm, 0x0036,
(bcm43xx_phy_read(bcm, 0x0036)
- & 0xF000) | (FIXME << 12));
- */
+ & 0xF000) | (radio->txctl2 << 12));
}
if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
bcm43xx_phy_write(bcm, 0x002E, 0x8075);
else
- bcm43xx_phy_write(bcm, 0x003E, 0x807F);
+ bcm43xx_phy_write(bcm, 0x002E, 0x807F);
if (phy->rev < 2)
bcm43xx_phy_write(bcm, 0x002F, 0x0101);
else
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index 888077fc14c..9b7b15cf656 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -334,7 +334,7 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev,
size_t len;
mutex_lock(&bcm->mutex);
- len = strlen(bcm->nick) + 1;
+ len = strlen(bcm->nick);
memcpy(extra, bcm->nick, len);
data->data.length = (__u16)len;
data->data.flags = 1;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
index c0efbfe605a..0159e4e9320 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
@@ -496,15 +496,14 @@ int bcm43xx_rx(struct bcm43xx_private *bcm,
stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,
!!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ),
!!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ));
-//TODO stats.noise =
+ stats.noise = bcm->stats.noise;
if (is_ofdm)
stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp);
else
stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp);
stats.received_channel = radio->channel;
-//TODO stats.control =
stats.mask = IEEE80211_STATMASK_SIGNAL |
-//TODO IEEE80211_STATMASK_NOISE |
+ IEEE80211_STATMASK_NOISE |
IEEE80211_STATMASK_RATE |
IEEE80211_STATMASK_RSSI;
if (phy->type == BCM43xx_PHYTYPE_A)
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 7a4978516ea..d061fb3443f 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1412,9 +1412,9 @@ static int prism2_ioctl_siwretry(struct net_device *dev,
/* what could be done, if firmware would support this.. */
if (rrq->flags & IW_RETRY_LIMIT) {
- if (rrq->flags & IW_RETRY_MAX)
+ if (rrq->flags & IW_RETRY_LONG)
HFA384X_RID_LONGRETRYLIMIT = rrq->value;
- else if (rrq->flags & IW_RETRY_MIN)
+ else if (rrq->flags & IW_RETRY_SHORT)
HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
else {
HFA384X_RID_LONGRETRYLIMIT = rrq->value;
@@ -1468,14 +1468,14 @@ static int prism2_ioctl_giwretry(struct net_device *dev,
rrq->value = le16_to_cpu(altretry);
else
rrq->value = local->manual_retry_count;
- } else if ((rrq->flags & IW_RETRY_MAX)) {
- rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ } else if ((rrq->flags & IW_RETRY_LONG)) {
+ rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
rrq->value = longretry;
} else {
rrq->flags = IW_RETRY_LIMIT;
rrq->value = shortretry;
if (shortretry != longretry)
- rrq->flags |= IW_RETRY_MIN;
+ rrq->flags |= IW_RETRY_SHORT;
}
}
return 0;
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index b4d81a04c89..6c5add701a6 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -6958,7 +6958,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
}
if (wrqu->essid.flags && wrqu->essid.length) {
- length = wrqu->essid.length - 1;
+ length = wrqu->essid.length;
essid = extra;
}
@@ -7051,7 +7051,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
struct ipw2100_priv *priv = ieee80211_priv(dev);
- wrqu->data.length = strlen(priv->nick) + 1;
+ wrqu->data.length = strlen(priv->nick);
memcpy(extra, priv->nick, wrqu->data.length);
wrqu->data.flags = 1; /* active */
@@ -7343,14 +7343,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
goto done;
}
- if (wrqu->retry.flags & IW_RETRY_MIN) {
+ if (wrqu->retry.flags & IW_RETRY_SHORT) {
err = ipw2100_set_short_retry(priv, wrqu->retry.value);
IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
wrqu->retry.value);
goto done;
}
- if (wrqu->retry.flags & IW_RETRY_MAX) {
+ if (wrqu->retry.flags & IW_RETRY_LONG) {
err = ipw2100_set_long_retry(priv, wrqu->retry.value);
IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
wrqu->retry.value);
@@ -7383,14 +7383,14 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
return -EINVAL;
- if (wrqu->retry.flags & IW_RETRY_MAX) {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ if (wrqu->retry.flags & IW_RETRY_LONG) {
+ wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
wrqu->retry.value = priv->long_retry_limit;
} else {
wrqu->retry.flags =
(priv->short_retry_limit !=
priv->long_retry_limit) ?
- IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT;
+ IW_RETRY_LIMIT | IW_RETRY_SHORT : IW_RETRY_LIMIT;
wrqu->retry.value = priv->short_retry_limit;
}
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 7358664e090..5685d7ba55b 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -8875,8 +8875,6 @@ static int ipw_wx_set_essid(struct net_device *dev,
}
length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE);
- if (!extra[length - 1])
- length--;
priv->config |= CFG_STATIC_ESSID;
@@ -8953,7 +8951,7 @@ static int ipw_wx_get_nick(struct net_device *dev,
struct ipw_priv *priv = ieee80211_priv(dev);
IPW_DEBUG_WX("Getting nick\n");
mutex_lock(&priv->mutex);
- wrqu->data.length = strlen(priv->nick) + 1;
+ wrqu->data.length = strlen(priv->nick);
memcpy(extra, priv->nick, wrqu->data.length);
wrqu->data.flags = 1; /* active */
mutex_unlock(&priv->mutex);
@@ -9276,9 +9274,9 @@ static int ipw_wx_set_retry(struct net_device *dev,
return -EINVAL;
mutex_lock(&priv->mutex);
- if (wrqu->retry.flags & IW_RETRY_MIN)
+ if (wrqu->retry.flags & IW_RETRY_SHORT)
priv->short_retry_limit = (u8) wrqu->retry.value;
- else if (wrqu->retry.flags & IW_RETRY_MAX)
+ else if (wrqu->retry.flags & IW_RETRY_LONG)
priv->long_retry_limit = (u8) wrqu->retry.value;
else {
priv->short_retry_limit = (u8) wrqu->retry.value;
@@ -9307,11 +9305,11 @@ static int ipw_wx_get_retry(struct net_device *dev,
return -EINVAL;
}
- if (wrqu->retry.flags & IW_RETRY_MAX) {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ if (wrqu->retry.flags & IW_RETRY_LONG) {
+ wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
wrqu->retry.value = priv->long_retry_limit;
- } else if (wrqu->retry.flags & IW_RETRY_MIN) {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
+ } else if (wrqu->retry.flags & IW_RETRY_SHORT) {
+ wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
wrqu->retry.value = priv->short_retry_limit;
} else {
wrqu->retry.flags = IW_RETRY_LIMIT;
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 1840b69e3cb..9e19a963feb 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -3037,7 +3037,7 @@ static int orinoco_ioctl_getessid(struct net_device *dev,
}
erq->flags = 1;
- erq->length = strlen(essidbuf) + 1;
+ erq->length = strlen(essidbuf);
return 0;
}
@@ -3078,7 +3078,7 @@ static int orinoco_ioctl_getnick(struct net_device *dev,
memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
orinoco_unlock(priv, &flags);
- nrq->length = strlen(nickbuf)+1;
+ nrq->length = strlen(nickbuf);
return 0;
}
@@ -3575,14 +3575,14 @@ static int orinoco_ioctl_getretry(struct net_device *dev,
rrq->value = lifetime * 1000; /* ??? */
} else {
/* By default, display the min number */
- if ((rrq->flags & IW_RETRY_MAX)) {
- rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ if ((rrq->flags & IW_RETRY_LONG)) {
+ rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
rrq->value = long_limit;
} else {
rrq->flags = IW_RETRY_LIMIT;
rrq->value = short_limit;
if(short_limit != long_limit)
- rrq->flags |= IW_RETRY_MIN;
+ rrq->flags |= IW_RETRY_SHORT;
}
}
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index c09fbf733b3..286325ca329 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -742,9 +742,9 @@ prism54_set_essid(struct net_device *ndev, struct iw_request_info *info,
/* Check if we were asked for `any' */
if (dwrq->flags && dwrq->length) {
- if (dwrq->length > min(33, IW_ESSID_MAX_SIZE + 1))
+ if (dwrq->length > 32)
return -E2BIG;
- essid.length = dwrq->length - 1;
+ essid.length = dwrq->length;
memcpy(essid.octets, extra, dwrq->length);
} else
essid.length = 0;
@@ -814,7 +814,7 @@ prism54_get_nick(struct net_device *ndev, struct iw_request_info *info,
dwrq->length = 0;
down_read(&priv->mib_sem);
- dwrq->length = strlen(priv->nickname) + 1;
+ dwrq->length = strlen(priv->nickname);
memcpy(extra, priv->nickname, dwrq->length);
up_read(&priv->mib_sem);
@@ -992,9 +992,9 @@ prism54_set_retry(struct net_device *ndev, struct iw_request_info *info,
return -EINVAL;
if (vwrq->flags & IW_RETRY_LIMIT) {
- if (vwrq->flags & IW_RETRY_MIN)
+ if (vwrq->flags & IW_RETRY_SHORT)
slimit = vwrq->value;
- else if (vwrq->flags & IW_RETRY_MAX)
+ else if (vwrq->flags & IW_RETRY_LONG)
llimit = vwrq->value;
else {
/* we are asked to set both */
@@ -1035,18 +1035,18 @@ prism54_get_retry(struct net_device *ndev, struct iw_request_info *info,
mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r);
vwrq->value = r.u * 1024;
vwrq->flags = IW_RETRY_LIFETIME;
- } else if ((vwrq->flags & IW_RETRY_MAX)) {
+ } else if ((vwrq->flags & IW_RETRY_LONG)) {
/* we are asked for the long retry limit */
rvalue |=
mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r);
vwrq->value = r.u;
- vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
} else {
/* default. get the short retry limit */
rvalue |=
mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r);
vwrq->value = r.u;
- vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
+ vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
}
return rvalue;
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 4574290f971..e82548ea609 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1173,7 +1173,7 @@ static int ray_set_essid(struct net_device *dev,
return -EOPNOTSUPP;
} else {
/* Check the size of the string */
- if(dwrq->length > IW_ESSID_MAX_SIZE + 1) {
+ if(dwrq->length > IW_ESSID_MAX_SIZE) {
return -E2BIG;
}
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index e0d294c1297..e3ae5f60d5b 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1802,15 +1802,15 @@ static int wl3501_get_retry(struct net_device *dev,
&retry, sizeof(retry));
if (rc)
goto out;
- if (wrqu->retry.flags & IW_RETRY_MAX) {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ if (wrqu->retry.flags & IW_RETRY_LONG) {
+ wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
goto set_value;
}
rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_SHORT_RETRY_LIMIT,
&retry, sizeof(retry));
if (rc)
goto out;
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
+ wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
set_value:
wrqu->retry.value = retry;
wrqu->retry.disabled = 0;
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index c52e9bcf8d0..a44dda952c6 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -1218,7 +1218,7 @@ static int zd1201_set_essid(struct net_device *dev,
return -EINVAL;
if (data->length < 1)
data->length = 1;
- zd->essidlen = data->length-1;
+ zd->essidlen = data->length;
memset(zd->essid, 0, IW_ESSID_MAX_SIZE+1);
memcpy(zd->essid, essid, data->length);
return zd1201_join(zd, zd->essid, zd->essidlen);
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 7c4e32cf0d4..aa661b2b76c 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -249,7 +249,6 @@ int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
{
int r;
- ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex);
r = zd_ioread16_locked(chip, value, addr);
mutex_unlock(&chip->mutex);
@@ -260,7 +259,6 @@ int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value)
{
int r;
- ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex);
r = zd_ioread32_locked(chip, value, addr);
mutex_unlock(&chip->mutex);
@@ -271,7 +269,6 @@ int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value)
{
int r;
- ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex);
r = zd_iowrite16_locked(chip, value, addr);
mutex_unlock(&chip->mutex);
@@ -282,7 +279,6 @@ int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value)
{
int r;
- ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex);
r = zd_iowrite32_locked(chip, value, addr);
mutex_unlock(&chip->mutex);
@@ -294,7 +290,6 @@ int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses,
{
int r;
- ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex);
r = zd_ioread32v_locked(chip, values, addresses, count);
mutex_unlock(&chip->mutex);
@@ -306,7 +301,6 @@ int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
{
int r;
- ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex);
r = zd_iowrite32a_locked(chip, ioreqs, count);
mutex_unlock(&chip->mutex);
@@ -331,13 +325,22 @@ static int read_pod(struct zd_chip *chip, u8 *rf_type)
chip->patch_cr157 = (value >> 13) & 0x1;
chip->patch_6m_band_edge = (value >> 21) & 0x1;
chip->new_phy_layout = (value >> 31) & 0x1;
+ chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
+ chip->supports_tx_led = 1;
+ if (value & (1 << 24)) { /* LED scenario */
+ if (value & (1 << 29))
+ chip->supports_tx_led = 0;
+ }
dev_dbg_f(zd_chip_dev(chip),
"RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
- "patch 6M %d new PHY %d\n",
+ "patch 6M %d new PHY %d link LED%d tx led %d\n",
zd_rf_name(*rf_type), *rf_type,
chip->pa_type, chip->patch_cck_gain,
- chip->patch_cr157, chip->patch_6m_band_edge, chip->new_phy_layout);
+ chip->patch_cr157, chip->patch_6m_band_edge,
+ chip->new_phy_layout,
+ chip->link_led == LED1 ? 1 : 2,
+ chip->supports_tx_led);
return 0;
error:
*rf_type = 0;
@@ -1181,7 +1184,7 @@ static int update_pwr_int(struct zd_chip *chip, u8 channel)
u8 value = chip->pwr_int_values[channel - 1];
dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n",
channel, value);
- return zd_iowrite32_locked(chip, value, CR31);
+ return zd_iowrite16_locked(chip, value, CR31);
}
static int update_pwr_cal(struct zd_chip *chip, u8 channel)
@@ -1189,12 +1192,12 @@ static int update_pwr_cal(struct zd_chip *chip, u8 channel)
u8 value = chip->pwr_cal_values[channel-1];
dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n",
channel, value);
- return zd_iowrite32_locked(chip, value, CR68);
+ return zd_iowrite16_locked(chip, value, CR68);
}
static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
{
- struct zd_ioreq32 ioreqs[3];
+ struct zd_ioreq16 ioreqs[3];
ioreqs[0].addr = CR67;
ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
@@ -1206,7 +1209,7 @@ static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
dev_dbg_f(zd_chip_dev(chip),
"channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n",
channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value);
- return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+ return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
}
static int update_channel_integration_and_calibration(struct zd_chip *chip,
@@ -1218,7 +1221,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
if (r)
return r;
if (chip->is_zd1211b) {
- static const struct zd_ioreq32 ioreqs[] = {
+ static const struct zd_ioreq16 ioreqs[] = {
{ CR69, 0x28 },
{},
{ CR69, 0x2a },
@@ -1230,7 +1233,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
r = update_pwr_cal(chip, channel);
if (r)
return r;
- r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+ r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
if (r)
return r;
}
@@ -1252,7 +1255,7 @@ static int patch_cck_gain(struct zd_chip *chip)
if (r)
return r;
dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
- return zd_iowrite32_locked(chip, value & 0xff, CR47);
+ return zd_iowrite16_locked(chip, value & 0xff, CR47);
}
int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
@@ -1295,89 +1298,60 @@ u8 zd_chip_get_channel(struct zd_chip *chip)
return channel;
}
-static u16 led_mask(int led)
+int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
{
- switch (led) {
- case 1:
- return LED1;
- case 2:
- return LED2;
- default:
- return 0;
- }
-}
-
-static int read_led_reg(struct zd_chip *chip, u16 *status)
-{
- ZD_ASSERT(mutex_is_locked(&chip->mutex));
- return zd_ioread16_locked(chip, status, CR_LED);
-}
-
-static int write_led_reg(struct zd_chip *chip, u16 status)
-{
- ZD_ASSERT(mutex_is_locked(&chip->mutex));
- return zd_iowrite16_locked(chip, status, CR_LED);
-}
+ static const zd_addr_t a[] = {
+ FW_LINK_STATUS,
+ CR_LED,
+ };
-int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status)
-{
- int r, ret;
- u16 mask = led_mask(led);
- u16 reg;
+ int r;
+ u16 v[ARRAY_SIZE(a)];
+ struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = {
+ [0] = { FW_LINK_STATUS },
+ [1] = { CR_LED },
+ };
+ u16 other_led;
- if (!mask)
- return -EINVAL;
mutex_lock(&chip->mutex);
- r = read_led_reg(chip, &reg);
+ r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a));
if (r)
- return r;
+ goto out;
+
+ other_led = chip->link_led == LED1 ? LED2 : LED1;
+
switch (status) {
- case LED_STATUS:
- return (reg & mask) ? LED_ON : LED_OFF;
case LED_OFF:
- reg &= ~mask;
- ret = LED_OFF;
+ ioreqs[0].value = FW_LINK_OFF;
+ ioreqs[1].value = v[1] & ~(LED1|LED2);
break;
- case LED_FLIP:
- reg ^= mask;
- ret = (reg&mask) ? LED_ON : LED_OFF;
+ case LED_SCANNING:
+ ioreqs[0].value = FW_LINK_OFF;
+ ioreqs[1].value = v[1] & ~other_led;
+ if (get_seconds() % 3 == 0) {
+ ioreqs[1].value &= ~chip->link_led;
+ } else {
+ ioreqs[1].value |= chip->link_led;
+ }
break;
- case LED_ON:
- reg |= mask;
- ret = LED_ON;
+ case LED_ASSOCIATED:
+ ioreqs[0].value = FW_LINK_TX;
+ ioreqs[1].value = v[1] & ~other_led;
+ ioreqs[1].value |= chip->link_led;
break;
default:
- return -EINVAL;
- }
- r = write_led_reg(chip, reg);
- if (r) {
- ret = r;
+ r = -EINVAL;
goto out;
}
-out:
- mutex_unlock(&chip->mutex);
- return r;
-}
-
-int zd_chip_led_flip(struct zd_chip *chip, int led,
- const unsigned int *phases_msecs, unsigned int count)
-{
- int i, r;
- enum led_status status;
- r = zd_chip_led_status(chip, led, LED_STATUS);
- if (r)
- return r;
- status = r;
- for (i = 0; i < count; i++) {
- r = zd_chip_led_status(chip, led, LED_FLIP);
- if (r < 0)
+ if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) {
+ r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+ if (r)
goto out;
- msleep(phases_msecs[i]);
}
-
+ r = 0;
out:
- zd_chip_led_status(chip, led, status);
+ mutex_unlock(&chip->mutex);
return r;
}
@@ -1679,4 +1653,3 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip,
return 0;
}
-
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index 4b125085989..ae59597ce4e 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -428,6 +428,7 @@
/* masks for controlling LEDs */
#define LED1 0x0100
#define LED2 0x0200
+#define LED_SW 0x0400
/* Seems to indicate that the configuration is over.
*/
@@ -629,6 +630,10 @@
#define FW_SOFT_RESET FW_REG(4)
#define FW_FLASH_CHK FW_REG(5)
+#define FW_LINK_OFF 0x0
+#define FW_LINK_TX 0x1
+/* 0x2 - link led on? */
+
enum {
CR_BASE_OFFSET = 0x9000,
FW_START_OFFSET = 0xee00,
@@ -663,8 +668,11 @@ struct zd_chip {
u8 pwr_int_values[E2P_CHANNEL_COUNT];
/* SetPointOFDM in the vendor driver */
u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT];
- u8 pa_type:4, patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
- new_phy_layout:1, is_zd1211b:1;
+ u16 link_led;
+ unsigned int pa_type:4,
+ patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
+ new_phy_layout:1,
+ is_zd1211b:1, supports_tx_led:1;
};
static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb)
@@ -812,15 +820,12 @@ int zd_chip_lock_phy_regs(struct zd_chip *chip);
int zd_chip_unlock_phy_regs(struct zd_chip *chip);
enum led_status {
- LED_OFF = 0,
- LED_ON = 1,
- LED_FLIP = 2,
- LED_STATUS = 3,
+ LED_OFF = 0,
+ LED_SCANNING = 1,
+ LED_ASSOCIATED = 2,
};
-int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status);
-int zd_chip_led_flip(struct zd_chip *chip, int led,
- const unsigned int *phases_msecs, unsigned int count);
+int zd_chip_control_leds(struct zd_chip *chip, enum led_status status);
int zd_set_beacon_interval(struct zd_chip *chip, u32 interval);
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 1989f1c05fb..2d12837052b 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -33,6 +33,10 @@
static void ieee_init(struct ieee80211_device *ieee);
static void softmac_init(struct ieee80211softmac_device *sm);
+static void housekeeping_init(struct zd_mac *mac);
+static void housekeeping_enable(struct zd_mac *mac);
+static void housekeeping_disable(struct zd_mac *mac);
+
int zd_mac_init(struct zd_mac *mac,
struct net_device *netdev,
struct usb_interface *intf)
@@ -46,6 +50,7 @@ int zd_mac_init(struct zd_mac *mac,
ieee_init(ieee);
softmac_init(ieee80211_priv(netdev));
zd_chip_init(&mac->chip, netdev, intf);
+ housekeeping_init(mac);
return 0;
}
@@ -178,6 +183,7 @@ int zd_mac_open(struct net_device *netdev)
if (r < 0)
goto disable_rx;
+ housekeeping_enable(mac);
ieee80211softmac_start(netdev);
return 0;
disable_rx:
@@ -204,6 +210,7 @@ int zd_mac_stop(struct net_device *netdev)
*/
zd_chip_disable_rx(chip);
+ housekeeping_disable(mac);
ieee80211softmac_stop(netdev);
zd_chip_disable_hwint(chip);
@@ -1080,3 +1087,46 @@ void zd_dump_rx_status(const struct rx_status *status)
}
}
#endif /* DEBUG */
+
+#define LINK_LED_WORK_DELAY HZ
+
+static void link_led_handler(void *p)
+{
+ struct zd_mac *mac = p;
+ struct zd_chip *chip = &mac->chip;
+ struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev);
+ int is_associated;
+ int r;
+
+ spin_lock_irq(&mac->lock);
+ is_associated = sm->associated != 0;
+ spin_unlock_irq(&mac->lock);
+
+ r = zd_chip_control_leds(chip,
+ is_associated ? LED_ASSOCIATED : LED_SCANNING);
+ if (r)
+ dev_err(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);
+
+ queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
+ LINK_LED_WORK_DELAY);
+}
+
+static void housekeeping_init(struct zd_mac *mac)
+{
+ INIT_WORK(&mac->housekeeping.link_led_work, link_led_handler, mac);
+}
+
+static void housekeeping_enable(struct zd_mac *mac)
+{
+ dev_dbg_f(zd_mac_dev(mac), "\n");
+ queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
+ 0);
+}
+
+static void housekeeping_disable(struct zd_mac *mac)
+{
+ dev_dbg_f(zd_mac_dev(mac), "\n");
+ cancel_rearming_delayed_workqueue(zd_workqueue,
+ &mac->housekeeping.link_led_work);
+ zd_chip_control_leds(&mac->chip, LED_OFF);
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 29b51fd7d4e..b8ea3de7924 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -120,6 +120,10 @@ enum mac_flags {
MAC_FIXED_CHANNEL = 0x01,
};
+struct housekeeping {
+ struct work_struct link_led_work;
+};
+
#define ZD_MAC_STATS_BUFFER_SIZE 16
struct zd_mac {
@@ -128,6 +132,7 @@ struct zd_mac {
struct net_device *netdev;
/* Unlocked reading possible */
struct iw_statistics iw_stats;
+ struct housekeeping housekeeping;
unsigned int stats_count;
u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c
index 440ef24b5fd..af3a7b36d07 100644
--- a/drivers/net/wireless/zd1211rw/zd_netdev.c
+++ b/drivers/net/wireless/zd1211rw/zd_netdev.c
@@ -82,7 +82,7 @@ static int iw_get_nick(struct net_device *netdev,
union iwreq_data *req, char *extra)
{
strcpy(extra, "zd1211");
- req->data.length = strlen(extra) + 1;
+ req->data.length = strlen(extra);
req->data.flags = 1;
return 0;
}
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 31027e52b04..5c265ad0485 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -24,6 +24,7 @@
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <linux/usb.h>
+#include <linux/workqueue.h>
#include <net/ieee80211.h>
#include "zd_def.h"
@@ -1112,12 +1113,20 @@ static struct usb_driver driver = {
.disconnect = disconnect,
};
+struct workqueue_struct *zd_workqueue;
+
static int __init usb_init(void)
{
int r;
pr_debug("usb_init()\n");
+ zd_workqueue = create_singlethread_workqueue(driver.name);
+ if (zd_workqueue == NULL) {
+ printk(KERN_ERR "%s: couldn't create workqueue\n", driver.name);
+ return -ENOMEM;
+ }
+
r = usb_register(&driver);
if (r) {
printk(KERN_ERR "usb_register() failed. Error number %d\n", r);
@@ -1132,6 +1141,7 @@ static void __exit usb_exit(void)
{
pr_debug("usb_exit()\n");
usb_deregister(&driver);
+ destroy_workqueue(zd_workqueue);
}
module_init(usb_init);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index ded39de5f72..e81a2d3cfff 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -238,4 +238,6 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits);
+extern struct workqueue_struct *zd_workqueue;
+
#endif /* _ZD_USB_H */