Commit 618a821d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

* '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.
parents 5e7a3927 47330077
...@@ -916,7 +916,7 @@ int cxio_rdev_open(struct cxio_rdev *rdev_p) ...@@ -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); PDBG("%s opening rnic dev %s\n", __FUNCTION__, rdev_p->dev_name);
memset(&rdev_p->ctrl_qp, 0, sizeof(rdev_p->ctrl_qp)); memset(&rdev_p->ctrl_qp, 0, sizeof(rdev_p->ctrl_qp));
if (!rdev_p->t3cdev_p) 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; rdev_p->t3cdev_p->ulp = (void *) rdev_p;
err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, RDMA_GET_PARAMS, err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, RDMA_GET_PARAMS,
&(rdev_p->rnic_info)); &(rdev_p->rnic_info));
......
...@@ -50,7 +50,9 @@ typedef irqreturn_t(*intr_handler_t) (int, void *); ...@@ -50,7 +50,9 @@ typedef irqreturn_t(*intr_handler_t) (int, void *);
struct vlan_group; struct vlan_group;
struct adapter;
struct port_info { struct port_info {
struct adapter *adapter;
struct vlan_group *vlan_grp; struct vlan_group *vlan_grp;
const struct port_type_info *port_type; const struct port_type_info *port_type;
u8 port_id; u8 port_id;
......
...@@ -679,7 +679,8 @@ const struct adapter_info *t3_get_adapter_info(unsigned int board_id); ...@@ -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_read(struct adapter *adapter, u32 addr, u32 *data);
int t3_seeprom_write(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_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_check_tpsram(struct adapter *adapter, u8 *tp_ram, unsigned int size);
int t3_set_proto_sram(struct adapter *adap, u8 *data); int t3_set_proto_sram(struct adapter *adap, u8 *data);
int t3_read_flash(struct adapter *adapter, unsigned int addr, int t3_read_flash(struct adapter *adapter, unsigned int addr,
......
This diff is collapsed.
...@@ -593,6 +593,16 @@ int cxgb3_alloc_stid(struct t3cdev *tdev, struct cxgb3_client *client, ...@@ -593,6 +593,16 @@ int cxgb3_alloc_stid(struct t3cdev *tdev, struct cxgb3_client *client,
EXPORT_SYMBOL(cxgb3_alloc_stid); 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) static int do_smt_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
{ {
struct cpl_smt_write_rpl *rpl = cplhdr(skb); struct cpl_smt_write_rpl *rpl = cplhdr(skb);
...@@ -925,7 +935,7 @@ void cxgb_neigh_update(struct neighbour *neigh) ...@@ -925,7 +935,7 @@ void cxgb_neigh_update(struct neighbour *neigh)
struct net_device *dev = neigh->dev; struct net_device *dev = neigh->dev;
if (dev && (is_offloading(dev))) { if (dev && (is_offloading(dev))) {
struct t3cdev *tdev = T3CDEV(dev); struct t3cdev *tdev = dev2t3cdev(dev);
BUG_ON(!tdev); BUG_ON(!tdev);
t3_l2t_update(tdev, neigh); t3_l2t_update(tdev, neigh);
...@@ -973,9 +983,9 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) ...@@ -973,9 +983,9 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
"device ignored.\n", __FUNCTION__); "device ignored.\n", __FUNCTION__);
return; return;
} }
tdev = T3CDEV(olddev); tdev = dev2t3cdev(olddev);
BUG_ON(!tdev); BUG_ON(!tdev);
if (tdev != T3CDEV(newdev)) { if (tdev != dev2t3cdev(newdev)) {
printk(KERN_WARNING "%s: Redirect to different " printk(KERN_WARNING "%s: Redirect to different "
"offload device ignored.\n", __FUNCTION__); "offload device ignored.\n", __FUNCTION__);
return; return;
......
...@@ -51,6 +51,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter); ...@@ -51,6 +51,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter);
void cxgb3_set_dummy_ops(struct t3cdev *dev); void cxgb3_set_dummy_ops(struct t3cdev *dev);
struct t3cdev *dev2t3cdev(struct net_device *dev);
/* /*
* Client registration. Users of T3 driver must register themselves. * Client registration. Users of T3 driver must register themselves.
* The T3 driver will call the add function of every client for each T3 * The T3 driver will call the add function of every client for each T3
......
...@@ -1073,7 +1073,7 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1073,7 +1073,7 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
unsigned int ndesc, pidx, credits, gen, compl; unsigned int ndesc, pidx, credits, gen, compl;
const struct port_info *pi = netdev_priv(dev); 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_qset *qs = dev2qset(dev);
struct sge_txq *q = &qs->txq[TXQ_ETH]; struct sge_txq *q = &qs->txq[TXQ_ETH];
...@@ -1326,7 +1326,8 @@ static void restart_ctrlq(unsigned long data) ...@@ -1326,7 +1326,8 @@ static void restart_ctrlq(unsigned long data)
struct sk_buff *skb; struct sk_buff *skb;
struct sge_qset *qs = (struct sge_qset *)data; struct sge_qset *qs = (struct sge_qset *)data;
struct sge_txq *q = &qs->txq[TXQ_CTRL]; 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); spin_lock(&q->lock);
again:reclaim_completed_tx_imm(q); again:reclaim_completed_tx_imm(q);
...@@ -1531,7 +1532,8 @@ static void restart_offloadq(unsigned long data) ...@@ -1531,7 +1532,8 @@ static void restart_offloadq(unsigned long data)
struct sk_buff *skb; struct sk_buff *skb;
struct sge_qset *qs = (struct sge_qset *)data; struct sge_qset *qs = (struct sge_qset *)data;
struct sge_txq *q = &qs->txq[TXQ_OFLD]; 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); spin_lock(&q->lock);
again:reclaim_completed_tx(adap, q); again:reclaim_completed_tx(adap, q);
...@@ -1675,7 +1677,8 @@ static inline void deliver_partial_bundle(struct t3cdev *tdev, ...@@ -1675,7 +1677,8 @@ static inline void deliver_partial_bundle(struct t3cdev *tdev,
*/ */
static int ofld_poll(struct net_device *dev, int *budget) 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_qset *qs = dev2qset(dev);
struct sge_rspq *q = &qs->rspq; struct sge_rspq *q = &qs->rspq;
int work_done, limit = min(*budget, dev->quota), avail = limit; 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) ...@@ -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) 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); struct sge_qset *qs = dev2qset(dev);
int effective_budget = min(*budget, dev->quota); int effective_budget = min(*budget, dev->quota);
...@@ -2205,7 +2209,8 @@ static inline int handle_responses(struct adapter *adap, struct sge_rspq *q) ...@@ -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) irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
{ {
struct sge_qset *qs = 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; struct sge_rspq *q = &qs->rspq;
spin_lock(&q->lock); spin_lock(&q->lock);
...@@ -2224,7 +2229,8 @@ irqreturn_t t3_sge_intr_msix(int irq, void *cookie) ...@@ -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) irqreturn_t t3_sge_intr_msix_napi(int irq, void *cookie)
{ {
struct sge_qset *qs = 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; struct sge_rspq *q = &qs->rspq;
spin_lock(&q->lock); spin_lock(&q->lock);
...@@ -2508,7 +2514,8 @@ static void sge_timer_cb(unsigned long data) ...@@ -2508,7 +2514,8 @@ static void sge_timer_cb(unsigned long data)
{ {
spinlock_t *lock; spinlock_t *lock;
struct sge_qset *qs = (struct sge_qset *)data; 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)) { if (spin_trylock(&qs->txq[TXQ_ETH].lock)) {
reclaim_completed_tx(adap, &qs->txq[TXQ_ETH]); reclaim_completed_tx(adap, &qs->txq[TXQ_ETH]);
......
...@@ -848,16 +848,15 @@ static int t3_write_flash(struct adapter *adapter, unsigned int addr, ...@@ -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 * @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; int ret;
u32 vers;
unsigned int major, minor;
/* Get version loaded in SRAM */ /* Get version loaded in SRAM */
t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0); t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0);
...@@ -866,7 +865,32 @@ int t3_check_tpsram_version(struct adapter *adapter) ...@@ -866,7 +865,32 @@ int t3_check_tpsram_version(struct adapter *adapter)
if (ret) if (ret)
return 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); major = G_TP_VERSION_MAJOR(vers);
minor = G_TP_VERSION_MINOR(vers); minor = G_TP_VERSION_MINOR(vers);
...@@ -874,6 +898,16 @@ int t3_check_tpsram_version(struct adapter *adapter) ...@@ -874,6 +898,16 @@ int t3_check_tpsram_version(struct adapter *adapter)
if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR) if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
return 0; 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; return -EINVAL;
} }
......
...@@ -42,9 +42,6 @@ ...@@ -42,9 +42,6 @@
#define T3CNAMSIZ 16 #define T3CNAMSIZ 16
/* Get the t3cdev associated with a net_device */
#define T3CDEV(netdev) (struct t3cdev *)(netdev->priv)
struct cxgb3_client; struct cxgb3_client;
enum t3ctype { enum t3ctype {
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#ifdef CONFIG_SERIAL_8250 #ifdef CONFIG_SERIAL_8250
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/serial_8250.h> #include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#endif #endif
#include <linux/netdevice.h> #include <linux/netdevice.h>
...@@ -1151,13 +1152,41 @@ static int ioc3_is_menet(struct pci_dev *pdev) ...@@ -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 * Also look in ip27-pci.c:pci_fixup_ioc3() for some comments on working
* around ioc3 oddities in this respect. * 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) 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 * We need to recognice and treat the fourth MENET serial as it
* does not have an SuperIO chip attached to it, therefore attempting * 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) ...@@ -1171,24 +1200,35 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
return; return;
/* /*
* Register to interrupt zero because we share the interrupt with * Switch IOC3 to PIO mode. It probably already was but let's be
* the serial driver which we don't properly support yet. * paranoid
*
* Can't use UPF_IOREMAP as the whole of IOC3 resources have already
* been registered.
*/ */
memset(&port, 0, sizeof(port)); ioc3->gpcr_s = GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL;
port.irq = 0; ioc3->gpcr_s;
port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; ioc3->gppr_6 = 0;
port.iotype = UPIO_MEM; ioc3->gppr_6;
port.regshift = 0; ioc3->gppr_7 = 0;
port.uartclk = 22000000 / 3; ioc3->gppr_7;
ioc3->sscr_a = ioc3->sscr_a & ~SSCR_DMA_EN;
port.membase = (unsigned char *) &ioc3->sregs.uarta; ioc3->sscr_a;
serial8250_register_port(&port); ioc3->sscr_b = ioc3->sscr_b & ~SSCR_DMA_EN;
ioc3->sscr_b;
port.membase = (unsigned char *) &ioc3->sregs.uartb; /* Disable all SA/B interrupts except for SA/B_INT in SIO_IEC. */
serial8250_register_port(&port); 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 #endif
......
...@@ -649,9 +649,11 @@ enum { ...@@ -649,9 +649,11 @@ enum {
#define PCIX_INT_VECTOR (0x10100) #define PCIX_INT_VECTOR (0x10100)
#define PCIX_INT_MASK (0x10104) #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_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 (0x10210)
#define PCIX_CRB_WINDOW_F0 (0x10210) #define PCIX_CRB_WINDOW_F0 (0x10210)
#define PCIX_CRB_WINDOW_F1 (0x10230) #define PCIX_CRB_WINDOW_F1 (0x10230)
......
...@@ -904,11 +904,11 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter, ...@@ -904,11 +904,11 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter,
ddr_mn_window = window; ddr_mn_window = window;
writel(window, PCI_OFFSET_SECOND_RANGE(adapter, writel(window, PCI_OFFSET_SECOND_RANGE(adapter,
NETXEN_PCIX_PH_REG NETXEN_PCIX_PH_REG
(PCIX_MN_WINDOW))); (PCIX_MN_WINDOW(adapter->ahw.pci_func))));
/* MUST make sure window is set before we forge on... */ /* MUST make sure window is set before we forge on... */
readl(PCI_OFFSET_SECOND_RANGE(adapter, readl(PCI_OFFSET_SECOND_RANGE(adapter,
NETXEN_PCIX_PH_REG NETXEN_PCIX_PH_REG
(PCIX_MN_WINDOW))); (PCIX_MN_WINDOW(adapter->ahw.pci_func))));
} }
addr -= (window * NETXEN_WINDOW_ONE); addr -= (window * NETXEN_WINDOW_ONE);
addr += NETXEN_PCI_DDR_NET; addr += NETXEN_PCI_DDR_NET;
...@@ -929,11 +929,11 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter, ...@@ -929,11 +929,11 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter,
writel((window << 22), writel((window << 22),
PCI_OFFSET_SECOND_RANGE(adapter, PCI_OFFSET_SECOND_RANGE(adapter,
NETXEN_PCIX_PH_REG NETXEN_PCIX_PH_REG
(PCIX_SN_WINDOW))); (PCIX_SN_WINDOW(adapter->ahw.pci_func))));
/* MUST make sure window is set before we forge on... */ /* MUST make sure window is set before we forge on... */
readl(PCI_OFFSET_SECOND_RANGE(adapter, readl(PCI_OFFSET_SECOND_RANGE(adapter,
NETXEN_PCIX_PH_REG NETXEN_PCIX_PH_REG
(PCIX_SN_WINDOW))); (PCIX_SN_WINDOW(adapter->ahw.pci_func))));
} }
addr -= (window * 0x400000); addr -= (window * 0x400000);
addr += NETXEN_PCI_QDR_NET; addr += NETXEN_PCI_QDR_NET;
......
...@@ -639,10 +639,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -639,10 +639,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
NETXEN_CRB_NORMALIZE(adapter, NETXEN_CRB_NORMALIZE(adapter,
NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
/* Handshake with the card before we register the devices. */ /* 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); netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
} }
...@@ -750,9 +746,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) ...@@ -750,9 +746,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
netxen_nic_disable_int(adapter); netxen_nic_disable_int(adapter);
if (adapter->irq)
free_irq(adapter->irq, adapter);
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
init_firmware_done++; init_firmware_done++;
netxen_free_hw_resources(adapter); netxen_free_hw_resources(adapter);
...@@ -776,13 +769,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) ...@@ -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); vfree(adapter->cmd_buf_arr);
pci_disable_device(pdev);
if (adapter->portnum == 0) { if (adapter->portnum == 0) {
if (init_firmware_done) { if (init_firmware_done) {
i = 100; i = 100;
...@@ -833,12 +821,19 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) ...@@ -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.db_base);
iounmap(adapter->ahw.pci_base0); iounmap(adapter->ahw.pci_base0);
iounmap(adapter->ahw.pci_base1); iounmap(adapter->ahw.pci_base1);
iounmap(adapter->ahw.pci_base2); iounmap(adapter->ahw.pci_base2);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
free_netdev(netdev); free_netdev(netdev);
......
...@@ -556,7 +556,6 @@ static int gelic_net_stop(struct net_device *netdev) ...@@ -556,7 +556,6 @@ static int gelic_net_stop(struct net_device *netdev)
{ {
struct gelic_net_card *card = netdev_priv(netdev); struct gelic_net_card *card = netdev_priv(netdev);
netif_poll_disable(netdev);
netif_stop_queue(netdev); netif_stop_queue(netdev);
/* turn off DMA, force end */ /* turn off DMA, force end */
......
...@@ -1178,9 +1178,9 @@ qeth_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr, ...@@ -1178,9 +1178,9 @@ qeth_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr,
char *buf) char *buf)
{ {
if (proto == QETH_PROT_IPV4) if (proto == QETH_PROT_IPV4)
return qeth_ipaddr4_to_string(addr, buf); qeth_ipaddr4_to_string(addr, buf);
else if (proto == QETH_PROT_IPV6) else if (proto == QETH_PROT_IPV6)
return qeth_ipaddr6_to_string(addr, buf); qeth_ipaddr6_to_string(addr, buf);
} }
static inline int static inline int
......
...@@ -561,7 +561,7 @@ qeth_set_offline(struct ccwgroup_device *cgdev) ...@@ -561,7 +561,7 @@ qeth_set_offline(struct ccwgroup_device *cgdev)
} }
static int 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 static void
...@@ -576,8 +576,7 @@ qeth_remove_device(struct ccwgroup_device *cgdev) ...@@ -576,8 +576,7 @@ qeth_remove_device(struct ccwgroup_device *cgdev)
if (!card) if (!card)
return; return;
if (qeth_wait_for_threads(card, 0xffffffff)) wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
return;
if (cgdev->state == CCWGROUP_ONLINE){ if (cgdev->state == CCWGROUP_ONLINE){
card->use_hard_stop = 1; card->use_hard_stop = 1;
...@@ -1542,16 +1541,21 @@ qeth_idx_write_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob) ...@@ -1542,16 +1541,21 @@ qeth_idx_write_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
card = CARD_FROM_CDEV(channel->ccwdev); card = CARD_FROM_CDEV(channel->ccwdev);
if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) { if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
PRINT_ERR("IDX_ACTIVATE on write channel device %s: negative " if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
"reply\n", CARD_WDEV_ID(card)); 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; goto out;
} }
memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2); memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
if ((temp & ~0x0100) != qeth_peer_func_level(card->info.func_level)) { if ((temp & ~0x0100) != qeth_peer_func_level(card->info.func_level)) {
PRINT_WARN("IDX_ACTIVATE on write channel device %s: " PRINT_WARN("IDX_ACTIVATE on write channel device %s: "
"function level mismatch " "function level mismatch "
"(sent: 0x%x, received: 0x%x)\n", "(sent: 0x%x, received: 0x%x)\n",
CARD_WDEV_ID(card), card->info.func_level, temp); CARD_WDEV_ID(card), card->info.func_level, temp);
goto out; goto out;
} }
channel->state = CH_STATE_UP; channel->state = CH_STATE_UP;
...@@ -1597,8 +1601,13 @@ qeth_idx_read_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob) ...@@ -1597,8 +1601,13 @@ qeth_idx_read_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
goto out; goto out;
} }
if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) { if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
PRINT_ERR("IDX_ACTIVATE on read channel device %s: negative " if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
"reply\n", CARD_RDEV_ID(card)); 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; goto out;
} }
...@@ -1613,8 +1622,8 @@ qeth_idx_read_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob) ...@@ -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); memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
if (temp != qeth_peer_func_level(card->info.func_level)) { if (temp != qeth_peer_func_level(card->info.func_level)) {
PRINT_WARN("IDX_ACTIVATE on read channel device %s: function " PRINT_WARN("IDX_ACTIVATE on read channel device %s: function "
"level mismatch (sent: 0x%x, received: 0x%x)\n", "level mismatch (sent: 0x%x, received: 0x%x)\n",
CARD_RDEV_ID(card), card->info.func_level, temp); CARD_RDEV_ID(card), card->info.func_level, temp);
goto out; goto out;
} }
memcpy(&card->token.issuer_rm_r, memcpy(&card->token.issuer_rm_r,
...@@ -2496,7 +2505,7 @@ qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb, ...@@ -2496,7 +2505,7 @@ qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb,
struct iphdr *ip_hdr; struct iphdr *ip_hdr;
QETH_DBF_TEXT(trace,5,"skbfktr"); 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 */ /* this is a fake ethernet header */
fake_hdr = tr_hdr(skb); fake_hdr = tr_hdr(skb);
...@@ -2804,13 +2813,16 @@ qeth_queue_input_buffer(struct qeth_card *card, int index) ...@@ -2804,13 +2813,16 @@ qeth_queue_input_buffer(struct qeth_card *card, int index)
if (newcount < count) { if (newcount < count) {
/* we are in memory shortage so we switch back to /* we are in memory shortage so we switch back to
traditional skb allocation and drop packages */ traditional skb allocation and drop packages */
if (atomic_cmpxchg(&card->force_alloc_skb, 0, 1)) if (!atomic_read(&card->force_alloc_skb) &&
printk(KERN_WARNING net_ratelimit())
"qeth: switch to alloc skb\n"); PRINT_WARN("Switch to alloc skb\n");
atomic_set(&card->force_alloc_skb, 3);
count = newcount; count = newcount;
} else { } else {
if (atomic_cmpxchg(&card->force_alloc_skb, 1, 0)) if ((atomic_read(&card->force_alloc_skb) == 1) &&
printk(KERN_WARNING "qeth: switch to sg\n"); net_ratelimit())
PRINT_WARN("Switch to sg\n");
atomic_add_unless(&card->force_alloc_skb, -1, 0);
} }
/* /*
...@@ -3354,10 +3366,12 @@ qeth_alloc_qdio_buffers(struct qeth_card *card) ...@@ -3354,10 +3366,12 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
while (i > 0) while (i > 0)
kfree(card->qdio.out_qs[--i]); kfree(card->qdio.out_qs[--i]);
kfree(card->qdio.out_qs); kfree(card->qdio.out_qs);
card->qdio.out_qs = NULL;
out_freepool: out_freepool:
qeth_free_buffer_pool(card); qeth_free_buffer_pool(card);
out_freeinq: out_freeinq:
kfree(card->qdio.in_q); kfree(card->qdio.in_q);
card->qdio.in_q = NULL;
out_nomem: out_nomem:
atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED); atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
return -ENOMEM; return -ENOMEM;
...@@ -3373,16 +3387,20 @@ qeth_free_qdio_buffers(struct qeth_card *card) ...@@ -3373,16 +3387,20 @@ qeth_free_qdio_buffers(struct qeth_card *card)
QETH_QDIO_UNINITIALIZED) QETH_QDIO_UNINITIALIZED)
return; return;
kfree(card->qdio.in_q); kfree(card->qdio.in_q);
card->qdio.in_q = NULL;
/* inbound buffer pool */ /* inbound buffer pool */
qeth_free_buffer_pool(card); qeth_free_buffer_pool(card);
/* free outbound qdio_qs */ /* free outbound qdio_qs */
for (i = 0; i < card->qdio.no_out_queues; ++i){ if (card->qdio.out_qs) {
for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) for (i = 0; i < card->qdio.no_out_queues; ++i) {
qeth_clear_output_buffer(card->qdio.out_qs[i], for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
&card->qdio.out_qs[i]->bufs[j]); qeth_clear_output_buffer(card->qdio.out_qs[i],
kfree(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 static void
...@@ -3393,7 +3411,7 @@ qeth_clear_qdio_buffers(struct qeth_card *card) ...@@ -3393,7 +3411,7 @@ qeth_clear_qdio_buffers(struct qeth_card *card)
QETH_DBF_TEXT(trace, 2, "clearqdbf"); QETH_DBF_TEXT(trace, 2, "clearqdbf");
/* clear outbound buffers to free skbs */ /* clear outbound buffers to free skbs */
for (i = 0; i < card->qdio.no_out_queues; ++i) 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) for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
qeth_clear_output_buffer(card->qdio.out_qs[i], qeth_clear_output_buffer(card->qdio.out_qs[i],
&card->qdio.out_qs[i]->bufs[j]); &card->qdio.out_qs[i]->bufs[j]);
...@@ -4553,6 +4571,53 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr, ...@@ -4553,6 +4571,53 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr,
return elements_needed; 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 static int
qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) 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) ...@@ -4638,12 +4703,22 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
elements_needed += elems; 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) if (card->info.type != QETH_CARD_TYPE_IQD)
rc = qeth_do_send_packet(card, queue, new_skb, hdr, rc = qeth_do_send_packet(card, queue, new_skb, hdr,
elements_needed, ctx); 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, rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
elements_needed, ctx); elements_needed, ctx);
}
if (!rc) { if (!rc) {
card->stats.tx_packets++; card->stats.tx_packets++;
card->stats.tx_bytes += tx_bytes; card->stats.tx_bytes += tx_bytes;
...@@ -6385,20 +6460,18 @@ qeth_deregister_addr_entry(struct qeth_card *card, struct qeth_ipaddr *addr) ...@@ -6385,20 +6460,18 @@ qeth_deregister_addr_entry(struct qeth_card *card, struct qeth_ipaddr *addr)
static u32 static u32
qeth_ethtool_get_tx_csum(struct net_device *dev) qeth_ethtool_get_tx_csum(struct net_device *dev)
{ {
/* We may need to say that we support tx csum offload if return (dev->features & NETIF_F_HW_CSUM) != 0;
* 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;
} }
static int static int
qeth_ethtool_set_tx_csum(struct net_device *dev, u32 data) 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 static u32
...@@ -7412,7 +7485,8 @@ qeth_start_ipa_tso(struct qeth_card *card) ...@@ -7412,7 +7485,8 @@ qeth_start_ipa_tso(struct qeth_card *card)
} }
if (rc && (card->options.large_send == QETH_LARGE_SEND_TSO)){ if (rc && (card->options.large_send == QETH_LARGE_SEND_TSO)){
card->options.large_send = QETH_LARGE_SEND_NO; 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; return rc;
} }
...@@ -7552,22 +7626,26 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type) ...@@ -7552,22 +7626,26 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
card->options.large_send = type; card->options.large_send = type;
switch (card->options.large_send) { switch (card->options.large_send) {
case QETH_LARGE_SEND_EDDP: 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; break;
case QETH_LARGE_SEND_TSO: case QETH_LARGE_SEND_TSO:
if (qeth_is_supported(card, IPA_OUTBOUND_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 { } else {
PRINT_WARN("TSO not supported on %s. " PRINT_WARN("TSO not supported on %s. "
"large_send set to 'no'.\n", "large_send set to 'no'.\n",
card->dev->name); 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; card->options.large_send = QETH_LARGE_SEND_NO;
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} }
break; break;
default: /* includes QETH_LARGE_SEND_NO */ 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; break;
} }
if (card->state == CARD_STATE_UP) if (card->state == CARD_STATE_UP)
......
...@@ -565,6 +565,7 @@ extern unsigned char IDX_ACTIVATE_WRITE[]; ...@@ -565,6 +565,7 @@ extern unsigned char IDX_ACTIVATE_WRITE[];
#define QETH_IDX_ACT_QDIO_DEV_REALADDR(buffer) (buffer+0x20) #define QETH_IDX_ACT_QDIO_DEV_REALADDR(buffer) (buffer+0x20)
#define QETH_IS_IDX_ACT_POS_REPLY(buffer) (((buffer)[0x08]&3)==2) #define QETH_IS_IDX_ACT_POS_REPLY(buffer) (((buffer)[0x08]&3)==2)
#define QETH_IDX_REPLY_LEVEL(buffer) (buffer+0x12) #define QETH_IDX_REPLY_LEVEL(buffer) (buffer+0x12)
#define QETH_IDX_ACT_CAUSE_CODE(buffer) (buffer)[0x09]
#define PDU_ENCAPSULATION(buffer) \ #define PDU_ENCAPSULATION(buffer) \
(buffer + *(buffer + (*(buffer+0x0b)) + \ (buffer + *(buffer + (*(buffer+0x0b)) + \
......
...@@ -1760,10 +1760,10 @@ qeth_remove_device_attributes(struct device *dev) ...@@ -1760,10 +1760,10 @@ qeth_remove_device_attributes(struct device *dev)
{ {
struct qeth_card *card = dev->driver_data; struct qeth_card *card = dev->driver_data;
if (card->info.type == QETH_CARD_TYPE_OSN) if (card->info.type == QETH_CARD_TYPE_OSN) {
return sysfs_remove_group(&dev->kobj, sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group);
&qeth_osn_device_attr_group); return;
}
sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); 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_ipato_group);
sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group); sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment