Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 1 Sep 2007 03:03:15 +0000 (20:03 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 1 Sep 2007 03:03:15 +0000 (20:03 -0700)
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6:
  - cxgb3 engine microcode load
  cxgb3 - Fix dev->priv usage
  qeth: Drop ARP packages on HiperSockets interface with NOARP attribute.
  qeth: provide specific message for OSA-adapters exclusively used
  qeth: crash during reboot after failing online setting
  qeth: Announce tx checksumming for qeth devices in TSO/EDDP mode
  qeth: dont return the return values of void functions.
  qeth: enforce a rate limit for inbound scatter gather messages
  qeth: ungrouping a device must not be interruptible
  netxen: fix crashes during module unload
  netxen: Avoid firmware load in PCI probe
  PS3: fix the bug that 'ifconfig down' would hang
  IOC3: Program UART predividers.

18 files changed:
drivers/infiniband/hw/cxgb3/cxio_hal.c
drivers/net/cxgb3/adapter.h
drivers/net/cxgb3/common.h
drivers/net/cxgb3/cxgb3_main.c
drivers/net/cxgb3/cxgb3_offload.c
drivers/net/cxgb3/cxgb3_offload.h
drivers/net/cxgb3/sge.c
drivers/net/cxgb3/t3_hw.c
drivers/net/cxgb3/t3cdev.h
drivers/net/ioc3-eth.c
drivers/net/netxen/netxen_nic_hdr.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/ps3_gelic_net.c
drivers/s390/net/qeth.h
drivers/s390/net/qeth_main.c
drivers/s390/net/qeth_mpc.h
drivers/s390/net/qeth_sys.c

index 1518b41482ae017467faab19246805da98033414..beb2a381467f75abf2ae04711c810bb224f80888 100644 (file)
@@ -916,7 +916,7 @@ int cxio_rdev_open(struct cxio_rdev *rdev_p)
        PDBG("%s opening rnic dev %s\n", __FUNCTION__, rdev_p->dev_name);
        memset(&rdev_p->ctrl_qp, 0, sizeof(rdev_p->ctrl_qp));
        if (!rdev_p->t3cdev_p)
-               rdev_p->t3cdev_p = T3CDEV(netdev_p);
+               rdev_p->t3cdev_p = dev2t3cdev(netdev_p);
        rdev_p->t3cdev_p->ulp = (void *) rdev_p;
        err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, RDMA_GET_PARAMS,
                                         &(rdev_p->rnic_info));
index ab72563b81ee569ce7f9a139203762dcc5598314..20e887de2545cb2951baa398402e2ae3c20a966f 100644 (file)
@@ -50,7 +50,9 @@ typedef irqreturn_t(*intr_handler_t) (int, void *);
 
 struct vlan_group;
 
+struct adapter;
 struct port_info {
+       struct adapter *adapter;
        struct vlan_group *vlan_grp;
        const struct port_type_info *port_type;
        u8 port_id;
index 16378004507ad65c253b0b6df22c4c600897e00f..2129210a67c11803aedefd49f06b7f15e72d1a54 100644 (file)
@@ -679,7 +679,8 @@ const struct adapter_info *t3_get_adapter_info(unsigned int board_id);
 int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data);
 int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data);
 int t3_seeprom_wp(struct adapter *adapter, int enable);
-int t3_check_tpsram_version(struct adapter *adapter);
+int t3_get_tp_version(struct adapter *adapter, u32 *vers);
+int t3_check_tpsram_version(struct adapter *adapter, int *must_load);
 int t3_check_tpsram(struct adapter *adapter, u8 *tp_ram, unsigned int size);
 int t3_set_proto_sram(struct adapter *adap, u8 *data);
 int t3_read_flash(struct adapter *adapter, unsigned int addr,
index dc5d26988bb3e912030ae2a35bb91020a45ca5f4..5ab319cfe5de8dc0000376ee9291c70474b50ed3 100644 (file)
@@ -358,11 +358,14 @@ static int init_dummy_netdevs(struct adapter *adap)
 
                for (j = 0; j < pi->nqsets - 1; j++) {
                        if (!adap->dummy_netdev[dummy_idx]) {
-                               nd = alloc_netdev(0, "", ether_setup);
+                               struct port_info *p;
+
+                               nd = alloc_netdev(sizeof(*p), "", ether_setup);
                                if (!nd)
                                        goto free_all;
 
-                               nd->priv = adap;
+                               p = netdev_priv(nd);
+                               p->adapter = adap;
                                nd->weight = 64;
                                set_bit(__LINK_STATE_START, &nd->state);
                                adap->dummy_netdev[dummy_idx] = nd;
@@ -482,7 +485,8 @@ static ssize_t attr_store(struct device *d, struct device_attribute *attr,
 #define CXGB3_SHOW(name, val_expr) \
 static ssize_t format_##name(struct net_device *dev, char *buf) \
 { \
-       struct adapter *adap = dev->priv; \
+       struct port_info *pi = netdev_priv(dev); \
+       struct adapter *adap = pi->adapter; \
        return sprintf(buf, "%u\n", val_expr); \
 } \
 static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
@@ -493,7 +497,8 @@ static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
 
 static ssize_t set_nfilters(struct net_device *dev, unsigned int val)
 {
-       struct adapter *adap = dev->priv;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adap = pi->adapter;
        int min_tids = is_offload(adap) ? MC5_MIN_TIDS : 0;
 
        if (adap->flags & FULL_INIT_DONE)
@@ -515,7 +520,8 @@ static ssize_t store_nfilters(struct device *d, struct device_attribute *attr,
 
 static ssize_t set_nservers(struct net_device *dev, unsigned int val)
 {
-       struct adapter *adap = dev->priv;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adap = pi->adapter;
 
        if (adap->flags & FULL_INIT_DONE)
                return -EBUSY;
@@ -556,9 +562,10 @@ static struct attribute_group cxgb3_attr_group = {.attrs = cxgb3_attrs };
 static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr,
                            char *buf, int sched)
 {
-       ssize_t len;
+       struct port_info *pi = netdev_priv(to_net_dev(d));
+       struct adapter *adap = pi->adapter;
        unsigned int v, addr, bpt, cpt;
-       struct adapter *adap = to_net_dev(d)->priv;
+       ssize_t len;
 
        addr = A_TP_TX_MOD_Q1_Q0_RATE_LIMIT - sched / 2;
        rtnl_lock();
@@ -581,10 +588,11 @@ static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr,
 static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr,
                             const char *buf, size_t len, int sched)
 {
+       struct port_info *pi = netdev_priv(to_net_dev(d));
+       struct adapter *adap = pi->adapter;
+       unsigned int val;
        char *endp;
        ssize_t ret;
-       unsigned int val;
-       struct adapter *adap = to_net_dev(d)->priv;
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
@@ -721,6 +729,7 @@ static void bind_qsets(struct adapter *adap)
 }
 
 #define FW_FNAME "t3fw-%d.%d.%d.bin"
+#define TPSRAM_NAME "t3%c_protocol_sram-%d.%d.%d.bin"
 
 static int upgrade_fw(struct adapter *adap)
 {
@@ -739,6 +748,71 @@ static int upgrade_fw(struct adapter *adap)
        }
        ret = t3_load_fw(adap, fw->data, fw->size);
        release_firmware(fw);
+
+       if (ret == 0)
+               dev_info(dev, "successful upgrade to firmware %d.%d.%d\n",
+                        FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO);
+       else
+               dev_err(dev, "failed to upgrade to firmware %d.%d.%d\n",
+                       FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO);
+       
+       return ret;
+}
+
+static inline char t3rev2char(struct adapter *adapter)
+{
+       char rev = 0;
+
+       switch(adapter->params.rev) {
+       case T3_REV_B:
+       case T3_REV_B2:
+               rev = 'b';
+               break;
+       }
+       return rev;
+}
+
+int update_tpsram(struct adapter *adap)
+{
+       const struct firmware *tpsram;
+       char buf[64];
+       struct device *dev = &adap->pdev->dev;
+       int ret;
+       char rev;
+       
+       rev = t3rev2char(adap);
+       if (!rev)
+               return 0;
+
+       snprintf(buf, sizeof(buf), TPSRAM_NAME, rev,
+                TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
+
+       ret = request_firmware(&tpsram, buf, dev);
+       if (ret < 0) {
+               dev_err(dev, "could not load TP SRAM: unable to load %s\n",
+                       buf);
+               return ret;
+       }
+       
+       ret = t3_check_tpsram(adap, tpsram->data, tpsram->size);
+       if (ret)
+               goto release_tpsram;    
+
+       ret = t3_set_proto_sram(adap, tpsram->data);
+       if (ret == 0)
+               dev_info(dev,
+                        "successful update of protocol engine "
+                        "to %d.%d.%d\n",
+                        TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
+       else
+               dev_err(dev, "failed to update of protocol engine %d.%d.%d\n",
+                       TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
+       if (ret)
+               dev_err(dev, "loading protocol SRAM failed\n");
+
+release_tpsram:
+       release_firmware(tpsram);
+       
        return ret;
 }
 
@@ -755,6 +829,7 @@ static int upgrade_fw(struct adapter *adap)
 static int cxgb_up(struct adapter *adap)
 {
        int err = 0;
+       int must_load;
 
        if (!(adap->flags & FULL_INIT_DONE)) {
                err = t3_check_fw_version(adap);
@@ -763,6 +838,13 @@ static int cxgb_up(struct adapter *adap)
                if (err)
                        goto out;
 
+               err = t3_check_tpsram_version(adap, &must_load);
+               if (err == -EINVAL) {
+                       err = update_tpsram(adap);
+                       if (err && must_load)
+                               goto out;
+               }
+
                err = init_dummy_netdevs(adap);
                if (err)
                        goto out;
@@ -858,8 +940,9 @@ static void schedule_chk_task(struct adapter *adap)
 
 static int offload_open(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
-       struct t3cdev *tdev = T3CDEV(dev);
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+       struct t3cdev *tdev = dev2t3cdev(dev);
        int adap_up = adapter->open_device_map & PORT_MASK;
        int err = 0;
 
@@ -924,10 +1007,10 @@ static int offload_close(struct t3cdev *tdev)
 
 static int cxgb_open(struct net_device *dev)
 {
-       int err;
-       struct adapter *adapter = dev->priv;
        struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        int other_ports = adapter->open_device_map & PORT_MASK;
+       int err;
 
        if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
                return err;
@@ -951,17 +1034,17 @@ static int cxgb_open(struct net_device *dev)
 
 static int cxgb_close(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
-       struct port_info *p = netdev_priv(dev);
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
 
-       t3_port_intr_disable(adapter, p->port_id);
+       t3_port_intr_disable(adapter, pi->port_id);
        netif_stop_queue(dev);
-       p->phy.ops->power_down(&p->phy, 1);
+       pi->phy.ops->power_down(&pi->phy, 1);
        netif_carrier_off(dev);
-       t3_mac_disable(&p->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
+       t3_mac_disable(&pi->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
 
        spin_lock(&adapter->work_lock); /* sync with update task */
-       clear_bit(p->port_id, &adapter->open_device_map);
+       clear_bit(pi->port_id, &adapter->open_device_map);
        spin_unlock(&adapter->work_lock);
 
        if (!(adapter->open_device_map & PORT_MASK))
@@ -976,13 +1059,13 @@ static int cxgb_close(struct net_device *dev)
 
 static struct net_device_stats *cxgb_get_stats(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
-       struct port_info *p = netdev_priv(dev);
-       struct net_device_stats *ns = &p->netstats;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+       struct net_device_stats *ns = &pi->netstats;
        const struct mac_stats *pstats;
 
        spin_lock(&adapter->stats_lock);
-       pstats = t3_mac_update_stats(&p->mac);
+       pstats = t3_mac_update_stats(&pi->mac);
        spin_unlock(&adapter->stats_lock);
 
        ns->tx_bytes = pstats->tx_octets;
@@ -1015,14 +1098,16 @@ static struct net_device_stats *cxgb_get_stats(struct net_device *dev)
 
 static u32 get_msglevel(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
 
        return adapter->msg_enable;
 }
 
 static void set_msglevel(struct net_device *dev, u32 val)
 {
-       struct adapter *adapter = dev->priv;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
 
        adapter->msg_enable = val;
 }
@@ -1096,10 +1181,13 @@ static int get_eeprom_len(struct net_device *dev)
 
 static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        u32 fw_vers = 0;
-       struct adapter *adapter = dev->priv;
+       u32 tp_vers = 0;
 
        t3_get_fw_version(adapter, &fw_vers);
+       t3_get_tp_version(adapter, &tp_vers);
 
        strcpy(info->driver, DRV_NAME);
        strcpy(info->version, DRV_VERSION);
@@ -1108,11 +1196,14 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
                strcpy(info->fw_version, "N/A");
        else {
                snprintf(info->fw_version, sizeof(info->fw_version),
-                        "%s %u.%u.%u",
+                        "%s %u.%u.%u TP %u.%u.%u",
                         G_FW_VERSION_TYPE(fw_vers) ? "T" : "N",
                         G_FW_VERSION_MAJOR(fw_vers),
                         G_FW_VERSION_MINOR(fw_vers),
-                        G_FW_VERSION_MICRO(fw_vers));
+                        G_FW_VERSION_MICRO(fw_vers),
+                        G_TP_VERSION_MAJOR(tp_vers),
+                        G_TP_VERSION_MINOR(tp_vers),
+                        G_TP_VERSION_MICRO(tp_vers));
        }
 }
 
@@ -1136,8 +1227,8 @@ static unsigned long collect_sge_port_stats(struct adapter *adapter,
 static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
                      u64 *data)
 {
-       struct adapter *adapter = dev->priv;
        struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        const struct mac_stats *s;
 
        spin_lock(&adapter->stats_lock);
@@ -1205,7 +1296,8 @@ static inline void reg_block_dump(struct adapter *ap, void *buf,
 static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
                     void *buf)
 {
-       struct adapter *ap = dev->priv;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *ap = pi->adapter;
 
        /*
         * Version scheme:
@@ -1246,8 +1338,9 @@ static int restart_autoneg(struct net_device *dev)
 
 static int cxgb3_phys_id(struct net_device *dev, u32 data)
 {
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        int i;
-       struct adapter *adapter = dev->priv;
 
        if (data == 0)
                data = 2;
@@ -1408,8 +1501,8 @@ static int set_rx_csum(struct net_device *dev, u32 data)
 
 static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 {
-       const struct adapter *adapter = dev->priv;
-       const struct port_info *pi = netdev_priv(dev);
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        const struct qset_params *q = &adapter->params.sge.qset[pi->first_qset];
 
        e->rx_max_pending = MAX_RX_BUFFERS;
@@ -1425,10 +1518,10 @@ static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 
 static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 {
-       int i;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        struct qset_params *q;
-       struct adapter *adapter = dev->priv;
-       const struct port_info *pi = netdev_priv(dev);
+       int i;
 
        if (e->rx_pending > MAX_RX_BUFFERS ||
            e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS ||
@@ -1457,7 +1550,8 @@ static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 
 static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 {
-       struct adapter *adapter = dev->priv;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        struct qset_params *qsp = &adapter->params.sge.qset[0];
        struct sge_qset *qs = &adapter->sge.qs[0];
 
@@ -1471,7 +1565,8 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 
 static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 {
-       struct adapter *adapter = dev->priv;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        struct qset_params *q = adapter->params.sge.qset;
 
        c->rx_coalesce_usecs = q->coalesce_usecs;
@@ -1481,8 +1576,9 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
                      u8 * data)
 {
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        int i, err = 0;
-       struct adapter *adapter = dev->priv;
 
        u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL);
        if (!buf)
@@ -1501,10 +1597,11 @@ static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
 static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                      u8 * data)
 {
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+       u32 aligned_offset, aligned_len, *p;
        u8 *buf;
        int err = 0;
-       u32 aligned_offset, aligned_len, *p;
-       struct adapter *adapter = dev->priv;
 
        if (eeprom->magic != EEPROM_MAGIC)
                return -EINVAL;
@@ -1592,9 +1689,10 @@ static int in_range(int val, int lo, int hi)
 
 static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
 {
-       int ret;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        u32 cmd;
-       struct adapter *adapter = dev->priv;
+       int ret;
 
        if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
                return -EFAULT;
@@ -1923,10 +2021,10 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
 
 static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 {
-       int ret, mmd;
-       struct adapter *adapter = dev->priv;
-       struct port_info *pi = netdev_priv(dev);
        struct mii_ioctl_data *data = if_mii(req);
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+       int ret, mmd;
 
        switch (cmd) {
        case SIOCGMIIPHY:
@@ -1994,9 +2092,9 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 
 static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
 {
-       int ret;
-       struct adapter *adapter = dev->priv;
        struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+       int ret;
 
        if (new_mtu < 81)       /* accommodate SACK */
                return -EINVAL;
@@ -2013,8 +2111,8 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
 
 static int cxgb_set_mac_addr(struct net_device *dev, void *p)
 {
-       struct adapter *adapter = dev->priv;
        struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        struct sockaddr *addr = p;
 
        if (!is_valid_ether_addr(addr->sa_data))
@@ -2050,8 +2148,8 @@ static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p)
 
 static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
 {
-       struct adapter *adapter = dev->priv;
        struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
 
        pi->vlan_grp = grp;
        if (adapter->params.rev > 0)
@@ -2070,8 +2168,8 @@ static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void cxgb_netpoll(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
        struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        int qidx;
 
        for (qidx = pi->first_qset; qidx < pi->first_qset + pi->nqsets; qidx++) {
@@ -2088,42 +2186,6 @@ static void cxgb_netpoll(struct net_device *dev)
 }
 #endif
 
-#define TPSRAM_NAME "t3%c_protocol_sram-%d.%d.%d.bin"
-int update_tpsram(struct adapter *adap)
-{
-       const struct firmware *tpsram;
-       char buf[64];
-       struct device *dev = &adap->pdev->dev;
-       int ret;
-       char rev;
-       
-       rev = adap->params.rev == T3_REV_B2 ? 'b' : 'a';
-
-       snprintf(buf, sizeof(buf), TPSRAM_NAME, rev,
-                TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
-
-       ret = request_firmware(&tpsram, buf, dev);
-       if (ret < 0) {
-               dev_err(dev, "could not load TP SRAM: unable to load %s\n",
-                       buf);
-               return ret;
-       }
-       
-       ret = t3_check_tpsram(adap, tpsram->data, tpsram->size);
-       if (ret)
-               goto release_tpsram;    
-
-       ret = t3_set_proto_sram(adap, tpsram->data);
-       if (ret)
-               dev_err(dev, "loading protocol SRAM failed\n");
-
-release_tpsram:
-       release_firmware(tpsram);
-       
-       return ret;
-}
-
-
 /*
  * Periodic accumulation of MAC statistics.
  */
@@ -2433,6 +2495,7 @@ static int __devinit init_one(struct pci_dev *pdev,
 
                adapter->port[i] = netdev;
                pi = netdev_priv(netdev);
+               pi->adapter = adapter;
                pi->rx_csum_offload = 1;
                pi->nqsets = 1;
                pi->first_qset = i;
@@ -2442,7 +2505,6 @@ static int __devinit init_one(struct pci_dev *pdev,
                netdev->irq = pdev->irq;
                netdev->mem_start = mmio_start;
                netdev->mem_end = mmio_start + mmio_len - 1;
-               netdev->priv = adapter;
                netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
                netdev->features |= NETIF_F_LLTX;
                if (pci_using_dac)
@@ -2467,18 +2529,11 @@ static int __devinit init_one(struct pci_dev *pdev,
                SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
        }
 
-       pci_set_drvdata(pdev, adapter->port[0]);
+       pci_set_drvdata(pdev, adapter);
        if (t3_prep_adapter(adapter, ai, 1) < 0) {
                err = -ENODEV;
                goto out_free_dev;
        }
-
-       err = t3_check_tpsram_version(adapter);
-       if (err == -EINVAL)
-               err = update_tpsram(adapter);
-
-       if (err)
-               goto out_free_dev;
                
        /*
         * The card is now ready to go.  If any errors occur during device
@@ -2547,11 +2602,10 @@ out_release_regions:
 
 static void __devexit remove_one(struct pci_dev *pdev)
 {
-       struct net_device *dev = pci_get_drvdata(pdev);
+       struct adapter *adapter = pci_get_drvdata(pdev);
 
-       if (dev) {
+       if (adapter) {
                int i;
-               struct adapter *adapter = dev->priv;
 
                t3_sge_stop(adapter);
                sysfs_remove_group(&adapter->port[0]->dev.kobj,
index e620ed4c3ff0b5fb7aaa8650cc0315f2f4a714f8..bdff7baeb59da4d5683270d50a1cea9da5fcb845 100644 (file)
@@ -593,6 +593,16 @@ int cxgb3_alloc_stid(struct t3cdev *tdev, struct cxgb3_client *client,
 
 EXPORT_SYMBOL(cxgb3_alloc_stid);
 
+/* Get the t3cdev associated with a net_device */
+struct t3cdev *dev2t3cdev(struct net_device *dev)
+{
+       const struct port_info *pi = netdev_priv(dev);
+
+       return (struct t3cdev *)pi->adapter;
+}
+
+EXPORT_SYMBOL(dev2t3cdev);
+
 static int do_smt_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
 {
        struct cpl_smt_write_rpl *rpl = cplhdr(skb);
@@ -925,7 +935,7 @@ void cxgb_neigh_update(struct neighbour *neigh)
        struct net_device *dev = neigh->dev;
 
        if (dev && (is_offloading(dev))) {
-               struct t3cdev *tdev = T3CDEV(dev);
+               struct t3cdev *tdev = dev2t3cdev(dev);
 
                BUG_ON(!tdev);
                t3_l2t_update(tdev, neigh);
@@ -973,9 +983,9 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
                       "device ignored.\n", __FUNCTION__);
                return;
        }
-       tdev = T3CDEV(olddev);
+       tdev = dev2t3cdev(olddev);
        BUG_ON(!tdev);
-       if (tdev != T3CDEV(newdev)) {
+       if (tdev != dev2t3cdev(newdev)) {
                printk(KERN_WARNING "%s: Redirect to different "
                       "offload device ignored.\n", __FUNCTION__);
                return;
index f15446a32efca176c2c1c0ddfb442a399bcd046e..7a379138b5a6ebe757da3ce5c86abfd37174fc46 100644 (file)
@@ -51,6 +51,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter);
 
 void cxgb3_set_dummy_ops(struct t3cdev *dev);
 
+struct t3cdev *dev2t3cdev(struct net_device *dev);
+
 /*
  * Client registration.  Users of T3 driver must register themselves.
  * The T3 driver will call the add function of every client for each T3
index a2cfd68ac757555e42b13309f019146f6a6f00e4..58a5f60521ed87194db262b5a2577e7df90c02d7 100644 (file)
@@ -1073,7 +1073,7 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned int ndesc, pidx, credits, gen, compl;
        const struct port_info *pi = netdev_priv(dev);
-       struct adapter *adap = dev->priv;
+       struct adapter *adap = pi->adapter;
        struct sge_qset *qs = dev2qset(dev);
        struct sge_txq *q = &qs->txq[TXQ_ETH];
 
@@ -1326,7 +1326,8 @@ static void restart_ctrlq(unsigned long data)
        struct sk_buff *skb;
        struct sge_qset *qs = (struct sge_qset *)data;
        struct sge_txq *q = &qs->txq[TXQ_CTRL];
-       struct adapter *adap = qs->netdev->priv;
+       const struct port_info *pi = netdev_priv(qs->netdev);
+       struct adapter *adap = pi->adapter;
 
        spin_lock(&q->lock);
       again:reclaim_completed_tx_imm(q);
@@ -1531,7 +1532,8 @@ static void restart_offloadq(unsigned long data)
        struct sk_buff *skb;
        struct sge_qset *qs = (struct sge_qset *)data;
        struct sge_txq *q = &qs->txq[TXQ_OFLD];
-       struct adapter *adap = qs->netdev->priv;
+       const struct port_info *pi = netdev_priv(qs->netdev);
+       struct adapter *adap = pi->adapter;
 
        spin_lock(&q->lock);
       again:reclaim_completed_tx(adap, q);
@@ -1675,7 +1677,8 @@ static inline void deliver_partial_bundle(struct t3cdev *tdev,
  */
 static int ofld_poll(struct net_device *dev, int *budget)
 {
-       struct adapter *adapter = dev->priv;
+       const struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        struct sge_qset *qs = dev2qset(dev);
        struct sge_rspq *q = &qs->rspq;
        int work_done, limit = min(*budget, dev->quota), avail = limit;
@@ -2075,7 +2078,8 @@ static inline int is_pure_response(const struct rsp_desc *r)
  */
 static int napi_rx_handler(struct net_device *dev, int *budget)
 {
-       struct adapter *adap = dev->priv;
+       const struct port_info *pi = netdev_priv(dev);
+       struct adapter *adap = pi->adapter;
        struct sge_qset *qs = dev2qset(dev);
        int effective_budget = min(*budget, dev->quota);
 
@@ -2205,7 +2209,8 @@ static inline int handle_responses(struct adapter *adap, struct sge_rspq *q)
 irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
 {
        struct sge_qset *qs = cookie;
-       struct adapter *adap = qs->netdev->priv;
+       const struct port_info *pi = netdev_priv(qs->netdev);
+       struct adapter *adap = pi->adapter;
        struct sge_rspq *q = &qs->rspq;
 
        spin_lock(&q->lock);
@@ -2224,7 +2229,8 @@ irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
 irqreturn_t t3_sge_intr_msix_napi(int irq, void *cookie)
 {
        struct sge_qset *qs = cookie;
-       struct adapter *adap = qs->netdev->priv;
+       const struct port_info *pi = netdev_priv(qs->netdev);
+       struct adapter *adap = pi->adapter;
        struct sge_rspq *q = &qs->rspq;
 
        spin_lock(&q->lock);
@@ -2508,7 +2514,8 @@ static void sge_timer_cb(unsigned long data)
 {
        spinlock_t *lock;
        struct sge_qset *qs = (struct sge_qset *)data;
-       struct adapter *adap = qs->netdev->priv;
+       const struct port_info *pi = netdev_priv(qs->netdev);
+       struct adapter *adap = pi->adapter;
 
        if (spin_trylock(&qs->txq[TXQ_ETH].lock)) {
                reclaim_completed_tx(adap, &qs->txq[TXQ_ETH]);
index dd3149d94ba8ed7115e9bd5149d7a26afe5b09f9..b02d15daf5d90f56fac24a6b531fbf40ac2aa8f0 100644 (file)
@@ -848,16 +848,15 @@ static int t3_write_flash(struct adapter *adapter, unsigned int addr,
 }
 
 /**
- *     t3_check_tpsram_version - read the tp sram version
+ *     t3_get_tp_version - read the tp sram version
  *     @adapter: the adapter
+ *     @vers: where to place the version
  *
- *     Reads the protocol sram version from serial eeprom.
+ *     Reads the protocol sram version from sram.
  */
-int t3_check_tpsram_version(struct adapter *adapter)
+int t3_get_tp_version(struct adapter *adapter, u32 *vers)
 {
        int ret;
-       u32 vers;
-       unsigned int major, minor;
 
        /* Get version loaded in SRAM */
        t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0);
@@ -866,7 +865,32 @@ int t3_check_tpsram_version(struct adapter *adapter)
        if (ret)
                return ret;
        
-       vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
+       *vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
+
+       return 0;
+}
+
+/**
+ *     t3_check_tpsram_version - read the tp sram version
+ *     @adapter: the adapter
+ *     @must_load: set to 1 if loading a new microcode image is required
+ *
+ *     Reads the protocol sram version from flash.
+ */
+int t3_check_tpsram_version(struct adapter *adapter, int *must_load)
+{
+       int ret;
+       u32 vers;
+       unsigned int major, minor;
+
+       if (adapter->params.rev == T3_REV_A)
+               return 0;
+
+       *must_load = 1;
+
+       ret = t3_get_tp_version(adapter, &vers);
+       if (ret)
+               return ret;
 
        major = G_TP_VERSION_MAJOR(vers);
        minor = G_TP_VERSION_MINOR(vers);
@@ -874,6 +898,16 @@ int t3_check_tpsram_version(struct adapter *adapter)
        if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR) 
                return 0;
 
+       if (major != TP_VERSION_MAJOR)
+               CH_ERR(adapter, "found wrong TP version (%u.%u), "
+                      "driver needs version %d.%d\n", major, minor,
+                      TP_VERSION_MAJOR, TP_VERSION_MINOR);
+       else {
+               *must_load = 0;
+               CH_ERR(adapter, "found wrong TP version (%u.%u), "
+                      "driver compiled for version %d.%d\n", major, minor,
+                      TP_VERSION_MAJOR, TP_VERSION_MINOR);
+       }
        return -EINVAL;
 }
 
index fa4099bc0416a0220c6d80a29b9c01a22188f4db..77fcc1a4984eda92d650d1c06cc369b37a93868f 100644 (file)
@@ -42,9 +42,6 @@
 
 #define T3CNAMSIZ 16
 
-/* Get the t3cdev associated with a net_device */
-#define T3CDEV(netdev) (struct t3cdev *)(netdev->priv)
-
 struct cxgb3_client;
 
 enum t3ctype {
index 3ca1e8ece5485c43a99079175c1ab1aaab9db732..0834ef0eddb4e7b61c6e33ae6c7283c8965c8705 100644 (file)
@@ -48,6 +48,7 @@
 #ifdef CONFIG_SERIAL_8250
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
 #endif
 
 #include <linux/netdevice.h>
@@ -1151,13 +1152,41 @@ static int ioc3_is_menet(struct pci_dev *pdev)
  * Also look in ip27-pci.c:pci_fixup_ioc3() for some comments on working
  * around ioc3 oddities in this respect.
  *
- * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
+ * The IOC3 serials use a 22MHz clock rate with an additional divider which
+ * can be programmed in the SCR register if the DLAB bit is set.
+ *
+ * Register to interrupt zero because we share the interrupt with
+ * the serial driver which we don't properly support yet.
+ *
+ * Can't use UPF_IOREMAP as the whole of IOC3 resources have already been
+ * registered.
  */
+static void __devinit ioc3_8250_register(struct ioc3_uartregs __iomem *uart)
+{
+#define COSMISC_CONSTANT 6
+
+       struct uart_port port = {
+               .irq            = 0,
+               .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = (22000000 << 1) / COSMISC_CONSTANT,
+
+               .membase        = (unsigned char __iomem *) uart,
+               .mapbase        = (unsigned long) uart,
+       };
+       unsigned char lcr;
+
+       lcr = uart->iu_lcr;
+       uart->iu_lcr = lcr | UART_LCR_DLAB;
+       uart->iu_scr = COSMISC_CONSTANT,
+       uart->iu_lcr = lcr;
+       uart->iu_lcr;
+       serial8250_register_port(&port);
+}
 
 static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
 {
-       struct uart_port port;
-
        /*
         * We need to recognice and treat the fourth MENET serial as it
         * does not have an SuperIO chip attached to it, therefore attempting
@@ -1171,24 +1200,35 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
                return;
 
        /*
-        * Register to interrupt zero because we share the interrupt with
-        * the serial driver which we don't properly support yet.
-        *
-        * Can't use UPF_IOREMAP as the whole of IOC3 resources have already
-        * been registered.
+        * Switch IOC3 to PIO mode.  It probably already was but let's be
+        * paranoid
         */
-       memset(&port, 0, sizeof(port));
-       port.irq      = 0;
-       port.flags    = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
-       port.iotype   = UPIO_MEM;
-       port.regshift = 0;
-       port.uartclk  = 22000000 / 3;
-
-       port.membase  = (unsigned char *) &ioc3->sregs.uarta;
-       serial8250_register_port(&port);
-
-       port.membase  = (unsigned char *) &ioc3->sregs.uartb;
-       serial8250_register_port(&port);
+       ioc3->gpcr_s = GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL;
+       ioc3->gpcr_s;
+       ioc3->gppr_6 = 0;
+       ioc3->gppr_6;
+       ioc3->gppr_7 = 0;
+       ioc3->gppr_7;
+       ioc3->sscr_a = ioc3->sscr_a & ~SSCR_DMA_EN;
+       ioc3->sscr_a;
+       ioc3->sscr_b = ioc3->sscr_b & ~SSCR_DMA_EN;
+       ioc3->sscr_b;
+       /* Disable all SA/B interrupts except for SA/B_INT in SIO_IEC. */
+       ioc3->sio_iec &= ~ (SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL |
+                           SIO_IR_SA_RX_HIGH | SIO_IR_SA_RX_TIMER |
+                           SIO_IR_SA_DELTA_DCD | SIO_IR_SA_DELTA_CTS |
+                           SIO_IR_SA_TX_EXPLICIT | SIO_IR_SA_MEMERR);
+       ioc3->sio_iec |= SIO_IR_SA_INT;
+       ioc3->sscr_a = 0;
+       ioc3->sio_iec &= ~ (SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL |
+                           SIO_IR_SB_RX_HIGH | SIO_IR_SB_RX_TIMER |
+                           SIO_IR_SB_DELTA_DCD | SIO_IR_SB_DELTA_CTS |
+                           SIO_IR_SB_TX_EXPLICIT | SIO_IR_SB_MEMERR);
+       ioc3->sio_iec |= SIO_IR_SB_INT;
+       ioc3->sscr_b = 0;
+
+       ioc3_8250_register(&ioc3->sregs.uarta);
+       ioc3_8250_register(&ioc3->sregs.uartb);
 }
 #endif
 
index 3276866b17e2c17cc27446f42d42072b708c1687..d72f8f8fcb50b58f1ffce626dd6da44a6de31216 100644 (file)
@@ -649,9 +649,11 @@ enum {
 #define PCIX_INT_VECTOR                (0x10100)
 #define PCIX_INT_MASK          (0x10104)
 
-#define PCIX_MN_WINDOW         (0x10200)
+#define PCIX_MN_WINDOW_F0      (0x10200)
+#define PCIX_MN_WINDOW(_f)     (PCIX_MN_WINDOW_F0 + (0x20 * (_f)))
 #define PCIX_MS_WINDOW         (0x10204)
-#define PCIX_SN_WINDOW         (0x10208)
+#define PCIX_SN_WINDOW_F0      (0x10208)
+#define PCIX_SN_WINDOW(_f)     (PCIX_SN_WINDOW_F0 + (0x20 * (_f)))
 #define PCIX_CRB_WINDOW                (0x10210)
 #define PCIX_CRB_WINDOW_F0     (0x10210)
 #define PCIX_CRB_WINDOW_F1     (0x10230)
index aac15421bd1ed49dc7fbb68b84809ebd5d43ddd3..a7b8d7f23259ced85ce9a5925c68dd5e3235dea5 100644 (file)
@@ -904,11 +904,11 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter,
                        ddr_mn_window = window;
                        writel(window, PCI_OFFSET_SECOND_RANGE(adapter,
                                                               NETXEN_PCIX_PH_REG
-                                                              (PCIX_MN_WINDOW)));
+                                                              (PCIX_MN_WINDOW(adapter->ahw.pci_func))));
                        /* MUST make sure window is set before we forge on... */
                        readl(PCI_OFFSET_SECOND_RANGE(adapter,
                                                      NETXEN_PCIX_PH_REG
-                                                     (PCIX_MN_WINDOW)));
+                                                     (PCIX_MN_WINDOW(adapter->ahw.pci_func))));
                }
                addr -= (window * NETXEN_WINDOW_ONE);
                addr += NETXEN_PCI_DDR_NET;
@@ -929,11 +929,11 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter,
                        writel((window << 22),
                               PCI_OFFSET_SECOND_RANGE(adapter,
                                                       NETXEN_PCIX_PH_REG
-                                                      (PCIX_SN_WINDOW)));
+                                                      (PCIX_SN_WINDOW(adapter->ahw.pci_func))));
                        /* MUST make sure window is set before we forge on... */
                        readl(PCI_OFFSET_SECOND_RANGE(adapter,
                                                      NETXEN_PCIX_PH_REG
-                                                     (PCIX_SN_WINDOW)));
+                                                     (PCIX_SN_WINDOW(adapter->ahw.pci_func))));
                }
                addr -= (window * 0x400000);
                addr += NETXEN_PCI_QDR_NET;
index 08a62acde8bf0e991c91706c53fa87fdb8c475d2..3122d0101638a0d232ac6f983ed6c19632dfd05f 100644 (file)
@@ -639,10 +639,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        NETXEN_CRB_NORMALIZE(adapter,
                                NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
                /* Handshake with the card before we register the devices. */
-               writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
-               netxen_pinit_from_rom(adapter, 0);
-               msleep(1);
-               netxen_load_firmware(adapter);
                netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
        }
 
@@ -750,9 +746,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
        netxen_nic_disable_int(adapter);
 
-       if (adapter->irq)
-               free_irq(adapter->irq, adapter);
-
        if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
                init_firmware_done++;
                netxen_free_hw_resources(adapter);
@@ -776,13 +769,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
                }
        }
 
-       if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
-               pci_disable_msi(pdev);
-
        vfree(adapter->cmd_buf_arr);
 
-       pci_disable_device(pdev);
-
        if (adapter->portnum == 0) {
                if (init_firmware_done) {
                        i = 100;
@@ -833,12 +821,19 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
                }
        }
 
+       if (adapter->irq)
+               free_irq(adapter->irq, adapter);
+
+       if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
+               pci_disable_msi(pdev);
+
        iounmap(adapter->ahw.db_base);
        iounmap(adapter->ahw.pci_base0);
        iounmap(adapter->ahw.pci_base1);
        iounmap(adapter->ahw.pci_base2);
 
        pci_release_regions(pdev);
+       pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
 
        free_netdev(netdev);
index 13d1c0a2a25fc2d1598f80fd0a88949eb8e1d5e8..e565039184369b22b25dc486ff4f8a945c92e26e 100644 (file)
@@ -556,7 +556,6 @@ static int gelic_net_stop(struct net_device *netdev)
 {
        struct gelic_net_card *card = netdev_priv(netdev);
 
-       netif_poll_disable(netdev);
        netif_stop_queue(netdev);
 
        /* turn off DMA, force end */
index ec18bae05df0893f1ccf20d69e3a908b6c9d320a..6d4959807abcc0e291f217bfcccb6898360c2de9 100644 (file)
@@ -1178,9 +1178,9 @@ qeth_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr,
                      char *buf)
 {
        if (proto == QETH_PROT_IPV4)
-               return qeth_ipaddr4_to_string(addr, buf);
+               qeth_ipaddr4_to_string(addr, buf);
        else if (proto == QETH_PROT_IPV6)
-               return qeth_ipaddr6_to_string(addr, buf);
+               qeth_ipaddr6_to_string(addr, buf);
 }
 
 static inline int
index 57f69434fbf9f2319b5b9a6ac33692c80474d546..f3e6fbeb2123192d4f1b279e1bcaedfb60a30c23 100644 (file)
@@ -561,7 +561,7 @@ qeth_set_offline(struct ccwgroup_device *cgdev)
 }
 
 static int
-qeth_wait_for_threads(struct qeth_card *card, unsigned long threads);
+qeth_threads_running(struct qeth_card *card, unsigned long threads);
 
 
 static void
@@ -576,8 +576,7 @@ qeth_remove_device(struct ccwgroup_device *cgdev)
        if (!card)
                return;
 
-       if (qeth_wait_for_threads(card, 0xffffffff))
-               return;
+       wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
 
        if (cgdev->state == CCWGROUP_ONLINE){
                card->use_hard_stop = 1;
@@ -1542,16 +1541,21 @@ qeth_idx_write_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
        card = CARD_FROM_CDEV(channel->ccwdev);
 
        if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
-               PRINT_ERR("IDX_ACTIVATE on write channel device %s: negative "
-                         "reply\n", CARD_WDEV_ID(card));
+               if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
+                       PRINT_ERR("IDX_ACTIVATE on write channel device %s: "
+                               "adapter exclusively used by another host\n",
+                               CARD_WDEV_ID(card));
+               else
+                       PRINT_ERR("IDX_ACTIVATE on write channel device %s: "
+                               "negative reply\n", CARD_WDEV_ID(card));
                goto out;
        }
        memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
        if ((temp & ~0x0100) != qeth_peer_func_level(card->info.func_level)) {
                PRINT_WARN("IDX_ACTIVATE on write channel device %s: "
-                          "function level mismatch "
-                          "(sent: 0x%x, received: 0x%x)\n",
-                          CARD_WDEV_ID(card), card->info.func_level, temp);
+                       "function level mismatch "
+                       "(sent: 0x%x, received: 0x%x)\n",
+                       CARD_WDEV_ID(card), card->info.func_level, temp);
                goto out;
        }
        channel->state = CH_STATE_UP;
@@ -1597,8 +1601,13 @@ qeth_idx_read_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
                        goto out;
        }
        if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
-               PRINT_ERR("IDX_ACTIVATE on read channel device %s: negative "
-                         "reply\n", CARD_RDEV_ID(card));
+               if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
+                       PRINT_ERR("IDX_ACTIVATE on read channel device %s: "
+                               "adapter exclusively used by another host\n",
+                               CARD_RDEV_ID(card));
+               else
+                       PRINT_ERR("IDX_ACTIVATE on read channel device %s: "
+                               "negative reply\n", CARD_RDEV_ID(card));
                goto out;
        }
 
@@ -1613,8 +1622,8 @@ qeth_idx_read_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
        memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
        if (temp != qeth_peer_func_level(card->info.func_level)) {
                PRINT_WARN("IDX_ACTIVATE on read channel device %s: function "
-                          "level mismatch (sent: 0x%x, received: 0x%x)\n",
-                          CARD_RDEV_ID(card), card->info.func_level, temp);
+                       "level mismatch (sent: 0x%x, received: 0x%x)\n",
+                       CARD_RDEV_ID(card), card->info.func_level, temp);
                goto out;
        }
        memcpy(&card->token.issuer_rm_r,
@@ -2496,7 +2505,7 @@ qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb,
        struct iphdr *ip_hdr;
 
        QETH_DBF_TEXT(trace,5,"skbfktr");
-       skb_set_mac_header(skb, -QETH_FAKE_LL_LEN_TR);
+       skb_set_mac_header(skb, (int)-QETH_FAKE_LL_LEN_TR);
        /* this is a fake ethernet header */
        fake_hdr = tr_hdr(skb);
 
@@ -2804,13 +2813,16 @@ qeth_queue_input_buffer(struct qeth_card *card, int index)
                if (newcount < count) {
                        /* we are in memory shortage so we switch back to
                           traditional skb allocation and drop packages */
-                       if (atomic_cmpxchg(&card->force_alloc_skb, 0, 1))
-                               printk(KERN_WARNING
-                                       "qeth: switch to alloc skb\n");
+                       if (!atomic_read(&card->force_alloc_skb) &&
+                           net_ratelimit())
+                               PRINT_WARN("Switch to alloc skb\n");
+                       atomic_set(&card->force_alloc_skb, 3);
                        count = newcount;
                } else {
-                       if (atomic_cmpxchg(&card->force_alloc_skb, 1, 0))
-                               printk(KERN_WARNING "qeth: switch to sg\n");
+                       if ((atomic_read(&card->force_alloc_skb) == 1) &&
+                           net_ratelimit())
+                               PRINT_WARN("Switch to sg\n");
+                       atomic_add_unless(&card->force_alloc_skb, -1, 0);
                }
 
                /*
@@ -3354,10 +3366,12 @@ out_freeoutq:
        while (i > 0)
                kfree(card->qdio.out_qs[--i]);
        kfree(card->qdio.out_qs);
+       card->qdio.out_qs = NULL;
 out_freepool:
        qeth_free_buffer_pool(card);
 out_freeinq:
        kfree(card->qdio.in_q);
+       card->qdio.in_q = NULL;
 out_nomem:
        atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
        return -ENOMEM;
@@ -3373,16 +3387,20 @@ qeth_free_qdio_buffers(struct qeth_card *card)
                QETH_QDIO_UNINITIALIZED)
                return;
        kfree(card->qdio.in_q);
+       card->qdio.in_q = NULL;
        /* inbound buffer pool */
        qeth_free_buffer_pool(card);
        /* free outbound qdio_qs */
-       for (i = 0; i < card->qdio.no_out_queues; ++i){
-               for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
-                       qeth_clear_output_buffer(card->qdio.out_qs[i],
-                                       &card->qdio.out_qs[i]->bufs[j]);
-               kfree(card->qdio.out_qs[i]);
+       if (card->qdio.out_qs) {
+               for (i = 0; i < card->qdio.no_out_queues; ++i) {
+                       for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
+                               qeth_clear_output_buffer(card->qdio.out_qs[i],
+                                               &card->qdio.out_qs[i]->bufs[j]);
+                       kfree(card->qdio.out_qs[i]);
+               }
+               kfree(card->qdio.out_qs);
+               card->qdio.out_qs = NULL;
        }
-       kfree(card->qdio.out_qs);
 }
 
 static void
@@ -3393,7 +3411,7 @@ qeth_clear_qdio_buffers(struct qeth_card *card)
        QETH_DBF_TEXT(trace, 2, "clearqdbf");
        /* clear outbound buffers to free skbs */
        for (i = 0; i < card->qdio.no_out_queues; ++i)
-               if (card->qdio.out_qs[i]){
+               if (card->qdio.out_qs && card->qdio.out_qs[i]) {
                        for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
                                qeth_clear_output_buffer(card->qdio.out_qs[i],
                                                &card->qdio.out_qs[i]->bufs[j]);
@@ -4553,6 +4571,53 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr,
         return elements_needed;
 }
 
+static void qeth_tx_csum(struct sk_buff *skb)
+{
+       int tlen;
+
+       if (skb->protocol == htons(ETH_P_IP)) {
+               tlen = ntohs(ip_hdr(skb)->tot_len) - (ip_hdr(skb)->ihl << 2);
+               switch (ip_hdr(skb)->protocol) {
+               case IPPROTO_TCP:
+                       tcp_hdr(skb)->check = 0;
+                       tcp_hdr(skb)->check = csum_tcpudp_magic(
+                               ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
+                               tlen, ip_hdr(skb)->protocol,
+                               skb_checksum(skb, skb_transport_offset(skb),
+                                       tlen, 0));
+                       break;
+               case IPPROTO_UDP:
+                       udp_hdr(skb)->check = 0;
+                       udp_hdr(skb)->check = csum_tcpudp_magic(
+                               ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
+                               tlen, ip_hdr(skb)->protocol,
+                               skb_checksum(skb, skb_transport_offset(skb),
+                                       tlen, 0));
+                       break;
+               }
+       } else if (skb->protocol == htons(ETH_P_IPV6)) {
+               switch (ipv6_hdr(skb)->nexthdr) {
+               case IPPROTO_TCP:
+                       tcp_hdr(skb)->check = 0;
+                       tcp_hdr(skb)->check = csum_ipv6_magic(
+                               &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
+                               ipv6_hdr(skb)->payload_len,
+                               ipv6_hdr(skb)->nexthdr,
+                               skb_checksum(skb, skb_transport_offset(skb),
+                                       ipv6_hdr(skb)->payload_len, 0));
+                       break;
+               case IPPROTO_UDP:
+                       udp_hdr(skb)->check = 0;
+                       udp_hdr(skb)->check = csum_ipv6_magic(
+                               &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
+                               ipv6_hdr(skb)->payload_len,
+                               ipv6_hdr(skb)->nexthdr,
+                               skb_checksum(skb, skb_transport_offset(skb),
+                                       ipv6_hdr(skb)->payload_len, 0));
+                       break;
+               }
+       }
+}
 
 static int
 qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
@@ -4638,12 +4703,22 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
                elements_needed += elems;
        }
 
+       if ((large_send == QETH_LARGE_SEND_NO) &&
+           (skb->ip_summed == CHECKSUM_PARTIAL))
+               qeth_tx_csum(new_skb);
+
        if (card->info.type != QETH_CARD_TYPE_IQD)
                rc = qeth_do_send_packet(card, queue, new_skb, hdr,
                                         elements_needed, ctx);
-       else
+       else {
+               if ((skb->protocol == htons(ETH_P_ARP)) &&
+                   (card->dev->flags & IFF_NOARP)) {
+                       __qeth_free_new_skb(skb, new_skb);
+                       return -EPERM;
+               }
                rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
                                              elements_needed, ctx);
+       }
        if (!rc) {
                card->stats.tx_packets++;
                card->stats.tx_bytes += tx_bytes;
@@ -6385,20 +6460,18 @@ qeth_deregister_addr_entry(struct qeth_card *card, struct qeth_ipaddr *addr)
 static u32
 qeth_ethtool_get_tx_csum(struct net_device *dev)
 {
-       /* We may need to say that we support tx csum offload if
-        * we do EDDP or TSO. There are discussions going on to
-        * enforce rules in the stack and in ethtool that make
-        * SG and TSO depend on HW_CSUM. At the moment there are
-        * no such rules....
-        * If we say yes here, we have to checksum outbound packets
-        * any time. */
-       return 0;
+       return (dev->features & NETIF_F_HW_CSUM) != 0;
 }
 
 static int
 qeth_ethtool_set_tx_csum(struct net_device *dev, u32 data)
 {
-       return -EINVAL;
+       if (data)
+               dev->features |= NETIF_F_HW_CSUM;
+       else
+               dev->features &= ~NETIF_F_HW_CSUM;
+
+       return 0;
 }
 
 static u32
@@ -7412,7 +7485,8 @@ qeth_start_ipa_tso(struct qeth_card *card)
        }
        if (rc && (card->options.large_send == QETH_LARGE_SEND_TSO)){
                card->options.large_send = QETH_LARGE_SEND_NO;
-               card->dev->features &= ~ (NETIF_F_TSO | NETIF_F_SG);
+               card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
+                                               NETIF_F_HW_CSUM);
        }
        return rc;
 }
@@ -7552,22 +7626,26 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
        card->options.large_send = type;
        switch (card->options.large_send) {
        case QETH_LARGE_SEND_EDDP:
-               card->dev->features |= NETIF_F_TSO | NETIF_F_SG;
+               card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
+                                       NETIF_F_HW_CSUM;
                break;
        case QETH_LARGE_SEND_TSO:
                if (qeth_is_supported(card, IPA_OUTBOUND_TSO)){
-                       card->dev->features |= NETIF_F_TSO | NETIF_F_SG;
+                       card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
+                                               NETIF_F_HW_CSUM;
                } else {
                        PRINT_WARN("TSO not supported on %s. "
                                   "large_send set to 'no'.\n",
                                   card->dev->name);
-                       card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
+                       card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
+                                               NETIF_F_HW_CSUM);
                        card->options.large_send = QETH_LARGE_SEND_NO;
                        rc = -EOPNOTSUPP;
                }
                break;
        default: /* includes QETH_LARGE_SEND_NO */
-               card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
+               card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
+                                       NETIF_F_HW_CSUM);
                break;
        }
        if (card->state == CARD_STATE_UP)
index 1d8083c91765891197ee83114d07e6eaad16d256..6de2da5ed5fd6da2234c050efbf912b4caee9231 100644 (file)
@@ -565,6 +565,7 @@ extern unsigned char IDX_ACTIVATE_WRITE[];
 #define QETH_IDX_ACT_QDIO_DEV_REALADDR(buffer) (buffer+0x20)
 #define QETH_IS_IDX_ACT_POS_REPLY(buffer) (((buffer)[0x08]&3)==2)
 #define QETH_IDX_REPLY_LEVEL(buffer) (buffer+0x12)
+#define QETH_IDX_ACT_CAUSE_CODE(buffer) (buffer)[0x09]
 
 #define PDU_ENCAPSULATION(buffer) \
        (buffer + *(buffer + (*(buffer+0x0b)) + \
index bb0287ad1aacff26f97cd80ecf6278ad946f003b..2cc3f3a0e393beec5e8611e40e508756bf018888 100644 (file)
@@ -1760,10 +1760,10 @@ qeth_remove_device_attributes(struct device *dev)
 {
        struct qeth_card *card = dev->driver_data;
 
-       if (card->info.type == QETH_CARD_TYPE_OSN)
-               return sysfs_remove_group(&dev->kobj,
-                                         &qeth_osn_device_attr_group);
-
+       if (card->info.type == QETH_CARD_TYPE_OSN) {
+               sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group);
+               return;
+       }
        sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
        sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
        sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);