mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits) macvlan: fix panic if lowerdev in a bond tg3: Add braces around 5906 workaround. tg3: Fix NETIF_F_LOOPBACK error macvlan: remove one synchronize_rcu() call networking: NET_CLS_ROUTE4 depends on INET irda: Fix error propagation in ircomm_lmp_connect_response() irda: Kill set but unused variable 'bytes' in irlan_check_command_param() irda: Kill set but unused variable 'clen' in ircomm_connect_indication() rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport() be2net: Kill set but unused variable 'req' in lancer_fw_download() irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication() atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined. rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer(). rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler() rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection() rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window() pkt_sched: Kill set but unused variable 'protocol' in tc_classify() isdn: capi: Use pr_debug() instead of ifdefs. tg3: Update version to 3.119 tg3: Apply rx_discards fix to 5719/5720 ... Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c as per Davem.
This commit is contained in:
commit
06f4e926d2
1198 changed files with 126873 additions and 79635 deletions
|
|
@ -845,12 +845,10 @@ claw_irq_tasklet ( unsigned long data )
|
|||
{
|
||||
struct chbk * p_ch;
|
||||
struct net_device *dev;
|
||||
struct claw_privbk * privptr;
|
||||
|
||||
p_ch = (struct chbk *) data;
|
||||
dev = (struct net_device *)p_ch->ndev;
|
||||
CLAW_DBF_TEXT(4, trace, "IRQtask");
|
||||
privptr = (struct claw_privbk *)dev->ml_priv;
|
||||
unpack_read(dev);
|
||||
clear_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a);
|
||||
CLAW_DBF_TEXT(4, trace, "TskletXt");
|
||||
|
|
@ -1026,7 +1024,6 @@ claw_write_next ( struct chbk * p_ch )
|
|||
struct net_device *dev;
|
||||
struct claw_privbk *privptr=NULL;
|
||||
struct sk_buff *pk_skb;
|
||||
int rc;
|
||||
|
||||
CLAW_DBF_TEXT(4, trace, "claw_wrt");
|
||||
if (p_ch->claw_state == CLAW_STOP)
|
||||
|
|
@ -1038,7 +1035,7 @@ claw_write_next ( struct chbk * p_ch )
|
|||
!skb_queue_empty(&p_ch->collect_queue)) {
|
||||
pk_skb = claw_pack_skb(privptr);
|
||||
while (pk_skb != NULL) {
|
||||
rc = claw_hw_tx( pk_skb, dev,1);
|
||||
claw_hw_tx(pk_skb, dev, 1);
|
||||
if (privptr->write_free_count > 0) {
|
||||
pk_skb = claw_pack_skb(privptr);
|
||||
} else
|
||||
|
|
@ -1322,15 +1319,12 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
|
|||
unsigned char *pDataAddress;
|
||||
struct endccw *pEnd;
|
||||
struct ccw1 tempCCW;
|
||||
struct chbk *p_ch;
|
||||
struct claw_env *p_env;
|
||||
int lock;
|
||||
struct clawph *pk_head;
|
||||
struct chbk *ch;
|
||||
|
||||
CLAW_DBF_TEXT(4, trace, "hw_tx");
|
||||
privptr = (struct claw_privbk *)(dev->ml_priv);
|
||||
p_ch = (struct chbk *)&privptr->channel[WRITE_CHANNEL];
|
||||
p_env =privptr->p_env;
|
||||
claw_free_wrt_buf(dev); /* Clean up free chain if posible */
|
||||
/* scan the write queue to free any completed write packets */
|
||||
|
|
@ -1511,12 +1505,6 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
|
|||
|
||||
} /* endif (p_first_ccw!=NULL) */
|
||||
dev_kfree_skb_any(skb);
|
||||
if (linkid==0) {
|
||||
lock=LOCK_NO;
|
||||
}
|
||||
else {
|
||||
lock=LOCK_YES;
|
||||
}
|
||||
claw_strt_out_IO(dev );
|
||||
/* if write free count is zero , set NOBUFFER */
|
||||
if (privptr->write_free_count==0) {
|
||||
|
|
@ -2821,15 +2809,11 @@ claw_free_wrt_buf( struct net_device *dev )
|
|||
{
|
||||
|
||||
struct claw_privbk *privptr = (struct claw_privbk *)dev->ml_priv;
|
||||
struct ccwbk*p_first_ccw;
|
||||
struct ccwbk*p_last_ccw;
|
||||
struct ccwbk*p_this_ccw;
|
||||
struct ccwbk*p_next_ccw;
|
||||
|
||||
CLAW_DBF_TEXT(4, trace, "freewrtb");
|
||||
/* scan the write queue to free any completed write packets */
|
||||
p_first_ccw=NULL;
|
||||
p_last_ccw=NULL;
|
||||
p_this_ccw=privptr->p_write_active_first;
|
||||
while ( (p_this_ccw!=NULL) && (p_this_ccw->header.flag!=CLAW_PENDING))
|
||||
{
|
||||
|
|
@ -3072,7 +3056,7 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
|
|||
{
|
||||
struct claw_privbk *priv;
|
||||
struct net_device *ndev;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
|
||||
priv = dev_get_drvdata(&cgdev->dev);
|
||||
|
|
@ -3095,7 +3079,7 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
|
|||
}
|
||||
ccw_device_set_offline(cgdev->cdev[1]);
|
||||
ccw_device_set_offline(cgdev->cdev[0]);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -672,7 +672,6 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
int ccw_idx;
|
||||
unsigned long hi;
|
||||
unsigned long saveflags = 0; /* avoids compiler warning */
|
||||
__u16 block_len;
|
||||
|
||||
CTCM_PR_DEBUG("Enter %s: %s, cp=%i ch=0x%p id=%s state=%s\n",
|
||||
__func__, dev->name, smp_processor_id(), ch,
|
||||
|
|
@ -719,7 +718,6 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
*/
|
||||
atomic_inc(&skb->users);
|
||||
|
||||
block_len = skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
|
||||
/*
|
||||
* IDAL support in CTCM is broken, so we have to
|
||||
* care about skb's above 2G ourselves.
|
||||
|
|
|
|||
|
|
@ -653,7 +653,6 @@ static void ctcmpc_send_sweep_resp(struct channel *rch)
|
|||
struct net_device *dev = rch->netdev;
|
||||
struct ctcm_priv *priv = dev->ml_priv;
|
||||
struct mpc_group *grp = priv->mpcg;
|
||||
int rc = 0;
|
||||
struct th_sweep *header;
|
||||
struct sk_buff *sweep_skb;
|
||||
struct channel *ch = priv->channel[CTCM_WRITE];
|
||||
|
|
@ -665,16 +664,14 @@ static void ctcmpc_send_sweep_resp(struct channel *rch)
|
|||
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): sweep_skb allocation ERROR\n",
|
||||
CTCM_FUNTAIL, rch->id);
|
||||
rc = -ENOMEM;
|
||||
goto done;
|
||||
goto done;
|
||||
}
|
||||
|
||||
header = kmalloc(sizeof(struct th_sweep), gfp_type());
|
||||
|
||||
if (!header) {
|
||||
dev_kfree_skb_any(sweep_skb);
|
||||
rc = -ENOMEM;
|
||||
goto done;
|
||||
goto done;
|
||||
}
|
||||
|
||||
header->th.th_seg = 0x00 ;
|
||||
|
|
@ -1370,8 +1367,7 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
|
|||
struct net_device *dev = arg;
|
||||
struct ctcm_priv *priv;
|
||||
struct mpc_group *grp;
|
||||
int rc = 0;
|
||||
struct channel *wch, *rch;
|
||||
struct channel *wch;
|
||||
|
||||
BUG_ON(dev == NULL);
|
||||
CTCM_PR_DEBUG("Enter %s: %s\n", __func__, dev->name);
|
||||
|
|
@ -1396,7 +1392,6 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
|
|||
fsm_deltimer(&priv->restart_timer);
|
||||
|
||||
wch = priv->channel[CTCM_WRITE];
|
||||
rch = priv->channel[CTCM_READ];
|
||||
|
||||
switch (grp->saved_state) {
|
||||
case MPCG_STATE_RESET:
|
||||
|
|
@ -1435,7 +1430,7 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
|
|||
|
||||
if (grp->send_qllc_disc == 1) {
|
||||
grp->send_qllc_disc = 0;
|
||||
rc = mpc_send_qllc_discontact(dev);
|
||||
mpc_send_qllc_discontact(dev);
|
||||
}
|
||||
|
||||
/* DO NOT issue DEV_EVENT_STOP directly out of this code */
|
||||
|
|
|
|||
|
|
@ -1483,7 +1483,6 @@ lcs_tasklet(unsigned long data)
|
|||
struct lcs_channel *channel;
|
||||
struct lcs_buffer *iob;
|
||||
int buf_idx;
|
||||
int rc;
|
||||
|
||||
channel = (struct lcs_channel *) data;
|
||||
LCS_DBF_TEXT_(5, trace, "tlet%s", dev_name(&channel->ccwdev->dev));
|
||||
|
|
@ -1500,14 +1499,11 @@ lcs_tasklet(unsigned long data)
|
|||
channel->buf_idx = buf_idx;
|
||||
|
||||
if (channel->state == LCS_CH_STATE_STOPPED)
|
||||
// FIXME: what if rc != 0 ??
|
||||
rc = lcs_start_channel(channel);
|
||||
lcs_start_channel(channel);
|
||||
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
|
||||
if (channel->state == LCS_CH_STATE_SUSPENDED &&
|
||||
channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY) {
|
||||
// FIXME: what if rc != 0 ??
|
||||
rc = __lcs_resume_channel(channel);
|
||||
}
|
||||
channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY)
|
||||
__lcs_resume_channel(channel);
|
||||
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
|
||||
|
||||
/* Something happened on the channel. Wake up waiters. */
|
||||
|
|
|
|||
|
|
@ -1994,8 +1994,6 @@ static struct net_device *netiucv_init_netdevice(char *username)
|
|||
netiucv_setup_netdevice);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
if (dev_alloc_name(dev, dev->name) < 0)
|
||||
goto out_netdev;
|
||||
|
||||
privptr = netdev_priv(dev);
|
||||
privptr->fsm = init_fsm("netiucvdev", dev_state_names,
|
||||
|
|
|
|||
|
|
@ -407,12 +407,6 @@ struct qeth_qdio_q {
|
|||
int next_buf_to_init;
|
||||
} __attribute__ ((aligned(256)));
|
||||
|
||||
/* possible types of qeth large_send support */
|
||||
enum qeth_large_send_types {
|
||||
QETH_LARGE_SEND_NO,
|
||||
QETH_LARGE_SEND_TSO,
|
||||
};
|
||||
|
||||
struct qeth_qdio_out_buffer {
|
||||
struct qdio_buffer *buffer;
|
||||
atomic_t state;
|
||||
|
|
@ -637,6 +631,8 @@ struct qeth_card_info {
|
|||
__u32 csum_mask;
|
||||
__u32 tx_csum_mask;
|
||||
enum qeth_ipa_promisc_modes promisc_mode;
|
||||
__u32 diagass_support;
|
||||
__u32 hwtrap;
|
||||
};
|
||||
|
||||
struct qeth_card_options {
|
||||
|
|
@ -645,13 +641,11 @@ struct qeth_card_options {
|
|||
struct qeth_ipa_info adp; /*Adapter parameters*/
|
||||
struct qeth_routing_info route6;
|
||||
struct qeth_ipa_info ipa6;
|
||||
enum qeth_checksum_types checksum_type;
|
||||
int broadcast_mode;
|
||||
int macaddr_mode;
|
||||
int fake_broadcast;
|
||||
int add_hhlen;
|
||||
int layer2;
|
||||
enum qeth_large_send_types large_send;
|
||||
int performance_stats;
|
||||
int rx_sg_cb;
|
||||
enum qeth_ipa_isolation_modes isolation;
|
||||
|
|
@ -760,6 +754,14 @@ struct qeth_card_list_struct {
|
|||
rwlock_t rwlock;
|
||||
};
|
||||
|
||||
struct qeth_trap_id {
|
||||
__u16 lparnr;
|
||||
char vmname[8];
|
||||
__u8 chpid;
|
||||
__u8 ssid;
|
||||
__u16 devno;
|
||||
} __packed;
|
||||
|
||||
/*some helper functions*/
|
||||
#define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
|
||||
|
||||
|
|
@ -794,6 +796,12 @@ static inline void qeth_put_buffer_pool_entry(struct qeth_card *card,
|
|||
list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list);
|
||||
}
|
||||
|
||||
static inline int qeth_is_diagass_supported(struct qeth_card *card,
|
||||
enum qeth_diags_cmds cmd)
|
||||
{
|
||||
return card->info.diagass_support & (__u32)cmd;
|
||||
}
|
||||
|
||||
extern struct ccwgroup_driver qeth_l2_ccwgroup_driver;
|
||||
extern struct ccwgroup_driver qeth_l3_ccwgroup_driver;
|
||||
const char *qeth_get_cardname_short(struct qeth_card *);
|
||||
|
|
@ -879,6 +887,8 @@ void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...);
|
|||
int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
|
||||
int qeth_set_access_ctrl_online(struct qeth_card *card);
|
||||
int qeth_hdr_chk_and_bounce(struct sk_buff *, int);
|
||||
int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
|
||||
int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot);
|
||||
|
||||
/* exports for OSN */
|
||||
int qeth_osn_assist(struct net_device *, void *, int);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <asm/ebcdic.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/sysinfo.h>
|
||||
|
||||
#include "qeth_core.h"
|
||||
|
||||
|
|
@ -349,6 +350,8 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
|
|||
card->info.chpid);
|
||||
netif_carrier_on(card->dev);
|
||||
card->lan_online = 1;
|
||||
if (card->info.hwtrap)
|
||||
card->info.hwtrap = 2;
|
||||
qeth_schedule_recovery(card);
|
||||
return NULL;
|
||||
case IPA_CMD_MODCCID:
|
||||
|
|
@ -1039,7 +1042,6 @@ static void qeth_set_intial_options(struct qeth_card *card)
|
|||
{
|
||||
card->options.route4.type = NO_ROUTER;
|
||||
card->options.route6.type = NO_ROUTER;
|
||||
card->options.checksum_type = QETH_CHECKSUM_DEFAULT;
|
||||
card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
|
||||
card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL;
|
||||
card->options.fake_broadcast = 0;
|
||||
|
|
@ -2574,6 +2576,142 @@ int qeth_query_setadapterparms(struct qeth_card *card)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_query_setadapterparms);
|
||||
|
||||
static int qeth_query_ipassists_cb(struct qeth_card *card,
|
||||
struct qeth_reply *reply, unsigned long data)
|
||||
{
|
||||
struct qeth_ipa_cmd *cmd;
|
||||
|
||||
QETH_DBF_TEXT(SETUP, 2, "qipasscb");
|
||||
|
||||
cmd = (struct qeth_ipa_cmd *) data;
|
||||
if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
|
||||
card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
|
||||
card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
|
||||
} else {
|
||||
card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
|
||||
card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
|
||||
}
|
||||
QETH_DBF_TEXT(SETUP, 2, "suppenbl");
|
||||
QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_supported);
|
||||
QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_enabled);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot)
|
||||
{
|
||||
int rc;
|
||||
struct qeth_cmd_buffer *iob;
|
||||
|
||||
QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot);
|
||||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot);
|
||||
rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_query_ipassists);
|
||||
|
||||
static int qeth_query_setdiagass_cb(struct qeth_card *card,
|
||||
struct qeth_reply *reply, unsigned long data)
|
||||
{
|
||||
struct qeth_ipa_cmd *cmd;
|
||||
__u16 rc;
|
||||
|
||||
cmd = (struct qeth_ipa_cmd *)data;
|
||||
rc = cmd->hdr.return_code;
|
||||
if (rc)
|
||||
QETH_CARD_TEXT_(card, 2, "diagq:%x", rc);
|
||||
else
|
||||
card->info.diagass_support = cmd->data.diagass.ext;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qeth_query_setdiagass(struct qeth_card *card)
|
||||
{
|
||||
struct qeth_cmd_buffer *iob;
|
||||
struct qeth_ipa_cmd *cmd;
|
||||
|
||||
QETH_DBF_TEXT(SETUP, 2, "qdiagass");
|
||||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd->data.diagass.subcmd_len = 16;
|
||||
cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY;
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_query_setdiagass_cb, NULL);
|
||||
}
|
||||
|
||||
static void qeth_get_trap_id(struct qeth_card *card, struct qeth_trap_id *tid)
|
||||
{
|
||||
unsigned long info = get_zeroed_page(GFP_KERNEL);
|
||||
struct sysinfo_2_2_2 *info222 = (struct sysinfo_2_2_2 *)info;
|
||||
struct sysinfo_3_2_2 *info322 = (struct sysinfo_3_2_2 *)info;
|
||||
struct ccw_dev_id ccwid;
|
||||
int level, rc;
|
||||
|
||||
tid->chpid = card->info.chpid;
|
||||
ccw_device_get_id(CARD_RDEV(card), &ccwid);
|
||||
tid->ssid = ccwid.ssid;
|
||||
tid->devno = ccwid.devno;
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
rc = stsi(NULL, 0, 0, 0);
|
||||
if (rc == -ENOSYS)
|
||||
level = rc;
|
||||
else
|
||||
level = (((unsigned int) rc) >> 28);
|
||||
|
||||
if ((level >= 2) && (stsi(info222, 2, 2, 2) != -ENOSYS))
|
||||
tid->lparnr = info222->lpar_number;
|
||||
|
||||
if ((level >= 3) && (stsi(info322, 3, 2, 2) != -ENOSYS)) {
|
||||
EBCASC(info322->vm[0].name, sizeof(info322->vm[0].name));
|
||||
memcpy(tid->vmname, info322->vm[0].name, sizeof(tid->vmname));
|
||||
}
|
||||
free_page(info);
|
||||
return;
|
||||
}
|
||||
|
||||
static int qeth_hw_trap_cb(struct qeth_card *card,
|
||||
struct qeth_reply *reply, unsigned long data)
|
||||
{
|
||||
struct qeth_ipa_cmd *cmd;
|
||||
__u16 rc;
|
||||
|
||||
cmd = (struct qeth_ipa_cmd *)data;
|
||||
rc = cmd->hdr.return_code;
|
||||
if (rc)
|
||||
QETH_CARD_TEXT_(card, 2, "trapc:%x", rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action)
|
||||
{
|
||||
struct qeth_cmd_buffer *iob;
|
||||
struct qeth_ipa_cmd *cmd;
|
||||
|
||||
QETH_DBF_TEXT(SETUP, 2, "diagtrap");
|
||||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd->data.diagass.subcmd_len = 80;
|
||||
cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP;
|
||||
cmd->data.diagass.type = 1;
|
||||
cmd->data.diagass.action = action;
|
||||
switch (action) {
|
||||
case QETH_DIAGS_TRAP_ARM:
|
||||
cmd->data.diagass.options = 0x0003;
|
||||
cmd->data.diagass.ext = 0x00010000 +
|
||||
sizeof(struct qeth_trap_id);
|
||||
qeth_get_trap_id(card,
|
||||
(struct qeth_trap_id *)cmd->data.diagass.cdata);
|
||||
break;
|
||||
case QETH_DIAGS_TRAP_DISARM:
|
||||
cmd->data.diagass.options = 0x0001;
|
||||
break;
|
||||
case QETH_DIAGS_TRAP_CAPTURE:
|
||||
break;
|
||||
}
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_hw_trap_cb, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_hw_trap);
|
||||
|
||||
int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
|
||||
unsigned int qdio_error, const char *dbftext)
|
||||
{
|
||||
|
|
@ -3903,6 +4041,7 @@ MODULE_DEVICE_TABLE(ccw, qeth_ids);
|
|||
|
||||
static struct ccw_driver qeth_ccw_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "qeth",
|
||||
},
|
||||
.ids = qeth_ids,
|
||||
|
|
@ -3984,6 +4123,15 @@ retriable:
|
|||
QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
card->options.ipa4.supported_funcs = 0;
|
||||
card->options.adp.supported_funcs = 0;
|
||||
card->info.diagass_support = 0;
|
||||
qeth_query_ipassists(card, QETH_PROT_IPV4);
|
||||
if (qeth_is_supported(card, IPA_SETADAPTERPARMS))
|
||||
qeth_query_setadapterparms(card);
|
||||
if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST))
|
||||
qeth_query_setdiagass(card);
|
||||
return 0;
|
||||
out:
|
||||
dev_warn(&card->gdev->dev, "The qeth device driver failed to recover "
|
||||
|
|
|
|||
|
|
@ -80,14 +80,6 @@ enum qeth_tr_broadcast_modes {
|
|||
QETH_TR_BROADCAST_LOCAL = 1,
|
||||
};
|
||||
|
||||
/* these values match CHECKSUM_* in include/linux/skbuff.h */
|
||||
enum qeth_checksum_types {
|
||||
SW_CHECKSUMMING = 0, /* TODO: set to bit flag used in IPA Command */
|
||||
HW_CHECKSUMMING = 1,
|
||||
NO_CHECKSUMMING = 2,
|
||||
};
|
||||
#define QETH_CHECKSUM_DEFAULT SW_CHECKSUMMING
|
||||
|
||||
/*
|
||||
* Routing stuff
|
||||
*/
|
||||
|
|
@ -456,6 +448,12 @@ enum qeth_diags_trace_cmds {
|
|||
QETH_DIAGS_CMD_TRACE_QUERY = 0x0010,
|
||||
};
|
||||
|
||||
enum qeth_diags_trap_action {
|
||||
QETH_DIAGS_TRAP_ARM = 0x01,
|
||||
QETH_DIAGS_TRAP_DISARM = 0x02,
|
||||
QETH_DIAGS_TRAP_CAPTURE = 0x04,
|
||||
};
|
||||
|
||||
struct qeth_ipacmd_diagass {
|
||||
__u32 host_tod2;
|
||||
__u32:32;
|
||||
|
|
@ -465,7 +463,8 @@ struct qeth_ipacmd_diagass {
|
|||
__u8 type;
|
||||
__u8 action;
|
||||
__u16 options;
|
||||
__u32:32;
|
||||
__u32 ext;
|
||||
__u8 cdata[64];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Header for each IPA command */
|
||||
|
|
|
|||
|
|
@ -530,6 +530,66 @@ out:
|
|||
static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
|
||||
qeth_dev_isolation_store);
|
||||
|
||||
static ssize_t qeth_hw_trap_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(dev);
|
||||
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
if (card->info.hwtrap)
|
||||
return snprintf(buf, 5, "arm\n");
|
||||
else
|
||||
return snprintf(buf, 8, "disarm\n");
|
||||
}
|
||||
|
||||
static ssize_t qeth_hw_trap_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(dev);
|
||||
int rc = 0;
|
||||
char *tmp, *curtoken;
|
||||
int state = 0;
|
||||
curtoken = (char *)buf;
|
||||
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&card->conf_mutex);
|
||||
if (card->state == CARD_STATE_SOFTSETUP || card->state == CARD_STATE_UP)
|
||||
state = 1;
|
||||
tmp = strsep(&curtoken, "\n");
|
||||
|
||||
if (!strcmp(tmp, "arm") && !card->info.hwtrap) {
|
||||
if (state) {
|
||||
if (qeth_is_diagass_supported(card,
|
||||
QETH_DIAGS_CMD_TRAP)) {
|
||||
rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM);
|
||||
if (!rc)
|
||||
card->info.hwtrap = 1;
|
||||
} else
|
||||
rc = -EINVAL;
|
||||
} else
|
||||
card->info.hwtrap = 1;
|
||||
} else if (!strcmp(tmp, "disarm") && card->info.hwtrap) {
|
||||
if (state) {
|
||||
rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
|
||||
if (!rc)
|
||||
card->info.hwtrap = 0;
|
||||
} else
|
||||
card->info.hwtrap = 0;
|
||||
} else if (!strcmp(tmp, "trap") && state && card->info.hwtrap)
|
||||
rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_CAPTURE);
|
||||
else
|
||||
rc = -EINVAL;
|
||||
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
return rc ? rc : count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(hw_trap, 0644, qeth_hw_trap_show,
|
||||
qeth_hw_trap_store);
|
||||
|
||||
static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
|
||||
{
|
||||
|
||||
|
|
@ -653,6 +713,7 @@ static struct attribute *qeth_device_attrs[] = {
|
|||
&dev_attr_performance_stats.attr,
|
||||
&dev_attr_layer2.attr,
|
||||
&dev_attr_isolation.attr,
|
||||
&dev_attr_hw_trap.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -420,10 +420,7 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
|
|||
case QETH_HEADER_TYPE_LAYER2:
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
skb->protocol = eth_type_trans(skb, skb->dev);
|
||||
if (card->options.checksum_type == NO_CHECKSUMMING)
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
else
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
if (skb->protocol == htons(ETH_P_802_2))
|
||||
*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
|
||||
len = skb->len;
|
||||
|
|
@ -879,6 +876,7 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
|
|||
INIT_LIST_HEAD(&card->vid_list);
|
||||
INIT_LIST_HEAD(&card->mc_list);
|
||||
card->options.layer2 = 1;
|
||||
card->info.hwtrap = 0;
|
||||
card->discipline.start_poll = qeth_qdio_start_poll;
|
||||
card->discipline.input_handler = (qdio_handler_t *)
|
||||
qeth_qdio_input_handler;
|
||||
|
|
@ -997,6 +995,13 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|||
if (card->info.type != QETH_CARD_TYPE_OSN)
|
||||
qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
|
||||
|
||||
if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
|
||||
if (card->info.hwtrap &&
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM))
|
||||
card->info.hwtrap = 0;
|
||||
} else
|
||||
card->info.hwtrap = 0;
|
||||
|
||||
card->state = CARD_STATE_HARDSETUP;
|
||||
memset(&card->rx, 0, sizeof(struct qeth_rx));
|
||||
qeth_print_status_message(card);
|
||||
|
|
@ -1095,6 +1100,10 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
|
|||
if (card->dev && netif_carrier_ok(card->dev))
|
||||
netif_carrier_off(card->dev);
|
||||
recover_flag = card->state;
|
||||
if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
|
||||
card->info.hwtrap = 1;
|
||||
}
|
||||
qeth_l2_stop_card(card, recovery_mode);
|
||||
rc = ccw_device_set_offline(CARD_DDEV(card));
|
||||
rc2 = ccw_device_set_offline(CARD_WDEV(card));
|
||||
|
|
@ -1160,6 +1169,8 @@ static void __exit qeth_l2_exit(void)
|
|||
static void qeth_l2_shutdown(struct ccwgroup_device *gdev)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
|
||||
if ((gdev->state == CCWGROUP_ONLINE) && card->info.hwtrap)
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
|
||||
qeth_qdio_clear_card(card, 0);
|
||||
qeth_clear_qdio_buffers(card);
|
||||
}
|
||||
|
|
@ -1175,6 +1186,8 @@ static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev)
|
|||
if (gdev->state == CCWGROUP_OFFLINE)
|
||||
return 0;
|
||||
if (card->state == CARD_STATE_UP) {
|
||||
if (card->info.hwtrap)
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
|
||||
__qeth_l2_set_offline(card->gdev, 1);
|
||||
} else
|
||||
__qeth_l2_set_offline(card->gdev, 0);
|
||||
|
|
|
|||
|
|
@ -62,8 +62,6 @@ void qeth_l3_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
|
|||
int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
|
||||
void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions,
|
||||
const u8 *);
|
||||
int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types);
|
||||
int qeth_l3_set_rx_csum(struct qeth_card *, enum qeth_checksum_types);
|
||||
int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);
|
||||
|
||||
#endif /* __QETH_L3_H__ */
|
||||
|
|
|
|||
|
|
@ -43,33 +43,6 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *,
|
|||
static int __qeth_l3_set_online(struct ccwgroup_device *, int);
|
||||
static int __qeth_l3_set_offline(struct ccwgroup_device *, int);
|
||||
|
||||
int qeth_l3_set_large_send(struct qeth_card *card,
|
||||
enum qeth_large_send_types type)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
card->options.large_send = type;
|
||||
if (card->dev == NULL)
|
||||
return 0;
|
||||
|
||||
if (card->options.large_send == QETH_LARGE_SEND_TSO) {
|
||||
if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
|
||||
card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
|
||||
NETIF_F_IP_CSUM;
|
||||
} else {
|
||||
card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
|
||||
NETIF_F_IP_CSUM);
|
||||
card->options.large_send = QETH_LARGE_SEND_NO;
|
||||
rc = -EOPNOTSUPP;
|
||||
}
|
||||
} else {
|
||||
card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
|
||||
NETIF_F_IP_CSUM);
|
||||
card->options.large_send = QETH_LARGE_SEND_NO;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int qeth_l3_isxdigit(char *buf)
|
||||
{
|
||||
while (*buf) {
|
||||
|
|
@ -1304,39 +1277,6 @@ static int qeth_l3_start_ipa_multicast(struct qeth_card *card)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int qeth_l3_query_ipassists_cb(struct qeth_card *card,
|
||||
struct qeth_reply *reply, unsigned long data)
|
||||
{
|
||||
struct qeth_ipa_cmd *cmd;
|
||||
|
||||
QETH_DBF_TEXT(SETUP, 2, "qipasscb");
|
||||
|
||||
cmd = (struct qeth_ipa_cmd *) data;
|
||||
if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
|
||||
card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
|
||||
card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
|
||||
} else {
|
||||
card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
|
||||
card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
|
||||
}
|
||||
QETH_DBF_TEXT(SETUP, 2, "suppenbl");
|
||||
QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_supported);
|
||||
QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_enabled);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qeth_l3_query_ipassists(struct qeth_card *card,
|
||||
enum qeth_prot_versions prot)
|
||||
{
|
||||
int rc;
|
||||
struct qeth_cmd_buffer *iob;
|
||||
|
||||
QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot);
|
||||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot);
|
||||
rc = qeth_send_ipa_cmd(card, iob, qeth_l3_query_ipassists_cb, NULL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QETH_IPV6
|
||||
static int qeth_l3_softsetup_ipv6(struct qeth_card *card)
|
||||
{
|
||||
|
|
@ -1347,7 +1287,7 @@ static int qeth_l3_softsetup_ipv6(struct qeth_card *card)
|
|||
if (card->info.type == QETH_CARD_TYPE_IQD)
|
||||
goto out;
|
||||
|
||||
rc = qeth_l3_query_ipassists(card, QETH_PROT_IPV6);
|
||||
rc = qeth_query_ipassists(card, QETH_PROT_IPV6);
|
||||
if (rc) {
|
||||
dev_err(&card->gdev->dev,
|
||||
"Activating IPv6 support for %s failed\n",
|
||||
|
|
@ -1472,68 +1412,38 @@ static int qeth_l3_send_checksum_command(struct qeth_card *card)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int qeth_l3_set_rx_csum(struct qeth_card *card,
|
||||
enum qeth_checksum_types csum_type)
|
||||
int qeth_l3_set_rx_csum(struct qeth_card *card, int on)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (card->options.checksum_type == HW_CHECKSUMMING) {
|
||||
if ((csum_type != HW_CHECKSUMMING) &&
|
||||
(card->state != CARD_STATE_DOWN)) {
|
||||
rc = qeth_l3_send_simple_setassparms(card,
|
||||
IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
|
||||
if (rc)
|
||||
return -EIO;
|
||||
}
|
||||
if (on) {
|
||||
rc = qeth_l3_send_checksum_command(card);
|
||||
if (rc)
|
||||
return -EIO;
|
||||
dev_info(&card->gdev->dev,
|
||||
"HW Checksumming (inbound) enabled\n");
|
||||
} else {
|
||||
if (csum_type == HW_CHECKSUMMING) {
|
||||
if (card->state != CARD_STATE_DOWN) {
|
||||
if (!qeth_is_supported(card,
|
||||
IPA_INBOUND_CHECKSUM))
|
||||
return -EPERM;
|
||||
rc = qeth_l3_send_checksum_command(card);
|
||||
if (rc)
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
rc = qeth_l3_send_simple_setassparms(card,
|
||||
IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
|
||||
if (rc)
|
||||
return -EIO;
|
||||
}
|
||||
card->options.checksum_type = csum_type;
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qeth_l3_start_ipa_checksum(struct qeth_card *card)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
QETH_CARD_TEXT(card, 3, "strtcsum");
|
||||
|
||||
if (card->options.checksum_type == NO_CHECKSUMMING) {
|
||||
dev_info(&card->gdev->dev,
|
||||
"Using no checksumming on %s.\n",
|
||||
QETH_CARD_IFNAME(card));
|
||||
return 0;
|
||||
if (card->dev->features & NETIF_F_RXCSUM) {
|
||||
rtnl_lock();
|
||||
/* force set_features call */
|
||||
card->dev->features &= ~NETIF_F_RXCSUM;
|
||||
netdev_update_features(card->dev);
|
||||
rtnl_unlock();
|
||||
}
|
||||
if (card->options.checksum_type == SW_CHECKSUMMING) {
|
||||
dev_info(&card->gdev->dev,
|
||||
"Using SW checksumming on %s.\n",
|
||||
QETH_CARD_IFNAME(card));
|
||||
return 0;
|
||||
}
|
||||
if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) {
|
||||
dev_info(&card->gdev->dev,
|
||||
"Inbound HW Checksumming not "
|
||||
"supported on %s,\ncontinuing "
|
||||
"using Inbound SW Checksumming\n",
|
||||
QETH_CARD_IFNAME(card));
|
||||
card->options.checksum_type = SW_CHECKSUMMING;
|
||||
return 0;
|
||||
}
|
||||
rc = qeth_l3_send_checksum_command(card);
|
||||
if (!rc)
|
||||
dev_info(&card->gdev->dev,
|
||||
"HW Checksumming (inbound) enabled\n");
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qeth_l3_start_ipa_tx_checksum(struct qeth_card *card)
|
||||
|
|
@ -1580,10 +1490,8 @@ static int qeth_l3_start_ipa_tso(struct qeth_card *card)
|
|||
dev_info(&card->gdev->dev,
|
||||
"Outbound TSO enabled\n");
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (rc)
|
||||
card->dev->features &= ~NETIF_F_TSO;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -2064,14 +1972,7 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card,
|
|||
is_vlan = 1;
|
||||
}
|
||||
|
||||
switch (card->options.checksum_type) {
|
||||
case SW_CHECKSUMMING:
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
break;
|
||||
case NO_CHECKSUMMING:
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
break;
|
||||
case HW_CHECKSUMMING:
|
||||
if (card->dev->features & NETIF_F_RXCSUM) {
|
||||
if ((hdr->hdr.l3.ext_flags &
|
||||
(QETH_HDR_EXT_CSUM_HDR_REQ |
|
||||
QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
|
||||
|
|
@ -2080,7 +1981,8 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card,
|
|||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
else
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
}
|
||||
} else
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
return is_vlan;
|
||||
}
|
||||
|
|
@ -3024,7 +2926,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
struct qeth_qdio_out_q *queue = card->qdio.out_qs
|
||||
[qeth_get_priority_queue(card, skb, ipv, cast_type)];
|
||||
int tx_bytes = skb->len;
|
||||
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
|
||||
bool large_send;
|
||||
int data_offset = -1;
|
||||
int nr_frags;
|
||||
|
||||
|
|
@ -3046,8 +2948,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
card->perf_stats.outbound_start_time = qeth_get_micros();
|
||||
}
|
||||
|
||||
if (skb_is_gso(skb))
|
||||
large_send = card->options.large_send;
|
||||
large_send = skb_is_gso(skb);
|
||||
|
||||
if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
|
||||
(skb_shinfo(skb)->nr_frags == 0)) {
|
||||
|
|
@ -3096,7 +2997,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
/* fix hardware limitation: as long as we do not have sbal
|
||||
* chaining we can not send long frag lists
|
||||
*/
|
||||
if (large_send == QETH_LARGE_SEND_TSO) {
|
||||
if (large_send) {
|
||||
if (qeth_l3_tso_elements(new_skb) + 1 > 16) {
|
||||
if (skb_linearize(new_skb))
|
||||
goto tx_drop;
|
||||
|
|
@ -3105,8 +3006,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
if ((large_send == QETH_LARGE_SEND_TSO) &&
|
||||
(cast_type == RTN_UNSPEC)) {
|
||||
if (large_send && (cast_type == RTN_UNSPEC)) {
|
||||
hdr = (struct qeth_hdr *)skb_push(new_skb,
|
||||
sizeof(struct qeth_hdr_tso));
|
||||
memset(hdr, 0, sizeof(struct qeth_hdr_tso));
|
||||
|
|
@ -3141,7 +3041,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
if (card->info.type != QETH_CARD_TYPE_IQD) {
|
||||
int len;
|
||||
if (large_send == QETH_LARGE_SEND_TSO)
|
||||
if (large_send)
|
||||
len = ((unsigned long)tcp_hdr(new_skb) +
|
||||
tcp_hdr(new_skb)->doff * 4) -
|
||||
(unsigned long)new_skb->data;
|
||||
|
|
@ -3162,7 +3062,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if (new_skb != skb)
|
||||
dev_kfree_skb_any(skb);
|
||||
if (card->options.performance_stats) {
|
||||
if (large_send != QETH_LARGE_SEND_NO) {
|
||||
if (large_send) {
|
||||
card->perf_stats.large_send_bytes += tx_bytes;
|
||||
card->perf_stats.large_send_cnt++;
|
||||
}
|
||||
|
|
@ -3248,65 +3148,42 @@ static int qeth_l3_stop(struct net_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u32 qeth_l3_ethtool_get_rx_csum(struct net_device *dev)
|
||||
static u32 qeth_l3_fix_features(struct net_device *dev, u32 features)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
|
||||
return (card->options.checksum_type == HW_CHECKSUMMING);
|
||||
if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
|
||||
features &= ~NETIF_F_IP_CSUM;
|
||||
if (!qeth_is_supported(card, IPA_OUTBOUND_TSO))
|
||||
features &= ~NETIF_F_TSO;
|
||||
if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
|
||||
features &= ~NETIF_F_RXCSUM;
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data)
|
||||
static int qeth_l3_set_features(struct net_device *dev, u32 features)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
enum qeth_checksum_types csum_type;
|
||||
u32 changed = dev->features ^ features;
|
||||
int err;
|
||||
|
||||
if (data)
|
||||
csum_type = HW_CHECKSUMMING;
|
||||
else
|
||||
csum_type = SW_CHECKSUMMING;
|
||||
if (!(changed & NETIF_F_RXCSUM))
|
||||
return 0;
|
||||
|
||||
return qeth_l3_set_rx_csum(card, csum_type);
|
||||
}
|
||||
if (card->state == CARD_STATE_DOWN ||
|
||||
card->state == CARD_STATE_RECOVER)
|
||||
return 0;
|
||||
|
||||
static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
int rc = 0;
|
||||
err = qeth_l3_set_rx_csum(card, features & NETIF_F_RXCSUM);
|
||||
if (err)
|
||||
dev->features = features ^ NETIF_F_RXCSUM;
|
||||
|
||||
if (data) {
|
||||
rc = qeth_l3_set_large_send(card, QETH_LARGE_SEND_TSO);
|
||||
} else {
|
||||
dev->features &= ~NETIF_F_TSO;
|
||||
card->options.large_send = QETH_LARGE_SEND_NO;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int qeth_l3_ethtool_set_tx_csum(struct net_device *dev, u32 data)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
|
||||
if (data) {
|
||||
if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
|
||||
dev->features |= NETIF_F_IP_CSUM;
|
||||
else
|
||||
return -EPERM;
|
||||
} else
|
||||
dev->features &= ~NETIF_F_IP_CSUM;
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct ethtool_ops qeth_l3_ethtool_ops = {
|
||||
.get_link = ethtool_op_get_link,
|
||||
.get_tx_csum = ethtool_op_get_tx_csum,
|
||||
.set_tx_csum = qeth_l3_ethtool_set_tx_csum,
|
||||
.get_rx_csum = qeth_l3_ethtool_get_rx_csum,
|
||||
.set_rx_csum = qeth_l3_ethtool_set_rx_csum,
|
||||
.get_sg = ethtool_op_get_sg,
|
||||
.set_sg = ethtool_op_set_sg,
|
||||
.get_tso = ethtool_op_get_tso,
|
||||
.set_tso = qeth_l3_ethtool_set_tso,
|
||||
.get_strings = qeth_core_get_strings,
|
||||
.get_ethtool_stats = qeth_core_get_ethtool_stats,
|
||||
.get_sset_count = qeth_core_get_sset_count,
|
||||
|
|
@ -3347,6 +3224,8 @@ static const struct net_device_ops qeth_l3_netdev_ops = {
|
|||
.ndo_set_multicast_list = qeth_l3_set_multicast_list,
|
||||
.ndo_do_ioctl = qeth_l3_do_ioctl,
|
||||
.ndo_change_mtu = qeth_change_mtu,
|
||||
.ndo_fix_features = qeth_l3_fix_features,
|
||||
.ndo_set_features = qeth_l3_set_features,
|
||||
.ndo_vlan_rx_register = qeth_l3_vlan_rx_register,
|
||||
.ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid,
|
||||
.ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid,
|
||||
|
|
@ -3362,6 +3241,8 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = {
|
|||
.ndo_set_multicast_list = qeth_l3_set_multicast_list,
|
||||
.ndo_do_ioctl = qeth_l3_do_ioctl,
|
||||
.ndo_change_mtu = qeth_change_mtu,
|
||||
.ndo_fix_features = qeth_l3_fix_features,
|
||||
.ndo_set_features = qeth_l3_set_features,
|
||||
.ndo_vlan_rx_register = qeth_l3_vlan_rx_register,
|
||||
.ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid,
|
||||
.ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid,
|
||||
|
|
@ -3392,8 +3273,12 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
|
|||
if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
|
||||
card->dev->dev_id = card->info.unique_id &
|
||||
0xffff;
|
||||
if (!card->info.guestlan)
|
||||
card->dev->features |= NETIF_F_GRO;
|
||||
if (!card->info.guestlan) {
|
||||
card->dev->hw_features = NETIF_F_SG |
|
||||
NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
|
||||
NETIF_F_TSO;
|
||||
card->dev->features = NETIF_F_RXCSUM;
|
||||
}
|
||||
}
|
||||
} else if (card->info.type == QETH_CARD_TYPE_IQD) {
|
||||
card->dev = alloc_netdev(0, "hsi%d", ether_setup);
|
||||
|
|
@ -3426,15 +3311,13 @@ static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
|
|||
|
||||
qeth_l3_create_device_attributes(&gdev->dev);
|
||||
card->options.layer2 = 0;
|
||||
card->info.hwtrap = 0;
|
||||
card->discipline.start_poll = qeth_qdio_start_poll;
|
||||
card->discipline.input_handler = (qdio_handler_t *)
|
||||
qeth_qdio_input_handler;
|
||||
card->discipline.output_handler = (qdio_handler_t *)
|
||||
qeth_qdio_output_handler;
|
||||
card->discipline.recover = qeth_l3_recover;
|
||||
if ((card->info.type == QETH_CARD_TYPE_OSD) ||
|
||||
(card->info.type == QETH_CARD_TYPE_OSX))
|
||||
card->options.checksum_type = HW_CHECKSUMMING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3480,13 +3363,18 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|||
goto out_remove;
|
||||
}
|
||||
|
||||
qeth_l3_query_ipassists(card, QETH_PROT_IPV4);
|
||||
|
||||
if (!card->dev && qeth_l3_setup_netdev(card)) {
|
||||
rc = -ENODEV;
|
||||
goto out_remove;
|
||||
}
|
||||
|
||||
if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
|
||||
if (card->info.hwtrap &&
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM))
|
||||
card->info.hwtrap = 0;
|
||||
} else
|
||||
card->info.hwtrap = 0;
|
||||
|
||||
card->state = CARD_STATE_HARDSETUP;
|
||||
memset(&card->rx, 0, sizeof(struct qeth_rx));
|
||||
qeth_print_status_message(card);
|
||||
|
|
@ -3516,7 +3404,6 @@ contin:
|
|||
rc = qeth_l3_start_ipassists(card);
|
||||
if (rc)
|
||||
QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
|
||||
qeth_l3_set_large_send(card, card->options.large_send);
|
||||
rc = qeth_l3_setrouting_v4(card);
|
||||
if (rc)
|
||||
QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
|
||||
|
|
@ -3589,6 +3476,10 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev,
|
|||
if (card->dev && netif_carrier_ok(card->dev))
|
||||
netif_carrier_off(card->dev);
|
||||
recover_flag = card->state;
|
||||
if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
|
||||
card->info.hwtrap = 1;
|
||||
}
|
||||
qeth_l3_stop_card(card, recovery_mode);
|
||||
rc = ccw_device_set_offline(CARD_DDEV(card));
|
||||
rc2 = ccw_device_set_offline(CARD_WDEV(card));
|
||||
|
|
@ -3644,6 +3535,8 @@ static int qeth_l3_recover(void *ptr)
|
|||
static void qeth_l3_shutdown(struct ccwgroup_device *gdev)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
|
||||
if ((gdev->state == CCWGROUP_ONLINE) && card->info.hwtrap)
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
|
||||
qeth_qdio_clear_card(card, 0);
|
||||
qeth_clear_qdio_buffers(card);
|
||||
}
|
||||
|
|
@ -3659,6 +3552,8 @@ static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev)
|
|||
if (gdev->state == CCWGROUP_OFFLINE)
|
||||
return 0;
|
||||
if (card->state == CARD_STATE_UP) {
|
||||
if (card->info.hwtrap)
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
|
||||
__qeth_l3_set_offline(card->gdev, 1);
|
||||
} else
|
||||
__qeth_l3_set_offline(card->gdev, 0);
|
||||
|
|
|
|||
|
|
@ -15,16 +15,6 @@
|
|||
#define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
|
||||
struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
|
||||
|
||||
static const char *qeth_l3_get_checksum_str(struct qeth_card *card)
|
||||
{
|
||||
if (card->options.checksum_type == SW_CHECKSUMMING)
|
||||
return "sw";
|
||||
else if (card->options.checksum_type == HW_CHECKSUMMING)
|
||||
return "hw";
|
||||
else
|
||||
return "no";
|
||||
}
|
||||
|
||||
static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
|
||||
struct qeth_routing_info *route, char *buf)
|
||||
{
|
||||
|
|
@ -295,51 +285,6 @@ out:
|
|||
static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
|
||||
qeth_l3_dev_canonical_macaddr_store);
|
||||
|
||||
static ssize_t qeth_l3_dev_checksum_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(dev);
|
||||
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
|
||||
return sprintf(buf, "%s checksumming\n",
|
||||
qeth_l3_get_checksum_str(card));
|
||||
}
|
||||
|
||||
static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(dev);
|
||||
enum qeth_checksum_types csum_type;
|
||||
char *tmp;
|
||||
int rc = 0;
|
||||
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&card->conf_mutex);
|
||||
tmp = strsep((char **) &buf, "\n");
|
||||
if (!strcmp(tmp, "sw_checksumming"))
|
||||
csum_type = SW_CHECKSUMMING;
|
||||
else if (!strcmp(tmp, "hw_checksumming"))
|
||||
csum_type = HW_CHECKSUMMING;
|
||||
else if (!strcmp(tmp, "no_checksumming"))
|
||||
csum_type = NO_CHECKSUMMING;
|
||||
else {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = qeth_l3_set_rx_csum(card, csum_type);
|
||||
out:
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
return rc ? rc : count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
|
||||
qeth_l3_dev_checksum_store);
|
||||
|
||||
static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
|
@ -402,61 +347,13 @@ out:
|
|||
static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
|
||||
qeth_l3_dev_sniffer_store);
|
||||
|
||||
static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(dev);
|
||||
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
|
||||
switch (card->options.large_send) {
|
||||
case QETH_LARGE_SEND_NO:
|
||||
return sprintf(buf, "%s\n", "no");
|
||||
case QETH_LARGE_SEND_TSO:
|
||||
return sprintf(buf, "%s\n", "TSO");
|
||||
default:
|
||||
return sprintf(buf, "%s\n", "N/A");
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(dev);
|
||||
enum qeth_large_send_types type;
|
||||
int rc = 0;
|
||||
char *tmp;
|
||||
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
tmp = strsep((char **) &buf, "\n");
|
||||
if (!strcmp(tmp, "no"))
|
||||
type = QETH_LARGE_SEND_NO;
|
||||
else if (!strcmp(tmp, "TSO"))
|
||||
type = QETH_LARGE_SEND_TSO;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&card->conf_mutex);
|
||||
if (card->options.large_send != type)
|
||||
rc = qeth_l3_set_large_send(card, type);
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
return rc ? rc : count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
|
||||
qeth_l3_dev_large_send_store);
|
||||
|
||||
static struct attribute *qeth_l3_device_attrs[] = {
|
||||
&dev_attr_route4.attr,
|
||||
&dev_attr_route6.attr,
|
||||
&dev_attr_fake_broadcast.attr,
|
||||
&dev_attr_broadcast_mode.attr,
|
||||
&dev_attr_canonical_macaddr.attr,
|
||||
&dev_attr_checksumming.attr,
|
||||
&dev_attr_sniffer.attr,
|
||||
&dev_attr_large_send.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue