Commit c08129bb authored by David S. Miller's avatar David S. Miller

Merge branch 's390-net-next'

Julian Wiedmann says:

====================
s390/net: updates 2019-08-20

please apply the following patches to net-next. This series brings a mix
of cleanups and small improvements for various parts of qeth's control
path. Also, a minor cleanup for ctcm and lcs.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d9bd6d27 0506d5ba
...@@ -307,8 +307,7 @@ static void chx_txdone(fsm_instance *fi, int event, void *arg) ...@@ -307,8 +307,7 @@ static void chx_txdone(fsm_instance *fi, int event, void *arg)
ch->ccw[1].count = ch->trans_skb->len; ch->ccw[1].count = ch->trans_skb->len;
fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
ch->prof.send_stamp = jiffies; ch->prof.send_stamp = jiffies;
rc = ccw_device_start(ch->cdev, &ch->ccw[0], rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
ch->prof.doios_multi++; ch->prof.doios_multi++;
if (rc != 0) { if (rc != 0) {
priv->stats.tx_dropped += i; priv->stats.tx_dropped += i;
...@@ -417,8 +416,7 @@ static void chx_rx(fsm_instance *fi, int event, void *arg) ...@@ -417,8 +416,7 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
if (ctcm_checkalloc_buffer(ch)) if (ctcm_checkalloc_buffer(ch))
return; return;
ch->ccw[1].count = ch->max_bufsize; ch->ccw[1].count = ch->max_bufsize;
rc = ccw_device_start(ch->cdev, &ch->ccw[0], rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
if (rc != 0) if (rc != 0)
ctcm_ccw_check_rc(ch, rc, "normal RX"); ctcm_ccw_check_rc(ch, rc, "normal RX");
} }
...@@ -478,8 +476,7 @@ static void chx_firstio(fsm_instance *fi, int event, void *arg) ...@@ -478,8 +476,7 @@ static void chx_firstio(fsm_instance *fi, int event, void *arg)
fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == CTCM_READ) fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == CTCM_READ)
? CTC_STATE_RXINIT : CTC_STATE_TXINIT); ? CTC_STATE_RXINIT : CTC_STATE_TXINIT);
rc = ccw_device_start(ch->cdev, &ch->ccw[0], rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
if (rc != 0) { if (rc != 0) {
fsm_deltimer(&ch->timer); fsm_deltimer(&ch->timer);
fsm_newstate(fi, CTC_STATE_SETUPWAIT); fsm_newstate(fi, CTC_STATE_SETUPWAIT);
...@@ -527,8 +524,7 @@ static void chx_rxidle(fsm_instance *fi, int event, void *arg) ...@@ -527,8 +524,7 @@ static void chx_rxidle(fsm_instance *fi, int event, void *arg)
return; return;
ch->ccw[1].count = ch->max_bufsize; ch->ccw[1].count = ch->max_bufsize;
fsm_newstate(fi, CTC_STATE_RXIDLE); fsm_newstate(fi, CTC_STATE_RXIDLE);
rc = ccw_device_start(ch->cdev, &ch->ccw[0], rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
if (rc != 0) { if (rc != 0) {
fsm_newstate(fi, CTC_STATE_RXINIT); fsm_newstate(fi, CTC_STATE_RXINIT);
ctcm_ccw_check_rc(ch, rc, "initial RX"); ctcm_ccw_check_rc(ch, rc, "initial RX");
...@@ -571,8 +567,7 @@ static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg) ...@@ -571,8 +567,7 @@ static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg)
/* Such conditional locking is undeterministic in /* Such conditional locking is undeterministic in
* static view. => ignore sparse warnings here. */ * static view. => ignore sparse warnings here. */
rc = ccw_device_start(ch->cdev, &ch->ccw[6], rc = ccw_device_start(ch->cdev, &ch->ccw[6], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
if (event == CTC_EVENT_TIMER) /* see above comments */ if (event == CTC_EVENT_TIMER) /* see above comments */
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (rc != 0) { if (rc != 0) {
...@@ -637,7 +632,7 @@ static void ctcm_chx_start(fsm_instance *fi, int event, void *arg) ...@@ -637,7 +632,7 @@ static void ctcm_chx_start(fsm_instance *fi, int event, void *arg)
fsm_newstate(fi, CTC_STATE_STARTWAIT); fsm_newstate(fi, CTC_STATE_STARTWAIT);
fsm_addtimer(&ch->timer, 1000, CTC_EVENT_TIMER, ch); fsm_addtimer(&ch->timer, 1000, CTC_EVENT_TIMER, ch);
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
rc = ccw_device_halt(ch->cdev, (unsigned long)ch); rc = ccw_device_halt(ch->cdev, 0);
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (rc != 0) { if (rc != 0) {
if (rc != -EBUSY) if (rc != -EBUSY)
...@@ -672,7 +667,7 @@ static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg) ...@@ -672,7 +667,7 @@ static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg)
* static view. => ignore sparse warnings here. */ * static view. => ignore sparse warnings here. */
oldstate = fsm_getstate(fi); oldstate = fsm_getstate(fi);
fsm_newstate(fi, CTC_STATE_TERM); fsm_newstate(fi, CTC_STATE_TERM);
rc = ccw_device_halt(ch->cdev, (unsigned long)ch); rc = ccw_device_halt(ch->cdev, 0);
if (event == CTC_EVENT_STOP) if (event == CTC_EVENT_STOP)
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
...@@ -799,7 +794,7 @@ static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg) ...@@ -799,7 +794,7 @@ static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg)
fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
if (!IS_MPC(ch) && if (!IS_MPC(ch) &&
(CHANNEL_DIRECTION(ch->flags) == CTCM_READ)) { (CHANNEL_DIRECTION(ch->flags) == CTCM_READ)) {
int rc = ccw_device_halt(ch->cdev, (unsigned long)ch); int rc = ccw_device_halt(ch->cdev, 0);
if (rc != 0) if (rc != 0)
ctcm_ccw_check_rc(ch, rc, ctcm_ccw_check_rc(ch, rc,
"HaltIO in chx_setuperr"); "HaltIO in chx_setuperr");
...@@ -851,7 +846,7 @@ static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg) ...@@ -851,7 +846,7 @@ static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg)
/* Such conditional locking is a known problem for /* Such conditional locking is a known problem for
* sparse because its undeterministic in static view. * sparse because its undeterministic in static view.
* Warnings should be ignored here. */ * Warnings should be ignored here. */
rc = ccw_device_halt(ch->cdev, (unsigned long)ch); rc = ccw_device_halt(ch->cdev, 0);
if (event == CTC_EVENT_TIMER) if (event == CTC_EVENT_TIMER)
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (rc != 0) { if (rc != 0) {
...@@ -947,8 +942,8 @@ static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg) ...@@ -947,8 +942,8 @@ static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg)
ch2 = priv->channel[CTCM_WRITE]; ch2 = priv->channel[CTCM_WRITE];
fsm_newstate(ch2->fsm, CTC_STATE_DTERM); fsm_newstate(ch2->fsm, CTC_STATE_DTERM);
ccw_device_halt(ch->cdev, (unsigned long)ch); ccw_device_halt(ch->cdev, 0);
ccw_device_halt(ch2->cdev, (unsigned long)ch2); ccw_device_halt(ch2->cdev, 0);
} }
/** /**
...@@ -1041,8 +1036,7 @@ static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg) ...@@ -1041,8 +1036,7 @@ static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)
ctcmpc_dumpit((char *)&ch->ccw[3], ctcmpc_dumpit((char *)&ch->ccw[3],
sizeof(struct ccw1) * 3); sizeof(struct ccw1) * 3);
rc = ccw_device_start(ch->cdev, &ch->ccw[3], rc = ccw_device_start(ch->cdev, &ch->ccw[3], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
if (event == CTC_EVENT_TIMER) if (event == CTC_EVENT_TIMER)
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev),
saveflags); saveflags);
...@@ -1361,8 +1355,7 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg) ...@@ -1361,8 +1355,7 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
ch->prof.send_stamp = jiffies; ch->prof.send_stamp = jiffies;
if (do_debug_ccw) if (do_debug_ccw)
ctcmpc_dumpit((char *)&ch->ccw[0], sizeof(struct ccw1) * 3); ctcmpc_dumpit((char *)&ch->ccw[0], sizeof(struct ccw1) * 3);
rc = ccw_device_start(ch->cdev, &ch->ccw[0], rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
ch->prof.doios_multi++; ch->prof.doios_multi++;
if (rc != 0) { if (rc != 0) {
priv->stats.tx_dropped += i; priv->stats.tx_dropped += i;
...@@ -1462,8 +1455,7 @@ static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg) ...@@ -1462,8 +1455,7 @@ static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg)
if (dolock) if (dolock)
spin_lock_irqsave( spin_lock_irqsave(
get_ccwdev_lock(ch->cdev), saveflags); get_ccwdev_lock(ch->cdev), saveflags);
rc = ccw_device_start(ch->cdev, &ch->ccw[0], rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
if (dolock) /* see remark about conditional locking */ if (dolock) /* see remark about conditional locking */
spin_unlock_irqrestore( spin_unlock_irqrestore(
get_ccwdev_lock(ch->cdev), saveflags); get_ccwdev_lock(ch->cdev), saveflags);
...@@ -1569,8 +1561,7 @@ void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg) ...@@ -1569,8 +1561,7 @@ void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)
if (event == CTC_EVENT_START) if (event == CTC_EVENT_START)
/* see remark about conditional locking */ /* see remark about conditional locking */
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
rc = ccw_device_start(ch->cdev, &ch->ccw[0], rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
if (event == CTC_EVENT_START) if (event == CTC_EVENT_START)
spin_unlock_irqrestore( spin_unlock_irqrestore(
get_ccwdev_lock(ch->cdev), saveflags); get_ccwdev_lock(ch->cdev), saveflags);
...@@ -1825,8 +1816,7 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg) ...@@ -1825,8 +1816,7 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)
spin_lock_irqsave(get_ccwdev_lock(wch->cdev), saveflags); spin_lock_irqsave(get_ccwdev_lock(wch->cdev), saveflags);
wch->prof.send_stamp = jiffies; wch->prof.send_stamp = jiffies;
rc = ccw_device_start(wch->cdev, &wch->ccw[3], rc = ccw_device_start(wch->cdev, &wch->ccw[3], 0, 0xff, 0);
(unsigned long) wch, 0xff, 0);
spin_unlock_irqrestore(get_ccwdev_lock(wch->cdev), saveflags); spin_unlock_irqrestore(get_ccwdev_lock(wch->cdev), saveflags);
if ((grp->sweep_req_pend_num == 0) && if ((grp->sweep_req_pend_num == 0) &&
......
...@@ -569,8 +569,7 @@ static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb) ...@@ -569,8 +569,7 @@ static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb)
fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
ch->prof.send_stamp = jiffies; ch->prof.send_stamp = jiffies;
rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (ccw_idx == 3) if (ccw_idx == 3)
ch->prof.doios_single++; ch->prof.doios_single++;
...@@ -833,8 +832,7 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb) ...@@ -833,8 +832,7 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
ch->prof.send_stamp = jiffies; ch->prof.send_stamp = jiffies;
rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (ccw_idx == 3) if (ccw_idx == 3)
ch->prof.doios_single++; ch->prof.doios_single++;
......
...@@ -1523,8 +1523,7 @@ void mpc_action_send_discontact(unsigned long thischan) ...@@ -1523,8 +1523,7 @@ void mpc_action_send_discontact(unsigned long thischan)
unsigned long saveflags = 0; unsigned long saveflags = 0;
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
rc = ccw_device_start(ch->cdev, &ch->ccw[15], rc = ccw_device_start(ch->cdev, &ch->ccw[15], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (rc != 0) { if (rc != 0) {
...@@ -1797,8 +1796,7 @@ static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side) ...@@ -1797,8 +1796,7 @@ static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side)
} }
fsm_addtimer(&ch->timer, 5000 , CTC_EVENT_TIMER, ch); fsm_addtimer(&ch->timer, 5000 , CTC_EVENT_TIMER, ch);
rc = ccw_device_start(ch->cdev, &ch->ccw[8], rc = ccw_device_start(ch->cdev, &ch->ccw[8], 0, 0xff, 0);
(unsigned long)ch, 0xff, 0);
if (gotlock) /* see remark above about conditional locking */ if (gotlock) /* see remark above about conditional locking */
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
......
...@@ -504,7 +504,7 @@ lcs_clear_channel(struct lcs_channel *channel) ...@@ -504,7 +504,7 @@ lcs_clear_channel(struct lcs_channel *channel)
LCS_DBF_TEXT(4,trace,"clearch"); LCS_DBF_TEXT(4,trace,"clearch");
LCS_DBF_TEXT_(4, trace, "%s", dev_name(&channel->ccwdev->dev)); LCS_DBF_TEXT_(4, trace, "%s", dev_name(&channel->ccwdev->dev));
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
rc = ccw_device_clear(channel->ccwdev, (addr_t) channel); rc = ccw_device_clear(channel->ccwdev, 0);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
if (rc) { if (rc) {
LCS_DBF_TEXT_(4, trace, "ecsc%s", LCS_DBF_TEXT_(4, trace, "ecsc%s",
...@@ -532,7 +532,7 @@ lcs_stop_channel(struct lcs_channel *channel) ...@@ -532,7 +532,7 @@ lcs_stop_channel(struct lcs_channel *channel)
LCS_DBF_TEXT_(4, trace, "%s", dev_name(&channel->ccwdev->dev)); LCS_DBF_TEXT_(4, trace, "%s", dev_name(&channel->ccwdev->dev));
channel->state = LCS_CH_STATE_INIT; channel->state = LCS_CH_STATE_INIT;
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
rc = ccw_device_halt(channel->ccwdev, (addr_t) channel); rc = ccw_device_halt(channel->ccwdev, 0);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
if (rc) { if (rc) {
LCS_DBF_TEXT_(4, trace, "ehsc%s", LCS_DBF_TEXT_(4, trace, "ehsc%s",
...@@ -1427,7 +1427,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) ...@@ -1427,7 +1427,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
channel->state = LCS_CH_STATE_SUSPENDED; channel->state = LCS_CH_STATE_SUSPENDED;
if (irb->scsw.cmd.fctl & SCSW_FCTL_HALT_FUNC) { if (irb->scsw.cmd.fctl & SCSW_FCTL_HALT_FUNC) {
if (irb->scsw.cmd.cc != 0) { if (irb->scsw.cmd.cc != 0) {
ccw_device_halt(channel->ccwdev, (addr_t) channel); ccw_device_halt(channel->ccwdev, 0);
return; return;
} }
/* The channel has been stopped by halt_IO. */ /* The channel has been stopped by halt_IO. */
......
...@@ -572,15 +572,26 @@ struct qeth_channel { ...@@ -572,15 +572,26 @@ struct qeth_channel {
atomic_t irq_pending; atomic_t irq_pending;
}; };
struct qeth_reply {
int (*callback)(struct qeth_card *card, struct qeth_reply *reply,
unsigned long data);
void *param;
};
struct qeth_cmd_buffer { struct qeth_cmd_buffer {
struct list_head list;
struct completion done;
spinlock_t lock;
unsigned int length; unsigned int length;
refcount_t ref_count; refcount_t ref_count;
struct qeth_channel *channel; struct qeth_channel *channel;
struct qeth_reply *reply; struct qeth_reply reply;
long timeout; long timeout;
unsigned char *data; unsigned char *data;
void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob); void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob);
void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob); void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob,
unsigned int data_length);
int rc;
}; };
static inline void qeth_get_cmd(struct qeth_cmd_buffer *iob) static inline void qeth_get_cmd(struct qeth_cmd_buffer *iob)
...@@ -626,19 +637,6 @@ struct qeth_seqno { ...@@ -626,19 +637,6 @@ struct qeth_seqno {
__u16 ipa; __u16 ipa;
}; };
struct qeth_reply {
struct list_head list;
struct completion received;
spinlock_t lock;
int (*callback)(struct qeth_card *, struct qeth_reply *,
unsigned long);
u32 seqno;
unsigned long offset;
int rc;
void *param;
refcount_t refcnt;
};
struct qeth_card_blkt { struct qeth_card_blkt {
int time_total; int time_total;
int inter_packet; int inter_packet;
...@@ -651,10 +649,11 @@ struct qeth_card_blkt { ...@@ -651,10 +649,11 @@ struct qeth_card_blkt {
struct qeth_card_info { struct qeth_card_info {
unsigned short unit_addr2; unsigned short unit_addr2;
unsigned short cula; unsigned short cula;
unsigned short chpid; u8 chpid;
__u16 func_level; __u16 func_level;
char mcl_level[QETH_MCL_LENGTH + 1]; char mcl_level[QETH_MCL_LENGTH + 1];
u8 open_when_online:1; u8 open_when_online:1;
u8 promisc_mode:1;
u8 use_v1_blkt:1; u8 use_v1_blkt:1;
u8 is_vm_nic:1; u8 is_vm_nic:1;
int mac_bits; int mac_bits;
...@@ -664,7 +663,6 @@ struct qeth_card_info { ...@@ -664,7 +663,6 @@ struct qeth_card_info {
int unique_id; int unique_id;
bool layer_enforced; bool layer_enforced;
struct qeth_card_blkt blkt; struct qeth_card_blkt blkt;
enum qeth_ipa_promisc_modes promisc_mode;
__u32 diagass_support; __u32 diagass_support;
__u32 hwtrap; __u32 hwtrap;
}; };
...@@ -994,6 +992,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card, ...@@ -994,6 +992,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
struct qeth_cmd_buffer *qeth_get_diag_cmd(struct qeth_card *card, struct qeth_cmd_buffer *qeth_get_diag_cmd(struct qeth_card *card,
enum qeth_diags_cmds sub_cmd, enum qeth_diags_cmds sub_cmd,
unsigned int data_length); unsigned int data_length);
void qeth_notify_cmd(struct qeth_cmd_buffer *iob, int reason);
void qeth_put_cmd(struct qeth_cmd_buffer *iob); void qeth_put_cmd(struct qeth_cmd_buffer *iob);
struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
...@@ -1005,10 +1004,9 @@ void qeth_clear_ipacmd_list(struct qeth_card *); ...@@ -1005,10 +1004,9 @@ void qeth_clear_ipacmd_list(struct qeth_card *);
int qeth_qdio_clear_card(struct qeth_card *, int); int qeth_qdio_clear_card(struct qeth_card *, int);
void qeth_clear_working_pool_list(struct qeth_card *); void qeth_clear_working_pool_list(struct qeth_card *);
void qeth_drain_output_queues(struct qeth_card *card); void qeth_drain_output_queues(struct qeth_card *card);
void qeth_setadp_promisc_mode(struct qeth_card *); void qeth_setadp_promisc_mode(struct qeth_card *card, bool enable);
int qeth_setadpparms_change_macaddr(struct qeth_card *); int qeth_setadpparms_change_macaddr(struct qeth_card *);
void qeth_tx_timeout(struct net_device *); void qeth_tx_timeout(struct net_device *);
void qeth_notify_reply(struct qeth_reply *reply, int reason);
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
u16 cmd_length); u16 cmd_length);
int qeth_query_switch_attributes(struct qeth_card *card, int qeth_query_switch_attributes(struct qeth_card *card,
......
...@@ -63,7 +63,8 @@ static struct device *qeth_core_root_dev; ...@@ -63,7 +63,8 @@ static struct device *qeth_core_root_dev;
static struct lock_class_key qdio_out_skb_queue_key; static struct lock_class_key qdio_out_skb_queue_key;
static void qeth_issue_next_read_cb(struct qeth_card *card, static void qeth_issue_next_read_cb(struct qeth_card *card,
struct qeth_cmd_buffer *iob); struct qeth_cmd_buffer *iob,
unsigned int data_length);
static void qeth_free_buffer_pool(struct qeth_card *); static void qeth_free_buffer_pool(struct qeth_card *);
static int qeth_qdio_establish(struct qeth_card *); static int qeth_qdio_establish(struct qeth_card *);
static void qeth_free_qdio_queues(struct qeth_card *card); static void qeth_free_qdio_queues(struct qeth_card *card);
...@@ -536,50 +537,28 @@ static int qeth_issue_next_read(struct qeth_card *card) ...@@ -536,50 +537,28 @@ static int qeth_issue_next_read(struct qeth_card *card)
return ret; return ret;
} }
static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) static void qeth_enqueue_cmd(struct qeth_card *card,
{ struct qeth_cmd_buffer *iob)
struct qeth_reply *reply;
reply = kzalloc(sizeof(*reply), GFP_KERNEL);
if (reply) {
refcount_set(&reply->refcnt, 1);
init_completion(&reply->received);
spin_lock_init(&reply->lock);
}
return reply;
}
static void qeth_get_reply(struct qeth_reply *reply)
{
refcount_inc(&reply->refcnt);
}
static void qeth_put_reply(struct qeth_reply *reply)
{
if (refcount_dec_and_test(&reply->refcnt))
kfree(reply);
}
static void qeth_enqueue_reply(struct qeth_card *card, struct qeth_reply *reply)
{ {
spin_lock_irq(&card->lock); spin_lock_irq(&card->lock);
list_add_tail(&reply->list, &card->cmd_waiter_list); list_add_tail(&iob->list, &card->cmd_waiter_list);
spin_unlock_irq(&card->lock); spin_unlock_irq(&card->lock);
} }
static void qeth_dequeue_reply(struct qeth_card *card, struct qeth_reply *reply) static void qeth_dequeue_cmd(struct qeth_card *card,
struct qeth_cmd_buffer *iob)
{ {
spin_lock_irq(&card->lock); spin_lock_irq(&card->lock);
list_del(&reply->list); list_del(&iob->list);
spin_unlock_irq(&card->lock); spin_unlock_irq(&card->lock);
} }
void qeth_notify_reply(struct qeth_reply *reply, int reason) void qeth_notify_cmd(struct qeth_cmd_buffer *iob, int reason)
{ {
reply->rc = reason; iob->rc = reason;
complete(&reply->received); complete(&iob->done);
} }
EXPORT_SYMBOL_GPL(qeth_notify_reply); EXPORT_SYMBOL_GPL(qeth_notify_cmd);
static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc, static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc,
struct qeth_card *card) struct qeth_card *card)
...@@ -657,14 +636,14 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card, ...@@ -657,14 +636,14 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
void qeth_clear_ipacmd_list(struct qeth_card *card) void qeth_clear_ipacmd_list(struct qeth_card *card)
{ {
struct qeth_reply *reply; struct qeth_cmd_buffer *iob;
unsigned long flags; unsigned long flags;
QETH_CARD_TEXT(card, 4, "clipalst"); QETH_CARD_TEXT(card, 4, "clipalst");
spin_lock_irqsave(&card->lock, flags); spin_lock_irqsave(&card->lock, flags);
list_for_each_entry(reply, &card->cmd_waiter_list, list) list_for_each_entry(iob, &card->cmd_waiter_list, list)
qeth_notify_reply(reply, -EIO); qeth_notify_cmd(iob, -EIO);
spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags);
} }
EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list); EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list);
...@@ -693,8 +672,6 @@ static int qeth_check_idx_response(struct qeth_card *card, ...@@ -693,8 +672,6 @@ static int qeth_check_idx_response(struct qeth_card *card,
void qeth_put_cmd(struct qeth_cmd_buffer *iob) void qeth_put_cmd(struct qeth_cmd_buffer *iob)
{ {
if (refcount_dec_and_test(&iob->ref_count)) { if (refcount_dec_and_test(&iob->ref_count)) {
if (iob->reply)
qeth_put_reply(iob->reply);
kfree(iob->data); kfree(iob->data);
kfree(iob); kfree(iob);
} }
...@@ -702,17 +679,15 @@ void qeth_put_cmd(struct qeth_cmd_buffer *iob) ...@@ -702,17 +679,15 @@ void qeth_put_cmd(struct qeth_cmd_buffer *iob)
EXPORT_SYMBOL_GPL(qeth_put_cmd); EXPORT_SYMBOL_GPL(qeth_put_cmd);
static void qeth_release_buffer_cb(struct qeth_card *card, static void qeth_release_buffer_cb(struct qeth_card *card,
struct qeth_cmd_buffer *iob) struct qeth_cmd_buffer *iob,
unsigned int data_length)
{ {
qeth_put_cmd(iob); qeth_put_cmd(iob);
} }
static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc) static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc)
{ {
struct qeth_reply *reply = iob->reply; qeth_notify_cmd(iob, rc);
if (reply)
qeth_notify_reply(reply, rc);
qeth_put_cmd(iob); qeth_put_cmd(iob);
} }
...@@ -736,6 +711,9 @@ struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, ...@@ -736,6 +711,9 @@ struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel,
return NULL; return NULL;
} }
init_completion(&iob->done);
spin_lock_init(&iob->lock);
INIT_LIST_HEAD(&iob->list);
refcount_set(&iob->ref_count, 1); refcount_set(&iob->ref_count, 1);
iob->channel = channel; iob->channel = channel;
iob->timeout = timeout; iob->timeout = timeout;
...@@ -745,11 +723,13 @@ struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, ...@@ -745,11 +723,13 @@ struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel,
EXPORT_SYMBOL_GPL(qeth_alloc_cmd); EXPORT_SYMBOL_GPL(qeth_alloc_cmd);
static void qeth_issue_next_read_cb(struct qeth_card *card, static void qeth_issue_next_read_cb(struct qeth_card *card,
struct qeth_cmd_buffer *iob) struct qeth_cmd_buffer *iob,
unsigned int data_length)
{ {
struct qeth_cmd_buffer *request = NULL;
struct qeth_ipa_cmd *cmd = NULL; struct qeth_ipa_cmd *cmd = NULL;
struct qeth_reply *reply = NULL; struct qeth_reply *reply = NULL;
struct qeth_reply *r; struct qeth_cmd_buffer *tmp;
unsigned long flags; unsigned long flags;
int rc = 0; int rc = 0;
...@@ -784,44 +764,39 @@ static void qeth_issue_next_read_cb(struct qeth_card *card, ...@@ -784,44 +764,39 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
/* match against pending cmd requests */ /* match against pending cmd requests */
spin_lock_irqsave(&card->lock, flags); spin_lock_irqsave(&card->lock, flags);
list_for_each_entry(r, &card->cmd_waiter_list, list) { list_for_each_entry(tmp, &card->cmd_waiter_list, list) {
if ((r->seqno == QETH_IDX_COMMAND_SEQNO) || if (!IS_IPA(tmp->data) ||
(cmd && (r->seqno == cmd->hdr.seqno))) { __ipa_cmd(tmp)->hdr.seqno == cmd->hdr.seqno) {
reply = r; request = tmp;
/* take the object outside the lock */ /* take the object outside the lock */
qeth_get_reply(reply); qeth_get_cmd(request);
break; break;
} }
} }
spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags);
if (!reply) if (!request)
goto out; goto out;
reply = &request->reply;
if (!reply->callback) { if (!reply->callback) {
rc = 0; rc = 0;
goto no_callback; goto no_callback;
} }
spin_lock_irqsave(&reply->lock, flags); spin_lock_irqsave(&request->lock, flags);
if (reply->rc) { if (request->rc)
/* Bail out when the requestor has already left: */ /* Bail out when the requestor has already left: */
rc = reply->rc; rc = request->rc;
} else { else
if (cmd) { rc = reply->callback(card, reply, cmd ? (unsigned long)cmd :
reply->offset = (u16)((char *)cmd - (char *)iob->data); (unsigned long)iob);
rc = reply->callback(card, reply, (unsigned long)cmd); spin_unlock_irqrestore(&request->lock, flags);
} else {
rc = reply->callback(card, reply, (unsigned long)iob);
}
}
spin_unlock_irqrestore(&reply->lock, flags);
no_callback: no_callback:
if (rc <= 0) if (rc <= 0)
qeth_notify_reply(reply, rc); qeth_notify_cmd(request, rc);
qeth_put_reply(reply); qeth_put_cmd(request);
out: out:
memcpy(&card->seqno.pdu_hdr_ack, memcpy(&card->seqno.pdu_hdr_ack,
QETH_PDU_HEADER_SEQ_NO(iob->data), QETH_PDU_HEADER_SEQ_NO(iob->data),
...@@ -1072,8 +1047,16 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, ...@@ -1072,8 +1047,16 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
} }
} }
if (iob && iob->callback) if (iob) {
iob->callback(card, iob); /* sanity check: */
if (irb->scsw.cmd.count > iob->length) {
qeth_cancel_cmd(iob, -EIO);
goto out;
}
if (iob->callback)
iob->callback(card, iob,
iob->length - irb->scsw.cmd.count);
}
out: out:
wake_up(&card->wait_q); wake_up(&card->wait_q);
...@@ -1652,7 +1635,6 @@ static void qeth_mpc_finalize_cmd(struct qeth_card *card, ...@@ -1652,7 +1635,6 @@ static void qeth_mpc_finalize_cmd(struct qeth_card *card,
memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data), memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
&card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH); &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
iob->reply->seqno = QETH_IDX_COMMAND_SEQNO;
iob->callback = qeth_release_buffer_cb; iob->callback = qeth_release_buffer_cb;
} }
...@@ -1703,29 +1685,19 @@ static int qeth_send_control_data(struct qeth_card *card, ...@@ -1703,29 +1685,19 @@ static int qeth_send_control_data(struct qeth_card *card,
void *reply_param) void *reply_param)
{ {
struct qeth_channel *channel = iob->channel; struct qeth_channel *channel = iob->channel;
struct qeth_reply *reply = &iob->reply;
long timeout = iob->timeout; long timeout = iob->timeout;
int rc; int rc;
struct qeth_reply *reply = NULL;
QETH_CARD_TEXT(card, 2, "sendctl"); QETH_CARD_TEXT(card, 2, "sendctl");
reply = qeth_alloc_reply(card);
if (!reply) {
qeth_put_cmd(iob);
return -ENOMEM;
}
reply->callback = reply_cb; reply->callback = reply_cb;
reply->param = reply_param; reply->param = reply_param;
/* pairs with qeth_put_cmd(): */
qeth_get_reply(reply);
iob->reply = reply;
timeout = wait_event_interruptible_timeout(card->wait_q, timeout = wait_event_interruptible_timeout(card->wait_q,
qeth_trylock_channel(channel), qeth_trylock_channel(channel),
timeout); timeout);
if (timeout <= 0) { if (timeout <= 0) {
qeth_put_reply(reply);
qeth_put_cmd(iob); qeth_put_cmd(iob);
return (timeout == -ERESTARTSYS) ? -EINTR : -ETIME; return (timeout == -ERESTARTSYS) ? -EINTR : -ETIME;
} }
...@@ -1734,7 +1706,10 @@ static int qeth_send_control_data(struct qeth_card *card, ...@@ -1734,7 +1706,10 @@ static int qeth_send_control_data(struct qeth_card *card,
iob->finalize(card, iob); iob->finalize(card, iob);
QETH_DBF_HEX(CTRL, 2, iob->data, min(iob->length, QETH_DBF_CTRL_LEN)); QETH_DBF_HEX(CTRL, 2, iob->data, min(iob->length, QETH_DBF_CTRL_LEN));
qeth_enqueue_reply(card, reply); qeth_enqueue_cmd(card, iob);
/* This pairs with iob->callback, and keeps the iob alive after IO: */
qeth_get_cmd(iob);
QETH_CARD_TEXT(card, 6, "noirqpnd"); QETH_CARD_TEXT(card, 6, "noirqpnd");
spin_lock_irq(get_ccwdev_lock(channel->ccwdev)); spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
...@@ -1745,51 +1720,74 @@ static int qeth_send_control_data(struct qeth_card *card, ...@@ -1745,51 +1720,74 @@ static int qeth_send_control_data(struct qeth_card *card,
QETH_DBF_MESSAGE(2, "qeth_send_control_data on device %x: ccw_device_start rc = %i\n", QETH_DBF_MESSAGE(2, "qeth_send_control_data on device %x: ccw_device_start rc = %i\n",
CARD_DEVID(card), rc); CARD_DEVID(card), rc);
QETH_CARD_TEXT_(card, 2, " err%d", rc); QETH_CARD_TEXT_(card, 2, " err%d", rc);
qeth_dequeue_reply(card, reply); qeth_dequeue_cmd(card, iob);
qeth_put_reply(reply);
qeth_put_cmd(iob); qeth_put_cmd(iob);
atomic_set(&channel->irq_pending, 0); atomic_set(&channel->irq_pending, 0);
wake_up(&card->wait_q); wake_up(&card->wait_q);
return rc; goto out;
} }
timeout = wait_for_completion_interruptible_timeout(&reply->received, timeout = wait_for_completion_interruptible_timeout(&iob->done,
timeout); timeout);
if (timeout <= 0) if (timeout <= 0)
rc = (timeout == -ERESTARTSYS) ? -EINTR : -ETIME; rc = (timeout == -ERESTARTSYS) ? -EINTR : -ETIME;
qeth_dequeue_reply(card, reply); qeth_dequeue_cmd(card, iob);
if (reply_cb) { if (reply_cb) {
/* Wait until the callback for a late reply has completed: */ /* Wait until the callback for a late reply has completed: */
spin_lock_irq(&reply->lock); spin_lock_irq(&iob->lock);
if (rc) if (rc)
/* Zap any callback that's still pending: */ /* Zap any callback that's still pending: */
reply->rc = rc; iob->rc = rc;
spin_unlock_irq(&reply->lock); spin_unlock_irq(&iob->lock);
} }
if (!rc) if (!rc)
rc = reply->rc; rc = iob->rc;
qeth_put_reply(reply);
out:
qeth_put_cmd(iob);
return rc; return rc;
} }
struct qeth_node_desc {
struct node_descriptor nd1;
struct node_descriptor nd2;
struct node_descriptor nd3;
};
static void qeth_read_conf_data_cb(struct qeth_card *card, static void qeth_read_conf_data_cb(struct qeth_card *card,
struct qeth_cmd_buffer *iob) struct qeth_cmd_buffer *iob,
unsigned int data_length)
{ {
unsigned char *prcd = iob->data; struct qeth_node_desc *nd = (struct qeth_node_desc *) iob->data;
int rc = 0;
u8 *tag;
QETH_CARD_TEXT(card, 2, "cfgunit"); QETH_CARD_TEXT(card, 2, "cfgunit");
card->info.chpid = prcd[30];
card->info.unit_addr2 = prcd[31]; if (data_length < sizeof(*nd)) {
card->info.cula = prcd[63]; rc = -EINVAL;
card->info.is_vm_nic = ((prcd[0x10] == _ascebc['V']) && goto out;
(prcd[0x11] == _ascebc['M'])); }
card->info.use_v1_blkt = prcd[74] == 0xF0 && prcd[75] == 0xF0 &&
prcd[76] >= 0xF1 && prcd[76] <= 0xF4; card->info.is_vm_nic = nd->nd1.plant[0] == _ascebc['V'] &&
nd->nd1.plant[1] == _ascebc['M'];
qeth_notify_reply(iob->reply, 0); tag = (u8 *)&nd->nd1.tag;
card->info.chpid = tag[0];
card->info.unit_addr2 = tag[1];
tag = (u8 *)&nd->nd2.tag;
card->info.cula = tag[1];
card->info.use_v1_blkt = nd->nd3.model[0] == 0xF0 &&
nd->nd3.model[1] == 0xF0 &&
nd->nd3.model[2] >= 0xF1 &&
nd->nd3.model[2] <= 0xF4;
out:
qeth_notify_cmd(iob, rc);
qeth_put_cmd(iob); qeth_put_cmd(iob);
} }
...@@ -1803,6 +1801,8 @@ static int qeth_read_conf_data(struct qeth_card *card) ...@@ -1803,6 +1801,8 @@ static int qeth_read_conf_data(struct qeth_card *card)
ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD); ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD);
if (!ciw || ciw->cmd == 0) if (!ciw || ciw->cmd == 0)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (ciw->count < sizeof(struct qeth_node_desc))
return -EINVAL;
iob = qeth_alloc_cmd(channel, ciw->count, 1, QETH_RCD_TIMEOUT); iob = qeth_alloc_cmd(channel, ciw->count, 1, QETH_RCD_TIMEOUT);
if (!iob) if (!iob)
...@@ -1850,7 +1850,8 @@ static int qeth_idx_check_activate_response(struct qeth_card *card, ...@@ -1850,7 +1850,8 @@ static int qeth_idx_check_activate_response(struct qeth_card *card,
} }
static void qeth_idx_activate_read_channel_cb(struct qeth_card *card, static void qeth_idx_activate_read_channel_cb(struct qeth_card *card,
struct qeth_cmd_buffer *iob) struct qeth_cmd_buffer *iob,
unsigned int data_length)
{ {
struct qeth_channel *channel = iob->channel; struct qeth_channel *channel = iob->channel;
u16 peer_level; u16 peer_level;
...@@ -1878,12 +1879,13 @@ static void qeth_idx_activate_read_channel_cb(struct qeth_card *card, ...@@ -1878,12 +1879,13 @@ static void qeth_idx_activate_read_channel_cb(struct qeth_card *card,
QETH_IDX_REPLY_LEVEL(iob->data), QETH_MCL_LENGTH); QETH_IDX_REPLY_LEVEL(iob->data), QETH_MCL_LENGTH);
out: out:
qeth_notify_reply(iob->reply, rc); qeth_notify_cmd(iob, rc);
qeth_put_cmd(iob); qeth_put_cmd(iob);
} }
static void qeth_idx_activate_write_channel_cb(struct qeth_card *card, static void qeth_idx_activate_write_channel_cb(struct qeth_card *card,
struct qeth_cmd_buffer *iob) struct qeth_cmd_buffer *iob,
unsigned int data_length)
{ {
struct qeth_channel *channel = iob->channel; struct qeth_channel *channel = iob->channel;
u16 peer_level; u16 peer_level;
...@@ -1905,7 +1907,7 @@ static void qeth_idx_activate_write_channel_cb(struct qeth_card *card, ...@@ -1905,7 +1907,7 @@ static void qeth_idx_activate_write_channel_cb(struct qeth_card *card,
} }
out: out:
qeth_notify_reply(iob->reply, rc); qeth_notify_cmd(iob, rc);
qeth_put_cmd(iob); qeth_put_cmd(iob);
} }
...@@ -2638,8 +2640,7 @@ static void qeth_ipa_finalize_cmd(struct qeth_card *card, ...@@ -2638,8 +2640,7 @@ static void qeth_ipa_finalize_cmd(struct qeth_card *card,
qeth_mpc_finalize_cmd(card, iob); qeth_mpc_finalize_cmd(card, iob);
/* override with IPA-specific values: */ /* override with IPA-specific values: */
__ipa_cmd(iob)->hdr.seqno = card->seqno.ipa; __ipa_cmd(iob)->hdr.seqno = card->seqno.ipa++;
iob->reply->seqno = card->seqno.ipa++;
} }
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
...@@ -4014,23 +4015,14 @@ static int qeth_setadp_promisc_mode_cb(struct qeth_card *card, ...@@ -4014,23 +4015,14 @@ static int qeth_setadp_promisc_mode_cb(struct qeth_card *card,
return (cmd->hdr.return_code) ? -EIO : 0; return (cmd->hdr.return_code) ? -EIO : 0;
} }
void qeth_setadp_promisc_mode(struct qeth_card *card) void qeth_setadp_promisc_mode(struct qeth_card *card, bool enable)
{ {
enum qeth_ipa_promisc_modes mode; enum qeth_ipa_promisc_modes mode = enable ? SET_PROMISC_MODE_ON :
struct net_device *dev = card->dev; SET_PROMISC_MODE_OFF;
struct qeth_cmd_buffer *iob; struct qeth_cmd_buffer *iob;
struct qeth_ipa_cmd *cmd; struct qeth_ipa_cmd *cmd;
QETH_CARD_TEXT(card, 4, "setprom"); QETH_CARD_TEXT(card, 4, "setprom");
if (((dev->flags & IFF_PROMISC) &&
(card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
(!(dev->flags & IFF_PROMISC) &&
(card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
return;
mode = SET_PROMISC_MODE_OFF;
if (dev->flags & IFF_PROMISC)
mode = SET_PROMISC_MODE_ON;
QETH_CARD_TEXT_(card, 4, "mode:%x", mode); QETH_CARD_TEXT_(card, 4, "mode:%x", mode);
iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE, iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,
...@@ -4298,20 +4290,16 @@ static int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum) ...@@ -4298,20 +4290,16 @@ static int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
} }
static int qeth_snmp_command_cb(struct qeth_card *card, static int qeth_snmp_command_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long sdata) struct qeth_reply *reply, unsigned long data)
{ {
struct qeth_ipa_cmd *cmd; struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
struct qeth_arp_query_info *qinfo; struct qeth_arp_query_info *qinfo = reply->param;
unsigned char *data; struct qeth_ipacmd_setadpparms *adp_cmd;
unsigned int data_len;
void *snmp_data; void *snmp_data;
__u16 data_len;
QETH_CARD_TEXT(card, 3, "snpcmdcb"); QETH_CARD_TEXT(card, 3, "snpcmdcb");
cmd = (struct qeth_ipa_cmd *) sdata;
data = (unsigned char *)((char *)cmd - reply->offset);
qinfo = (struct qeth_arp_query_info *) reply->param;
if (cmd->hdr.return_code) { if (cmd->hdr.return_code) {
QETH_CARD_TEXT_(card, 4, "scer1%x", cmd->hdr.return_code); QETH_CARD_TEXT_(card, 4, "scer1%x", cmd->hdr.return_code);
return -EIO; return -EIO;
...@@ -4322,15 +4310,14 @@ static int qeth_snmp_command_cb(struct qeth_card *card, ...@@ -4322,15 +4310,14 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
QETH_CARD_TEXT_(card, 4, "scer2%x", cmd->hdr.return_code); QETH_CARD_TEXT_(card, 4, "scer2%x", cmd->hdr.return_code);
return -EIO; return -EIO;
} }
data_len = *((__u16 *)QETH_IPA_PDU_LEN_PDU1(data));
if (cmd->data.setadapterparms.hdr.seq_no == 1) { adp_cmd = &cmd->data.setadapterparms;
snmp_data = &cmd->data.setadapterparms.data.snmp; data_len = adp_cmd->hdr.cmdlength - sizeof(adp_cmd->hdr);
data_len -= offsetof(struct qeth_ipa_cmd, if (adp_cmd->hdr.seq_no == 1) {
data.setadapterparms.data.snmp); snmp_data = &adp_cmd->data.snmp;
} else { } else {
snmp_data = &cmd->data.setadapterparms.data.snmp.request; snmp_data = &adp_cmd->data.snmp.request;
data_len -= offsetof(struct qeth_ipa_cmd, data_len -= offsetof(struct qeth_snmp_cmd, request);
data.setadapterparms.data.snmp.request);
} }
/* check if there is enough room in userspace */ /* check if there is enough room in userspace */
......
...@@ -27,7 +27,6 @@ extern unsigned char IPA_PDU_HEADER[]; ...@@ -27,7 +27,6 @@ extern unsigned char IPA_PDU_HEADER[];
#define QETH_TIMEOUT (10 * HZ) #define QETH_TIMEOUT (10 * HZ)
#define QETH_IPA_TIMEOUT (45 * HZ) #define QETH_IPA_TIMEOUT (45 * HZ)
#define QETH_IDX_COMMAND_SEQNO 0xffff0000
#define QETH_CLEAR_CHANNEL_PARM -10 #define QETH_CLEAR_CHANNEL_PARM -10
#define QETH_HALT_CHANNEL_PARM -11 #define QETH_HALT_CHANNEL_PARM -11
......
...@@ -439,23 +439,14 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) ...@@ -439,23 +439,14 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
return 0; return 0;
} }
static void qeth_promisc_to_bridge(struct qeth_card *card) static void qeth_l2_promisc_to_bridge(struct qeth_card *card, bool enable)
{ {
struct net_device *dev = card->dev;
enum qeth_ipa_promisc_modes promisc_mode;
int role; int role;
int rc; int rc;
QETH_CARD_TEXT(card, 3, "pmisc2br"); QETH_CARD_TEXT(card, 3, "pmisc2br");
if (!card->options.sbp.reflect_promisc) if (enable) {
return;
promisc_mode = (dev->flags & IFF_PROMISC) ? SET_PROMISC_MODE_ON
: SET_PROMISC_MODE_OFF;
if (promisc_mode == card->info.promisc_mode)
return;
if (promisc_mode == SET_PROMISC_MODE_ON) {
if (card->options.sbp.reflect_promisc_primary) if (card->options.sbp.reflect_promisc_primary)
role = QETH_SBP_ROLE_PRIMARY; role = QETH_SBP_ROLE_PRIMARY;
else else
...@@ -464,14 +455,26 @@ static void qeth_promisc_to_bridge(struct qeth_card *card) ...@@ -464,14 +455,26 @@ static void qeth_promisc_to_bridge(struct qeth_card *card)
role = QETH_SBP_ROLE_NONE; role = QETH_SBP_ROLE_NONE;
rc = qeth_bridgeport_setrole(card, role); rc = qeth_bridgeport_setrole(card, role);
QETH_CARD_TEXT_(card, 2, "bpm%c%04x", QETH_CARD_TEXT_(card, 2, "bpm%c%04x", enable ? '+' : '-', rc);
(promisc_mode == SET_PROMISC_MODE_ON) ? '+' : '-', rc);
if (!rc) { if (!rc) {
card->options.sbp.role = role; card->options.sbp.role = role;
card->info.promisc_mode = promisc_mode; card->info.promisc_mode = enable;
} }
}
static void qeth_l2_set_promisc_mode(struct qeth_card *card)
{
bool enable = card->dev->flags & IFF_PROMISC;
if (card->info.promisc_mode == enable)
return;
if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
qeth_setadp_promisc_mode(card, enable);
else if (card->options.sbp.reflect_promisc)
qeth_l2_promisc_to_bridge(card, enable);
} }
/* New MAC address is added to the hash table and marked to be written on card /* New MAC address is added to the hash table and marked to be written on card
* only if there is not in the hash table storage already * only if there is not in the hash table storage already
* *
...@@ -539,10 +542,7 @@ static void qeth_l2_rx_mode_work(struct work_struct *work) ...@@ -539,10 +542,7 @@ static void qeth_l2_rx_mode_work(struct work_struct *work)
} }
} }
if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) qeth_l2_set_promisc_mode(card);
qeth_setadp_promisc_mode(card);
else
qeth_promisc_to_bridge(card);
} }
static int qeth_l2_xmit_osn(struct qeth_card *card, struct sk_buff *skb, static int qeth_l2_xmit_osn(struct qeth_card *card, struct sk_buff *skb,
...@@ -1000,9 +1000,10 @@ struct qeth_discipline qeth_l2_discipline = { ...@@ -1000,9 +1000,10 @@ struct qeth_discipline qeth_l2_discipline = {
EXPORT_SYMBOL_GPL(qeth_l2_discipline); EXPORT_SYMBOL_GPL(qeth_l2_discipline);
static void qeth_osn_assist_cb(struct qeth_card *card, static void qeth_osn_assist_cb(struct qeth_card *card,
struct qeth_cmd_buffer *iob) struct qeth_cmd_buffer *iob,
unsigned int data_length)
{ {
qeth_notify_reply(iob->reply, 0); qeth_notify_cmd(iob, 0);
qeth_put_cmd(iob); qeth_put_cmd(iob);
} }
...@@ -1703,7 +1704,6 @@ static int qeth_l2_vnicc_makerc(struct qeth_card *card, u16 ipa_rc) ...@@ -1703,7 +1704,6 @@ static int qeth_l2_vnicc_makerc(struct qeth_card *card, u16 ipa_rc)
/* generic VNICC request call back control */ /* generic VNICC request call back control */
struct _qeth_l2_vnicc_request_cbctl { struct _qeth_l2_vnicc_request_cbctl {
u32 sub_cmd;
struct { struct {
union{ union{
u32 *sup_cmds; u32 *sup_cmds;
...@@ -1721,6 +1721,7 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card, ...@@ -1721,6 +1721,7 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card,
(struct _qeth_l2_vnicc_request_cbctl *) reply->param; (struct _qeth_l2_vnicc_request_cbctl *) reply->param;
struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data; struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
struct qeth_ipacmd_vnicc *rep = &cmd->data.vnicc; struct qeth_ipacmd_vnicc *rep = &cmd->data.vnicc;
u32 sub_cmd = cmd->data.vnicc.hdr.sub_command;
QETH_CARD_TEXT(card, 2, "vniccrcb"); QETH_CARD_TEXT(card, 2, "vniccrcb");
if (cmd->hdr.return_code) if (cmd->hdr.return_code)
...@@ -1729,10 +1730,9 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card, ...@@ -1729,10 +1730,9 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card,
card->options.vnicc.sup_chars = rep->vnicc_cmds.supported; card->options.vnicc.sup_chars = rep->vnicc_cmds.supported;
card->options.vnicc.cur_chars = rep->vnicc_cmds.enabled; card->options.vnicc.cur_chars = rep->vnicc_cmds.enabled;
if (cbctl->sub_cmd == IPA_VNICC_QUERY_CMDS) if (sub_cmd == IPA_VNICC_QUERY_CMDS)
*cbctl->result.sup_cmds = rep->data.query_cmds.sup_cmds; *cbctl->result.sup_cmds = rep->data.query_cmds.sup_cmds;
else if (sub_cmd == IPA_VNICC_GET_TIMEOUT)
if (cbctl->sub_cmd == IPA_VNICC_GET_TIMEOUT)
*cbctl->result.timeout = rep->data.getset_timeout.timeout; *cbctl->result.timeout = rep->data.getset_timeout.timeout;
return 0; return 0;
...@@ -1760,7 +1760,6 @@ static struct qeth_cmd_buffer *qeth_l2_vnicc_build_cmd(struct qeth_card *card, ...@@ -1760,7 +1760,6 @@ static struct qeth_cmd_buffer *qeth_l2_vnicc_build_cmd(struct qeth_card *card,
/* VNICC query VNIC characteristics request */ /* VNICC query VNIC characteristics request */
static int qeth_l2_vnicc_query_chars(struct qeth_card *card) static int qeth_l2_vnicc_query_chars(struct qeth_card *card)
{ {
struct _qeth_l2_vnicc_request_cbctl cbctl;
struct qeth_cmd_buffer *iob; struct qeth_cmd_buffer *iob;
QETH_CARD_TEXT(card, 2, "vniccqch"); QETH_CARD_TEXT(card, 2, "vniccqch");
...@@ -1768,10 +1767,7 @@ static int qeth_l2_vnicc_query_chars(struct qeth_card *card) ...@@ -1768,10 +1767,7 @@ static int qeth_l2_vnicc_query_chars(struct qeth_card *card)
if (!iob) if (!iob)
return -ENOMEM; return -ENOMEM;
/* prepare callback control */ return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, NULL);
cbctl.sub_cmd = IPA_VNICC_QUERY_CHARS;
return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
} }
/* VNICC query sub commands request */ /* VNICC query sub commands request */
...@@ -1790,7 +1786,6 @@ static int qeth_l2_vnicc_query_cmds(struct qeth_card *card, u32 vnic_char, ...@@ -1790,7 +1786,6 @@ static int qeth_l2_vnicc_query_cmds(struct qeth_card *card, u32 vnic_char,
__ipa_cmd(iob)->data.vnicc.data.query_cmds.vnic_char = vnic_char; __ipa_cmd(iob)->data.vnicc.data.query_cmds.vnic_char = vnic_char;
/* prepare callback control */ /* prepare callback control */
cbctl.sub_cmd = IPA_VNICC_QUERY_CMDS;
cbctl.result.sup_cmds = sup_cmds; cbctl.result.sup_cmds = sup_cmds;
return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl); return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
...@@ -1800,7 +1795,6 @@ static int qeth_l2_vnicc_query_cmds(struct qeth_card *card, u32 vnic_char, ...@@ -1800,7 +1795,6 @@ static int qeth_l2_vnicc_query_cmds(struct qeth_card *card, u32 vnic_char,
static int qeth_l2_vnicc_set_char(struct qeth_card *card, u32 vnic_char, static int qeth_l2_vnicc_set_char(struct qeth_card *card, u32 vnic_char,
u32 cmd) u32 cmd)
{ {
struct _qeth_l2_vnicc_request_cbctl cbctl;
struct qeth_cmd_buffer *iob; struct qeth_cmd_buffer *iob;
QETH_CARD_TEXT(card, 2, "vniccedc"); QETH_CARD_TEXT(card, 2, "vniccedc");
...@@ -1810,10 +1804,7 @@ static int qeth_l2_vnicc_set_char(struct qeth_card *card, u32 vnic_char, ...@@ -1810,10 +1804,7 @@ static int qeth_l2_vnicc_set_char(struct qeth_card *card, u32 vnic_char,
__ipa_cmd(iob)->data.vnicc.data.set_char.vnic_char = vnic_char; __ipa_cmd(iob)->data.vnicc.data.set_char.vnic_char = vnic_char;
/* prepare callback control */ return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, NULL);
cbctl.sub_cmd = cmd;
return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
} }
/* VNICC get/set timeout for characteristic request */ /* VNICC get/set timeout for characteristic request */
...@@ -1837,7 +1828,6 @@ static int qeth_l2_vnicc_getset_timeout(struct qeth_card *card, u32 vnicc, ...@@ -1837,7 +1828,6 @@ static int qeth_l2_vnicc_getset_timeout(struct qeth_card *card, u32 vnicc,
getset_timeout->timeout = *timeout; getset_timeout->timeout = *timeout;
/* prepare callback control */ /* prepare callback control */
cbctl.sub_cmd = cmd;
if (cmd == IPA_VNICC_GET_TIMEOUT) if (cmd == IPA_VNICC_GET_TIMEOUT)
cbctl.result.timeout = timeout; cbctl.result.timeout = timeout;
......
...@@ -1435,27 +1435,19 @@ static void qeth_l3_stop_card(struct qeth_card *card) ...@@ -1435,27 +1435,19 @@ static void qeth_l3_stop_card(struct qeth_card *card)
flush_workqueue(card->event_wq); flush_workqueue(card->event_wq);
} }
/* static void qeth_l3_set_promisc_mode(struct qeth_card *card)
* test for and Switch promiscuous mode (on or off)
* either for guestlan or HiperSocket Sniffer
*/
static void
qeth_l3_handle_promisc_mode(struct qeth_card *card)
{ {
struct net_device *dev = card->dev; bool enable = card->dev->flags & IFF_PROMISC;
if (((dev->flags & IFF_PROMISC) && if (card->info.promisc_mode == enable)
(card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
(!(dev->flags & IFF_PROMISC) &&
(card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
return; return;
if (IS_VM_NIC(card)) { /* Guestlan trace */ if (IS_VM_NIC(card)) { /* Guestlan trace */
if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
qeth_setadp_promisc_mode(card); qeth_setadp_promisc_mode(card, enable);
} else if (card->options.sniffer && /* HiperSockets trace */ } else if (card->options.sniffer && /* HiperSockets trace */
qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) { qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) {
if (dev->flags & IFF_PROMISC) { if (enable) {
QETH_CARD_TEXT(card, 3, "+promisc"); QETH_CARD_TEXT(card, 3, "+promisc");
qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_ENABLE); qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_ENABLE);
} else { } else {
...@@ -1502,11 +1494,9 @@ static void qeth_l3_rx_mode_work(struct work_struct *work) ...@@ -1502,11 +1494,9 @@ static void qeth_l3_rx_mode_work(struct work_struct *work)
addr->disp_flag = QETH_DISP_ADDR_DELETE; addr->disp_flag = QETH_DISP_ADDR_DELETE;
} }
} }
if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
return;
} }
qeth_l3_handle_promisc_mode(card);
qeth_l3_set_promisc_mode(card);
} }
static int qeth_l3_arp_makerc(u16 rc) static int qeth_l3_arp_makerc(u16 rc)
......
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